misc bugfixes

- wix: added forgotten profile in gateways management
- xml_tools: removed XMLClass to the 2 methods as a direct methods
- plugin_xep_100 (gateways discovery): added error callback
This commit is contained in:
Goffi 2010-06-22 13:58:53 +08:00
commit 2f2594de6b
10 changed files with 112 additions and 91 deletions

View file

@ -156,7 +156,7 @@ class QuickApp():
return return
debug(_("Connected")) debug(_("Connected"))
self.setStatusOnline(True) self.setStatusOnline(True)
self.bridge.joinMUC('conference.necton2.int', 'test', self.profiles[self.profile]['whoami'].node, self.profile) #gof: #self.bridge.joinMUC('conference.necton2.int', 'test', self.profiles[self.profile]['whoami'].node, self.profile) #gof:
def disconnected(self, profile): def disconnected(self, profile):

View file

@ -33,7 +33,7 @@ CARD_HEIGHT = 136
MIN_WIDTH = 950 #Minimum size of the panel MIN_WIDTH = 950 #Minimum size of the panel
MIN_HEIGHT = 500 MIN_HEIGHT = 500
suits_order = ['pique', 'coeur', 'trefle', 'carreau', 'atout'] #I have swith the usual order 'trefle' and 'carreau' because card are more easy to see if suit colour change (black, red, black, red) suits_order = ['pique', 'coeur', 'trefle', 'carreau', 'atout'] #I have switched the usual order 'trefle' and 'carreau' because card are more easy to see if suit colour change (black, red, black, red)
values_order = map(str,range(1,11))+["valet","cavalier","dame","roi"] values_order = map(str,range(1,11))+["valet","cavalier","dame","roi"]
class Card(): class Card():

View file

@ -105,7 +105,7 @@ class GatewaysManager(wx.Frame):
"""Open the gateway manager on given server""" """Open the gateway manager on given server"""
server = self.ext_server_text.GetValue() server = self.ext_server_text.GetValue()
debug(_("Opening gateways manager on [%s]") % server) debug(_("Opening gateways manager on [%s]") % server)
id = self.host.bridge.findGateways(server) id = self.host.bridge.findGateways(server, self.host.profile)
self.host.current_action_ids.add(id) self.host.current_action_ids.add(id)
self.host.current_action_ids_cb[id] = self.host.onGatewaysFound self.host.current_action_ids_cb[id] = self.host.onGatewaysFound
self.MakeModal(False) self.MakeModal(False)
@ -157,7 +157,7 @@ class GatewaysManager(wx.Frame):
def register_cb(event): def register_cb(event):
"""Called when register button is clicked""" """Called when register button is clicked"""
gateway_jid = event.GetEventObject().gateway_jid gateway_jid = event.GetEventObject().gateway_jid
id = self.host.bridge.in_band_register(gateway_jid) id = self.host.bridge.in_band_register(gateway_jid, self.host.profile)
self.host.current_action_ids.add(id) self.host.current_action_ids.add(id)
self.MakeModal(False) self.MakeModal(False)
self.Destroy() self.Destroy()
@ -165,7 +165,7 @@ class GatewaysManager(wx.Frame):
def unregister_cb(event): def unregister_cb(event):
"""Called when unregister button is clicked""" """Called when unregister button is clicked"""
gateway_jid = event.GetEventObject().gateway_jid gateway_jid = event.GetEventObject().gateway_jid
id = self.host.bridge.gatewayRegister("CANCEL",gateway_jid, None) id = self.host.bridge.gatewayRegister("CANCEL",gateway_jid, None, self.host.profile)
self.host.current_action_ids.add(id) self.host.current_action_ids.add(id)
self.MakeModal(False) self.MakeModal(False)
self.Destroy() self.Destroy()

View file

@ -452,7 +452,7 @@ class MainWindow(wx.Frame, QuickApp):
def onFindGateways(self, e): def onFindGateways(self, e):
debug(_("Find Gateways request")) debug(_("Find Gateways request"))
id = self.bridge.findGateways(self.profiles[self.profile]['whoami'].domain) id = self.bridge.findGateways(self.profiles[self.profile]['whoami'].domain, self.profile)
self.current_action_ids.add(id) self.current_action_ids.add(id)
self.current_action_ids_cb[id] = self.onGatewaysFound self.current_action_ids_cb[id] = self.onGatewaysFound

View file

@ -26,7 +26,6 @@ from twisted.words.protocols.jabber import client, jid, xmlstream
from twisted.words.protocols.jabber import error as jab_error from twisted.words.protocols.jabber import error as jab_error
from twisted.words.protocols.jabber.xmlstream import IQ from twisted.words.protocols.jabber.xmlstream import IQ
from twisted.web.client import getPage from twisted.web.client import getPage
#from twisted.web.http_headers import Headers
import os.path import os.path
import pdb import pdb
import random import random
@ -34,10 +33,10 @@ import random
from zope.interface import implements from zope.interface import implements
from wokkel import disco, iwokkel, data_form from wokkel import disco, iwokkel, data_form
from tools.xml_tools import XMLTools from tools.xml_tools import dataForm2xml
#from twisted.web.iweb import IBodyProducer
import urllib import urllib
from BeautifulSoup import BeautifulSoup
@ -74,7 +73,13 @@ class CS_Plugin():
host.memory.importParams(CS_Plugin.params) host.memory.importParams(CS_Plugin.params)
#menu #menu
host.importMenu(_("Plugin"), "CouchSurfing", self.menuSelected, help_string = _("Launch CoushSurfing mangement interface")) host.importMenu(_("Plugin"), "CouchSurfing", self.menuSelected, help_string = _("Launch CoushSurfing mangement interface"))
self.session_cookies={} #TODO: delete cookies after a while self.data={} #TODO: delete cookies/data after a while
def erroCB(self, e, id):
"""Called when something is going wrong when contacting CS website"""
message_data={"reason": "connection error", "message":_(u"Impossible to contact CS website, please check your login/password, connection or try again later")}
self.host.bridge.actionResult("ERROR", id, message_data)
def menuSelected(self, id, profile): def menuSelected(self, id, profile):
"""Called when the couchsurfing menu item is selected""" """Called when the couchsurfing menu item is selected"""
@ -87,24 +92,36 @@ class CS_Plugin():
post_data = urllib.urlencode({'auth_login[un]':login,'auth_login[pw]':password,'auth_login[action]':'Login...'}) post_data = urllib.urlencode({'auth_login[un]':login,'auth_login[pw]':password,'auth_login[action]':'Login...'})
cookies = {} self.data[profile] = {'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): def connectionCB(html):
print 'Response received' print 'Response received'
soup = self.data[profile]['soup'] = BeautifulSoup(html)
user_nick = soup.find('a','item_link',href='/home.html').contents[0]
user_name = soup.html.head.title.string.split(' - ')[1]
unread_messages = int(soup.find('div','item_bubble').a.string)
form_xml = """
<form>
<elem type='text' value='Welcome %(name)s, you have %(nb_message)i unread messages'/>
</form>
""" % {'name':user_name, 'nb_message':unread_messages}
self.host.bridge.actionResult("FORM", id, {"type":"window", "xml":form_xml})
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): #d = getPage('http://www.couchsurfing.org/messages.html?message_status=inbox', agent=AGENT, cookies=self.session_cookies[profile])
print "cookies:",cookies
pdb.set_trace() #tmp
d.addBoth(toto) f = open('/home/goffi/tmp/CS_principale.html','r')
html = f.read()
connectionCB(html)
"""d = getPage('http://www.couchsurfing.org/login.html', method='POST', postdata=post_data, headers={'Content-Type':'application/x-www-form-urlencoded'} , agent=AGENT, cookies=self.data[profile]['cookies'])
d.addCallback(connectionCB) d.addCallback(connectionCB)
d.addErrback(self.erroCB, id)"""
self.host.bridge.actionResult("SUPPRESS", id, {}) #self.host.bridge.actionResult("SUPPRESS", id, {})

View file

@ -32,7 +32,7 @@ import random
from zope.interface import implements from zope.interface import implements
from wokkel import disco, iwokkel, data_form from wokkel import disco, iwokkel, data_form
from tools.xml_tools import XMLTools from tools.xml_tools import dataForm2xml
try: try:
from twisted.words.protocols.xmlstream import XMPPHandler from twisted.words.protocols.xmlstream import XMPPHandler
@ -55,7 +55,7 @@ PLUGIN_INFO = {
"description": _("""Implementation of Tarot card game""") "description": _("""Implementation of Tarot card game""")
} }
suits_order = ['pique', 'coeur', 'trefle', 'carreau', 'atout'] #I have swith the usual order 'trefle' and 'carreau' because card are more easy to see if suit colour change (black, red, black, red) suits_order = ['pique', 'coeur', 'trefle', 'carreau', 'atout'] #I have switched the usual order 'trefle' and 'carreau' because card are more easy to see if suit colour change (black, red, black, red)
values_order = map(str,range(1,11))+["valet","cavalier","dame","roi"] values_order = map(str,range(1,11))+["valet","cavalier","dame","roi"]
class Card(): class Card():
@ -591,7 +591,7 @@ class Tarot():
elif elt.name == 'contrat': #it's time to choose contrat elif elt.name == 'contrat': #it's time to choose contrat
form = data_form.Form.fromElement(elt.firstChildElement()) form = data_form.Form.fromElement(elt.firstChildElement())
xml_data = XMLTools.dataForm2xml(form) xml_data = dataForm2xml(form)
self.host.bridge.tarotGameChooseContrat(room_jid.userhost(), xml_data, profile) self.host.bridge.tarotGameChooseContrat(room_jid.userhost(), xml_data, profile)
elif elt.name == 'contrat_choosed': elif elt.name == 'contrat_choosed':
@ -733,7 +733,7 @@ class Tarot():
for looser in elt.elements(name='looser', uri=''): for looser in elt.elements(name='looser', uri=''):
loosers.append(unicode(looser)) loosers.append(unicode(looser))
form = data_form.Form.fromElement(form_elt) form = data_form.Form.fromElement(form_elt)
xml_data = XMLTools.dataForm2xml(form) xml_data = dataForm2xml(form)
self.host.bridge.tarotGameScore(room_jid.userhost(), xml_data, winners, loosers, profile) self.host.bridge.tarotGameScore(room_jid.userhost(), xml_data, winners, loosers, profile)
elif elt.name == 'error': elif elt.name == 'error':
if elt['type'] == 'invalid_cards': if elt['type'] == 'invalid_cards':

View file

@ -24,7 +24,7 @@ from twisted.words.protocols.jabber import client, jid
from twisted.words.protocols.jabber import error as jab_error from twisted.words.protocols.jabber import error as jab_error
from twisted.words.protocols.jabber.xmlstream import IQ from twisted.words.protocols.jabber.xmlstream import IQ
from twisted.internet import reactor from twisted.internet import reactor
from tools.xml_tools import XMLTools from tools.xml_tools import dataForm2xml
import pdb import pdb
from wokkel import data_form from wokkel import data_form
@ -67,7 +67,7 @@ class XEP_0077():
return return
form = data_form.Form.fromElement(x_elem) form = data_form.Form.fromElement(x_elem)
xml_data = XMLTools.dataForm2xml(form) xml_data = dataForm2xml(form)
self.host.bridge.actionResult("FORM", answer['id'], {"target":answer["from"], "type":"registration", "xml":xml_data}) self.host.bridge.actionResult("FORM", answer['id'], {"target":answer["from"], "type":"registration", "xml":xml_data})
def reg_err(self, failure): def reg_err(self, failure):
@ -75,7 +75,7 @@ class XEP_0077():
info (_("Registration failure: %s") % str(failure.value)) info (_("Registration failure: %s") % str(failure.value))
answer_data = {} answer_data = {}
answer_data['reason'] = 'unknown' answer_data['reason'] = 'unknown'
answer_data={"message":"%s [code: %s]" % (failure.value.condition, failure.value.code)} answer_data={"message":"%s [code: %s]" % (failure.value.condition, unicode(failure.value))}
answer_type = "ERROR" answer_type = "ERROR"
self.host.bridge.actionResult(answer_type, failure.value.stanza['id'], answer_data) self.host.bridge.actionResult(answer_type, failure.value.stanza['id'], answer_data)

View file

@ -88,8 +88,14 @@ class XEP_0100():
self.__gateways[request_id] = {'__total_items':len(disco._items), '__handled_items':0, '__private__':{'target':target.full()}} self.__gateways[request_id] = {'__total_items':len(disco._items), '__handled_items':0, '__private__':{'target':target.full()}}
for item in disco._items: for item in disco._items:
debug (_("item found: %s"), item.name) debug (_("item found: %s"), item.name)
client.disco.requestInfo(item.entity).addCallback(self.discoInfo, entity=item.entity, request_id=request_id) client.disco.requestInfo(item.entity).addCallback(self.discoInfo, entity=item.entity, request_id=request_id).addErrback(self.discoInfoErr, entity=item.entity, request_id=request_id)
client.disco.requestInfo(item.entity).addErrback(self.discoInfoErr, entity=item.entity, request_id=request_id)
def discoItemsErr(self, failure, request_id, target, client):
"""Something is going wrong with disco"""
error(_("Error when discovering [%(target)s]: %(condition)s") % {'target':target.full(), 'condition':unicode(failure.value)})
message_data={"reason": "connection error", "message":_(u"Error while trying to discover %(target)s gateways: %(error_mess)s") % {'target':target.full(), 'error_mess':unicode(failure.value)}}
self.host.bridge.actionResult("ERROR", request_id, message_data)
def registrationSuccessful(self, target): def registrationSuccessful(self, target):
"""Called when in_band registration is ok, we must now follow the rest of procedure""" """Called when in_band registration is ok, we must now follow the rest of procedure"""
@ -107,10 +113,11 @@ class XEP_0100():
"""Find gateways in the target JID, using discovery protocol """Find gateways in the target JID, using discovery protocol
Return an id used for retrieving the list of gateways Return an id used for retrieving the list of gateways
""" """
profile = self.host.memory.getProfileName(profile_key)
client = self.host.getClient(profile_key) client = self.host.getClient(profile_key)
assert(client) assert(client)
to_jid = jid.JID(target) to_jid = jid.JID(target)
debug (_("find gateways (target = %s)") % to_jid.full()) debug (_("find gateways (target = %(target)s, profile = %(profile)s)") % {'target':to_jid.full(), 'profile':profile})
request_id = self.host.get_next_id() request_id = self.host.get_next_id()
client.disco.requestItems(to_jid).addCallback(self.discoItems, request_id=request_id, target = to_jid, client = client) client.disco.requestItems(to_jid).addCallback(self.discoItems, request_id=request_id, target = to_jid, client = client).addErrback(self.discoItemsErr, request_id=request_id, target = to_jid, client = client)
return request_id return request_id

10
sat.tac
View file

@ -47,7 +47,7 @@ import signal, sys
import os.path import os.path
from tools.memory import Memory from tools.memory import Memory
from tools.xml_tools import XMLTools from tools.xml_tools import tupleList2dataForm
from glob import glob from glob import glob
import gettext import gettext
@ -527,7 +527,7 @@ class SAT(service.Service):
iq["from"] = self.profiles[profile].jid.full() iq["from"] = self.profiles[profile].jid.full()
query = iq.addElement(('jabber:iq:register', 'query')) query = iq.addElement(('jabber:iq:register', 'query'))
if action=='SUBMIT': if action=='SUBMIT':
form = XMLTools.tupleList2dataForm(fields) form = tupleList2dataForm(fields)
query.addChild(form.toElement()) query.addChild(form.toElement())
elif action=='CANCEL': elif action=='CANCEL':
query.addElement('remove') query.addElement('remove')
@ -774,12 +774,12 @@ class SAT(service.Service):
if not profile_key: if not profile_key:
error (_('Non-exsitant profile')) error (_('Non-exsitant profile'))
return "" return ""
try: if self.menus.has_key((category,name,type)):
id = self.get_next_id() id = self.get_next_id()
self.menus[(category,name,type)]['callback'](id, profile) self.menus[(category,name,type)]['callback'](id, profile)
return id return id
except KeyError: else:
error (_("Trying to access an unknown menu")) error (_("Trying to access an unknown menu (%(category)s/%(name)s/%(type)s)")%{'category':category, 'name':name,'type':type})
return "" return ""

View file

@ -24,65 +24,62 @@ from xml.dom import minidom
from wokkel import data_form from wokkel import data_form
import pdb import pdb
class XMLTools: """This library help manage XML used in SàT (parameters, registration, etc) """
"""This class help manage XML used in SàT (parameters, registration, etc) """
@staticmethod def dataForm2xml(form):
def dataForm2xml(form): """Take a data form (xep-0004, Wokkel's implementation) and convert it to a SàT xml"""
"""Take a data form (xep-0004, Wokkel's implementation) and convert it to a SàT xml"""
impl = minidom.getDOMImplementation() impl = minidom.getDOMImplementation()
doc = impl.createDocument(None, "form", None) doc = impl.createDocument(None, "form", None)
top_element = doc.documentElement top_element = doc.documentElement
#result_xml = ["<form>", "</form>"] #result_xml = ["<form>", "</form>"]
if form.instructions: if form.instructions:
elem = doc.createElement('elem') elem = doc.createElement('elem')
elem.setAttribute('name','instructions') elem.setAttribute('name','instructions')
elem.setAttribute('type','text') elem.setAttribute('type','text')
text = doc.createTextNode('\n'.join(form.instructions)) text = doc.createTextNode('\n'.join(form.instructions))
elem.appendChild(text) elem.appendChild(text)
top_element.appendChild(elem) top_element.appendChild(elem)
for field in form.fieldList: for field in form.fieldList:
if field.fieldType == 'fixed': if field.fieldType == 'fixed':
__field_type = 'text' __field_type = 'text'
elif field.fieldType == 'text-single': elif field.fieldType == 'text-single':
__field_type = "string" __field_type = "string"
elif field.fieldType == 'text-private': elif field.fieldType == 'text-private':
__field_type = "password" __field_type = "password"
elif field.fieldType == 'list-single': elif field.fieldType == 'list-single':
__field_type = "list" __field_type = "list"
else: else:
error (u"FIXME FIXME FIXME: Type [%s] is not managed yet by SàT" % field.fieldType) error (u"FIXME FIXME FIXME: Type [%s] is not managed yet by SàT" % field.fieldType)
__field_type = "string" __field_type = "string"
elem = doc.createElement('elem') elem = doc.createElement('elem')
if field.var: if field.var:
elem.setAttribute('name', field.var) elem.setAttribute('name', field.var)
elem.setAttribute('type', __field_type) elem.setAttribute('type', __field_type)
elem.setAttribute('label', field.label or "") elem.setAttribute('label', field.label or "")
if field.value: if field.value:
elem.setAttribute('value', field.value) elem.setAttribute('value', field.value)
top_element.appendChild(elem) top_element.appendChild(elem)
for option in field.options: for option in field.options:
opt = doc.createElement('option') opt = doc.createElement('option')
opt.setAttribute('value', option.value) opt.setAttribute('value', option.value)
elem.appendChild(opt) elem.appendChild(opt)
result = doc.toxml() result = doc.toxml()
doc.unlink() doc.unlink()
return result return result
@staticmethod def tupleList2dataForm(values):
def tupleList2dataForm(values): """convert a list of tuples (name,value) to a wokkel submit data form"""
"""convert a list of tuples (name,value) to a wokkel submit data form""" form = data_form.Form('submit')
form = data_form.Form('submit') for value in values:
for value in values: field = data_form.Field(var=value[0], value=value[1])
field = data_form.Field(var=value[0], value=value[1]) form.addField(field)
form.addField(field)
return form return form