From 4fb77ac8787422169566d613562127acf75a427b Mon Sep 17 00:00:00 2001 From: Lance Stout Date: Sat, 6 Nov 2010 01:28:59 -0400 Subject: Logging no longer uses root logger. Each module should now log into its own logger. --- sleekxmpp/basexmpp.py | 35 +++++++------ sleekxmpp/clientxmpp.py | 29 +++++----- sleekxmpp/componentxmpp.py | 5 +- sleekxmpp/plugins/gmail_notify.py | 25 +++++---- sleekxmpp/plugins/jobs.py | 10 ++-- sleekxmpp/plugins/old_0004.py | 80 ++++++++++++++-------------- sleekxmpp/plugins/xep_0004.py | 27 +++++----- sleekxmpp/plugins/xep_0012.py | 7 ++- sleekxmpp/plugins/xep_0030.py | 20 ++++--- sleekxmpp/plugins/xep_0045.py | 82 +++++++++++++++-------------- sleekxmpp/plugins/xep_0060.py | 40 +++++++------- sleekxmpp/plugins/xep_0078.py | 17 +++--- sleekxmpp/plugins/xep_0085.py | 23 ++++---- sleekxmpp/plugins/xep_0199.py | 14 +++-- sleekxmpp/plugins/xep_0202.py | 7 ++- sleekxmpp/stanza/rootstanza.py | 5 +- sleekxmpp/thirdparty/statemachine.py | 96 +++++++++++++++++----------------- sleekxmpp/xmlstream/handler/waiter.py | 5 +- sleekxmpp/xmlstream/matcher/xmlmask.py | 8 ++- sleekxmpp/xmlstream/scheduler.py | 7 ++- sleekxmpp/xmlstream/stanzabase.py | 5 +- sleekxmpp/xmlstream/xmlstream.py | 67 ++++++++++++------------ 22 files changed, 342 insertions(+), 272 deletions(-) diff --git a/sleekxmpp/basexmpp.py b/sleekxmpp/basexmpp.py index 1e8441aa..77191e77 100644 --- a/sleekxmpp/basexmpp.py +++ b/sleekxmpp/basexmpp.py @@ -26,6 +26,9 @@ from sleekxmpp.xmlstream.matcher import * from sleekxmpp.xmlstream.handler import * +log = logging.getLogger(__name__) + + # Flag indicating if DNS SRV records are available for use. SRV_SUPPORT = True try: @@ -192,9 +195,9 @@ class BaseXMPP(XMLStream): xep = "(XEP-%s) " % self.plugin[plugin].xep desc = (xep, self.plugin[plugin].description) - logging.debug("Loaded Plugin %s%s" % desc) + log.debug("Loaded Plugin %s%s" % desc) except: - logging.exception("Unable to load plugin: %s", plugin) + log.exception("Unable to load plugin: %s", plugin) def register_plugins(self): """ @@ -228,7 +231,7 @@ class BaseXMPP(XMLStream): if key in self.plugin: return self.plugin[key] else: - logging.warning("""Plugin "%s" is not loaded.""" % key) + log.warning("""Plugin "%s" is not loaded.""" % key) return False def get(self, key, default): @@ -446,12 +449,12 @@ class BaseXMPP(XMLStream): """ Attribute accessor for bare jid """ - logging.warning("jid property deprecated. Use boundjid.bare") + log.warning("jid property deprecated. Use boundjid.bare") return self.boundjid.bare @jid.setter def jid(self, value): - logging.warning("jid property deprecated. Use boundjid.bare") + log.warning("jid property deprecated. Use boundjid.bare") self.boundjid.bare = value @property @@ -459,12 +462,12 @@ class BaseXMPP(XMLStream): """ Attribute accessor for full jid """ - logging.warning("fulljid property deprecated. Use boundjid.full") + log.warning("fulljid property deprecated. Use boundjid.full") return self.boundjid.full @fulljid.setter def fulljid(self, value): - logging.warning("fulljid property deprecated. Use boundjid.full") + log.warning("fulljid property deprecated. Use boundjid.full") self.boundjid.full = value @property @@ -472,12 +475,12 @@ class BaseXMPP(XMLStream): """ Attribute accessor for jid resource """ - logging.warning("resource property deprecated. Use boundjid.resource") + log.warning("resource property deprecated. Use boundjid.resource") return self.boundjid.resource @resource.setter def resource(self, value): - logging.warning("fulljid property deprecated. Use boundjid.full") + log.warning("fulljid property deprecated. Use boundjid.full") self.boundjid.resource = value @property @@ -485,12 +488,12 @@ class BaseXMPP(XMLStream): """ Attribute accessor for jid usernode """ - logging.warning("username property deprecated. Use boundjid.user") + log.warning("username property deprecated. Use boundjid.user") return self.boundjid.user @username.setter def username(self, value): - logging.warning("username property deprecated. Use boundjid.user") + log.warning("username property deprecated. Use boundjid.user") self.boundjid.user = value @property @@ -498,17 +501,17 @@ class BaseXMPP(XMLStream): """ Attribute accessor for jid host """ - logging.warning("server property deprecated. Use boundjid.host") + log.warning("server property deprecated. Use boundjid.host") return self.boundjid.server @server.setter def server(self, value): - logging.warning("server property deprecated. Use boundjid.host") + log.warning("server property deprecated. Use boundjid.host") self.boundjid.server = value def set_jid(self, jid): """Rip a JID apart and claim it as our own.""" - logging.debug("setting jid to %s" % jid) + log.debug("setting jid to %s" % jid) self.boundjid.full = jid def getjidresource(self, fulljid): @@ -588,7 +591,7 @@ class BaseXMPP(XMLStream): # disconnects. Determine if this was the last connection # for the JID. if show == 'unavailable': - logging.debug("%s %s got offline" % (jid, resource)) + log.debug("%s %s got offline" % (jid, resource)) del connections[resource] if not connections and not self.roster[jid]['in_roster']: @@ -604,7 +607,7 @@ class BaseXMPP(XMLStream): self.event("changed_status", presence) if got_online: self.event("got_online", presence) - logging.debug("STATUS: %s%s/%s[%s]: %s" % (name, jid, resource, + log.debug("STATUS: %s%s/%s[%s]: %s" % (name, jid, resource, show, status)) def _handle_subscribe(self, presence): diff --git a/sleekxmpp/clientxmpp.py b/sleekxmpp/clientxmpp.py index dc4d0e4a..a88c5ccb 100644 --- a/sleekxmpp/clientxmpp.py +++ b/sleekxmpp/clientxmpp.py @@ -32,6 +32,9 @@ except: SRV_SUPPORT = False +log = logging.getLogger(__name__) + + class ClientXMPP(BaseXMPP): """ @@ -133,7 +136,7 @@ class ClientXMPP(BaseXMPP): def _session_timeout_check(self): if not self.session_started_event.isSet(): - logging.debug("Session start has taken more than 15 seconds") + log.debug("Session start has taken more than 15 seconds") self.disconnect(reconnect=self.auto_reconnect) def connect(self, address=tuple()): @@ -150,19 +153,19 @@ class ClientXMPP(BaseXMPP): self.session_started_event.clear() if not address or len(address) < 2: if not self.srv_support: - logging.debug("Did not supply (address, port) to connect" + \ + log.debug("Did not supply (address, port) to connect" + \ " to and no SRV support is installed" + \ " (http://www.dnspython.org)." + \ " Continuing to attempt connection, using" + \ " server hostname from JID.") else: - logging.debug("Since no address is supplied," + \ + log.debug("Since no address is supplied," + \ "attempting SRV lookup.") try: xmpp_srv = "_xmpp-client._tcp.%s" % self.server answers = dns.resolver.query(xmpp_srv, dns.rdatatype.SRV) except dns.resolver.NXDOMAIN: - logging.debug("No appropriate SRV record found." + \ + log.debug("No appropriate SRV record found." + \ " Using JID server name.") else: # Pick a random server, weighted by priority. @@ -276,7 +279,7 @@ class ClientXMPP(BaseXMPP): self.send_xml(xml) return True else: - logging.warning("The module tlslite is required to log in" +\ + log.warning("The module tlslite is required to log in" +\ " to some servers, and has not been found.") return False @@ -286,7 +289,7 @@ class ClientXMPP(BaseXMPP): Restarts the stream. """ - logging.debug("Starting TLS") + log.debug("Starting TLS") if self.start_tls(): raise RestartStream() @@ -300,7 +303,7 @@ class ClientXMPP(BaseXMPP): if '{urn:ietf:params:xml:ns:xmpp-tls}starttls' in self.features: return False - logging.debug("Starting SASL Auth") + log.debug("Starting SASL Auth") sasl_ns = 'urn:ietf:params:xml:ns:xmpp-sasl' self.add_handler("" % sasl_ns, self._handle_auth_success, @@ -334,7 +337,7 @@ class ClientXMPP(BaseXMPP): sasl_ns, 'ANONYMOUS')) else: - logging.error("No appropriate login method.") + log.error("No appropriate login method.") self.disconnect() return True @@ -356,7 +359,7 @@ class ClientXMPP(BaseXMPP): Arguments: xml -- The SASL authentication failure element. """ - logging.info("Authentication failed.") + log.info("Authentication failed.") self.event("failed_auth", direct=True) self.disconnect() @@ -367,7 +370,7 @@ class ClientXMPP(BaseXMPP): Arguments: xml -- The bind feature element. """ - logging.debug("Requesting resource: %s" % self.boundjid.resource) + log.debug("Requesting resource: %s" % self.boundjid.resource) xml.clear() iq = self.Iq(stype='set') if self.boundjid.resource: @@ -381,10 +384,10 @@ class ClientXMPP(BaseXMPP): self.set_jid(response.xml.find('{%s}bind/{%s}jid' % (bind_ns, bind_ns)).text) self.bound = True - logging.info("Node set to: %s" % self.boundjid.fulljid) + log.info("Node set to: %s" % self.boundjid.fulljid) session_ns = 'urn:ietf:params:xml:ns:xmpp-session' if "{%s}session" % session_ns not in self.features or self.bindfail: - logging.debug("Established Session") + log.debug("Established Session") self.sessionstarted = True self.session_started_event.set() self.event("session_start") @@ -399,7 +402,7 @@ class ClientXMPP(BaseXMPP): if self.authenticated and self.bound: iq = self.makeIqSet(xml) response = iq.send() - logging.debug("Established Session") + log.debug("Established Session") self.sessionstarted = True self.session_started_event.set() self.event("session_start") diff --git a/sleekxmpp/componentxmpp.py b/sleekxmpp/componentxmpp.py index 3fcb88d9..8b0b6cc0 100644 --- a/sleekxmpp/componentxmpp.py +++ b/sleekxmpp/componentxmpp.py @@ -22,6 +22,9 @@ from sleekxmpp.xmlstream.matcher import * from sleekxmpp.xmlstream.handler import * +log = logging.getLogger(__name__) + + class ComponentXMPP(BaseXMPP): """ @@ -82,7 +85,7 @@ class ComponentXMPP(BaseXMPP): Overrides XMLStream.connect. """ - logging.debug("Connecting to %s:%s" % (self.server_host, + log.debug("Connecting to %s:%s" % (self.server_host, self.server_port)) return XMLStream.connect(self, self.server_host, self.server_port) diff --git a/sleekxmpp/plugins/gmail_notify.py b/sleekxmpp/plugins/gmail_notify.py index 7e442346..7e888b90 100644 --- a/sleekxmpp/plugins/gmail_notify.py +++ b/sleekxmpp/plugins/gmail_notify.py @@ -14,6 +14,9 @@ from .. xmlstream.stanzabase import registerStanzaPlugin, ElementBase, ET, JID from .. stanza.iq import Iq +log = logging.getLogger(__name__) + + class GmailQuery(ElementBase): namespace = 'google:mail:notify' name = 'query' @@ -34,12 +37,12 @@ class MailBox(ElementBase): namespace = 'google:mail:notify' name = 'mailbox' plugin_attrib = 'mailbox' - interfaces = set(('result-time', 'total-matched', 'total-estimate', + interfaces = set(('result-time', 'total-matched', 'total-estimate', 'url', 'threads', 'matched', 'estimate')) def getThreads(self): threads = [] - for threadXML in self.xml.findall('{%s}%s' % (MailThread.namespace, + for threadXML in self.xml.findall('{%s}%s' % (MailThread.namespace, MailThread.name)): threads.append(MailThread(xml=threadXML, parent=None)) return threads @@ -55,10 +58,10 @@ class MailThread(ElementBase): namespace = 'google:mail:notify' name = 'mail-thread-info' plugin_attrib = 'thread' - interfaces = set(('tid', 'participation', 'messages', 'date', + interfaces = set(('tid', 'participation', 'messages', 'date', 'senders', 'url', 'labels', 'subject', 'snippet')) sub_interfaces = set(('labels', 'subject', 'snippet')) - + def getSenders(self): senders = [] sendersXML = self.xml.find('{%s}senders' % self.namespace) @@ -91,13 +94,13 @@ class gmail_notify(base.base_plugin): """ Google Talk: Gmail Notifications """ - + def plugin_init(self): self.description = 'Google Talk: Gmail Notifications' self.xmpp.registerHandler( Callback('Gmail Result', - MatchXPath('{%s}iq/{%s}%s' % (self.xmpp.default_ns, + MatchXPath('{%s}iq/{%s}%s' % (self.xmpp.default_ns, MailBox.namespace, MailBox.name)), self.handle_gmail)) @@ -108,7 +111,7 @@ class gmail_notify(base.base_plugin): NewMail.namespace, NewMail.name)), self.handle_new_mail)) - + registerStanzaPlugin(Iq, GmailQuery) registerStanzaPlugin(Iq, MailBox) registerStanzaPlugin(Iq, NewMail) @@ -118,12 +121,12 @@ class gmail_notify(base.base_plugin): def handle_gmail(self, iq): mailbox = iq['mailbox'] approx = ' approximately' if mailbox['estimated'] else '' - logging.info('Gmail: Received%s %s emails' % (approx, mailbox['total-matched'])) + log.info('Gmail: Received%s %s emails' % (approx, mailbox['total-matched'])) self.last_result_time = mailbox['result-time'] self.xmpp.event('gmail_messages', iq) def handle_new_mail(self, iq): - logging.info("Gmail: New emails received!") + log.info("Gmail: New emails received!") self.xmpp.event('gmail_notify') self.checkEmail() @@ -135,9 +138,9 @@ class gmail_notify(base.base_plugin): def search(self, query=None, newer=None): if query is None: - logging.info("Gmail: Checking for new emails") + log.info("Gmail: Checking for new emails") else: - logging.info('Gmail: Searching for emails matching: "%s"' % query) + log.info('Gmail: Searching for emails matching: "%s"' % query) iq = self.xmpp.Iq() iq['type'] = 'get' iq['to'] = self.xmpp.jid diff --git a/sleekxmpp/plugins/jobs.py b/sleekxmpp/plugins/jobs.py index c52e524e..0b93d62e 100644 --- a/sleekxmpp/plugins/jobs.py +++ b/sleekxmpp/plugins/jobs.py @@ -3,15 +3,19 @@ import logging from xml.etree import cElementTree as ET import types + +log = logging.getLogger(__name__) + + class jobs(base.base_plugin): def plugin_init(self): self.xep = 'pubsubjob' self.description = "Job distribution over Pubsub" - + def post_init(self): pass #TODO add event - + def createJobNode(self, host, jid, node, config=None): pass @@ -40,7 +44,7 @@ class jobs(base.base_plugin): iq['psstate']['payload'] = state result = iq.send() if result is None or type(result) == types.BooleanType or result['type'] != 'result': - logging.error("Unable to change %s:%s to %s" % (node, jobid, state)) + log.error("Unable to change %s:%s to %s" % (node, jobid, state)) return False return True diff --git a/sleekxmpp/plugins/old_0004.py b/sleekxmpp/plugins/old_0004.py index 651408ae..ade3d682 100644 --- a/sleekxmpp/plugins/old_0004.py +++ b/sleekxmpp/plugins/old_0004.py @@ -2,42 +2,46 @@ SleekXMPP: The Sleek XMPP Library Copyright (C) 2010 Nathanael C. Fritz This file is part of SleekXMPP. - + See the file LICENSE for copying permission. """ from . import base -import logging +import log from xml.etree import cElementTree as ET import copy import logging #TODO support item groups and results + +log = logging.getLogger(__name__) + + class old_0004(base.base_plugin): - + def plugin_init(self): self.xep = '0004' self.description = '*Deprecated Data Forms' self.xmpp.add_handler("", self.handler_message_xform, name='Old Message Form') - + def post_init(self): base.base_plugin.post_init(self) self.xmpp.plugin['xep_0030'].add_feature('jabber:x:data') - logging.warning("This implementation of XEP-0004 is deprecated.") - + log.warning("This implementation of XEP-0004 is deprecated.") + def handler_message_xform(self, xml): object = self.handle_form(xml) self.xmpp.event("message_form", object) - + def handler_presence_xform(self, xml): object = self.handle_form(xml) self.xmpp.event("presence_form", object) - + def handle_form(self, xml): xmlform = xml.find('{jabber:x:data}x') object = self.buildForm(xmlform) self.xmpp.event("message_xform", object) return object - + def buildForm(self, xml): form = Form(ftype=xml.attrib['type']) form.fromXML(xml) @@ -51,12 +55,12 @@ class FieldContainer(object): self.fields = [] self.field = {} self.stanza = stanza - + def addField(self, var, ftype='text-single', label='', desc='', required=False, value=None): self.field[var] = FormField(var, ftype, label, desc, required, value) self.fields.append(self.field[var]) return self.field[var] - + def buildField(self, xml): self.field[xml.get('var', '__unnamed__')] = FormField(xml.get('var', '__unnamed__'), xml.get('type', 'text-single')) self.fields.append(self.field[xml.get('var', '__unnamed__')]) @@ -66,13 +70,13 @@ class FieldContainer(object): self.stanza = xml.tag for field in xml.findall('{jabber:x:data}field'): self.buildField(field) - + def getXML(self, ftype): container = ET.Element(self.stanza) for field in self.fields: container.append(field.getXML(ftype)) return container - + class Form(FieldContainer): types = ('form', 'submit', 'cancel', 'result') def __init__(self, xmpp=None, ftype='form', title='', instructions=''): @@ -85,7 +89,7 @@ class Form(FieldContainer): self.instructions = instructions self.reported = [] self.items = [] - + def merge(self, form2): form1 = Form(ftype=self.type) form1.fromXML(self.getXML(self.type)) @@ -98,18 +102,18 @@ class Form(FieldContainer): if (option, label) not in form1.field[field.var].options: form1.fields[field.var].addOption(option, label) return form1 - + def copy(self): newform = Form(ftype=self.type) newform.fromXML(self.getXML(self.type)) return newform - + def update(self, form): values = form.getValues() for var in values: if var in self.fields: self.fields[var].setValue(self.fields[var]) - + def getValues(self): result = {} for field in self.fields: @@ -118,7 +122,7 @@ class Form(FieldContainer): value = value[0] result[field.var] = value return result - + def setValues(self, values={}): for field in values: if field in self.field: @@ -127,10 +131,10 @@ class Form(FieldContainer): self.field[field].setValue(value) else: self.field[field].setValue(values[field]) - + def fromXML(self, xml): self.buildForm(xml) - + def addItem(self): newitem = FieldContainer('item') self.items.append(newitem) @@ -148,21 +152,21 @@ class Form(FieldContainer): def buildReported(self, xml): reported = self.addReported() reported.buildContainer(xml) - + def setTitle(self, title): self.title = title - + def setInstructions(self, instructions): self.instructions = instructions - + def setType(self, ftype): self.type = ftype - + def getXMLMessage(self, to): msg = self.xmpp.makeMessage(to) msg.append(self.getXML()) return msg - + def buildForm(self, xml): self.type = xml.get('type', 'form') if xml.find('{jabber:x:data}title') is not None: @@ -175,7 +179,7 @@ class Form(FieldContainer): self.buildReported(reported) for item in xml.findall('{jabber:x:data}item'): self.buildItem(item) - + #def getXML(self, tostring = False): def getXML(self, ftype=None): if ftype: @@ -199,7 +203,7 @@ class Form(FieldContainer): #if tostring: # form = self.xmpp.tostring(form) return form - + def getXHTML(self): form = ET.Element('{http://www.w3.org/1999/xhtml}form') if self.title: @@ -217,8 +221,8 @@ class Form(FieldContainer): for field in self.items: form.append(field.getXHTML()) return form - - + + def makeSubmit(self): self.setType('submit') @@ -246,13 +250,13 @@ class FormField(object): self.islinebreak = False if value: self.setValue(value) - + def addOption(self, value, label): if self.islist: self.options.append((value, label)) else: raise ValueError("Cannot add options to non-list type field.") - + def setTrue(self): if self.type == 'boolean': self.value = [True] @@ -263,10 +267,10 @@ class FormField(object): def require(self): self.required = True - + def setDescription(self, desc): self.desc = desc - + def setValue(self, value): if self.type == 'boolean': if value in ('1', 1, True, 'true', 'True', 'yes'): @@ -291,10 +295,10 @@ class FormField(object): pass else: self.value = '' - + def setAnswer(self, value): self.setValue(value) - + def buildField(self, xml): self.type = xml.get('type', 'text-single') self.label = xml.get('label', '') @@ -306,7 +310,7 @@ class FormField(object): self.require() if xml.find('{jabber:x:data}desc') is not None: self.setDescription(xml.find('{jabber:x:data}desc').text) - + def getXML(self, ftype): field = ET.Element('{jabber:x:data}field') if ftype != 'result': @@ -342,7 +346,7 @@ class FormField(object): valuexml.text = value field.append(valuexml) return field - + def getXHTML(self): field = ET.Element('div', {'class': 'xmpp-xforms-%s' % self.type}) if self.label: @@ -414,4 +418,4 @@ class FormField(object): pass label.append(formf) return field - + diff --git a/sleekxmpp/plugins/xep_0004.py b/sleekxmpp/plugins/xep_0004.py index e8dba74c..b8b7ebfa 100644 --- a/sleekxmpp/plugins/xep_0004.py +++ b/sleekxmpp/plugins/xep_0004.py @@ -16,6 +16,9 @@ from .. stanza.message import Message import types +log = logging.getLogger(__name__) + + class Form(ElementBase): namespace = 'jabber:x:data' name = 'x' @@ -33,7 +36,7 @@ class Form(ElementBase): if title is not None: self['title'] = title self.field = FieldAccessor(self) - + def setup(self, xml=None): if ElementBase.setup(self, xml): #if we had to generate xml self['type'] = 'form' @@ -55,11 +58,11 @@ class Form(ElementBase): return field def getXML(self, type='submit'): - logging.warning("Form.getXML() is deprecated API compatibility with plugins/old_0004.py") + log.warning("Form.getXML() is deprecated API compatibility with plugins/old_0004.py") return self.xml - + def fromXML(self, xml): - logging.warning("Form.fromXML() is deprecated API compatibility with plugins/old_0004.py") + log.warning("Form.fromXML() is deprecated API compatibility with plugins/old_0004.py") n = Form(xml=xml) return n @@ -113,10 +116,10 @@ class Form(ElementBase): reportedXML = self.xml.find('{%s}reported' % self.namespace) if reportedXML is not None: self.xml.remove(reportedXML) - + def getFields(self, use_dict=False): fields = {} if use_dict else [] - fieldsXML = self.xml.findall('{%s}field' % FormField.namespace) + fieldsXML = self.xml.findall('{%s}field' % FormField.namespace) for fieldXML in fieldsXML: field = FormField(xml=fieldXML) if use_dict: @@ -144,7 +147,7 @@ class Form(ElementBase): def getReported(self): fields = {} - fieldsXML = self.xml.findall('{%s}reported/{%s}field' % (self.namespace, + fieldsXML = self.xml.findall('{%s}reported/{%s}field' % (self.namespace, FormField.namespace)) for fieldXML in fieldsXML: field = FormField(xml=fieldXML) @@ -197,7 +200,7 @@ class Form(ElementBase): fields = self.getFields(use_dict=True) for field in values: fields[field]['value'] = values[field] - + def merge(self, other): new = copy.copy(self) if type(other) == types.DictType: @@ -212,7 +215,7 @@ class Form(ElementBase): class FieldAccessor(object): def __init__(self, form): self.form = form - + def __getitem__(self, key): return self.form.getFields(use_dict=True)[key] @@ -366,21 +369,21 @@ class xep_0004(base.base_plugin): self.xmpp.registerHandler( Callback('Data Form', - MatchXPath('{%s}message/{%s}x' % (self.xmpp.default_ns, + MatchXPath('{%s}message/{%s}x' % (self.xmpp.default_ns, Form.namespace)), self.handle_form)) registerStanzaPlugin(FormField, FieldOption) registerStanzaPlugin(Form, FormField) registerStanzaPlugin(Message, Form) - + def makeForm(self, ftype='form', title='', instructions=''): f = Form() f['type'] = ftype f['title'] = title f['instructions'] = instructions return f - + def post_init(self): base.base_plugin.post_init(self) self.xmpp.plugin['xep_0030'].add_feature('jabber:x:data') diff --git a/sleekxmpp/plugins/xep_0012.py b/sleekxmpp/plugins/xep_0012.py index 45ca8a00..d636d4d7 100644 --- a/sleekxmpp/plugins/xep_0012.py +++ b/sleekxmpp/plugins/xep_0012.py @@ -16,6 +16,9 @@ from .. xmlstream.matcher.xpath import MatchXPath from .. xmlstream import ElementBase, ET, JID, register_stanza_plugin +log = logging.getLogger(__name__) + + class LastActivity(ElementBase): name = 'query' namespace = 'jabber:iq:last' @@ -68,10 +71,10 @@ class xep_0012(base.base_plugin): def handle_last_activity_query(self, iq): if iq['type'] == 'get': - logging.debug("Last activity requested by %s" % iq['from']) + log.debug("Last activity requested by %s" % iq['from']) self.xmpp.event('last_activity_request', iq) elif iq['type'] == 'result': - logging.debug("Last activity result from %s" % iq['from']) + log.debug("Last activity result from %s" % iq['from']) self.xmpp.event('last_activity', iq) def handle_last_activity(self, iq): diff --git a/sleekxmpp/plugins/xep_0030.py b/sleekxmpp/plugins/xep_0030.py index 21f4538a..a3fac346 100644 --- a/sleekxmpp/plugins/xep_0030.py +++ b/sleekxmpp/plugins/xep_0030.py @@ -13,6 +13,10 @@ from .. xmlstream.matcher.xpath import MatchXPath from .. xmlstream.stanzabase import registerStanzaPlugin, ElementBase, ET, JID from .. stanza.iq import Iq + +log = logging.getLogger(__name__) + + class DiscoInfo(ElementBase): namespace = 'http://jabber.org/protocol/disco#info' name = 'query' @@ -222,18 +226,18 @@ class xep_0030(base.base_plugin): def handle_item_query(self, iq): if iq['type'] == 'get': - logging.debug("Items requested by %s" % iq['from']) + log.debug("Items requested by %s" % iq['from']) self.xmpp.event('disco_items_request', iq) elif iq['type'] == 'result': - logging.debug("Items result from %s" % iq['from']) + log.debug("Items result from %s" % iq['from']) self.xmpp.event('disco_items', iq) def handle_info_query(self, iq): if iq['type'] == 'get': - logging.debug("Info requested by %s" % iq['from']) + log.debug("Info requested by %s" % iq['from']) self.xmpp.event('disco_info_request', iq) elif iq['type'] == 'result': - logging.debug("Info result from %s" % iq['from']) + log.debug("Info result from %s" % iq['from']) self.xmpp.event('disco_info', iq) def handle_disco_info(self, iq, forwarded=False): @@ -248,13 +252,13 @@ class xep_0030(base.base_plugin): if not node_name: node_name = 'main' - logging.debug("Using default handler for disco#info on node '%s'." % node_name) + log.debug("Using default handler for disco#info on node '%s'." % node_name) if node_name in self.nodes: node = self.nodes[node_name] iq.reply().setPayload(node.info.xml).send() else: - logging.debug("Node %s requested, but does not exist." % node_name) + log.debug("Node %s requested, but does not exist." % node_name) iq.reply().error().setPayload(iq['disco_info'].xml) iq['error']['code'] = '404' iq['error']['type'] = 'cancel' @@ -276,13 +280,13 @@ class xep_0030(base.base_plugin): if not node_name: node_name = 'main' - logging.debug("Using default handler for disco#items on node '%s'." % node_name) + log.debug("Using default handler for disco#items on node '%s'." % node_name) if node_name in self.nodes: node = self.nodes[node_name] iq.reply().setPayload(node.items.xml).send() else: - logging.debug("Node %s requested, but does not exist." % node_name) + log.debug("Node %s requested, but does not exist." % node_name) iq.reply().error().setPayload(iq['disco_items'].xml) iq['error']['code'] = '404' iq['error']['type'] = 'cancel' diff --git a/sleekxmpp/plugins/xep_0045.py b/sleekxmpp/plugins/xep_0045.py index bf472a46..de982356 100644 --- a/sleekxmpp/plugins/xep_0045.py +++ b/sleekxmpp/plugins/xep_0045.py @@ -2,7 +2,7 @@ SleekXMPP: The Sleek XMPP Library Copyright (C) 2010 Nathanael C. Fritz This file is part of SleekXMPP. - + See the file LICENSE for copying permission. """ from __future__ import with_statement @@ -15,6 +15,10 @@ from .. xmlstream.handler.callback import Callback from .. xmlstream.matcher.xpath import MatchXPath from .. xmlstream.matcher.xmlmask import MatchXMLMask + +log = logging.getLogger(__name__) + + class MUCPresence(ElementBase): name = 'x' namespace = 'http://jabber.org/protocol/muc#user' @@ -34,79 +38,79 @@ class MUCPresence(ElementBase): #TODO if no affilation, set it to the default and return default item = self.getXMLItem() return item.get('affiliation', '') - + def setAffiliation(self, value): item = self.getXMLItem() #TODO check for valid affiliation item.attrib['affiliation'] = value return self - + def delAffiliation(self): item = self.getXMLItem() #TODO set default affiliation if 'affiliation' in item.attrib: del item.attrib['affiliation'] return self - + def getJid(self): item = self.getXMLItem() return JID(item.get('jid', '')) - + def setJid(self, value): item = self.getXMLItem() if not isinstance(value, str): value = str(value) item.attrib['jid'] = value return self - + def delJid(self): item = self.getXMLItem() if 'jid' in item.attrib: del item.attrib['jid'] return self - + def getRole(self): item = self.getXMLItem() #TODO get default role, set default role if none return item.get('role', '') - + def setRole(self, value): item = self.getXMLItem() #TODO check for valid role item.attrib['role'] = value return self - + def delRole(self): item = self.getXMLItem() #TODO set default role if 'role' in item.attrib: del item.attrib['role'] return self - + def getNick(self): return self.parent()['from'].resource - + def getRoom(self): return self.parent()['from'].bare - + def setNick(self, value): - logging.warning("Cannot set nick through mucpresence plugin.") + log.warning("Cannot set nick through mucpresence plugin.") return self - + def setRoom(self, value): - logging.warning("Cannot set room through mucpresence plugin.") + log.warning("Cannot set room through mucpresence plugin.") return self - + def delNick(self): - logging.warning("Cannot delete nick through mucpresence plugin.") + log.warning("Cannot delete nick through mucpresence plugin.") return self - + def delRoom(self): - logging.warning("Cannot delete room through mucpresence plugin.") + log.warning("Cannot delete room through mucpresence plugin.") return self class xep_0045(base.base_plugin): """ Impliments XEP-0045 Multi User Chat """ - + def plugin_init(self): self.rooms = {} self.ourNicks = {} @@ -116,7 +120,7 @@ class xep_0045(base.base_plugin): registerStanzaPlugin(Presence, MUCPresence) self.xmpp.registerHandler(Callback('MUCPresence', MatchXMLMask("" % self.xmpp.default_ns), self.handle_groupchat_presence)) self.xmpp.registerHandler(Callback('MUCMessage', MatchXMLMask("" % self.xmpp.default_ns), self.handle_groupchat_message)) - + def handle_groupchat_presence(self, pr): """ Handle a presence in a muc. """ @@ -135,27 +139,27 @@ class xep_0045(base.base_plugin): if entry['nick'] not in self.rooms[entry['room']]: got_online = True self.rooms[entry['room']][entry['nick']] = entry - logging.debug("MUC presence from %s/%s : %s" % (entry['room'],entry['nick'], entry)) + log.debug("MUC presence from %s/%s : %s" % (entry['room'],entry['nick'], entry)) self.xmpp.event("groupchat_presence", pr) self.xmpp.event("muc::%s::presence" % entry['room'], pr) if got_offline: self.xmpp.event("muc::%s::got_offline" % entry['room'], pr) if got_online: self.xmpp.event("muc::%s::got_online" % entry['room'], pr) - + def handle_groupchat_message(self, msg): """ Handle a message event in a muc. """ self.xmpp.event('groupchat_message', msg) self.xmpp.event("muc::%s::message" % msg['from'].bare, msg) - + def jidInRoom(self, room, jid): for nick in self.rooms[room]: entry = self.rooms[room][nick] if entry is not None and entry['jid'].full == jid: return True return False - + def getNick(self, room, jid): for nick in self.rooms[room]: entry = self.rooms[room][nick] @@ -176,12 +180,12 @@ class xep_0045(base.base_plugin): if xform is None: return False form = self.xmpp.plugin['old_0004'].buildForm(xform) return form - + def configureRoom(self, room, form=None, ifrom=None): if form is None: form = self.getRoomForm(room, ifrom=ifrom) #form = self.xmpp.plugin['old_0004'].makeForm(ftype='submit') - #form.addField('FORM_TYPE', value='http://jabber.org/protocol/muc#roomconfig') + #form.addField('FORM_TYPE', value='http://jabber.org/protocol/muc#roomconfig') iq = self.xmpp.makeIqSet() iq['to'] = room if ifrom is not None: @@ -194,7 +198,7 @@ class xep_0045(base.base_plugin): if result['type'] == 'error': return False return True - + def joinMUC(self, room, nick, maxhistory="0", password='', wait=False, pstatus=None, pshow=None): """ Join the specified room, requesting 'maxhistory' lines of history. """ @@ -220,7 +224,7 @@ class xep_0045(base.base_plugin): self.xmpp.send(stanza, expect) self.rooms[room] = {} self.ourNicks[room] = nick - + def destroy(self, room, reason='', altroom = '', ifrom=None): iq = self.xmpp.makeIqSet() if ifrom is not None: @@ -246,9 +250,9 @@ class xep_0045(base.base_plugin): raise TypeError query = ET.Element('{http://jabber.org/protocol/muc#admin}query') if nick is not None: - item = ET.Element('item', {'affiliation':affiliation, 'nick':nick}) + item = ET.Element('item', {'affiliation':affiliation, 'nick':nick}) else: - item = ET.Element('item', {'affiliation':affiliation, 'jid':jid}) + item = ET.Element('item', {'affiliation':affiliation, 'jid':jid}) query.append(item) iq = self.xmpp.makeIqSet(query) iq['to'] = room @@ -256,7 +260,7 @@ class xep_0045(base.base_plugin): if result is False or result['type'] != 'result': raise ValueError return True - + def invite(self, room, jid, reason=''): """ Invite a jid to a room.""" msg = self.xmpp.makeMessage(room) @@ -279,7 +283,7 @@ class xep_0045(base.base_plugin): else: self.xmpp.sendPresence(pshow='unavailable', pto="%s/%s" % (room, nick)) del self.rooms[room] - + def getRoomConfig(self, room): iq = self.xmpp.makeIqGet('http://jabber.org/protocol/muc#owner') iq['to'] = room @@ -291,14 +295,14 @@ class xep_0045(base.base_plugin): if form is None: raise ValueError return self.xmpp.plugin['xep_0004'].buildForm(form) - + def cancelConfig(self, room): query = ET.Element('{http://jabber.org/protocol/muc#owner}query') x = ET.Element('{jabber:x:data}x', type='cancel') query.append(x) iq = self.xmpp.makeIqSet(query) iq.send() - + def setRoomConfig(self, room, config): query = ET.Element('{http://jabber.org/protocol/muc#owner}query') x = config.getXML('submit') @@ -307,15 +311,15 @@ class xep_0045(base.base_plugin): iq['to'] = room iq['from'] = self.xmpp.jid iq.send() - + def getJoinedRooms(self): return self.rooms.keys() - + def getOurJidInRoom(self, roomJid): """ Return the jid we're using in a room. """ return "%s/%s" % (roomJid, self.ourNicks[roomJid]) - + def getJidProperty(self, room, nick, jidProperty): """ Get the property of a nick in a room, such as its 'jid' or 'affiliation' If not found, return None. @@ -324,7 +328,7 @@ class xep_0045(base.base_plugin): return self.rooms[room][nick][jidProperty] else: return None - + def getRoster(self, room): """ Get the list of nicks in a room. """ diff --git a/sleekxmpp/plugins/xep_0060.py b/sleekxmpp/plugins/xep_0060.py index 0b056f0b..a7c6d023 100644 --- a/sleekxmpp/plugins/xep_0060.py +++ b/sleekxmpp/plugins/xep_0060.py @@ -6,6 +6,10 @@ from .. xmlstream.stanzabase import registerStanzaPlugin, ElementBase, ET from . import stanza_pubsub from . xep_0004 import Form + +log = logging.getLogger(__name__) + + class xep_0060(base.base_plugin): """ XEP-0060 Publish Subscribe @@ -14,7 +18,7 @@ class xep_0060(base.base_plugin): def plugin_init(self): self.xep = '0060' self.description = 'Publish-Subscribe' - + def create_node(self, jid, node, config=None, collection=False, ntype=None): pubsub = ET.Element('{http://jabber.org/protocol/pubsub}pubsub') create = ET.Element('create') @@ -52,7 +56,7 @@ class xep_0060(base.base_plugin): result = iq.send() if result is False or result is None or result['type'] == 'error': return False return True - + def subscribe(self, jid, node, bare=True, subscribee=None): pubsub = ET.Element('{http://jabber.org/protocol/pubsub}pubsub') subscribe = ET.Element('subscribe') @@ -72,7 +76,7 @@ class xep_0060(base.base_plugin): result = iq.send() if result is False or result is None or result['type'] == 'error': return False return True - + def unsubscribe(self, jid, node, bare=True, subscribee=None): pubsub = ET.Element('{http://jabber.org/protocol/pubsub}pubsub') unsubscribe = ET.Element('unsubscribe') @@ -92,7 +96,7 @@ class xep_0060(base.base_plugin): result = iq.send() if result is False or result is None or result['type'] == 'error': return False return True - + def getNodeConfig(self, jid, node=None): # if no node, then grab default pubsub = ET.Element('{http://jabber.org/protocol/pubsub#owner}pubsub') if node is not None: @@ -110,17 +114,17 @@ class xep_0060(base.base_plugin): #self.xmpp.add_handler("" % id, self.handlerCreateNodeResponse) result = iq.send() if result is None or result == False or result['type'] == 'error': - logging.warning("got error instead of config") + log.warning("got error instead of config") return False if node is not None: form = result.find('{http://jabber.org/protocol/pubsub#owner}pubsub/{http://jabber.org/protocol/pubsub#owner}configure/{jabber:x:data}x') else: form = result.find('{http://jabber.org/protocol/pubsub#owner}pubsub/{http://jabber.org/protocol/pubsub#owner}default/{jabber:x:data}x') if not form or form is None: - logging.error("No form found.") + log.error("No form found.") return False return Form(xml=form) - + def getNodeSubscriptions(self, jid, node): pubsub = ET.Element('{http://jabber.org/protocol/pubsub#owner}pubsub') subscriptions = ET.Element('subscriptions') @@ -133,7 +137,7 @@ class xep_0060(base.base_plugin): id = iq['id'] result = iq.send() if result is None or result == False or result['type'] == 'error': - logging.warning("got error instead of config") + log.warning("got error instead of config") return False else: results = result.findall('{http://jabber.org/protocol/pubsub#owner}pubsub/{http://jabber.org/protocol/pubsub#owner}subscriptions/{http://jabber.org/protocol/pubsub#owner}subscription') @@ -156,7 +160,7 @@ class xep_0060(base.base_plugin): id = iq['id'] result = iq.send() if result is None or result == False or result['type'] == 'error': - logging.warning("got error instead of config") + log.warning("got error instead of config") return False else: results = result.findall('{http://jabber.org/protocol/pubsub#owner}pubsub/{http://jabber.org/protocol/pubsub#owner}affiliations/{http://jabber.org/protocol/pubsub#owner}affiliation') @@ -181,8 +185,8 @@ class xep_0060(base.base_plugin): return True else: return False - - + + def setNodeConfig(self, jid, node, config): pubsub = ET.Element('{http://jabber.org/protocol/pubsub#owner}pubsub') configure = ET.Element('configure') @@ -195,10 +199,10 @@ class xep_0060(base.base_plugin): iq.attrib['from'] = self.xmpp.fulljid id = iq['id'] result = iq.send() - if result is None or result['type'] == 'error': + if result is None or result['type'] == 'error': return False return True - + def setItem(self, jid, node, items=[]): pubsub = ET.Element('{http://jabber.org/protocol/pubsub}pubsub') publish = ET.Element('publish') @@ -218,7 +222,7 @@ class xep_0060(base.base_plugin): result = iq.send() if result is None or result is False or result['type'] == 'error': return False return True - + def addItem(self, jid, node, items=[]): return self.setItem(jid, node, items) @@ -237,7 +241,7 @@ class xep_0060(base.base_plugin): result = iq.send() if result is None or result is False or result['type'] == 'error': return False return True - + def getNodes(self, jid): response = self.xmpp.plugin['xep_0030'].getItems(jid) items = response.findall('{http://jabber.org/protocol/disco#items}query/{http://jabber.org/protocol/disco#items}item') @@ -246,7 +250,7 @@ class xep_0060(base.base_plugin): for item in items: nodes[item.get('node')] = item.get('name') return nodes - + def getItems(self, jid, node): response = self.xmpp.plugin['xep_0030'].getItems(jid, node) items = response.findall('{http://jabber.org/protocol/disco#items}query/{http://jabber.org/protocol/disco#items}item') @@ -264,7 +268,7 @@ class xep_0060(base.base_plugin): try: config.field['pubsub#collection'].setValue(parent) except KeyError: - logging.warning("pubsub#collection doesn't exist in config, trying to add it") + log.warning("pubsub#collection doesn't exist in config, trying to add it") config.addField('pubsub#collection', value=parent) if not self.setNodeConfig(jid, child, config): return False @@ -298,7 +302,7 @@ class xep_0060(base.base_plugin): try: config.field['pubsub#collection'].setValue(parent) except KeyError: - logging.warning("pubsub#collection doesn't exist in config, trying to add it") + log.warning("pubsub#collection doesn't exist in config, trying to add it") config.addField('pubsub#collection', value=parent) if not self.setNodeConfig(jid, child, config): return False diff --git a/sleekxmpp/plugins/xep_0078.py b/sleekxmpp/plugins/xep_0078.py index 4b3ab829..d2c81b16 100644 --- a/sleekxmpp/plugins/xep_0078.py +++ b/sleekxmpp/plugins/xep_0078.py @@ -2,7 +2,7 @@ SleekXMPP: The Sleek XMPP Library Copyright (C) 2010 Nathanael C. Fritz This file is part of SleekXMPP. - + See the file LICENSE for copying permission. """ from __future__ import with_statement @@ -12,6 +12,9 @@ import hashlib from . import base +log = logging.getLogger(__name__) + + class xep_0078(base.base_plugin): """ XEP-0078 NON-SASL Authentication @@ -23,14 +26,14 @@ class xep_0078(base.base_plugin): #disabling until I fix conflict with PLAIN #self.xmpp.registerFeature("", self.auth) self.streamid = '' - + def check_stream(self, xml): self.streamid = xml.attrib['id'] if xml.get('version', '0') != '1.0': self.auth() - + def auth(self, xml=None): - logging.debug("Starting jabber:iq:auth Authentication") + log.debug("Starting jabber:iq:auth Authentication") auth_request = self.xmpp.makeIqGet() auth_request_query = ET.Element('{jabber:iq:auth}query') auth_request.attrib['to'] = self.xmpp.server @@ -47,12 +50,12 @@ class xep_0078(base.base_plugin): query.append(username) query.append(resource) if rquery.find('{jabber:iq:auth}digest') is None: - logging.warning("Authenticating via jabber:iq:auth Plain.") + log.warning("Authenticating via jabber:iq:auth Plain.") password = ET.Element('password') password.text = self.xmpp.password query.append(password) else: - logging.debug("Authenticating via jabber:iq:auth Digest") + log.debug("Authenticating via jabber:iq:auth Digest") digest = ET.Element('digest') digest.text = hashlib.sha1(b"%s%s" % (self.streamid, self.xmpp.password)).hexdigest() query.append(digest) @@ -64,6 +67,6 @@ class xep_0078(base.base_plugin): self.xmpp.sessionstarted = True self.xmpp.event("session_start") else: - logging.info("Authentication failed") + log.info("Authentication failed") self.xmpp.disconnect() self.xmpp.event("failed_auth") diff --git a/sleekxmpp/plugins/xep_0085.py b/sleekxmpp/plugins/xep_0085.py index b7b5d6dd..3627e718 100644 --- a/sleekxmpp/plugins/xep_0085.py +++ b/sleekxmpp/plugins/xep_0085.py @@ -14,15 +14,18 @@ from .. xmlstream.stanzabase import registerStanzaPlugin, ElementBase, ET, JID from .. stanza.message import Message +log = logging.getLogger(__name__) + + class ChatState(ElementBase): namespace = 'http://jabber.org/protocol/chatstates' plugin_attrib = 'chat_state' interface = set(('state',)) states = set(('active', 'composing', 'gone', 'inactive', 'paused')) - + def active(self): self.setState('active') - + def composing(self): self.setState('composing') @@ -67,11 +70,11 @@ class xep_0085(base.base_plugin): """ XEP-0085 Chat State Notifications """ - + def plugin_init(self): self.xep = '0085' self.description = 'Chat State Notifications' - + handlers = [('Active Chat State', 'active'), ('Composing Chat State', 'composing'), ('Gone Chat State', 'gone'), @@ -79,10 +82,10 @@ class xep_0085(base.base_plugin): ('Paused Chat State', 'paused')] for handler in handlers: self.xmpp.registerHandler( - Callback(handler[0], - MatchXPath("{%s}message/{%s}%s" % (self.xmpp.default_ns, + Callback(handler[0], + MatchXPath("{%s}message/{%s}%s" % (self.xmpp.default_ns, ChatState.namespace, - handler[1])), + handler[1])), self._handleChatState)) registerStanzaPlugin(Message, Active) @@ -90,12 +93,12 @@ class xep_0085(base.base_plugin): registerStanzaPlugin(Message, Gone) registerStanzaPlugin(Message, Inactive) registerStanzaPlugin(Message, Paused) - + def post_init(self): base.base_plugin.post_init(self) self.xmpp.plugin['xep_0030'].add_feature('http://jabber.org/protocol/chatstates') - + def _handleChatState(self, msg): state = msg['chat_state'].name - logging.debug("Chat State: %s, %s" % (state, msg['from'].jid)) + log.debug("Chat State: %s, %s" % (state, msg['from'].jid)) self.xmpp.event('chatstate_%s' % state, msg) diff --git a/sleekxmpp/plugins/xep_0199.py b/sleekxmpp/plugins/xep_0199.py index 1be326cb..20055945 100644 --- a/sleekxmpp/plugins/xep_0199.py +++ b/sleekxmpp/plugins/xep_0199.py @@ -2,7 +2,7 @@ SleekXMPP: The Sleek XMPP Library Copyright (C) 2010 Nathanael C. Fritz This file is part of SleekXMPP. - + See the file LICENSE for copying permission. """ from xml.etree import cElementTree as ET @@ -10,6 +10,10 @@ from . import base import time import logging + +log = logging.getLogger(__name__) + + class xep_0199(base.base_plugin): """XEP-0199 XMPP Ping""" @@ -20,19 +24,19 @@ class xep_0199(base.base_plugin): self.running = False if self.config.get('keepalive', True): self.xmpp.add_event_handler('session_start', self.handler_pingserver, threaded=True) - + def post_init(self): base.base_plugin.post_init(self) self.xmpp.plugin['xep_0030'].add_feature('urn:xmpp:ping') - + def handler_pingserver(self, xml): if not self.running: time.sleep(self.config.get('frequency', 300)) while self.sendPing(self.xmpp.server, self.config.get('timeout', 30)) is not False: time.sleep(self.config.get('frequency', 300)) - logging.debug("Did not recieve ping back in time. Requesting Reconnect.") + log.debug("Did not recieve ping back in time. Requesting Reconnect.") self.xmpp.disconnect(reconnect=True) - + def handler_ping(self, xml): iq = self.xmpp.makeIqResult(xml.get('id', 'unknown')) iq.attrib['to'] = xml.get('from', self.xmpp.boundjid.domain) diff --git a/sleekxmpp/plugins/xep_0202.py b/sleekxmpp/plugins/xep_0202.py index c3f81b2e..fe1191ea 100644 --- a/sleekxmpp/plugins/xep_0202.py +++ b/sleekxmpp/plugins/xep_0202.py @@ -17,6 +17,9 @@ from .. xmlstream.matcher.xpath import MatchXPath from .. xmlstream import ElementBase, ET, JID, register_stanza_plugin +log = logging.getLogger(__name__) + + class EntityTime(ElementBase): name = 'time' namespace = 'urn:xmpp:time' @@ -84,10 +87,10 @@ class xep_0202(base.base_plugin): def handle_entity_time_query(self, iq): if iq['type'] == 'get': - logging.debug("Entity time requested by %s" % iq['from']) + log.debug("Entity time requested by %s" % iq['from']) self.xmpp.event('entity_time_request', iq) elif iq['type'] == 'result': - logging.debug("Entity time result from %s" % iq['from']) + log.debug("Entity time result from %s" % iq['from']) self.xmpp.event('entity_time', iq) def handle_entity_time(self, iq): diff --git a/sleekxmpp/stanza/rootstanza.py b/sleekxmpp/stanza/rootstanza.py index 2677ea91..6975c72a 100644 --- a/sleekxmpp/stanza/rootstanza.py +++ b/sleekxmpp/stanza/rootstanza.py @@ -15,6 +15,9 @@ from sleekxmpp.stanza import Error from sleekxmpp.xmlstream import ET, StanzaBase, register_stanza_plugin +log = logging.getLogger(__name__) + + class RootStanza(StanzaBase): """ @@ -58,7 +61,7 @@ class RootStanza(StanzaBase): self['error']['text'] = "SleekXMPP got into trouble." else: self['error']['text'] = traceback.format_tb(e.__traceback__) - logging.exception('Error handling {%s}%s stanza' % + log.exception('Error handling {%s}%s stanza' % (self.namespace, self.name)) self.send() diff --git a/sleekxmpp/thirdparty/statemachine.py b/sleekxmpp/thirdparty/statemachine.py index b176df02..8a7324b5 100644 --- a/sleekxmpp/thirdparty/statemachine.py +++ b/sleekxmpp/thirdparty/statemachine.py @@ -21,7 +21,7 @@ class StateMachine(object): self.addStates(states) self.__default_state = self.__states[0] self.__current_state = self.__default_state - + def addStates(self, states): self.lock.acquire() try: @@ -30,19 +30,19 @@ class StateMachine(object): raise IndexError("The state '%s' is already in the StateMachine." % state) self.__states.append(state) finally: self.lock.release() - - + + def transition(self, from_state, to_state, wait=0.0, func=None, args=[], kwargs={}): ''' - Transition from the given `from_state` to the given `to_state`. + Transition from the given `from_state` to the given `to_state`. This method will return `True` if the state machine is now in `to_state`. It - will return `False` if a timeout occurred the transition did not occur. - If `wait` is 0 (the default,) this method returns immediately if the state machine + will return `False` if a timeout occurred the transition did not occur. + If `wait` is 0 (the default,) this method returns immediately if the state machine is not in `from_state`. If you want the thread to block and transition once the state machine to enters - `from_state`, set `wait` to a non-negative value. Note there is no 'block - indefinitely' flag since this leads to deadlock. If you want to wait indefinitely, + `from_state`, set `wait` to a non-negative value. Note there is no 'block + indefinitely' flag since this leads to deadlock. If you want to wait indefinitely, choose a reasonable value for `wait` (e.g. 20 seconds) and do so in a while loop like so: :: @@ -60,42 +60,42 @@ class StateMachine(object): True value or if an exception is thrown, the transition will not occur. Any thrown exception is not caught by the state machine and is the caller's responsibility to handle. If `func` completes normally, this method will return the value returned by `func.` If - values for `args` and `kwargs` are provided, they are expanded and passed like so: + values for `args` and `kwargs` are provided, they are expanded and passed like so: `func( *args, **kwargs )`. ''' - return self.transition_any((from_state,), to_state, wait=wait, + return self.transition_any((from_state,), to_state, wait=wait, func=func, args=args, kwargs=kwargs) - - + + def transition_any(self, from_states, to_state, wait=0.0, func=None, args=[], kwargs={}): ''' Transition from any of the given `from_states` to the given `to_state`. ''' - if not (isinstance(from_states,tuple) or isinstance(from_states,list)): + if not (isinstance(from_states,tuple) or isinstance(from_states,list)): raise ValueError("from_states should be a list or tuple") for state in from_states: - if not state in self.__states: + if not state in self.__states: raise ValueError("StateMachine does not contain from_state %s." % state) - if not to_state in self.__states: + if not to_state in self.__states: raise ValueError("StateMachine does not contain to_state %s." % to_state) start = time.time() while not self.lock.acquire(False): time.sleep(.001) if (start + wait - time.time()) <= 0.0: - logging.debug("Could not acquire lock") + log.debug("Could not acquire lock") return False while not self.__current_state in from_states: # detect timeout: remainder = start + wait - time.time() - if remainder > 0: + if remainder > 0: self.notifier.wait(remainder) - else: - logging.debug("State was not ready") + else: + log.debug("State was not ready") self.lock.release() return False @@ -105,9 +105,9 @@ class StateMachine(object): # Note that func might throw an exception, but that's OK, it aborts the transition return_val = func(*args,**kwargs) if func is not None else True - # some 'false' value returned from func, + # some 'false' value returned from func, # indicating that transition should not occur: - if not return_val: return return_val + if not return_val: return return_val log.debug(' ==== TRANSITION %s -> %s', self.__current_state, to_state) self._set_state(to_state) @@ -115,7 +115,7 @@ class StateMachine(object): else: log.error("StateMachine bug!! The lock should ensure this doesn't happen!") return False - finally: + finally: self.notifier.set() # notify any waiting threads that the state has changed. self.notifier.clear() self.lock.release() @@ -125,13 +125,13 @@ class StateMachine(object): ''' Use the state machine as a context manager. The transition occurs on /exit/ from the `with` context, so long as no exception is thrown. For example: - + :: with state_machine.transition_ctx('one','two', wait=5) as locked: if locked: - # the state machine is currently locked in state 'one', and will - # transition to 'two' when the 'with' statement ends, so long as + # the state machine is currently locked in state 'one', and will + # transition to 'two' when the 'with' statement ends, so long as # no exception is thrown. print 'Currently locked in state one: %s' % state_machine['one'] @@ -142,20 +142,20 @@ class StateMachine(object): print 'Since no exception was thrown, we are now in state "two": %s' % state_machine['two'] - The other main difference between this method and `transition()` is that the - state machine is locked for the duration of the `with` statement. Normally, - after a `transition()` occurs, the state machine is immediately unlocked and + The other main difference between this method and `transition()` is that the + state machine is locked for the duration of the `with` statement. Normally, + after a `transition()` occurs, the state machine is immediately unlocked and available to another thread to call `transition()` again. ''' - if not from_state in self.__states: + if not from_state in self.__states: raise ValueError("StateMachine does not contain from_state %s." % from_state) - if not to_state in self.__states: + if not to_state in self.__states: raise ValueError("StateMachine does not contain to_state %s." % to_state) return _StateCtx(self, from_state, to_state, wait) - + def ensure(self, state, wait=0.0, block_on_transition=False): ''' Ensure the state machine is currently in `state`, or wait until it enters `state`. @@ -168,24 +168,24 @@ class StateMachine(object): Ensure we are currently in one of the given `states` or wait until we enter one of those states. - Note that due to the nature of the function, you cannot guarantee that + Note that due to the nature of the function, you cannot guarantee that the entirety of some operation completes while you remain in a given - state. That would require acquiring and holding a lock, which + state. That would require acquiring and holding a lock, which would mean no other threads could do the same. (You'd essentially be serializing all of the threads that are 'ensuring' their tasks - occurred in some state. + occurred in some state. ''' - if not (isinstance(states,tuple) or isinstance(states,list)): + if not (isinstance(states,tuple) or isinstance(states,list)): raise ValueError('states arg should be a tuple or list') for state in states: - if not state in self.__states: + if not state in self.__states: raise ValueError("StateMachine does not contain state '%s'" % state) - # if we're in the middle of a transition, determine whether we should - # 'fall back' to the 'current' state, or wait for the new state, in order to + # if we're in the middle of a transition, determine whether we should + # 'fall back' to the 'current' state, or wait for the new state, in order to # avoid an operation occurring in the wrong state. - # TODO another option would be an ensure_ctx that uses a semaphore to allow + # TODO another option would be an ensure_ctx that uses a semaphore to allow # threads to indicate they want to remain in a particular state. # will return immediately if no transition is in process. @@ -196,16 +196,16 @@ class StateMachine(object): else: self.notifier.wait() start = time.time() - while not self.__current_state in states: + while not self.__current_state in states: # detect timeout: remainder = start + wait - time.time() if remainder > 0: self.notifier.wait(remainder) else: return False return True - + def reset(self): - # TODO need to lock before calling this? + # TODO need to lock before calling this? self.transition(self.__current_state, self.__default_state) @@ -231,7 +231,7 @@ class StateMachine(object): def __str__(self): return "".join(("StateMachine(", ','.join(self.__states), "): ", self.__current_state)) - + class _StateCtx: @@ -244,28 +244,28 @@ class _StateCtx: def __enter__(self): start = time.time() - while not self.state_machine[self.from_state] or not self.state_machine.lock.acquire(False): + while not self.state_machine[self.from_state] or not self.state_machine.lock.acquire(False): # detect timeout: remainder = start + self.wait - time.time() if remainder > 0: self.state_machine.notifier.wait(remainder) - else: + else: log.debug('StateMachine timeout while waiting for state: %s', self.from_state) return False self._locked = True # lock has been acquired at this point self.state_machine.notifier.clear() - log.debug('StateMachine entered context in state: %s', + log.debug('StateMachine entered context in state: %s', self.state_machine.current_state()) return True def __exit__(self, exc_type, exc_val, exc_tb): if exc_val is not None: - log.exception("StateMachine exception in context, remaining in state: %s\n%s:%s", + log.exception("StateMachine exception in context, remaining in state: %s\n%s:%s", self.state_machine.current_state(), exc_type.__name__, exc_val) if self._locked: if exc_val is None: - log.debug(' ==== TRANSITION %s -> %s', + log.debug(' ==== TRANSITION %s -> %s', self.state_machine.current_state(), self.to_state) self.state_machine._set_state(self.to_state) diff --git a/sleekxmpp/xmlstream/handler/waiter.py b/sleekxmpp/xmlstream/handler/waiter.py index 80720226..a4bc3545 100644 --- a/sleekxmpp/xmlstream/handler/waiter.py +++ b/sleekxmpp/xmlstream/handler/waiter.py @@ -16,6 +16,9 @@ from sleekxmpp.xmlstream import StanzaBase, RESPONSE_TIMEOUT from sleekxmpp.xmlstream.handler.base import BaseHandler +log = logging.getLogger(__name__) + + class Waiter(BaseHandler): """ @@ -85,7 +88,7 @@ class Waiter(BaseHandler): stanza = self._payload.get(True, timeout) except queue.Empty: stanza = False - logging.warning("Timed out waiting for %s" % self.name) + log.warning("Timed out waiting for %s" % self.name) self.stream.removeHandler(self.name) return stanza diff --git a/sleekxmpp/xmlstream/matcher/xmlmask.py b/sleekxmpp/xmlstream/matcher/xmlmask.py index 2967a2af..6ebb437d 100644 --- a/sleekxmpp/xmlstream/matcher/xmlmask.py +++ b/sleekxmpp/xmlstream/matcher/xmlmask.py @@ -6,6 +6,8 @@ See the file LICENSE for copying permission. """ +import logging + from xml.parsers.expat import ExpatError from sleekxmpp.xmlstream.stanzabase import ET @@ -18,6 +20,9 @@ from sleekxmpp.xmlstream.matcher.base import MatcherBase IGNORE_NS = False +log = logging.getLogger(__name__) + + class MatchXMLMask(MatcherBase): """ @@ -97,8 +102,7 @@ class MatchXMLMask(MatcherBase): try: mask = ET.fromstring(mask) except ExpatError: - logging.log(logging.WARNING, - "Expat error: %s\nIn parsing: %s" % ('', mask)) + log.warning("Expat error: %s\nIn parsing: %s" % ('', mask)) if not use_ns: # Compare the element without using namespaces. diff --git a/sleekxmpp/xmlstream/scheduler.py b/sleekxmpp/xmlstream/scheduler.py index 240d4a4b..e0324cbe 100644 --- a/sleekxmpp/xmlstream/scheduler.py +++ b/sleekxmpp/xmlstream/scheduler.py @@ -15,6 +15,9 @@ except ImportError: import Queue as queue +log = logging.getLogger(__name__) + + class Task(object): """ @@ -168,13 +171,13 @@ class Scheduler(object): except KeyboardInterrupt: self.run = False if self.parentstop is not None: - logging.debug("stopping parent") + log.debug("stopping parent") self.parentstop.set() except SystemExit: self.run = False if self.parentstop is not None: self.parentstop.set() - logging.debug("Quitting Scheduler thread") + log.debug("Quitting Scheduler thread") if self.parentqueue is not None: self.parentqueue.put(('quit', None, None)) diff --git a/sleekxmpp/xmlstream/stanzabase.py b/sleekxmpp/xmlstream/stanzabase.py index f4d66aa8..aabd3864 100644 --- a/sleekxmpp/xmlstream/stanzabase.py +++ b/sleekxmpp/xmlstream/stanzabase.py @@ -16,6 +16,9 @@ from sleekxmpp.xmlstream import JID from sleekxmpp.xmlstream.tostring import tostring +log = logging.getLogger(__name__) + + # Used to check if an argument is an XML object. XML_TYPE = type(ET.Element('xml')) @@ -1140,7 +1143,7 @@ class StanzaBase(ElementBase): Meant to be overridden. """ - logging.exception('Error handling {%s}%s stanza' % (self.namespace, + log.exception('Error handling {%s}%s stanza' % (self.namespace, self.name)) def send(self): diff --git a/sleekxmpp/xmlstream/xmlstream.py b/sleekxmpp/xmlstream/xmlstream.py index 85619db4..30b76ce7 100644 --- a/sleekxmpp/xmlstream/xmlstream.py +++ b/sleekxmpp/xmlstream/xmlstream.py @@ -44,6 +44,9 @@ HANDLER_THREADS = 1 SSL_SUPPORT = True +log = logging.getLogger(__name__) + + class RestartStream(Exception): """ Exception to restart stream processing, including @@ -206,7 +209,7 @@ class XMLStream(object): # Used in Windows signal.signal(signal.SIGTERM, self._handle_kill) except: - logging.debug("Can not set interrupt signal handlers. " + \ + log.debug("Can not set interrupt signal handlers. " + \ "SleekXMPP is not running from a main thread.") def _handle_kill(self, signum, frame): @@ -275,7 +278,7 @@ class XMLStream(object): self.socket = self.socket_class(Socket.AF_INET, Socket.SOCK_STREAM) self.socket.settimeout(None) if self.use_ssl and self.ssl_support: - logging.debug("Socket Wrapped for SSL") + log.debug("Socket Wrapped for SSL") ssl_socket = ssl.wrap_socket(self.socket) if hasattr(self.socket, 'socket'): # We are using a testing socket, so preserve the top @@ -285,7 +288,7 @@ class XMLStream(object): self.socket = ssl_socket try: - logging.debug("Connecting to %s:%s" % self.address) + log.debug("Connecting to %s:%s" % self.address) self.socket.connect(self.address) self.set_socket(self.socket, ignore=True) #this event is where you should set your application state @@ -293,7 +296,7 @@ class XMLStream(object): return True except Socket.error as serr: error_msg = "Could not connect to %s:%s. Socket Error #%s: %s" - logging.error(error_msg % (self.address[0], self.address[1], + log.error(error_msg % (self.address[0], self.address[1], serr.errno, serr.strerror)) time.sleep(1) return False @@ -338,10 +341,10 @@ class XMLStream(object): """ Reset the stream's state and reconnect to the server. """ - logging.debug("reconnecting...") + log.debug("reconnecting...") self.state.transition('connected', 'disconnected', wait=2.0, func=self._disconnect, args=(True,)) - logging.debug("connecting...") + log.debug("connecting...") return self.state.transition('disconnected', 'connected', wait=2.0, func=self._connect) @@ -378,8 +381,8 @@ class XMLStream(object): to be restarted. """ if self.ssl_support: - logging.info("Negotiating TLS") - logging.info("Using SSL version: %s" % str(self.ssl_version)) + log.info("Negotiating TLS") + log.info("Using SSL version: %s" % str(self.ssl_version)) ssl_socket = ssl.wrap_socket(self.socket, ssl_version=self.ssl_version, do_handshake_on_connect=False) @@ -393,7 +396,7 @@ class XMLStream(object): self.set_socket(self.socket) return True else: - logging.warning("Tried to enable TLS, but ssl module not found.") + log.warning("Tried to enable TLS, but ssl module not found.") return False def start_stream_handler(self, xml): @@ -547,7 +550,7 @@ class XMLStream(object): name -- The name of the event to trigger. data -- Data that will be passed to each event handler. Defaults to an empty dictionary. - direct -- Runs the event directly if True, skipping the + direct -- Runs the event directly if True, skipping the event queue. All event handlers will run in the same thread. """ @@ -557,7 +560,7 @@ class XMLStream(object): handler[0](copy.copy(data)) except Exception as e: error_msg = 'Error processing event handler: %s' - logging.exception(error_msg % str(handler[0])) + log.exception(error_msg % str(handler[0])) if hasattr(data, 'exception'): data.exception(e) else: @@ -622,7 +625,7 @@ class XMLStream(object): mask = mask.xml data = str(data) if mask is not None: - logging.warning("Use of send mask waiters is deprecated.") + log.warning("Use of send mask waiters is deprecated.") wait_for = Waiter("SendWait_%s" % self.new_id(), MatchXMLMask(mask)) self.register_handler(wait_for) @@ -679,7 +682,7 @@ class XMLStream(object): self.__thread[name].start() for t in range(0, HANDLER_THREADS): - logging.debug("Starting HANDLER THREAD") + log.debug("Starting HANDLER THREAD") start_thread('stream_event_handler_%s' % t, self._event_runner) start_thread('send_thread', self._send_thread) @@ -717,16 +720,16 @@ class XMLStream(object): if self.is_client: self.send_raw(self.stream_header) except KeyboardInterrupt: - logging.debug("Keyboard Escape Detected in _process") + log.debug("Keyboard Escape Detected in _process") self.stop.set() except SystemExit: - logging.debug("SystemExit in _process") + log.debug("SystemExit in _process") self.stop.set() except Socket.error: - logging.exception('Socket Error') + log.exception('Socket Error') except: if not self.stop.isSet(): - logging.exception('Connection error.') + log.exception('Connection error.') if not self.stop.isSet() and self.auto_reconnect: self.reconnect() else: @@ -756,7 +759,7 @@ class XMLStream(object): if depth == 0: # The stream's root element has closed, # terminating the stream. - logging.debug("End of stream recieved") + log.debug("End of stream recieved") self.stream_end_event.set() return False elif depth == 1: @@ -770,7 +773,7 @@ class XMLStream(object): # Keep the root element empty of children to # save on memory use. root.clear() - logging.debug("Ending read XML loop") + log.debug("Ending read XML loop") def _build_stanza(self, xml, default_ns=None): """ @@ -781,7 +784,7 @@ class XMLStream(object): Arguments: xml -- The XML object to convert into a stanza object. - default_ns -- Optional default namespace to use instead of the + default_ns -- Optional default namespace to use instead of the stream's current default namespace. """ if default_ns is None: @@ -803,7 +806,7 @@ class XMLStream(object): Arguments: xml -- The XML stanza to analyze. """ - logging.debug("RECV: %s" % tostring(xml, + log.debug("RECV: %s" % tostring(xml, xmlns=self.default_ns, stream=self)) # Apply any preprocessing filters. @@ -852,7 +855,7 @@ class XMLStream(object): func(*args) except Exception as e: error_msg = 'Error processing event handler: %s' - logging.exception(error_msg % str(func)) + log.exception(error_msg % str(func)) if hasattr(args[0], 'exception'): args[0].exception(e) @@ -865,7 +868,7 @@ class XMLStream(object): Stream event handlers will all execute in this thread. Custom event handlers may be spawned in individual threads. """ - logging.debug("Loading event runner") + log.debug("Loading event runner") try: while not self.stop.isSet(): try: @@ -883,14 +886,14 @@ class XMLStream(object): handler.run(args[0]) except Exception as e: error_msg = 'Error processing stream handler: %s' - logging.exception(error_msg % handler.name) + log.exception(error_msg % handler.name) args[0].exception(e) elif etype == 'schedule': try: - logging.debug(args) + log.debug(args) handler(*args[0]) except: - logging.exception('Error processing scheduled task') + log.exception('Error processing scheduled task') elif etype == 'event': func, threaded, disposable = handler try: @@ -904,14 +907,14 @@ class XMLStream(object): func(*args) except Exception as e: error_msg = 'Error processing event handler: %s' - logging.exception(error_msg % str(func)) + log.exception(error_msg % str(func)) if hasattr(args[0], 'exception'): args[0].exception(e) elif etype == 'quit': - logging.debug("Quitting event runner thread") + log.debug("Quitting event runner thread") return False except KeyboardInterrupt: - logging.debug("Keyboard Escape Detected in _event_runner") + log.debug("Keyboard Escape Detected in _event_runner") self.disconnect() return except SystemExit: @@ -929,14 +932,14 @@ class XMLStream(object): data = self.send_queue.get(True, 1) except queue.Empty: continue - logging.debug("SEND: %s" % data) + log.debug("SEND: %s" % data) try: self.socket.send(data.encode('utf-8')) except: - logging.warning("Failed to send %s" % data) + log.warning("Failed to send %s" % data) self.disconnect(self.auto_reconnect) except KeyboardInterrupt: - logging.debug("Keyboard Escape Detected in _send_thread") + log.debug("Keyboard Escape Detected in _send_thread") self.disconnect() return except SystemExit: -- cgit v1.2.3