#!/usr/bin/env python3 from contextlib import closing import json import os import sys import time import tarfile import urllib.request import urllib.error import urllib.parse import http.server import socketserver from threading import Thread PORT = 9841 static_dir = os.path.normpath(os.path.abspath(os.path.dirname(__file__))) def makedirs(dirname): if not os.path.exists(dirname): os.makedirs(dirname) def get_platform(): name = sys.platform if name.startswith('darwin'): name = 'darwin64' elif name.startswith('linux'): import platform if platform.architecture()[0] == '64bit': name = 'linux64' else: name = 'linux32' return name class Handler(http.server.SimpleHTTPRequestHandler): def do_OPTIONS(self): self.send_response(200, 'OK') self.send_header('Allow', 'GET, POST, OPTIONS') self.send_header('Access-Control-Allow-Origin', '*') self.send_header('Access-Control-Allow-Headers', 'X-Requested-With') self.send_header('Content-Length', '0') self.end_headers() def do_GET(self): if self.path == '/status': content = json.dumps(self.server.install.status) self.send_response(200, 'OK') else: path = os.path.join(static_dir, 'index.html' if self.path == '/' else self.path[1:]) if os.path.exists(path): with open(path, 'rb') as fd: content = fd.read() self.send_response(200, 'OK') content_type = { 'html': 'text/html', 'png': 'image/png', 'svg': 'image/svg+xml', 'txt': 'text/plain', }.get(path.split('.')[-1], 'txt') self.send_header('Content-Type', content_type) else: self.send_response(404, 'not found') content = '404 not found' self.send_header('Access-Control-Allow-Origin', '*') self.send_header('Content-Length', str(len(content))) self.end_headers() if isinstance(content, str): content = content.encode() self.wfile.write(content) class Install(Thread): release_url = "http://downloads.openmedialibrary.com/release.json" status = { 'step': 'Downloading...' } def __init__(self, target, httpd): target = os.path.normpath(os.path.join(os.path.abspath(target))) self.target = target self.httpd = httpd Thread.__init__(self) self.daemon = True self.start() def run(self): target = self.target makedirs(target) os.chdir(target) self.status["step"] = 'Downloading...' release = self.get_release() self.status["release"] = release self.status["progress"] = 0 platform = get_platform() for module in sorted(release['modules']): if release['modules'][module].get('platform', platform) == platform: package_tar = release['modules'][module]['name'] url = self.release_url.replace('release.json', package_tar) self.download(url, package_tar) self.status["step"] = 'Installing...' for module in sorted(release['modules']): if release['modules'][module].get('platform', platform) == platform: package_tar = release['modules'][module]['name'] tar = tarfile.open(package_tar) tar.extractall() tar.close() os.unlink(package_tar) os.symlink('openmedialibrary/ctl', 'ctl') makedirs('data') with open('data/release.json', 'w') as fd: json.dump(release, fd, indent=2) self.status = {"relaunch": True} os.system("./ctl start &") time.sleep(5) self.httpd.shutdown() def download(self, url, filename): dirname = os.path.dirname(filename) if dirname: makedirs(dirname) with open(filename, 'wb') as f: with closing(urllib.request.urlopen(url)) as u: size = int(u.headers.get('content-length', 0)) self.status["size"] = size available = 0 data = u.read(4096) while data: if size: available += len(data) f.write(data) data = u.read(4096) def get_release(self): with closing(urllib.request.urlopen(self.release_url)) as u: data = json.load(u) return data if __name__ == '__main__': if len(sys.argv) == 1: target = os.path.expanduser("~/Library/Application Support/Open Media Library") elif len(sys.argv) != 2: print("usage: %s [target]" % sys.argv[0]) sys.exit(1) else: target = sys.argv[1] socketserver.TCPServer.allow_reuse_address = True httpd = socketserver.TCPServer(("", PORT), Handler) install = Install(target, httpd) httpd.install = install httpd.serve_forever()