def __init__(self, runtime, persist_dir=None): self.storage = None if persist_dir is not None: try: try: os.makedirs(os.path.join(persist_dir, 'localstorage')) except OSError as e: if e.errno != errno.EEXIST: raise self.storage = dumbdbm.open( os.path.join(persist_dir, 'localstorage', str(runtime.pbw.uuid)), 'c') except IOError: pass if self.storage is None: logger.warning("Using transient store.") self.storage = _storage_cache.setdefault(str(runtime.pbw.uuid), {}) self.extension = v8.JSExtension( runtime.ext_name("localstorage"), """ (function() { native function _internal(); var proxy = _make_proxies({}, _internal(), ['set', 'has', 'delete_', 'keys', 'enumerate']); var methods = _make_proxies({}, _internal(), ['clear', 'getItem', 'setItem', 'removeItem', 'key']); proxy.get = function get(p, name) { return methods[name] || _internal().get(p, name); } this.localStorage = Proxy.create(proxy); })(); """, lambda f: lambda: self, dependencies=["runtime/internal/proxy"])
def go(): if self.readyState != self.OPEN: return if self.binaryType == "arraybuffer": uint8_array = self.runtime.context.locals.Uint8Array buffer = uint8_array.create( uint8_array, (v8.JSArray(list(bytearray(data))), )).buffer self.triggerEvent("message", MessageEvent(self.runtime, self.url, buffer))
def setup(self): self.pjs = PebbleKitJS(self, self.qemu, persist=self.persist_dir) self.context = v8.JSContext(extensions=self.pjs.get_extension_names()) with self.context: # Do some setup self.context.eval( "this.toString = function() { return '[object Window]'; }") self.context.eval("window = this;") self.pjs.do_post_setup()
def __init__(self, runtime): self.runtime = runtime self.extension = v8.JSExtension( self.runtime.ext_name("console"), """ console = new (function () { native function _internal_console(); _make_proxies(this, _internal_console(), ['log', 'warn', 'info', 'error']); })(); """, lambda f: lambda: self, dependencies=["runtime/internal/proxy"])
def __init__(self, runtime): self.extension = v8.JSExtension( runtime.ext_name("performance"), """ performance = new (function() { native function _time(); var start = _time(); this.now = function() { return (_time() - start) * 1000; }; })(); """, lambda f: lambda: time.time())
def __init__(self, runtime): self.runtime = runtime self.timers = {} self.counter = 1 self.extension = v8.JSExtension( self.runtime.ext_name('timers'), """ (function() { native function _timers(); _make_proxies(this, _timers(), ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval']); })(); """, lambda f: lambda: self, dependencies=["runtime/internal/proxy"])
def go(): try: token = self._get_timeline_token() result = requests.get(self.runtime.runner.urls.app_subscription_list, headers={'X-User-Token': token}) result.raise_for_status() subs = v8.JSArray(result.json()['topics']) except (requests.RequestException, TokenException) as e: if callable(failure): self.runtime.enqueue(failure, str(e)) except Exception: traceback.print_exc() if callable(failure): self.runtime.enqueue(failure, "Internal failure.") else: if callable(success): self.runtime.enqueue(success, subs)
def __init__(self, runtime): self._runtime = runtime self._runtime = runtime self.extension = v8.JSExtension(runtime.ext_name("navigator"), """ navigator = new (function() { native function _internal_location(); this.language = 'en-GB'; var location = _internal_location(); if(true) { // TODO: this should be a check on geolocation being enabled. this.geolocation = new (function() { _make_proxies(this, location, ['getCurrentPosition', 'watchPosition', 'clearWatch']); })(); } })(); """, lambda f: lambda: Geolocation(runtime), dependencies=["runtime/internal/proxy"])
def _do_send(self): self._sent = True req = self._session.prepare_request(self._request) try: if self.timeout: timeout = self.timeout / 1000.0 else: timeout = None self._response = self._session.send(req, timeout=timeout, verify=True) self.readyState = self.DONE self.status = self._response.status_code self.statusText = self._response.reason self.responseText = self._response.text if self.responseType == "json": self.response = self._response.json() elif self.responseType == "arraybuffer": self.response = v8.JSObject.create( self._runtime.context.locals.Uint8Array, (v8.JSArray( list(bytearray(self._response.content))), )).buffer else: self.response = self.responseText self._trigger_async_event("load", ProgressEvent, (self._runtime, )) except requests.exceptions.Timeout: self._trigger_async_event("timeout", ProgressEvent, (self._runtime, )) self.readyState = self.DONE except requests.exceptions.RequestException as e: self.status = 0 self.statusText = str(e) self.readyState = self.DONE finally: self._trigger_async_event("loadend", ProgressEvent, (self._runtime, )) self._trigger_async_event("readystatechange")
def _handle_message(self, tid, uuid, dictionary): if uuid != self.uuid: logger.warning("Discarded message for %s (expected %s)", uuid, self.uuid) self.pebble._send_message("APPLICATION_MESSAGE", struct.pack('<BB', 0x7F, tid)) # ACK return app_keys = dict(zip(self.app_keys.values(), self.app_keys.keys())) d = self.runtime.context.eval("({})") # This is kinda absurd. for k, v in dictionary.iteritems(): if isinstance(v, int): value = v elif isinstance(v, basestring): value = v elif isinstance(v, bytearray): value = v8.JSArray(list(v)) else: raise JSRuntimeException("?????") d[str(k)] = value if k in app_keys: d[str(app_keys[k])] = value e = events.Event(self.runtime, "AppMessage") e.payload = d self.triggerEvent("appmessage", e)
def __init__(self, runtime, pebble): self.extension = v8.JSExtension(runtime.ext_name("pebble"), """ Pebble = new (function() { native function _internal_pebble(); _make_proxies(this, _internal_pebble(), ['sendAppMessage', 'showSimpleNotificationOnPebble', 'getAccountToken', 'getWatchToken', 'addEventListener', 'removeEventListener', 'openURL', 'getTimelineToken', 'timelineSubscribe', 'timelineUnsubscribe', 'timelineSubscriptions', 'getActiveWatchInfo', 'appGlanceReload']); this.platform = 'pypkjs'; })(); """, lambda f: lambda: self, dependencies=["runtime/internal/proxy"]) self.blobdb = pebble.blobdb self.pebble = pebble.pebble self.runtime = runtime self.tid = 0 self.uuid = runtime.pbw.uuid self.app_keys = runtime.pbw.manifest['appKeys'] self.pending_acks = {} self.is_ready = False self._timeline_token = None self._appmessage = self.runtime.runner.appmessage self._appmessage_handlers = [] super(Pebble, self).__init__(runtime)
from .exceptions import JSRuntimeException event = v8.JSExtension( "runtime/event", """ Event = function(event_type, event_init_dict) { var self = this; this.stopPropagation = function() {}; this.stopImmediatePropagation = function() { self._aborted = true; } this.preventDefault = function() { self.defaultPrevented = true; } this.initEvent = function(event_type, bubbles, cancelable) { self.type = event_type; self.bubbles = bubbles; self.cancelable = cancelable }; if(!event_init_dict) event_init_dict = {}; this.type = event_type; this.bubbles = event_init_dict.bubbles || false; this.cancelable = event_init_dict.cancelable || false; this.defaultPrevented = false; this.target = null; this.currentTarget = null; this.eventPhase = 2; this._aborted = false; }; Event.NONE = 0; Event.CAPTURING_PHASE = 1; Event.AT_TARGET = 2; Event.BUBBLING_PHASE = 3; """) Event = lambda runtime, *args: v8.JSObject.create(runtime.context.locals.Event,
close_event = v8.JSExtension("runtime/events/ws", """ CloseEvent = function(eventInitDict) { Event.call(this, "close", eventInitDict); var wasClean = eventInitDict.wasClean; var code = eventInitDict.code; var reason = eventInitDict.reason; Object.defineProperties(this, { wasClean: { get: function() { return wasClean; }, enumerable: true, }, code: { get: function() { return code; }, enumerable: true, }, reason: { get: function() { return reason; }, enumerable: true, }, }); }; CloseEvent.prototype = Object.create(Event.prototype); CloseEvent.prototype.constructor = CloseEvent; MessageEvent = function(origin, data, eventInitDict) { Event.call(this, "message", eventInitDict); this.data = data; this.origin = origin; }; MessageEvent.prototype = Object.create(Event.prototype); MessageEvent.prototype.constructor = CloseEvent; """, dependencies=["runtime/event"])
def get(self, p, name): return self.storage.get(str(name), v8.JSNull())
def keys(self, p): return v8.JSArray(self.storage.keys())
from .safe_requests import NonlocalHTTPAdapter from .exceptions import JSRuntimeException progress_event = v8.JSExtension("runtime/events/progress", """ ProgressEvent = function(computable, loaded, total) { Event.call(this); computable = computable || false; loaded = loaded || 0; total = total || 0; Object.defineProperties(this, { lengthComputable: { get: function() { return computable; }, enumerable: true, }, loaded: { get: function() { return loaded; }, enumerable: true, }, total: { get: function() { return total; }, enumerable: true, }, }); } ProgressEvent.prototype = Object.create(Event.prototype); ProgressEvent.prototype.constructor = ProgressEvent; """, dependencies=["runtime/event"]) ProgressEvent = lambda runtime, *args: v8.JSObject.create( runtime.context.locals.ProgressEvent, args)
def enumerate(self): return v8.JSArray(self.storage.keys())
def key(self, index, *args): if len(self.storage) > index: return self.storage.keys()[index] else: return v8.JSNull()
from __future__ import absolute_import __author__ = 'katharine' import pypkjs.PyV8 as v8 import time import requests import pygeoip import os.path position = v8.JSExtension( "runtime/geolocation/position", """ Position = (function(coords, timestamp) { this.coords = coords; this.timestamp = timestamp; }); """) Position = lambda runtime, *args: v8.JSObject.create( runtime.context.locals.Position, args) coordinates = v8.JSExtension( "runtime/geolocation/coordinates", """ Coordinates = (function(long, lat, accuracy) { this.longitude = long this.latitude = lat this.accuracy = accuracy }); """) Coordinates = lambda runtime, *args: v8.JSObject.create( runtime.context.locals.Coordinates, args)
from .exceptions import JSRuntimeException logger = logging.getLogger('pypkjs.javascript.pebble') make_proxy_extension = v8.JSExtension( "runtime/internal/proxy", """ function _make_proxies(proxy, origin, names) { names.forEach(function(name) { proxy[name] = eval("(function " + name + "() { return origin[name].apply(origin, arguments); })"); }); return proxy; } function _make_properties(proxy, origin, names) { names.forEach(function(name) { Object.defineProperty(proxy, name, { configurable: false, enumerable: true, get: function() { return origin[name]; }, set: function(value) { origin[name] = value; } }); }); return proxy; } """) class JSRuntime(object): def __init__(self,