From fdb62be2baf0fb2d317edebad9ec88bbcc6bc6c1 Mon Sep 17 00:00:00 2001 From: Eldon Date: Tue, 21 Jan 2014 06:41:46 +0000 Subject: [PATCH] First commit of umbra --- .gitignore | 6 +++++ setup.py | 21 +++++++++++++++ umbra/__init__.py | 0 umbra/umbra.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 .gitignore create mode 100644 setup.py create mode 100644 umbra/__init__.py create mode 100755 umbra/umbra.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6740b54 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.pyc +/bin/ +/include/ +/lib/ +/local/ +/share/ diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..86d80ca --- /dev/null +++ b/setup.py @@ -0,0 +1,21 @@ +import setuptools + +setuptools.setup(name='umbra', + version='0.1', + description='Google Chrome remote control interface', + url='https://github.com/eldondev/umbra', + author='Eldon Stegall', + author_email='eldon@archive.org', + long_description=open('README.rst').read(), + license='GPL', + packages=['umbra'], + install_requires=['kombu', 'websocket-client','psutil','argparse'], + scripts=['bin/umbra'], + zip_safe=False, + classifiers=[ + 'Development Status :: 3 - Alpha Development Status', + 'Environment :: Console', + 'License :: OSI Approved :: GNU General Public License (GPL)', + 'Programming Language :: Python :: 2.7', + 'Topic :: System :: Archiving', + ]) diff --git a/umbra/__init__.py b/umbra/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/umbra/umbra.py b/umbra/umbra.py new file mode 100755 index 0000000..4fa9d2f --- /dev/null +++ b/umbra/umbra.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +from json import dumps, loads +import os,sys,argparse, urllib2 +import websocket +import thread +import time + +def on_message(ws, message): + message = loads(message) + if "method" in message.keys() and message["method"] == "Network.requestWillBeSent": + print message + + +def on_error(ws, error): + print error + +def on_close(ws): + print "### closed ###" + +def on_open(ws): + cmd = {} + cmd['id'] = 1001 + cmd['method'] = "Network.enable" + ws.send(dumps(cmd)) + cmd['id'] = 1002 + cmd['method'] = "Runtime.evaluate" + cmd["params"] = { "expression" : "document.location = 'http://archive.org'"} + ws.send(dumps(cmd)) + +class Chrome(): + def __init__(self, port): + self.port = port + + def __enter__(self): + import psutil, subprocess + self.chrome_process = subprocess.Popen(["google-chrome", "--remote-debugging-port=%s" % self.port]) + start = time.time() + open_debug_port = lambda conn: conn.laddr[1] == int(self.port) + chrome_ps_wrapper = psutil.Process(self.chrome_process.pid) + while time.time() - start < 10 and len(filter(open_debug_port, chrome_ps_wrapper.get_connections())) == 0: + time.sleep(1) + if len(filter(open_debug_port, chrome_ps_wrapper.get_connections())) == 0: + self.chrome_process.kill() + raise Exception("Chrome failed to listen on the debug port in time!") + + def __exit__(self, *args): + print "Killing" + self.chrome_process.kill() + +if __name__ == "__main__": + arg_parser = argparse.ArgumentParser(prog=os.path.basename(sys.argv[0]), + description='umbra - Browser automation tool', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + arg_parser.add_argument('-p', '--port', dest='port', default='9222', + help='Port to have invoked chrome listen on for debugging connections') + args = arg_parser.parse_args(args=sys.argv[1:]) + with Chrome(args.port): + debug_info = loads(urllib2.urlopen("http://localhost:%s/json" % args.port).read()) + url = debug_info[0]['webSocketDebuggerUrl'] + ws = websocket.WebSocketApp(url, + on_message = on_message, + on_error = on_error, + on_close = on_close) + ws.on_open = on_open + ws.run_forever() +