# HG changeset patch # User Goffi # Date 1276938930 -28800 # Node ID 783e9d6980ec708aa331f26ccdd7433457cf33d9 # Parent 50f1591c8fc64c90b71164f671215526e48b696e Couchsurfing plugin: first draft SàT core: adding additionnal menu method bridge: new methods getMenus, getMenuHelp and callMenu wix: new menu are added on startup CS plugin: login on CS diff -r 50f1591c8fc6 -r 783e9d6980ec frontends/sat_bridge_frontend/DBus.py --- a/frontends/sat_bridge_frontend/DBus.py Fri Jun 18 17:14:14 2010 +0800 +++ b/frontends/sat_bridge_frontend/DBus.py Sat Jun 19 17:15:30 2010 +0800 @@ -109,6 +109,18 @@ def confirmationAnswer(self, id, accepted, data): return self.db_req_iface.confirmationAnswer(id, accepted, data) + def getProgress(self, id): + return self.db_req_iface.getProgress(id) + + def getMenus(self): + return self.db_req_iface.getMenus() + + def getMenuHelp(self, category, name, type="NORMAL"): + return self.db_req_iface.getMenuHelp(category, name, type) + + def callMenu(self, category, name, type="NORMAL", profile_key='@DEFAULT@'): + return self.db_req_iface.callMenu(category, name, type, profile_key) + #methods from plugins def getRoomJoined(self, profile_key='@DEFAULT@'): return self.db_comm_iface.getRoomJoined(profile_key) @@ -151,8 +163,7 @@ def gatewayRegister(self, action, target, data): if data == None: - data = [('', '')] #XXX: we have to this awful hack because python dbus need to guess the signature + data = [('', '')] #XXX: we have to do this awful hack because python dbus need to guess the signature return self.db_req_iface.gatewayRegister(action, target, data) - def getProgress(self, id): - return self.db_req_iface.getProgress(id) + diff -r 50f1591c8fc6 -r 783e9d6980ec frontends/wix/main_window.py --- a/frontends/wix/main_window.py Fri Jun 18 17:14:14 2010 +0800 +++ b/frontends/wix/main_window.py Sat Jun 19 17:15:30 2010 +0800 @@ -76,9 +76,6 @@ self.chat_wins=ChatList(self) self.CreateStatusBar() - self.createMenus() - for i in range(self.menuBar.GetMenuCount()): - self.menuBar.EnableTop(i, False) #ToolBar self.tools=self.CreateToolBar() @@ -105,6 +102,11 @@ QuickApp.__init__(self) #self.plug_profile() #gof: + #menus + self.createMenus() + for i in range(self.menuBar.GetMenuCount()): + self.menuBar.EnableTop(i, False) + #profile panel self.profile_pan = ProfileManager(self) #self.profile_pan.Hide() #gof: @@ -149,6 +151,31 @@ self.menuBar.Append(communicationMenu,_("&Communication")) self.SetMenuBar(self.menuBar) + #additionals menus + #FIXME: do this in a more generic way (in quickapp) + add_menus = self.bridge.getMenus() + for menu in add_menus: + category,item,type = menu + assert(type=="NORMAL") #TODO: manage other types + menu_idx = self.menuBar.FindMenu(category) + current_menu = None + if menu_idx == wx.NOT_FOUND: + #the menu is new, we create it + current_menu = wx.Menu() + self.menuBar.Append(current_menu, category) + else: + current_menu = self.menuBar.GetMenu(menu_idx) + assert(current_menu != None) + item_id = wx.NewId() + help_string = self.bridge.getMenuHelp(category, item, type) + current_menu.Append(item_id, item, help = help_string) + #now we register the event + def event_answer(e): + id = self.bridge.callMenu(category, item, type) + self.current_action_ids.add(id) + wx.EVT_MENU(self, item_id, event_answer) + + #events wx.EVT_MENU(self, idCONNECT, self.onConnectRequest) wx.EVT_MENU(self, idDISCONNECT, self.onDisconnectRequest) diff -r 50f1591c8fc6 -r 783e9d6980ec plugins/plugin_misc_cs.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/plugin_misc_cs.py Sat Jun 19 17:15:30 2010 +0800 @@ -0,0 +1,110 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +""" +SAT plugin for managing xep-0045 +Copyright (C) 2009, 2010 Jérôme Poisson (goffi@goffi.org) + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +""" + +from logging import debug, info, warning, error +from twisted.words.xish import domish +from twisted.internet import protocol, defer, threads, reactor +from twisted.words.protocols.jabber import client, jid, xmlstream +from twisted.words.protocols.jabber import error as jab_error +from twisted.words.protocols.jabber.xmlstream import IQ +from twisted.web.client import getPage +#from twisted.web.http_headers import Headers +import os.path +import pdb +import random + +from zope.interface import implements + +from wokkel import disco, iwokkel, data_form +from tools.xml_tools import XMLTools +#from twisted.web.iweb import IBodyProducer +import urllib + + + + +PLUGIN_INFO = { +"name": "CouchSurfing plugin", +"import_name": "CS", +"type": "Misc", +"protocols": [], +"dependencies": [], +"main": "CS_Plugin", +"handler": "no", +"description": _(u"""This plugin allow to manage your CouchSurfing account throught your SàT frontend""") +} + +AGENT = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.3) Gecko/20100423 Ubuntu/10.04 (lucid) Firefox/3.6.3' + +class CS_Plugin(): + + params = """ + + + + + + + + + """ + + def __init__(self, host): + info(_("Plugin CS initialization")) + self.host = host + #parameters + host.memory.importParams(CS_Plugin.params) + #menu + host.importMenu(_("Plugin"), "CouchSurfing", self.menuSelected, help_string = _("Launch CoushSurfing mangement interface")) + self.session_cookies={} #TODO: delete cookies after a while + + def menuSelected(self, id, profile): + """Called when the couchsurfing menu item is selected""" + login = self.host.memory.getParamA("Login", "CouchSurfing", profile_key=profile) + password = self.host.memory.getParamA("Password", "CouchSurfing", profile_key=profile) + if not login or not password: + message_data={"reason": "uncomplete", "message":_(u"You have to fill your CouchSurfing login & password in parameters before using this interface")} + self.host.bridge.actionResult("ERROR", id, message_data) + return + + post_data = urllib.urlencode({'auth_login[un]':login,'auth_login[pw]':password,'auth_login[action]':'Login...'}) + + cookies = {} + d = getPage('http://www.couchsurfing.org/login.html', method='POST', postdata=post_data, headers={'Content-Type':'application/x-www-form-urlencoded'} , agent=AGENT, cookies=cookies) + #d = getPage('file:///home/goffi/tmp/CS_principale.html', method='POST', postdata=post_data, headers={'Content-Type':'application/x-www-form-urlencoded'} , agent=AGENT, cookies=cookies) + + + def connectionCB(html): + print 'Response received' + + d = getPage('http://www.couchsurfing.org/messages.html?message_status=inbox', agent=AGENT, cookies=cookies) + #d = getPage('file:///home/goffi/tmp/CS_inbox.html', agent=AGENT, cookies=cookies) + def toto(html): + print "cookies:",cookies + pdb.set_trace() + d.addBoth(toto) + d.addCallback(connectionCB) + + + self.host.bridge.actionResult("SUPPRESS", id, {}) + + + diff -r 50f1591c8fc6 -r 783e9d6980ec plugins/plugin_misc_tarot.py --- a/plugins/plugin_misc_tarot.py Fri Jun 18 17:14:14 2010 +0800 +++ b/plugins/plugin_misc_tarot.py Sat Jun 19 17:15:30 2010 +0800 @@ -34,10 +34,6 @@ from wokkel import disco, iwokkel, data_form from tools.xml_tools import XMLTools -from base64 import b64decode -from hashlib import sha1 -from time import sleep - try: from twisted.words.protocols.xmlstream import XMPPHandler except ImportError: diff -r 50f1591c8fc6 -r 783e9d6980ec plugins/plugin_xep_0077.py --- a/plugins/plugin_xep_0077.py Fri Jun 18 17:14:14 2010 +0800 +++ b/plugins/plugin_xep_0077.py Sat Jun 19 17:15:30 2010 +0800 @@ -61,7 +61,6 @@ except IndexError: info(_("No data form found")) #TODO: manage registration without data form - answer_data = {} answer_data={"reason": "unmanaged", "message":_("This gateway can't be managed by SàT, sorry :(")} answer_type = "ERROR" self.host.bridge.actionResult(answer_type, answer['id'], answer_data) diff -r 50f1591c8fc6 -r 783e9d6980ec sat.tac --- a/sat.tac Fri Jun 18 17:14:14 2010 +0800 +++ b/sat.tac Sat Jun 19 17:15:30 2010 +0800 @@ -327,6 +327,7 @@ self.__private_data = {} #used for internal callbacks (key = id) self.profiles = {} self.plugins = {} + self.menus = {} #used to know which new menus are wanted by plugins self.memory=Memory(self) self.server_features=[] #XXX: temp dic, need to be transfered into self.memory in the future @@ -357,6 +358,9 @@ self.bridge.register("launchAction", self.launchAction) self.bridge.register("confirmationAnswer", self.confirmationAnswer) self.bridge.register("getProgress", self.getProgress) + self.bridge.register("getMenus", self.getMenus) + self.bridge.register("getMenuHelp", self.getMenuHelp) + self.bridge.register("callMenu", self.callMenu) self._import_plugins() @@ -689,7 +693,7 @@ def confirmationAnswer(self, id, accepted, data): """Called by frontends to answer confirmation requests""" - debug (_("Received confirmation answer for id [%(id)s]: %(success)s") % {'id': id, 'success':u("accepted") if accepted else _("refused")}) + debug (_("Received confirmation answer for id [%(id)s]: %(success)s") % {'id': id, 'success':_("accepted") if accepted else _("refused")}) if not self.__waiting_conf.has_key(id): error (_("Received an unknown confirmation")) else: @@ -740,6 +744,46 @@ error(_("Trying to call unknown function")) return None + #Menus management + + def importMenu(self, category, name, callback, help_string = "", type = "NORMAL"): + """register a new menu for frontends + @param category: category of the menu + @param name: menu item entry + @param callback: method to be called when menuitem is selected""" + if self.menus.has_key((category,name)): + error ("Want to register a menu which already existe") + return + self.menus[(category,name,type)] = {'callback':callback, 'help_string':help_string, 'type':type} + + def getMenus(self): + """Return all menus registered""" + return self.menus.keys() + + def getMenuHelp(self, category, name, type="NORMAL"): + """return the help string of the menu""" + try: + return self.menus[(category,name,type)]['help_string'] + except KeyError: + error (_("Trying to access an unknown menu")) + return "" + + def callMenu(self, category, name, type="NORMAL", profile_key='@DEFAULT@'): + """return the help string of the menu""" + profile = self.memory.getProfileName(profile_key) + if not profile_key: + error (_('Non-exsitant profile')) + return "" + try: + id = self.get_next_id() + self.menus[(category,name,type)]['callback'](id, profile) + return id + except KeyError: + error (_("Trying to access an unknown menu")) + return "" + + + application = service.Application('SàT') service = SAT() service.setServiceParent(application) diff -r 50f1591c8fc6 -r 783e9d6980ec sat_bridge/DBus.py --- a/sat_bridge/DBus.py Fri Jun 18 17:14:14 2010 +0800 +++ b/sat_bridge/DBus.py Sat Jun 19 17:15:30 2010 +0800 @@ -248,6 +248,21 @@ #debug("Progress asked for %s", id) return self.cb["getProgress"](id) + @dbus.service.method(const_INT_PREFIX+const_REQ_SUFFIX, + in_signature='', out_signature='a(sss)') + def getMenus(self): + return self.cb["getMenus"]() + + @dbus.service.method(const_INT_PREFIX+const_REQ_SUFFIX, + in_signature='sss', out_signature='s') + def getMenuHelp(self, category, name, type="NORMAL"): + return self.cb["getMenuHelp"](category, name, type) + + @dbus.service.method(const_INT_PREFIX+const_REQ_SUFFIX, + in_signature='ssss', out_signature='s') + def callMenu(self, category, name, type, profile_key): + return self.cb["callMenu"](category, name, type, profile_key) + def __attribute_string(self, in_sign): i=0 idx=0