diff --git a/src/plugins/deprecated_misc_cs.py b/src/plugins/deprecated_misc_cs.py
index 0a30ac53..3dbe8011 100755
--- a/src/plugins/deprecated_misc_cs.py
+++ b/src/plugins/deprecated_misc_cs.py
@@ -40,20 +40,20 @@ import webbrowser
from BeautifulSoup import BeautifulSoup
import re
-
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""")
+ "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 = 'Salut à Toi XMPP/CS Plugin'
+
class CS_Plugin(object):
params = """
@@ -73,16 +73,17 @@ class CS_Plugin(object):
#parameters
host.memory.importParams(CS_Plugin.params)
#menu
- host.importMenu(_("Plugin"), "CouchSurfing", self.menuSelected, help_string = _("Launch CoushSurfing management interface"))
- self.data={} #TODO: delete cookies/data after a while
+ host.importMenu(_("Plugin"), "CouchSurfing", self.menuSelected, help_string=_("Launch CoushSurfing management interface"))
+ self.data = {} # TODO: delete cookies/data after a while
self.host.registerGeneralCB("plugin_CS_sendMessage", self.sendMessage)
self.host.registerGeneralCB("plugin_CS_showUnreadMessages", self.showUnreadMessages)
def profileConnected(self, profile):
self.data[profile] = PersistentBinaryDict("plugin_CS", profile)
+
def dataLoaded(ignore):
if not self.data[profile]:
- self.data[profile] = {'cookies':{}}
+ self.data[profile] = {'cookies': {}}
self.data[profile].load().addCallback(dataLoaded)
@@ -92,7 +93,7 @@ class CS_Plugin(object):
def erroCB(self, e, id):
"""Called when something is going wrong when contacting CS website"""
#pdb.set_trace()
- message_data={"reason": "connection error", "message":_(u"Impossible to contact CS website, please check your login/password, connection or try again later")}
+ 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):
@@ -100,24 +101,24 @@ class CS_Plugin(object):
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")}
+ 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...'})
+ post_data = urllib.urlencode({'auth_login[un]': login, 'auth_login[pw]': password, 'auth_login[action]': 'Login...'})
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=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=self.data[profile]['cookies'])
d.addCallback(self.__connectionCB, id, profile)
d.addErrback(self.erroCB, id)
#self.host.bridge.actionResult("SUPPRESS", id, {})
-
#pages parsing callbacks
+
def savePage(self, name, html):
- f = open ('/tmp/CS_'+name+'.html','w')
+ f = open('/tmp/CS_' + name + '.html', 'w')
f.write(html)
f.close()
print "page [%s] sauvee" % name
@@ -127,27 +128,27 @@ class CS_Plugin(object):
print 'Response received'
#self.savePage('principale',html)
soup = BeautifulSoup(html)
- self.data[profile]['user_nick'] = soup.find('a','item_link',href='/home.html').contents[0]
+ self.data[profile]['user_nick'] = soup.find('a', 'item_link', href='/home.html').contents[0]
self.data[profile]['user_name'] = soup.html.head.title.string.split(' - ')[1]
#unread messages
try:
- self.data[profile]['unread_messages'] = int(soup.find(lambda tag: tag.name=='div' and ('class','item_bubble') in tag.attrs and tag.find('a', href="/messages.html?message_status=inbox")).find(text=True))
+ self.data[profile]['unread_messages'] = int(soup.find(lambda tag: tag.name == 'div' and ('class', 'item_bubble') in tag.attrs and tag.find('a', href="/messages.html?message_status=inbox")).find(text=True))
except:
self.data[profile]['unread_messages'] = 0
#unread couchrequest messages
try:
- self.data[profile]['unread_CR_messages'] = int(soup.find(lambda tag: tag.name=='div' and ('class','item_bubble') in tag.attrs and tag.find('a', href="/couchmanager")).find(text=True))
+ self.data[profile]['unread_CR_messages'] = int(soup.find(lambda tag: tag.name == 'div' and ('class', 'item_bubble') in tag.attrs and tag.find('a', href="/couchmanager")).find(text=True))
except:
self.data[profile]['unread_CR_messages'] = 0
#if we have already the list of friend, no need to make new requests
- if not self.data[profile].has_key('friends'):
+ if 'friends' not in self.data[profile]:
self.data[profile]['friends'] = {}
d = getPage('http://www.couchsurfing.org/connections.html?type=myfriends&show=10000', agent=AGENT, cookies=self.data[profile]['cookies'])
d.addCallback(self.__friendsPageCB, id=id, profile=profile)
d.addErrback(self.erroCB, id)
else:
- self.host.bridge.actionResult("XMLUI", id, {"type":"window", "xml":self.__buildUI(self.data[profile])})
+ self.host.bridge.actionResult("XMLUI", id, {"type": "window", "xml": self.__buildUI(self.data[profile])})
def __buildUI(self, data):
"""Build the XML UI of the plugin
@@ -158,11 +159,11 @@ class CS_Plugin(object):
unread_CR_mess = data['unread_CR_messages']
friends_list = data['friends'].keys()
friends_list.sort()
- interface = XMLUI('window','tabs', title='CouchSurfing management')
+ interface = XMLUI('window', 'tabs', title='CouchSurfing management')
interface.addCategory(_("Messages"), "vertical")
- interface.addText(_("G'day %(name)s, you have %(nb_message)i unread message%(plural_mess)s and %(unread_CR_mess)s unread couch request message%(plural_CR)s\nIf you want to send a message, select the recipient(s) in the list below") % {'name':user_name, 'nb_message':unread_mess, 'plural_mess':'s' if unread_mess>1 else '', 'unread_CR_mess': unread_CR_mess, 'plural_CR':'s' if unread_CR_mess>1 else ''})
+ interface.addText(_("G'day %(name)s, you have %(nb_message)i unread message%(plural_mess)s and %(unread_CR_mess)s unread couch request message%(plural_CR)s\nIf you want to send a message, select the recipient(s) in the list below") % {'name': user_name, 'nb_message': unread_mess, 'plural_mess': 's' if unread_mess > 1 else '', 'unread_CR_mess': unread_CR_mess, 'plural_CR': 's' if unread_CR_mess > 1 else ''})
if unread_mess:
- interface.addButton('plugin_CS_showUnreadMessages', 'showUnreadMessages', _('Show unread message%(plural)s in external web browser') % {'plural':'s' if unread_mess>1 else ''})
+ interface.addButton('plugin_CS_showUnreadMessages', 'showUnreadMessages', _('Show unread message%(plural)s in external web browser') % {'plural': 's' if unread_mess > 1 else ''})
interface.addList(friends_list, 'friends', style=['multi'])
interface.changeLayout('pairs')
interface.addLabel(_("Subject"))
@@ -171,7 +172,7 @@ class CS_Plugin(object):
interface.addLabel(_("Message"))
interface.addText("(use %name% for contact name and %firstname% for guessed first name)")
interface.addTextBox('message')
- interface.addButton('plugin_CS_sendMessage', 'sendMessage', _('send'), fields_back=['friends','subject','message'])
+ interface.addButton('plugin_CS_sendMessage', 'sendMessage', _('send'), fields_back=['friends', 'subject', 'message'])
#interface.addCategory(_("Events"), "vertical") #TODO: coming soon, hopefuly :)
#interface.addCategory(_("Couch search"), "vertical")
return interface.toXml()
@@ -181,28 +182,28 @@ class CS_Plugin(object):
def __friendsPageCB(self, html, id, profile):
"""Called when the friends list page has been received"""
- self.savePage('friends',html)
- soup = BeautifulSoup(html.replace('"formtable width="400','"formtable" width="400"')) #CS html fix #TODO: report the bug to CS dev team
+ self.savePage('friends', html)
+ soup = BeautifulSoup(html.replace('"formtable width="400', '"formtable" width="400"')) # CS html fix #TODO: report the bug to CS dev team
friends = self.data[profile]['friends']
- for _tr in soup.findAll('tr', {'class':re.compile("^msgRow*")}): #we parse the row with friends infos
- _nobr = _tr.find('nobr') #contain the friend name
+ for _tr in soup.findAll('tr', {'class': re.compile("^msgRow*")}): # we parse the row with friends infos
+ _nobr = _tr.find('nobr') # contain the friend name
friend_name = unicode(_nobr.string)
- friend_link = u'http://www.couchsurfing.org'+_nobr.parent['href']
+ friend_link = u'http://www.couchsurfing.org' + _nobr.parent['href']
regex_href = re.compile(r'/connections\.html\?id=([^&]+)')
- a_tag = _tr.find('a',href=regex_href)
+ a_tag = _tr.find('a', href=regex_href)
friend_id = regex_href.search(unicode(a_tag)).groups()[0]
- debug(_("CS friend found: %(friend_name)s (id: %(friend_id)s, link: %(friend_link)s)") % {'friend_name':friend_name, 'friend_id':friend_id, 'friend_link':friend_link})
- friends[friend_name] = {'link':friend_link,'id':friend_id}
- a = soup.find('td','barmiddle next').a #is there several pages ?
+ debug(_("CS friend found: %(friend_name)s (id: %(friend_id)s, link: %(friend_link)s)") % {'friend_name': friend_name, 'friend_id': friend_id, 'friend_link': friend_link})
+ friends[friend_name] = {'link': friend_link, 'id': friend_id}
+ a = soup.find('td', 'barmiddle next').a # is there several pages ?
if a:
#yes, we parse the next page
- d = getPage('http://www.couchsurfing.org/'+str(a['href']), agent=AGENT, cookies=self.data[profile]['cookies'])
+ d = getPage('http://www.couchsurfing.org/' + str(a['href']), agent=AGENT, cookies=self.data[profile]['cookies'])
d.addCallback(self.__friendsPageCB, id=id, profile=profile)
d.addErrback(self.erroCB, id)
else:
#no, we show the result
- self.host.bridge.actionResult("XMLUI", id, {"type":"window", "xml":self.__buildUI(self.data[profile])})
+ self.host.bridge.actionResult("XMLUI", id, {"type": "window", "xml": self.__buildUI(self.data[profile])})
def __sendMessage(self, answer, subject, message, data, recipient_list, id, profile):
"""Send actually the message
@@ -224,18 +225,18 @@ class CS_Plugin(object):
friend_id = data['friends'][recipient]['id']
except KeyError:
error('INTERNAL ERROR: unknown friend')
- return #send an error to the frontend
- mess = message.replace('%name%',recipient).replace('%firstname%',recipient.split(' ')[0])
+ return # send an error to the frontend
+ mess = message.replace('%name%', recipient).replace('%firstname%', recipient.split(' ')[0])
info(_('Sending message to %s') % recipient)
- debug(_("\nsubject: %(subject)s\nmessage: \n---\n%(message)s\n---\n\n") % {'subject':subject,'message':mess})
- post_data = urllib.urlencode({'email[subject]':subject.encode('utf-8'),'email[body]':mess.encode('utf-8'),'email[id]':friend_id,'email[action]':'Send Message','email[replied_id]':'','email[couchsurf]':'','email[directions_to_add]':''})
- d = getPage("http://www.couchsurfing.org/send_message.html", method='POST', postdata=post_data, headers={'Content-Type':'application/x-www-form-urlencoded'} , agent=AGENT, cookies=data['cookies'])
+ debug(_("\nsubject: %(subject)s\nmessage: \n---\n%(message)s\n---\n\n") % {'subject': subject, 'message': mess})
+ post_data = urllib.urlencode({'email[subject]': subject.encode('utf-8'), 'email[body]': mess.encode('utf-8'), 'email[id]': friend_id, 'email[action]': 'Send Message', 'email[replied_id]': '', 'email[couchsurf]': '', 'email[directions_to_add]': ''})
+ d = getPage("http://www.couchsurfing.org/send_message.html", method='POST', postdata=post_data, headers={'Content-Type': 'application/x-www-form-urlencoded'}, agent=AGENT, cookies=data['cookies'])
d.addCallback(self.__sendMessage, subject, message, data, recipient_list, id, profile)
d.addErrback(self.erroCB, id)
else:
- interface = XMLUI('window', title=_('Message sent')) #TODO: create particular actionResult for alerts ?
+ interface = XMLUI('window', title=_('Message sent')) # TODO: create particular actionResult for alerts ?
interface.addText(_('The message has been sent to every recipients'))
- self.host.bridge.actionResult("XMLUI", id, {"type":"window", "xml":interface.toXml()})
+ self.host.bridge.actionResult("XMLUI", id, {"type": "window", "xml": interface.toXml()})
def sendMessage(self, id, data, profile):
"""Called to send a message to a friend
@@ -247,26 +248,25 @@ class CS_Plugin(object):
- %firstname%: guessed first name of the friend (currently the first part of the name)
"""
if not data['friends']:
- message_data={"reason": "bad data", "message":_(u"There is not recipient selected for this message !")}
+ message_data = {"reason": "bad data", "message": _(u"There is not recipient selected for this message !")}
self.host.bridge.actionResult("ERROR", id, message_data)
return
friends = data['friends'].split('\t')
subject = data['subject']
message = data['message']
- info(_("sending message to %(friends)s with subject [%(subject)s]" % {'friends':friends, 'subject':subject}))
+ info(_("sending message to %(friends)s with subject [%(subject)s]" % {'friends': friends, 'subject': subject}))
self.__sendMessage(None, subject, message, self.data[profile], friends, id, profile)
def __showUnreadMessages2(self, html, id, profile):
"""Called when the inbox page has been received"""
#FIXME: that's really too fragile, only works if the unread messages are in the first page, and it would be too resources consuming for the website to DL each time all pages. In addition, the show attribute doesn't work as expected.
soup = BeautifulSoup(html)
- for tag in soup.findAll(lambda tag: tag.name=='strong' and tag.a and tag.a['href'].startswith('messages.html?message_status=inbox')):
- link = "http://www.couchsurfing.org/"+str(tag.a['href'])
- webbrowser.open_new_tab(link) #TODO: the web browser need to already have CS cookies (i.e. already be opened & logged on CS, or be permanently loggued), a warning to the user should be sent/or a balloon-tip
+ for tag in soup.findAll(lambda tag: tag.name == 'strong' and tag.a and tag.a['href'].startswith('messages.html?message_status=inbox')):
+ link = "http://www.couchsurfing.org/" + str(tag.a['href'])
+ webbrowser.open_new_tab(link) # TODO: the web browser need to already have CS cookies (i.e. already be opened & logged on CS, or be permanently loggued), a warning to the user should be sent/or a balloon-tip
def showUnreadMessages(self, id, data, profile):
"""Called when user want to see all unread messages in the external browser"""
d = getPage("http://www.couchsurfing.org/messages.html?message_status=inbox&show=10000", agent=AGENT, cookies=self.data[profile]['cookies'])
d.addCallback(self.__showUnreadMessages2, id, profile)
d.addErrback(self.erroCB, id)
-
diff --git a/src/plugins/plugin_exp_parrot.py b/src/plugins/plugin_exp_parrot.py
index 1a81d8dc..784c59b1 100755
--- a/src/plugins/plugin_exp_parrot.py
+++ b/src/plugins/plugin_exp_parrot.py
@@ -22,21 +22,21 @@ along with this program. If not, see .
from logging import debug, info, warning, error
from twisted.words.protocols.jabber import jid
-
from sat.core.exceptions import UnknownEntityError
from sat.tools.misc import SkipOtherTriggers
PLUGIN_INFO = {
-"name": "Parrot Plugin",
-"import_name": "EXP-PARROT",
-"type": "EXP",
-"protocols": [],
-"dependencies": ["XEP-0045"],
-"main": "Exp_Parrot",
-"handler": "no",
-"description": _("""Implementation of parrot mode (repeat messages between 2 entities)""")
+ "name": "Parrot Plugin",
+ "import_name": "EXP-PARROT",
+ "type": "EXP",
+ "protocols": [],
+ "dependencies": ["XEP-0045"],
+ "main": "Exp_Parrot",
+ "handler": "no",
+ "description": _("""Implementation of parrot mode (repeat messages between 2 entities)""")
}
+
class Exp_Parrot(object):
"""Parrot mode plugin: repeat messages from one entity or MUC room to another one"""
#XXX: This plugin can be potentially dangerous if we don't trust entities linked
@@ -123,5 +123,3 @@ class Exp_Parrot(object):
del client.parrot_links[source_jid.userhostJID()]
except (AttributeError, KeyError):
pass
-
-
diff --git a/src/plugins/plugin_exp_pipe.py b/src/plugins/plugin_exp_pipe.py
index 6f5c7d37..98b20a6a 100755
--- a/src/plugins/plugin_exp_pipe.py
+++ b/src/plugins/plugin_exp_pipe.py
@@ -23,7 +23,7 @@ from logging import debug, info, warning, error
from twisted.words.xish import domish
from twisted.words.protocols.jabber import jid
from twisted.words.protocols.jabber import error as jab_error
-import os, os.path
+import os
from twisted.internet import reactor
from sat.core.exceptions import ProfileNotInCacheError
@@ -34,16 +34,17 @@ PROFILE_NAME = "pipe-transfer"
PROFILE = "http://jabber.org/protocol/si/profile/" + PROFILE_NAME
PLUGIN_INFO = {
-"name": "Pipe Plugin",
-"import_name": "EXP-PIPE",
-"type": "EXP",
-"protocols": ["EXP-PIPE"],
-"dependencies": ["XEP-0020", "XEP-0095", "XEP-0065", "XEP-0047"],
-"main": "Exp_Pipe",
-"handler": "no",
-"description": _("""Implementation of SI Pipe Transfer""")
+ "name": "Pipe Plugin",
+ "import_name": "EXP-PIPE",
+ "type": "EXP",
+ "protocols": ["EXP-PIPE"],
+ "dependencies": ["XEP-0020", "XEP-0095", "XEP-0065", "XEP-0047"],
+ "main": "Exp_Pipe",
+ "handler": "no",
+ "description": _("""Implementation of SI Pipe Transfer""")
}
+
class Exp_Pipe(object):
"""This is a modified version of XEP-0096 to work with named pipes instead of files"""
@@ -51,13 +52,13 @@ class Exp_Pipe(object):
info(_("Plugin Pipe initialization"))
self.host = host
self.managed_stream_m = [self.host.plugins["XEP-0065"].NAMESPACE,
- self.host.plugins["XEP-0047"].NAMESPACE] #Stream methods managed
+ self.host.plugins["XEP-0047"].NAMESPACE] # Stream methods managed
self.host.plugins["XEP-0095"].registerSIProfile(PROFILE_NAME, self.transferRequest)
host.bridge.addMethod("pipeOut", ".plugin", in_sign='ssa{ss}s', out_sign='s', method=self.pipeOut)
def profileConnected(self, profile):
client = self.host.getClient(profile)
- client._pipe_waiting_for_approval = {} #key = id, value = [transfer data, IdelayedCall Reactor timeout,
+ client._pipe_waiting_for_approval = {} # key = id, value = [transfer data, IdelayedCall Reactor timeout,
# current stream method, [failed stream methods], profile]
def _kill_id(self, approval_id, profile):
@@ -78,7 +79,7 @@ class Exp_Pipe(object):
@param si_mime_type: Mime type of the pipe (or default "application/octet-stream" if unknown)
@param si_el: domish.Element of the request
@param profile: %(doc_profile)s"""
- info (_("EXP-PIPE file transfer requested"))
+ info(_("EXP-PIPE file transfer requested"))
debug(si_el.toXml())
client = self.host.getClient(profile)
if not client:
@@ -95,7 +96,7 @@ class Exp_Pipe(object):
feature_el = feature_elts[0]
form = data_form.Form.fromElement(feature_el.firstChildElement())
try:
- stream_method = self.host.plugins["XEP-0020"].negociate(feature_el, 'stream-method',self.managed_stream_m)
+ stream_method = self.host.plugins["XEP-0020"].negociate(feature_el, 'stream-method', self.managed_stream_m)
except KeyError:
warning(_("No stream method found"))
self.host.plugins["XEP-0095"].sendBadRequestError(iq_id, from_jid, profile)
@@ -110,12 +111,11 @@ class Exp_Pipe(object):
return
#if we are here, the transfer can start, we just need user's agreement
- data={ "id": iq_id, "from":from_jid }
+ data = {"id": iq_id, "from": from_jid}
client._pipe_waiting_for_approval[si_id] = [data, reactor.callLater(300, self._kill_id, si_id), stream_method, [], profile]
self.host.askConfirmation(si_id, "PIPE_TRANSFER", data, self.confirmationCB, profile)
-
def confirmationCB(self, sid, accepted, frontend_data, profile):
"""Called on confirmation answer
@param sid: file transfer session id
@@ -146,13 +146,13 @@ class Exp_Pipe(object):
return
#we can send the iq result
- feature_elt = self.host.plugins["XEP-0020"].chooseOption({'stream-method':stream_method})
+ feature_elt = self.host.plugins["XEP-0020"].chooseOption({'stream-method': stream_method})
misc_elts = []
misc_elts.append(domish.Element((PROFILE, "file")))
self.host.plugins["XEP-0095"].acceptStream(data["id"], data['from'], feature_elt, misc_elts, profile)
else:
- debug (_("Transfer [%s] refused"), sid)
- self.host.plugins["XEP-0095"].sendRejectedError (data["id"], data['from'], profile=profile)
+ debug(_("Transfer [%s] refused"), sid)
+ self.host.plugins["XEP-0095"].sendRejectedError(data["id"], data['from'], profile=profile)
del(client._pipe_waiting_for_approval[sid])
def _transferSucceeded(self, sid, file_obj, stream_method, profile):
@@ -173,8 +173,8 @@ class Exp_Pipe(object):
if not client:
raise ProfileNotInCacheError
data, timeout, stream_method, failed_methods, profile = client._pipe_waiting_for_approval[sid]
- warning(_('Transfer %(id)s failed with stream method %(s_method)s') % { 'id': sid,
- 's_method': stream_method })
+ warning(_('Transfer %(id)s failed with stream method %(s_method)s') % {'id': sid,
+ 's_method': stream_method})
filepath = file_obj.name
file_obj.close()
#TODO: session remenber (within a time limit) when a stream method fail, and avoid that stream method with full jid for the rest of the session
@@ -211,15 +211,15 @@ class Exp_Pipe(object):
return
if stream_method == self.host.plugins["XEP-0065"].NAMESPACE:
- #fd = os.open(filepath, os.O_RDONLY | os.O_NONBLOCK) #XXX: non blocking openingl cause issues with XEP-0065's FileSender
- #file_obj = os.fdopen(fd, 'r')
- file_obj = open(filepath, 'r') #XXX: we have to be sure that filepath is well opened, as reading can block it
- self.host.plugins["XEP-0065"].startStream(file_obj, jid.JID(IQ['from']), sid, None, self.sendSuccessCb, self.sendFailureCb, None, profile)
+ #fd = os.open(filepath, os.O_RDONLY | os.O_NONBLOCK) #XXX: non blocking openingl cause issues with XEP-0065's FileSender
+ #file_obj = os.fdopen(fd, 'r')
+ file_obj = open(filepath, 'r') # XXX: we have to be sure that filepath is well opened, as reading can block it
+ self.host.plugins["XEP-0065"].startStream(file_obj, jid.JID(IQ['from']), sid, None, self.sendSuccessCb, self.sendFailureCb, None, profile)
elif stream_method == self.host.plugins["XEP-0047"].NAMESPACE:
- #fd = os.open(filepath, os.O_RDONLY | os.O_NONBLOCK) #XXX: non blocking openingl cause issues with XEP-0065's FileSender
- #file_obj = os.fdopen(fd, 'r')
- file_obj = open(filepath, 'r') #XXX: we have to be sure that filepath is well opened, as reading can block it
- self.host.plugins["XEP-0047"].startStream(file_obj, jid.JID(IQ['from']), sid, None, self.sendSuccessCb, self.sendFailureCb, None, profile)
+ #fd = os.open(filepath, os.O_RDONLY | os.O_NONBLOCK) #XXX: non blocking openingl cause issues with XEP-0065's FileSender
+ #file_obj = os.fdopen(fd, 'r')
+ file_obj = open(filepath, 'r') # XXX: we have to be sure that filepath is well opened, as reading can block it
+ self.host.plugins["XEP-0047"].startStream(file_obj, jid.JID(IQ['from']), sid, None, self.sendSuccessCb, self.sendFailureCb, None, profile)
else:
warning(_("Invalid stream method received"))
@@ -242,7 +242,7 @@ class Exp_Pipe(object):
pipe_elt = domish.Element((PROFILE, 'pipe'))
pipe_transfer_elts.append(pipe_elt)
- sid, offer = self.host.plugins["XEP-0095"].proposeStream(jid.JID(to_jid), PROFILE, feature_elt, pipe_transfer_elts, profile_key = profile)
+ sid, offer = self.host.plugins["XEP-0095"].proposeStream(jid.JID(to_jid), PROFILE, feature_elt, pipe_transfer_elts, profile_key=profile)
offer.addCallback(self.pipeCb, filepath, sid, profile)
return sid
@@ -252,5 +252,4 @@ class Exp_Pipe(object):
def sendFailureCb(self, sid, file_obj, stream_method, reason, profile):
file_obj.close()
- warning(_('Transfer %(id)s failed with stream method %(s_method)s %(profile)s') % { 'id': sid, "s_method": stream_method, "profile": profile })
-
+ warning(_('Transfer %(id)s failed with stream method %(s_method)s %(profile)s') % {'id': sid, "s_method": stream_method, "profile": profile})
diff --git a/src/plugins/plugin_misc_account.py b/src/plugins/plugin_misc_account.py
index 4563b952..48a0313b 100755
--- a/src/plugins/plugin_misc_account.py
+++ b/src/plugins/plugin_misc_account.py
@@ -28,14 +28,14 @@ from email.mime.text import MIMEText
from twisted.mail.smtp import sendmail
PLUGIN_INFO = {
-"name": "Account Plugin",
-"import_name": "MISC-ACCOUNT",
-"type": "MISC",
-"protocols": [],
-"dependencies": [],
-"main": "MiscAccount",
-"handler": "no",
-"description": _(u"""SàT account creation""")
+ "name": "Account Plugin",
+ "import_name": "MISC-ACCOUNT",
+ "type": "MISC",
+ "protocols": [],
+ "dependencies": [],
+ "main": "MiscAccount",
+ "handler": "no",
+ "description": _(u"""SàT account creation""")
}
#You need do adapt the following consts to your server
@@ -45,24 +45,24 @@ _REG_ADMIN_EMAIL = "admin@example.net"
_NEW_ACCOUNT_SERVER = "localhost"
_NEW_ACCOUNT_DOMAIN = "example.net"
_NEW_ACCOUNT_RESOURCE = "libervia"
-_PROSODY_PATH = None #prosody path (where prosodyctl will be executed from), or None to automaticaly find it
+_PROSODY_PATH = None # prosody path (where prosodyctl will be executed from), or None to automaticaly find it
_PROSODYCTL = "prosodyctl"
RESERVED = ['libervia']
+
class ProsodyRegisterProtocol(protocol.ProcessProtocol):
""" Try to register an account with prosody """
- def __init__(self, password, deferred = None):
+ def __init__(self, password, deferred=None):
self.password = password
self.deferred = deferred
self.data = ''
def connectionMade(self):
- self.transport.write("%s\n%s" % ((self.password.encode('utf-8'),)*2))
+ self.transport.write("%s\n%s" % ((self.password.encode('utf-8'), ) * 2))
self.transport.closeStdin()
-
def outReceived(self, data):
self.data += data
@@ -87,14 +87,14 @@ class MiscAccount(object):
def __init__(self, host):
info(_(u"Plugin Account initialization"))
self.host = host
- host.bridge.addMethod("registerSatAccount", ".plugin", in_sign='sss', out_sign='', method=self._registerAccount, async = True)
+ host.bridge.addMethod("registerSatAccount", ".plugin", in_sign='sss', out_sign='', method=self._registerAccount, async=True)
if not self._prosody_path:
paths = which(_PROSODYCTL)
if not paths:
- error(_("Can't find %s") % (_PROSODYCTL,))
+ error(_("Can't find %s") % (_PROSODYCTL, ))
else:
self._prosody_path = dirname(paths[0])
- info(_('Prosody path found: %s') % (self._prosody_path,))
+ info(_('Prosody path found: %s') % (self._prosody_path, ))
def _registerAccount(self, email, password, profile):
@@ -128,7 +128,7 @@ class MiscAccount(object):
# and just change the password if the account already exists
d = defer.Deferred()
prosody_reg = ProsodyRegisterProtocol(password, d)
- prosody_exe = join (self._prosody_path, _PROSODYCTL)
+ prosody_exe = join(self._prosody_path, _PROSODYCTL)
reactor.spawnProcess(prosody_reg, prosody_exe, [prosody_exe, 'adduser', "%s@%s" % (profile, _NEW_ACCOUNT_DOMAIN)], path=self._prosody_path)
d.addCallback(self._accountCreated, profile, email, password)
@@ -145,7 +145,7 @@ class MiscAccount(object):
def email_ko(ignore):
#TODO: return error code to user
- error ("Failed to send email to %s" % email)
+ error("Failed to send email to %s" % email)
body = (u"""Welcome to Libervia, a Salut à Toi project part
@@ -165,7 +165,7 @@ follow SàT news: http://www.goffi.org
Any feedback welcome
Cheers
-Goffi""" % { 'login': login, 'password': password, 'jid':"%s@%s" % (login, _NEW_ACCOUNT_DOMAIN) }).encode('utf-8')
+Goffi""" % {'login': login, 'password': password, 'jid': "%s@%s" % (login, _NEW_ACCOUNT_DOMAIN)}).encode('utf-8')
msg = MIMEText(body, 'plain', 'UTF-8')
msg['Subject'] = 'Libervia account created'
msg['From'] = _email_from
@@ -173,10 +173,9 @@ Goffi""" % { 'login': login, 'password': password, 'jid':"%s@%s" % (login, _NEW_
d = sendmail(_email_host, _email_from, email, msg.as_string())
d.addCallbacks(email_ok, email_ko)
-
#email to the administrator
- body = (u"""New account created: %(login)s [%(email)s]""" % { 'login': login, 'email': email }).encode('utf-8')
+ body = (u"""New account created: %(login)s [%(email)s]""" % {'login': login, 'email': email}).encode('utf-8')
msg = MIMEText(body, 'plain', 'UTF-8')
msg['Subject'] = 'Libervia new account created'
msg['From'] = _email_from
diff --git a/src/plugins/plugin_misc_groupblog.py b/src/plugins/plugin_misc_groupblog.py
index 64e4bc7a..d9f5762c 100755
--- a/src/plugins/plugin_misc_groupblog.py
+++ b/src/plugins/plugin_misc_groupblog.py
@@ -36,7 +36,7 @@ NS_PUBSUB = 'http://jabber.org/protocol/pubsub'
NS_GROUPBLOG = 'http://goffi.org/protocol/groupblog'
NS_NODE_PREFIX = 'urn:xmpp:groupblog:'
#NS_PUBSUB_EXP = 'http://goffi.org/protocol/pubsub' #for non official features
-NS_PUBSUB_EXP = NS_PUBSUB #XXX: we can't use custom namespace as Wokkel's PubSubService use official NS
+NS_PUBSUB_EXP = NS_PUBSUB # XXX: we can't use custom namespace as Wokkel's PubSubService use official NS
NS_PUBSUB_ITEM_ACCESS = NS_PUBSUB_EXP + "#item-access"
NS_PUBSUB_CREATOR_JID_CHECK = NS_PUBSUB_EXP + "#creator-jid-check"
NS_PUBSUB_ITEM_CONFIG = NS_PUBSUB_EXP + "#item-config"
@@ -51,28 +51,33 @@ OPT_SUBSCRIPTION_DEPTH = 'pubsub#subscription_depth'
TYPE_COLLECTION = 'collection'
PLUGIN_INFO = {
-"name": "Group blogging throught collections",
-"import_name": "groupblog",
-"type": "MISC",
-"protocols": [],
-"dependencies": ["XEP-0277"],
-"main": "GroupBlog",
-"handler": "yes",
-"description": _("""Implementation of microblogging with roster access""")
+ "name": "Group blogging throught collections",
+ "import_name": "groupblog",
+ "type": "MISC",
+ "protocols": [],
+ "dependencies": ["XEP-0277"],
+ "main": "GroupBlog",
+ "handler": "yes",
+ "description": _("""Implementation of microblogging with roster access""")
}
+
class NoCompatiblePubSubServerFound(Exception):
pass
+
class BadAccessTypeError(Exception):
pass
+
class BadAccessListError(Exception):
pass
+
class UnknownType(Exception):
pass
+
class GroupBlog(object):
"""This class use a SàT PubSub Service to manage access on microblog"""
@@ -81,29 +86,28 @@ class GroupBlog(object):
self.host = host
host.bridge.addMethod("sendGroupBlog", ".plugin", in_sign='sasss', out_sign='',
- method=self.sendGroupBlog)
+ method=self.sendGroupBlog)
host.bridge.addMethod("getLastGroupBlogs", ".plugin",
in_sign='sis', out_sign='aa{ss}',
method=self.getLastGroupBlogs,
- async = True)
+ async=True)
host.bridge.addMethod("getMassiveLastGroupBlogs", ".plugin",
in_sign='sasis', out_sign='a{saa{ss}}',
method=self.getMassiveLastGroupBlogs,
- async = True)
+ async=True)
host.bridge.addMethod("subscribeGroupBlog", ".plugin", in_sign='ss', out_sign='',
- method=self.subscribeGroupBlog,
- async = True)
+ method=self.subscribeGroupBlog,
+ async=True)
host.bridge.addMethod("massiveSubscribeGroupBlogs", ".plugin", in_sign='sass', out_sign='',
- method=self.massiveSubscribeGroupBlogs,
- async = True)
+ method=self.massiveSubscribeGroupBlogs,
+ async=True)
host.trigger.add("PubSubItemsReceived", self.pubSubItemsReceivedTrigger)
-
def getHandler(self, profile):
return GroupBlog_handler()
@@ -121,10 +125,10 @@ class GroupBlog(object):
if not client:
error(_('No client for this profile key: %s') % profile_key)
raise Exception("Unknown profile")
- yield client.client_initialized #we want to be sure that the client is initialized
+ yield client.client_initialized # we want to be sure that the client is initialized
#we first check that we have a item-access pubsub server
- if not hasattr(client,"item_access_pubsub"):
+ if not hasattr(client, "item_access_pubsub"):
debug(_('Looking for item-access power pubsub server'))
#we don't have any pubsub server featuring item access yet
client.item_access_pubsub = None
@@ -137,7 +141,7 @@ class GroupBlog(object):
client.item_access_pubsub = entity
client._item_access_pubsub_pending.callback(None)
- if hasattr(client,"_item_access_pubsub_pending"):
+ if hasattr(client, "_item_access_pubsub_pending"):
#XXX: we need to wait for item access pubsub service check
yield client._item_access_pubsub_pending
del client._item_access_pubsub_pending
@@ -157,8 +161,8 @@ class GroupBlog(object):
#FIXME: basic origin check, must be improved
#TODO: automatic security test
if (not (origin_host)
- or len(event_host) < len(origin_host)
- or event_host[-len(origin_host):] != origin_host):
+ or len(event_host) < len(origin_host)
+ or event_host[-len(origin_host):] != origin_host):
warning("Host incoherence between %s and %s (hack attempt ?)" % (unicode(event.sender),
unicode(publisher)))
return
@@ -169,7 +173,6 @@ class GroupBlog(object):
return False
return True
-
def _parseAccessData(self, microblog_data, item):
form_elts = filter(lambda elt: elt.name == "x", item.children)
for form_elt in form_elts:
@@ -192,15 +195,12 @@ class GroupBlog(object):
self._parseAccessData(microblog_data, item)
return microblog_data
-
def getNodeName(self, publisher):
"""Retrieve the name of publisher's node
@param publisher: publisher's jid
@return: node's name (string)"""
return NS_NODE_PREFIX + publisher.userhost()
-
-
def _publishMblog(self, service, client, access_type, access_list, message):
"""Actually publish the message on the group blog
@param service: jid of the item-access pubsub service
@@ -209,7 +209,7 @@ class GroupBlog(object):
@param access_list: set of entities (empty list for all, groups or jids) allowed to see the item
@param message: message to publish
"""
- mblog_item = self.host.plugins["XEP-0277"].data2entry({'content':message}, client.profile)
+ mblog_item = self.host.plugins["XEP-0277"].data2entry({'content': message}, client.profile)
form = data_form.Form('submit', formNamespace=NS_PUBSUB_ITEM_CONFIG)
if access_type == "PUBLIC":
if access_list:
@@ -243,6 +243,7 @@ class GroupBlog(object):
@profile_key: %(doc_profile)s
"""
print "sendGroupBlog"
+
def initialised(result):
profile, client = result
if access_type == "PUBLIC":
@@ -250,7 +251,7 @@ class GroupBlog(object):
raise Exception("Publishers list must be empty when getting microblogs for all contacts")
self._publishMblog(client.item_access_pubsub, client, "PUBLIC", [], message)
elif access_type == "GROUP":
- _groups = set(access_list).intersection(client.roster.getGroups()) #We only keep group which actually exist
+ _groups = set(access_list).intersection(client.roster.getGroups()) # We only keep group which actually exist
if not _groups:
raise BadAccessListError("No valid group")
self._publishMblog(client.item_access_pubsub, client, "GROUP", _groups, message)
@@ -262,8 +263,6 @@ class GroupBlog(object):
self.initialise(profile_key).addCallback(initialised)
-
-
def getLastGroupBlogs(self, pub_jid, max_items=10, profile_key='@DEFAULT@'):
"""Get the last published microblogs
@param pub_jid: jid of the publisher
@@ -277,7 +276,7 @@ class GroupBlog(object):
d = self.host.plugins["XEP-0060"].getItems(client.item_access_pubsub, self.getNodeName(jid.JID(pub_jid)),
max_items=max_items, profile_key=profile_key)
d.addCallback(lambda items: map(self.item2gbdata, items))
- d.addErrback(lambda ignore: {}) #TODO: more complete error management (log !)
+ d.addErrback(lambda ignore: {}) # TODO: more complete error management (log !)
return d
#TODO: we need to use the server corresponding the the host of the jid
@@ -290,6 +289,7 @@ class GroupBlog(object):
@param max_items: how many microblogs we want to get
@param profile_key: profile key
"""
+
def sendResult(result):
"""send result of DeferredList (list of microblogs to the calling method"""
@@ -329,11 +329,10 @@ class GroupBlog(object):
return dlist
-
#TODO: custom exception
if publishers_type not in ["GROUP", "JID", "ALL"]:
raise Exception("Bad call, unknown publishers_type")
- if publishers_type=="ALL" and publishers:
+ if publishers_type == "ALL" and publishers:
raise Exception("Publishers list must be empty when getting microblogs for all contacts")
return self.initialise(profile_key).addCallback(initialised)
#TODO: we need to use the server corresponding the the host of the jid
@@ -348,13 +347,13 @@ class GroupBlog(object):
#TODO: we need to use the server corresponding the the host of the jid
return self.initialise(profile_key).addCallback(initialised)
-
def massiveSubscribeGroupBlogs(self, publishers_type, publishers, profile_key='@DEFAULT@'):
"""Subscribe microblogs for a list of groups or jids
@param publishers_type: type of the list of publishers (one of "GROUP" or "JID" or "ALL")
@param publishers: list of publishers, according to "publishers_type" (list of groups or list of jids)
@param profile_key: profile key
"""
+
def initialised(result):
profile, client = result
@@ -378,17 +377,15 @@ class GroupBlog(object):
dlist = defer.DeferredList(mblogs)
return dlist
-
#TODO: custom exception
if publishers_type not in ["GROUP", "JID", "ALL"]:
raise Exception("Bad call, unknown publishers_type")
- if publishers_type=="ALL" and publishers:
+ if publishers_type == "ALL" and publishers:
raise Exception("Publishers list must be empty when getting microblogs for all contacts")
return self.initialise(profile_key).addCallback(initialised)
#TODO: we need to use the server corresponding the the host of the jid
-
class GroupBlog_handler(XMPPHandler):
implements(iwokkel.IDisco)
@@ -397,4 +394,3 @@ class GroupBlog_handler(XMPPHandler):
def getDiscoItems(self, requestor, target, nodeIdentifier=''):
return []
-
diff --git a/src/plugins/plugin_misc_imap.py b/src/plugins/plugin_misc_imap.py
index 5bf557dd..287b599b 100755
--- a/src/plugins/plugin_misc_imap.py
+++ b/src/plugins/plugin_misc_imap.py
@@ -21,34 +21,33 @@ along with this program. If not, see .
from logging import debug, info, error
import warnings
-from twisted.internet import protocol,defer
+from twisted.internet import protocol, defer
from twisted.words.protocols.jabber import error as jab_error
-from twisted.cred import portal,checkers,credentials
+from twisted.cred import portal, checkers, credentials
from twisted.cred import error as cred_error
from twisted.mail import imap4
from twisted.python import failure
from email.parser import Parser
import email.message
-import os,os.path
+import os
from cStringIO import StringIO
from twisted.internet import reactor
import pdb
-
from zope.interface import implements
-
PLUGIN_INFO = {
-"name": "IMAP server Plugin",
-"import_name": "IMAP",
-"type": "Misc",
-"protocols": [],
-"dependencies": ["Maildir"],
-"main": "IMAP_server",
-"handler": "no",
-"description": _("""Create an Imap server that you can use to read your "normal" type messages""")
+ "name": "IMAP server Plugin",
+ "import_name": "IMAP",
+ "type": "Misc",
+ "protocols": [],
+ "dependencies": ["Maildir"],
+ "main": "IMAP_server",
+ "handler": "no",
+ "description": _("""Create an Imap server that you can use to read your "normal" type messages""")
}
+
class IMAP_server(object):
#TODO: connect profile on mailbox request, once password is accepted
@@ -75,15 +74,16 @@ class IMAP_server(object):
self.server_factory = ImapServerFactory(self.host)
reactor.listenTCP(port, self.server_factory)
+
class Message(object):
implements(imap4.IMessage)
def __init__(self, uid, flags, mess_fp):
debug('Message Init')
- self.uid=uid
- self.flags=flags
- self.mess_fp=mess_fp
- self.message=Parser().parse(mess_fp)
+ self.uid = uid
+ self.flags = flags
+ self.mess_fp = mess_fp
+ self.message = Parser().parse(mess_fp)
def getUID(self):
"""Retrieve the unique identifier associated with this message.
@@ -105,7 +105,6 @@ class Message(object):
debug('getInternalDate')
return self.message['Date']
-
def getHeaders(self, negate, *names):
"""Retrieve a group of message headers.
@param names: The names of the headers to retrieve or omit.
@@ -114,12 +113,12 @@ class Message(object):
@return: A mapping of header field names to header field values
"""
debug('getHeaders %s - %s' % (negate, names))
- final_dict={}
- to_check=[name.lower() for name in names]
+ final_dict = {}
+ to_check = [name.lower() for name in names]
for header in self.message.keys():
if (negate and not header.lower() in to_check) or \
- (not negate and header.lower() in to_check):
- final_dict[header]=self.message[header]
+ (not negate and header.lower() in to_check):
+ final_dict[header] = self.message[header]
return final_dict
def getBodyFile(self):
@@ -132,17 +131,16 @@ class Message(object):
"""Retrieve the total size, in octets, of this message.
"""
debug('getSize')
- self.mess_fp.seek(0,os.SEEK_END)
+ self.mess_fp.seek(0, os.SEEK_END)
return self.mess_fp.tell()
-
def isMultipart(self):
"""Indicate whether this message has subparts.
"""
debug('isMultipart')
return False
- def getSubPart(self,part):
+ def getSubPart(self, part):
"""Retrieve a MIME sub-message
@param part: The number of the part to retrieve, indexed from 0.
@return: The specified sub-part.
@@ -154,39 +152,39 @@ class Message(object):
class SatMailbox(object):
implements(imap4.IMailbox)
- def __init__(self,host,name,profile):
+ def __init__(self, host, name, profile):
self.host = host
- self.listeners=set()
- debug ('Mailbox init (%s)', name)
- if name!="INBOX":
+ self.listeners = set()
+ debug('Mailbox init (%s)', name)
+ if name != "INBOX":
raise imap4.MailboxException("Only INBOX is managed for the moment")
- self.mailbox=self.host.plugins["Maildir"].accessMessageBox(name,self.newMessage, profile)
+ self.mailbox = self.host.plugins["Maildir"].accessMessageBox(name, self.newMessage, profile)
def newMessage(self):
"""Called when a new message is in the mailbox"""
- debug ("newMessage signal received")
- nb_messages=self.getMessageCount()
+ debug("newMessage signal received")
+ nb_messages = self.getMessageCount()
for listener in self.listeners:
- listener.newMessages(nb_messages,None)
+ listener.newMessages(nb_messages, None)
def getUIDValidity(self):
"""Return the unique validity identifier for this mailbox.
"""
- debug ('getUIDValidity')
+ debug('getUIDValidity')
return 0
def getUIDNext(self):
"""Return the likely UID for the next message added to this mailbox.
"""
- debug ('getUIDNext')
+ debug('getUIDNext')
return self.mailbox.getNextUid()
- def getUID(self,message):
+ def getUID(self, message):
"""Return the UID of a message in the mailbox
@param message: The message sequence number
@return: The UID of the message.
"""
- debug ('getUID (%i)' % message)
+ debug('getUID (%i)' % message)
#return self.mailbox.getUid(message-1) #XXX: it seems that this method get uid and not message sequence number
return message
@@ -208,7 +206,7 @@ class SatMailbox(object):
"""Return the number of messages with the 'Unseen' flag.
"""
debug('getUnseenCount')
- return self.getMessageCount()-len(self.mailbox.getMessageIdsWithFlag('\\SEEN'))
+ return self.getMessageCount() - len(self.mailbox.getMessageIdsWithFlag('\\SEEN'))
def isWriteable(self):
"""Get the read/write status of the mailbox.
@@ -222,7 +220,6 @@ class SatMailbox(object):
"""
debug('destroy')
-
def requestStatus(self, names):
"""Return status information about this mailbox.
@param names: The status names to return information regarding.
@@ -262,7 +259,7 @@ class SatMailbox(object):
else:
raise imap4.MailboxException('Trying to remove an unknown listener')
- def addMessage(self, message, flags = (), date = None):
+ def addMessage(self, message, flags=(), date=None):
"""Add the given message to this mailbox.
@param message: The RFC822 formatted message
@param flags: The flags to associate with this message
@@ -288,24 +285,24 @@ class SatMailbox(object):
about
@param uid: If true, the IDs specified in the query are UIDs;
"""
- debug('fetch (%s, %s)'%(messages,uid))
+ debug('fetch (%s, %s)' % (messages, uid))
if uid:
messages.last = self.mailbox.getMaxUid()
messages.getnext = self.mailbox.getNextExistingUid
for mess_uid in messages:
- if mess_uid == None:
- debug ('stopping iteration')
+ if mess_uid is None:
+ debug('stopping iteration')
raise StopIteration
try:
- yield (mess_uid,Message(mess_uid,self.mailbox.getFlagsUid(mess_uid), self.mailbox.getMessageUid(mess_uid)))
+ yield (mess_uid, Message(mess_uid, self.mailbox.getFlagsUid(mess_uid), self.mailbox.getMessageUid(mess_uid)))
except IndexError:
continue
else:
messages.last = self.getMessageCount()
for mess_idx in messages:
- if mess_idx>self.getMessageCount():
+ if mess_idx > self.getMessageCount():
raise StopIteration
- yield (mess_idx,Message(mess_idx,self.mailbox.getFlags(mess_idx),self.mailbox.getMessage(mess_idx-1)))
+ yield (mess_idx, Message(mess_idx, self.mailbox.getFlags(mess_idx), self.mailbox.getMessage(mess_idx - 1)))
def store(self, messages, flags, mode, uid):
"""Set the flags of one or more messages.
@@ -324,19 +321,19 @@ class SatMailbox(object):
"""
debug('store')
- flags=[flag.upper() for flag in flags]
+ flags = [flag.upper() for flag in flags]
- def updateFlags(getF,setF):
+ def updateFlags(getF, setF):
ret = {}
for mess_id in messages:
- if (uid and mess_id == None) or (not uid and mess_id>self.getMessageCount()):
+ if (uid and mess_id is None) or (not uid and mess_id > self.getMessageCount()):
break
- _flags=set(getF(mess_id) if mode else [])
- if mode==-1:
+ _flags = set(getF(mess_id) if mode else [])
+ if mode == -1:
_flags.difference_update(set(flags))
else:
_flags.update(set(flags))
- new_flags=list(_flags)
+ new_flags = list(_flags)
setF(mess_id, new_flags)
ret[mess_id] = tuple(new_flags)
return ret
@@ -344,15 +341,15 @@ class SatMailbox(object):
if uid:
messages.last = self.mailbox.getMaxUid()
messages.getnext = self.mailbox.getNextExistingUid
- ret = updateFlags(self.mailbox.getFlagsUid,self.mailbox.setFlagsUid)
+ ret = updateFlags(self.mailbox.getFlagsUid, self.mailbox.setFlagsUid)
for listener in self.listeners:
listener.flagsChanged(ret)
return ret
else:
messages.last = self.getMessageCount()
- ret = updateFlags(self.mailbox.getFlags,self.mailbox.setFlags)
- newFlags={}
+ ret = updateFlags(self.mailbox.getFlags, self.mailbox.setFlags)
+ newFlags = {}
for idx in ret:
#we have to convert idx to uid for the listeners
newFlags[self.mailbox.getUid(idx)] = ret[idx]
@@ -366,7 +363,7 @@ class SatMailbox(object):
@return: A list of the flags that can be set on messages in this mailbox.
"""
debug('getFlags')
- return ['\\SEEN','\\ANSWERED','\\FLAGGED','\\DELETED','\\DRAFT'] #TODO: add '\\RECENT'
+ return ['\\SEEN', '\\ANSWERED', '\\FLAGGED', '\\DELETED', '\\DRAFT'] # TODO: add '\\RECENT'
def getHierarchicalDelimiter(self):
"""Get the character which delimits namespaces for in this mailbox.
@@ -374,33 +371,35 @@ class SatMailbox(object):
debug('getHierarchicalDelimiter')
return '.'
+
class ImapSatAccount(imap4.MemoryAccount):
#implements(imap4.IAccount)
def __init__(self, host, profile):
debug("ImapAccount init")
- self.host=host
- self.profile=profile
- imap4.MemoryAccount.__init__(self,profile)
- self.addMailbox("Inbox") #We only manage Inbox for the moment
- debug ('INBOX added')
+ self.host = host
+ self.profile = profile
+ imap4.MemoryAccount.__init__(self, profile)
+ self.addMailbox("Inbox") # We only manage Inbox for the moment
+ debug('INBOX added')
def _emptyMailbox(self, name, id):
- return SatMailbox(self.host,name,self.profile)
+ return SatMailbox(self.host, name, self.profile)
class ImapRealm(object):
implements(portal.IRealm)
- def __init__(self,host):
+ def __init__(self, host):
self.host = host
def requestAvatar(self, avatarID, mind, *interfaces):
debug('requestAvatar')
- profile=avatarID.decode('utf-8')
+ profile = avatarID.decode('utf-8')
if imap4.IAccount not in interfaces:
raise NotImplementedError
- return imap4.IAccount, ImapSatAccount(self.host,profile), lambda:None
+ return imap4.IAccount, ImapSatAccount(self.host, profile), lambda: None
+
class SatProfileCredentialChecker(object):
"""
@@ -412,7 +411,6 @@ class SatProfileCredentialChecker(object):
credentialInterfaces = (credentials.IUsernamePassword,
credentials.IUsernameHashedPassword)
-
def __init__(self, host):
self.host = host
@@ -431,20 +429,21 @@ class SatProfileCredentialChecker(object):
d.addCallback(self._cbPasswordMatch, credentials.username)
return d
+
class ImapServerFactory(protocol.ServerFactory):
protocol = imap4.IMAP4Server
def __init__(self, host):
- self.host=host
+ self.host = host
def startedConnecting(self, connector):
- debug (_("IMAP server connection started"))
+ debug(_("IMAP server connection started"))
def clientConnectionLost(self, connector, reason):
- debug (_("IMAP server connection lost (reason: %s)"), reason)
+ debug(_("IMAP server connection lost (reason: %s)"), reason)
def buildProtocol(self, addr):
- debug ("Building protocol")
+ debug("Building protocol")
prot = protocol.ServerFactory.buildProtocol(self, addr)
prot.portal = portal.Portal(ImapRealm(self.host))
prot.portal.registerChecker(SatProfileCredentialChecker(self.host))
diff --git a/src/plugins/plugin_misc_maildir.py b/src/plugins/plugin_misc_maildir.py
index 63aaee9c..218fd9f4 100755
--- a/src/plugins/plugin_misc_maildir.py
+++ b/src/plugins/plugin_misc_maildir.py
@@ -21,54 +21,54 @@ along with this program. If not, see .
from logging import debug, info, error
import warnings
-warnings.filterwarnings('ignore','the MimeWriter',DeprecationWarning,'twisted' ) #FIXME: to be removed, see http://twistedmatrix.com/trac/ticket/4038
+warnings.filterwarnings('ignore', 'the MimeWriter', DeprecationWarning, 'twisted') # FIXME: to be removed, see http://twistedmatrix.com/trac/ticket/4038
from twisted.internet import protocol
from twisted.words.protocols.jabber import error as jab_error
-from twisted.cred import portal,checkers
-from twisted.mail import imap4,maildir
+from twisted.cred import portal, checkers
+from twisted.mail import imap4, maildir
from email.parser import Parser
import email.message
from email.charset import Charset
-import os,os.path
+import os
from cStringIO import StringIO
from twisted.internet import reactor
import pdb
from sat.core.exceptions import ProfileUnknownError
from sat.memory.persistent import PersistentBinaryDict
-
from zope.interface import implements
-
PLUGIN_INFO = {
-"name": "Maildir Plugin",
-"import_name": "Maildir",
-"type": "Misc",
-"protocols": [],
-"dependencies": [],
-"main": "MaildirBox",
-"handler": "no",
-"description": _("""Intercept "normal" type messages, and put them in a Maildir type box""")
+ "name": "Maildir Plugin",
+ "import_name": "Maildir",
+ "type": "Misc",
+ "protocols": [],
+ "dependencies": [],
+ "main": "MaildirBox",
+ "handler": "no",
+ "description": _("""Intercept "normal" type messages, and put them in a Maildir type box""")
}
MAILDIR_PATH = "Maildir"
+
class MaildirError(Exception):
pass
+
class MaildirBox(object):
def __init__(self, host):
info(_("Plugin Maildir initialization"))
self.host = host
- self.__observed={}
- self.data={} #list of profile spectific data. key = profile, value = PersistentBinaryDict where key=mailbox name,
+ self.__observed = {}
+ self.data = {} # list of profile spectific data. key = profile, value = PersistentBinaryDict where key=mailbox name,
# and value is a dictionnary with the following value
# - cur_idx: value of the current unique integer increment (UID)
# - message_id (as returned by MaildirMailbox): a tuple of (UID, [flag1, flag2, ...])
- pList=host.memory.getProfilesList #shorter :)
- self.__mailboxes={} #key: profile, value: {boxname: MailboxUser instance}
+ pList = host.memory.getProfilesList # shorter :)
+ self.__mailboxes = {} # key: profile, value: {boxname: MailboxUser instance}
#the triggers
host.trigger.add("MessageReceived", self.messageReceivedTrigger)
@@ -76,11 +76,12 @@ class MaildirBox(object):
def profileConnected(self, profile):
"""Called on profile connection, create profile data"""
self.data[profile] = PersistentBinaryDict("plugin_maildir", profile)
- self.__mailboxes[profile]={}
+ self.__mailboxes[profile] = {}
+
def dataLoaded(ignore):
if not self.data[profile]:
#the mailbox is new, we initiate the data
- self.data[profile]["INBOX"] = {"cur_idx":0}
+ self.data[profile]["INBOX"] = {"cur_idx": 0}
self.data[profile].load().addCallback(dataLoaded)
def profileDisconnected(self, profile):
@@ -108,8 +109,8 @@ class MaildirBox(object):
profile = self.host.memory.getProfileName(profile_key)
if not profile:
raise ProfileUnknownError(profile_key)
- if not self.__mailboxes[profile].has_key(boxname):
- self.__mailboxes[profile][boxname]=MailboxUser(self, boxname, observer, profile=profile)
+ if boxname not in self.__mailboxes[profile]:
+ self.__mailboxes[profile][boxname] = MailboxUser(self, boxname, observer, profile=profile)
else:
if observer:
self.addObserver(observer, profile, boxname)
@@ -118,33 +119,33 @@ class MaildirBox(object):
def _getProfilePath(self, profile):
"""Return a unique path for profile's mailbox
The path must be unique, usable as a dir name, and bijectional"""
- return profile.replace('/','_').replace('..','_') #FIXME: this is too naive to work well, must be improved
+ return profile.replace('/', '_').replace('..', '_') # FIXME: this is too naive to work well, must be improved
def _removeBoxAccess(self, boxname, mailboxUser, profile):
"""Remove a reference to a box
@param name: name of the box
@param mailboxUser: MailboxUser instance"""
- if not self.__mailboxes.has_key(boxname):
- err_msg=_("Trying to remove an mailboxUser not referenced")
+ if boxname not in self.__mailboxes:
+ err_msg = _("Trying to remove an mailboxUser not referenced")
error(_("INTERNAL ERROR: ") + err_msg)
raise MaildirError(err_msg)
- assert self.__mailboxes[profile][boxname]==mailboxUser
+ assert self.__mailboxes[profile][boxname] == mailboxUser
del __mailboxes[profile][boxname]
def _checkBoxReference(self, boxname, profile):
"""Check if there is a reference on a box, and return it
@param boxname: name of the box to check
@return: MailboxUser instance or None"""
- if self.__mailboxes.has_key(profile):
- if self.__mailboxes[profile].has_key(boxname):
+ if profile in self.__mailboxes:
+ if boxname in self.__mailboxes[profile]:
return self.__mailboxes[profile][boxname]
def __getBoxData(self, boxname, profile):
"""Return the date of a box"""
try:
- return self.data[profile][boxname] #the boxname MUST exist in the data
+ return self.data[profile][boxname] # the boxname MUST exist in the data
except KeyError:
- err_msg=_("Boxname doesn't exist in internal data")
+ err_msg = _("Boxname doesn't exist in internal data")
error(_("INTERNAL ERROR: ") + err_msg)
raise MaildirError(err_msg)
@@ -155,11 +156,11 @@ class MaildirBox(object):
@param message_id: unique id of the message as given by MaildirMailbox
@return: Integer UID"""
box_data = self.__getBoxData(boxname, profile)
- if box_data.has_key(message_id):
+ if message_id in box_data:
ret = box_data[message_id][0]
else:
- box_data['cur_idx']+=1
- box_data[message_id]=[box_data['cur_idx'],[]]
+ box_data['cur_idx'] += 1
+ box_data[message_id] = [box_data['cur_idx'], []]
ret = box_data[message_id]
self.data[profile].force(boxname)
return ret
@@ -170,7 +171,7 @@ class MaildirBox(object):
@param boxname: name of the box where the message is
@return: Integer UID"""
box_data = self.__getBoxData(boxname, profile)
- return box_data['cur_idx']+1
+ return box_data['cur_idx'] + 1
def getNextExistingUid(self, boxname, uid, profile):
"""Give the next uid of existing message
@@ -178,10 +179,10 @@ class MaildirBox(object):
@param uid: uid to start from
@return: uid or None if the is no more message"""
box_data = self.__getBoxData(boxname, profile)
- idx=uid+1
- while self.getIdFromUid(boxname, idx, profile) == None: #TODO: this is highly inefficient because getIdfromUid is inefficient, fix this
- idx+=1
- if idx>box_data['cur_idx']:
+ idx = uid + 1
+ while self.getIdFromUid(boxname, idx, profile) is None: # TODO: this is highly inefficient because getIdfromUid is inefficient, fix this
+ idx += 1
+ if idx > box_data['cur_idx']:
return None
return idx
@@ -198,7 +199,7 @@ class MaildirBox(object):
@param message_uid: unique integer identifier
@return: unique id of the message as given by MaildirMailbox or None if not found"""
box_data = self.__getBoxData(boxname, profile)
- for message_id in box_data.keys(): #TODO: this is highly inefficient on big mailbox, must be replaced in the future
+ for message_id in box_data.keys(): # TODO: this is highly inefficient on big mailbox, must be replaced in the future
if message_id == 'cur_idx':
continue
if box_data[message_id][0] == message_uid:
@@ -211,7 +212,7 @@ class MaildirBox(object):
@param message_idx: message id as given by MaildirMailbox
@return: list of strings"""
box_data = self.__getBoxData(boxname, profile)
- if not box_data.has_key(mess_id):
+ if mess_id not in box_data:
raise MailboxException("Trying to get flags from an unexisting message")
return box_data[mess_id][1]
@@ -222,11 +223,11 @@ class MaildirBox(object):
@param flags: list of strings
"""
box_data = self.__getBoxData(boxname, profile)
- assert(type(flags)==list)
- flags=[flag.upper() for flag in flags] #we store every flag UPPERCASE
- if not box_data.has_key(mess_id):
+ assert(type(flags) == list)
+ flags = [flag.upper() for flag in flags] # we store every flag UPPERCASE
+ if mess_id not in box_data:
raise MailboxException("Trying to set flags for an unexisting message")
- box_data[mess_id][1]=flags
+ box_data[mess_id][1] = flags
self.data[profile].force(boxname)
def getMessageIdsWithFlag(self, boxname, flag, profile):
@@ -235,11 +236,11 @@ class MaildirBox(object):
@param flag: flag to check
@return: list of id (as given by MaildirMailbox)"""
box_data = self.__getBoxData(boxname, profile)
- assert(isinstance(flag,basestring))
- flag=flag.upper()
+ assert(isinstance(flag, basestring))
+ flag = flag.upper()
result = []
for key in box_data:
- if key=='cur_idx':
+ if key == 'cur_idx':
continue
if flag in box_data[key][1]:
result.append(key)
@@ -250,8 +251,8 @@ class MaildirBox(object):
@param boxname: name of the box where the message is
"""
box_data = self.__getBoxData(boxname, profile)
- for mess_id in self.getMessageIdsWithFlag(boxname,"\\Deleted", profile):
- del(box_data[mess_id])
+ for mess_id in self.getMessageIdsWithFlag(boxname, "\\Deleted", profile):
+ del(box_data[mess_id])
self.data[profile].force(boxname)
def cleanTable(self, boxname, existant_id, profile):
@@ -259,9 +260,9 @@ class MaildirBox(object):
@param boxname: name of the box to clean
@param existant_id: list of id which actually exist"""
box_data = self.__getBoxData(boxname, profile)
- to_remove=[]
+ to_remove = []
for key in box_data:
- if key not in existant_id and key!="cur_idx":
+ if key not in existant_id and key != "cur_idx":
to_remove.append(key)
for key in to_remove:
del box_data[key]
@@ -271,34 +272,34 @@ class MaildirBox(object):
@param callback: method to call when the the box is updated
@param boxname: name of the box to observe
@param signal: which signal is observed by the caller"""
- if not self.__observed.has_key((profile,boxname)):
- self.__observed[(profile,boxname)]={}
- if not self.__observed[(profile,boxname)].has_key(signal):
- self.__observed[(profile,boxname)][signal]=set()
- self.__observed[(profile,boxname)][signal].add(callback)
+ if (profile, boxname) not in self.__observed:
+ self.__observed[(profile, boxname)] = {}
+ if signal not in self.__observed[(profile, boxname)]:
+ self.__observed[(profile, boxname)][signal] = set()
+ self.__observed[(profile, boxname)][signal].add(callback)
def removeObserver(self, callback, profile, boxname, signal="NEW_MESSAGE"):
"""Remove an observer of maildir box changes
@param callback: method to remove from obervers
@param boxname: name of the box which was observed
@param signal: which signal was observed by the caller"""
- if not self.__observed.has_key((profile,boxname)):
- err_msg=_("Trying to remove an observer for an inexistant mailbox")
+ if (profile, boxname) not in self.__observed:
+ err_msg = _("Trying to remove an observer for an inexistant mailbox")
error(_("INTERNAL ERROR: ") + err_msg)
raise MaildirError(err_msg)
- if not self.__observed[(profile,boxname)].has_key(signal):
- err_msg=_("Trying to remove an inexistant observer, no observer for this signal")
+ if signal not in self.__observed[(profile, boxname)]:
+ err_msg = _("Trying to remove an inexistant observer, no observer for this signal")
error(_("INTERNAL ERROR: ") + err_msg)
raise MaildirError(err_msg)
- if not callback in self.__observed[(profile,boxname)][signal]:
- err_msg=_("Trying to remove an inexistant observer")
+ if not callback in self.__observed[(profile, boxname)][signal]:
+ err_msg = _("Trying to remove an inexistant observer")
error(_("INTERNAL ERROR: ") + err_msg)
raise MaildirError(err_msg)
- self.__observed[(profile,boxname)][signal].remove(callback)
+ self.__observed[(profile, boxname)][signal].remove(callback)
def emitSignal(self, profile, boxname, signal_name):
"""Emit the signal to observer"""
- debug('emitSignal %s %s %s' %(profile, boxname, signal_name))
+ debug('emitSignal %s %s %s' % (profile, boxname, signal_name))
try:
for observer_cb in self.__observed[(profile, boxname)][signal_name]:
observer_cb()
@@ -325,7 +326,7 @@ class MailboxUser(object):
if e.name == "body":
mail.set_payload(e.children[0].encode('utf-8'))
elif e.name == "subject":
- mail['Subject'] = e.children[0].encode('utf-8')
+ mail['Subject'] = e.children[0].encode('utf-8')
return mail.as_string()
def __init__(self, _maildir, name, observer=None, profile="@NONE@"):
@@ -334,36 +335,35 @@ class MailboxUser(object):
@param profile: real profile (ie not a profile_key)
THIS OBJECT MUST NOT BE USED DIRECTLY: use MaildirBox.accessMessageBox instead"""
if _maildir._checkBoxReference(name, profile):
- error ("INTERNAL ERROR: MailboxUser MUST NOT be instancied directly")
+ error("INTERNAL ERROR: MailboxUser MUST NOT be instancied directly")
raise MailboxException('double MailboxUser instanciation')
- if name!="INBOX":
+ if name != "INBOX":
raise NotImplementedError
- self.name=name
- self.profile=profile
- self.maildir=_maildir
+ self.name = name
+ self.profile = profile
+ self.maildir = _maildir
profile_path = self.maildir._getProfilePath(profile)
- full_profile_path = os.path.join(self.maildir.host.memory.getConfig('','local_dir'), profile_path)
+ full_profile_path = os.path.join(self.maildir.host.memory.getConfig('', 'local_dir'), profile_path)
if not os.path.exists(full_profile_path):
- os.makedirs(full_profile_path,0700)
+ os.makedirs(full_profile_path, 0700)
mailbox_path = os.path.join(full_profile_path, MAILDIR_PATH)
- self.mailbox_path=mailbox_path
+ self.mailbox_path = mailbox_path
self.mailbox = maildir.MaildirMailbox(mailbox_path)
- self.observer=observer
+ self.observer = observer
self.__uid_table_update()
if observer:
- debug("adding observer for %s (%s)" % (name,profile))
+ debug("adding observer for %s (%s)" % (name, profile))
self.maildir.addObserver(observer, profile, name, "NEW_MESSAGE")
def __uid_table_update(self):
- existant_id=[]
- for mess_idx in range (self.getMessageCount()):
+ existant_id = []
+ for mess_idx in range(self.getMessageCount()):
#we update the uid table
existant_id.append(self.getId(mess_idx))
self.getUid(mess_idx)
self.maildir.cleanTable(self.name, existant_id, profile=self.profile)
-
def __del__(self):
if observer:
debug("removing observer for %s" % self.name)
@@ -377,8 +377,8 @@ class MailboxUser(object):
def emitSignal(self, ignore, signal):
"""Emit the signal to the observers"""
- if signal=="NEW_MESSAGE":
- self.getUid(self.getMessageCount()-1) #XXX: we make an uid for the last message added
+ if signal == "NEW_MESSAGE":
+ self.getUid(self.getMessageCount() - 1) # XXX: we make an uid for the last message added
self.maildir.emitSignal(self.profile, self.name, signal)
def getId(self, mess_idx):
@@ -388,8 +388,8 @@ class MailboxUser(object):
def getUid(self, mess_idx):
"""Return a unique interger id for the message, always ascending"""
- mess_id=self.getId(mess_idx)
- return self.maildir.getUid(self.name,mess_id, profile=self.profile)
+ mess_id = self.getId(mess_idx)
+ return self.maildir.getUid(self.name, mess_id, profile=self.profile)
def getNextUid(self):
return self.maildir.getNextUid(self.name, profile=self.profile)
@@ -413,7 +413,7 @@ class MailboxUser(object):
"""Return the message index from the uid
@param mess_uid: message unique identifier
@return: message index, as managed by MaildirMailbox"""
- for mess_idx in range (self.getMessageCount()):
+ for mess_idx in range(self.getMessageCount()):
if self.getUid(mess_idx) == mess_uid:
return mess_idx
raise IndexError
@@ -422,7 +422,7 @@ class MailboxUser(object):
"""Return the message index from the unique index
@param mess_id: message unique index as given by MaildirMailbox
@return: message sequence index"""
- for mess_idx in range (self.getMessageCount()):
+ for mess_idx in range(self.getMessageCount()):
if self.mailbox.getUidl(mess_idx) == mess_id:
return mess_idx
raise IndexError
@@ -448,7 +448,7 @@ class MailboxUser(object):
"""Return the flags of the message
@param mess_uid: message unique identifier
@return: list of strings"""
- id = self.maildir.getIdFromUid(self.name,mess_uid, profile=self.profile)
+ id = self.maildir.getIdFromUid(self.name, mess_uid, profile=self.profile)
return self.maildir.getFlags(self.name, id, profile=self.profile)
def setFlags(self, mess_idx, flags):
@@ -464,14 +464,14 @@ class MailboxUser(object):
@param mess_uid: message unique identifier
@param flags: list of strings
"""
- id = self.maildir.getIdFromUid(self.name,mess_uid, profile=self.profile)
+ id = self.maildir.getIdFromUid(self.name, mess_uid, profile=self.profile)
return self.maildir.setFlags(self.name, id, flags, profile=self.profile)
def getMessageIdsWithFlag(self, flag):
"""Return ids of messages where a flag is set
@param flag: flag to check
@return: list of id (as given by MaildirMailbox)"""
- return self.maildir.getMessageIdsWithFlag(self.name,flag, profile=self.profile)
+ return self.maildir.getMessageIdsWithFlag(self.name, flag, profile=self.profile)
def removeDeleted(self):
"""Actually delete message flagged "\\Deleted"
@@ -480,11 +480,10 @@ class MailboxUser(object):
for mess_id in self.getMessageIdsWithFlag("\\Deleted"):
print ("Deleting %s" % mess_id)
self.mailbox.deleteMessage(self.getIdxFromId(mess_id))
- self.mailbox = maildir.MaildirMailbox(self.mailbox_path) #We need to reparse the dir to have coherent indexing
+ self.mailbox = maildir.MaildirMailbox(self.mailbox_path) # We need to reparse the dir to have coherent indexing
self.maildir.purgeDeleted(self.name, profile=self.profile)
def emptyTrash(self):
"""Delete everything in the .Trash dir"""
import shutils
pdb.set_trace()
-
diff --git a/src/plugins/plugin_misc_quiz.py b/src/plugins/plugin_misc_quiz.py
index b5bbcb54..0f28788e 100755
--- a/src/plugins/plugin_misc_quiz.py
+++ b/src/plugins/plugin_misc_quiz.py
@@ -46,14 +46,14 @@ QG_TAG = 'quiz'
QG_REQUEST = MESSAGE + '/' + QG_TAG + '[@xmlns="' + NS_QG + '"]'
PLUGIN_INFO = {
-"name": "Quiz game plugin",
-"import_name": "Quiz",
-"type": "Game",
-"protocols": [],
-"dependencies": ["XEP-0045", "XEP-0249"],
-"main": "Quiz",
-"handler": "yes",
-"description": _("""Implementation of Quiz game""")
+ "name": "Quiz game plugin",
+ "import_name": "Quiz",
+ "type": "Game",
+ "protocols": [],
+ "dependencies": ["XEP-0045", "XEP-0249"],
+ "main": "Quiz",
+ "handler": "yes",
+ "description": _("""Implementation of Quiz game""")
}
@@ -62,66 +62,66 @@ class Quiz(object):
def __init__(self, host):
info(_("Plugin Quiz initialization"))
self.host = host
- self.games={}
- self.waiting_inv = {} #Invitation waiting for people to join to launch a game
- host.bridge.addMethod("quizGameLaunch", ".plugin", in_sign='ass', out_sign='', method=self.quizGameLaunch) #args: players, profile
- host.bridge.addMethod("quizGameCreate", ".plugin", in_sign='sass', out_sign='', method=self.quizGameCreate) #args: room_jid, players, profile
- host.bridge.addMethod("quizGameReady", ".plugin", in_sign='sss', out_sign='', method=self.newPlayerReady) #args: player, referee, profile
+ self.games = {}
+ self.waiting_inv = {} # Invitation waiting for people to join to launch a game
+ host.bridge.addMethod("quizGameLaunch", ".plugin", in_sign='ass', out_sign='', method=self.quizGameLaunch) # args: players, profile
+ host.bridge.addMethod("quizGameCreate", ".plugin", in_sign='sass', out_sign='', method=self.quizGameCreate) # args: room_jid, players, profile
+ host.bridge.addMethod("quizGameReady", ".plugin", in_sign='sss', out_sign='', method=self.newPlayerReady) # args: player, referee, profile
host.bridge.addMethod("quizGameAnswer", ".plugin", in_sign='ssss', out_sign='', method=self.playerAnswer)
- host.bridge.addSignal("quizGameStarted", ".plugin", signature='ssass') #args: room_jid, referee, players, profile
+ host.bridge.addSignal("quizGameStarted", ".plugin", signature='ssass') # args: room_jid, referee, players, profile
host.bridge.addSignal("quizGameNew", ".plugin",
signature='sa{ss}s',
- doc = { 'summary': 'Start a new game',
- 'param_0': "room_jid: jid of game's room",
- 'param_1': "game_data: data of the game",
- 'param_2': '%(doc_profile)s'})
+ doc={'summary': 'Start a new game',
+ 'param_0': "room_jid: jid of game's room",
+ 'param_1': "game_data: data of the game",
+ 'param_2': '%(doc_profile)s'})
host.bridge.addSignal("quizGameQuestion", ".plugin",
- signature = 'sssis',
- doc = { 'summary': "Send the current question",
- 'param_0': "room_jid: jid of game's room",
- 'param_1': "question_id: question id",
- 'param_2': "question: question to ask",
- 'param_3': "timer: timer",
- 'param_4': '%(doc_profile)s'})
+ signature='sssis',
+ doc={'summary': "Send the current question",
+ 'param_0': "room_jid: jid of game's room",
+ 'param_1': "question_id: question id",
+ 'param_2': "question: question to ask",
+ 'param_3': "timer: timer",
+ 'param_4': '%(doc_profile)s'})
host.bridge.addSignal("quizGamePlayerBuzzed", ".plugin",
- signature = 'ssbs',
- doc = { 'summary': "A player just pressed the buzzer",
- 'param_0': "room_jid: jid of game's room",
- 'param_1': "player: player who pushed the buzzer",
- 'param_2': "pause: should the game be paused ?",
- 'param_3': '%(doc_profile)s'})
+ signature='ssbs',
+ doc={'summary': "A player just pressed the buzzer",
+ 'param_0': "room_jid: jid of game's room",
+ 'param_1': "player: player who pushed the buzzer",
+ 'param_2': "pause: should the game be paused ?",
+ 'param_3': '%(doc_profile)s'})
host.bridge.addSignal("quizGamePlayerSays", ".plugin",
- signature = 'sssis',
- doc = { 'summary': "A player just pressed the buzzer",
- 'param_0': "room_jid: jid of game's room",
- 'param_1': "player: player who pushed the buzzer",
- 'param_2': "text: what the player say",
- 'param_3': "delay: how long, in seconds, the text must appear",
- 'param_4': '%(doc_profile)s'})
+ signature='sssis',
+ doc={'summary': "A player just pressed the buzzer",
+ 'param_0': "room_jid: jid of game's room",
+ 'param_1': "player: player who pushed the buzzer",
+ 'param_2': "text: what the player say",
+ 'param_3': "delay: how long, in seconds, the text must appear",
+ 'param_4': '%(doc_profile)s'})
host.bridge.addSignal("quizGameAnswerResult", ".plugin",
- signature = 'ssba{si}s',
- doc = { 'summary': "Result of the just given answer",
- 'param_0': "room_jid: jid of game's room",
- 'param_1': "player: player who gave the answer",
- 'param_2': "good_answer: True if the answer is right",
- 'param_3': "score: dict of score with player as key",
- 'param_4': '%(doc_profile)s'})
+ signature='ssba{si}s',
+ doc={'summary': "Result of the just given answer",
+ 'param_0': "room_jid: jid of game's room",
+ 'param_1': "player: player who gave the answer",
+ 'param_2': "good_answer: True if the answer is right",
+ 'param_3': "score: dict of score with player as key",
+ 'param_4': '%(doc_profile)s'})
host.bridge.addSignal("quizGameTimerExpired", ".plugin",
- signature = 'ss',
- doc = { 'summary': "Nobody answered the question in time",
- 'param_0': "room_jid: jid of game's room",
- 'param_1': '%(doc_profile)s'})
+ signature='ss',
+ doc={'summary': "Nobody answered the question in time",
+ 'param_0': "room_jid: jid of game's room",
+ 'param_1': '%(doc_profile)s'})
host.bridge.addSignal("quizGameTimerRestarted", ".plugin",
- signature = 'sis',
- doc = { 'summary': "Nobody answered the question in time",
- 'param_0': "room_jid: jid of game's room",
- 'param_1': "time_left: time left before timer expiration",
- 'param_2': '%(doc_profile)s'})
+ signature='sis',
+ doc={'summary': "Nobody answered the question in time",
+ 'param_0': "room_jid: jid of game's room",
+ 'param_1': "time_left: time left before timer expiration",
+ 'param_2': '%(doc_profile)s'})
host.trigger.add("MUC user joined", self.userJoinedTrigger)
def createGameElt(self, to_jid, type="normal"):
type = "normal" if to_jid.resource else "groupchat"
- elt = domish.Element((None,'message'))
+ elt = domish.Element((None, 'message'))
elt["to"] = to_jid.full()
elt["type"] = type
elt.addElement((NS_QG, QG_TAG))
@@ -129,9 +129,9 @@ class Quiz(object):
def __game_data_to_xml(self, game_data):
"""Convert a game data dict to domish element"""
- game_data_elt = domish.Element((None,'game_data'))
+ game_data_elt = domish.Element((None, 'game_data'))
for data in game_data:
- data_elt = domish.Element((None,data))
+ data_elt = domish.Element((None, data))
data_elt.addContent(game_data[data])
game_data_elt.addChild(data_elt)
return game_data_elt
@@ -162,12 +162,12 @@ class Quiz(object):
for player in game_data['players']:
score[player] = players_data[player]['score']
- answer_result_elt = domish.Element((None,'answer_result'))
+ answer_result_elt = domish.Element((None, 'answer_result'))
answer_result_elt['player'] = player_answering
answer_result_elt['good_answer'] = str(good_answer)
for player in score:
- score_elt = domish.Element((None,"score"))
+ score_elt = domish.Element((None, "score"))
score_elt['player'] = player
score_elt['score'] = str(score[player])
answer_result_elt.addChild(score_elt)
@@ -176,19 +176,19 @@ class Quiz(object):
def __create_started_elt(self, players):
"""Create a game_started domish element"""
- started_elt = domish.Element((None,'started'))
+ started_elt = domish.Element((None, 'started'))
idx = 0
for player in players:
- player_elt = domish.Element((None,'player'))
+ player_elt = domish.Element((None, 'player'))
player_elt.addContent(player)
player_elt['index'] = str(idx)
- idx+=1
+ idx += 1
started_elt.addChild(player_elt)
return started_elt
def __ask_question(self, question_id, question, timer):
"""Create a element for asking a question"""
- question_elt = domish.Element((None,'question'))
+ question_elt = domish.Element((None, 'question'))
question_elt['id'] = question_id
question_elt['timer'] = str(timer)
question_elt.addContent(question)
@@ -197,14 +197,13 @@ class Quiz(object):
def __start_play(self, room_jid, game_data, profile):
"""Start the game (tell to the first player after dealer to play"""
game_data['stage'] = "play"
- next_player_idx = game_data['current_player'] = (game_data['init_player'] + 1) % len(game_data['players']) #the player after the dealer start
+ next_player_idx = game_data['current_player'] = (game_data['init_player'] + 1) % len(game_data['players']) # the player after the dealer start
game_data['first_player'] = next_player = game_data['players'][next_player_idx]
- to_jid = jid.JID(room_jid.userhost()+"/"+next_player)
+ to_jid = jid.JID(room_jid.userhost() + "/" + next_player)
mess = self.createGameElt(to_jid)
yourturn_elt = mess.firstChildElement().addElement('your_turn')
self.host.profiles[profile].xmlstream.send(mess)
-
def userJoinedTrigger(self, room, user, profile):
"""This trigger is used to check if we are waiting people in this room,
and to create a game if everybody is here"""
@@ -229,8 +228,8 @@ class Quiz(object):
def quizRoomJoined(room):
_room = room.occupantJID.userhostJID()
for player in players:
- self.host.plugins["XEP-0249"].invite(jid.JID(player), room.occupantJID.userhostJID(), {"game":"Quiz"}, profile)
- self.waiting_inv[_room] = (time(), players) #TODO: remove invitation waiting for too long, using the time data
+ self.host.plugins["XEP-0249"].invite(jid.JID(player), room.occupantJID.userhostJID(), {"game": "Quiz"}, profile)
+ self.waiting_inv[_room] = (time(), players) # TODO: remove invitation waiting for too long, using the time data
def after_init(ignore):
room_name = "sat_quiz_%s" % self.host.plugins["XEP-0045"].getUniqueName(profile_key)
@@ -262,28 +261,28 @@ class Quiz(object):
@param room_jid_param: jid of the room
@param players: list of players nick (nick must exist in the room)
@param profile_key: %(doc_profile_key)s"""
- debug (_("Creating Quiz game"))
+ debug(_("Creating Quiz game"))
room_jid = jid.JID(room_jid_param)
profile = self.host.memory.getProfileName(profile_key)
if not profile:
- error (_("profile %s is unknown") % profile_key)
+ error(_("profile %s is unknown") % profile_key)
return
- if self.games.has_key(room_jid):
- warning (_("Quiz game already started in room %s") % room_jid.userhost())
+ if room_jid in self.games:
+ warning(_("Quiz game already started in room %s") % room_jid.userhost())
else:
room_nick = self.host.plugins["XEP-0045"].getRoomNick(room_jid.userhost(), profile)
if not room_nick:
- error ('Internal error')
+ error('Internal error')
return
referee = room_jid.userhost() + '/' + room_nick
status = {}
players_data = {}
for player in players:
- players_data[player] = {'score':0}
+ players_data[player] = {'score': 0}
status[player] = "init"
- self.games[room_jid.userhost()] = {'referee':referee, 'players':players, 'status':status, 'players_data':players_data, 'stage': None}
+ self.games[room_jid.userhost()] = {'referee': referee, 'players': players, 'status': status, 'players_data': players_data, 'stage': None}
for player in players:
- mess = self.createGameElt(jid.JID(room_jid.userhost()+'/'+player))
+ mess = self.createGameElt(jid.JID(room_jid.userhost() + '/' + player))
mess.firstChildElement().addChild(self.__create_started_elt(players))
self.host.profiles[profile].xmlstream.send(mess)
@@ -291,9 +290,9 @@ class Quiz(object):
"""Must be called when player is ready to start a new game"""
profile = self.host.memory.getProfileName(profile_key)
if not profile:
- error (_("profile %s is unknown") % profile_key)
+ error(_("profile %s is unknown") % profile_key)
return
- debug ('new player ready: %s' % profile)
+ debug('new player ready: %s' % profile)
mess = self.createGameElt(jid.JID(referee))
ready_elt = mess.firstChildElement().addElement('player_ready')
ready_elt['player'] = player
@@ -303,9 +302,9 @@ class Quiz(object):
"""Called when a player give an answer"""
profile = self.host.memory.getProfileName(profile_key)
if not profile:
- error (_("profile %s is unknown") % profile_key)
+ error(_("profile %s is unknown") % profile_key)
return
- debug ('new player answer (%(profile)s): %(answer)s' % {'profile':profile, 'answer':answer})
+ debug('new player answer (%(profile)s): %(answer)s' % {'profile': profile, 'answer': answer})
mess = self.createGameElt(jid.JID(referee))
answer_elt = mess.firstChildElement().addElement('player_answer')
answer_elt['player'] = player
@@ -333,7 +332,7 @@ class Quiz(object):
def restartTimer(self, room_jid, profile):
"""Restart a timer with the saved time"""
game_data = self.games[room_jid.userhost()]
- assert(game_data['time_left'] != None)
+ assert game_data['time_left'] is not None
mess = self.createGameElt(room_jid)
restarted_elt = mess.firstChildElement().addElement('timer_restarted')
restarted_elt["time_left"] = str(game_data['time_left'])
@@ -359,7 +358,7 @@ class Quiz(object):
"""Check if the answer given is right"""
game_data = self.games[room_jid.userhost()]
players_data = game_data['players_data']
- good_answer = game_data['question_id'] == "1" and answer=="42"
+ good_answer = game_data['question_id'] == "1" and answer == "42"
players_data[player]['score'] += 1 if good_answer else -1
players_data[player]['score'] = min(9, max(0, players_data[player]['score']))
@@ -374,7 +373,7 @@ class Quiz(object):
def newGame(self, room_jid, profile):
"""Launch a new round"""
- debug (_('new Quiz game'))
+ debug(_('new Quiz game'))
game_data = self.games[room_jid.userhost()]
players = game_data['players']
players_data = game_data['players_data']
@@ -401,30 +400,30 @@ Attention, tu es prêt ?""")}
for elt in game_elt.elements():
- if elt.name == 'started': #new game created
+ if elt.name == 'started': # new game created
players = []
for player in elt.elements():
players.append(unicode(player))
self.host.bridge.quizGameStarted(room_jid.userhost(), from_jid.full(), players, profile)
- elif elt.name == 'player_ready': #ready to play
+ elif elt.name == 'player_ready': # ready to play
player = elt['player']
status = self.games[room_jid.userhost()]['status']
nb_players = len(self.games[room_jid.userhost()]['players'])
status[player] = 'ready'
- debug (_('Player %(player)s is ready to start [status: %(status)s]') % {'player':player, 'status':status})
- if status.values().count('ready') == nb_players: #everybody is ready, we can start the game
+ debug(_('Player %(player)s is ready to start [status: %(status)s]') % {'player': player, 'status': status})
+ if status.values().count('ready') == nb_players: # everybody is ready, we can start the game
self.newGame(room_jid, profile)
elif elt.name == 'game_data':
self.host.bridge.quizGameNew(room_jid.userhost(), self.__xml_to_game_data(elt), profile)
- elif elt.name == 'question': #A question is asked
- self.host.bridge.quizGameQuestion(room_jid.userhost(), elt["id"], unicode(elt), int(elt["timer"]), profile )
+ elif elt.name == 'question': # A question is asked
+ self.host.bridge.quizGameQuestion(room_jid.userhost(), elt["id"], unicode(elt), int(elt["timer"]), profile)
elif elt.name == 'player_answer':
player = elt['player']
- pause = game_data['stage'] == 'question' #we pause the game only if we are have a question at the moment
+ pause = game_data['stage'] == 'question' # we pause the game only if we are have a question at the moment
#we first send a buzzer message
mess = self.createGameElt(room_jid)
buzzer_elt = mess.firstChildElement().addElement('player_buzzed')
@@ -460,10 +459,11 @@ Attention, tu es prêt ?""")}
self.host.bridge.quizGameTimerRestarted(room_jid.userhost(), int(elt['time_left']), profile)
else:
- error (_('Unmanaged game element: %s') % elt.name)
+ error(_('Unmanaged game element: %s') % elt.name)
def getHandler(self, profile):
- return QuizGameHandler(self)
+ return QuizGameHandler(self)
+
class QuizGameHandler (XMPPHandler):
implements(iwokkel.IDisco)
@@ -473,11 +473,10 @@ class QuizGameHandler (XMPPHandler):
self.host = plugin_parent.host
def connectionInitialized(self):
- self.xmlstream.addObserver(QG_REQUEST, self.plugin_parent.quiz_game_cmd, profile = self.parent.profile)
+ self.xmlstream.addObserver(QG_REQUEST, self.plugin_parent.quiz_game_cmd, profile=self.parent.profile)
def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
return [disco.DiscoFeature(NS_QG)]
def getDiscoItems(self, requestor, target, nodeIdentifier=''):
return []
-
diff --git a/src/plugins/plugin_misc_radiocol.py b/src/plugins/plugin_misc_radiocol.py
index b6111562..068447d4 100755
--- a/src/plugins/plugin_misc_radiocol.py
+++ b/src/plugins/plugin_misc_radiocol.py
@@ -43,14 +43,14 @@ RADIOC_TAG = 'radiocol'
RADIOC_REQUEST = MESSAGE + '/' + RADIOC_TAG + '[@xmlns="' + NC_RADIOCOL + '"]'
PLUGIN_INFO = {
-"name": "Radio collective plugin",
-"import_name": "Radiocol",
-"type": "Exp",
-"protocols": [],
-"dependencies": ["XEP-0045", "XEP-0249"],
-"main": "Radiocol",
-"handler": "yes",
-"description": _("""Implementation of radio collective""")
+ "name": "Radio collective plugin",
+ "import_name": "Radiocol",
+ "type": "Exp",
+ "protocols": [],
+ "dependencies": ["XEP-0045", "XEP-0249"],
+ "main": "Radiocol",
+ "handler": "yes",
+ "description": _("""Implementation of radio collective""")
}
QUEUE_LIMIT = 2
@@ -61,21 +61,21 @@ class Radiocol(object):
def __init__(self, host):
info(_("Radio collective initialization"))
self.host = host
- self.radios={}
+ self.radios = {}
host.bridge.addMethod("radiocolLaunch", ".plugin", in_sign='ass', out_sign='', method=self.radiocolLaunch)
host.bridge.addMethod("radiocolCreate", ".plugin", in_sign='ss', out_sign='', method=self.radiocolCreate)
host.bridge.addMethod("radiocolSongAdded", ".plugin", in_sign='sss', out_sign='', method=self.radiocolSongAdded)
- host.bridge.addSignal("radiocolStarted", ".plugin", signature='sss') #room_jid, referee, profile
- host.bridge.addSignal("radiocolSongRejected", ".plugin", signature='sss') #room_jid, reason, profile
- host.bridge.addSignal("radiocolPreload", ".plugin", signature='ssssss') #room_jid, filename, title, artist, album, profile
- host.bridge.addSignal("radiocolPlay", ".plugin", signature='sss') #room_jid, filename, profile
- host.bridge.addSignal("radiocolNoUpload", ".plugin", signature='ss') #room_jid, profile
- host.bridge.addSignal("radiocolUploadOk", ".plugin", signature='ss') #room_jid, profile
+ host.bridge.addSignal("radiocolStarted", ".plugin", signature='sss') # room_jid, referee, profile
+ host.bridge.addSignal("radiocolSongRejected", ".plugin", signature='sss') # room_jid, reason, profile
+ host.bridge.addSignal("radiocolPreload", ".plugin", signature='ssssss') # room_jid, filename, title, artist, album, profile
+ host.bridge.addSignal("radiocolPlay", ".plugin", signature='sss') # room_jid, filename, profile
+ host.bridge.addSignal("radiocolNoUpload", ".plugin", signature='ss') # room_jid, profile
+ host.bridge.addSignal("radiocolUploadOk", ".plugin", signature='ss') # room_jid, profile
host.trigger.add("MUC user joined", self.userJoinedTrigger)
def createRadiocolElt(self, to_jid, type="normal"):
type = "normal" if to_jid.resource else "groupchat"
- elt = domish.Element((None,'message'))
+ elt = domish.Element((None, 'message'))
elt["to"] = to_jid.full()
elt["type"] = type
elt.addElement((NC_RADIOCOL, RADIOC_TAG))
@@ -83,26 +83,25 @@ class Radiocol(object):
def __create_started_elt(self):
"""Create a game_started domish element"""
- started_elt = domish.Element((None,'started'))
+ started_elt = domish.Element((None, 'started'))
return started_elt
def __create_preload_elt(self, sender, filename, title, artist, album):
- preload_elt = domish.Element((None,'preload'))
+ preload_elt = domish.Element((None, 'preload'))
preload_elt['sender'] = sender
- preload_elt['filename'] = filename #XXX: the frontend should know the temporary directory where file is put
+ preload_elt['filename'] = filename # XXX: the frontend should know the temporary directory where file is put
preload_elt['title'] = title
preload_elt['artist'] = artist
preload_elt['album'] = album
return preload_elt
-
def userJoinedTrigger(self, room, user, profile):
"""This trigger is used to check if we are waiting people in this room,
and to create a game if everybody is here"""
room_jid = room.occupantJID.userhost()
- if self.radios.has_key(room_jid) and self.radios[room_jid]["referee"] == room.occupantJID.full():
+ if room_jid in self.radios and self.radios[room_jid]["referee"] == room.occupantJID.full():
#we are in a radiocol room, let's start the party !
- mess = self.createRadiocolElt(jid.JID(room_jid+'/'+user.nick))
+ mess = self.createRadiocolElt(jid.JID(room_jid + '/' + user.nick))
mess.firstChildElement().addChild(self.__create_started_elt())
self.host.profiles[profile].xmlstream.send(mess)
return True
@@ -121,7 +120,7 @@ class Radiocol(object):
_room_jid = room.occupantJID.userhostJID()
self.radiocolCreate(_room_jid.userhost(), profile_key=profile)
for occupant in occupants:
- self.host.plugins["XEP-0249"].invite(jid.JID(occupant), room.occupantJID.userhostJID(), {"game":"Radiocol"}, profile)
+ self.host.plugins["XEP-0249"].invite(jid.JID(occupant), room.occupantJID.userhostJID(), {"game": "Radiocol"}, profile)
def after_init(ignore):
room_name = "sat_radiocol_%s" % self.host.plugins["XEP-0045"].getUniqueName(profile_key)
@@ -153,21 +152,21 @@ class Radiocol(object):
"""Create a new game
@param room_jid_param: jid of the room
@param profile_key: %(doc_profile_key)s"""
- debug (_("Creating Radiocol"))
+ debug(_("Creating Radiocol"))
room_jid = jid.JID(room_jid_param)
profile = self.host.memory.getProfileName(profile_key)
if not profile:
- error (_("profile %s is unknown") % profile_key)
+ error(_("profile %s is unknown") % profile_key)
return
- if self.radios.has_key(room_jid):
- warning (_("Radiocol already started in room %s") % room_jid.userhost())
+ if room_jid in self.radios:
+ warning(_("Radiocol already started in room %s") % room_jid.userhost())
else:
room_nick = self.host.plugins["XEP-0045"].getRoomNick(room_jid.userhost(), profile)
if not room_nick:
- error ('Internal error')
+ error('Internal error')
return
referee = room_jid.userhost() + '/' + room_nick
- self.radios[room_jid.userhost()] = {'referee':referee, 'queue':[], 'upload':True, 'playing': False, 'occupants_data':{}, 'to_delete':{}}
+ self.radios[room_jid.userhost()] = {'referee': referee, 'queue': [], 'upload': True, 'playing': False, 'occupants_data': {}, 'to_delete': {}}
mess = self.createRadiocolElt(jid.JID(room_jid.userhost()))
mess.firstChildElement().addChild(self.__create_started_elt())
self.host.profiles[profile].xmlstream.send(mess)
@@ -189,8 +188,8 @@ class Radiocol(object):
song = OggVorbis(song_path)
except OggVorbisHeaderError:
#this file is not ogg vorbis, we reject it
- unlink(song_path) # FIXME: same host trick (see note above)
- self.host.bridge.radiocolSongRejected(jid.JID(referee).userhost(), \
+ unlink(song_path) # FIXME: same host trick (see note above)
+ self.host.bridge.radiocolSongRejected(jid.JID(referee).userhost(),
"Uploaded file is not Ogg Vorbis song, only Ogg Vorbis songs are acceptable", profile)
"""mess = self.createRadiocolElt(jid.JID(referee))
reject_elt = mess.firstChildElement().addElement(('','song_rejected'))
@@ -204,7 +203,7 @@ class Radiocol(object):
album = song.get("album", ["Unknown"])[0]
length = song.info.length
mess = self.createRadiocolElt(jid.JID(referee))
- added_elt = mess.firstChildElement().addElement(('','song_added'))
+ added_elt = mess.firstChildElement().addElement(('', 'song_added'))
added_elt['filename'] = filename = os.path.basename(song_path)
added_elt['title'] = title
added_elt['artist'] = artist
@@ -212,8 +211,8 @@ class Radiocol(object):
added_elt['length'] = str(length)
self.host.profiles[profile].xmlstream.send(mess)
- radio_data = self.radios[jid.JID(referee).userhost()] #FIXME: referee comes from Libervia's client side, it's unsecure
- radio_data['to_delete'][filename] = song_path #FIXME: works only because of the same host trick, see the note under the docstring
+ radio_data = self.radios[jid.JID(referee).userhost()] # FIXME: referee comes from Libervia's client side, it's unsecure
+ radio_data['to_delete'][filename] = song_path # FIXME: works only because of the same host trick, see the note under the docstring
def playNext(self, room_jid, profile):
""""Play next sont in queue if exists, and put a timer
@@ -231,14 +230,14 @@ class Radiocol(object):
filename, length = queue.pop(0)
mess = self.createRadiocolElt(room_jid)
- play_elt = mess.firstChildElement().addElement(('','play'))
+ play_elt = mess.firstChildElement().addElement(('', 'play'))
play_elt['filename'] = filename
self.host.profiles[profile].xmlstream.send(mess)
if not radio_data['upload'] and len(queue) < QUEUE_LIMIT:
#upload is blocked and we now have resources to get more, we reactivate it
mess = self.createRadiocolElt(room_jid)
- no_upload_elt = mess.firstChildElement().addElement(('','upload_ok'))
+ no_upload_elt = mess.firstChildElement().addElement(('', 'upload_ok'))
self.host.profiles[profile].xmlstream.send(mess)
radio_data['upload'] = True
@@ -250,8 +249,7 @@ class Radiocol(object):
return
#we wait more than the song length to delete the file, to manage poorly reactive networks/clients
- reactor.callLater(length + 90, unlink, file_to_delete) #FIXME: same host trick (see above)
-
+ reactor.callLater(length + 90, unlink, file_to_delete) # FIXME: same host trick (see above)
def radiocol_game_cmd(self, mess_elt, profile):
#FIXME: we should check sender (is it referee ?) here before accepting commands
@@ -264,26 +262,26 @@ class Radiocol(object):
for elt in radio_elt.elements():
- if elt.name == 'started': #new game created
+ if elt.name == 'started': # new game created
self.host.bridge.radiocolStarted(room_jid.userhost(), from_jid.full(), profile)
- elif elt.name == 'preload': #a song is in queue and must be preloaded
+ elif elt.name == 'preload': # a song is in queue and must be preloaded
self.host.bridge.radiocolPreload(room_jid.userhost(), elt['filename'], elt['title'], elt['artist'], elt['album'], profile)
elif elt.name == 'play':
self.host.bridge.radiocolPlay(room_jid.userhost(), elt['filename'], profile)
- elif elt.name == 'song_rejected': #a song has been refused
+ elif elt.name == 'song_rejected': # a song has been refused
self.host.bridge.radiocolSongRejected(room_jid.userhost(), elt['reason'], profile)
elif elt.name == 'no_upload':
self.host.bridge.radiocolNoUpload(room_jid.userhost(), profile)
elif elt.name == 'upload_ok':
self.host.bridge.radiocolUploadOk(room_jid.userhost(), profile)
- elif elt.name == 'song_added': #a song has been added
+ elif elt.name == 'song_added': # a song has been added
#FIXME: we are KISS for the proof of concept: every song is added, to a limit of 3 in queue.
# Need to manage some sort of rules to allow peoples to send songs
if len(queue) >= QUEUE_LIMIT:
#there are already too many songs in queue, we reject this one
mess = self.createRadiocolElt(room_jid)
- reject_elt = mess.firstChildElement().addElement(('','song_rejected'))
+ reject_elt = mess.firstChildElement().addElement(('', 'song_rejected'))
reject_elt['sender'] = from_jid.resource
reject_elt['reason'] = "Too many songs in queue"
#FIXME: add an error code
@@ -296,12 +294,11 @@ class Radiocol(object):
if len(queue) >= QUEUE_LIMIT:
#We are at the limit, we refuse new upload until next play
mess = self.createRadiocolElt(room_jid)
- no_upload_elt = mess.firstChildElement().addElement(('','no_upload'))
+ no_upload_elt = mess.firstChildElement().addElement(('', 'no_upload'))
#FIXME: add an error code
self.host.profiles[profile].xmlstream.send(mess)
radio_data['upload'] = False
-
mess = self.createRadiocolElt(room_jid)
preload_elt = self.__create_preload_elt(from_jid.resource,
elt['filename'],
@@ -316,10 +313,11 @@ class Radiocol(object):
radio_data['playing'] = True
self.playNext(room_jid, profile)
else:
- error (_('Unmanaged game element: %s') % elt.name)
+ error(_('Unmanaged game element: %s') % elt.name)
def getHandler(self, profile):
- return RadiocolHandler(self)
+ return RadiocolHandler(self)
+
class RadiocolHandler (XMPPHandler):
implements(iwokkel.IDisco)
@@ -329,11 +327,10 @@ class RadiocolHandler (XMPPHandler):
self.host = plugin_parent.host
def connectionInitialized(self):
- self.xmlstream.addObserver(RADIOC_REQUEST, self.plugin_parent.radiocol_game_cmd, profile = self.parent.profile)
+ self.xmlstream.addObserver(RADIOC_REQUEST, self.plugin_parent.radiocol_game_cmd, profile=self.parent.profile)
def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
return [disco.DiscoFeature(NC_RADIOCOL)]
def getDiscoItems(self, requestor, target, nodeIdentifier=''):
return []
-
diff --git a/src/plugins/plugin_misc_smtp.py b/src/plugins/plugin_misc_smtp.py
index e52882ed..059a4153 100755
--- a/src/plugins/plugin_misc_smtp.py
+++ b/src/plugins/plugin_misc_smtp.py
@@ -21,34 +21,33 @@ along with this program. If not, see .
from logging import debug, info, error
import warnings
-from twisted.internet import protocol,defer
+from twisted.internet import protocol, defer
from twisted.words.protocols.jabber import error as jab_error
-from twisted.cred import portal,checkers,credentials
+from twisted.cred import portal, checkers, credentials
from twisted.cred import error as cred_error
from twisted.mail import smtp
from twisted.python import failure
from email.parser import Parser
from email.utils import parseaddr
from twisted.mail.imap4 import LOGINCredentials, PLAINCredentials
-import os,os.path
+import os
from twisted.internet import reactor
import sys
-
from zope.interface import implements
-
PLUGIN_INFO = {
-"name": "SMTP server Plugin",
-"import_name": "SMTP",
-"type": "Misc",
-"protocols": [],
-"dependencies": ["Maildir"],
-"main": "SMTP_server",
-"handler": "no",
-"description": _("""Create a SMTP server that you can use to send your "normal" type messages""")
+ "name": "SMTP server Plugin",
+ "import_name": "SMTP",
+ "type": "Misc",
+ "protocols": [],
+ "dependencies": ["Maildir"],
+ "main": "SMTP_server",
+ "handler": "no",
+ "description": _("""Create a SMTP server that you can use to send your "normal" type messages""")
}
+
class SMTP_server(object):
params = """
@@ -74,13 +73,14 @@ class SMTP_server(object):
self.server_factory = SmtpServerFactory(self.host)
reactor.listenTCP(port, self.server_factory)
+
class SatSmtpMessage(object):
implements(smtp.IMessage)
def __init__(self, host, profile):
- self.host=host
- self.profile=profile
- self.message=[]
+ self.host = host
+ self.profile = profile
+ self.message = []
def lineReceived(self, line):
"""handle another line"""
@@ -90,25 +90,26 @@ class SatSmtpMessage(object):
"""handle end of message"""
mail = Parser().parsestr("\n".join(self.message))
try:
- self.host.sendMessage(parseaddr(mail['to'].decode('utf-8','replace'))[1], mail.get_payload().decode('utf-8','replace'), #TODO: manage other charsets
- subject=mail['subject'].decode('utf-8','replace'), mess_type='normal', profile_key=self.profile)
+ self.host.sendMessage(parseaddr(mail['to'].decode('utf-8', 'replace'))[1], mail.get_payload().decode('utf-8', 'replace'), # TODO: manage other charsets
+ subject=mail['subject'].decode('utf-8', 'replace'), mess_type='normal', profile_key=self.profile)
except:
exc_type, exc_value, exc_traceback = sys.exc_info()
- error(_("Can't send message: %s") % exc_value) #The email is invalid or incorreclty parsed
+ error(_("Can't send message: %s") % exc_value) # The email is invalid or incorreclty parsed
return defer.fail()
- self.message=None
+ self.message = None
return defer.succeed(None)
def connectionLost(self):
"""handle message truncated"""
raise smtp.SMTPError
+
class SatSmtpDelivery(object):
implements(smtp.IMessageDelivery)
def __init__(self, host, profile):
- self.host=host
- self.profile=profile
+ self.host = host
+ self.profile = profile
def receivedHeader(self, helo, origin, recipients):
"""
@@ -144,18 +145,20 @@ class SatSmtpDelivery(object):
"""
return origin
+
class SmtpRealm(object):
implements(portal.IRealm)
- def __init__(self,host):
+ def __init__(self, host):
self.host = host
def requestAvatar(self, avatarID, mind, *interfaces):
debug('requestAvatar')
- profile=avatarID.decode('utf-8')
+ profile = avatarID.decode('utf-8')
if smtp.IMessageDelivery not in interfaces:
raise NotImplementedError
- return smtp.IMessageDelivery, SatSmtpDelivery(self.host,profile), lambda:None
+ return smtp.IMessageDelivery, SatSmtpDelivery(self.host, profile), lambda: None
+
class SatProfileCredentialChecker(object):
"""
@@ -167,7 +170,6 @@ class SatProfileCredentialChecker(object):
credentialInterfaces = (credentials.IUsernamePassword,
credentials.IUsernameHashedPassword)
-
def __init__(self, host):
self.host = host
@@ -182,26 +184,26 @@ class SatProfileCredentialChecker(object):
if not credentials.username in profiles:
return defer.fail(cred_error.UnauthorizedLogin())
password = self.host.memory.getParamA("Password", "Connection", profile_key=credentials.username)
- return defer.maybeDeferred(
- credentials.checkPassword,
- password).addCallback(
- self._cbPasswordMatch, credentials.username)
+ return defer.maybeDeferred(credentials.checkPassword,
+ password).addCallback(self._cbPasswordMatch,
+ credentials.username)
+
class SmtpServerFactory(smtp.SMTPFactory):
def __init__(self, host):
self.protocol = smtp.ESMTP
- self.host=host
+ self.host = host
_portal = portal.Portal(SmtpRealm(self.host))
_portal.registerChecker(SatProfileCredentialChecker(self.host))
smtp.SMTPFactory.__init__(self, _portal)
def startedConnecting(self, connector):
- debug (_("SMTP server connection started"))
+ debug(_("SMTP server connection started"))
smtp.SMTPFactory.startedConnecting(self, connector)
def clientConnectionLost(self, connector, reason):
- debug (_("SMTP server connection lost (reason: %s)"), reason)
+ debug(_("SMTP server connection lost (reason: %s)"), reason)
smtp.SMTPFactory.clientConnectionLost(self, connector, reason)
def buildProtocol(self, addr):
@@ -209,4 +211,3 @@ class SmtpServerFactory(smtp.SMTPFactory):
# add the challengers from imap4, more secure and complicated challengers are available
p.challengers = {"LOGIN": LOGINCredentials, "PLAIN": PLAINCredentials}
return p
-
diff --git a/src/plugins/plugin_misc_tarot.py b/src/plugins/plugin_misc_tarot.py
index 1fdb7c4d..2ee1acf3 100755
--- a/src/plugins/plugin_misc_tarot.py
+++ b/src/plugins/plugin_misc_tarot.py
@@ -43,14 +43,14 @@ CG_TAG = 'card_game'
CG_REQUEST = MESSAGE + '/' + CG_TAG + '[@xmlns="' + NS_CG + '"]'
PLUGIN_INFO = {
-"name": "Tarot cards plugin",
-"import_name": "Tarot",
-"type": "Misc",
-"protocols": [],
-"dependencies": ["XEP-0045", "XEP-0249"],
-"main": "Tarot",
-"handler": "yes",
-"description": _("""Implementation of Tarot card game""")
+ "name": "Tarot cards plugin",
+ "import_name": "Tarot",
+ "type": "Misc",
+ "protocols": [],
+ "dependencies": ["XEP-0045", "XEP-0249"],
+ "main": "Tarot",
+ "handler": "yes",
+ "description": _("""Implementation of Tarot card game""")
}
@@ -59,33 +59,33 @@ class Tarot(object):
def __init__(self, host):
info(_("Plugin Tarot initialization"))
self.host = host
- self.games={}
- self.waiting_inv = {} #Invitation waiting for people to join to launch a game
+ self.games = {}
+ self.waiting_inv = {} # Invitation waiting for people to join to launch a game
self.contrats = [_('Passe'), _('Petite'), _('Garde'), _('Garde Sans'), _('Garde Contre')]
- host.bridge.addMethod("tarotGameLaunch", ".plugin", in_sign='ass', out_sign='', method=self.launchGame) #args: room_jid, players, profile
- host.bridge.addMethod("tarotGameCreate", ".plugin", in_sign='sass', out_sign='', method=self.createGame) #args: room_jid, players, profile
- host.bridge.addMethod("tarotGameReady", ".plugin", in_sign='sss', out_sign='', method=self.newPlayerReady) #args: player, referee, profile
- host.bridge.addMethod("tarotGameContratChoosed", ".plugin", in_sign='ssss', out_sign='', method=self.contratChoosed) #args: player, referee, contrat, profile
- host.bridge.addMethod("tarotGamePlayCards", ".plugin", in_sign='ssa(ss)s', out_sign='', method=self.play_cards) #args: player, referee, cards, profile
- host.bridge.addSignal("tarotGameStarted", ".plugin", signature='ssass') #args: room_jid, referee, players, profile
- host.bridge.addSignal("tarotGameNew", ".plugin", signature='sa(ss)s') #args: room_jid, hand, profile
- host.bridge.addSignal("tarotGameChooseContrat", ".plugin", signature='sss') #args: room_jid, xml_data, profile
- host.bridge.addSignal("tarotGameShowCards", ".plugin", signature='ssa(ss)a{ss}s') #args: room_jid, type ["chien", "poignée",...], cards, data[dict], profile
- host.bridge.addSignal("tarotGameCardsPlayed", ".plugin", signature='ssa(ss)s') #args: room_jid, player, type ["chien", "poignée",...], cards, data[dict], profile
- host.bridge.addSignal("tarotGameYourTurn", ".plugin", signature='ss') #args: room_jid, profile
- host.bridge.addSignal("tarotGameScore", ".plugin", signature='ssasass') #args: room_jid, xml_data, winners (list of nicks), loosers (list of nicks), profile
- host.bridge.addSignal("tarotGameInvalidCards", ".plugin", signature='ssa(ss)a(ss)s') #args: room_jid, game phase, played_cards, invalid_cards, profile
+ host.bridge.addMethod("tarotGameLaunch", ".plugin", in_sign='ass', out_sign='', method=self.launchGame) # args: room_jid, players, profile
+ host.bridge.addMethod("tarotGameCreate", ".plugin", in_sign='sass', out_sign='', method=self.createGame) # args: room_jid, players, profile
+ host.bridge.addMethod("tarotGameReady", ".plugin", in_sign='sss', out_sign='', method=self.newPlayerReady) # args: player, referee, profile
+ host.bridge.addMethod("tarotGameContratChoosed", ".plugin", in_sign='ssss', out_sign='', method=self.contratChoosed) # args: player, referee, contrat, profile
+ host.bridge.addMethod("tarotGamePlayCards", ".plugin", in_sign='ssa(ss)s', out_sign='', method=self.play_cards) # args: player, referee, cards, profile
+ host.bridge.addSignal("tarotGameStarted", ".plugin", signature='ssass') # args: room_jid, referee, players, profile
+ host.bridge.addSignal("tarotGameNew", ".plugin", signature='sa(ss)s') # args: room_jid, hand, profile
+ host.bridge.addSignal("tarotGameChooseContrat", ".plugin", signature='sss') # args: room_jid, xml_data, profile
+ host.bridge.addSignal("tarotGameShowCards", ".plugin", signature='ssa(ss)a{ss}s') # args: room_jid, type ["chien", "poignée",...], cards, data[dict], profile
+ host.bridge.addSignal("tarotGameCardsPlayed", ".plugin", signature='ssa(ss)s') # args: room_jid, player, type ["chien", "poignée",...], cards, data[dict], profile
+ host.bridge.addSignal("tarotGameYourTurn", ".plugin", signature='ss') # args: room_jid, profile
+ host.bridge.addSignal("tarotGameScore", ".plugin", signature='ssasass') # args: room_jid, xml_data, winners (list of nicks), loosers (list of nicks), profile
+ host.bridge.addSignal("tarotGameInvalidCards", ".plugin", signature='ssa(ss)a(ss)s') # args: room_jid, game phase, played_cards, invalid_cards, profile
host.trigger.add("MUC user joined", self.userJoinedTrigger)
self.deck_ordered = []
- for value in ['excuse']+map(str,range(1,22)):
- self.deck_ordered.append(TarotCard(("atout",value)))
+ for value in ['excuse'] + map(str, range(1, 22)):
+ self.deck_ordered.append(TarotCard(("atout", value)))
for suit in ["pique", "coeur", "carreau", "trefle"]:
- for value in map(str,range(1,11))+["valet","cavalier","dame","roi"]:
+ for value in map(str, range(1, 11)) + ["valet", "cavalier", "dame", "roi"]:
self.deck_ordered.append(TarotCard((suit, value)))
def createGameElt(self, to_jid, type="normal"):
type = "normal" if to_jid.resource else "groupchat"
- elt = domish.Element((None,'message'))
+ elt = domish.Element((None, 'message'))
elt["to"] = to_jid.full()
elt["type"] = type
elt.addElement((NS_CG, CG_TAG))
@@ -93,9 +93,9 @@ class Tarot(object):
def __card_list_to_xml(self, cards_list, elt_name):
"""Convert a card list to domish element"""
- cards_list_elt = domish.Element((None,elt_name))
+ cards_list_elt = domish.Element((None, elt_name))
for card in cards_list:
- card_elt = domish.Element((None,'card'))
+ card_elt = domish.Element((None, 'card'))
card_elt['suit'] = card.suit
card_elt['value'] = card.value
cards_list_elt.addChild(card_elt)
@@ -108,22 +108,21 @@ class Tarot(object):
cards_list.append((card['suit'], card['value']))
return cards_list
-
def __create_started_elt(self, players):
"""Create a game_started domish element"""
- started_elt = domish.Element((None,'started'))
+ started_elt = domish.Element((None, 'started'))
idx = 0
for player in players:
- player_elt = domish.Element((None,'player'))
+ player_elt = domish.Element((None, 'player'))
player_elt.addContent(player)
player_elt['index'] = str(idx)
- idx+=1
+ idx += 1
started_elt.addChild(player_elt)
return started_elt
def __ask_contrat(self):
"""Create a element for asking contrat"""
- contrat_elt = domish.Element((None,'contrat'))
+ contrat_elt = domish.Element((None, 'contrat'))
form = data_form.Form('form', title=_('contrat selection'))
field = data_form.Field('list-single', 'contrat', options=map(data_form.Option, self.contrats), required=True)
form.addField(field)
@@ -136,18 +135,18 @@ class Tarot(object):
@param winners: list of unicode nicks of winners
@param loosers: list of unicode nicks of loosers"""
- score_elt = domish.Element((None,'score'))
+ score_elt = domish.Element((None, 'score'))
form = data_form.Form('form', title=_('scores'))
for line in scores.split('\n'):
- field = data_form.Field('fixed', value = line)
+ field = data_form.Field('fixed', value=line)
form.addField(field)
score_elt.addChild(form.toElement())
for winner in winners:
- winner_elt = domish.Element((None,'winner'))
+ winner_elt = domish.Element((None, 'winner'))
winner_elt.addContent(winner)
score_elt.addChild(winner_elt)
for looser in loosers:
- looser_elt = domish.Element((None,'looser'))
+ looser_elt = domish.Element((None, 'looser'))
looser_elt.addContent(looser)
score_elt.addChild(looser_elt)
return score_elt
@@ -156,7 +155,7 @@ class Tarot(object):
"""Create a element for invalid_cards error
@param list_cards: list of Card
@param game_phase: phase of the game ['ecart', 'play']"""
- error_elt = domish.Element((None,'error'))
+ error_elt = domish.Element((None, 'error'))
played_elt = self.__card_list_to_xml(played_cards, 'played')
invalid_elt = self.__card_list_to_xml(invalid_cards, 'invalid')
error_elt['type'] = 'invalid_cards'
@@ -165,7 +164,7 @@ class Tarot(object):
error_elt.addChild(invalid_elt)
return error_elt
- def __next_player(self, game_data, next_pl = None):
+ def __next_player(self, game_data, next_pl=None):
"""Increment player number & return player name
@param next_pl: if given, then next_player is forced to this one
"""
@@ -189,7 +188,7 @@ class Tarot(object):
card = players_data[player]['played']
if card.value == "excuse":
continue
- if suit_asked == None:
+ if suit_asked is None:
suit_asked = card.suit
if (card.suit == suit_asked or card.suit == "atout") and card > strongest:
strongest = card
@@ -204,7 +203,7 @@ class Tarot(object):
@param winner: nick of the trick winner"""
#TODO: manage the case where excuse is played on the last trick (and lost)
players_data = game_data['players_data']
- excuse = TarotCard(("atout","excuse"))
+ excuse = TarotCard(("atout", "excuse"))
#we first check if the Excuse was already played
#and if somebody is waiting for a card
@@ -218,7 +217,7 @@ class Tarot(object):
pl_waiting = players_data[player]['wait_for_low']
played.remove(card)
players_data[pl_waiting]['levees'].append(card)
- debug (_('Player %(excuse_owner)s give %(card_waited)s to %(player_waiting)s for Excuse compensation') % {"excuse_owner":player, "card_waited": card, "player_waiting":pl_waiting})
+ debug(_('Player %(excuse_owner)s give %(card_waited)s to %(player_waiting)s for Excuse compensation') % {"excuse_owner": player, "card_waited": card, "player_waiting": pl_waiting})
return
return
@@ -226,14 +225,14 @@ class Tarot(object):
#the Excuse is not on the table, nothing to do
return
- excuse_player = None #Who has played the Excuse ?
+ excuse_player = None # Who has played the Excuse ?
for player in game_data['players']:
if players_data[player]['played'] == excuse:
excuse_player = player
break
if excuse_player == winner:
- return #the excuse player win the trick, nothing to do
+ return # the excuse player win the trick, nothing to do
#first we remove the excuse from played cards
played.remove(excuse)
@@ -244,18 +243,17 @@ class Tarot(object):
low_card = None
#We look backward in cards won by the Excuse owner to
#find a low value card
- for card_idx in range(len(owner_levees)-1, -1, -1):
+ for card_idx in range(len(owner_levees) - 1, -1, -1):
if owner_levees[card_idx].points == 0.5:
low_card = owner_levees[card_idx]
del owner_levees[card_idx]
players_data[winner]['levees'].append(low_card)
- debug (_('Player %(excuse_owner)s give %(card_waited)s to %(player_waiting)s for Excuse compensation') % {"excuse_owner":excuse_player, "card_waited": low_card, "player_waiting":winner})
+ debug(_('Player %(excuse_owner)s give %(card_waited)s to %(player_waiting)s for Excuse compensation') % {"excuse_owner": excuse_player, "card_waited": low_card, "player_waiting": winner})
break
- if not low_card: #The player has no low card yet
+ if not low_card: # The player has no low card yet
#TODO: manage case when player never win a trick with low card
players_data[excuse_player]['wait_for_low'] = winner
- debug(_("%(excuse_owner)s keep the Excuse but has not card to give, %(winner)s is waiting for one") % {'excuse_owner':excuse_player, 'winner':winner})
-
+ debug(_("%(excuse_owner)s keep the Excuse but has not card to give, %(winner)s is waiting for one") % {'excuse_owner': excuse_player, 'winner': winner})
def __draw_game(self, game_data):
"""The game is draw, no score change
@@ -263,14 +261,13 @@ class Tarot(object):
@return: tuple with (string victory message, list of winners, list of loosers)"""
players_data = game_data['players_data']
scores_str = _('Draw game')
- scores_str+='\n'
+ scores_str += '\n'
for player in game_data['players']:
- scores_str+=_("\n--\n%(player)s:\nscore for this game ==> %(score_game)i\ntotal score ==> %(total_score)i") % {'player':player, 'score_game':0, 'total_score': players_data[player]['score']}
+ scores_str += _("\n--\n%(player)s:\nscore for this game ==> %(score_game)i\ntotal score ==> %(total_score)i") % {'player': player, 'score_game': 0, 'total_score': players_data[player]['score']}
debug(scores_str)
return (scores_str, [], [])
-
def __calculate_scores(self, game_data):
"""The game is finished, time to know who won :)
@param game_data: data of the game
@@ -282,7 +279,7 @@ class Tarot(object):
bouts = []
for card in levees:
if card.bout:
- nb_bouts +=1
+ nb_bouts += 1
bouts.append(card.value)
score += card.points
@@ -292,10 +289,10 @@ class Tarot(object):
defenseurs.remove(game_data['attaquant'])
for defenseur in defenseurs:
for card in players_data[defenseur]['levees']:
- check_score+=card.points
+ check_score += card.points
if game_data['contrat'] == "Garde Contre":
for card in game_data['chien']:
- check_score+=card.points
+ check_score += card.points
assert (score + check_score == 91)
point_limit = None
@@ -329,16 +326,16 @@ class Tarot(object):
#TODO: adjust this for 3 and 5 players variants
#TODO: manage bonuses (petit au bout, poignée, chelem)
player_score[player] = points_defenseur if player != game_data['attaquant'] else points_defenseur * -3
- players_data[player]['score'] += player_score[player] #we add score of this game to the global score
+ players_data[player]['score'] += player_score[player] # we add score of this game to the global score
if player_score[player] > 0:
winners.append(player)
else:
loosers.append(player)
- scores_str = _('The attacker (%(attaquant)s) makes %(points)i and needs to make %(point_limit)i (%(nb_bouts)s oulder%(plural)s%(separator)s%(bouts)s): he %(victory)s') % {'attaquant':game_data['attaquant'], 'points':score, 'point_limit':point_limit, 'nb_bouts': nb_bouts, 'plural': 's' if nb_bouts>1 else '', 'separator':': ' if nb_bouts != 0 else '', 'bouts':','.join(map(str,bouts)), 'victory': 'win' if victory else 'loose'}
- scores_str+='\n'
+ scores_str = _('The attacker (%(attaquant)s) makes %(points)i and needs to make %(point_limit)i (%(nb_bouts)s oulder%(plural)s%(separator)s%(bouts)s): he %(victory)s') % {'attaquant': game_data['attaquant'], 'points': score, 'point_limit': point_limit, 'nb_bouts': nb_bouts, 'plural': 's' if nb_bouts > 1 else '', 'separator': ': ' if nb_bouts != 0 else '', 'bouts': ','.join(map(str, bouts)), 'victory': 'win' if victory else 'loose'}
+ scores_str += '\n'
for player in game_data['players']:
- scores_str+=_("\n--\n%(player)s:\nscore for this game ==> %(score_game)i\ntotal score ==> %(total_score)i") % {'player':player, 'score_game':player_score[player], 'total_score': players_data[player]['score']}
+ scores_str += _("\n--\n%(player)s:\nscore for this game ==> %(score_game)i\ntotal score ==> %(total_score)i") % {'player': player, 'score_game': player_score[player], 'total_score': players_data[player]['score']}
debug(scores_str)
return (scores_str, winners, loosers)
@@ -351,7 +348,7 @@ class Tarot(object):
forbidden_cards = []
if game_data['stage'] == 'ecart':
for card in cards:
- if card.bout or card.value=="roi":
+ if card.bout or card.value == "roi":
forbidden_cards.append(card)
#TODO: manage case where atouts (trumps) are in the dog
elif game_data['stage'] == 'play':
@@ -373,7 +370,7 @@ class Tarot(object):
if played_card.suit == "atout" and played_card > biggest_atout:
biggest_atout = played_card
idx = (idx + 1) % len(players)
- has_suit = False #True if there is one card of the asked suit in the hand of the player
+ has_suit = False # True if there is one card of the asked suit in the hand of the player
has_atout = False
biggest_hand_atout = None
@@ -399,18 +396,16 @@ class Tarot(object):
error(_('Internal error: unmanaged game stage'))
return forbidden_cards
-
def __start_play(self, room_jid, game_data, profile):
"""Start the game (tell to the first player after dealer to play"""
game_data['stage'] = "play"
- next_player_idx = game_data['current_player'] = (game_data['init_player'] + 1) % len(game_data['players']) #the player after the dealer start
+ next_player_idx = game_data['current_player'] = (game_data['init_player'] + 1) % len(game_data['players']) # the player after the dealer start
game_data['first_player'] = next_player = game_data['players'][next_player_idx]
- to_jid = jid.JID(room_jid.userhost()+"/"+next_player) #FIXME: gof:
+ to_jid = jid.JID(room_jid.userhost() + "/" + next_player) # FIXME: gof:
mess = self.createGameElt(to_jid)
yourturn_elt = mess.firstChildElement().addElement('your_turn')
self.host.profiles[profile].xmlstream.send(mess)
-
def userJoinedTrigger(self, room, user, profile):
"""This trigger is used to check if we are waiting people in this room,
and to create a game if everybody is here"""
@@ -435,8 +430,8 @@ class Tarot(object):
def tarotRoomJoined(room):
_room = room.occupantJID.userhostJID()
for player in players:
- self.host.plugins["XEP-0249"].invite(jid.JID(player), room.occupantJID.userhostJID(), {"game":"Tarot"}, profile)
- self.waiting_inv[_room] = (time(), players) #TODO: remove invitation waiting for too long, using the time data
+ self.host.plugins["XEP-0249"].invite(jid.JID(player), room.occupantJID.userhostJID(), {"game": "Tarot"}, profile)
+ self.waiting_inv[_room] = (time(), players) # TODO: remove invitation waiting for too long, using the time data
def after_init(ignore):
room_name = "sat_tarot_%s" % self.host.plugins["XEP-0045"].getUniqueName(profile_key)
@@ -464,36 +459,33 @@ class Tarot(object):
return
client.client_initialized.addCallback(after_init)
-
-
-
def createGame(self, room_jid_param, players, profile_key='@NONE@'):
"""Create a new game
@param room_jid_param: jid of the room
@param players: list of players nick (nick must exist in the room)
@param profile_key: %(doc_profile_key)s"""
- debug (_("Creating Tarot game"))
+ debug(_("Creating Tarot game"))
room_jid = jid.JID(room_jid_param)
profile = self.host.memory.getProfileName(profile_key)
if not profile:
- error (_("profile %s is unknown") % profile_key)
+ error(_("profile %s is unknown") % profile_key)
return
- if self.games.has_key(room_jid):
- warning (_("Tarot game already started in room %s") % room_jid.userhost())
+ if room_jid in self.games:
+ warning(_("Tarot game already started in room %s") % room_jid.userhost())
else:
room_nick = self.host.plugins["XEP-0045"].getRoomNick(room_jid.userhost(), profile)
if not room_nick:
- error ('Internal error')
+ error('Internal error')
return
referee = room_jid.userhost() + '/' + room_nick
status = {}
players_data = {}
for player in players:
- players_data[player] = {'score':0}
+ players_data[player] = {'score': 0}
status[player] = "init"
- self.games[room_jid.userhost()] = {'referee':referee, 'players':players, 'status':status, 'players_data':players_data, 'hand_size':18, 'init_player':0, 'current_player': None, 'contrat': None, 'stage': None}
+ self.games[room_jid.userhost()] = {'referee': referee, 'players': players, 'status': status, 'players_data': players_data, 'hand_size': 18, 'init_player': 0, 'current_player': None, 'contrat': None, 'stage': None}
for player in players:
- mess = self.createGameElt(jid.JID(room_jid.userhost()+'/'+player))
+ mess = self.createGameElt(jid.JID(room_jid.userhost() + '/' + player))
mess.firstChildElement().addChild(self.__create_started_elt(players))
self.host.profiles[profile].xmlstream.send(mess)
@@ -501,9 +493,9 @@ class Tarot(object):
"""Must be called when player is ready to start a new game"""
profile = self.host.memory.getProfileName(profile_key)
if not profile:
- error (_("profile %s is unknown") % profile_key)
+ error(_("profile %s is unknown") % profile_key)
return
- debug ('new player ready: %s' % profile)
+ debug('new player ready: %s' % profile)
mess = self.createGameElt(jid.JID(referee))
ready_elt = mess.firstChildElement().addElement('player_ready')
ready_elt['player'] = player
@@ -518,11 +510,11 @@ class Tarot(object):
"""
profile = self.host.memory.getProfileName(profile_key)
if not profile:
- error (_("profile %s is unknown") % profile_key)
+ error(_("profile %s is unknown") % profile_key)
return
- debug (_('contrat [%(contrat)s] choosed by %(profile)s') % {'contrat':contrat, 'profile':profile})
+ debug(_('contrat [%(contrat)s] choosed by %(profile)s') % {'contrat': contrat, 'profile': profile})
mess = self.createGameElt(jid.JID(referee))
- contrat_elt = mess.firstChildElement().addElement(('','contrat_choosed'), content=contrat)
+ contrat_elt = mess.firstChildElement().addElement(('', 'contrat_choosed'), content=contrat)
contrat_elt['player'] = player
self.host.profiles[profile].xmlstream.send(mess)
@@ -535,9 +527,9 @@ class Tarot(object):
"""
profile = self.host.memory.getProfileName(profile_key)
if not profile:
- error (_("profile %s is unknown") % profile_key)
+ error(_("profile %s is unknown") % profile_key)
return
- debug (_('Cards played by %(profile)s: [%(cards)s]') % {'profile':profile,'cards':cards})
+ debug(_('Cards played by %(profile)s: [%(cards)s]') % {'profile': profile, 'cards': cards})
mess = self.createGameElt(jid.JID(referee))
playcard_elt = mess.firstChildElement().addChild(self.__card_list_to_xml(TarotCard.from_tuples(cards), 'cards_played'))
playcard_elt['player'] = player
@@ -545,7 +537,7 @@ class Tarot(object):
def newGame(self, room_jid, profile):
"""Launch a new round"""
- debug (_('new Tarot game'))
+ debug(_('new Tarot game'))
deck = self.deck_ordered[:]
random.shuffle(deck)
game_data = self.games[room_jid.userhost()]
@@ -553,7 +545,7 @@ class Tarot(object):
players_data = game_data['players_data']
current_player = game_data['current_player']
game_data['stage'] = "init"
- game_data['first_player'] = None #first player for the current trick
+ game_data['first_player'] = None # first player for the current trick
game_data['contrat'] = None
hand = game_data['hand'] = {}
hand_size = game_data['hand_size']
@@ -565,23 +557,22 @@ class Tarot(object):
del(deck[:])
for player in players:
- to_jid = jid.JID(room_jid.userhost()+"/"+player) #FIXME: gof:
+ to_jid = jid.JID(room_jid.userhost() + "/" + player) # FIXME: gof:
mess = self.createGameElt(to_jid)
mess.firstChildElement().addChild(self.__card_list_to_xml(hand[player], 'hand'))
self.host.profiles[profile].xmlstream.send(mess)
players_data[player]['contrat'] = None
- players_data[player]['levees'] = [] #cards won
- players_data[player]['played'] = None #card on the table
- players_data[player]['wait_for_low'] = None #Used when a player wait for a low card because of excuse
+ players_data[player]['levees'] = [] # cards won
+ players_data[player]['played'] = None # card on the table
+ players_data[player]['wait_for_low'] = None # Used when a player wait for a low card because of excuse
- pl_idx = game_data['current_player'] = (game_data['init_player'] + 1) % len(players) #the player after the dealer start
+ pl_idx = game_data['current_player'] = (game_data['init_player'] + 1) % len(players) # the player after the dealer start
player = players[pl_idx]
- to_jid = jid.JID(room_jid.userhost()+"/"+player) #FIXME: gof:
+ to_jid = jid.JID(room_jid.userhost() + "/" + player) # FIXME: gof:
mess = self.createGameElt(to_jid)
mess.firstChildElement().addChild(self.__ask_contrat())
self.host.profiles[profile].xmlstream.send(mess)
-
def card_game_cmd(self, mess_elt, profile):
from_jid = jid.JID(mess_elt['from'])
room_jid = jid.JID(from_jid.userhost())
@@ -591,25 +582,25 @@ class Tarot(object):
for elt in game_elt.elements():
- if elt.name == 'started': #new game created
+ if elt.name == 'started': # new game created
players = []
for player in elt.elements():
players.append(unicode(player))
self.host.bridge.tarotGameStarted(room_jid.userhost(), from_jid.full(), players, profile)
- elif elt.name == 'player_ready': #ready to play
+ elif elt.name == 'player_ready': # ready to play
player = elt['player']
status = self.games[room_jid.userhost()]['status']
nb_players = len(self.games[room_jid.userhost()]['players'])
status[player] = 'ready'
- debug (_('Player %(player)s is ready to start [status: %(status)s]') % {'player':player, 'status':status})
- if status.values().count('ready') == nb_players: #everybody is ready, we can start the game
+ debug(_('Player %(player)s is ready to start [status: %(status)s]') % {'player': player, 'status': status})
+ if status.values().count('ready') == nb_players: # everybody is ready, we can start the game
self.newGame(room_jid, profile)
- elif elt.name == 'hand': #a new hand has been received
+ elif elt.name == 'hand': # a new hand has been received
self.host.bridge.tarotGameNew(room_jid.userhost(), self.__xml_to_list(elt), profile)
- 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())
xml_data = dataForm2xml(form)
self.host.bridge.tarotGameChooseContrat(room_jid.userhost(), xml_data, profile)
@@ -623,7 +614,7 @@ class Tarot(object):
if contrats.count(None):
#not everybody has choosed his contrat, it's next one turn
player = self.__next_player(game_data)
- to_jid = jid.JID(room_jid.userhost()+"/"+player) #FIXME: gof:
+ to_jid = jid.JID(room_jid.userhost() + "/" + player) # FIXME: gof:
mess = self.createGameElt(to_jid)
mess.firstChildElement().addChild(self.__ask_contrat())
self.host.profiles[profile].xmlstream.send(mess)
@@ -642,11 +633,11 @@ class Tarot(object):
mess = self.createGameElt(to_jid)
mess.firstChildElement().addChild(self.__give_scores(*self.__draw_game(game_data)))
self.host.profiles[profile].xmlstream.send(mess)
- game_data['init_player'] = (game_data['init_player'] + 1) % len(game_data['players']) #we change the dealer
+ game_data['init_player'] = (game_data['init_player'] + 1) % len(game_data['players']) # we change the dealer
for player in game_data['players']:
game_data['status'][player] = "init"
return
- debug (_("%(player)s win the bid with %(contrat)s") % {'player':best_contrat[0],'contrat':best_contrat[1]})
+ debug(_("%(player)s win the bid with %(contrat)s") % {'player': best_contrat[0], 'contrat': best_contrat[1]})
game_data['contrat'] = best_contrat[1]
if game_data['contrat'] == "Garde Sans" or game_data['contrat'] == "Garde Contre":
@@ -654,7 +645,7 @@ class Tarot(object):
game_data['attaquant'] = best_contrat[0]
else:
#Time to show the chien to everybody
- to_jid = jid.JID(room_jid.userhost()) #FIXME: gof:
+ to_jid = jid.JID(room_jid.userhost()) # FIXME: gof:
mess = self.createGameElt(to_jid)
chien_elt = mess.firstChildElement().addChild(self.__card_list_to_xml(game_data['chien'], 'chien'))
chien_elt['attaquant'] = best_contrat[0]
@@ -668,10 +659,9 @@ class Tarot(object):
players_data[best_contrat[0]]['levees'].extend(game_data['chien'])
del game_data['chien'][:]
-
- elif elt.name == 'chien': #we have received the chien
- debug (_("tarot: chien received"))
- data = {"attaquant":elt['attaquant']}
+ elif elt.name == 'chien': # we have received the chien
+ debug(_("tarot: chien received"))
+ data = {"attaquant": elt['attaquant']}
game_data['stage'] = "ecart"
game_data['attaquant'] = elt['attaquant']
self.host.bridge.tarotGameShowCards(room_jid.userhost(), "chien", self.__xml_to_list(elt), data, profile)
@@ -679,18 +669,18 @@ class Tarot(object):
elif elt.name == 'cards_played':
if game_data['stage'] == "ecart":
#TODO: show atouts (trumps) if player put some in écart
- assert (game_data['attaquant'] == elt['player']) #TODO: throw an xml error here
+ assert (game_data['attaquant'] == elt['player']) # TODO: throw an xml error here
list_cards = TarotCard.from_tuples(self.__xml_to_list(elt))
#we now check validity of card
invalid_cards = self.__invalid_cards(game_data, list_cards)
if invalid_cards:
- mess = self.createGameElt(jid.JID(room_jid.userhost()+'/'+elt['player']))
+ mess = self.createGameElt(jid.JID(room_jid.userhost() + '/' + elt['player']))
mess.firstChildElement().addChild(self.__invalid_cards_elt(list_cards, invalid_cards, game_data['stage']))
self.host.profiles[profile].xmlstream.send(mess)
return
#FIXME: gof: manage Garde Sans & Garde Contre cases
- players_data[elt['player']]['levees'].extend(list_cards) #we add the chien to attaquant's levées
+ players_data[elt['player']]['levees'].extend(list_cards) # we add the chien to attaquant's levées
for card in list_cards:
game_data['hand'][elt['player']].remove(card)
@@ -706,7 +696,7 @@ class Tarot(object):
#we first check validity of card
invalid_cards = self.__invalid_cards(game_data, cards)
if invalid_cards:
- mess = self.createGameElt(jid.JID(room_jid.userhost()+'/'+current_player))
+ mess = self.createGameElt(jid.JID(room_jid.userhost() + '/' + current_player))
mess.firstChildElement().addChild(self.__invalid_cards_elt(cards, invalid_cards, game_data['stage']))
self.host.profiles[profile].xmlstream.send(mess)
return
@@ -725,7 +715,7 @@ class Tarot(object):
if all(played):
#everybody has played
winner = self.__winner(game_data)
- debug (_('The winner of this trick is %s') % winner)
+ debug(_('The winner of this trick is %s') % winner)
#the winner win the trick
self.__excuse_hack(game_data, played, winner)
players_data[elt['player']]['levees'].extend(played)
@@ -738,7 +728,7 @@ class Tarot(object):
mess = self.createGameElt(to_jid)
chien_elt = mess.firstChildElement().addChild(self.__give_scores(*self.__calculate_scores(game_data)))
self.host.profiles[profile].xmlstream.send(mess)
- game_data['init_player'] = (game_data['init_player'] + 1) % len(game_data['players']) #we change the dealer
+ game_data['init_player'] = (game_data['init_player'] + 1) % len(game_data['players']) # we change the dealer
for player in game_data['players']:
game_data['status'][player] = "init"
return
@@ -748,7 +738,7 @@ class Tarot(object):
next_player = self.__next_player(game_data)
#finally, we tell to the next player to play
- to_jid = jid.JID(room_jid.userhost()+"/"+next_player)
+ to_jid = jid.JID(room_jid.userhost() + "/" + next_player)
mess = self.createGameElt(to_jid)
yourturn_elt = mess.firstChildElement().addElement('your_turn')
self.host.profiles[profile].xmlstream.send(mess)
@@ -757,7 +747,7 @@ class Tarot(object):
self.host.bridge.tarotGameYourTurn(room_jid.userhost(), profile)
elif elt.name == 'score':
- form_elt = elt.elements(name='x',uri='jabber:x:data').next()
+ form_elt = elt.elements(name='x', uri='jabber:x:data').next()
winners = []
loosers = []
for winner in elt.elements(name='winner', uri=NS_CG):
@@ -769,16 +759,17 @@ class Tarot(object):
self.host.bridge.tarotGameScore(room_jid.userhost(), xml_data, winners, loosers, profile)
elif elt.name == 'error':
if elt['type'] == 'invalid_cards':
- played_cards = self.__xml_to_list(elt.elements(name='played',uri=NS_CG).next())
- invalid_cards = self.__xml_to_list(elt.elements(name='invalid',uri=NS_CG).next())
+ played_cards = self.__xml_to_list(elt.elements(name='played', uri=NS_CG).next())
+ invalid_cards = self.__xml_to_list(elt.elements(name='invalid', uri=NS_CG).next())
self.host.bridge.tarotGameInvalidCards(room_jid.userhost(), elt['phase'], played_cards, invalid_cards, profile)
else:
- error (_('Unmanaged error type: %s') % elt['type'])
+ error(_('Unmanaged error type: %s') % elt['type'])
else:
- error (_('Unmanaged card game element: %s') % elt.name)
+ error(_('Unmanaged card game element: %s') % elt.name)
def getHandler(self, profile):
- return CardGameHandler(self)
+ return CardGameHandler(self)
+
class CardGameHandler (XMPPHandler):
implements(iwokkel.IDisco)
@@ -788,11 +779,10 @@ class CardGameHandler (XMPPHandler):
self.host = plugin_parent.host
def connectionInitialized(self):
- self.xmlstream.addObserver(CG_REQUEST, self.plugin_parent.card_game_cmd, profile = self.parent.profile)
+ self.xmlstream.addObserver(CG_REQUEST, self.plugin_parent.card_game_cmd, profile=self.parent.profile)
def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
return [disco.DiscoFeature(NS_CG)]
def getDiscoItems(self, requestor, target, nodeIdentifier=''):
return []
-
diff --git a/src/plugins/plugin_misc_text_commands.py b/src/plugins/plugin_misc_text_commands.py
index 7354bf1b..ee688c5d 100755
--- a/src/plugins/plugin_misc_text_commands.py
+++ b/src/plugins/plugin_misc_text_commands.py
@@ -23,16 +23,17 @@ from twisted.words.protocols.jabber import jid
from logging import debug, info, warning, error
PLUGIN_INFO = {
-"name": "Text commands",
-"import_name": "text-commands",
-"type": "Misc",
-"protocols": [],
-"dependencies": ["XEP-0045", "EXP-PARROT"],
-"main": "TextCommands",
-"handler": "no",
-"description": _("""IRC like text commands""")
+ "name": "Text commands",
+ "import_name": "text-commands",
+ "type": "Misc",
+ "protocols": [],
+ "dependencies": ["XEP-0045", "EXP-PARROT"],
+ "main": "TextCommands",
+ "handler": "no",
+ "description": _("""IRC like text commands""")
}
+
class TextCommands(object):
#FIXME: doc strings for commands have to be translatable
# plugins need a dynamic translation system (translation
@@ -52,13 +53,13 @@ class TextCommands(object):
if command.isalpha():
# looks like an actual command, we try to call the corresponding method
try:
- mess_data["unparsed"] = msg[1+len(command):] #part not yet parsed of the message
- return getattr(self,"cmd_%s" % command)(mess_data,profile)
+ mess_data["unparsed"] = msg[1 + len(command):] # part not yet parsed of the message
+ return getattr(self, "cmd_%s" % command)(mess_data, profile)
except AttributeError:
pass
- elif msg[0] == '\\': #we have escape char
+ elif msg[0] == '\\': # we have escape char
try:
- if msg[1] in ('/','\\'): # we have '\/' or '\\', we escape to '/' or '\'
+ if msg[1] in ('/', '\\'): # we have '\/' or '\\', we escape to '/' or '\'
mess_data["message"] = msg[1:]
except IndexError:
pass
@@ -72,9 +73,9 @@ class TextCommands(object):
"""
nb_arobas = arg.count('@')
if nb_arobas == 1:
- if arg[-1] !='@':
+ if arg[-1] != '@':
return jid.JID(arg)
- return jid.JID(arg+service_jid)
+ return jid.JID(arg + service_jid)
return jid.JID(u"%s@%s" % (arg, service_jid))
def _feedBack(self, message, mess_data, profile):
@@ -99,7 +100,7 @@ class TextCommands(object):
nick = mess_data["unparsed"].strip()
room = mess_data["to"]
- self.host.plugins["XEP-0045"].nick(room,nick,profile)
+ self.host.plugins["XEP-0045"].nick(room, nick, profile)
return False
@@ -134,7 +135,7 @@ class TextCommands(object):
else:
room = mess_data["to"]
- self.host.plugins["XEP-0045"].leave(room,profile)
+ self.host.plugins["XEP-0045"].leave(room, profile)
return False
@@ -183,7 +184,7 @@ class TextCommands(object):
self.host.plugins["EXP-PARROT"].addParrot(link_left_jid, link_right_jid, profile)
self.host.plugins["EXP-PARROT"].addParrot(link_right_jid, link_left_jid, profile)
- self._feedBack("Parrot mode activated for %s" % (unicode(link_left_jid),), mess_data, profile)
+ self._feedBack("Parrot mode activated for %s" % (unicode(link_left_jid), ), mess_data, profile)
return False
@@ -210,7 +211,7 @@ class TextCommands(object):
def cmd_help(self, mess_data, profile):
"""show help on available commands"""
- commands=filter(lambda method: method.startswith('cmd_'), dir(self))
+ commands = filter(lambda method: method.startswith('cmd_'), dir(self))
longuest = max([len(command) for command in commands])
help_cmds = []
@@ -223,7 +224,5 @@ class TextCommands(object):
spaces = (longuest - len(command)) * ' '
help_cmds.append(" /%s: %s %s" % (command[4:], spaces, help_str))
- help_mess = _(u"Text commands available:\n%s") % (u'\n'.join(help_cmds),)
+ help_mess = _(u"Text commands available:\n%s") % (u'\n'.join(help_cmds), )
self._feedBack(help_mess, mess_data, profile)
-
-
diff --git a/src/plugins/plugin_misc_xmllog.py b/src/plugins/plugin_misc_xmllog.py
index 22c5d2c3..fd7a8319 100755
--- a/src/plugins/plugin_misc_xmllog.py
+++ b/src/plugins/plugin_misc_xmllog.py
@@ -24,24 +24,25 @@ from twisted.words.protocols.jabber.xmlstream import XmlStream
from twisted.words.xish import domish
PLUGIN_INFO = {
-"name": "Raw XML log Plugin",
-"import_name": "XmlLog",
-"type": "Misc",
-"protocols": [],
-"dependencies": [],
-"main": "XmlLog",
-"handler": "no",
-"description": _("""Send raw XML logs to bridge""")
+ "name": "Raw XML log Plugin",
+ "import_name": "XmlLog",
+ "type": "Misc",
+ "protocols": [],
+ "dependencies": [],
+ "main": "XmlLog",
+ "handler": "no",
+ "description": _("""Send raw XML logs to bridge""")
}
+
class LoggingXmlStream(XmlStream):
"""This class send the raw XML to the Bridge, for logging purpose"""
def send(self, obj):
- if isinstance(obj,basestring):
- log=unicode(obj)
+ if isinstance(obj, basestring):
+ log = unicode(obj)
elif isinstance(obj, domish.Element):
- log=obj.toXml()
+ log = obj.toXml()
else:
error(_('INTERNAL ERROR: Unmanaged XML type'))
self._host.bridge.xmlLog("OUT", log, self._profile)
@@ -72,7 +73,7 @@ class XmlLog(object):
host.memory.importParams(self.params)
#bridge
- host.bridge.addSignal("xmlLog", ".plugin", signature='sss') #args: direction("IN" or "OUT"), xml_data, profile
+ host.bridge.addSignal("xmlLog", ".plugin", signature='sss') # args: direction("IN" or "OUT"), xml_data, profile
do_log = self.host.memory.getParamA("Xml log", "Debug")
if do_log:
diff --git a/src/plugins/plugin_xep_0020.py b/src/plugins/plugin_xep_0020.py
index d153e033..7c7c6d85 100755
--- a/src/plugins/plugin_xep_0020.py
+++ b/src/plugins/plugin_xep_0020.py
@@ -35,15 +35,16 @@ from wokkel import disco, iwokkel, data_form
NS_FEATURE_NEG = 'http://jabber.org/protocol/feature-neg'
PLUGIN_INFO = {
-"name": "XEP 0020 Plugin",
-"import_name": "XEP-0020",
-"type": "XEP",
-"protocols": ["XEP-0020"],
-"main": "XEP_0020",
-"handler": "yes",
-"description": _("""Implementation of Feature Negotiation""")
+ "name": "XEP 0020 Plugin",
+ "import_name": "XEP-0020",
+ "type": "XEP",
+ "protocols": ["XEP-0020"],
+ "main": "XEP_0020",
+ "handler": "yes",
+ "description": _("""Implementation of Feature Negotiation""")
}
+
class XEP_0020(object):
def __init__(self, host):
@@ -67,7 +68,7 @@ class XEP_0020(object):
for field in form.fields:
values = form.fields[field].values
result[field] = values[0] if values else None
- if len(values)>1:
+ if len(values) > 1:
warning(_("More than one value choosed for %s, keeping the first one") % field)
return result
@@ -92,7 +93,7 @@ class XEP_0020(object):
feature_elt.addChild(x_form.toElement())
return feature_elt
- def proposeFeatures(self, options_dict, namespace = None):
+ def proposeFeatures(self, options_dict, namespace=None):
"""Build a feature element with options to propose
@param options_dict: dict with feature as key and list of acceptable options as value
@param namespace: feature namespace"""
@@ -104,6 +105,7 @@ class XEP_0020(object):
feature_elt.addChild(x_form.toElement())
return feature_elt
+
class XEP_0020_handler(XMPPHandler):
implements(iwokkel.IDisco)
@@ -112,4 +114,3 @@ class XEP_0020_handler(XMPPHandler):
def getDiscoItems(self, requestor, target, nodeIdentifier=''):
return []
-
diff --git a/src/plugins/plugin_xep_0045.py b/src/plugins/plugin_xep_0045.py
index 1419391f..3cb866e3 100755
--- a/src/plugins/plugin_xep_0045.py
+++ b/src/plugins/plugin_xep_0045.py
@@ -36,53 +36,55 @@ except ImportError:
from wokkel.subprotocols import XMPPHandler
PLUGIN_INFO = {
-"name": "XEP 0045 Plugin",
-"import_name": "XEP-0045",
-"type": "XEP",
-"protocols": ["XEP-0045"],
-"dependencies": [],
-"main": "XEP_0045",
-"handler": "yes",
-"description": _("""Implementation of Multi-User Chat""")
+ "name": "XEP 0045 Plugin",
+ "import_name": "XEP-0045",
+ "type": "XEP",
+ "protocols": ["XEP-0045"],
+ "dependencies": [],
+ "main": "XEP_0045",
+ "handler": "yes",
+ "description": _("""Implementation of Multi-User Chat""")
}
+
class UnknownRoom(Exception):
pass
+
class XEP_0045(object):
def __init__(self, host):
info(_("Plugin XEP_0045 initialization"))
self.host = host
- self.clients={}
+ self.clients = {}
host.bridge.addMethod("joinMUC", ".plugin", in_sign='ssa{ss}s', out_sign='', method=self._join)
host.bridge.addMethod("mucNick", ".plugin", in_sign='sss', out_sign='', method=self.mucNick)
host.bridge.addMethod("mucLeave", ".plugin", in_sign='ss', out_sign='', method=self.leave)
host.bridge.addMethod("getRoomsJoined", ".plugin", in_sign='s', out_sign='a(sass)', method=self.getRoomsJoined)
host.bridge.addMethod("getRoomsSubjects", ".plugin", in_sign='s', out_sign='a(ss)', method=self.getRoomsSubjects)
host.bridge.addMethod("getUniqueRoomName", ".plugin", in_sign='s', out_sign='s', method=self.getUniqueName)
- host.bridge.addSignal("roomJoined", ".plugin", signature='sasss') #args: room_jid, room_nicks, user_nick, profile
- host.bridge.addSignal("roomLeft", ".plugin", signature='ss') #args: room_jid, profile
- host.bridge.addSignal("roomUserJoined", ".plugin", signature='ssa{ss}s') #args: room_jid, user_nick, user_data, profile
- host.bridge.addSignal("roomUserLeft", ".plugin", signature='ssa{ss}s') #args: room_jid, user_nick, user_data, profile
- host.bridge.addSignal("roomUserChangedNick", ".plugin", signature='ssss') #args: room_jid, old_nick, new_nick, profile
- host.bridge.addSignal("roomNewSubject", ".plugin", signature='sss') #args: room_jid, subject, profile
-
+ host.bridge.addSignal("roomJoined", ".plugin", signature='sasss') # args: room_jid, room_nicks, user_nick, profile
+ host.bridge.addSignal("roomLeft", ".plugin", signature='ss') # args: room_jid, profile
+ host.bridge.addSignal("roomUserJoined", ".plugin", signature='ssa{ss}s') # args: room_jid, user_nick, user_data, profile
+ host.bridge.addSignal("roomUserLeft", ".plugin", signature='ssa{ss}s') # args: room_jid, user_nick, user_data, profile
+ host.bridge.addSignal("roomUserChangedNick", ".plugin", signature='ssss') # args: room_jid, old_nick, new_nick, profile
+ host.bridge.addSignal("roomNewSubject", ".plugin", signature='sss') # args: room_jid, subject, profile
def __check_profile(self, profile):
"""check if profile is used and connected
if profile known but disconnected, remove it from known profiles
@param profile: profile to check
@return: True if the profile is known and connected, else False"""
- if not profile or not self.clients.has_key(profile) or not self.host.isConnected(profile):
- error (_('Unknown or disconnected profile (%s)') % profile)
- if self.clients.has_key(profile):
+ if not profile or profile not in self.clients or not self.host.isConnected(profile):
+ error(_('Unknown or disconnected profile (%s)') % profile)
+ if profile in self.clients:
del self.clients[profile]
return False
return True
def __room_joined(self, room, profile):
"""Called when the user is in the requested room"""
+
def _sendBridgeSignal(ignore=None):
self.host.bridge.roomJoined(room.roomJID.userhost(), [user.nick for user in room.roster.values()], room.nick, profile)
@@ -99,16 +101,15 @@ class XEP_0045(object):
_sendBridgeSignal()
return room
-
def __err_joining_room(self, failure, room_jid, nick, history_options, password, profile):
"""Called when something is going wrong when joining the room"""
if failure.value.condition == 'conflict':
# we have a nickname conflict, we try again with "_" suffixed to current nickname
nick += '_'
- return self.clients[profile].join(room_jid, nick, history_options, password).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile':profile}, errbackArgs=[room_jid, nick, history_options, password, profile])
+ return self.clients[profile].join(room_jid, nick, history_options, password).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile': profile}, errbackArgs=[room_jid, nick, history_options, password, profile])
mess = _("Error when joining the room")
- error (mess)
+ error(mess)
self.host.bridge.newAlert(mess, _("Group chat error"), "ERROR", profile)
raise failure
@@ -128,7 +129,7 @@ class XEP_0045(object):
@profile_key: profile
@return: nick or empty string in case of error"""
profile = self.host.memory.getProfileName(profile_key)
- if not self.__check_profile(profile) or not self.clients[profile].joined_rooms.has_key(room_jid_s):
+ if not self.__check_profile(profile) or room_jid_s not in self.clients[profile].joined_rooms:
return ''
return self.clients[profile].joined_rooms[room_jid_s].nick
@@ -137,7 +138,7 @@ class XEP_0045(object):
profile = self.host.memory.getProfileName(profile)
if not self.__check_profile(profile):
raise exceptions.UnknownProfileError("Unknown or disconnected profile")
- if not self.clients[profile].joined_rooms.has_key(room_jid.userhost()):
+ if room_jid.userhost() not in self.clients[profile].joined_rooms:
raise UnknownRoom("This room has not been joined")
return self.clients[profile].joined_rooms[room_jid.userhost()].inRoster(nick)
@@ -155,7 +156,7 @@ class XEP_0045(object):
return uuid.uuid1()
def join(self, room_jid, nick, options, profile_key='@DEFAULT@'):
- def _errDeferred(exc_obj = Exception, txt='Error while joining room'):
+ def _errDeferred(exc_obj=Exception, txt='Error while joining room'):
d = defer.Deferred()
d.errback(exc_obj(txt))
return d
@@ -163,15 +164,15 @@ class XEP_0045(object):
profile = self.host.memory.getProfileName(profile_key)
if not self.__check_profile(profile):
return _errDeferred()
- if self.clients[profile].joined_rooms.has_key(room_jid.userhost()):
- warning(_('%(profile)s is already in room %(room_jid)s') % {'profile':profile, 'room_jid':room_jid.userhost()})
+ if room_jid.userhost() in self.clients[profile].joined_rooms:
+ warning(_('%(profile)s is already in room %(room_jid)s') % {'profile': profile, 'room_jid': room_jid.userhost()})
return _errDeferred()
- info (_("[%(profile)s] is joining room %(room)s with nick %(nick)s") % {'profile':profile,'room':room_jid.userhost(), 'nick':nick})
+ info(_("[%(profile)s] is joining room %(room)s with nick %(nick)s") % {'profile': profile, 'room': room_jid.userhost(), 'nick': nick})
- history_options = options["history"] == "True" if options.has_key("history") else None
- password = options["password"] if options.has_key("password") else None
+ history_options = options["history"] == "True" if "history" in options else None
+ password = options["password"] if "password" in options else None
- return self.clients[profile].join(room_jid, nick, history_options, password).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile':profile}, errbackArgs=[room_jid, nick, history_options, password, profile])
+ return self.clients[profile].join(room_jid, nick, history_options, password).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile': profile}, errbackArgs=[room_jid, nick, history_options, password, profile])
def _join(self, room_jid_s, nick, options={}, profile_key='@DEFAULT@'):
"""join method used by bridge: use the _join method, but doesn't return any deferred"""
@@ -186,13 +187,13 @@ class XEP_0045(object):
self.host.bridge.newAlert(mess, _("Group chat error"), "ERROR", profile)
return
d = self.join(room_jid, nick, options, profile)
- d.addErrback(lambda x: warning(_('Error while joining room'))) #TODO: error management + signal in bridge
+ d.addErrback(lambda x: warning(_('Error while joining room'))) # TODO: error management + signal in bridge
def nick(self, room_jid, nick, profile_key):
profile = self.host.memory.getProfileName(profile_key)
if not self.__check_profile(profile):
raise exceptions.UnknownProfileError("Unknown or disconnected profile")
- if not self.clients[profile].joined_rooms.has_key(room_jid.userhost()):
+ if room_jid.userhost() not in self.clients[profile].joined_rooms:
raise UnknownRoom("This room has not been joined")
return self.clients[profile].nick(room_jid, nick)
@@ -200,7 +201,7 @@ class XEP_0045(object):
profile = self.host.memory.getProfileName(profile_key)
if not self.__check_profile(profile):
raise exceptions.UnknownProfileError("Unknown or disconnected profile")
- if not self.clients[profile].joined_rooms.has_key(room_jid.userhost()):
+ if room_jid.userhost() not in self.clients[profile].joined_rooms:
raise UnknownRoom("This room has not been joined")
return self.clients[profile].leave(room_jid)
@@ -208,7 +209,7 @@ class XEP_0045(object):
profile = self.host.memory.getProfileName(profile_key)
if not self.__check_profile(profile):
raise exceptions.UnknownProfileError("Unknown or disconnected profile")
- if not self.clients[profile].joined_rooms.has_key(room_jid.userhost()):
+ if room_jid.userhost() not in self.clients[profile].joined_rooms:
raise UnknownRoom("This room has not been joined")
return self.clients[profile].subject(room_jid, subject)
@@ -232,9 +233,9 @@ class SatMUCClient (muc.MUCClient):
self.plugin_parent = plugin_parent
self.host = plugin_parent.host
muc.MUCClient.__init__(self)
- self.joined_rooms = {} #FIXME: seem to do the same thing as MUCClient's _rooms attribute, must be removed
+ self.joined_rooms = {} # FIXME: seem to do the same thing as MUCClient's _rooms attribute, must be removed
self.rec_subjects = {}
- self.__changing_nicks = set() # used to keep trace of who is changing nick,
+ self.__changing_nicks = set() # used to keep trace of who is changing nick,
# and to discard userJoinedRoom signal in this case
print "init SatMUCClient OK"
@@ -271,35 +272,35 @@ class SatMUCClient (muc.MUCClient):
if user.nick in self.__changing_nicks:
self.__changing_nicks.remove(user.nick)
else:
- debug (_("user %(nick)s has joined room (%(room_id)s)") % {'nick':user.nick, 'room_id':room.occupantJID.userhost()})
+ debug(_("user %(nick)s has joined room (%(room_id)s)") % {'nick': user.nick, 'room_id': room.occupantJID.userhost()})
if not self.host.trigger.point("MUC user joined", room, user, self.parent.profile):
return
- user_data={'entity':user.entity.full() if user.entity else '', 'affiliation':user.affiliation, 'role':user.role}
+ user_data = {'entity': user.entity.full() if user.entity else '', 'affiliation': user.affiliation, 'role': user.role}
self.host.bridge.roomUserJoined(room.roomJID.userhost(), user.nick, user_data, self.parent.profile)
def userLeftRoom(self, room, user):
if user.nick == room.nick:
# we left the room
room_jid_s = room.roomJID.userhost()
- info (_("Room [%(room)s] left (%(profile)s))") % { "room": room_jid_s,
- "profile": self.parent.profile })
+ info(_("Room [%(room)s] left (%(profile)s))") % {"room": room_jid_s,
+ "profile": self.parent.profile})
self.host.memory.delEntityCache(room.roomJID, self.parent.profile)
del self.plugin_parent.clients[self.parent.profile].joined_rooms[room_jid_s]
self.host.bridge.roomLeft(room.roomJID.userhost(), self.parent.profile)
else:
- debug (_("user %(nick)s left room (%(room_id)s)") % {'nick':user.nick, 'room_id':room.occupantJID.userhost()})
- user_data={'entity':user.entity.full() if user.entity else '', 'affiliation':user.affiliation, 'role':user.role}
+ debug(_("user %(nick)s left room (%(room_id)s)") % {'nick': user.nick, 'room_id': room.occupantJID.userhost()})
+ user_data = {'entity': user.entity.full() if user.entity else '', 'affiliation': user.affiliation, 'role': user.role}
self.host.bridge.roomUserLeft(room.roomJID.userhost(), user.nick, user_data, self.parent.profile)
def userChangedNick(self, room, user, new_nick):
- self.host.bridge.roomUserChangedNick(room.roomJID.userhost(), user.nick, new_nick, self.parent.profile)
+ self.host.bridge.roomUserChangedNick(room.roomJID.userhost(), user.nick, new_nick, self.parent.profile)
def userUpdatedStatus(self, room, user, show, status):
print("FIXME: MUC status not managed yet")
#FIXME:
def receivedSubject(self, room, user, subject):
- debug (_("New subject for room (%(room_id)s): %(subject)s") % {'room_id':room.roomJID.full(),'subject':subject})
+ debug(_("New subject for room (%(room_id)s): %(subject)s") % {'room_id': room.roomJID.full(), 'subject': subject})
self.rec_subjects[room.roomJID.userhost()] = (room.roomJID.userhost(), subject)
self.host.bridge.roomNewSubject(room.roomJID.userhost(), subject, self.parent.profile)
@@ -311,4 +312,3 @@ class SatMUCClient (muc.MUCClient):
#def getDiscoItems(self, requestor, target, nodeIdentifier=''):
#return []
-
diff --git a/src/plugins/plugin_xep_0047.py b/src/plugins/plugin_xep_0047.py
index 244d3e3b..8fb6891e 100644
--- a/src/plugins/plugin_xep_0047.py
+++ b/src/plugins/plugin_xep_0047.py
@@ -44,19 +44,20 @@ IBB_OPEN = IQ_SET + '/open[@xmlns="' + NS_IBB + '"]'
IBB_CLOSE = IQ_SET + '/close[@xmlns="' + NS_IBB + '" and @sid="%s"]'
IBB_IQ_DATA = IQ_SET + '/data[@xmlns="' + NS_IBB + '" and @sid="%s"]'
IBB_MESSAGE_DATA = MESSAGE + '/data[@xmlns="' + NS_IBB + '" and @sid="%s"]'
-TIMEOUT = 60 #timeout for workflow
+TIMEOUT = 60 # timeout for workflow
BLOCK_SIZE = 4096
PLUGIN_INFO = {
-"name": "In-Band Bytestream Plugin",
-"import_name": "XEP-0047",
-"type": "XEP",
-"protocols": ["XEP-0047"],
-"main": "XEP_0047",
-"handler": "yes",
-"description": _("""Implementation of In-Band Bytestreams""")
+ "name": "In-Band Bytestream Plugin",
+ "import_name": "XEP-0047",
+ "type": "XEP",
+ "protocols": ["XEP-0047"],
+ "main": "XEP_0047",
+ "handler": "yes",
+ "description": _("""Implementation of In-Band Bytestreams""")
}
+
class XEP_0047(object):
NAMESPACE = NS_IBB
@@ -71,7 +72,7 @@ class XEP_0047(object):
client = self.host.getClient(profile)
if not client:
raise ProfileNotInCacheError
- client.xep_0047_current_stream = {} #key: stream_id, value: data(dict)
+ client.xep_0047_current_stream = {} # key: stream_id, value: data(dict)
def _timeOut(self, sid, profile):
"""Delecte current_stream id, called after timeout
@@ -87,14 +88,14 @@ class XEP_0047(object):
if not client:
warning(_("Client no more in cache"))
return
- if not client.xep_0047_current_stream.has_key(sid):
+ if sid not in client.xep_0047_current_stream:
warning(_("kill id called on a non existant id"))
return
- if client.xep_0047_current_stream[sid].has_key("observer_cb"):
+ if "observer_cb" in client.xep_0047_current_stream[sid]:
client.xmlstream.removeObserver(client.xep_0047_current_stream[sid]["event_data"], client.xep_0047_current_stream[sid]["observer_cb"])
if client.xep_0047_current_stream[sid]['timer'].active():
client.xep_0047_current_stream[sid]['timer'].cancel()
- if client.xep_0047_current_stream[sid].has_key("size"):
+ if "size" in client.xep_0047_current_stream[sid]:
self.host.removeProgressCB(sid, profile)
file_obj = client.xep_0047_current_stream[sid]['file_obj']
@@ -145,7 +146,7 @@ class XEP_0047(object):
def streamOpening(self, IQ, profile):
debug(_("IBB stream opening"))
- IQ.handled=True
+ IQ.handled = True
client = self.host.getClient(profile)
if not client:
raise ProfileNotInCacheError
@@ -153,7 +154,7 @@ class XEP_0047(object):
block_size = open_elt.getAttribute('block-size')
sid = open_elt.getAttribute('sid')
stanza = open_elt.getAttribute('stanza', 'iq')
- if not sid or not block_size or int(block_size)>65535:
+ if not sid or not block_size or int(block_size) > 65535:
warning(_("malformed IBB transfer: %s" % IQ['id']))
self.sendNotAcceptableError(IQ['id'], IQ['from'], client.xmlstream)
return
@@ -173,12 +174,12 @@ class XEP_0047(object):
client.xep_0047_current_stream[sid]["timer"].reset(TIMEOUT)
#we save the xmlstream, events and observer data to allow observer removal
- client.xep_0047_current_stream[sid]["event_data"] = event_data = (IBB_MESSAGE_DATA if stanza=='message' else IBB_IQ_DATA) % sid
- client.xep_0047_current_stream[sid]["observer_cb"] = observer_cb = self.messageData if stanza=='message' else self.iqData
+ client.xep_0047_current_stream[sid]["event_data"] = event_data = (IBB_MESSAGE_DATA if stanza == 'message' else IBB_IQ_DATA) % sid
+ client.xep_0047_current_stream[sid]["observer_cb"] = observer_cb = self.messageData if stanza == 'message' else self.iqData
event_close = IBB_CLOSE % sid
#we now set the stream observer to look after data packet
- client.xmlstream.addObserver(event_data, observer_cb, profile = profile)
- client.xmlstream.addOnetimeObserver(event_close, self.streamClosing, profile = profile)
+ client.xmlstream.addObserver(event_data, observer_cb, profile=profile)
+ client.xmlstream.addOnetimeObserver(event_close, self.streamClosing, profile=profile)
#finally, we send the accept stanza
result = domish.Element((None, 'iq'))
result['type'] = 'result'
@@ -187,7 +188,7 @@ class XEP_0047(object):
client.xmlstream.send(result)
def streamClosing(self, IQ, profile):
- IQ.handled=True
+ IQ.handled = True
client = self.host.getClient(profile)
if not client:
raise ProfileNotInCacheError
@@ -202,7 +203,7 @@ class XEP_0047(object):
self._killId(sid, success=True, profile=profile)
def iqData(self, IQ, profile):
- IQ.handled=True
+ IQ.handled = True
client = self.host.getClient(profile)
if not client:
raise ProfileNotInCacheError
@@ -219,7 +220,7 @@ class XEP_0047(object):
def messageData(self, message_elt, profile):
data_elt = message_elt.firstChildElement()
- sid = message_elt.getAttribute('id','')
+ sid = message_elt.getAttribute('id', '')
self._manageDataElt(message_elt, 'message', sid, jid.JID(message_elt['from']), profile)
def _manageDataElt(self, data_elt, stanza, sid, stanza_from_jid, profile):
@@ -239,14 +240,14 @@ class XEP_0047(object):
if stanza_from_jid != from_jid:
warning(_("sended jid inconsistency (man in the middle attack attempt ?)"))
- if stanza=='iq':
+ if stanza == 'iq':
self.sendNotAcceptableError(sid, from_jid, client.xmlstream)
return False
- client.xep_0047_current_stream[sid]["seq"]+=1
- if int(data_elt.getAttribute("seq",-1)) != client.xep_0047_current_stream[sid]["seq"]:
+ client.xep_0047_current_stream[sid]["seq"] += 1
+ if int(data_elt.getAttribute("seq", -1)) != client.xep_0047_current_stream[sid]["seq"]:
warning(_("Sequence error"))
- if stanza=='iq':
+ if stanza == 'iq':
self.sendNotAcceptableError(data_elt["id"], from_jid, client.xmlstream)
return False
@@ -259,7 +260,7 @@ class XEP_0047(object):
except TypeError:
#The base64 data is invalid
warning(_("Invalid base64 data"))
- if stanza=='iq':
+ if stanza == 'iq':
self.sendNotAcceptableError(data_elt["id"], from_jid, client.xmlstream)
return False
return True
@@ -275,10 +276,10 @@ class XEP_0047(object):
result['to'] = to_jid
error_el = result.addElement('error')
error_el['type'] = 'cancel'
- error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas','not-acceptable'))
+ error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas', 'not-acceptable'))
xmlstream.send(result)
- def startStream(self, file_obj, to_jid, sid, length, successCb, failureCb, size = None, profile=None):
+ def startStream(self, file_obj, to_jid, sid, length, successCb, failureCb, size=None, profile=None):
"""Launch the stream workflow
@param file_obj: file_obj to send
@param to_jid: JID of the recipient
@@ -290,7 +291,7 @@ class XEP_0047(object):
client = self.host.getClient(profile)
if not client:
raise ProfileNotInCacheError
- if length != None:
+ if length is not None:
error(_('stream length not managed yet'))
return
data = client.xep_0047_current_stream[sid] = {}
@@ -303,10 +304,10 @@ class XEP_0047(object):
if size:
data["size"] = size
self.host.registerProgressCB(sid, self.getProgress, profile)
- iq_elt = jabber_client.IQ(client.xmlstream,'set')
+ iq_elt = jabber_client.IQ(client.xmlstream, 'set')
iq_elt['from'] = client.jid.full()
iq_elt['to'] = to_jid.full()
- open_elt = iq_elt.addElement('open',NS_IBB)
+ open_elt = iq_elt.addElement('open', NS_IBB)
open_elt['block-size'] = str(BLOCK_SIZE)
open_elt['sid'] = sid
open_elt['stanza'] = 'iq'
@@ -329,18 +330,18 @@ class XEP_0047(object):
buffer = data["file_obj"].read(data["block_size"])
if buffer:
- next_iq_elt = jabber_client.IQ(client.xmlstream,'set')
+ next_iq_elt = jabber_client.IQ(client.xmlstream, 'set')
next_iq_elt['to'] = data["to"].full()
data_elt = next_iq_elt.addElement('data', NS_IBB)
data_elt['seq'] = str(seq)
data_elt['sid'] = sid
data_elt.addContent(base64.b64encode(buffer))
- next_iq_elt.addCallback(self.iqResult, sid, seq+1, length, profile)
+ next_iq_elt.addCallback(self.iqResult, sid, seq + 1, length, profile)
next_iq_elt.send()
else:
self.terminateStream(sid, profile=profile)
- def terminateStream(self, sid, failure_reason = None, profile=None):
+ def terminateStream(self, sid, failure_reason=None, profile=None):
"""Terminate the stream session
@param to_jid: recipient
@param sid: Session id
@@ -353,9 +354,9 @@ class XEP_0047(object):
if not client:
raise ProfileNotInCacheError
data = client.xep_0047_current_stream[sid]
- iq_elt = jabber_client.IQ(client.xmlstream,'set')
+ iq_elt = jabber_client.IQ(client.xmlstream, 'set')
iq_elt['to'] = data["to"].full()
- close_elt = iq_elt.addElement('close',NS_IBB)
+ close_elt = iq_elt.addElement('close', NS_IBB)
close_elt['sid'] = sid
iq_elt.send()
self.host.removeProgressCB(sid, profile)
@@ -364,14 +365,15 @@ class XEP_0047(object):
else:
self._killId(sid, True, profile=profile)
+
class XEP_0047_handler(XMPPHandler):
implements(iwokkel.IDisco)
- def __init__(self,parent):
+ def __init__(self, parent):
self.plugin_parent = parent
def connectionInitialized(self):
- self.xmlstream.addObserver(IBB_OPEN, self.plugin_parent.streamOpening, profile = self.parent.profile)
+ self.xmlstream.addObserver(IBB_OPEN, self.plugin_parent.streamOpening, profile=self.parent.profile)
def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
return [disco.DiscoFeature(NS_IBB)]
diff --git a/src/plugins/plugin_xep_0054.py b/src/plugins/plugin_xep_0054.py
index 3ef3148f..8824ba6c 100755
--- a/src/plugins/plugin_xep_0054.py
+++ b/src/plugins/plugin_xep_0054.py
@@ -31,7 +31,7 @@ from zope.interface import implements
from wokkel import disco, iwokkel
-from base64 import b64decode,b64encode
+from base64 import b64decode, b64encode
from hashlib import sha1
from sat.core import exceptions
from sat.memory.persistent import PersistentDict
@@ -47,23 +47,24 @@ AVATAR_PATH = "avatars"
IQ_GET = '/iq[@type="get"]'
NS_VCARD = 'vcard-temp'
-VCARD_REQUEST = IQ_GET + '/vCard[@xmlns="' + NS_VCARD + '"]' #TODO: manage requests
+VCARD_REQUEST = IQ_GET + '/vCard[@xmlns="' + NS_VCARD + '"]' # TODO: manage requests
PRESENCE = '/presence'
NS_VCARD_UPDATE = 'vcard-temp:x:update'
-VCARD_UPDATE = PRESENCE + '/x[@xmlns="' + NS_VCARD_UPDATE + '"]'
+VCARD_UPDATE = PRESENCE + '/x[@xmlns="' + NS_VCARD_UPDATE + '"]'
PLUGIN_INFO = {
-"name": "XEP 0054 Plugin",
-"import_name": "XEP-0054",
-"type": "XEP",
-"protocols": ["XEP-0054", "XEP-0153"],
-"dependencies": [],
-"main": "XEP_0054",
-"handler": "yes",
-"description": _("""Implementation of vcard-temp""")
+ "name": "XEP 0054 Plugin",
+ "import_name": "XEP-0054",
+ "type": "XEP",
+ "protocols": ["XEP-0054", "XEP-0153"],
+ "dependencies": [],
+ "main": "XEP_0054",
+ "handler": "yes",
+ "description": _("""Implementation of vcard-temp""")
}
+
class XEP_0054(object):
#TODO: - check that nickname is ok
# - refactor the code/better use of Wokkel
@@ -76,10 +77,10 @@ class XEP_0054(object):
if not os.path.exists(self.avatar_path):
os.makedirs(self.avatar_path)
self.avatars_cache = PersistentDict(NS_VCARD)
- self.avatars_cache.load() #FIXME: resulting deferred must be correctly managed
+ self.avatars_cache.load() # FIXME: resulting deferred must be correctly managed
host.bridge.addMethod("getCard", ".plugin", in_sign='ss', out_sign='s', method=self.getCard)
host.bridge.addMethod("getAvatarFile", ".plugin", in_sign='s', out_sign='s', method=self.getAvatarFile)
- host.bridge.addMethod("setAvatar", ".plugin", in_sign='ss', out_sign='', method=self.setAvatar, async = True)
+ host.bridge.addMethod("setAvatar", ".plugin", in_sign='ss', out_sign='', method=self.setAvatar, async=True)
host.trigger.add("presence_available", self.presenceTrigger)
def getHandler(self, profile):
@@ -144,9 +145,9 @@ class XEP_0054(object):
debug(_('Decoding binary'))
decoded = b64decode(str(elem))
image_hash = sha1(decoded).hexdigest()
- filename = self.avatar_path+'/'+image_hash
+ filename = self.avatar_path + '/' + image_hash
if not os.path.exists(filename):
- with open(filename,'wb') as file:
+ with open(filename, 'wb') as file:
file.write(decoded)
debug(_("file saved to %s") % image_hash)
else:
@@ -156,7 +157,7 @@ class XEP_0054(object):
@inlineCallbacks
def vCard2Dict(self, vcard, target, profile):
"""Convert a VCard to a dict, and save binaries"""
- debug (_("parsing vcard"))
+ debug(_("parsing vcard"))
dictionary = {}
for elem in vcard.elements():
@@ -173,18 +174,18 @@ class XEP_0054(object):
dictionary['birthday'] = unicode(elem)
elif elem.name == 'PHOTO':
dictionary["avatar"] = yield threads.deferToThread(self.save_photo, elem)
- if not dictionary["avatar"]: #can happen in case of e.g. empty photo elem
+ if not dictionary["avatar"]: # can happen in case of e.g. empty photo elem
del dictionary['avatar']
else:
self.update_cache(target, 'avatar', dictionary['avatar'], profile)
else:
- info (_('FIXME: [%s] VCard tag is not managed yet') % elem.name)
+ info(_('FIXME: [%s] VCard tag is not managed yet') % elem.name)
returnValue(dictionary)
def vcard_ok(self, answer, profile):
"""Called after the first get IQ"""
- debug (_("VCard found"))
+ debug(_("VCard found"))
if answer.firstChildElement().name == "vCard":
_jid, steam = self.host.getJidNStream(profile)
@@ -195,13 +196,13 @@ class XEP_0054(object):
d = self.vCard2Dict(answer.firstChildElement(), from_jid, profile)
d.addCallback(lambda data: self.host.bridge.actionResult("RESULT", answer['id'], data, profile))
else:
- error (_("FIXME: vCard not found as first child element"))
- self.host.bridge.actionResult("SUPPRESS", answer['id'], {}, profile) #FIXME: maybe an error message would be better
+ error(_("FIXME: vCard not found as first child element"))
+ self.host.bridge.actionResult("SUPPRESS", answer['id'], {}, profile) # FIXME: maybe an error message would be better
def vcard_err(self, failure, profile):
"""Called when something is wrong with registration"""
- error (_("Can't find VCard of %s") % failure.value.stanza['from'])
- self.host.bridge.actionResult("SUPPRESS", failure.value.stanza['id'], {}, profile) #FIXME: maybe an error message would be better
+ error(_("Can't find VCard of %s") % failure.value.stanza['from'])
+ self.host.bridge.actionResult("SUPPRESS", failure.value.stanza['id'], {}, profile) # FIXME: maybe an error message would be better
def getCard(self, target_s, profile_key='@DEFAULT@'):
"""Ask server for VCard
@@ -209,13 +210,13 @@ class XEP_0054(object):
@result: id to retrieve the profile"""
current_jid, xmlstream = self.host.getJidNStream(profile_key)
if not xmlstream:
- error (_('Asking vcard for a non-existant or not connected profile'))
+ error(_('Asking vcard for a non-existant or not connected profile'))
return ""
profile = self.host.memory.getProfileName(profile_key)
to_jid = jid.JID(target_s)
debug(_("Asking for %s's VCard") % to_jid.userhost())
- reg_request=IQ(xmlstream,'get')
- reg_request["from"]=current_jid.full()
+ reg_request = IQ(xmlstream, 'get')
+ reg_request["from"] = current_jid.full()
reg_request["to"] = to_jid.userhost()
reg_request.addElement('vCard', NS_VCARD)
reg_request.send(to_jid.userhost()).addCallbacks(self.vcard_ok, self.vcard_err, callbackArgs=[profile], errbackArgs=[profile])
@@ -226,9 +227,9 @@ class XEP_0054(object):
@param hash: SHA1 hash
@return full_path
"""
- filename = self.avatar_path+'/'+avatar_hash
+ filename = self.avatar_path + '/' + avatar_hash
if not os.path.exists(filename):
- error (_("Asking for an uncached avatar [%s]") % avatar_hash)
+ error(_("Asking for an uncached avatar [%s]") % avatar_hash)
return ""
return filename
@@ -259,13 +260,13 @@ class XEP_0054(object):
if not client:
raise exceptions.NotConnectedProfileError(_('Trying to set avatar for a non-existant or not connected profile'))
- vcard_set = IQ(client.xmlstream,'set')
+ vcard_set = IQ(client.xmlstream, 'set')
d = threads.deferToThread(self._buildSetAvatar, vcard_set, filepath)
def elementBuilt(result):
"""Called once the image is at the right size/format, and the vcard set element is build"""
set_avatar_elt, img_hash = result
- self.avatars_cache[client.jid.userhost()] = img_hash # we need to update the hash, so we can send a new presence
+ self.avatars_cache[client.jid.userhost()] = img_hash # we need to update the hash, so we can send a new presence
# element with the right hash
return set_avatar_elt.send().addCallback(lambda ignore: client.presence.available())
@@ -296,7 +297,7 @@ class XEP_0054_handler(XMPPHandler):
"""
from_jid = jid.JID(presence['from'])
#FIXME: wokkel's data_form should be used here
- x_elem = filter (lambda x:x.name == "x", presence.elements())[0] #We only want the "x" element
+ x_elem = filter(lambda x: x.name == "x", presence.elements())[0] # We only want the "x" element
for elem in x_elem.elements():
if elem.name == 'photo':
_hash = str(elem)
diff --git a/src/plugins/plugin_xep_0060.py b/src/plugins/plugin_xep_0060.py
index 3b3003fa..6714c967 100755
--- a/src/plugins/plugin_xep_0060.py
+++ b/src/plugins/plugin_xep_0060.py
@@ -30,23 +30,24 @@ from wokkel import disco, iwokkel, pubsub
from zope.interface import implements
PLUGIN_INFO = {
-"name": "Publish-Subscribe",
-"import_name": "XEP-0060",
-"type": "XEP",
-"protocols": ["XEP-0060"],
-"dependencies": [],
-"main": "XEP_0060",
-"handler": "yes",
-"description": _("""Implementation of PubSub Protocol""")
+ "name": "Publish-Subscribe",
+ "import_name": "XEP-0060",
+ "type": "XEP",
+ "protocols": ["XEP-0060"],
+ "dependencies": [],
+ "main": "XEP_0060",
+ "handler": "yes",
+ "description": _("""Implementation of PubSub Protocol""")
}
+
class XEP_0060(object):
def __init__(self, host):
info(_("PubSub plugin initialization"))
self.host = host
- self.managedNodes=[]
- self.clients={}
+ self.managedNodes = []
+ self.clients = {}
"""host.bridge.addMethod("getItems", ".plugin", in_sign='ssa{ss}s', out_sign='as', method=self.getItems,
async = True,
doc = { 'summary':'retrieve items',
@@ -78,8 +79,8 @@ class XEP_0060(object):
profile = self.host.memory.getProfileName(profile_key)
if not profile:
err_mess = _('Trying to %(action)s with an unknown profile key [%(profile_key)s]') % {
- 'action':action,
- 'profile_key':profile_key}
+ 'action': action,
+ 'profile_key': profile_key}
error(err_mess)
raise Exception(err_mess)
try:
@@ -91,31 +92,31 @@ class XEP_0060(object):
return profile, client
def publish(self, service, nodeIdentifier, items=None, profile_key='@DEFAULT@'):
- profile,client = self.__getClientNProfile(profile_key, 'publish item')
+ profile, client = self.__getClientNProfile(profile_key, 'publish item')
return client.publish(service, nodeIdentifier, items, client.parent.jid)
def getItems(self, service, node, max_items=None, sub_id=None, profile_key='@DEFAULT@'):
- profile,client = self.__getClientNProfile(profile_key, 'get items')
+ profile, client = self.__getClientNProfile(profile_key, 'get items')
return client.items(service, node, max_items, sub_id, client.parent.jid)
def getOptions(self, service, nodeIdentifier, subscriber, subscriptionIdentifier=None, profile_key='@DEFAULT@'):
- profile,client = self.__getClientNProfile(profile_key, 'get options')
+ profile, client = self.__getClientNProfile(profile_key, 'get options')
return client.getOptions(service, nodeIdentifier, subscriber, subscriptionIdentifier)
def setOptions(self, service, nodeIdentifier, subscriber, options, subscriptionIdentifier=None, profile_key='@DEFAULT@'):
- profile,client = self.__getClientNProfile(profile_key, 'set options')
+ profile, client = self.__getClientNProfile(profile_key, 'set options')
return client.setOptions(service, nodeIdentifier, subscriber, options, subscriptionIdentifier)
def createNode(self, service, nodeIdentifier, options, profile_key='@DEFAULT@'):
- profile,client = self.__getClientNProfile(profile_key, 'create node')
+ profile, client = self.__getClientNProfile(profile_key, 'create node')
return client.createNode(service, nodeIdentifier, options)
def deleteNode(self, service, nodeIdentifier, profile_key='@DEFAULT@'):
- profile,client = self.__getClientNProfile(profile_key, 'delete node')
+ profile, client = self.__getClientNProfile(profile_key, 'delete node')
return client.deleteNode(service, nodeIdentifier)
- def subscribe(self, service, nodeIdentifier, sub_jid = None, options=None, profile_key='@DEFAULT@'):
- profile,client = self.__getClientNProfile(profile_key, 'subscribe node')
+ def subscribe(self, service, nodeIdentifier, sub_jid=None, options=None, profile_key='@DEFAULT@'):
+ profile, client = self.__getClientNProfile(profile_key, 'subscribe node')
return client.subscribe(service, nodeIdentifier, sub_jid or client.parent.jid.userhostJID(), options=options)
@@ -123,7 +124,7 @@ class SatPubSubClient(pubsub.PubSubClient):
implements(disco.IDisco)
def __init__(self, host, parent_plugin):
- self.host=host
+ self.host = host
self.parent_plugin = parent_plugin
pubsub.PubSubClient.__init__(self)
@@ -152,4 +153,3 @@ class SatPubSubClient(pubsub.PubSubClient):
def getDiscoItems(self, requestor, target, nodeIdentifier=''):
return []
-
diff --git a/src/plugins/plugin_xep_0065.py b/src/plugins/plugin_xep_0065.py
index ce94ede2..23c56f20 100755
--- a/src/plugins/plugin_xep_0065.py
+++ b/src/plugins/plugin_xep_0065.py
@@ -78,30 +78,28 @@ from wokkel import disco, iwokkel
IQ_SET = '/iq[@type="set"]'
NS_BS = 'http://jabber.org/protocol/bytestreams'
BS_REQUEST = IQ_SET + '/query[@xmlns="' + NS_BS + '"]'
-TIMEOUT = 60 #timeout for workflow
-
-
+TIMEOUT = 60 # timeout for workflow
PLUGIN_INFO = {
-"name": "XEP 0065 Plugin",
-"import_name": "XEP-0065",
-"type": "XEP",
-"protocols": ["XEP-0065"],
-"main": "XEP_0065",
-"handler": "yes",
-"description": _("""Implementation of SOCKS5 Bytestreams""")
+ "name": "XEP 0065 Plugin",
+ "import_name": "XEP-0065",
+ "type": "XEP",
+ "protocols": ["XEP-0065"],
+ "main": "XEP_0065",
+ "handler": "yes",
+ "description": _("""Implementation of SOCKS5 Bytestreams""")
}
STATE_INITIAL = 0
-STATE_AUTH = 1
+STATE_AUTH = 1
STATE_REQUEST = 2
-STATE_READY = 3
+STATE_READY = 3
STATE_AUTH_USERPASS = 4
STATE_TARGET_INITIAL = 5
-STATE_TARGET_AUTH = 6
+STATE_TARGET_AUTH = 6
STATE_TARGET_REQUEST = 7
-STATE_TARGET_READY = 8
-STATE_LAST = 9
+STATE_TARGET_READY = 8
+STATE_LAST = 9
STATE_CONNECT_PENDING = STATE_LAST + 1
@@ -139,15 +137,14 @@ def calculateHash(from_jid, to_jid, sid):
return hashlib.sha1((sid + from_jid.full() + to_jid.full()).encode('utf-8')).hexdigest()
-
class SOCKSv5(protocol.Protocol, FileSender):
def __init__(self):
debug(_("Protocol init"))
self.state = STATE_INITIAL
self.buf = ""
- self.supportedAuthMechs = [ AUTHMECH_ANON ]
- self.supportedAddrs = [ ADDR_DOMAINNAME ]
- self.enabledCommands = [ CMD_CONNECT ]
+ self.supportedAuthMechs = [AUTHMECH_ANON]
+ self.supportedAddrs = [ADDR_DOMAINNAME]
+ self.enabledCommands = [CMD_CONNECT]
self.peersock = None
self.addressType = 0
self.requestType = 0
@@ -162,7 +159,7 @@ class SOCKSv5(protocol.Protocol, FileSender):
try:
# Parse out data
ver, nmethod = struct.unpack('!BB', self.buf[:2])
- methods = struct.unpack('%dB' % nmethod, self.buf[2:nmethod+2])
+ methods = struct.unpack('%dB' % nmethod, self.buf[2:nmethod + 2])
# Ensure version is correct
if ver != 5:
@@ -171,7 +168,7 @@ class SOCKSv5(protocol.Protocol, FileSender):
return
# Trim off front of the buffer
- self.buf = self.buf[nmethod+2:]
+ self.buf = self.buf[nmethod + 2:]
# Check for supported auth mechs
for m in self.supportedAuthMechs:
@@ -320,7 +317,7 @@ class SOCKSv5(protocol.Protocol, FileSender):
debug("connectRequested")
# Check that this session is expected
- if not self.factory.hash_sid_map.has_key(addr):
+ if addr not in self.factory.hash_sid_map:
#no: we refuse it
self.sendErrorReply(REPLY_CONN_REFUSED)
return
@@ -374,14 +371,13 @@ class SOCKSv5(protocol.Protocol, FileSender):
if self.state == STATE_TARGET_AUTH:
ver, method = struct.unpack('!BB', buf)
self.buf = self.buf[2:]
- if ver!=SOCKS5_VER or method!=AUTHMECH_ANON:
+ if ver != SOCKS5_VER or method != AUTHMECH_ANON:
self.transport.loseConnection()
else:
self._makeRequest()
if self.state == STATE_TARGET_REQUEST:
self._parseRequestReply()
-
def clientConnectionLost(self, reason):
debug("clientConnectionLost")
self.transport.loseConnection()
@@ -390,7 +386,7 @@ class SOCKSv5(protocol.Protocol, FileSender):
debug("connectionLost")
if self.state != STATE_CONNECT_PENDING:
self.transport.unregisterProducer()
- if self.peersock != None:
+ if self.peersock is not None:
self.peersock.peersock = None
self.peersock.transport.unregisterProducer()
self.peersock = None
@@ -405,10 +401,11 @@ class Socks5ServerFactory(protocol.ServerFactory):
self.finishedCb = finishedCb
def startedConnecting(self, connector):
- debug (_("Socks 5 server connection started"))
+ debug(_("Socks 5 server connection started"))
def clientConnectionLost(self, connector, reason):
- debug (_("Socks 5 server connection lost (reason: %s)"), reason)
+ debug(_("Socks 5 server connection lost (reason: %s)"), reason)
+
class Socks5ClientFactory(protocol.ClientFactory):
protocol = SOCKSv5
@@ -432,11 +429,11 @@ class Socks5ClientFactory(protocol.ClientFactory):
self.profile = profile
def startedConnecting(self, connector):
- debug (_("Socks 5 client connection started"))
+ debug(_("Socks 5 client connection started"))
def clientConnectionLost(self, connector, reason):
- debug (_("Socks 5 client connection lost (reason: %s)"), reason)
- self.finishedCb(self.sid, reason.type == jab_error.ConnectionDone, self.profile) #TODO: really check if the state is actually successful
+ debug(_("Socks 5 client connection lost (reason: %s)"), reason)
+ self.finishedCb(self.sid, reason.type == jab_error.ConnectionDone, self.profile) # TODO: really check if the state is actually successful
class XEP_0065(object):
@@ -465,7 +462,7 @@ class XEP_0065(object):
info(_("Plugin XEP_0065 initialization"))
#session data
- self.hash_sid_map = {} #key: hash of the transfer session, value: (session id, profile)
+ self.hash_sid_map = {} # key: hash of the transfer session, value: (session id, profile)
self.host = host
debug(_("registering"))
@@ -486,7 +483,7 @@ class XEP_0065(object):
client = self.host.getClient(profile)
if not client:
raise ProfileNotInCacheError
- client.xep_0065_current_stream = {} #key: stream_id, value: data(dict)
+ client.xep_0065_current_stream = {} # key: stream_id, value: data(dict)
def getExternalIP(self):
"""Return IP visible from outside, by asking to a website"""
@@ -518,15 +515,15 @@ class XEP_0065(object):
if not client:
warning(_("Client no more in cache"))
return
- if not client.xep_0065_current_stream.has_key(sid):
+ if sid not in client.xep_0065_current_stream:
warning(_("kill id called on a non existant id"))
return
- if client.xep_0065_current_stream[sid].has_key("observer_cb"):
+ if "observer_cb" in client.xep_0065_current_stream[sid]:
xmlstream = client.xep_0065_current_stream[sid]["xmlstream"]
xmlstream.removeObserver(client.xep_0065_current_stream[sid]["event_data"], client.xep_0065_current_stream[sid]["observer_cb"])
if client.xep_0065_current_stream[sid]['timer'].active():
client.xep_0065_current_stream[sid]['timer'].cancel()
- if client.xep_0065_current_stream[sid].has_key("size"):
+ if "size" in client.xep_0065_current_stream[sid]:
self.host.removeProgressCB(sid, profile)
file_obj = client.xep_0065_current_stream[sid]['file_obj']
@@ -544,7 +541,7 @@ class XEP_0065(object):
else:
failure_cb(sid, file_obj, NS_BS, failure_reason, profile)
- def startStream(self, file_obj, to_jid, sid, length, successCb, failureCb, size = None, profile=None):
+ def startStream(self, file_obj, to_jid, sid, length, successCb, failureCb, size=None, profile=None):
"""Launch the stream workflow
@param file_obj: file_obj to send
@param to_jid: JID of the recipient
@@ -559,7 +556,7 @@ class XEP_0065(object):
error(_("Unknown profile, this should not happen"))
raise ProfileNotInCacheError
- if length != None:
+ if length is not None:
error(_('stream length not managed yet'))
return
@@ -579,7 +576,7 @@ class XEP_0065(object):
if size:
data["size"] = size
self.host.registerProgressCB(sid, self.getProgress, profile)
- iq_elt = jabber_client.IQ(xmlstream,'set')
+ iq_elt = jabber_client.IQ(xmlstream, 'set')
iq_elt["from"] = profile_jid.full()
iq_elt["to"] = to_jid.full()
query_elt = iq_elt.addElement('query', NS_BS)
@@ -638,7 +635,7 @@ class XEP_0065(object):
factory = Socks5ClientFactory(client.xep_0065_current_stream, sid, None, self.activateProxyStream, lambda sid, success, profile: self._killId(sid, success, profile=profile), True, profile)
reactor.connectTCP(proxy_host, int(proxy_port), factory)
else:
- data["start_transfer_cb"](file_obj) #We now activate the stream
+ data["start_transfer_cb"](file_obj) # We now activate the stream
def activateProxyStream(self, sid, iq_id, start_transfer_cb, profile):
debug(_("activating stream"))
@@ -648,7 +645,7 @@ class XEP_0065(object):
data = client.xep_0065_current_stream[sid]
profile_jid, xmlstream = self.host.getJidNStream(profile)
- iq_elt = client.IQ(xmlstream,'set')
+ iq_elt = client.IQ(xmlstream, 'set')
iq_elt["from"] = profile_jid.full()
iq_elt["to"] = self.host.memory.getParamA("Proxy", "File Transfer", profile_key=profile)
query_elt = iq_elt.addElement('query', NS_BS)
@@ -687,7 +684,6 @@ class XEP_0065(object):
data["success_cb"] = success_cb
data["failure_cb"] = failure_cb
-
def streamQuery(self, iq_elt, profile):
"""Get file using byte stream"""
debug(_("BS stream query"))
@@ -717,7 +713,7 @@ class XEP_0065(object):
self.sendBadRequestError(iq_elt['id'], iq_elt['from'], xmlstream)
return
- streamhost_elt = streamhost_elts[0] #TODO: manage several streamhost elements case
+ streamhost_elt = streamhost_elts[0] # TODO: manage several streamhost elements case
sh_host = streamhost_elt.getAttribute("host")
sh_port = streamhost_elt.getAttribute("port")
sh_jid = streamhost_elt.getAttribute("jid")
@@ -728,7 +724,7 @@ class XEP_0065(object):
client.xep_0065_current_stream[sid]["streamhost"] = (sh_host, sh_port, sh_jid)
- info (_("Stream proposed: host=[%(host)s] port=[%(port)s]") % {'host':sh_host, 'port':sh_port})
+ info(_("Stream proposed: host=[%(host)s] port=[%(port)s]") % {'host': sh_host, 'port': sh_port})
factory = Socks5ClientFactory(client.xep_0065_current_stream, sid, iq_elt["id"], self.activateStream, lambda sid, success, profile: self._killId(sid, success, profile=profile), profile=profile)
reactor.connectTCP(sh_host, int(sh_port), factory)
@@ -760,7 +756,7 @@ class XEP_0065(object):
result['to'] = to_jid
error_el = result.addElement('error')
error_el['type'] = 'modify'
- error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas','not-acceptable'))
+ error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas', 'not-acceptable'))
xmlstream.send(result)
def sendBadRequestError(self, iq_id, to_jid, xmlstream):
@@ -774,9 +770,10 @@ class XEP_0065(object):
result['to'] = to_jid
error_el = result.addElement('error')
error_el['type'] = 'cancel'
- error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas','bad-request'))
+ error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas', 'bad-request'))
xmlstream.send(result)
+
class XEP_0065_handler(XMPPHandler):
implements(iwokkel.IDisco)
@@ -801,10 +798,9 @@ class XEP_0065_handler(XMPPHandler):
if len(streamhost_elts) != 1:
warning(_("Multiple streamhost elements in proxy not managed, keeping only the first one"))
streamhost_elt = streamhost_elts[0]
- proxy = self.host.memory.setParam("Proxy", streamhost_elt.getAttribute("jid",""), "File Transfer", self.parent.profile)
- proxy = self.host.memory.setParam("Proxy host", streamhost_elt.getAttribute("host",""), "File Transfer", self.parent.profile)
- proxy = self.host.memory.setParam("Proxy port", streamhost_elt.getAttribute("port",""), "File Transfer", self.parent.profile)
-
+ proxy = self.host.memory.setParam("Proxy", streamhost_elt.getAttribute("jid", ""), "File Transfer", self.parent.profile)
+ proxy = self.host.memory.setParam("Proxy host", streamhost_elt.getAttribute("host", ""), "File Transfer", self.parent.profile)
+ proxy = self.host.memory.setParam("Proxy port", streamhost_elt.getAttribute("port", ""), "File Transfer", self.parent.profile)
def connectionInitialized(self):
def after_init(ignore):
@@ -812,20 +808,17 @@ class XEP_0065_handler(XMPPHandler):
if not proxy_ent:
debug(_("No proxy found on this server"))
return
- iq_elt = jabber_client.IQ(self.parent.xmlstream,'get')
+ iq_elt = jabber_client.IQ(self.parent.xmlstream, 'get')
iq_elt["to"] = proxy_ent.full()
query_elt = iq_elt.addElement('query', NS_BS)
iq_elt.addCallback(self._proxyDataResult)
iq_elt.send()
-
- self.xmlstream.addObserver(BS_REQUEST, self.plugin_parent.streamQuery, profile = self.parent.profile)
- proxy = self.host.memory.getParamA("Proxy", "File Transfer", profile_key = self.parent.profile)
+ self.xmlstream.addObserver(BS_REQUEST, self.plugin_parent.streamQuery, profile=self.parent.profile)
+ proxy = self.host.memory.getParamA("Proxy", "File Transfer", profile_key=self.parent.profile)
if not proxy:
self.parent.client_initialized.addCallback(after_init)
-
-
def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
return [disco.DiscoFeature(NS_BS)]
diff --git a/src/plugins/plugin_xep_0077.py b/src/plugins/plugin_xep_0077.py
index 5bb9cd68..1ac342c5 100755
--- a/src/plugins/plugin_xep_0077.py
+++ b/src/plugins/plugin_xep_0077.py
@@ -29,21 +29,22 @@ from wokkel import data_form
NS_REG = 'jabber:iq:register'
PLUGIN_INFO = {
-"name": "XEP 0077 Plugin",
-"import_name": "XEP-0077",
-"type": "XEP",
-"protocols": ["XEP-0077"],
-"dependencies": [],
-"main": "XEP_0077",
-"description": _("""Implementation of in-band registration""")
+ "name": "XEP 0077 Plugin",
+ "import_name": "XEP-0077",
+ "type": "XEP",
+ "protocols": ["XEP-0077"],
+ "dependencies": [],
+ "main": "XEP_0077",
+ "description": _("""Implementation of in-band registration""")
}
+
class XEP_0077(object):
def __init__(self, host):
info(_("Plugin XEP_0077 initialization"))
self.host = host
- self.triggers = {} #used by other protocol (e.g. XEP-0100) to finish registration. key = target_jid
+ self.triggers = {} # used by other protocol (e.g. XEP-0100) to finish registration. key = target_jid
host.bridge.addMethod("in_band_register", ".plugin", in_sign='ss', out_sign='s', method=self.in_band_register)
host.bridge.addMethod("in_band_submit", ".plugin", in_sign='ssa(ss)s', out_sign='s', method=self.in_band_submit)
@@ -54,65 +55,65 @@ class XEP_0077(object):
def reg_ok(self, answer, profile):
"""Called after the first get IQ"""
try:
- x_elem = filter (lambda x:x.name == "x", answer.firstChildElement().elements())[0] #We only want the "x" element (data form)
+ x_elem = filter(lambda x: x.name == "x", answer.firstChildElement().elements())[0] # We only want the "x" element (data form)
except IndexError:
info(_("No data form found"))
#TODO: manage registration without data form
- answer_data={"reason": "unmanaged", "message":_("This gateway can't be managed by SàT, sorry :(")}
+ 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, profile)
return
form = data_form.Form.fromElement(x_elem)
xml_data = dataForm2xml(form)
- self.host.bridge.actionResult("XMLUI", answer['id'], {"target":answer["from"], "type":"registration", "xml":xml_data}, profile)
+ self.host.bridge.actionResult("XMLUI", answer['id'], {"target": answer["from"], "type": "registration", "xml": xml_data}, profile)
def reg_err(self, failure, profile):
"""Called when something is wrong with registration"""
- info (_("Registration failure: %s") % str(failure.value))
+ info(_("Registration failure: %s") % str(failure.value))
answer_data = {}
answer_data['reason'] = 'unknown'
- answer_data={"message":"%s [code: %s]" % (failure.value.condition, unicode(failure.value))}
+ answer_data = {"message": "%s [code: %s]" % (failure.value.condition, unicode(failure.value))}
answer_type = "ERROR"
self.host.bridge.actionResult(answer_type, failure.value.stanza['id'], answer_data, profile)
def unregistrationAnswer(self, answer, profile):
- debug (_("registration answer: %s") % answer.toXml())
+ debug(_("registration answer: %s") % answer.toXml())
answer_type = "SUCCESS"
- answer_data={"message":_("Your are now unregistred")}
+ answer_data = {"message": _("Your are now unregistred")}
self.host.bridge.actionResult(answer_type, answer['id'], answer_data, profile)
def unregistrationFailure(self, failure, profile):
- info (_("Unregistration failure: %s") % str(failure.value))
+ info(_("Unregistration failure: %s") % str(failure.value))
answer_type = "ERROR"
answer_data = {}
answer_data['reason'] = 'unknown'
- answer_data={"message":_("Unregistration failed: %s") % failure.value.condition}
+ answer_data = {"message": _("Unregistration failed: %s") % failure.value.condition}
self.host.bridge.actionResult(answer_type, failure.value.stanza['id'], answer_data, profile)
def registrationAnswer(self, answer, profile):
- debug (_("registration answer: %s") % answer.toXml())
+ debug(_("registration answer: %s") % answer.toXml())
answer_type = "SUCCESS"
- answer_data={"message":_("Registration successfull")}
+ answer_data = {"message": _("Registration successfull")}
self.host.bridge.actionResult(answer_type, answer['id'], answer_data, profile)
- if self.triggers.has_key(answer["from"]):
- callback,profile = self.triggers[answer["from"]]
+ if answer["from"] in self.triggers:
+ callback, profile = self.triggers[answer["from"]]
callback(answer["from"], profile)
del self.triggers[answer["from"]]
def registrationFailure(self, failure, profile):
- info (_("Registration failure: %s") % str(failure.value))
+ info(_("Registration failure: %s") % str(failure.value))
print failure.value.stanza.toXml()
answer_type = "ERROR"
answer_data = {}
if failure.value.condition == 'conflict':
answer_data['reason'] = 'conflict'
- answer_data={"message":_("Username already exists, please choose an other one")}
+ answer_data = {"message": _("Username already exists, please choose an other one")}
else:
answer_data['reason'] = 'unknown'
- answer_data={"message":_("Registration failed")}
+ answer_data = {"message": _("Registration failed")}
self.host.bridge.actionResult(answer_type, failure.value.stanza['id'], answer_data, profile)
- if failure.value.stanza["from"] in self.triggers.has_key:
+ if failure.value.stanza["from"] in self.triggers:
del self.triggers[failure.value.stanza["from"]]
def in_band_submit(self, action, target, fields, profile):
@@ -128,12 +129,12 @@ class XEP_0077(object):
"""register to a target JID"""
client = self.host.getClient(profile_key)
if not client:
- error (_('Asking for an non-existant or not connected profile'))
+ error(_('Asking for an non-existant or not connected profile'))
return ""
to_jid = jid.JID(target)
debug(_("Asking registration for [%s]") % to_jid.full())
- reg_request=IQ(client.xmlstream,'get')
- reg_request["from"]=client.jid.full()
+ reg_request = IQ(client.xmlstream, 'get')
+ reg_request["from"] = client.jid.full()
reg_request["to"] = to_jid.full()
reg_request.addElement('query', NS_REG)
reg_request.send(to_jid.full()).addCallbacks(self.reg_ok, self.reg_err, callbackArgs=[client.profile], errbackArgs=[client.profile])
diff --git a/src/plugins/plugin_xep_0095.py b/src/plugins/plugin_xep_0095.py
index fba453f6..e78678ba 100644
--- a/src/plugins/plugin_xep_0095.py
+++ b/src/plugins/plugin_xep_0095.py
@@ -43,21 +43,22 @@ SI_REQUEST = IQ_SET + '/si[@xmlns="' + NS_SI + '"]'
SI_PROFILE_HEADER = "http://jabber.org/protocol/si/profile/"
PLUGIN_INFO = {
-"name": "XEP 0095 Plugin",
-"import_name": "XEP-0095",
-"type": "XEP",
-"protocols": ["XEP-0095"],
-"main": "XEP_0095",
-"handler": "yes",
-"description": _("""Implementation of Stream Initiation""")
+ "name": "XEP 0095 Plugin",
+ "import_name": "XEP-0095",
+ "type": "XEP",
+ "protocols": ["XEP-0095"],
+ "main": "XEP_0095",
+ "handler": "yes",
+ "description": _("""Implementation of Stream Initiation""")
}
+
class XEP_0095(object):
def __init__(self, host):
info(_("Plugin XEP_0095 initialization"))
self.host = host
- self.si_profiles = {} #key: SI profile, value: callback
+ self.si_profiles = {} # key: SI profile, value: callback
def getHandler(self, profile):
return XEP_0095_handler(self)
@@ -66,33 +67,33 @@ class XEP_0095(object):
"""Add a callback for a SI Profile
param si_profile: SI profile name (e.g. file-transfer)
param callback: method to call when the profile name is asked"""
- self.si_profiles[si_profile] = callback
+ self.si_profiles[si_profile] = callback
def streamInit(self, iq_el, profile):
"""This method is called on stream initiation (XEP-0095 #3.2)
@param iq_el: IQ element
@param profile: %(doc_profile)s"""
- info (_("XEP-0095 Stream initiation"))
- iq_el.handled=True
+ info(_("XEP-0095 Stream initiation"))
+ iq_el.handled = True
si_el = iq_el.firstChildElement()
si_id = si_el.getAttribute('id')
si_mime_type = iq_el.getAttribute('mime-type', 'application/octet-stream')
si_profile = si_el.getAttribute('profile')
- si_profile_key = si_profile[len(SI_PROFILE_HEADER):] if si_profile.startswith(SI_PROFILE_HEADER) else si_profile
- if self.si_profiles.has_key(si_profile_key):
+ si_profile_key = si_profile[len(SI_PROFILE_HEADER):] if si_profile.startswith(SI_PROFILE_HEADER) else si_profile
+ if si_profile_key in self.si_profiles:
#We know this SI profile, we call the callback
self.si_profiles[si_profile_key](iq_el['id'], iq_el['from'], si_id, si_mime_type, si_el, profile)
else:
#We don't know this profile, we send an error
self.sendBadProfileError(iq_el['id'], iq_el['from'], profile)
- def sendRejectedError(self, iq_id, to_jid, reason = 'Offer Declined', profile='@NONE@'):
+ def sendRejectedError(self, iq_id, to_jid, reason='Offer Declined', profile='@NONE@'):
"""Helper method to send when the stream is rejected
@param iq_id: IQ id
@param to_jid: recipient
@param reason: human readable reason (string)
@param profile: %(doc_profile)s"""
- self.sendError(iq_id, to_jid, 403, 'cancel', {'text':reason}, profile=profile)
+ self.sendError(iq_id, to_jid, 403, 'cancel', {'text': reason}, profile=profile)
def sendBadProfileError(self, iq_id, to_jid, profile):
"""Helper method to send when we don't know the SI profile
@@ -113,7 +114,7 @@ class XEP_0095(object):
@param iq_id: IQ id
@param to_jid: recipient
@param profile: %(doc_profile)s"""
- self.sendError(iq_id, to_jid, 500, 'cancel', {'custom':'failed'}, profile=profile) #as there is no error code for failed transfer, we use 500 (undefined-condition)
+ self.sendError(iq_id, to_jid, 500, 'cancel', {'custom': 'failed'}, profile=profile) # as there is no error code for failed transfer, we use 500 (undefined-condition)
def sendError(self, iq_id, to_jid, err_code, err_type='cancel', data={}, profile='@NONE@'):
"""Send IQ error as a result
@@ -131,21 +132,21 @@ class XEP_0095(object):
result['id'] = iq_id
result['to'] = to_jid
error_el = result.addElement('error')
- error_el['err_code'] = str(err_code)
+ error_el['err_code'] = str(err_code)
error_el['type'] = err_type
- if err_code==400 and err_type=='cancel':
- error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas','bad-request'))
- error_el.addElement((NS_SI,'no-valid-streams'))
- elif err_code==400 and err_type=='modify':
- error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas','bad-request'))
- error_el.addElement((NS_SI,'bad-profile'))
- elif err_code==403 and err_type=='cancel':
- error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas','forbidden'))
- if data.has_key('text'):
- error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas','text'), content=data['text'])
- elif err_code==500 and err_type=='cancel':
- condition_el = error_el.addElement((NS_SI,'undefined-condition'))
- if data.has_key('custom') and data['custom']=='failed':
+ if err_code == 400 and err_type == 'cancel':
+ error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas', 'bad-request'))
+ error_el.addElement((NS_SI, 'no-valid-streams'))
+ elif err_code == 400 and err_type == 'modify':
+ error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas', 'bad-request'))
+ error_el.addElement((NS_SI, 'bad-profile'))
+ elif err_code == 403 and err_type == 'cancel':
+ error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas', 'forbidden'))
+ if 'text' in data:
+ error_el.addElement(('urn:ietf:params:xml:ns:xmpp-stanzas', 'text'), content=data['text'])
+ elif err_code == 500 and err_type == 'cancel':
+ condition_el = error_el.addElement((NS_SI, 'undefined-condition'))
+ if 'custom' in data and data['custom'] == 'failed':
condition_el.addContent('Stream failed')
_client.xmlstream.send(result)
@@ -158,7 +159,7 @@ class XEP_0095(object):
@param profile: %(doc_profile)s"""
_client = self.host.getClient(profile)
assert(_client)
- info (_("sending stream initiation accept answer"))
+ info(_("sending stream initiation accept answer"))
result = domish.Element((None, 'iq'))
result['type'] = 'result'
result['id'] = iq_id
@@ -180,16 +181,16 @@ class XEP_0095(object):
@return: session id, offer"""
current_jid, xmlstream = self.host.getJidNStream(profile_key)
if not xmlstream:
- error (_('Asking for an non-existant or not connected profile'))
+ error(_('Asking for an non-existant or not connected profile'))
return ""
- offer = client.IQ(xmlstream,'set')
+ offer = client.IQ(xmlstream, 'set')
sid = str(uuid.uuid4())
- debug (_("Stream Session ID: %s") % offer["id"])
+ debug(_("Stream Session ID: %s") % offer["id"])
offer["from"] = current_jid.full()
offer["to"] = to_jid.full()
- si=offer.addElement('si',NS_SI)
+ si = offer.addElement('si', NS_SI)
si['id'] = sid
si["mime-type"] = mime_type
si["profile"] = si_profile
@@ -209,11 +210,10 @@ class XEP_0095_handler(XMPPHandler):
self.host = plugin_parent.host
def connectionInitialized(self):
- self.xmlstream.addObserver(SI_REQUEST, self.plugin_parent.streamInit, profile = self.parent.profile)
+ self.xmlstream.addObserver(SI_REQUEST, self.plugin_parent.streamInit, profile=self.parent.profile)
def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
return [disco.DiscoFeature(NS_SI)] + [disco.DiscoFeature("http://jabber.org/protocol/si/profile/%s" % profile_name) for profile_name in self.plugin_parent.si_profiles]
def getDiscoItems(self, requestor, target, nodeIdentifier=''):
return []
-
diff --git a/src/plugins/plugin_xep_0096.py b/src/plugins/plugin_xep_0096.py
index 624300bc..00660d6c 100755
--- a/src/plugins/plugin_xep_0096.py
+++ b/src/plugins/plugin_xep_0096.py
@@ -23,11 +23,10 @@ from logging import debug, info, warning, error
from twisted.words.xish import domish
from twisted.words.protocols.jabber import jid
from twisted.words.protocols.jabber import error as jab_error
-import os, os.path
+import os
from twisted.internet import reactor
from sat.core.exceptions import ProfileNotInCacheError
-
from wokkel import data_form
IQ_SET = '/iq[@type="set"]'
@@ -35,29 +34,30 @@ PROFILE_NAME = "file-transfer"
PROFILE = "http://jabber.org/protocol/si/profile/" + PROFILE_NAME
PLUGIN_INFO = {
-"name": "XEP 0096 Plugin",
-"import_name": "XEP-0096",
-"type": "XEP",
-"protocols": ["XEP-0096"],
-"dependencies": ["XEP-0020", "XEP-0095", "XEP-0065", "XEP-0047"],
-"main": "XEP_0096",
-"handler": "no",
-"description": _("""Implementation of SI File Transfer""")
+ "name": "XEP 0096 Plugin",
+ "import_name": "XEP-0096",
+ "type": "XEP",
+ "protocols": ["XEP-0096"],
+ "dependencies": ["XEP-0020", "XEP-0095", "XEP-0065", "XEP-0047"],
+ "main": "XEP_0096",
+ "handler": "no",
+ "description": _("""Implementation of SI File Transfer""")
}
+
class XEP_0096(object):
def __init__(self, host):
info(_("Plugin XEP_0096 initialization"))
self.host = host
self.managed_stream_m = [self.host.plugins["XEP-0065"].NAMESPACE,
- self.host.plugins["XEP-0047"].NAMESPACE] #Stream methods managed
+ self.host.plugins["XEP-0047"].NAMESPACE] # Stream methods managed
self.host.plugins["XEP-0095"].registerSIProfile(PROFILE_NAME, self.transferRequest)
host.bridge.addMethod("sendFile", ".plugin", in_sign='ssa{ss}s', out_sign='s', method=self.sendFile)
def profileConnected(self, profile):
client = self.host.getClient(profile)
- client._xep_0096_waiting_for_approval = {} #key = id, value = [transfer data, IdelayedCall Reactor timeout,
+ client._xep_0096_waiting_for_approval = {} # key = id, value = [transfer data, IdelayedCall Reactor timeout,
# current stream method, [failed stream methods], profile]
def _kill_id(self, approval_id, profile):
@@ -78,7 +78,7 @@ class XEP_0096(object):
@param si_mime_type: Mime type of the file (or default "application/octet-stream" if unknown)
@param si_el: domish.Element of the request
@param profile: %(doc_profile)s"""
- info (_("XEP-0096 file transfer requested"))
+ info(_("XEP-0096 file transfer requested"))
debug(si_el.toXml())
client = self.host.getClient(profile)
if not client:
@@ -98,7 +98,7 @@ class XEP_0096(object):
file_size = file_el["size"]
file_date = file_el.getAttribute("date", "")
file_hash = file_el.getAttribute("hash", "")
- info (_("File proposed: name=[%(name)s] size=%(size)s") % {'name':filename, 'size':file_size})
+ info(_("File proposed: name=[%(name)s] size=%(size)s") % {'name': filename, 'size': file_size})
for file_child_el in file_el.elements():
if file_child_el.name == "desc":
file_desc = unicode(file_child_el)
@@ -113,7 +113,7 @@ class XEP_0096(object):
feature_el = feature_elts[0]
form = data_form.Form.fromElement(feature_el.firstChildElement())
try:
- stream_method = self.host.plugins["XEP-0020"].negociate(feature_el, 'stream-method',self.managed_stream_m)
+ stream_method = self.host.plugins["XEP-0020"].negociate(feature_el, 'stream-method', self.managed_stream_m)
except KeyError:
warning(_("No stream method found"))
self.host.plugins["XEP-0095"].sendBadRequestError(iq_id, from_jid, profile)
@@ -128,13 +128,12 @@ class XEP_0096(object):
return
#if we are here, the transfer can start, we just need user's agreement
- data={ "filename":filename, "id": iq_id, "from":from_jid, "size":file_size, "date":file_date, "hash":file_hash, "desc":file_desc, "can_range": str(can_range) }
+ data = {"filename": filename, "id": iq_id, "from": from_jid, "size": file_size, "date": file_date, "hash": file_hash, "desc": file_desc, "can_range": str(can_range)}
client._xep_0096_waiting_for_approval[si_id] = [data, reactor.callLater(300, self._kill_id, si_id, profile), stream_method, []]
self.host.askConfirmation(si_id, "FILE_TRANSFER", data, self.confirmationCB, profile)
-
- def _getFileObject(self, dest_path, can_range = False):
+ def _getFileObject(self, dest_path, can_range=False):
"""Open file, put file pointer to the end if the file if needed
@param dest_path: path of the destination file
@param can_range: True if the file pointer can be moved
@@ -175,7 +174,7 @@ class XEP_0096(object):
return
#we can send the iq result
- feature_elt = self.host.plugins["XEP-0020"].chooseOption({'stream-method':stream_method})
+ feature_elt = self.host.plugins["XEP-0020"].chooseOption({'stream-method': stream_method})
misc_elts = []
misc_elts.append(domish.Element((PROFILE, "file")))
if can_range:
@@ -185,8 +184,8 @@ class XEP_0096(object):
misc_elts.append(range_elt)
self.host.plugins["XEP-0095"].acceptStream(data["id"], data['from'], feature_elt, misc_elts, profile)
else:
- debug (_("Transfer [%s] refused"), sid)
- self.host.plugins["XEP-0095"].sendRejectedError (data["id"], data['from'], profile=profile)
+ debug(_("Transfer [%s] refused"), sid)
+ self.host.plugins["XEP-0095"].sendRejectedError(data["id"], data['from'], profile=profile)
del(client._xep_0096_waiting_for_approval[sid])
def _transferSucceeded(self, sid, file_obj, stream_method, profile):
@@ -207,9 +206,10 @@ class XEP_0096(object):
if not client:
raise ProfileNotInCacheError
data, timeout, stream_method, failed_methods = client._xep_0096_waiting_for_approval[sid]
- warning(_('Transfer %(id)s failed with stream method %(s_method)s: %(reason)s') % { 'id': sid,
- 's_method': stream_method,
- 'reason': reason})
+ warning(_('Transfer %(id)s failed with stream method %(s_method)s: %(reason)s') % {
+ 'id': sid,
+ 's_method': stream_method,
+ 'reason': reason})
filepath = file_obj.name
file_obj.close()
os.remove(filepath)
@@ -255,15 +255,15 @@ class XEP_0096(object):
range_length = range_elt.getAttribute("length")
if stream_method == self.host.plugins["XEP-0065"].NAMESPACE:
- file_obj = open(filepath, 'r')
- if range_offset:
- file_obj.seek(range_offset)
- self.host.plugins["XEP-0065"].startStream(file_obj, jid.JID(IQ['from']), sid, range_length, self.sendSuccessCb, self.sendFailureCb, size, profile)
+ file_obj = open(filepath, 'r')
+ if range_offset:
+ file_obj.seek(range_offset)
+ self.host.plugins["XEP-0065"].startStream(file_obj, jid.JID(IQ['from']), sid, range_length, self.sendSuccessCb, self.sendFailureCb, size, profile)
elif stream_method == self.host.plugins["XEP-0047"].NAMESPACE:
- file_obj = open(filepath, 'r')
- if range_offset:
- file_obj.seek(range_offset)
- self.host.plugins["XEP-0047"].startStream(file_obj, jid.JID(IQ['from']), sid, range_length, self.sendSuccessCb, self.sendFailureCb, size, profile)
+ file_obj = open(filepath, 'r')
+ if range_offset:
+ file_obj.seek(range_offset)
+ self.host.plugins["XEP-0047"].startStream(file_obj, jid.JID(IQ['from']), sid, range_length, self.sendSuccessCb, self.sendFailureCb, size, profile)
else:
warning(_("Invalid stream method received"))
@@ -286,13 +286,13 @@ class XEP_0096(object):
statinfo = os.stat(filepath)
file_elt = domish.Element((PROFILE, 'file'))
- file_elt['name']=os.path.basename(filepath)
- size = file_elt['size']=str(statinfo.st_size)
+ file_elt['name'] = os.path.basename(filepath)
+ size = file_elt['size'] = str(statinfo.st_size)
file_transfer_elts.append(file_elt)
- file_transfer_elts.append(domish.Element((None,'range')))
+ file_transfer_elts.append(domish.Element((None, 'range')))
- sid, offer = self.host.plugins["XEP-0095"].proposeStream(jid.JID(to_jid), PROFILE, feature_elt, file_transfer_elts, profile_key = profile)
+ sid, offer = self.host.plugins["XEP-0095"].proposeStream(jid.JID(to_jid), PROFILE, feature_elt, file_transfer_elts, profile_key=profile)
offer.addCallback(self.fileCb, filepath, sid, size, profile)
return sid
@@ -302,4 +302,4 @@ class XEP_0096(object):
def sendFailureCb(self, sid, file_obj, stream_method, reason, profile):
file_obj.close()
- warning(_('Transfer %(id)s failed with stream method %(s_method)s: %(reason)s [%(profile)s') % { 'id': sid, "s_method": stream_method, 'reason': reason, 'profile': profile })
+ warning(_('Transfer %(id)s failed with stream method %(s_method)s: %(reason)s [%(profile)s') % {'id': sid, "s_method": stream_method, 'reason': reason, 'profile': profile})
diff --git a/src/plugins/plugin_xep_0100.py b/src/plugins/plugin_xep_0100.py
index 6c62760a..b37d71ce 100755
--- a/src/plugins/plugin_xep_0100.py
+++ b/src/plugins/plugin_xep_0100.py
@@ -25,86 +25,85 @@ from twisted.words.protocols.jabber import error as jab_error
import twisted.internet.error
PLUGIN_INFO = {
-"name": "Gateways Plugin",
-"import_name": "XEP-0100",
-"type": "XEP",
-"protocols": ["XEP-0100"],
-"dependencies": ["XEP-0077"],
-"main": "XEP_0100",
-"description": _("""Implementation of Gateways protocol""")
+ "name": "Gateways Plugin",
+ "import_name": "XEP-0100",
+ "type": "XEP",
+ "protocols": ["XEP-0100"],
+ "dependencies": ["XEP-0077"],
+ "main": "XEP_0100",
+ "description": _("""Implementation of Gateways protocol""")
}
+
class XEP_0100(object):
def __init__(self, host):
info(_("Gateways plugin initialization"))
self.host = host
- self.__gateways = {} #dict used to construct the answer to findGateways. Key = target jid
+ self.__gateways = {} # dict used to construct the answer to findGateways. Key = target jid
host.bridge.addMethod("findGateways", ".plugin", in_sign='ss', out_sign='s', method=self.findGateways)
host.bridge.addMethod("gatewayRegister", ".plugin", in_sign='ssa(ss)s', out_sign='s', method=self.gatewayRegister)
def __inc_handled_items(self, request_id, profile):
- self.__gateways[request_id]['__handled_items']+=1
+ self.__gateways[request_id]['__handled_items'] += 1
if self.__gateways[request_id]['__total_items'] == self.__gateways[request_id]['__handled_items']:
- debug (_("All items checked for id [%s]") % str(request_id))
+ debug(_("All items checked for id [%s]") % str(request_id))
del self.__gateways[request_id]['__total_items']
del self.__gateways[request_id]['__handled_items']
- self.host.actionResultExt(request_id,"DICT_DICT",self.__gateways[request_id], profile)
+ self.host.actionResultExt(request_id, "DICT_DICT", self.__gateways[request_id], profile)
def discoInfo(self, disco, entity, request_id, profile):
"""Find disco infos about entity, to check if it is a gateway"""
for identity in disco.identities:
if identity[0] == 'gateway':
- print (_("Found gateway (%(jid)s): %(identity)s") % {'jid':entity.full(), 'identity':disco.identities[identity]})
+ print (_("Found gateway (%(jid)s): %(identity)s") % {'jid': entity.full(), 'identity': disco.identities[identity]})
self.__gateways[request_id][entity.full()] = {
- 'name':disco.identities[identity],
- 'type':identity[1]
+ 'name': disco.identities[identity],
+ 'type': identity[1]
}
self.__inc_handled_items(request_id, profile)
def discoInfoErr(self, failure, entity, request_id, profile):
"""Something is going wrong with disco"""
- failure.trap(jab_error.StanzaError,twisted.internet.error.ConnectionLost)
- error(_("Error when discovering [%(jid)s]: %(error)s") % {'jid':entity.full(), 'error':failure.getErrorMessage()})
+ failure.trap(jab_error.StanzaError, twisted.internet.error.ConnectionLost)
+ error(_("Error when discovering [%(jid)s]: %(error)s") % {'jid': entity.full(), 'error': failure.getErrorMessage()})
self.__inc_handled_items(request_id, profile)
-
def discoItems(self, disco, request_id, target, client):
"""Look for items with disco protocol, and ask infos for each one"""
#FIXME: target is used as we can't find the original iq node (parent is None)
# an other way would avoid this useless parameter (is there a way with wokkel ?)
if len(disco._items) == 0:
- debug (_("No gateway found"))
- self.host.actionResultExt(request_id,"DICT_DICT",{})
+ debug(_("No gateway found"))
+ self.host.actionResultExt(request_id, "DICT_DICT", {})
return
- 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:
#TODO: need to set a timeout for theses requests
- 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, profile=client.profile).addErrback(self.discoInfoErr, entity=item.entity, request_id=request_id, profile=client.profile)
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)}}
+ 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, profile):
"""Called when in_band registration is ok, we must now follow the rest of procedure"""
- debug (_("Registration successful, doing the rest"))
+ debug(_("Registration successful, doing the rest"))
self.host.addContact(target, profile)
self.host.setPresence(target, profile)
def gatewayRegister(self, action, target, fields, profile_key='@DEFAULT@'):
"""Register gateway using in-band registration, then log-in to gateway"""
profile = self.host.memory.getProfileName(profile_key)
- assert(profile) #FIXME: return an error here
+ assert(profile) # FIXME: return an error here
if action == 'SUBMIT':
self.host.plugins["XEP-0077"].addTrigger(target, self.registrationSuccessful, profile)
return self.host.plugins["XEP-0077"].in_band_submit(action, target, fields, profile)
@@ -117,7 +116,7 @@ class XEP_0100(object):
client = self.host.getClient(profile_key)
assert(client)
to_jid = jid.JID(target)
- debug (_("find gateways (target = %(target)s, profile = %(profile)s)") % {'target':to_jid.full(), 'profile':profile})
+ debug(_("find gateways (target = %(target)s, profile = %(profile)s)") % {'target': to_jid.full(), 'profile': profile})
request_id = self.host.get_next_id()
- 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)
+ 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
diff --git a/src/plugins/plugin_xep_0115.py b/src/plugins/plugin_xep_0115.py
index 841154dd..69572383 100755
--- a/src/plugins/plugin_xep_0115.py
+++ b/src/plugins/plugin_xep_0115.py
@@ -42,22 +42,24 @@ except ImportError:
PRESENCE = '/presence'
NS_ENTITY_CAPABILITY = 'http://jabber.org/protocol/caps'
-CAPABILITY_UPDATE = PRESENCE + '/c[@xmlns="' + NS_ENTITY_CAPABILITY + '"]'
+CAPABILITY_UPDATE = PRESENCE + '/c[@xmlns="' + NS_ENTITY_CAPABILITY + '"]'
PLUGIN_INFO = {
-"name": "XEP 0115 Plugin",
-"import_name": "XEP-0115",
-"type": "XEP",
-"protocols": ["XEP-0115"],
-"dependencies": [],
-"main": "XEP_0115",
-"handler": "yes",
-"description": _("""Implementation of entity capabilities""")
+ "name": "XEP 0115 Plugin",
+ "import_name": "XEP-0115",
+ "type": "XEP",
+ "protocols": ["XEP-0115"],
+ "dependencies": [],
+ "main": "XEP_0115",
+ "handler": "yes",
+ "description": _("""Implementation of entity capabilities""")
}
+
class HashGenerationError(Exception):
pass
+
class ByteIdentity(object):
"""This class manage identity as bytes (needed for i;octet sort),
it is used for the hash generation"""
@@ -74,16 +76,16 @@ class ByteIdentity(object):
class XEP_0115(object):
- cap_hash = None #capabilities hash is class variable as it is common to all profiles
+ cap_hash = None # capabilities hash is class variable as it is common to all profiles
#TODO: this code is really dirty, need to clean it and try to move it to Wokkel
def __init__(self, host):
info(_("Plugin XEP_0115 initialization"))
self.host = host
host.trigger.add("Disco Handled", self.checkHash)
- self.hash_cache = PersistentBinaryDict(NS_ENTITY_CAPABILITY) #key = hash or jid, value = features
+ self.hash_cache = PersistentBinaryDict(NS_ENTITY_CAPABILITY) # key = hash or jid, value = features
self.hash_cache.load()
- self.jid_hash = {} #jid to hash mapping, map to a discoInfo features if the hash method is unknown
+ self.jid_hash = {} # jid to hash mapping, map to a discoInfo features if the hash method is unknown
def checkHash(self, profile):
if not XEP_0115.cap_hash:
@@ -97,16 +99,17 @@ class XEP_0115(object):
def presenceHack(self, profile):
"""modify SatPresenceProtocol to add capabilities data"""
- client=self.host.getClient(profile)
+ client = self.host.getClient(profile)
presenceInst = client.presence
- c_elt = domish.Element((NS_ENTITY_CAPABILITY,'c'))
- c_elt['hash']='sha-1'
- c_elt['node']='http://wiki.goffi.org/wiki/Salut_%C3%A0_Toi'
- c_elt['ver']=XEP_0115.cap_hash
+ c_elt = domish.Element((NS_ENTITY_CAPABILITY, 'c'))
+ c_elt['hash'] = 'sha-1'
+ c_elt['node'] = 'http://wiki.goffi.org/wiki/Salut_%C3%A0_Toi'
+ c_elt['ver'] = XEP_0115.cap_hash
presenceInst._c_elt = c_elt
if "_legacy_send" in dir(presenceInst):
debug('capabilities already added to presence instance')
return
+
def hacked_send(self, obj):
obj.addChild(self._c_elt)
self._legacy_send(obj)
@@ -114,31 +117,30 @@ class XEP_0115(object):
presenceInst._legacy_send = presenceInst.send
presenceInst.send = new_send
-
def generateHash(self, profile_key="@DEFAULT@"):
"""This method generate a sha1 hash as explained in xep-0115 #5.1
it then store it in XEP_0115.cap_hash"""
profile = self.host.memory.getProfileName(profile_key)
if not profile:
- error ('Requesting hash for an inexistant profile')
+ error('Requesting hash for an inexistant profile')
raise HashGenerationError
client = self.host.getClient(profile_key)
if not client:
- error ('Requesting hash for an inexistant client')
+ error('Requesting hash for an inexistant client')
raise HashGenerationError
def generateHash_2(services, profile):
- _s=[]
- byte_identities = [ByteIdentity(identity) for identity in filter(lambda x:isinstance(x,disco.DiscoIdentity),services)] #FIXME: lang must be managed here
- byte_identities.sort(key=lambda i:i.lang)
- byte_identities.sort(key=lambda i:i.idType)
- byte_identities.sort(key=lambda i:i.category)
+ _s = []
+ byte_identities = [ByteIdentity(identity) for identity in filter(lambda x: isinstance(x, disco.DiscoIdentity), services)] # FIXME: lang must be managed here
+ byte_identities.sort(key=lambda i: i.lang)
+ byte_identities.sort(key=lambda i: i.idType)
+ byte_identities.sort(key=lambda i: i.category)
for identity in byte_identities:
_s.append(str(identity))
_s.append('<')
- byte_features = [feature.encode('utf-8') for feature in filter(lambda x:isinstance(x,disco.DiscoFeature),services)]
- byte_features.sort() #XXX: the default sort has the same behaviour as the requested RFC 4790 i;octet sort
+ byte_features = [feature.encode('utf-8') for feature in filter(lambda x: isinstance(x, disco.DiscoFeature), services)]
+ byte_features.sort() # XXX: the default sort has the same behaviour as the requested RFC 4790 i;octet sort
for feature in byte_features:
_s.append(feature)
_s.append('<')
@@ -149,6 +151,7 @@ class XEP_0115(object):
services = client.discoHandler.info(client.jid, client.jid, '').addCallback(generateHash_2, profile)
+
class XEP_0115_handler(XMPPHandler):
implements(iwokkel.IDisco)
@@ -176,7 +179,6 @@ class XEP_0115_handler(XMPPHandler):
#No key, that means unknown hash method
self.plugin_parent.jid_hash[from_jid] = discoResult.features
-
def update(self, presence):
"""
Manage the capabilities of the entity
@@ -184,11 +186,11 @@ class XEP_0115_handler(XMPPHandler):
and get the capibilities if necessary
"""
from_jid = jid.JID(presence['from'])
- c_elem = filter (lambda x:x.name == "c", presence.elements())[0] #We only want the "c" element
+ c_elem = filter(lambda x: x.name == "c", presence.elements())[0] # We only want the "c" element
try:
- ver=c_elem['ver']
- hash=c_elem['hash']
- node=c_elem['node']
+ ver = c_elem['ver']
+ hash = c_elem['hash']
+ node = c_elem['node']
except KeyError:
warning('Received invalid capabilities tag')
return
@@ -197,9 +199,8 @@ class XEP_0115_handler(XMPPHandler):
#we know that hash, we just link it with the jid
self.plugin_parent.jid_hash[from_jid] = ver
else:
- if hash!='sha-1':
+ if hash != 'sha-1':
#unknown hash method
warning('Unknown hash for entity capabilities: [%s]' % hash)
- self.parent.disco.requestInfo(from_jid).addCallback(self._updateCache, from_jid, ver if hash=='sha-1' else None )
+ self.parent.disco.requestInfo(from_jid).addCallback(self._updateCache, from_jid, ver if hash == 'sha-1' else None)
#TODO: me must manage the full algorithm described at XEP-0115 #5.4 part 3
-
diff --git a/src/plugins/plugin_xep_0163.py b/src/plugins/plugin_xep_0163.py
index 8eb0dedb..27745ace 100755
--- a/src/plugins/plugin_xep_0163.py
+++ b/src/plugins/plugin_xep_0163.py
@@ -26,32 +26,33 @@ from twisted.words.protocols.jabber import error as jab_error
import twisted.internet.error
from twisted.words.xish import domish
-from wokkel import disco,pubsub
+from wokkel import disco, pubsub
from wokkel.formats import Mood
NS_USER_MOOD = 'http://jabber.org/protocol/mood'
PLUGIN_INFO = {
-"name": "Personal Eventing Protocol Plugin",
-"import_name": "XEP-0163",
-"type": "XEP",
-"protocols": ["XEP-0163", "XEP-0107"],
-"dependencies": ["XEP-0060"],
-"main": "XEP_0163",
-"handler": "no",
-"description": _("""Implementation of Personal Eventing Protocol""")
+ "name": "Personal Eventing Protocol Plugin",
+ "import_name": "XEP-0163",
+ "type": "XEP",
+ "protocols": ["XEP-0163", "XEP-0107"],
+ "dependencies": ["XEP-0060"],
+ "main": "XEP_0163",
+ "handler": "no",
+ "description": _("""Implementation of Personal Eventing Protocol""")
}
+
class XEP_0163(object):
def __init__(self, host):
info(_("PEP plugin initialization"))
self.host = host
- self.pep_events=set()
- self.pep_out_cb={}
+ self.pep_events = set()
+ self.pep_out_cb = {}
host.trigger.add("PubSub Disco Info", self.disoInfoTrigger)
- host.bridge.addSignal("personalEvent", ".plugin", signature='ssa{ss}s') #args: from (jid), type(MOOD, TUNE, etc), data, profile
- host.bridge.addMethod("sendPersonalEvent", ".plugin", in_sign='sa{ss}s', out_sign='i', method=self.sendPersonalEvent) #args: type(MOOD, TUNE, etc), data, profile_key; return 0 or error_code
+ host.bridge.addSignal("personalEvent", ".plugin", signature='ssa{ss}s') # args: from (jid), type(MOOD, TUNE, etc), data, profile
+ host.bridge.addMethod("sendPersonalEvent", ".plugin", in_sign='sa{ss}s', out_sign='i', method=self.sendPersonalEvent) # args: type(MOOD, TUNE, etc), data, profile_key; return 0 or error_code
self.addPEPEvent("MOOD", NS_USER_MOOD, self.userMoodCB, self.sendMood)
def disoInfoTrigger(self, disco_info, profile):
@@ -62,7 +63,7 @@ class XEP_0163(object):
disco_info.extend(map(disco.DiscoFeature, self.pep_events))
return True
- def addPEPEvent(self, event_type, name, in_callback, out_callback = None, notify = True):
+ def addPEPEvent(self, event_type, name, in_callback, out_callback=None, notify=True):
"""Add a Personal Eventing Protocol event manager
@param event_type: type of the event (always uppercase), can be MOOD, TUNE, etc
@param name: namespace of the node (e.g. http://jabber.org/protocol/mood for User Mood)
@@ -73,7 +74,7 @@ class XEP_0163(object):
self.pep_out_cb[event_type] = out_callback
self.pep_events.add(name)
if notify:
- self.pep_events.add(name+"+notify")
+ self.pep_events.add(name + "+notify")
self.host.plugins["XEP-0060"].addManagedNode(name, in_callback)
def sendPEPEvent(self, namespace, data, profile):
@@ -83,7 +84,7 @@ class XEP_0163(object):
@param profile: profile which send the data"""
item = pubsub.Item(payload=data)
- self.host.plugins["XEP-0060"].publish(None, namespace, [item], profile_key = profile)
+ self.host.plugins["XEP-0060"].publish(None, namespace, [item], profile_key=profile)
def sendPersonalEvent(self, event_type, data, profile_key='@DEFAULT@'):
"""Send personal event after checking the data is alright
@@ -96,7 +97,7 @@ class XEP_0163(object):
error(_('Trying to send personal event with an unknown profile key [%s]') % profile_key)
return 1
if not event_type in self.pep_out_cb.keys():
- error (_('Trying to send personal event for an unknown type'))
+ error(_('Trying to send personal event for an unknown type'))
return 2
return self.pep_out_cb[event_type](data, profile)
@@ -105,7 +106,7 @@ class XEP_0163(object):
debug(_("No item found"))
return
try:
- mood_elem = filter(lambda x:x.name == "mood", itemsEvent.items[0].children)[0]
+ mood_elem = filter(lambda x: x.name == "mood", itemsEvent.items[0].children)[0]
except KeyError:
error(_("Can't find mood element in mood event"))
return
@@ -113,7 +114,7 @@ class XEP_0163(object):
if not _mood:
debug(_("No mood found"))
return
- self.host.bridge.personalEvent(itemsEvent.sender.full(), "MOOD", {"mood":_mood.value or "", "text":_mood.text or ""}, profile)
+ self.host.bridge.personalEvent(itemsEvent.sender.full(), "MOOD", {"mood": _mood.value or "", "text": _mood.text or ""}, profile)
def sendMood(self, data, profile):
"""Send XEP-0107's User Mood
@@ -121,7 +122,7 @@ class XEP_0163(object):
@param profile: profile which send the mood"""
try:
value = data['mood'].lower()
- text = data['text'] if data.has_key('text') else ''
+ text = data['text'] if 'text' in data else ''
except KeyError:
error(_("Mood data must contain at least 'mood' key"))
return 3
@@ -129,6 +130,7 @@ class XEP_0163(object):
self.sendPEPEvent(NS_USER_MOOD, _mood, profile)
return 0
+
class UserMood(Mood, domish.Element):
"""Improved wokkel Mood which is also a domish.Element"""
@@ -138,4 +140,3 @@ class UserMood(Mood, domish.Element):
self.addElement(value)
if text:
self.addElement('text', content=text)
-
diff --git a/src/plugins/plugin_xep_0249.py b/src/plugins/plugin_xep_0249.py
index 83ea4c7f..7b53a58e 100755
--- a/src/plugins/plugin_xep_0249.py
+++ b/src/plugins/plugin_xep_0249.py
@@ -34,21 +34,22 @@ try:
except ImportError:
from wokkel.subprotocols import XMPPHandler
-MESSAGE= '/message'
+MESSAGE = '/message'
NS_DIRECT_MUC_INVITATION = 'jabber:x:conference'
DIRECT_MUC_INVITATION_REQUEST = MESSAGE + '/x[@xmlns="' + NS_DIRECT_MUC_INVITATION + '"]'
PLUGIN_INFO = {
-"name": "XEP 0249 Plugin",
-"import_name": "XEP-0249",
-"type": "XEP",
-"protocols": ["XEP-0249"],
-"dependencies": ["XEP-0045"],
-"main": "XEP_0249",
-"handler": "yes",
-"description": _("""Implementation of Direct MUC Invitations""")
+ "name": "XEP 0249 Plugin",
+ "import_name": "XEP-0249",
+ "type": "XEP",
+ "protocols": ["XEP-0249"],
+ "dependencies": ["XEP-0045"],
+ "main": "XEP_0249",
+ "handler": "yes",
+ "description": _("""Implementation of Direct MUC Invitations""")
}
+
class XEP_0249(object):
def __init__(self, host):
@@ -71,15 +72,15 @@ class XEP_0249(object):
if not profile:
error(_("Profile doesn't exists !"))
return
- message = domish.Element((None,'message'))
+ message = domish.Element((None, 'message'))
message["to"] = target.full()
- x_elt = message.addElement('x',NS_DIRECT_MUC_INVITATION)
+ x_elt = message.addElement('x', NS_DIRECT_MUC_INVITATION)
x_elt['jid'] = room.userhost()
for opt in options:
x_elt[opt] = options[opt]
self.host.profiles[profile].xmlstream.send(message)
- def _invite(self, target, service, roomId, options = {}, profile_key='@DEFAULT@'):
+ def _invite(self, target, service, roomId, options={}, profile_key='@DEFAULT@'):
"""
Invite an user to a room
@param target: jid of the user to invite
@@ -90,14 +91,13 @@ class XEP_0249(object):
#TODO: check parameters validity
self.invite(jid.JID(target), jid.JID("%s@%s" % (roomId, service)), options, profile_key)
-
def onInvitation(self, message, profile):
"""
called when an invitation is received
@param message: message element
@profile: %(doc_profile)s
"""
- info(_('Invitation received for room %(room)s [%(profile)s]') % {'room':'','profile':profile})
+ info(_('Invitation received for room %(room)s [%(profile)s]') % {'room': '', 'profile': profile})
try:
room = jid.JID(message.firstChildElement()['jid'])
except:
@@ -116,7 +116,7 @@ class XEP_0249_handler(XMPPHandler):
self.host = plugin_parent.host
def connectionInitialized(self):
- self.xmlstream.addObserver(DIRECT_MUC_INVITATION_REQUEST, self.plugin_parent.onInvitation, profile = self.parent.profile)
+ self.xmlstream.addObserver(DIRECT_MUC_INVITATION_REQUEST, self.plugin_parent.onInvitation, profile=self.parent.profile)
def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
return [disco.DiscoFeature(NS_DIRECT_MUC_INVITATION)]
diff --git a/src/plugins/plugin_xep_0277.py b/src/plugins/plugin_xep_0277.py
index 69c2c24f..370bc87e 100755
--- a/src/plugins/plugin_xep_0277.py
+++ b/src/plugins/plugin_xep_0277.py
@@ -27,7 +27,7 @@ import twisted.internet.error
from twisted.words.xish import domish
from sat.tools.xml_tools import ElementParser
-from wokkel import disco,pubsub
+from wokkel import disco, pubsub
from feed.atom import Entry, Author
import uuid
from time import time
@@ -40,19 +40,21 @@ OPT_DELIVER_PAYLOADS = 'pubsub#deliver_payloads'
OPT_SEND_ITEM_SUBSCRIBE = 'pubsub#send_item_subscribe'
PLUGIN_INFO = {
-"name": "Microblogging over XMPP Plugin",
-"import_name": "XEP-0277",
-"type": "XEP",
-"protocols": [],
-"dependencies": ["XEP-0163","XEP-0060"],
-"main": "XEP_0277",
-"handler": "no",
-"description": _("""Implementation of microblogging Protocol""")
+ "name": "Microblogging over XMPP Plugin",
+ "import_name": "XEP-0277",
+ "type": "XEP",
+ "protocols": [],
+ "dependencies": ["XEP-0163", "XEP-0060"],
+ "main": "XEP_0277",
+ "handler": "no",
+ "description": _("""Implementation of microblogging Protocol""")
}
+
class NodeAccessChangeException(Exception):
pass
+
class XEP_0277(object):
def __init__(self, host):
@@ -62,30 +64,28 @@ class XEP_0277(object):
host.bridge.addMethod("getLastMicroblogs", ".plugin",
in_sign='sis', out_sign='aa{ss}',
method=self.getLastMicroblogs,
- async = True,
- doc = { 'summary':'retrieve items',
- 'param_0':'jid: publisher of wanted microblog',
- 'param_1':'max_items: see XEP-0060 #6.5.7',
- 'param_2':'%(doc_profile)s',
- 'return':'list of microblog data (dict)'
- })
+ async=True,
+ doc={'summary': 'retrieve items',
+ 'param_0': 'jid: publisher of wanted microblog',
+ 'param_1': 'max_items: see XEP-0060 #6.5.7',
+ 'param_2': '%(doc_profile)s',
+ 'return': 'list of microblog data (dict)'})
host.bridge.addMethod("setMicroblogAccess", ".plugin", in_sign='ss', out_sign='',
- method=self.setMicroblogAccess,
- async = True,
- doc = {
- })
+ method=self.setMicroblogAccess,
+ async=True,
+ doc={})
def item2mbdata(self, item):
"""Convert an XML Item to microblog data used in bridge API
@param item: domish.Element of microblog item
@return: microblog data (dictionary)"""
try:
- entry_elt = filter (lambda x:x.name == "entry", item.children)[0]
+ entry_elt = filter(lambda x: x.name == "entry", item.children)[0]
except KeyError:
warning(_('No entry element in microblog item'))
return
_entry = Entry().import_xml(entry_elt.toXml().encode('utf-8'))
- microblog_data={}
+ microblog_data = {}
try:
microblog_data['content'] = _entry.title.text
if len(_entry.authors):
@@ -100,7 +100,7 @@ class XEP_0277(object):
if not 'author' in microblog_data:
from xe import NestElement
try:
- author=NestElement('author')
+ author = NestElement('author')
author.import_xml(str(_entry))
microblog_data['author'] = author.nick.text
except:
@@ -123,8 +123,8 @@ class XEP_0277(object):
#FIXME: need to escape html
_entry.title = unicode(content).encode('utf-8')
_entry.author = Author()
- _entry.author.name = data.get('author',self.host.getJidNStream(profile)[0].userhost()).encode('utf-8')
- _entry.updated = float(data.get('timestamp',time()))
+ _entry.author.name = data.get('author', self.host.getJidNStream(profile)[0].userhost()).encode('utf-8')
+ _entry.updated = float(data.get('timestamp', time()))
_entry.id = str(_uuid)
_entry_elt = ElementParser()(str(_entry).decode('utf-8'))
item = pubsub.Item(payload=_entry_elt)
@@ -135,7 +135,7 @@ class XEP_0277(object):
"""Send XEP-0277's microblog data
@param data: must include content
@param profile: profile which send the mood"""
- if not data.has_key('content'):
+ if 'content' not in data:
error(_("Microblog data must contain at least 'content' key"))
return 3
content = data['content']
@@ -143,7 +143,7 @@ class XEP_0277(object):
error(_("Microblog data's content value must not be empty"))
return 3
item = self.data2entry(data, profile)
- self.host.plugins["XEP-0060"].publish(None, NS_MICROBLOG, [item], profile_key = profile)
+ self.host.plugins["XEP-0060"].publish(None, NS_MICROBLOG, [item], profile_key=profile)
return 0
def getLastMicroblogs(self, pub_jid, max_items=10, profile_key='@DEFAULT@'):
@@ -168,7 +168,7 @@ class XEP_0277(object):
if not _jid:
error(_("Can't find profile's jid"))
return
- _options = {OPT_ACCESS_MODEL:access, OPT_PERSIST_ITEMS:1, OPT_MAX_ITEMS:-1, OPT_DELIVER_PAYLOADS:1, OPT_SEND_ITEM_SUBSCRIBE: 1}
+ _options = {OPT_ACCESS_MODEL: access, OPT_PERSIST_ITEMS: 1, OPT_MAX_ITEMS: -1, OPT_DELIVER_PAYLOADS: 1, OPT_SEND_ITEM_SUBSCRIBE: 1}
def cb(result):
#Node is created with right permission
@@ -182,7 +182,7 @@ class XEP_0277(object):
def err_cb(s_error):
#If the node already exists, the condition is "conflict",
#else we have an unmanaged error
- if s_error.value.condition=='conflict':
+ if s_error.value.condition == 'conflict':
#d = self.host.plugins["XEP-0060"].deleteNode(_jid.userhostJID(), NS_MICROBLOG, profile_key=profile_key)
#d.addCallback(lambda x: create_node().addCallback(cb).addErrback(fatal_err))
change_node_options().addCallback(cb).addErrback(fatal_err)
@@ -196,6 +196,3 @@ class XEP_0277(object):
return self.host.plugins["XEP-0060"].setOptions(_jid.userhostJID(), NS_MICROBLOG, _jid.userhostJID(), _options, profile_key=profile_key)
create_node().addCallback(cb).addErrback(err_cb)
-
-
-