kopia lustrzana https://github.com/DL7AD/pecanpico9
132 wiersze
3.5 KiB
Python
132 wiersze
3.5 KiB
Python
import binascii
|
|
import urllib.request
|
|
import urllib.error
|
|
from datetime import datetime
|
|
from subprocess import *
|
|
import time
|
|
import threading
|
|
from shutil import copyfile
|
|
import base91
|
|
|
|
def decode_callsign(code):
|
|
callsign = ''
|
|
|
|
while code > 0:
|
|
s = code % 40
|
|
if s == 0: callsign += '-'
|
|
elif s < 11: callsign += chr(47 + s)
|
|
elif s < 14: callsign += '-'
|
|
else: callsign += chr(51 + s)
|
|
code /= 40
|
|
|
|
return callsign
|
|
|
|
def encode_callsign(callsign):
|
|
x = 0
|
|
for i in range(len(callsign)-1,-1,-1):
|
|
x *= 40
|
|
c = ord(callsign[i])
|
|
if c >= 65 and c <= 90: x += c - 51
|
|
elif c >= 97 and c <= 122: x += c - 83
|
|
elif c >= 48 and c <= 57: x += c - 47
|
|
|
|
return x
|
|
|
|
imageProcessor = None
|
|
imageData = {}
|
|
lock = threading.RLock()
|
|
|
|
def imgproc():
|
|
global imageData
|
|
|
|
while True:
|
|
with lock:
|
|
for _id in imageData:
|
|
(call, data) = imageData[_id]
|
|
|
|
filename = 'html/images/%s-%d.jpg' % (call.replace('-',''), _id)
|
|
f = open(filename, 'wb')
|
|
process = Popen(['./ssdv', '-d'], stdin=PIPE, stdout=f, stderr=PIPE)
|
|
process.stdin.write(data)
|
|
dummy,err = process.communicate()
|
|
f.close()
|
|
|
|
filename2 = 'html/images/%s.jpg' % (call.replace('-',''))
|
|
copyfile(filename, filename2)
|
|
|
|
imageData = {} # Clear data
|
|
|
|
time.sleep(1)
|
|
|
|
w = time.time()
|
|
def insert_image(sqlite, receiver, call, data_b91):
|
|
global imageProcessor,imageData,w
|
|
|
|
data = base91.decode(data_b91)
|
|
if len(data) != 174:
|
|
return # APRS message has invalid type or length (or both)
|
|
|
|
cur = sqlite.cursor()
|
|
|
|
# Decode various meta data
|
|
imageID = data[0]
|
|
packetID = (data[1] << 8) | data[2]
|
|
data = binascii.hexlify(data[3:]).decode("ascii")
|
|
|
|
# Encode callsign (ensure callsign has no more than 6 chars)
|
|
bcall = call.split('-') # Split callsign and SSID
|
|
if len(bcall) == 1: # No SSID available, so take the callsign
|
|
bcall = bcall[0][0:6]
|
|
elif(len(bcall[0]) < 5): # Callsign has 4 chars, so take it with the SSID
|
|
bcall = bcall[0] + bcall[1][0:2]
|
|
elif(len(bcall[0]) < 6): # Callsign has 5 chars, so take it with the last digit of the SSID
|
|
bcall = bcall[0] + bcall[1][-1]
|
|
else:
|
|
bcall = bcall[0][0:6] # Callsign has 6 chars, so take the call without SSID
|
|
|
|
data = ('68%08x%02x%04x' % (encode_callsign(bcall), imageID, packetID)) + data
|
|
data += "%08x" % (binascii.crc32(binascii.unhexlify(data)) & 0xffffffff)
|
|
|
|
timd = int(datetime.now().timestamp())
|
|
|
|
# Find image ID (or generate new one)
|
|
_id = None
|
|
cur.execute("SELECT id,packetID FROM image WHERE call = ? AND imageID = ? AND rxtime+15*60 >= ? ORDER BY rxtime DESC LIMIT 1", (call, imageID, timd))
|
|
fetch = cur.fetchall()
|
|
if len(fetch):
|
|
_id = fetch[0][0]
|
|
lastPacketId = fetch[0][1]
|
|
|
|
if _id is None or lastPacketId > packetID:
|
|
# Generate ID
|
|
cur.execute("SELECT id+1 FROM image ORDER BY id DESC LIMIT 1")
|
|
fetch = cur.fetchall()
|
|
if len(fetch):
|
|
_id = fetch[0][0]
|
|
else: # No entries in the database
|
|
_id = 0
|
|
|
|
# Debug
|
|
print('Received image packet Call=%s ImageID=%d PacketID=%d ServerID=%d' % (call, imageID, packetID, _id))
|
|
|
|
# Insert into database
|
|
cur.execute("""
|
|
INSERT OR IGNORE INTO image (call,rxtime,imageID,packetID,data,id)
|
|
VALUES (?,?,?,?,?,?)""",
|
|
(call, timd, imageID, packetID, data, _id)
|
|
)
|
|
|
|
if w+0.5 < time.time():
|
|
sqlite.commit()
|
|
w = time.time()
|
|
|
|
with lock:
|
|
cur.execute("SELECT GROUP_CONCAT('55' || data || '"+(144*'0')+"', '') FROM image WHERE id = ? GROUP BY id ORDER BY packetID", (_id,))
|
|
data = cur.fetchall()[0][0]
|
|
imageData[_id] = (call, binascii.unhexlify(data))
|
|
|
|
if imageProcessor is None:
|
|
imageProcessor = threading.Thread(target=imgproc)
|
|
imageProcessor.start()
|
|
|