aboutsummaryrefslogtreecommitdiffstats
path: root/libmproxy/script
diff options
context:
space:
mode:
authorMaximilian Hils <git@maximilianhils.com>2015-11-14 05:57:02 +0100
committerMaximilian Hils <git@maximilianhils.com>2015-11-14 05:57:02 +0100
commit0d98b9dcc58f62c6fcb1ab597456b13a24ea88a3 (patch)
tree198546e0afd357073814376be02e9fd94afdd160 /libmproxy/script
parent4499ab61c04d765fc191227e25af0ee1cc98a83a (diff)
downloadmitmproxy-0d98b9dcc58f62c6fcb1ab597456b13a24ea88a3.tar.gz
mitmproxy-0d98b9dcc58f62c6fcb1ab597456b13a24ea88a3.tar.bz2
mitmproxy-0d98b9dcc58f62c6fcb1ab597456b13a24ea88a3.zip
finalize script reloading :tada:
Diffstat (limited to 'libmproxy/script')
-rw-r--r--libmproxy/script/__init__.py8
-rw-r--r--libmproxy/script/reloader.py37
-rw-r--r--libmproxy/script/script.py60
3 files changed, 59 insertions, 46 deletions
diff --git a/libmproxy/script/__init__.py b/libmproxy/script/__init__.py
index 0f487795..8bcdc5a2 100644
--- a/libmproxy/script/__init__.py
+++ b/libmproxy/script/__init__.py
@@ -1,11 +1,13 @@
-from .script import Script, script_change
+from .script import Script
from .script_context import ScriptContext
from .concurrent import concurrent
from ..exceptions import ScriptException
+from . import reloader
__all__ = [
- "Script", "script_change",
+ "Script",
"ScriptContext",
"concurrent",
- "ScriptException"
+ "ScriptException",
+ "reloader"
] \ No newline at end of file
diff --git a/libmproxy/script/reloader.py b/libmproxy/script/reloader.py
new file mode 100644
index 00000000..b867238f
--- /dev/null
+++ b/libmproxy/script/reloader.py
@@ -0,0 +1,37 @@
+import os
+from watchdog.events import PatternMatchingEventHandler
+from watchdog.observers import Observer
+
+_observers = {}
+
+
+def watch(script, callback):
+ script_dir = os.path.dirname(os.path.abspath(script.args[0]))
+ event_handler = _ScriptModificationHandler(callback)
+ observer = Observer()
+ observer.schedule(event_handler, script_dir)
+ observer.start()
+ _observers[script] = observer
+
+
+def unwatch(script):
+ observer = _observers.pop(script, None)
+ if observer:
+ observer.stop()
+
+
+class _ScriptModificationHandler(PatternMatchingEventHandler):
+ def __init__(self, callback):
+ # We could enumerate all relevant *.py files (as werkzeug does it),
+ # but our case looks like it isn't as simple as enumerating sys.modules.
+ # This should be good enough for now.
+ super(_ScriptModificationHandler, self).__init__(
+ ignore_directories=True,
+ patterns=["*.py"]
+ )
+ self.callback = callback
+
+ def on_modified(self, event):
+ self.callback()
+
+__all__ = ["watch", "unwatch"] \ No newline at end of file
diff --git a/libmproxy/script/script.py b/libmproxy/script/script.py
index a58ba0af..498caf94 100644
--- a/libmproxy/script/script.py
+++ b/libmproxy/script/script.py
@@ -8,32 +8,27 @@ import os
import shlex
import traceback
import sys
-import blinker
-
-from watchdog.events import PatternMatchingEventHandler, FileModifiedEvent
-from watchdog.observers import Observer
-
from ..exceptions import ScriptException
-script_change = blinker.Signal()
-
class Script(object):
"""
- Script object representing an inline script.
+ Script object representing an inline script.
"""
- def __init__(self, command, context, use_reloader=True):
+ def __init__(self, command, context):
self.command = command
self.args = self.parse_command(command)
self.ctx = context
self.ns = None
self.load()
- if use_reloader:
- self.start_observe()
- @classmethod
- def parse_command(cls, command):
+ @property
+ def filename(self):
+ return self.args[0]
+
+ @staticmethod
+ def parse_command(command):
if not command or not command.strip():
raise ScriptException("Empty script command.")
if os.name == "nt": # Windows: escape all backslashes in the path.
@@ -64,21 +59,22 @@ class Script(object):
if self.ns is not None:
self.unload()
script_dir = os.path.dirname(os.path.abspath(self.args[0]))
- ns = {'__file__': os.path.abspath(self.args[0])}
+ self.ns = {'__file__': os.path.abspath(self.args[0])}
sys.path.append(script_dir)
try:
- execfile(self.args[0], ns, ns)
+ execfile(self.args[0], self.ns, self.ns)
except Exception as e:
# Python 3: use exception chaining, https://www.python.org/dev/peps/pep-3134/
raise ScriptException(traceback.format_exc(e))
- sys.path.pop()
- self.ns = ns
+ finally:
+ sys.path.pop()
return self.run("start", self.args)
def unload(self):
- ret = self.run("done")
- self.ns = None
- return ret
+ try:
+ return self.run("done")
+ finally:
+ self.ns = None
def run(self, name, *args, **kwargs):
"""
@@ -98,26 +94,4 @@ class Script(object):
except Exception as e:
raise ScriptException(traceback.format_exc(e))
else:
- return None
-
- def start_observe(self):
- script_dir = os.path.dirname(self.args[0])
- event_handler = ScriptModified(self)
- observer = Observer()
- observer.schedule(event_handler, script_dir)
- observer.start()
-
- def stop_observe(self):
- raise NotImplementedError() # FIXME
-
-
-class ScriptModified(PatternMatchingEventHandler):
- def __init__(self, script):
- # We could enumerate all relevant *.py files (as werkzeug does it),
- # but our case looks like it isn't as simple as enumerating sys.modules.
- # This should be good enough for now.
- super(ScriptModified, self).__init__(ignore_directories=True, patterns=["*.py"])
- self.script = script
-
- def on_modified(self, event=FileModifiedEvent):
- script_change.send(self.script)
+ return None \ No newline at end of file