bridge: constructor and template improved, documentation added

This commit is contained in:
Goffi 2011-01-24 17:47:45 +01:00
commit 793e6d6c3d
4 changed files with 221 additions and 22 deletions

View file

@ -24,7 +24,6 @@ from bridge import Bridge
import dbus
import dbus.service
import dbus.mainloop.glib
import pdb
from logging import debug, info, error
const_INT_PREFIX = "org.goffi.SAT" #Interface prefix
@ -55,7 +54,7 @@ class DbusObject(dbus.service.Object):
@dbus.service.signal(const_INT_PREFIX+const_COMM_SUFFIX,
signature='ss')
def connection_error(self, profile, error_type):
def connection_error(self, error_type, profile):
debug("Connection_error signal")
@dbus.service.signal(const_INT_PREFIX+const_COMM_SUFFIX,
@ -142,7 +141,7 @@ class DbusObject(dbus.service.Object):
in_signature='s', out_signature='i')
def deleteProfile(self, name):
info ('Profile deletion asked')
return self.cb["deleteProfile"](str(name))
return self.cb["deleteProfile"](unicode(name))
@dbus.service.method(const_INT_PREFIX+const_COMM_SUFFIX,
in_signature='sssi', out_signature='s')
@ -163,7 +162,7 @@ class DbusObject(dbus.service.Object):
return self.cb["disconnect"](profile_key)
@dbus.service.method(const_INT_PREFIX+const_COMM_SUFFIX,
in_signature='', out_signature='b')
in_signature='s', out_signature='b')
def isConnected(self, profile_key='@DEFAULT@'):
info ("Connection status asked")
return self.cb["isConnected"](profile_key)

View file

@ -41,8 +41,9 @@ import sys
import os
from os import path
from optparse import OptionParser
from ConfigParser import RawConfigParser as Parser
from ConfigParser import SafeConfigParser as Parser
from ConfigParser import NoOptionError
import re
class ParseError(Exception):
@ -67,8 +68,49 @@ class Constructor:
value = None
function[option] = value
return function
def getDefault(self, name):
"""Return default values of a function in a dict
@param name: Name of the function to get
@return: dict, each key is the integer param number (no key if no default value)"""
default_dict={}
def_re = re.compile(r"param_(\d+)_default")
for option in self.bridge_template.options(name):
if option == 'doc_return':
default_dict['return'] = self.bridge_template.get(name, option)
continue
match = def_re.match(option)
if match:
try:
idx = int(match.group(1))
except ValueError:
raise ParseError("Invalid value [%s] for parameter number" % match.group(1))
default_dict[idx] = self.bridge_template.get(name, option)
return default_dict
def getArguments(self, signature):
def getArgumentsDoc(self, name):
"""Return documentation of arguments
@param name: Name of the function to get
@return: dict, each key is the integer param number (no key if no argument doc), value is a tuple (name, doc)"""
doc_dict={}
option_re = re.compile(r"doc_param_(\d+)")
value_re = re.compile(r"^(\w+): (.*)$", re.MULTILINE | re.DOTALL)
for option in self.bridge_template.options(name):
match = option_re.match(option)
if match:
try:
idx = int(match.group(1))
except ValueError:
raise ParseError("Invalid value [%s] for parameter number" % match.group(1))
value_match = value_re.match(self.bridge_template.get(name, option))
if not value_match:
raise ParseError("Invalid value for parameter doc [%i]" % idx)
doc_dict[idx]=(value_match.group(1),value_match.group(2))
return doc_dict
def getArguments(self, signature, name=None, default=None):
"""Return arguments to user given a signature
@param signature: signature in the short form (using s,a,i,b etc)
@return: list of arguments that correspond to a signature (e.g.: "sss" return "arg1, arg2, arg3")"""
@ -79,7 +121,10 @@ class Constructor:
if signature[i] not in ['b','y','n','i','x','q','u','t','d','s','a']:
raise ParseError("Unmanaged attribute type [%c]" % signature[i])
attr_string += ("" if idx==0 else ", ") + ("arg_%i" % idx)
attr_string += ("" if idx==0 else ", ") + ("%(name)s%(default)s" % {
'name':name[idx][0] if (name and name.has_key(idx)) else "arg_%i" % idx,
'default':"="+default[idx] if (default and default.has_key(idx)) else ''
}) #give arg_1, arg2, etc or name1, name2=default, etc
idx+=1
if signature[i] == 'a':
@ -88,6 +133,7 @@ class Constructor:
i+=1
continue #we have a simple type for the array
opening_car = signature[i]
assert(opening_car in ['{','('])
closing_car = '}' if opening_car == '{' else ')'
opening_count = 1
while (True): #we have a dict or a list of tuples
@ -123,12 +169,14 @@ class DbusConstructor(Constructor):
for section in sections:
function = self.getValues(section)
print ("Adding %s %s" % (section, function["type"]))
default = self.getDefault(section)
arg_doc = self.getArgumentsDoc(section)
completion = {
'sig_in':function['sig_in'] or '',
'sig_out':function['sig_out'] or '',
'category':'REQ' if function['category'] == 'request' else 'COMM',
'name':section,
'args':self.getArguments(function['sig_in'])
'args':self.getArguments(function['sig_in'], name=arg_doc, default=default, )
}
if function["type"] == "signal":
@ -146,11 +194,12 @@ class DbusConstructor(Constructor):
elif function["type"] == "method":
completion['debug'] = "" if not self.options.debug else 'debug ("%s")\n%s' % (section,8*' ')
completion['args_nodefault'] = self.getArguments(function['sig_in'], name=arg_doc)
methods_part.append("""\
@dbus.service.method(const_INT_PREFIX+const_%(category)s_SUFFIX,
in_signature='%(sig_in)s', out_signature='%(sig_out)s')
def %(name)s(self, %(args)s):
%(debug)sreturn self.cb["%(name)s"](%(args)s)
%(debug)sreturn self.cb["%(name)s"](%(args_nodefault)s)
""" % completion)
#at this point, signals_part, methods_part and direct_calls should be filled,

View file

@ -1,3 +1,7 @@
[DEFAULT]
doc_profile=profile: Name of the profile.
doc_profile_key=profile_key: Profile key which can be either a magic (eg: @DEFAULT@) or the name of an existing profile.
;signals
[connected]
@ -5,84 +9,140 @@ type=signal
category=communication
sig_in=s
doc=Connection is done
doc_param_0=%(doc_profile)s
[disconnected]
type=signal
category=communication
sig_in=s
doc=Connection is finished or lost
doc_param_0=%(doc_profile)s
[connection_error]
type=signal
category=communication
sig_in=ss
doc=Something went wront with the connection
doc_param_0=error_type: Why the connection got wrong, can be
- AUTH_ERROR: Authentification error
doc_param_1=%(doc_profile)s
[newContact]
type=signal
category=communication
sig_in=sa{ss}ass
doc=New contact received in roster
doc_param_0=contact: JID from who the message is comming
doc_param_1=attributes: Dictionary of attributes where keys are:
- name: name of the contact
- to: "True" if the contact give its presence information to us
- from: "True" if contact is registred to our presence information
- ask: "True" is subscription is pending
doc_param_2=groups: Roster's groups where the contact is
doc_param_3=%(doc_profile)s
[newMessage]
type=signal
category=communication
sig_in=sssss
doc=A message has been received
doc_param_0=from_jid: JID where the message is comming from
doc_param_1=message: Message itself
doc_param_2=mess_type: Type of the message (cf RFC 3921 #2.1.1)
doc_param_3=to_jid: JID where the message must be sent
doc_param_4=%(doc_profile)s
[newAlert]
type=signal
category=communication
sig_in=ssss
doc=A message has been received
doc=A new alert happened
doc_param_0=message: Body of the alert
doc_param_1=title: Title of the alert
doc_param_2=alert_type: Type of the alert, can be:
- INFO: Informative message
- ERROR: something went wrong
doc_param_3=%(doc_profile)s
[presenceUpdate]
type=signal
category=communication
sig_in=ssia{ss}s
doc=Somebody changed his presence informations.
doc_param_0=entity: JID from which we have presence informations
doc_param_1=show: availability status (see RFC 3921 #2.2.2.1)
doc_param_2=priority: Priority level of the ressource (see RFC 3921 #2.2.2.3)
doc_param_3=statuses: Natural language description of the availability status (see RFC 3921 #2.2.2.2)
doc_param_4=%(doc_profile)s
[subscribe]
type=signal
category=communication
sig_in=sss
doc=Somebody wants to be added in roster list
doc=Somebody wants to be added in roster
doc_param_0=sub_type: Subscription states (see RFC 3921 #9)
doc_param_1=entity: JID from which the subscription is coming
doc_param_2=%(doc_profile)s
[paramUpdate]
type=signal
category=communication
sig_in=ssss
doc=A parameter has been changed
doc_param_0=name: Name of the updated parameter
doc_param_1=value: New value of the parameter
doc_param_2=category: Category of the updated parameter
doc_param_3=%(doc_profile)s
[contactDeleted]
type=signal
category=communication
sig_in=ss
doc=A contact has been supressed from roster list
doc=A contact has been supressed from roster
doc_param_0=entity: JID of the contact removed from roster
doc_param_1=%(doc_profile)s
[askConfirmation]
type=signal
category=request
sig_in=ssa{ss}
doc=A confirmation is needed for an action
doc_param_0=conf_type: Type of the confirmation, can be:
- YES/NO: A question which need a yes or no answer
- FILE_TRANSFERT: A confirmation is needed before transfering a file
doc_param_1=id: Id of the confirmation query
doc_param_2=data: conf_type dependent data
[actionResult]
type=signal
category=request
sig_in=ssa{ss}
doc=Requested result of an action
doc_param_0=answer_type: Type of the answer, can be:
- SUPPRESS: The action is managed, the id MUST be removed from queue
- XMLUI: A SàT XMLUI interface is sent
- ERROR: Something went wrong when doing the action
- RESULT: General result, interpretation depend of the action
doc_param_1=id: Id of the action
doc_param_2=data: answer_type specific data
[actionResultExt]
type=signal
category=request
sig_in=ssa{sa{ss}}
doc=Requested result of an action (Extended)
doc_param_0=answer_type: Same as for [actionResult] but with the following additional one:
- DICT_DICT: As RESULT, but returned as a dictionary of dictionary
doc_param_1=id: Id of the action
doc_param_2=data: answer_type specific data
[updatedValue]
type=signal
category=request
sig_in=sa{ss}
doc=A value has been updated
doc_param_0=name: Name of the updated value
doc_param_1=value: New value
;methods
@ -99,6 +159,7 @@ category=request
sig_in=s
sig_out=s
doc=Get real profile name from profile key
doc_param_0=%(doc_profile_key)s
[getProfilesList]
type=method
@ -113,6 +174,10 @@ category=request
sig_in=s
sig_out=i
doc=Create a new profile
doc_param_0=%(doc_profile)s
doc_return=status of the creation:
- 0: Profile created
- 1: The profile name already exists
[deleteProfile]
type=method
@ -120,13 +185,23 @@ category=request
sig_in=s
sig_out=i
doc=Delete a profile
doc_param_0=%(doc_profile)s
doc_return=status of the deletion:
- 0: Profile deleted
- 1: The profile doesn't exists
[registerNewAccount]
deprecated=
type=method
category=communication
sig_in=sssi
sig_out=s
param_3_default=5222
doc=Register a new account on a given server
doc_param_0=login: login of the account
doc_param_1=password: password of the account
doc_param_2=host: host of the server to register to
doc_param_3=port: port of the server to register to
[connect]
type=method
@ -135,6 +210,7 @@ sig_in=s
sig_out=
param_0_default="@DEFAULT@"
doc=Connect a profile
doc_param_0=%(doc_profile_key)s
[disconnect]
type=method
@ -143,14 +219,16 @@ sig_in=s
sig_out=
param_0_default="@DEFAULT@"
doc=Disconnect a profile
doc_param_0=%(doc_profile_key)s
[isConnected]
type=method
category=communication
sig_in=
sig_in=s
sig_out=b
param_0_default="@DEFAULT@"
doc=Tell if a profile is connected
doc_param_0=%(doc_profile_key)s
[getContacts]
type=method
@ -159,6 +237,11 @@ sig_in=s
sig_out=a(sa{ss}as)
param_0_default="@DEFAULT@"
doc=Return informations about all contacts
doc_param_0=%(doc_profile_key)s
doc_return=array of tuples with the following values:
- JID of the contact
- list of attributes as in [newContact]
- groups where the contact is
[getPresenceStatus]
type=method
@ -167,6 +250,9 @@ sig_in=s
sig_out=a{sa{s(sia{ss})}}
param_0_default="@DEFAULT@"
doc=Return presence informations of all contacts
doc_param_0=%(doc_profile_key)s
doc_return=Dict of presence with bare JID of contact as key, and value as follow:
A dict where key is the resource and the value is a tuple with (show, priority, statuses) as for [presenceUpdate]
[getWaitingSub]
type=method
@ -175,22 +261,40 @@ sig_in=s
sig_out=a{ss}
param_0_default="@DEFAULT@"
doc=Get subscription requests in queue
doc_param_0=%(doc_profile_key)s
doc_return=Dict where contact JID is the key, and value is the subscription type
[sendMessage]
type=method
category=communication
sig_in=sssss
sig_out=
param_2_default=""
param_3_default="chat"
param_4_default="@DEFAULT@"
doc=Send a message
doc_param_0=to_jid: JID of the recipient
doc_param_1=message: body of the message
doc_param_2=subject: Subject of the message ("" if no subject)
doc_param_3=mess_type: Type of the message (cf RFC 3921 #2.1.1)
doc_param_4=%(doc_profile_key)s
[setPresence]
type=method
category=communication
sig_in=ssia{ss}s
sig_out=
param_0_default=""
param_1_default=""
param_2_default=0
param_3_default={}
param_4_default="@DEFAULT@"
doc=Set presence information for the profile
doc_param_0=to_jid: the JID to who we send the presence data (emtpy string for broadcast)
doc_param_1=show: as for [presenceUpdate]
doc_param_2=priority: as for [presenceUpdate]
doc_param_3=statuses: as for [presenceUpdate]
doc_param_4=%(doc_profile_key)s
[subscription]
type=method
@ -199,6 +303,9 @@ sig_in=sss
sig_out=
param_2_default="@DEFAULT@"
doc=Send subscription request/answer to a contact
doc_param_0=sub_type: as for [subscribe]
doc_param_1=entity: as for [subscribe]
doc_param_2=%(doc_profile_key)s
[setParam]
type=method
@ -207,6 +314,10 @@ sig_in=ssss
sig_out=
param_3_default="@DEFAULT@"
doc=Change a parameter
doc_param_0=name: Name of the parameter to change
doc_param_1=value: New Value of the parameter
doc_param_2=category: Category of the parameter to change
doc_param_3=%(doc_profile_key)s
[getParamA]
type=method
@ -215,6 +326,9 @@ sig_in=sss
sig_out=s
param_2_default="@DEFAULT@"
doc=Helper method to get a parameter's attribute
doc_param_0=name: as for [setParam]
doc_param_1=category: as for [setParam]
doc_param_2=%(doc_profile_key)s
[getParamsUI]
type=method
@ -223,6 +337,7 @@ sig_in=s
sig_out=s
param_0_default="@DEFAULT@"
doc=Return a SàT XMLUI for parameters
doc_param_0=%(doc_profile_key)s
[getParams]
type=method
@ -231,6 +346,7 @@ sig_in=s
sig_out=s
param_0_default="@DEFAULT@"
doc=Return XML of parameters
doc_param_0=%(doc_profile_key)s
[getParamsForCategory]
type=method
@ -238,7 +354,9 @@ category=communication
sig_in=ss
sig_out=s
param_1_default="@DEFAULT@"
doc=Return a xml of all params in a category
doc=Return a xml of all params in a category
doc_param_0=category: Category to get
doc_param_1=%(doc_profile_key)s
[getParamsCategories]
type=method
@ -246,6 +364,7 @@ category=communication
sig_in=
sig_out=as
doc=Get all categories currently existing in parameters
doc_return=list of categories
[getHistory]
type=method
@ -253,6 +372,10 @@ category=communication
sig_in=ssi
sig_out=a{i(ss)}
doc=Get history of a communication between two entities
doc_param_0=from_jid: source JID
doc_param_1=to_jid: dest JID
doc_param_2=size: size of the history (0 for the whole history)
doc_return=Dict where key is timestamp (seconds this the Epoch), and value is a tuple (from_jid, to_jid)
[addContact]
type=method
@ -260,7 +383,9 @@ category=communication
sig_in=ss
sig_out=
param_1_default="@DEFAULT@"
doc=Add a contact to profile's roster list
doc=Add a contact to profile's roster
doc_param_0=entity: JID to add to roster
doc_param_1=%(doc_profile_key)s
[delContact]
type=method
@ -268,7 +393,9 @@ category=communication
sig_in=ss
sig_out=
param_1_default="@DEFAULT@"
doc=Remove a contact from profile's roster list
doc=Remove a contact from profile's roster
doc_param_0=entity: JID to remove from roster
doc_param_1=%(doc_profile_key)s
[launchAction]
type=method
@ -277,6 +404,10 @@ sig_in=sa{ss}s
sig_out=s
param_2_default="@DEFAULT@"
doc=Launch a specific action
doc_param_0=action_type: type of the action which can be:
- button: A button is pushed
doc_param_1=data: action_type dependant data
doc_param_2=%(doc_profile_key)s
[confirmationAnswer]
type=method
@ -284,6 +415,9 @@ category=request
sig_in=sba{ss}
sig_out=
doc=Give answer to a confirmation request
doc_param_0=id: id of the confirmation request
doc_param_1=accepted: True if the action is confirmed
doc_param_2=data: action specific data
[getProgress]
type=method
@ -291,6 +425,10 @@ category=request
sig_in=s
sig_out=a{ss}
doc=Get progress information for an action
doc_param_0=id: id of the progression status
doc_return=dict with progress information:
- position: current position
- size: end position
[getMenus]
type=method
@ -298,6 +436,11 @@ category=request
sig_in=
sig_out=a(sss)
doc=Get all additional menus
doc_return=list of tuple with the following value:
- category: Category of the menu
- name: Name of the menu
- menu_type: Type which can be:
* NORMAL: Classical application menu
[getMenuHelp]
type=method
@ -305,7 +448,11 @@ category=request
sig_in=sss
sig_out=s
param_2="NORMAL"
doc=Get help informationd for a menu
doc=Get help information for a menu
doc_param_0=category: Category of the menu
doc_param_1=name: Name of the menu
doc_param_2=menu_type: Type of the menu as in [getMenus] return value
doc_return=Help string
[callMenu]
type=method
@ -313,4 +460,8 @@ category=request
sig_in=ssss
sig_out=s
doc=Execute action associated with a menu
doc_param_0=category: as in [getMenuHelp]
doc_param_1=name: as in [getMenuHelp]
doc_param_2=menu_type: as in [getMenuHelp]
doc_param_3=%(doc_profile_key)s
doc_return=return an actionId or the empty string if something went wrong

View file

@ -108,7 +108,7 @@ class SatXMPPClient(client.XMPPClient):
def initializationFailed(self, reason):
print ("initializationFailed: %s" % reason)
self.host_app.bridge.connection_error(self.profile,"AUTH_ERROR")
self.host_app.bridge.connection_error("AUTH_ERROR", self.profile)
try:
client.XMPPClient.initializationFailed(self, reason)
except:
@ -793,7 +793,7 @@ class SAT(service.Service):
return ""
def callMenu(self, category, name, type="NORMAL", profile_key='@DEFAULT@'):
"""return the help string of the menu"""
"""return the id of the action"""
profile = self.memory.getProfileName(profile_key)
if not profile_key:
error (_('Non-exsitant profile'))