Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implemented most of the Python-JS bridge

  • Loading branch information...
commit bf4767e25d5a5aff231a59bcdd6378eb7a38a428 1 parent c770614
@kkris kkris authored
View
42 src/data/common/core/melange.js
@@ -0,0 +1,42 @@
+var Widget = new Class({
+
+ initialize: function(id) {
+ this.id = id;
+ this.callbacks = {};
+ this.socket = new WebSocket('ws://127.0.0.1:8086');
+
+ this.socket.onopen = function(){
+ var msg = {type: 'init', id: this.id};
+ this.socket.send(JSON.encode(msg));
+ }.bind(this);
+
+ this.socket.onmessage = function(e){
+ var data = JSON.decode(e.data);
+
+ if(data.type == 'init'){
+ for(i = 0; i < data.methods.length; i++){
+ method = data.methods[i];
+ this[method] = function(arguments, cb){
+ this.callRemote(method, arguments, cb);
+ }
+ }
+ }
+ else if(data.type == 'call'){
+ this.callbacks[data.callback_id](data.arguments);
+ }
+
+ }.bind(this);
+ },
+
+ callRemote: function(methodName, arguments, cb){
+ var callback_id = '' + new Date().getTime();
+ this.callbacks[callback_id] = cb;
+ var msg = {type: 'call',
+ method: methodName,
+ callback_id: callback_id,
+ arguments: arguments};
+
+ this.socket.send(JSON.encode(msg));
+ }
+
+});
View
15 src/melange.py
@@ -81,6 +81,10 @@ def __init__(self):
self.themes.append(MelangeTheme(path, name))
+ #self.available_widgets = {}
+ #for name, path in yield_available_widgets():
+ # self.available_widgets[name] = path
+
self.widgets = {}
@@ -93,7 +97,7 @@ def __init__(self):
for name, path in yield_available_widgets():
- if name == 'org.cream.melange.CalculatorWidget':
+ if name == 'org.cream.melange.widget.Example':
widget = Widget(name, path, self.themes)
self.widgets[name] = widget
@@ -110,13 +114,14 @@ def run_servers(self):
- def on_client_connected(self, server, widget_api):
+ def on_client_connected(self, server, websocket_handler):
- def init_api(api):
+ def init_api(handler):
- self.widgets[api.id].init_api(api)
+ widget = self.widgets[handler.id]
+ widget.init_api(handler)
- widget_api.connect('initialized', init_api)
+ websocket_handler.connect('initialized', init_api)
View
73 src/melange/api.py
@@ -16,6 +16,9 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
# MA 02110-1301, USA.
+import os
+import sys
+import imp
import json
from gi.repository import GObject as gobject
@@ -23,24 +26,43 @@
from melange.websocket import WebSocket
+APIS = {}
-class WidgetApi(WebSocket, gobject.GObject):
+
+
+def import_api_file(path, widget_id):
+
+ api_file = os.path.join(path, '__init__.py')
+ if os.path.isfile(api_file):
+ sys.path.insert(0, path)
+ with open(api_file) as file_handle:
+ imp.load_module(
+ widget_id,
+ file_handle,
+ api_file,
+ ('.py', 'r', imp.PY_SOURCE)
+ )
+
+
+class WebSocketHandler(WebSocket, gobject.GObject):
__gsignals__ = {
- 'initialized': (gobject.SignalFlags.RUN_LAST, None, (object,))
+ 'initialized': (gobject.SignalFlags.RUN_LAST, None, ())
}
def __init__(self, client):
- WebSocket.__init_(self, client)
+ WebSocket.__init__(self, client)
gobject.GObject.__init__(self)
self.id = None
+ self.path = None
self.api = None
def onmessage(self, data):
+ print 'Got', data
data = json.loads(data)
self.dispatch(data)
@@ -51,16 +73,26 @@ def dispatch(self, data):
self.init(data)
- def init(self, data):
- # The JS-Side requests to be initialized!
- self.id = data['id']
+ def load_api(self, path):
+ self.path = path
- self.emit('initialized')
+ if self.id not in APIS:
+ import_api_file(self.path, self.id)
+
+ self.api = APIS[self.id]()
+
+ response = {'type': 'init', 'methods': self.api.get_exposed_methods()}
+ self.send(json.dumps(response))
+ def init(self, data):
+ # The JS-Side requests to be initialized!
+
+ self.id = data['id']
+ self.emit('initialized')
@@ -69,3 +101,30 @@ def call_remote(self, data):
# The JS-Side wants a method called, here you go, Mr. Widget.
pass
+
+
+
+class API(object):
+
+ def get_exposed_methods(self):
+ methods = []
+ for attr in dir(self):
+ if hasattr(getattr(self, attr), '_exposed'):
+ methods.append(attr)
+ return methods
+
+
+
+def expose(func):
+
+ func._exposed = True
+ return func
+
+
+
+def register(widget_id):
+
+ def wrapper(api_cls):
+ APIS[widget_id] = api_cls
+ return api_cls
+ return wrapper
View
2  src/melange/server/websocket.py
@@ -23,7 +23,7 @@
from gi.repository import GObject as gobject
-from melange.api import WidgetApi
+from melange.api import WebSocketHandler
from melange.common import WEBSOCKET_HOST, WEBSOCKET_PORT
View
9 src/melange/widget.py
@@ -51,7 +51,7 @@ def __init__(self, id_, path, themes):
self.id = id_
self.path = path
self.themes = themes
- self.api = None
+ self.websocket_handler = None
#self.config = Configuration(self.id)
@@ -89,11 +89,14 @@ def selected_theme(self):
- def init_api(self, api):
+ def init_api(self, handler):
'''
Called when the websocket is initialized and ready to roll.
'''
- self.api = api
+
+ self.websocket_handler = handler
+ self.websocket_handler.load_api(self.path)
+
Please sign in to comment.
Something went wrong with that request. Please try again.