presence.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. """
  2. SleekXMPP: The Sleek XMPP Library
  3. Copyright (C) 2010 Nathanael C. Fritz
  4. This file is part of SleekXMPP.
  5. See the file LICENSE for copying permission.
  6. """
  7. from sleekxmpp.stanza.rootstanza import RootStanza
  8. from sleekxmpp.xmlstream import StanzaBase
  9. class Presence(RootStanza):
  10. """
  11. XMPP's <presence> stanza allows entities to know the status of other
  12. clients and components. Since it is currently the only multi-cast
  13. stanza in XMPP, many extensions add more information to <presence>
  14. stanzas to broadcast to every entry in the roster, such as
  15. capabilities, music choices, or locations (XEP-0115: Entity Capabilities
  16. and XEP-0163: Personal Eventing Protocol).
  17. Since <presence> stanzas are broadcast when an XMPP entity changes
  18. its status, the bulk of the traffic in an XMPP network will be from
  19. <presence> stanzas. Therefore, do not include more information than
  20. necessary in a status message or within a <presence> stanza in order
  21. to help keep the network running smoothly.
  22. Example <presence> stanzas:
  23. <presence />
  24. <presence from="user@example.com">
  25. <show>away</show>
  26. <status>Getting lunch.</status>
  27. <priority>5</priority>
  28. </presence>
  29. <presence type="unavailable" />
  30. <presence to="user@otherhost.com" type="subscribe" />
  31. Stanza Interface:
  32. priority -- A value used by servers to determine message routing.
  33. show -- The type of status, such as away or available for chat.
  34. status -- Custom, human readable status message.
  35. Attributes:
  36. types -- One of: available, unavailable, error, probe,
  37. subscribe, subscribed, unsubscribe,
  38. and unsubscribed.
  39. showtypes -- One of: away, chat, dnd, and xa.
  40. Methods:
  41. setup -- Overrides StanzaBase.setup
  42. reply -- Overrides StanzaBase.reply
  43. set_show -- Set the value of the <show> element.
  44. get_type -- Get the value of the type attribute or <show> element.
  45. set_type -- Set the value of the type attribute or <show> element.
  46. get_priority -- Get the value of the <priority> element.
  47. set_priority -- Set the value of the <priority> element.
  48. """
  49. name = 'presence'
  50. namespace = 'jabber:client'
  51. plugin_attrib = name
  52. interfaces = set(['type', 'to', 'from', 'id', 'show',
  53. 'status', 'priority'])
  54. sub_interfaces = set(['show', 'status', 'priority'])
  55. lang_interfaces = set(['status'])
  56. types = set(['available', 'unavailable', 'error', 'probe', 'subscribe',
  57. 'subscribed', 'unsubscribe', 'unsubscribed'])
  58. showtypes = set(['dnd', 'chat', 'xa', 'away'])
  59. def __init__(self, *args, **kwargs):
  60. """
  61. Initialize a new <presence /> stanza with an optional 'id' value.
  62. Overrides StanzaBase.__init__.
  63. """
  64. StanzaBase.__init__(self, *args, **kwargs)
  65. if self['id'] == '':
  66. if self.stream is not None and self.stream.use_presence_ids:
  67. self['id'] = self.stream.new_id()
  68. def exception(self, e):
  69. """
  70. Override exception passback for presence.
  71. """
  72. pass
  73. def set_show(self, show):
  74. """
  75. Set the value of the <show> element.
  76. Arguments:
  77. show -- Must be one of: away, chat, dnd, or xa.
  78. """
  79. if show is None:
  80. self._del_sub('show')
  81. elif show in self.showtypes:
  82. self._set_sub_text('show', text=show)
  83. return self
  84. def get_type(self):
  85. """
  86. Return the value of the <presence> stanza's type attribute, or
  87. the value of the <show> element.
  88. """
  89. out = self._get_attr('type')
  90. if not out:
  91. out = self['show']
  92. if not out or out is None:
  93. out = 'available'
  94. return out
  95. def set_type(self, value):
  96. """
  97. Set the type attribute's value, and the <show> element
  98. if applicable.
  99. Arguments:
  100. value -- Must be in either self.types or self.showtypes.
  101. """
  102. if value in self.types:
  103. self['show'] = None
  104. if value == 'available':
  105. value = ''
  106. self._set_attr('type', value)
  107. elif value in self.showtypes:
  108. self['show'] = value
  109. return self
  110. def del_type(self):
  111. """
  112. Remove both the type attribute and the <show> element.
  113. """
  114. self._del_attr('type')
  115. self._del_sub('show')
  116. def set_priority(self, value):
  117. """
  118. Set the entity's priority value. Some server use priority to
  119. determine message routing behavior.
  120. Bot clients should typically use a priority of 0 if the same
  121. JID is used elsewhere by a human-interacting client.
  122. Arguments:
  123. value -- An integer value greater than or equal to 0.
  124. """
  125. self._set_sub_text('priority', text=str(value))
  126. def get_priority(self):
  127. """
  128. Return the value of the <presence> element as an integer.
  129. """
  130. p = self._get_sub_text('priority')
  131. if not p:
  132. p = 0
  133. try:
  134. return int(p)
  135. except ValueError:
  136. # The priority is not a number: we consider it 0 as a default
  137. return 0
  138. def reply(self, clear=True):
  139. """
  140. Set the appropriate presence reply type.
  141. Overrides StanzaBase.reply.
  142. Arguments:
  143. clear -- Indicates if the stanza contents should be removed
  144. before replying. Defaults to True.
  145. """
  146. if self['type'] == 'unsubscribe':
  147. self['type'] = 'unsubscribed'
  148. elif self['type'] == 'subscribe':
  149. self['type'] = 'subscribed'
  150. return StanzaBase.reply(self, clear)
  151. # To comply with PEP8, method names now use underscores.
  152. # Deprecated method names are re-mapped for backwards compatibility.
  153. Presence.setShow = Presence.set_show
  154. Presence.getType = Presence.get_type
  155. Presence.setType = Presence.set_type
  156. Presence.delType = Presence.get_type
  157. Presence.getPriority = Presence.get_priority
  158. Presence.setPriority = Presence.set_priority