Back to index

moin  1.9.0~rc2
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes
jabberbot.xmppbot.XMPPBot Class Reference
Inheritance diagram for jabberbot.xmppbot.XMPPBot:
Inheritance graph
[legend]
Collaboration diagram for jabberbot.xmppbot.XMPPBot:
Collaboration graph
[legend]

List of all members.

Public Member Functions

def __init__
def run
def stop
def loop
def idle
def session_started
def expire_contacts
def get_text
def poll_commands
def handle_command
def handle_changed_action
def handle_deleted_action
def handle_attached_action
def handle_renamed_action
def handle_user_created_action
def ask_for_subscription
def remove_subscription
def send_message
def send_form
def send_search_form
def send_change_form
def send_change_text
def send_deleted_form
def send_deleted_text
def send_attached_form
def send_attached_text
def send_renamed_form
def send_renamed_text
def send_user_created_text
def handle_page_info
def send_pageinfo_text
def send_pageinfo_form
def is_internal
def is_xmlrpc
def contains_form
def handle_form
def handle_search_form
def handle_message
def handle_internal_command
def do_search
def help_on
def handle_xmlrpc_command
def handle_unsubscribed_presence
def handle_subscribe_presence
def handle_unavailable_presence
def handle_available_presence
def get_user_language
def handle_disco_query
def service_discovery
def check_presence
def send_disco_query
def add_to_disco_wait
def handle_disco_result
def disco_result_right
def disco_result_wrong
def check_disco_delays
def check_if_waiting
def set_support
def send_queued_messages
def reply_help
def authenticated
def authorized
def connected
def disconnected
def roster_updated
def stream_closed
def stream_created
def stream_error

Public Attributes

 from_commands
 to_commands
 config
 log
 jid
 tlsconfig
 contacts
 last_expiration
 contact_check
 stopping
 known_xmlrpc_cmds
 internal_commands
 xmlrpc_commands
 disco_cache
 disco_wait
 disco_temp

Private Member Functions

def _handle_notification
def _handle_search
def _handle_add_contact
def _handle_remove_contact
def _handle_get_page
def _handle_get_page_list
def _handle_get_page_info
def _handle_get_language

Private Attributes

 _msg_handlers

Detailed Description

A simple XMPP bot

Definition at line 166 of file xmppbot.py.


Constructor & Destructor Documentation

def jabberbot.xmppbot.XMPPBot.__init__ (   self,
  config,
  from_commands,
  to_commands 
)
A constructor

@param from_commands: a Queue object used to send commands to other (xmlrpc) threads
@param to_commands: a Queue object used to receive commands from other threads

Definition at line 169 of file xmppbot.py.

00169 
00170     def __init__(self, config, from_commands, to_commands):
00171         """A constructor
00172 
00173         @param from_commands: a Queue object used to send commands to other (xmlrpc) threads
00174         @param to_commands: a Queue object used to receive commands from other threads
00175 
00176         """
00177         Thread.__init__(self)
00178 
00179         self.from_commands = from_commands
00180         self.to_commands = to_commands
00181 
00182         self.config = config
00183         self.log = logging.getLogger(__name__)
00184         self.jid = JID(node_or_jid=config.xmpp_node, domain=config.xmpp_server)
00185         self.tlsconfig = TLSSettings(require = True, verify_peer=False)
00186 
00187         # A dictionary of contact objects, ordered by bare JID
00188         self.contacts = {}
00189 
00190         # The last time when contacts were checked for expiration, in seconds
00191         self.last_expiration = time.time()
00192 
00193         # How often should the contacts be checked for expiration, in seconds
00194         self.contact_check = 600
00195         self.stopping = False
00196 
00197         self.known_xmlrpc_cmds = [cmd.GetPage, cmd.GetPageHTML, cmd.GetPageList, cmd.GetPageInfo, cmd.Search, cmd.RevertPage]
00198         self.internal_commands = ["ping", "help", "searchform"]
00199 
00200         self.xmlrpc_commands = {}
00201         for command, name in [(command, command.__name__) for command in self.known_xmlrpc_cmds]:
00202             self.xmlrpc_commands[name.lower()] = command
00203 
00204         Client.__init__(self, self.jid, config.xmpp_password, config.xmpp_server, tls_settings=self.tlsconfig)
00205 
00206         # Setup message handlers
00207 
00208         self._msg_handlers = {cmd.NotificationCommand: self._handle_notification,
00209                               cmd.NotificationCommandI18n: self._handle_notification,
00210                               cmd.AddJIDToRosterCommand: self._handle_add_contact,
00211                               cmd.RemoveJIDFromRosterCommand: self._handle_remove_contact,
00212                               cmd.GetPage: self._handle_get_page,
00213                               cmd.GetPageHTML: self._handle_get_page,
00214                               cmd.GetPageList: self._handle_get_page_list,
00215                               cmd.GetPageInfo: self._handle_get_page_info,
00216                               cmd.GetUserLanguage: self._handle_get_language,
00217                               cmd.Search: self._handle_search}
00218 
00219         # cache for service discovery results ( (ver, algo) : Capabilities = libxml2.xmlNode)
00220         self.disco_cache = Cache(max_items=config.disco_cache_size, default_purge_period=0)
00221 
00222         # dictionary of jids waiting for service discovery results
00223         # ( (ver, algo) : (timeout=datetime.timedelta, [list_of_jids=pyxmpp.jid]) )
00224         self.disco_wait = {}
00225 
00226         # temporary dictionary ( pyxmpp.jid:  (ver, algo) )
00227         self.disco_temp = {}


Member Function Documentation

def jabberbot.xmppbot.XMPPBot._handle_add_contact (   self,
  command,
  ignore_dnd 
) [private]

Definition at line 1659 of file xmppbot.py.

01659 
01660     def _handle_add_contact(self, command, ignore_dnd):
01661         jid = JID(node_or_jid = command.jid)
01662         self.ask_for_subscription(jid)

Here is the call graph for this function:

def jabberbot.xmppbot.XMPPBot._handle_get_language (   self,
  command,
  ignore_dnd 
) [private]

Definition at line 1684 of file xmppbot.py.

01684 
01685     def _handle_get_language(self, command, ignore_dnd):
01686         if command.jid in self.contacts:
01687             self.contacts[command.jid].language = command.language
def jabberbot.xmppbot.XMPPBot._handle_get_page (   self,
  command,
  ignore_dnd 
) [private]

Definition at line 1667 of file xmppbot.py.

01667 
01668     def _handle_get_page(self, command, ignore_dnd):
01669         _ = self.get_text(command.jid)
01670         msg = _(u"""Here's the page "%(pagename)s" that you've requested:\n\n%(data)s""")
01671 
01672         cmd_data = {'text': msg % {'pagename': command.pagename, 'data': command.data}}
01673         self.send_message(command.jid, cmd_data)

Here is the call graph for this function:

def jabberbot.xmppbot.XMPPBot._handle_get_page_info (   self,
  command,
  ignore_dnd 
) [private]

Definition at line 1681 of file xmppbot.py.

01681 
01682     def _handle_get_page_info(self, command, ignore_dnd):
01683         self.handle_page_info(command)

Here is the call graph for this function:

def jabberbot.xmppbot.XMPPBot._handle_get_page_list (   self,
  command,
  ignore_dnd 
) [private]

Definition at line 1674 of file xmppbot.py.

01674 
01675     def _handle_get_page_list(self, command, ignore_dnd):
01676         _ = self.get_text(command.jid)
01677         msg = _("That's the list of pages accesible to you:\n\n%s")
01678         pagelist = u"\n".join(command.data)
01679 
01680         self.send_message(command.jid, {'text': msg % (pagelist, )})

Here is the call graph for this function:

def jabberbot.xmppbot.XMPPBot._handle_notification (   self,
  command,
  ignore_dnd 
) [private]

Definition at line 1572 of file xmppbot.py.

01572 
01573     def _handle_notification(self, command, ignore_dnd):
01574         cmd_data = command.notification
01575         original_text = cmd_data.get('text', '')
01576         original_subject = cmd_data.get('subject', '')
01577 
01578         for recipient in command.jids:
01579             jid = JID(recipient)
01580             jid_text = jid.bare().as_unicode()
01581 
01582             if isinstance(command, cmd.NotificationCommandI18n):
01583                 # Translate&interpolate the message with data
01584                 gettext_func = self.get_text(jid_text)
01585                 text, subject = command.translate(gettext_func)
01586                 cmd_data['text'] = text
01587                 cmd_data['subject'] = subject
01588             else:
01589                 cmd_data['text'] = original_text
01590                 cmd_data['subject'] = original_subject
01591 
01592             # Check if contact is DoNotDisturb.
01593             # If so, queue the message for delayed delivery.
01594             contact = self.contacts.get(jid_text, '')
01595             if contact:
01596                 if command.async and contact.is_dnd() and not ignore_dnd:
01597                     contact.messages.append(command)
01598                     return
01599 
01600             action = cmd_data.get('action', '')
01601             if action == u'page_changed':
01602                 self.handle_changed_action(cmd_data, jid, contact)
01603             elif action == u'page_deleted':
01604                 self.handle_deleted_action(cmd_data, jid, contact)
01605             elif action == u'file_attached':
01606                 self.handle_attached_action(cmd_data, jid, contact)
01607             elif action == u'page_renamed':
01608                 self.handle_renamed_action(cmd_data, jid, contact)
01609             elif action == u'user_created':
01610                 self.handle_user_created_action(cmd_data, jid, contact)
01611             else:
01612                 self.send_message(jid, cmd_data, command.msg_type)

Here is the call graph for this function:

def jabberbot.xmppbot.XMPPBot._handle_remove_contact (   self,
  command,
  ignore_dnd 
) [private]

Definition at line 1663 of file xmppbot.py.

01663 
01664     def _handle_remove_contact(self, command, ignore_dnd):
01665         jid = JID(node_or_jid = command.jid)
01666         self.remove_subscription(jid)

Here is the call graph for this function:

def jabberbot.xmppbot.XMPPBot._handle_search (   self,
  command,
  ignore_dnd 
) [private]

Definition at line 1613 of file xmppbot.py.

01613 
01614     def _handle_search(self, command, ignore_dnd):
01615         warnings = []
01616         _ = self.get_text(command.jid)
01617 
01618         if not command.data:
01619             warnings.append(_("There are no pages matching your search criteria!"))
01620 
01621         # This hardcoded limitation relies on (mostly correct) assumption that Jabber
01622         # servers have rather tight traffic limits. Sending more than 25 results is likely
01623         # to take a second or two - users should not have to wait longer (+search time!).
01624         elif len(command.data) > 25:
01625             warnings.append(_("There are too many results (%(number)s). Limiting to first 25 entries.") % {'number': str(len(command.data))})
01626             command.data = command.data[:25]
01627 
01628         results = [{'description': result[0], 'url': result[2]} for result in command.data]
01629 
01630         if command.presentation == u"text":
01631             for warning in warnings:
01632                 self.send_message(command.jid, {'text': warning})
01633 
01634             if not results:
01635                 return
01636 
01637             data = {'text': _('Following pages match your search criteria:'), 'url_list': results}
01638             self.send_message(command.jid, data, u"chat")
01639         else:
01640             form_title = _("Search results").encode("utf-8")
01641             help_form = _("Submit this form to perform a wiki search").encode("utf-8")
01642             form = forms.Form(xmlnode_or_type="result", title=form_title, instructions=help_form)
01643 
01644             action_label = _("What to do next")
01645             do_nothing = forms.Option("n", _("Do nothing"))
01646             search_again = forms.Option("s", _("Search again"))
01647 
01648             for no, warning in enumerate(warnings):
01649                 form.add_field(name="warning", field_type="fixed", value=warning)
01650 
01651             for no, result in enumerate(results):
01652                 field_name = "url%d" % (no, )
01653                 form.add_field(name=field_name, value=unicode(result["url"]), label=result["description"].encode("utf-8"), field_type="text-single")
01654 
01655             # Selection of a following action
01656             form.add_field(name="options", field_type="list-single", options=[do_nothing, search_again], label=action_label)
01657 
01658             self.send_form(command.jid, form, _("Search results"))

Here is the call graph for this function:

def jabberbot.xmppbot.XMPPBot.add_to_disco_wait (   self,
  ver_algo,
  jid 
)
Adds given jid to the list of contacts waiting for service
discovery results.

@param ver_algo: 'ver' and 'algo' attributes of the given jid
@type ver_algo: tuple of (str, str)
@type jid: pyxmpp.jid.JID

Definition at line 1380 of file xmppbot.py.

01380 
01381     def add_to_disco_wait(self, ver_algo, jid):
01382         """Adds given jid to the list of contacts waiting for service
01383         discovery results.
01384 
01385         @param ver_algo: 'ver' and 'algo' attributes of the given jid
01386         @type ver_algo: tuple of (str, str)
01387         @type jid: pyxmpp.jid.JID
01388         """
01389         if ver_algo in self.disco_wait:
01390             # query already sent, add to the end of waiting list
01391             self.disco_wait[ver_algo][1].append(jid)
01392         else:
01393             # send a query and create a new entry
01394             self.send_disco_query(jid)
01395             timeout = time.time() + self.config.disco_answering_timeout
01396             self.disco_wait[ver_algo] = (timeout, [jid])

Here is the call graph for this function:

Here is the caller graph for this function:

Sends a <presence/> stanza with type="subscribe"

Bot tries to subscribe to every contact's presence, so that
it can honor special cases, like DoNotDisturb setting.

@param jid: Jabber ID of entity we're subscribing to
@type jid: pyxmpp.jid.JID

Definition at line 423 of file xmppbot.py.

00423 
00424     def ask_for_subscription(self, jid):
00425         """Sends a <presence/> stanza with type="subscribe"
00426 
00427         Bot tries to subscribe to every contact's presence, so that
00428         it can honor special cases, like DoNotDisturb setting.
00429 
00430         @param jid: Jabber ID of entity we're subscribing to
00431         @type jid: pyxmpp.jid.JID
00432 
00433         """
00434         stanza = Presence(to_jid=jid, stanza_type="subscribe")
00435         self.get_stream().send(stanza)

Here is the caller graph for this function:

Called when authentication succeedes

Definition at line 1528 of file xmppbot.py.

01528 
01529     def authenticated(self):
01530         """Called when authentication succeedes"""
01531         self.log.info("Authenticated.")

Called when authorization succeedes

Definition at line 1532 of file xmppbot.py.

01532 
01533     def authorized(self):
01534         """Called when authorization succeedes"""
01535 
01536         self.log.info("Authorized.")
01537 
01538         stream = self.get_stream()
01539         stream.set_message_handler("normal", self.handle_message)
01540         stream.set_presence_handler("available", self.handle_available_presence)
01541         stream.set_presence_handler("unavailable", self.handle_unavailable_presence)
01542         stream.set_presence_handler("unsubscribed", self.handle_unsubscribed_presence)
01543         stream.set_presence_handler("subscribe", self.handle_subscribe_presence)
01544 
01545         self.request_session()

Here is the call graph for this function:

Called when idle to check if some contacts haven't answered in allowed time

Definition at line 1462 of file xmppbot.py.

01462 
01463     def check_disco_delays(self):
01464         """Called when idle to check if some contacts haven't answered in allowed time"""
01465         for item in self.disco_wait:
01466             timeout, jid_list = self.disco_wait[item]
01467             if timeout < time.time():
01468                 self.disco_result_wrong(item)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.check_if_waiting (   self,
  jid 
)
Check if we were waiting for disco#info reply from client that
has just become unavailable. If so, ask next candidate.

@param jid: jid that has just gone unavailable
@type jid: pyxmpp.jid.JID

Definition at line 1469 of file xmppbot.py.

01469 
01470     def check_if_waiting(self, jid):
01471         """Check if we were waiting for disco#info reply from client that
01472         has just become unavailable. If so, ask next candidate.
01473 
01474         @param jid: jid that has just gone unavailable
01475         @type jid: pyxmpp.jid.JID
01476         """
01477         ver_algo = self.disco_temp[jid]
01478         if ver_algo in self.disco_wait:
01479             timeout, jid_list = self.disco_wait[ver_algo]
01480             if jid_list:
01481                 if jid == jid_list[0]:
01482                     self.disco_result_wrong(ver_algo)
01483             else:
01484                 # this should never happen
01485                 self.log.debug(u"disco_wait: keeping empty entry at (%s, %s) !" % ver_algo)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.check_presence (   self,
  presence 
)
Search received presence for a <c> child with 'ver' and 'algo' attributes
return (ver, algo) or None if no 'ver' found.
(no 'algo' attribute defaults to 'sha-1', as described in XEP-0115)

@param presence: received presence stanza (pyxmpp.presence.Presence)
@return type: tuple of (str, str) or None

Definition at line 1340 of file xmppbot.py.

01340 
01341     def check_presence(self, presence):
01342         """Search received presence for a <c> child with 'ver' and 'algo' attributes
01343         return (ver, algo) or None if no 'ver' found.
01344         (no 'algo' attribute defaults to 'sha-1', as described in XEP-0115)
01345 
01346         @param presence: received presence stanza (pyxmpp.presence.Presence)
01347         @return type: tuple of (str, str) or None
01348         """
01349         # TODO: <c> could be found directly using more appropriate xpath
01350         tags = presence.xpath_eval('child::*')
01351         for tag in tags:
01352             if tag.name == 'c':
01353                 ver = tag.xpathEval('@ver')
01354                 algo = tag.xpathEval('@algo')
01355                 if ver:
01356                     if algo:
01357                         ver_algo = (ver[0].children.content, algo[0].children.content)
01358                     else:
01359                         # no algo attribute defaults to 'sha-1'
01360                         ver_algo = (ver[0].children.content, 'sha-1')
01361 
01362                     return ver_algo
01363                 else:
01364                     #self.log.debug(u"%s: presence with <c> but without 'ver' attribute." % jid.as_unicode())
01365                     return None
01366                 break
01367         else:
01368             #self.log.debug(u"%s: presence without a <c> tag." % jid.as_unicode())
01369             return None

Here is the caller graph for this function:

Called when connections has been established

Definition at line 1546 of file xmppbot.py.

01546 
01547     def connected(self):
01548         """Called when connections has been established"""
01549         self.log.info("Connected.")

def jabberbot.xmppbot.XMPPBot.contains_form (   self,
  message 
)
Checks if passed message stanza contains a submitted form and parses it

@param message: message stanza
@type message: pyxmpp.message.Message
@return: xml node with form data if found, or None

Definition at line 955 of file xmppbot.py.

00955 
00956     def contains_form(self, message):
00957         """Checks if passed message stanza contains a submitted form and parses it
00958 
00959         @param message: message stanza
00960         @type message: pyxmpp.message.Message
00961         @return: xml node with form data if found, or None
00962 
00963         """
00964         if not isinstance(message, Message):
00965             raise ValueError("The 'message' parameter must be of type pyxmpp.message.Message!")
00966 
00967         payload = message.get_node()
00968         form = message.xpath_eval('/ns:message/data:x', {'data': 'jabber:x:data'})
00969 
00970         if form:
00971             return form[0]
00972         else:
00973             return None

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.disco_result_right (   self,
  ver_algo,
  payload 
)
We received a correct service discovery response so we can safely cache it
for future use and apply to every waiting contact from the list (first one is already done)

@param ver_algo: 'ver' and 'algo' attributes matching received capabilities
@param payload: received capabilities
@type ver_algo: tuple of (str, str)
@type payload: libxml2.xmlNode

Definition at line 1427 of file xmppbot.py.

01427 
01428     def disco_result_right(self, ver_algo, payload):
01429         """We received a correct service discovery response so we can safely cache it
01430         for future use and apply to every waiting contact from the list (first one is already done)
01431 
01432         @param ver_algo: 'ver' and 'algo' attributes matching received capabilities
01433         @param payload: received capabilities
01434         @type ver_algo: tuple of (str, str)
01435         @type payload: libxml2.xmlNode
01436         """
01437         delta = timedelta(0)
01438         cache_item = CacheItem(ver_algo, payload, delta, delta, delta)
01439         self.disco_cache.add_item(cache_item)
01440 
01441         timeout, jid_list = self.disco_wait[ver_algo]
01442         for jid in jid_list[1:]:
01443             if jid.bare().as_unicode() in self.contacts:
01444                 self.set_support(jid, payload)
01445         del self.disco_wait[ver_algo]

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.disco_result_wrong (   self,
  ver_algo 
)
First jid from the list returned wrong response
if it is possible try to ask the second one

@param ver_algo: 'ver' and 'algo' attributes for which we received an inappropriate response
@type ver_algo: tuple of (str, str)

Definition at line 1446 of file xmppbot.py.

01446 
01447     def disco_result_wrong(self, ver_algo):
01448         """First jid from the list returned wrong response
01449         if it is possible try to ask the second one
01450 
01451         @param ver_algo: 'ver' and 'algo' attributes for which we received an inappropriate response
01452         @type ver_algo: tuple of (str, str)
01453         """
01454         timeout, jid_list = self.disco_wait[ver_algo]
01455         jid_list = jid_list[1:]
01456         if jid_list:
01457             self.send_disco_query(jid_list[0])
01458             timeout = time.time() + self.config.disco_answering_timeout
01459             self.disco_wait[ver_algo] = (timeout, jid_list)
01460         else:
01461             del self.disco_wait[ver_algo]

Here is the call graph for this function:

Here is the caller graph for this function:

Called when disconnection occurs

Definition at line 1550 of file xmppbot.py.

01550 
01551     def disconnected(self):
01552         """Called when disconnection occurs"""
01553         self.log.info("Disconnected.")

def jabberbot.xmppbot.XMPPBot.do_search (   self,
  jid,
  search_type,
  presentation,
  args 
)
Performs a Wiki search of term

@param jid: Jabber ID of user performing a search
@type jid: pyxmpp.jid.JID
@param term: term to search for
@type term: unicode
@param search_type: type of search; either "text" or "title"
@type search_type: unicode
@param presentation: how to present the results; "text" or "dataforms"
@type presentation: unicode

Definition at line 1120 of file xmppbot.py.

01120 
01121     def do_search(self, jid, search_type, presentation, *args):
01122         """Performs a Wiki search of term
01123 
01124         @param jid: Jabber ID of user performing a search
01125         @type jid: pyxmpp.jid.JID
01126         @param term: term to search for
01127         @type term: unicode
01128         @param search_type: type of search; either "text" or "title"
01129         @type search_type: unicode
01130         @param presentation: how to present the results; "text" or "dataforms"
01131         @type presentation: unicode
01132 
01133         """
01134         search = cmd.Search(jid, search_type, presentation=presentation, *args)
01135         self.from_commands.put_nowait(search)

def jabberbot.xmppbot.XMPPBot.expire_contacts (   self,
  current_time 
)
Check which contats have been offline for too long and should be removed

@param current_time: current time in seconds

Definition at line 280 of file xmppbot.py.

00280 
00281     def expire_contacts(self, current_time):
00282         """Check which contats have been offline for too long and should be removed
00283 
00284         @param current_time: current time in seconds
00285 
00286         """
00287         for jid, contact in self.contacts.items():
00288             if not contact.is_valid(current_time):
00289                 del self.contacts[jid]

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.get_text (   self,
  jid 
)
Returns a gettext function (_) for the given JID

@param jid: bare Jabber ID of the user we're going to communicate with
@type jid: str or pyxmpp.jid.JID

Definition at line 290 of file xmppbot.py.

00290 
00291     def get_text(self, jid):
00292         """Returns a gettext function (_) for the given JID
00293 
00294         @param jid: bare Jabber ID of the user we're going to communicate with
00295         @type jid: str or pyxmpp.jid.JID
00296 
00297         """
00298         language = "en"
00299         if isinstance(jid, str) or isinstance(jid, unicode):
00300             jid = JID(jid).bare().as_unicode()
00301         else:
00302             jid = jid.bare().as_unicode()
00303 
00304         if jid in self.contacts:
00305             language = self.contacts[jid].language
00306 
00307         return lambda text: i18n.get_text(text, lang=language)

Here is the caller graph for this function:

Request user's language setting from the wiki

@param jid: bare Jabber ID of the user to query for
@type jid: unicode

Definition at line 1298 of file xmppbot.py.

01298 
01299     def get_user_language(self, jid):
01300         """Request user's language setting from the wiki
01301 
01302         @param jid: bare Jabber ID of the user to query for
01303         @type jid: unicode
01304         """
01305         request = cmd.GetUserLanguage(jid)
01306         self.from_commands.put_nowait(request)

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_attached_action (   self,
  cmd_data,
  jid,
  contact 
)
Handles a notification cmd_data with 'file_attached' action

@param cmd_data: notification cmd_data
@param jid: jid to send the notification to
@param contact: a roster contact
@type cmd_data: dict
@type jid: pyxmpp.jid.JID
@type contact: Contact

Definition at line 375 of file xmppbot.py.

00375 
00376     def handle_attached_action(self, cmd_data, jid, contact):
00377         """Handles a notification cmd_data with 'file_attached' action
00378 
00379         @param cmd_data: notification cmd_data
00380         @param jid: jid to send the notification to
00381         @param contact: a roster contact
00382         @type cmd_data: dict
00383         @type jid: pyxmpp.jid.JID
00384         @type contact: Contact
00385 
00386         """
00387         if contact and contact.supports(jid.resource, u"jabber:x:data"):
00388             self.send_attached_form(jid.as_unicode(), cmd_data)
00389             return
00390         else:
00391             self.send_attached_text(jid.as_unicode(), cmd_data)

Here is the call graph for this function:

Here is the caller graph for this function:

Handles available presence stanzas

@type presence: pyxmpp.presence.Presence

Definition at line 1252 of file xmppbot.py.

01252 
01253     def handle_available_presence(self, presence):
01254         """Handles available presence stanzas
01255 
01256         @type presence: pyxmpp.presence.Presence
01257 
01258         """
01259         self.log.debug("Handling available presence.")
01260 
01261         show = presence.get_show()
01262         if show is None:
01263             show = u'available'
01264 
01265         priority = presence.get_priority()
01266         jid = presence.get_from_jid()
01267         bare_jid = jid.bare().as_unicode()
01268 
01269         if bare_jid in self.contacts:
01270             contact = self.contacts[bare_jid]
01271 
01272             # The resource is already known, so update it
01273             if contact.uses_resource(jid.resource):
01274                 contact.set_show(jid.resource, show)
01275 
01276             # Unknown resource, add it to the list
01277             else:
01278                 contact.add_resource(jid.resource, show, priority)
01279 
01280                 # Discover capabilities of the newly connected client
01281                 self.service_discovery(jid, presence)
01282 
01283             if self.config.verbose:
01284                 self.log.debug(contact)
01285 
01286             # Either way check, if we can deliver queued messages now
01287             if not contact.is_dnd():
01288                 self.send_queued_messages(contact)
01289 
01290         else:
01291             self.contacts[bare_jid] = Contact(jid, jid.resource, priority, show)
01292             self.service_discovery(jid, presence)
01293             self.get_user_language(bare_jid)
01294             self.log.debug(self.contacts[bare_jid])
01295 
01296         # Confirm that we've handled this stanza
01297         return True

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_changed_action (   self,
  cmd_data,
  jid,
  contact 
)
Handles a notification command with 'page_changed' action

@param cmd_data: notification command data
@param jid: jid to send the notification to
@param contact: a roster contact
@type cmd_data: dict
@type jid: pyxmpp.jid.JID
@type contact: Contact

Definition at line 341 of file xmppbot.py.

00341 
00342     def handle_changed_action(self, cmd_data, jid, contact):
00343         """Handles a notification command with 'page_changed' action
00344 
00345         @param cmd_data: notification command data
00346         @param jid: jid to send the notification to
00347         @param contact: a roster contact
00348         @type cmd_data: dict
00349         @type jid: pyxmpp.jid.JID
00350         @type contact: Contact
00351 
00352         """
00353         if contact and contact.supports(jid.resource, u"jabber:x:data"):
00354             self.send_change_form(jid.as_unicode(), cmd_data)
00355             return
00356         else:
00357             self.send_change_text(jid.as_unicode(), cmd_data)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_command (   self,
  command,
  ignore_dnd = False 
)
Excecutes commands from other components

@param command: a command to execute
@type command: any class defined in commands.py (FIXME?)
@param ignore_dnd: if command results in user interaction, should DnD be ignored?

Definition at line 321 of file xmppbot.py.

00321 
00322     def handle_command(self, command, ignore_dnd=False):
00323         """Excecutes commands from other components
00324 
00325         @param command: a command to execute
00326         @type command: any class defined in commands.py (FIXME?)
00327         @param ignore_dnd: if command results in user interaction, should DnD be ignored?
00328 
00329         """
00330 
00331         cmd_cls = command.__class__
00332 
00333         try:
00334             handler = self._msg_handlers[cmd_cls]
00335         except KeyError:
00336             self.log.debug("No such command: " + cmd_cls.__name__)
00337             return
00338 
00339         # NOTE: handler is a method, so it takes self as a hidden arg
00340         handler(command, ignore_dnd)

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_deleted_action (   self,
  cmd_data,
  jid,
  contact 
)
Handles a notification cmd_data with 'page_deleted' action

@param cmd_data: notification cmd_data
@param jid: jid to send the notification to
@param contact: a roster contact
@type cmd_data: dict
@type jid: pyxmpp.jid.JID
@type contact: Contact

Definition at line 358 of file xmppbot.py.

00358 
00359     def handle_deleted_action(self, cmd_data, jid, contact):
00360         """Handles a notification cmd_data with 'page_deleted' action
00361 
00362         @param cmd_data: notification cmd_data
00363         @param jid: jid to send the notification to
00364         @param contact: a roster contact
00365         @type cmd_data: dict
00366         @type jid: pyxmpp.jid.JID
00367         @type contact: Contact
00368 
00369         """
00370         if contact and contact.supports(jid.resource, u"jabber:x:data"):
00371             self.send_deleted_form(jid.as_unicode(), cmd_data)
00372             return
00373         else:
00374             self.send_deleted_text(jid.as_unicode(), cmd_data)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_disco_query (   self,
  stanza 
)
Handler for <Iq /> service discovery query

@param stanza: received query stanza (pyxmpp.iq.Iq)

Definition at line 1307 of file xmppbot.py.

01307 
01308     def handle_disco_query(self, stanza):
01309         """Handler for <Iq /> service discovery query
01310 
01311         @param stanza: received query stanza (pyxmpp.iq.Iq)
01312         """
01313         response = capat.create_response(stanza)
01314         self.get_stream().send(response)

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_disco_result (   self,
  stanza 
)
Handler for <iq> service discovery results
check if contact is still available and if 'ver' matches the capabilities' hash

@param stanza: a received result stanza (pyxmpp.iq.Iq)

Definition at line 1397 of file xmppbot.py.

01397 
01398     def handle_disco_result(self, stanza):
01399         """Handler for <iq> service discovery results
01400         check if contact is still available and if 'ver' matches the capabilities' hash
01401 
01402         @param stanza: a received result stanza (pyxmpp.iq.Iq)
01403         """
01404         jid = stanza.get_from_jid()
01405         bare_jid = jid.bare().as_unicode()
01406         payload = stanza.get_query()
01407 
01408         if bare_jid in self.contacts:
01409             ver_algo = self.disco_temp[jid]
01410 
01411             if ver_algo is not None:
01412                 ver, algo = ver_algo
01413                 payload_hash = capat.hash_iq(stanza, algo)
01414 
01415                 if payload_hash == ver:
01416                     # we can trust this 'ver' string
01417                     self.disco_result_right(ver_algo, payload)
01418                 else:
01419                     self.log.debug(u"%s: 'ver' and hash do not match! (legacy client?)" % jid.as_unicode())
01420                     self.disco_result_wrong(ver_algo)
01421 
01422             self.set_support(jid, payload)
01423 
01424         else:
01425             self.log.debug(u"%s is unavailable but sends service discovery response." % jid.as_unicode())
01426             # such situation is handled by check_if_waiting

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_form (   self,
  jid,
  form_node 
)
Handles a submitted data form

@param jid: jid that submitted the form (full jid)
@type jid: pyxmpp.jid.JID
@param form_node: a xml node with data form
@type form_node: libxml2.xmlNode

Definition at line 974 of file xmppbot.py.

00974 
00975     def handle_form(self, jid, form_node):
00976         """Handles a submitted data form
00977 
00978         @param jid: jid that submitted the form (full jid)
00979         @type jid: pyxmpp.jid.JID
00980         @param form_node: a xml node with data form
00981         @type form_node: libxml2.xmlNode
00982 
00983         """
00984         if not isinstance(form_node, libxml2.xmlNode):
00985             raise ValueError("The 'form' parameter must be of type libxml2.xmlNode!")
00986 
00987         if not isinstance(jid, JID):
00988             raise ValueError("The 'jid' parameter must be of type jid!")
00989 
00990         _ = self.get_text(jid.bare().as_unicode())
00991 
00992         form = forms.Form(form_node)
00993 
00994         if form.type != u"submit":
00995             return
00996 
00997         if "action" in form:
00998             action = form["action"].value
00999             if action == u"search":
01000                 self.handle_search_form(jid, form)
01001             else:
01002                 data = {'text': _('The form you submitted was invalid!'), 'subject': _('Invalid data')}
01003                 self.send_message(jid.as_unicode(), data, u"normal")
01004         elif "options" in form:
01005             option = form["options"].value
01006 
01007             # View page info
01008             if option == "v":
01009                 command = cmd.GetPageInfo(jid.as_unicode(), form["page_name"].value, presentation="dataforms")
01010                 self.from_commands.put_nowait(command)
01011 
01012             # Perform an another search
01013             elif option == "s":
01014                 self.handle_internal_command(jid, ["searchform"])
01015 
01016             # Revert a change
01017             elif option == "r":
01018                 revision = int(form["revision"].value)
01019 
01020                 # We can't really revert creation of a page, right?
01021                 if revision == 1:
01022                     return
01023 
01024                 self.handle_xmlrpc_command(jid, ["revertpage", form["page_name"].value, "%d" % (revision - 1, )])

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_internal_command (   self,
  sender,
  command 
)
Handles internal commands, that can be completed by the XMPP bot itself

@param command: list representing a command
@param sender: JID of sender
@type sender: pyxmpp.jid.JID

Definition at line 1088 of file xmppbot.py.

01088 
01089     def handle_internal_command(self, sender, command):
01090         """Handles internal commands, that can be completed by the XMPP bot itself
01091 
01092         @param command: list representing a command
01093         @param sender: JID of sender
01094         @type sender: pyxmpp.jid.JID
01095 
01096         """
01097         _ = self.get_text(sender)
01098 
01099         if command[0] == "ping":
01100             return "pong"
01101         elif command[0] == "help":
01102             if len(command) == 1:
01103                 return self.reply_help(sender)
01104             else:
01105                 return self.help_on(sender, command[1])
01106         elif command[0] == "searchform":
01107             jid = sender.bare().as_unicode()
01108             resource = sender.resource
01109 
01110             # Assume that outsiders know what they are doing. Clients that don't support
01111             # data forms should display a warning passed in message <body>.
01112             if jid not in self.contacts or self.contacts[jid].supports(resource, u"jabber:x:data"):
01113                 self.send_search_form(sender)
01114             else:
01115                 msg = {'text': _("This command requires a client supporting Data Forms.")}
01116                 self.send_message(sender, msg, u"")
01117         else:
01118             # For unknown command return a generic help message
01119             return self.reply_help(sender)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_message (   self,
  message 
)
Handles incoming messages

@param message: a message stanza to parse
@type message: pyxmpp.message.Message

Definition at line 1054 of file xmppbot.py.

01054 
01055     def handle_message(self, message):
01056         """Handles incoming messages
01057 
01058         @param message: a message stanza to parse
01059         @type message: pyxmpp.message.Message
01060 
01061         """
01062         if self.config.verbose:
01063             msg = "Message from %s." % (message.get_from_jid().as_unicode(), )
01064             self.log.debug(msg)
01065 
01066         form = self.contains_form(message)
01067         if form:
01068             self.handle_form(message.get_from_jid(), form)
01069             return
01070 
01071         text = message.get_body()
01072         sender = message.get_from_jid()
01073         if text:
01074             command = text.split()
01075             command[0] = command[0].lower()
01076         else:
01077             return
01078 
01079         if self.is_internal(command[0]):
01080             response = self.handle_internal_command(sender, command)
01081         elif self.is_xmlrpc(command[0]):
01082             response = self.handle_xmlrpc_command(sender, command)
01083         else:
01084             response = self.reply_help(sender)
01085 
01086         if response:
01087             self.send_message(sender, {'text': response})

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_page_info (   self,
  command 
)
Handles GetPageInfo commands

@param command: a command instance
@type command: jabberbot.commands.GetPageInfo

Definition at line 834 of file xmppbot.py.

00834 
00835     def handle_page_info(self, command):
00836         """Handles GetPageInfo commands
00837 
00838         @param command: a command instance
00839         @type command: jabberbot.commands.GetPageInfo
00840 
00841         """
00842         # Process command data first so it can be directly usable
00843         if command.data['author'].startswith("Self:"):
00844             command.data['author'] = command.data['author'][5:]
00845 
00846         datestr = str(command.data['lastModified'])
00847         command.data['lastModified'] = u"%(year)s-%(month)s-%(day)s at %(time)s" % {
00848                     'year': datestr[:4],
00849                     'month': datestr[4:6],
00850                     'day': datestr[6:8],
00851                     'time': datestr[9:17],
00852         }
00853 
00854         if command.presentation == u"text":
00855             self.send_pageinfo_text(command)
00856         elif command.presentation == u"dataforms":
00857             self.send_pageinfo_form(command)
00858 
00859         else:
00860             raise ValueError("presentation value '%s' is not supported!" % (command.presentation, ))

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_renamed_action (   self,
  cmd_data,
  jid,
  contact 
)
Handles a notification cmd_data with 'page_renamed' action

@param cmd_data: notification cmd_data
@param jid: jid to send the notification to
@param contact: a roster contact
@type cmd_data: dict
@type jid: pyxmpp.jid.JID
@type contact: Contact

Definition at line 392 of file xmppbot.py.

00392 
00393     def handle_renamed_action(self, cmd_data, jid, contact):
00394         """Handles a notification cmd_data with 'page_renamed' action
00395 
00396         @param cmd_data: notification cmd_data
00397         @param jid: jid to send the notification to
00398         @param contact: a roster contact
00399         @type cmd_data: dict
00400         @type jid: pyxmpp.jid.JID
00401         @type contact: Contact
00402 
00403         """
00404         if contact and contact.supports(jid.resource, u"jabber:x:data"):
00405             self.send_renamed_form(jid.as_unicode(), cmd_data)
00406             return
00407         else:
00408             self.send_renamed_text(jid.as_unicode(), cmd_data)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_search_form (   self,
  jid,
  form 
)
Handles a search form

@param jid: jid that submitted the form
@type jid: pyxmpp.jid.JID
@param form: a form object
@type form_node: pyxmpp.jabber.dataforms.Form

Definition at line 1025 of file xmppbot.py.

01025 
01026     def handle_search_form(self, jid, form):
01027         """Handles a search form
01028 
01029         @param jid: jid that submitted the form
01030         @type jid: pyxmpp.jid.JID
01031         @param form: a form object
01032         @type form_node: pyxmpp.jabber.dataforms.Form
01033 
01034         """
01035         required_fields = ["case", "regexp", "search_type", "search"]
01036         jid_text = jid.bare().as_unicode()
01037         _ = self.get_text(jid_text)
01038 
01039         for field in required_fields:
01040             if field not in form:
01041                 data = {'text': _('The form you submitted was invalid!'), 'subject': _('Invalid data')}
01042                 self.send_message(jid.as_unicode(), data, u"normal")
01043 
01044         case_sensitive = form['case'].value
01045         regexp_terms = form['regexp'].value
01046         if form['search_type'].value == 't':
01047             search_type = 'title'
01048         else:
01049             search_type = 'text'
01050 
01051         command = cmd.Search(jid.as_unicode(), search_type, form["search"].value, case=form['case'].value,
01052                              regexp=form['regexp'].value, presentation='dataforms')
01053         self.from_commands.put_nowait(command)

Here is the call graph for this function:

Here is the caller graph for this function:

Handles subscribe presence stanzas (requests)

Definition at line 1200 of file xmppbot.py.

01200 
01201     def handle_subscribe_presence(self, stanza):
01202         """Handles subscribe presence stanzas (requests)"""
01203 
01204         # FIXME: Let's just accept all subscribtion requests for now
01205         response = stanza.make_accept_response()
01206         self.get_stream().send(response)

Here is the caller graph for this function:

Handles unavailable presence stanzas

@type stanza: pyxmpp.presence.Presence

Definition at line 1207 of file xmppbot.py.

01207 
01208     def handle_unavailable_presence(self, stanza):
01209         """Handles unavailable presence stanzas
01210 
01211         @type stanza: pyxmpp.presence.Presence
01212 
01213         """
01214         self.log.debug("Handling unavailable presence.")
01215 
01216         jid = stanza.get_from_jid()
01217         bare_jid = jid.bare().as_unicode()
01218 
01219         # If we get presence, this contact should already be known
01220         if bare_jid in self.contacts:
01221             contact = self.contacts[bare_jid]
01222 
01223             if self.config.verbose:
01224                 self.log.debug("%s, going OFFLINE." % contact)
01225 
01226             # check if we are waiting for disco#info from this jid
01227             self.check_if_waiting(jid)
01228             del self.disco_temp[jid]
01229 
01230             try:
01231                 # Send queued messages now, as we can't guarantee to be
01232                 # alive the next time this contact becomes available.
01233                 if len(contact.resources) == 1:
01234                     self.send_queued_messages(contact, ignore_dnd=True)
01235                     contact.remove_resource(jid.resource)
01236                 else:
01237                     contact.remove_resource(jid.resource)
01238 
01239                     # The highest-priority resource, which used to be DnD might
01240                     # have gone offline. If so, try to deliver messages now.
01241                     if not contact.is_dnd():
01242                         self.send_queued_messages(contact)
01243 
01244             except ValueError:
01245                 self.log.error("Unknown contact (resource) going offline...")
01246 
01247         else:
01248             self.log.error("Unavailable presence from unknown contact.")
01249 
01250         # Confirm that we've handled this stanza
01251         return True

Here is the call graph for this function:

Here is the caller graph for this function:

Handles unsubscribed presence stanzas

Definition at line 1194 of file xmppbot.py.

01194 
01195     def handle_unsubscribed_presence(self, stanza):
01196         """Handles unsubscribed presence stanzas"""
01197 
01198         # FiXME: what policy should we adopt in this case?
01199         pass

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_user_created_action (   self,
  cmd_data,
  jid,
  contact 
)
Handles a notification cmd_data with 'user_created' action

@param cmd_data: notification cmd_data
@param jid: jid to send the notification to
@param contact: a roster contact
@type cmd_data: dict
@type jid: pyxmpp.jid.JID
@type contact: Contact

Definition at line 409 of file xmppbot.py.

00409 
00410     def handle_user_created_action(self, cmd_data, jid, contact):
00411         """Handles a notification cmd_data with 'user_created' action
00412 
00413         @param cmd_data: notification cmd_data
00414         @param jid: jid to send the notification to
00415         @param contact: a roster contact
00416         @type cmd_data: dict
00417         @type jid: pyxmpp.jid.JID
00418         @type contact: Contact
00419 
00420         """
00421         # TODO: send as form if user-client supports it
00422         self.send_user_created_text(jid.as_unicode(), cmd_data)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.handle_xmlrpc_command (   self,
  sender,
  command 
)
Creates a command object, and puts it the command queue

@param command: a valid name of available xmlrpc command
@type command: list representing a command, name and parameters

Definition at line 1169 of file xmppbot.py.

01169 
01170     def handle_xmlrpc_command(self, sender, command):
01171         """Creates a command object, and puts it the command queue
01172 
01173         @param command: a valid name of available xmlrpc command
01174         @type command: list representing a command, name and parameters
01175 
01176         """
01177         _ = self.get_text(sender)
01178         command_class = self.xmlrpc_commands[command[0]]
01179 
01180         # Add sender's JID to the argument list
01181         command.insert(1, sender.as_unicode())
01182 
01183         try:
01184             instance = command_class.__new__(command_class)
01185             instance.__init__(*command[1:])
01186             self.from_commands.put_nowait(instance)
01187 
01188         # This happens when user specifies wrong parameters
01189         except TypeError:
01190             msg = _("You've specified a wrong parameter list. \
01191 The call should look like:\n\n%(command)s %(params)s")
01192 
01193             return msg % {'command': command[0], 'params': command_class.parameter_list}

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.help_on (   self,
  jid,
  command 
)
Returns a help message on a given topic

@param command: a command to describe in a help message
@type command: str or unicode
@return: a help message

Definition at line 1136 of file xmppbot.py.

01136 
01137     def help_on(self, jid, command):
01138         """Returns a help message on a given topic
01139 
01140         @param command: a command to describe in a help message
01141         @type command: str or unicode
01142         @return: a help message
01143 
01144         """
01145         _ = self.get_text(jid)
01146 
01147         if command == "help":
01148             return _("""The "help" command prints a short, helpful message \
01149 about a given topic or function.\n\nUsage: help [topic_or_function]""")
01150 
01151         elif command == "ping":
01152             return _("""The "ping" command returns a "pong" message as soon \
01153 as it's received.""")
01154 
01155         elif command == "searchform":
01156             return _("""searchform - perform a wiki search using a form""")
01157 
01158         # Here we have to deal with help messages of external (xmlrpc) commands
01159         else:
01160             if command in self.xmlrpc_commands:
01161                 classobj = self.xmlrpc_commands[command]
01162                 help_str = _(u"%(command)s - %(description)s\n\nUsage: %(command)s %(params)s")
01163                 return help_str % {'command': command,
01164                                    'description': classobj.description,
01165                                    'params': classobj.parameter_list,
01166                                   }
01167             else:
01168                 return _("""Unknown command "%s" """) % (command, )

Here is the call graph for this function:

Here is the caller graph for this function:

Do some maintenance

Definition at line 256 of file xmppbot.py.

00256 
00257     def idle(self):
00258         """Do some maintenance"""
00259 
00260         Client.idle(self)
00261 
00262         current_time = time.time()
00263         if self.last_expiration + self.contact_check < current_time:
00264             self.expire_contacts(current_time)
00265             self.last_expiration = current_time
00266 
00267         self.disco_cache.tick()
00268         self.check_disco_delays()

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.is_internal (   self,
  command 
)
Check if a given command is internal

@type command: unicode

Definition at line 931 of file xmppbot.py.

00931 
00932     def is_internal(self, command):
00933         """Check if a given command is internal
00934 
00935         @type command: unicode
00936 
00937         """
00938         for internal_cmd in self.internal_commands:
00939             if internal_cmd.lower() == command:
00940                 return True
00941 
00942         return False

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.is_xmlrpc (   self,
  command 
)
Checks if a given commands requires interaction via XMLRPC

@type command: unicode

Definition at line 943 of file xmppbot.py.

00943 
00944     def is_xmlrpc(self, command):
00945         """Checks if a given commands requires interaction via XMLRPC
00946 
00947         @type command: unicode
00948 
00949         """
00950         for xmlrpc_cmd in self.xmlrpc_commands:
00951             if xmlrpc_cmd.lower() == command:
00952                 return True
00953 
00954         return False

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.loop (   self,
  timeout = 1 
)
Main event loop - stream and command handling

Definition at line 239 of file xmppbot.py.

00239 
00240     def loop(self, timeout=1):
00241         """Main event loop - stream and command handling"""
00242 
00243         while True:
00244             if self.stopping:
00245                 break
00246 
00247             stream = self.get_stream()
00248             if not stream:
00249                 break
00250 
00251             act = stream.loop_iter(timeout)
00252             if not act:
00253                 # Process all available commands
00254                 while self.poll_commands(): pass
00255                 self.idle()

Here is the call graph for this function:

Here is the caller graph for this function:

Checks for new commands in the input queue and executes them

@return: True if any command has been executed, False otherwise.

Definition at line 308 of file xmppbot.py.

00308 
00309     def poll_commands(self):
00310         """Checks for new commands in the input queue and executes them
00311 
00312         @return: True if any command has been executed, False otherwise.
00313 
00314         """
00315         try:
00316             command = self.to_commands.get_nowait()
00317             self.handle_command(command)
00318             return True
00319         except Queue.Empty:
00320             return False

Here is the call graph for this function:

Here is the caller graph for this function:

Sends a <presence/> stanza with type="unsubscribed

@param jid: Jabber ID of entity whose subscription we cancel
@type jid: JID

Definition at line 436 of file xmppbot.py.

00436 
00437     def remove_subscription(self, jid):
00438         """Sends a <presence/> stanza with type="unsubscribed
00439 
00440         @param jid: Jabber ID of entity whose subscription we cancel
00441         @type jid: JID
00442 
00443         """
00444         stanza = Presence(to_jid=jid, stanza_type="unsubscribed")
00445         self.get_stream().send(stanza)

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.reply_help (   self,
  jid 
)
Constructs a generic help message

It's sent in response to an uknown message or the "help" command.

Definition at line 1513 of file xmppbot.py.

01513 
01514     def reply_help(self, jid):
01515         """Constructs a generic help message
01516 
01517         It's sent in response to an uknown message or the "help" command.
01518 
01519         """
01520         _ = self.get_text(jid)
01521 
01522         msg = _("Hello there! I'm a MoinMoin Notification Bot. Available commands:\
01523 \n\n%(internal)s\n%(xmlrpc)s")
01524         internal = ", ".join(self.internal_commands)
01525         xmlrpc = ", ".join(self.xmlrpc_commands.keys())
01526 
01527         return msg % {'internal': internal, 'xmlrpc': xmlrpc}

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.roster_updated (   self,
  item = None 
)
Called when roster gets updated

Definition at line 1554 of file xmppbot.py.

01554 
01555     def roster_updated(self, item=None):
01556         """Called when roster gets updated"""
01557         self.log.debug("Updating roster.")

Start the bot - enter the event loop

Definition at line 228 of file xmppbot.py.

00228 
00229     def run(self):
00230         """Start the bot - enter the event loop"""
00231 
00232         self.log.info("Starting the jabber bot.")
00233         self.connect()
00234         self.loop()

Here is the call graph for this function:

def jabberbot.xmppbot.XMPPBot.send_attached_form (   self,
  jid,
  msg_data 
)
Sends a new attachment notification using Data Forms

@param jid: a Jabber ID to send the notification to
@type jid: unicode
@param msg_data: dictionary with notification data
@type msg_data: dict

Definition at line 675 of file xmppbot.py.

00675 
00676     def send_attached_form(self, jid, msg_data):
00677         """Sends a new attachment notification using Data Forms
00678 
00679         @param jid: a Jabber ID to send the notification to
00680         @type jid: unicode
00681         @param msg_data: dictionary with notification data
00682         @type msg_data: dict
00683 
00684         """
00685         _ = self.get_text(jid)
00686 
00687         form_title = _("File attached notification").encode("utf-8")
00688         instructions = _("Submit this form with a specified action to continue.").encode("utf-8")
00689         action_label = _("What to do next")
00690 
00691         action1 = _("Do nothing")
00692         action2 = _("View page info")
00693         action3 = _("Perform a search")
00694 
00695         do_nothing = forms.Option("n", action1)
00696         view_info = forms.Option("v", action2)
00697         search = forms.Option("s", action3)
00698 
00699         form = forms.Form(xmlnode_or_type="form", title=form_title, instructions=instructions)
00700         form.add_field(name='page_name', field_type='hidden', value=msg_data['page_name'])
00701         form.add_field(name='editor', field_type='text-single', value=msg_data['editor'], label=_("Editor"))
00702         form.add_field(name='page', field_type='text-single', value=msg_data['page_name'], label=_("Page name"))
00703         form.add_field(name='name', field_type='text-single', value=msg_data['attach_name'], label=_("File name"))
00704         form.add_field(name='size', field_type='text-single', value=msg_data['attach_size'], label=_("File size"))
00705 
00706         full_jid = JID(jid)
00707         bare_jid = full_jid.bare().as_unicode()
00708         resource = full_jid.resource
00709 
00710         # Add URLs as OOB data if it's supported and as separate fields otherwise
00711         if bare_jid in self.contacts and self.contacts[bare_jid].supports(resource, u'jabber:x:oob'):
00712             url_list = msg_data['url_list']
00713         else:
00714             url_list = []
00715 
00716             for number, url in enumerate(msg_data['url_list']):
00717                 field_name = "url%d" % (number, )
00718                 form.add_field(name=field_name, field_type="text-single", value=url["url"], label=url["description"])
00719 
00720         # Selection of a following action
00721         form.add_field(name="options", field_type="list-single", options=[do_nothing, view_info, search], label=action_label)
00722 
00723         self.send_form(jid, form, _("File attached notification"), url_list)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_attached_text (   self,
  jid,
  msg_data 
)
Sends a simple, text page deletion notification

@param jid: a Jabber ID to send the notification to
@type jid: unicode
@param msg_data: dictionary with notification data
@type msg_data: dict

Definition at line 724 of file xmppbot.py.

00724 
00725     def send_attached_text(self, jid, msg_data):
00726         """Sends a simple, text page deletion notification
00727 
00728         @param jid: a Jabber ID to send the notification to
00729         @type jid: unicode
00730         @param msg_data: dictionary with notification data
00731         @type msg_data: dict
00732 
00733         """
00734         _ = self.get_text(jid)
00735         separator = '-' * 78
00736         urls_text = '\n'.join(["%s - %s" % (url["description"], url["url"]) for url in msg_data['url_list']])
00737         message = _("%(preamble)s\n%(separator)s\n%(links)s") % {
00738                     'preamble': msg_data['text'],
00739                     'separator': separator,
00740                     'links': urls_text,
00741                   }
00742 
00743         data = {'text': message, 'subject': msg_data['subject']}
00744         self.send_message(jid, data, u"normal")

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_change_form (   self,
  jid,
  msg_data 
)
Sends a page change notification using Data Forms

@param jid: a Jabber ID to send the notification to
@type jid: unicode
@param msg_data: dictionary with notification data
@type msg_data: dict

Definition at line 532 of file xmppbot.py.

00532 
00533     def send_change_form(self, jid, msg_data):
00534         """Sends a page change notification using Data Forms
00535 
00536         @param jid: a Jabber ID to send the notification to
00537         @type jid: unicode
00538         @param msg_data: dictionary with notification data
00539         @type msg_data: dict
00540 
00541         """
00542         _ = self.get_text(jid)
00543 
00544         form_title = _("Page changed notification").encode("utf-8")
00545         instructions = _("Submit this form with a specified action to continue.").encode("utf-8")
00546         action_label = _("What to do next")
00547 
00548         action1 = _("Do nothing")
00549         action2 = _("Revert change")
00550         action3 = _("View page info")
00551         action4 = _("Perform a search")
00552 
00553         do_nothing = forms.Option("n", action1)
00554         revert = forms.Option("r", action2)
00555         view_info = forms.Option("v", action3)
00556         search = forms.Option("s", action4)
00557 
00558         form = forms.Form(xmlnode_or_type="form", title=form_title, instructions=instructions)
00559         form.add_field(name='revision', field_type='hidden', value=msg_data['revision'])
00560         form.add_field(name='page_name', field_type='hidden', value=msg_data['page_name'])
00561         form.add_field(name='editor', field_type='text-single', value=msg_data['editor'], label=_("Editor"))
00562         form.add_field(name='comment', field_type='text-single', value=msg_data.get('comment', ''), label=_("Comment"))
00563 
00564         # Add lines of text as separate values, as recommended in XEP
00565         diff_lines = msg_data['diff'].split('\n')
00566         form.add_field(name="diff", field_type="text-multi", values=diff_lines, label=("Diff"))
00567 
00568         full_jid = JID(jid)
00569         bare_jid = full_jid.bare().as_unicode()
00570         resource = full_jid.resource
00571 
00572         # Add URLs as OOB data if it's supported and as separate fields otherwise
00573         if bare_jid in self.contacts and self.contacts[bare_jid].supports(resource, u'jabber:x:oob'):
00574             url_list = msg_data['url_list']
00575         else:
00576             url_list = []
00577 
00578             for number, url in enumerate(msg_data['url_list']):
00579                 field_name = "url%d" % (number, )
00580                 form.add_field(name=field_name, field_type="text-single", value=url["url"], label=url["description"])
00581 
00582         # Selection of a following action
00583         form.add_field(name="options", field_type="list-single", options=[do_nothing, revert, view_info, search], label=action_label)
00584 
00585         self.send_form(jid, form, _("Page change notification"), url_list)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_change_text (   self,
  jid,
  msg_data 
)
Sends a simple, text page change notification

@param jid: a Jabber ID to send the notification to
@type jid: unicode
@param msg_data: dictionary with notification data
@type msg_data: dict

Definition at line 586 of file xmppbot.py.

00586 
00587     def send_change_text(self, jid, msg_data):
00588         """Sends a simple, text page change notification
00589 
00590         @param jid: a Jabber ID to send the notification to
00591         @type jid: unicode
00592         @param msg_data: dictionary with notification data
00593         @type msg_data: dict
00594 
00595         """
00596         _ = self.get_text(jid)
00597         separator = '-' * 78
00598         urls_text = '\n'.join(["%s - %s" % (url["description"], url["url"]) for url in msg_data['url_list']])
00599         message = _("%(preamble)s\nComment: %(comment)s\n%(separator)s\n%(diff)s\n%(separator)s\n%(links)s") % {
00600                     'preamble': msg_data['text'],
00601                     'separator': separator,
00602                     'diff': msg_data['diff'],
00603                     'comment': msg_data.get('comment', _('no comment')),
00604                     'links': urls_text,
00605                   }
00606 
00607         data = {'text': message, 'subject': msg_data.get('subject', '')}
00608         self.send_message(jid, data, u"normal")

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_deleted_form (   self,
  jid,
  msg_data 
)
Sends a page deleted notification using Data Forms

@param jid: a Jabber ID to send the notification to
@type jid: unicode
@param msg_data: dictionary with notification data
@type msg_data: dict

Definition at line 609 of file xmppbot.py.

00609 
00610     def send_deleted_form(self, jid, msg_data):
00611         """Sends a page deleted notification using Data Forms
00612 
00613         @param jid: a Jabber ID to send the notification to
00614         @type jid: unicode
00615         @param msg_data: dictionary with notification data
00616         @type msg_data: dict
00617 
00618         """
00619         _ = self.get_text(jid)
00620 
00621         form_title = _("Page deletion notification").encode("utf-8")
00622         instructions = _("Submit this form with a specified action to continue.").encode("utf-8")
00623         action_label = _("What to do next")
00624 
00625         action1 = _("Do nothing")
00626         action2 = _("Perform a search")
00627 
00628         do_nothing = forms.Option("n", action1)
00629         search = forms.Option("s", action2)
00630 
00631         form = forms.Form(xmlnode_or_type="form", title=form_title, instructions=instructions)
00632         form.add_field(name='editor', field_type='text-single', value=msg_data['editor'], label=_("Editor"))
00633         form.add_field(name='comment', field_type='text-single', value=msg_data.get('comment', ''), label=_("Comment"))
00634 
00635         full_jid = JID(jid)
00636         bare_jid = full_jid.bare().as_unicode()
00637         resource = full_jid.resource
00638 
00639         # Add URLs as OOB data if it's supported and as separate fields otherwise
00640         if bare_jid in self.contacts and self.contacts[bare_jid].supports(resource, u'jabber:x:oob'):
00641             url_list = msg_data['url_list']
00642         else:
00643             url_list = []
00644 
00645             for number, url in enumerate(msg_data['url_list']):
00646                 field_name = "url%d" % (number, )
00647                 form.add_field(name=field_name, field_type="text-single", value=url["url"], label=url["description"])
00648 
00649         # Selection of a following action
00650         form.add_field(name="options", field_type="list-single", options=[do_nothing, search], label=action_label)
00651 
00652         self.send_form(jid, form, _("Page deletion notification"), url_list)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_deleted_text (   self,
  jid,
  msg_data 
)
Sends a simple, text page deletion notification

@param jid: a Jabber ID to send the notification to
@type jid: unicode
@param msg_data: dictionary with notification data
@type msg_data: dict

Definition at line 653 of file xmppbot.py.

00653 
00654     def send_deleted_text(self, jid, msg_data):
00655         """Sends a simple, text page deletion notification
00656 
00657         @param jid: a Jabber ID to send the notification to
00658         @type jid: unicode
00659         @param msg_data: dictionary with notification data
00660         @type msg_data: dict
00661 
00662         """
00663         _ = self.get_text(jid)
00664         separator = '-' * 78
00665         urls_text = '\n'.join(["%s - %s" % (url["description"], url["url"]) for url in msg_data['url_list']])
00666         message = _("%(preamble)s\nComment: %(comment)s\n%(separator)s\n%(links)s") % {
00667                     'preamble': msg_data['text'],
00668                     'separator': separator,
00669                     'comment': msg_data.get('comment', _('no comment')),
00670                     'links': urls_text,
00671                   }
00672 
00673         data = {'text': message, 'subject': msg_data.get('subject', '')}
00674         self.send_message(jid, data, u"normal")

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_disco_query (   self,
  jid 
)
Sends disco#info query to a given jid

@type jid: pyxmpp.jid.JID

Definition at line 1370 of file xmppbot.py.

01370 
01371     def send_disco_query(self, jid):
01372         """Sends disco#info query to a given jid
01373 
01374         @type jid: pyxmpp.jid.JID
01375         """
01376         query = Iq(to_jid=jid, stanza_type="get")
01377         query.new_query("http://jabber.org/protocol/disco#info")
01378         self.get_stream().set_response_handlers(query, self.handle_disco_result, None)
01379         self.get_stream().send(query)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_form (   self,
  jid,
  form,
  subject,
  url_list = [] 
)
Send a data form

@param jid: jid to send the form to (full)
@param form: the form to send
@param subject: subject of the message
@param url_list: list of urls to use with OOB
@type jid: unicode
@type form: pyxmpp.jabber.dataforms.Form
@type subject: unicode
@type url_list: list

Definition at line 479 of file xmppbot.py.

00479 
00480     def send_form(self, jid, form, subject, url_list=[]):
00481         """Send a data form
00482 
00483         @param jid: jid to send the form to (full)
00484         @param form: the form to send
00485         @param subject: subject of the message
00486         @param url_list: list of urls to use with OOB
00487         @type jid: unicode
00488         @type form: pyxmpp.jabber.dataforms.Form
00489         @type subject: unicode
00490         @type url_list: list
00491 
00492         """
00493         if not isinstance(form, forms.Form):
00494             raise ValueError("The 'form' argument must be of type pyxmpp.jabber.dataforms.Form!")
00495 
00496         _ = self.get_text(JID(jid).bare().as_unicode())
00497 
00498         message = Message(to_jid=jid, subject=subject)
00499         message.add_content(form)
00500 
00501         if url_list:
00502             oob.add_urls(message, url_list)
00503 
00504         self.get_stream().send(message)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_message (   self,
  jid_text,
  data,
  msg_type = u"chat" 
)
Sends a message

@param jid_text: JID to send the message to
@param data: dictionary containing notification data
@param msg_type: message type, as defined in RFC
@type jid_text: unicode

Definition at line 446 of file xmppbot.py.

00446 
00447     def send_message(self, jid_text, data, msg_type=u"chat"):
00448         """Sends a message
00449 
00450         @param jid_text: JID to send the message to
00451         @param data: dictionary containing notification data
00452         @param msg_type: message type, as defined in RFC
00453         @type jid_text: unicode
00454 
00455         """
00456         use_oob = False
00457         subject = data.get('subject', '')
00458         jid = JID(jid_text)
00459 
00460         if data.has_key('url_list') and data['url_list']:
00461             jid_bare = jid.bare().as_unicode()
00462             contact = self.contacts.get(jid_bare, None)
00463             if contact and contact.supports(jid.resource, u'jabber:x:oob'):
00464                 use_oob = True
00465             else:
00466                 url_strings = ['%s - %s' % (entry['url'], entry['description']) for entry in data['url_list']]
00467 
00468                 # Insert a newline, so that the list of URLs doesn't start in the same
00469                 # line as the rest of message text
00470                 url_strings.insert(0, '\n')
00471                 data['text'] = data['text'] + '\n'.join(url_strings)
00472 
00473         message = Message(to_jid=jid, body=data['text'], stanza_type=msg_type, subject=subject)
00474 
00475         if use_oob:
00476             oob.add_urls(message, data['url_list'])
00477 
00478         self.get_stream().send(message)

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_pageinfo_form (   self,
  command 
)
Sends page info using Data Forms

Definition at line 884 of file xmppbot.py.

00884 
00885     def send_pageinfo_form(self, command):
00886         """Sends page info using Data Forms
00887 
00888 
00889         """
00890         _ = self.get_text(command.jid)
00891         data = command.data
00892 
00893         form_title = _("Detailed page information").encode("utf-8")
00894         instructions = _("Submit this form with a specified action to continue.").encode("utf-8")
00895         action_label = _("What to do next")
00896 
00897         action1 = _("Do nothing")
00898         action2 = _("Get page contents")
00899         action3 = _("Get page contents (HTML)")
00900         action4 = _("Perform a search")
00901 
00902         do_nothing = forms.Option("n", action1)
00903         get_content = forms.Option("c", action2)
00904         get_content_html = forms.Option("h", action3)
00905         search = forms.Option("s", action4)
00906 
00907         form = forms.Form(xmlnode_or_type="form", title=form_title, instructions=instructions)
00908         form.add_field(name='pagename', field_type='text-single', value=command.pagename, label=_("Page name"))
00909         form.add_field(name="changed", field_type='text-single', value=data['lastModified'], label=_("Last changed"))
00910         form.add_field(name='editor', field_type='text-single', value=data['author'], label=_("Last editor"))
00911         form.add_field(name='version', field_type='text-single', value=data['version'], label=_("Current version"))
00912 
00913 #        full_jid = JID(jid)
00914 #        bare_jid = full_jid.bare().as_unicode()
00915 #        resource = full_jid.resource
00916 
00917         # Add URLs as OOB data if it's supported and as separate fields otherwise
00918 #        if bare_jid in self.contacts and self.contacts[bare_jid].supports(resource, u'jabber:x:oob'):
00919 #            url_list = msg_data['url_list']
00920 #        else:
00921 #            url_list = []
00922 #
00923 #            for number, url in enumerate(msg_data['url_list']):
00924 #                field_name = "url%d" % (number, )
00925 #                form.add_field(name=field_name, field_type="text-single", value=url["url"], label=url["description"])
00926 
00927         # Selection of a following action
00928         form.add_field(name="options", field_type="list-single", options=[do_nothing, get_content, get_content_html, search], label=action_label)
00929 
00930         self.send_form(command.jid, form, _("Detailed page information"))

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_pageinfo_text (   self,
  command 
)
Sends detailed page info with plain text

@param command: command with detailed data
@type command: jabberbot.command.GetPageInfo

Definition at line 861 of file xmppbot.py.

00861 
00862     def send_pageinfo_text(self, command):
00863         """Sends detailed page info with plain text
00864 
00865         @param command: command with detailed data
00866         @type command: jabberbot.command.GetPageInfo
00867 
00868         """
00869         _ = self.get_text(command.jid)
00870 
00871         intro = _("""Following detailed information on page "%(pagename)s" \
00872 is available:""")
00873 
00874         msg = _("""Last author: %(author)s
00875 Last modification: %(modification)s
00876 Current version: %(version)s""") % {
00877          'author': command.data['author'],
00878          'modification': command.data['lastModified'],
00879          'version': command.data['version'],
00880         }
00881 
00882         self.send_message(command.jid, {'text': intro % {'pagename': command.pagename}})
00883         self.send_message(command.jid, {'text': msg})

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_queued_messages (   self,
  contact,
  ignore_dnd = False 
)
Sends messages queued for the contact

@param contact: a contact whose queued messages are to be sent
@type contact: jabberbot.xmppbot.Contact
@param ignore_dnd: should contact's DnD status be ignored?

Definition at line 1502 of file xmppbot.py.

01502 
01503     def send_queued_messages(self, contact, ignore_dnd=False):
01504         """Sends messages queued for the contact
01505 
01506         @param contact: a contact whose queued messages are to be sent
01507         @type contact: jabberbot.xmppbot.Contact
01508         @param ignore_dnd: should contact's DnD status be ignored?
01509 
01510         """
01511         for command in contact.messages:
01512             self.handle_command(command, ignore_dnd)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_renamed_form (   self,
  jid,
  msg_data 
)
Sends a page rename notification using Data Forms

@param jid: a Jabber ID to send the notification to
@type jid: unicode
@param msg_data: dictionary with notification data
@type msg_data: dict

Definition at line 745 of file xmppbot.py.

00745 
00746     def send_renamed_form(self, jid, msg_data):
00747         """Sends a page rename notification using Data Forms
00748 
00749         @param jid: a Jabber ID to send the notification to
00750         @type jid: unicode
00751         @param msg_data: dictionary with notification data
00752         @type msg_data: dict
00753 
00754         """
00755         _ = self.get_text(jid)
00756 
00757         form_title = _("Page rename notification").encode("utf-8")
00758         instructions = _("Submit this form with a specified action to continue.").encode("utf-8")
00759         action_label = _("What to do next")
00760 
00761         action1 = _("Do nothing")
00762         action2 = _("Revert change")
00763         action3 = _("View page info")
00764         action4 = _("Perform a search")
00765 
00766         do_nothing = forms.Option("n", action1)
00767         revert = forms.Option("r", action2)
00768         view_info = forms.Option("v", action3)
00769         search = forms.Option("s", action4)
00770 
00771         form = forms.Form(xmlnode_or_type="form", title=form_title, instructions=instructions)
00772         form.add_field(name='revision', field_type='hidden', value=msg_data['revision'])
00773         form.add_field(name='page_name', field_type='hidden', value=msg_data['page_name'])
00774         form.add_field(name='editor', field_type='text-single', value=msg_data['editor'], label=_("Editor"))
00775         form.add_field(name='comment', field_type='text-single', value=msg_data.get('comment', ''), label=_("Comment"))
00776         form.add_field(name='old', field_type='text-single', value=msg_data['old_name'], label=_("Old name"))
00777         form.add_field(name='new', field_type='text-single', value=msg_data['page_name'], label=_("New name"))
00778 
00779         full_jid = JID(jid)
00780         bare_jid = full_jid.bare().as_unicode()
00781         resource = full_jid.resource
00782 
00783         # Add URLs as OOB data if it's supported and as separate fields otherwise
00784         if bare_jid in self.contacts and self.contacts[bare_jid].supports(resource, u'jabber:x:oob'):
00785             url_list = msg_data['url_list']
00786         else:
00787             url_list = []
00788 
00789             for number, url in enumerate(msg_data['url_list']):
00790                 field_name = "url%d" % (number, )
00791                 form.add_field(name=field_name, field_type="text-single", value=url["url"], label=url["description"])
00792 
00793         # Selection of a following action
00794         form.add_field(name="options", field_type="list-single", options=[do_nothing, revert, view_info, search], label=action_label)
00795 
00796         self.send_form(jid, form, _("Page rename notification"), url_list)

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_renamed_text (   self,
  jid,
  msg_data 
)
Sends a simple, text page rename notification

@param jid: a Jabber ID to send the notification to
@type jid: unicode
@param msg_data: dictionary with notification data
@type msg_data: dict

Definition at line 797 of file xmppbot.py.

00797 
00798     def send_renamed_text(self, jid, msg_data):
00799         """Sends a simple, text page rename notification
00800 
00801         @param jid: a Jabber ID to send the notification to
00802         @type jid: unicode
00803         @param msg_data: dictionary with notification data
00804         @type msg_data: dict
00805 
00806         """
00807         _ = self.get_text(jid)
00808         separator = '-' * 78
00809         urls_text = '\n'.join(["%s - %s" % (url["description"], url["url"]) for url in msg_data['url_list']])
00810         message = _("%(preamble)s\nComment: %(comment)s\n%(separator)s\n%(links)s") % {
00811                     'preamble': msg_data['text'],
00812                     'separator': separator,
00813                     'comment': msg_data.get('comment', _('no comment')),
00814                     'links': urls_text,
00815                   }
00816 
00817         data = {'text': message, 'subject': msg_data['subject']}
00818         self.send_message(jid, data, u"normal")

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_search_form (   self,
  jid 
)

Definition at line 505 of file xmppbot.py.

00505 
00506     def send_search_form(self, jid):
00507         _ = self.get_text(jid)
00508 
00509         # These encode()s may look weird, but due to some pyxmpp oddness we have
00510         # to provide an utf-8 string instead of unicode. Bug reported, patches submitted...
00511         form_title = _("Wiki search").encode("utf-8")
00512         help_form = _("Submit this form to perform a wiki search").encode("utf-8")
00513         search_type1 = _("Title search")
00514         search_type2 = _("Full-text search")
00515         search_label = _("Search type")
00516         search_label2 = _("Search text")
00517         case_label = _("Case-sensitive search")
00518         regexp_label = _("Treat terms as regular expressions")
00519         forms_warn = _("If you see this, your client probably doesn't support Data Forms.")
00520 
00521         title_search = forms.Option("t", search_type1)
00522         full_search = forms.Option("f", search_type2)
00523 
00524         form = forms.Form(xmlnode_or_type="form", title=form_title, instructions=help_form)
00525         form.add_field(name="action", field_type="hidden", value="search")
00526         form.add_field(name="case", field_type="boolean", label=case_label)
00527         form.add_field(name="regexp", field_type="boolean", label=regexp_label)
00528         form.add_field(name="search_type", options=[title_search, full_search], field_type="list-single", label=search_label)
00529         form.add_field(name="search", field_type="text-single", label=search_label2)
00530 
00531         self.send_form(jid, form, _("Wiki search"))

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.send_user_created_text (   self,
  jid,
  msg_data 
)
Sends a simple, text page user-created-notification

@param jid: a Jabber ID to send the notification to
@type jid: unicode
@param msg_data: dictionary with notification data
@type msg_data: dict

Definition at line 819 of file xmppbot.py.

00819 
00820     def send_user_created_text(self, jid, msg_data):
00821         """Sends a simple, text page user-created-notification
00822 
00823         @param jid: a Jabber ID to send the notification to
00824         @type jid: unicode
00825         @param msg_data: dictionary with notification data
00826         @type msg_data: dict
00827 
00828         """
00829         _ = self.get_text(jid)
00830         message = _("%(text)s") % {'text': msg_data['text']}
00831 
00832         data = {'text': message, 'subject': msg_data['subject']}
00833         self.send_message(jid, data, u"normal")

Here is the call graph for this function:

Here is the caller graph for this function:

def jabberbot.xmppbot.XMPPBot.service_discovery (   self,
  jid,
  presence 
)
General handler for XEP-0115 (Entity Capabilities)

@param jid: whose capabilities to discover (pyxmpp.jid.JID)
@param presence: received presence stanza (pyxmpp.presence.Presence)

Definition at line 1315 of file xmppbot.py.

01315 
01316     def service_discovery(self, jid, presence):
01317         """General handler for XEP-0115 (Entity Capabilities)
01318 
01319         @param jid: whose capabilities to discover (pyxmpp.jid.JID)
01320         @param presence: received presence stanza (pyxmpp.presence.Presence)
01321         """
01322         ver_algo = self.check_presence(presence)
01323         self.disco_temp[jid] = ver_algo
01324 
01325         if ver_algo is None:
01326             # legacy client - send disco#info query
01327             self.send_disco_query(jid)
01328         else:
01329             # check if we have this (ver,algo) already cached
01330             cache_item = self.disco_cache.get_item(ver_algo, state='stale')
01331 
01332             if cache_item is None:
01333                 # add to disco_wait
01334                 self.add_to_disco_wait(ver_algo, jid)
01335             else:
01336                 # use cached capabilities
01337                 self.log.debug(u"%s: using cached capabilities." % jid.as_unicode())
01338                 payload = cache_item.value
01339                 self.set_support(jid, payload)

Here is the call graph for this function:

Here is the caller graph for this function:

Handle session started event.
Requests the user's roster and sends the initial presence with
a <c> child as described in XEP-0115 (Entity Capabilities)

Definition at line 269 of file xmppbot.py.

00269 
00270     def session_started(self):
00271         """Handle session started event.
00272         Requests the user's roster and sends the initial presence with
00273         a <c> child as described in XEP-0115 (Entity Capabilities)
00274 
00275         """
00276         self.request_roster()
00277         pres = capat.create_presence(self.jid)
00278         self.stream.set_iq_get_handler("query", "http://jabber.org/protocol/disco#info", self.handle_disco_query)
00279         self.stream.send(pres)

Here is the call graph for this function:

def jabberbot.xmppbot.XMPPBot.set_support (   self,
  jid,
  payload 
)
Searches service discovery results for support for
Out Of Band Data (XEP-066) and Data Forms (XEP-004)
and applies it to newly created Contact.

@param jid: client's jabber ID (pyxmpp.jid.JID)
@param payload: client's capabilities (libxml2.xmlNode)

Definition at line 1486 of file xmppbot.py.

01486 
01487     def set_support(self, jid, payload):
01488         """Searches service discovery results for support for
01489         Out Of Band Data (XEP-066) and Data Forms (XEP-004)
01490         and applies it to newly created Contact.
01491 
01492         @param jid: client's jabber ID (pyxmpp.jid.JID)
01493         @param payload: client's capabilities (libxml2.xmlNode)
01494         """
01495         supports = payload.xpathEval('//*[@var="jabber:x:oob"]')
01496         if supports:
01497             self.contacts[jid.bare().as_unicode()].set_supports(jid.resource, u"jabber:x:oob")
01498 
01499         supports = payload.xpathEval('//*[@var="jabber:x:data"]')
01500         if supports:
01501             self.contacts[jid.bare().as_unicode()].set_supports(jid.resource, u"jabber:x:data")

Here is the caller graph for this function:

Stop the thread

Definition at line 235 of file xmppbot.py.

00235 
00236     def stop(self):
00237         """Stop the thread"""
00238         self.stopping = True

def jabberbot.xmppbot.XMPPBot.stream_closed (   self,
  stream 
)
Called when stream closes

Definition at line 1558 of file xmppbot.py.

01558 
01559     def stream_closed(self, stream):
01560         """Called when stream closes"""
01561         self.log.debug("Stream closed.")

def jabberbot.xmppbot.XMPPBot.stream_created (   self,
  stream 
)
Called when stream gets created

Definition at line 1562 of file xmppbot.py.

01562 
01563     def stream_created(self, stream):
01564         """Called when stream gets created"""
01565         self.log.debug("Stream created.")

def jabberbot.xmppbot.XMPPBot.stream_error (   self,
  error 
)
Called when stream error gets received

Definition at line 1566 of file xmppbot.py.

01566 
01567     def stream_error(self, error):
01568         """Called when stream error gets received"""
01569         self.log.error("Received a stream error.")


Member Data Documentation

Definition at line 207 of file xmppbot.py.

Definition at line 181 of file xmppbot.py.

Definition at line 193 of file xmppbot.py.

Definition at line 187 of file xmppbot.py.

Definition at line 219 of file xmppbot.py.

Definition at line 226 of file xmppbot.py.

Definition at line 223 of file xmppbot.py.

Definition at line 178 of file xmppbot.py.

Definition at line 197 of file xmppbot.py.

Definition at line 183 of file xmppbot.py.

Definition at line 196 of file xmppbot.py.

Definition at line 190 of file xmppbot.py.

Definition at line 182 of file xmppbot.py.

Definition at line 194 of file xmppbot.py.

Definition at line 184 of file xmppbot.py.

Definition at line 179 of file xmppbot.py.

Definition at line 199 of file xmppbot.py.


The documentation for this class was generated from the following file: