Initial commit
This commit is contained in:
commit
133eb26a0b
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
__pycache__
|
11
app.py
Normal file
11
app.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
from flask import Flask, request, Response
|
||||
import os
|
||||
import requests
|
||||
import base64
|
||||
#import hcapi
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/client')
|
||||
def client():
|
||||
with open('client.html') as f:
|
||||
return f.read()
|
123
client.html
Normal file
123
client.html
Normal file
|
@ -0,0 +1,123 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>HamClock</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: black;
|
||||
}
|
||||
#errorbox {
|
||||
color: white;
|
||||
font-family: sans-serif;
|
||||
font-size: 200%;
|
||||
text-align: center
|
||||
}
|
||||
#holder {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
text-align: center
|
||||
}
|
||||
#holder * {
|
||||
margin: 0 auto;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id=login>
|
||||
<h1>HamClock Remote Access</h1>
|
||||
<form>
|
||||
<label for=url>Server URL:</label><input name=url id=url><br>
|
||||
<label for=password>Password:</label><input name=password id=password>
|
||||
<button id=start>Start</button>
|
||||
</form>
|
||||
</div>
|
||||
<div id=holder style="display:none">
|
||||
<div id=errorbox style="width: 800px; height: 480px">Loading...</div>
|
||||
<canvas id=canvas width=800 height=480 style="width: 800px; height: 480px; display: none"></canvas>
|
||||
</div>
|
||||
<script>
|
||||
let canvas = document.querySelector('canvas')
|
||||
let errorbox = document.querySelector('#errorbox')
|
||||
let login = document.querySelector('#login')
|
||||
let holder = document.querySelector('#holder')
|
||||
let url_el = document.querySelector('#url')
|
||||
let password_el = document.querySelector('#password')
|
||||
let start_button = document.querySelector('#start')
|
||||
let displayWidth, displayHeight
|
||||
function resize() {
|
||||
let bodyWidth = window.innerWidth
|
||||
let maxWidth = Math.min(bodyWidth - 60, 800)
|
||||
let bodyHeight = window.innerHeight
|
||||
let maxHeight = Math.min(bodyHeight - 60, 480)
|
||||
let equivalentHeight = maxWidth * 0.6
|
||||
if (equivalentHeight >= maxHeight) {
|
||||
displayHeight = Math.round(maxHeight)
|
||||
displayWidth = Math.round(maxHeight * (5/3))
|
||||
} else {
|
||||
displayWidth = Math.round(maxWidth)
|
||||
displayHeight = Math.round(maxWidth * 0.6)
|
||||
}
|
||||
canvas.style.width = displayWidth + 'px'
|
||||
canvas.style.height = displayHeight + 'px'
|
||||
//canvas.style.marginTop = '-' + displayHeight/2 + 'px'
|
||||
errorbox.style.width = displayWidth + 'px'
|
||||
errorbox.style.height = displayHeight + 'px'
|
||||
//errorbox.style.marginTop = '-' + displayHeight/2 + 'px'
|
||||
}
|
||||
resize()
|
||||
window.onresize = resize
|
||||
let ctx = canvas.getContext("2d")
|
||||
canvas.addEventListener('click', function (e) {
|
||||
x = e.layerX
|
||||
y = e.layerY
|
||||
w = displayWidth
|
||||
ws.send(localStorage.getItem('password') + ' ' + x + ' ' + y + ' ' + w)
|
||||
})
|
||||
let ws
|
||||
function setup() {
|
||||
ws = new WebSocket(localStorage.getItem('url'))
|
||||
ws.onmessage = function(e) {
|
||||
let type, pos, x, y, data, img, code, msg
|
||||
type = e.data.split('%')[0]
|
||||
if ( type == 'pic' ) {
|
||||
pos = e.data.split('%')[1]
|
||||
x = Number(pos.split('x')[0])
|
||||
y = Number(pos.split('x')[1])
|
||||
data = e.data.split('%')[2]
|
||||
img = new Image()
|
||||
img.src = data
|
||||
img.addEventListener("load", function(){
|
||||
ctx.drawImage(img,x,y)
|
||||
})
|
||||
errorbox.style.display = 'none'
|
||||
canvas.style.display = 'block'
|
||||
} else if ( type == 'err' ) {
|
||||
code = e.data.split('%')[1]
|
||||
msg = e.data.split('%')[2]
|
||||
errorbox.textContent = msg
|
||||
errorbox.style.display = 'block'
|
||||
canvas.style.display = 'none'
|
||||
console.error('Server reported error: ' + code + ': ' + msg)
|
||||
}
|
||||
}
|
||||
ws.onerror = setup
|
||||
ws.onclose = setup
|
||||
}
|
||||
start.onclick = function(e) {
|
||||
e.preventDefault()
|
||||
holder.style.display = 'block'
|
||||
login.style.display = 'none'
|
||||
localStorage.setItem('url', url_el.value)
|
||||
localStorage.setItem('password', password_el.value)
|
||||
setup()
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
1
crops.json
Normal file
1
crops.json
Normal file
|
@ -0,0 +1 @@
|
|||
["232x53+0+0", "232x11+0+53", "232x84+0+64", "163x148+232+0", "181x148+395+0", "170x148+576+0", "54x148+746+0", "139x148+0+148", "139x184+0+296", "110x166+139+148", "110x166+249+148", "110x166+359+148", "110x166+469+148", "110x166+579+148", "111x166+689+148", "110x166+139+314", "110x166+249+314", "110x166+359+314", "110x166+469+314", "110x166+579+314", "111x166+689+314"]
|
53
hcapi.py
Normal file
53
hcapi.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
import os
|
||||
import requests
|
||||
import threading
|
||||
import json
|
||||
|
||||
def get_img():
|
||||
raw_img = requests.get('http://localhost:8080/get_capture.bmp').content
|
||||
|
||||
with open('full_img.bmp', 'wb+') as f:
|
||||
f.write(raw_img)
|
||||
|
||||
os.system('convert full_img.bmp -resize 800x480 img.bmp')
|
||||
|
||||
#crops = []
|
||||
#for n in range(10):
|
||||
# for m in range(6):
|
||||
# crops.append(f'80x80+{n*80}+{m*80}')
|
||||
#print(crops)
|
||||
with open('crops.json') as f:
|
||||
crops = json.load(f)
|
||||
|
||||
threads = []
|
||||
for crop in crops:
|
||||
threads.append(threading.Thread(target=os.system, args=(f'convert img.bmp -crop {crop} pieces/{crop.split("+", 1)[1].replace("+", "x")}.jpg',)))
|
||||
threads[-1].start()
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
|
||||
os.system("md5sum -c oldlist 2>/dev/null | grep FAILED > newlist")
|
||||
changed = []
|
||||
with open('newlist') as f:
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
changed.append(line.split(": ")[0].split('.')[0].split('/')[1])
|
||||
os.system("md5sum pieces/* > oldlist")
|
||||
return changed
|
||||
|
||||
def get_full_img():
|
||||
raw_img = requests.get('http://localhost:8080/get_capture.bmp').content
|
||||
|
||||
with open('full_full.bmp', 'wb+') as f:
|
||||
f.write(raw_img)
|
||||
|
||||
os.system('convert full_full.bmp -resize 800x480 full.jpg')
|
||||
|
||||
os.unlink('full_full.bmp')
|
||||
|
||||
return 'full.jpg'
|
||||
|
||||
def touch(x, y, w):
|
||||
x = round(800 * x / w)
|
||||
y = round(800 * y / w)
|
||||
requests.get(f'http://localhost:8080/set_touch?x={x}&y={y}&hold={0}')
|
73
wss.py
Normal file
73
wss.py
Normal file
|
@ -0,0 +1,73 @@
|
|||
import os
|
||||
import base64
|
||||
import hcapi
|
||||
import threading
|
||||
import logging
|
||||
import random
|
||||
import time
|
||||
import shutil
|
||||
import tempfile
|
||||
from websocket_server import WebsocketServer
|
||||
|
||||
def cycle():
|
||||
try:
|
||||
changed = hcapi.get_img()
|
||||
except ImportError as e:
|
||||
server.send_message_to_all('err%noconn%Server failed to capture screenshot')
|
||||
time.sleep(3)
|
||||
return
|
||||
|
||||
for i in changed:
|
||||
threading.Thread(target=do_img, args=(i,)).start()
|
||||
|
||||
|
||||
def do_img(imgname):
|
||||
server.send_message_to_all(img(imgname))
|
||||
|
||||
|
||||
def img(imgname):
|
||||
with open(f'pieces/{imgname}.jpg', 'rb') as f:
|
||||
img = f.read()
|
||||
|
||||
response = f'pic%{imgname}%data:imgage/jpeg;base64,{base64.b64encode(img).decode("utf-8")}'
|
||||
|
||||
return response
|
||||
|
||||
def new_client(client, server):
|
||||
print('got client')
|
||||
try:
|
||||
imgname = hcapi.get_full_img()
|
||||
except Exception as e:
|
||||
server.send_message(client, 'err%noconn%Server failed to capture screenshot')
|
||||
return
|
||||
|
||||
with open(imgname, 'rb') as f:
|
||||
img = f.read()
|
||||
os.unlink(imgname)
|
||||
server.send_message(client, f'pic%0x0%data:imgage/jpeg;base64,{base64.b64encode(img).decode("utf-8")}')
|
||||
|
||||
def do_touch(client, server, message):
|
||||
password, x, y, w = message.split(' ')
|
||||
if password == 'password':
|
||||
x, y, w = int(x), int(y), int(w)
|
||||
hcapi.touch(x, y, w)
|
||||
else:
|
||||
server.send_message(client, f'badpass')
|
||||
|
||||
def do_cycles():
|
||||
while True:
|
||||
cycle()
|
||||
|
||||
tmp = tempfile.mkdtemp(prefix="HCRA-")
|
||||
try:
|
||||
shutil.copy('crops.json', tmp)
|
||||
os.chdir(tmp)
|
||||
os.mkdir('pieces')
|
||||
server = WebsocketServer(1234, host='0.0.0.0', loglevel=logging.INFO)
|
||||
threading.Thread(target=do_cycles).start()
|
||||
server.set_fn_new_client(new_client)
|
||||
server.set_fn_message_received(do_touch)
|
||||
server.run_forever()
|
||||
finally:
|
||||
os.chdir('/')
|
||||
shutil.rmtree(tmp)
|
Loading…
Reference in New Issue
Block a user