#!/usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Sugar interface for Enyo JavaScript framework
|
|
|
|
import logging
|
|
import json
|
|
import inspect
|
|
|
|
|
|
class Enyo:
|
|
"""Class to handle communication with Enyo"""
|
|
|
|
def __init__(self, webview):
|
|
"""Constructor: link to the WebKit widget"""
|
|
self.webview = webview
|
|
self.handlers = {}
|
|
self.webview.connect("console-message", self._message_emitted)
|
|
|
|
def connect(self, name, callback):
|
|
"""Add a new handler for an event"""
|
|
self.handlers[name] = callback
|
|
|
|
def send_message(self, name, args=None):
|
|
"""Send a message to Enyo"""
|
|
script = "enyo.Sugar.sendMessage('"+name+"', "
|
|
if not args is None:
|
|
value = "'"+self.json_encode(args)+"'"
|
|
else:
|
|
value = "null"
|
|
script = script+value+")"
|
|
logging.warning("sugar://"+name+"/"+value)
|
|
return self.webview.execute_script(script)
|
|
|
|
def _message_emitted(self, widget, value, line, source):
|
|
"""Raised when a message from Enyo has been received"""
|
|
# Only consider prefixed message
|
|
prefix = "enyo://"
|
|
if not value.startswith(prefix):
|
|
return False
|
|
|
|
# Get name
|
|
prefixlen = len(prefix)
|
|
size = value[prefixlen:prefixlen+value[prefixlen:].index("/")]
|
|
start = prefixlen+1+len(size)
|
|
name = value[start:start+int(size)]
|
|
|
|
# Get param
|
|
start = start + len(name)+1
|
|
size = value[start:start+value[start:].index("/")]
|
|
if int(size) == 0:
|
|
args = None
|
|
else:
|
|
start = start+1+len(size)
|
|
args = value[start:]
|
|
|
|
# Call handler if exist
|
|
logging.warning(value);
|
|
if name in self.handlers:
|
|
callback = self.handlers[name]
|
|
if args:
|
|
callback(json.loads(args))
|
|
else:
|
|
callback(None)
|
|
|
|
return True
|
|
|
|
def json_encode(self, obj):
|
|
"""Encode object as a JSON string"""
|
|
try:
|
|
result = json.dumps(obj)
|
|
except TypeError:
|
|
result = "{"
|
|
first = True
|
|
for name in dir(obj):
|
|
value = getattr(obj, name)
|
|
if not name.startswith('__') and not inspect.ismethod(value) and not inspect.isroutine(value) and not inspect.isbuiltin(value) and not isinstance(value, obj.__class__):
|
|
if not first:
|
|
result = result + ', '
|
|
else:
|
|
first = False
|
|
result = result + '"'+name+'": '
|
|
result = result + self.json_encode(value)
|
|
result = result + "}"
|
|
return result
|
|
|
|
def json_decode(self, str):
|
|
"""Decode JSON string as object"""
|
|
return json.loads(str)
|