#!/usr/bin/env python from __future__ import division, with_statement from contextlib import closing import json import os import sys import time import tarfile import urllib2 import SimpleHTTPServer 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) class Handler(SimpleHTTPServer.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) 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() self.wfile.write(content) class Install(Thread): release_url = "http://downloads.openmedialibrary.com/release.json" status = {} 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) release = self.get_release() self.status["release"] = release self.status["step"] = 'Downloading...' self.status["progress"] = 0 for module in sorted(release['modules']): 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']): 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, 'w') as f: with closing(urllib2.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) self.status["progress"] = available/size f.write(data) data = u.read(4096) def get_release(self): with closing(urllib2.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()