#!/usr/bin/env python from __future__ import division, with_statement from contextlib import closing import json import os import sys import tarfile import urllib2 import SimpleHTTPServer import SocketServer from threading import Thread PORT = 9841 static_dir = os.path.normpath(os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', 'Resources', 'static')) 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') 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 if not os.path.exists(target): os.makedirs(target) os.chdir(target) release = self.get_release() self.status["release"] = release for module in release['modules']: self.status["step"] = 'downloading %s' % module self.status["progress"] = 0 self.status["size"] = 0 package_tar = release['modules'][module]['name'] url = self.release_url.replace('release.json', package_tar) self.download(url, package_tar) self.status["step"] = 'extracting %s' % module self.status["progress"] = 0 tar = tarfile.open(package_tar) tar.extractall() tar.close() os.unlink(package_tar) os.symlink('openmedialibrary/ctl', 'ctl') self.status["progress"] = 0 self.status["step"] = "setup" os.system("./ctl setup") self.status["progress"] = 1 with open('config/release.json', 'w') as fd: json.dump(release, fd, indent=2) self.install_launchd() self.status = {"done": True} self.httpd.shutdown() def download(self, url, filename): dirname = os.path.dirname(filename) if dirname and not os.path.exists(dirname): os.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 def install_launchd(self): name = 'com.openmedialibrary.loginscript' plist = os.path.expanduser('~/Library/LaunchAgents/%s.plist'%name) with open(plist, 'w') as f: f.write(''' Label %s ProgramArguments %s/ctl start RunAtLoad ''' % (name, self.target)) os.system('launchctl load "%s"' % plist) os.system('launchctl start %s' % name) if __name__ == '__main__': if len(sys.argv) == 1: target = os.path.join(os.curdir, 'openmedialibrary') 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()