Installer_Server/main.py

174 lines
4.9 KiB
Python

import io
import os
import sys
import json
import hashlib
import tempfile
from flask import Flask, request, send_from_directory
def _fd(f):
return f.fileno() if hasattr(f, 'fileno') else f
if os.name == 'nt':
import msvcrt
from ctypes import (sizeof, c_ulong, c_void_p, c_int64, Structure, Union, POINTER, windll, byref)
from ctypes.wintypes import BOOL, DWORD, HANDLE
LOCK_SH = 0x0
LOCK_NB = 0x1
LOCK_EX = 0x2
LOCK_UN = 0x9
if sizeof(c_ulong) != sizeof(c_void_p):
ULONG_PTR = c_int64
else:
ULONG_PTR = c_ulong
PVOID = c_void_p
class _OFFSET(Structure):
_fields_ = [
('Offset', DWORD),
('OffsetHigh', DWORD)
]
class _OFFSET_UNION(Union):
_fields_ = [
('_offset', _OFFSET),
('Pointer', PVOID)
]
_anonymous_ = ['_offset']
class OVERLAPPED(Structure):
_fields_ = [
('Internal', ULONG_PTR),
('InternalHigh', ULONG_PTR),
('_offset_union', _OFFSET_UNION),
('hEvent', HANDLE)
]
_anonymous_ = ['_offset_union']
LPOVERLAPPED = POINTER(OVERLAPPED)
LockFileEx = windll.kernel32.LockFileEx
LockFileEx.restype = BOOL
LockFileEx.argtypes = [HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED]
UnlockFileEx = windll.kernel32.UnlockFileEx
UnlockFileEx.restype = BOOL
UnlockFileEx.argtypes = [HANDLE, DWORD, DWORD, DWORD, LPOVERLAPPED]
def flock(f, flags):
hfile = msvcrt.get_osfhandle(_fd(f))
overlapped = OVERLAPPED()
if flags == LOCK_UN:
ret = UnlockFileEx(
hfile,
0,
0,
0xFFFF0000,
byref(overlapped)
)
else:
ret = LockFileEx(
hfile,
flags,
0,
0,
0xFFFF0000,
byref(overlapped)
)
return bool(ret)
else:
try:
import fcntl
LOCK_SH = fcntl.LOCK_SH
LOCK_NB = fcntl.LOCK_NB
LOCK_EX = fcntl.LOCK_EX
LOCK_UN = fcntl.LOCK_UN
except (ImportError, AttributeError):
LOCK_EX = LOCK_SH = LOCK_NB = 0
def flock(f, flags):
return flags == LOCK_UN
else:
def flock(f, flags):
return fcntl.flock(_fd(f), flags) == 0
def getJson(file, data=None):
if os.path.exists(file):
try:
return json.loads(open(file=file, mode='r', encoding='utf-8').read())
except json.decoder.JSONDecodeError:
return data
return data
def md5(input_data):
if isinstance(input_data, bytes):
return hashlib.md5(input_data).hexdigest()
if isinstance(input_data, str):
return hashlib.md5(bytes(input_data, encoding='utf-8')).hexdigest()
md5_object = hashlib.md5()
while True:
data = input_data.read(io.DEFAULT_BUFFER_SIZE)
if data:
md5_object.update(data)
else:
return md5_object.hexdigest()
www_home = os.path.abspath(os.path.join(os.path.dirname(__file__), 'apps'))
app_data = []
app = Flask(__name__)
@app.route('/getApps', methods=['GET', 'POST'])
def get_apps():
data = []
for i in app_data:
data.append({'url': '%s://%s/%s' % (request.scheme, request.host, i['packages_path']), 'md5': i['md5'], 'manifest': i['manifest']})
return data
@app.route('/', methods=['GET', 'POST'])
def index():
return 'Hello world.'
@app.route('/<path:filename>')
def www(filename):
return send_from_directory(www_home, filename)
if __name__ == '__main__':
f_lock = open(file=os.path.abspath(os.path.join(tempfile.gettempdir(), '%s.lock' % hashlib.md5(bytes(__file__, encoding='utf-8')).hexdigest()[:16])), mode='w', encoding='utf-8')
if (not flock(f_lock, LOCK_EX | LOCK_NB)) == 1:
sys.exit(1)
else:
print('Scanning apps...')
if os.path.exists(www_home):
for item in os.listdir(www_home):
if (item.endswith('.zip')) is bool(1):
packages = os.path.join(www_home, item)
manifest = os.path.join(www_home, '%s.%s' % (os.path.splitext(os.path.basename(item))[0], 'MANIFEST'))
if (os.path.isfile(packages) and os.path.isfile(manifest)) is bool(1):
info = getJson(manifest, {})
try:
if (isinstance(info['appName'], str) and isinstance(info['HomeFolderName'], str) and isinstance(info['shortcutMapping'], list)) is bool(0):
continue
app_data.append({'packages_path': item, 'md5': md5(open(packages, 'rb')), 'manifest': info})
except KeyError:
pass
print('Starting web server...')
app.run(host='0.0.0.0', port=9988)