Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F7232209
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
39 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/pypjua/applications/pidf.py b/pypjua/applications/pidf.py
index 51432c86..08a0bff7 100644
--- a/pypjua/applications/pidf.py
+++ b/pypjua/applications/pidf.py
@@ -1,301 +1,305 @@
"""PIDF handling according to RFC3863
This module provides classes to parse and generate PIDF documents, and also
uses the XML Application extensibility API to allow extensions to PIDF.
Example usage:
>>> from datetime import datetime
>>> pidf = PIDF('pres:someone@example.com')
>>> status = Status(basic=Basic('open'))
>>> contact = Contact('im:someone@mobilecarrier.net')
>>> contact.priority = "0.8"
>>> tuple1 = Tuple('bs35r9', notes=[Note("Don't Disturb Please!"), Note("Ne derangez pas, s'il vous plait", lang="fr")], status=status)
>>> tuple1.contact = contact
>>> tuple1.timestamp = Timestamp(datetime(2008, 9, 11, 20, 42, 03))
>>> tuple2 = Tuple('eg92n8', status=Status(basic=Basic('open')), contact=Contact('mailto:someone@example.com'))
>>> tuple2.contact.priority = "1.0"
>>> pidf.notes.append(Note("I'll be in Tokyo next week"))
>>> pidf.append(tuple1)
>>> pidf.append(tuple2)
>>> print pidf.toxml(pretty_print=True)
<?xml version='1.0' encoding='UTF-8'?>
<presence xmlns="urn:ietf:params:xml:ns:pidf" entity="pres:someone@example.com">
<tuple id="bs35r9">
<status>
<basic>open</basic>
</status>
<contact priority="0.8">im:someone@mobilecarrier.net</contact>
<note>Don't Disturb Please!</note>
<note xml:lang="fr">Ne derangez pas, s'il vous plait</note>
<timestamp>2008-09-11T20:42:03+01:00</timestamp>
</tuple>
<tuple id="eg92n8">
<status>
<basic>open</basic>
</status>
<contact priority="1.0">mailto:someone@example.com</contact>
</tuple>
<note>I'll be in Tokyo next week</note>
</presence>
<BLANKLINE>
"""
import re
import datetime
from pypjua.applications import ParserError, XMLMeta, XMLApplication, XMLElement, XMLStringElement, ExtensibleXMLApplication, ExtensibleXMLListApplication, ExtensibleXMLElement
__all__ = ['_namespace_',
'PIDFMeta',
'PIDFTopElement',
'TupleExtension',
'StatusExtension',
'Note',
'NoteList',
'Tuple',
'Status',
'Basic',
'Contact',
'Timestamp',
'PIDF']
_namespace_ = 'urn:ietf:params:xml:ns:pidf'
class PIDFMeta(XMLMeta): pass
# Mixin types for extenisibility
class PIDFTopElement(object): pass
class TupleExtension(object): pass
class StatusExtension(object): pass
class Timestamp(XMLElement):
_xml_tag = 'timestamp'
_xml_namespace = _namespace_
_xml_attrs = {}
_xml_meta = PIDFMeta
_timestamp_re = re.compile(r'(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})T(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})(\.(?P<secfrac>\d{1,}))?((?P<UTC>Z)|((?P<tzsign>\+|-)(?P<tzhour>\d{2}):(?P<tzminute>\d{2})))')
def __init__(self, timestamp=None):
if timestamp is None:
timestamp = datetime.datetime.now()
self.timestamp = timestamp
def _parse_element(self, element):
self.timestamp = self.parse_timestamp(element.text)
def _build_element(self, element, nsmap):
element.text = self.format_timestamp(self.timestamp)
@classmethod
def utc_offset(cls):
timediff = datetime.datetime.now() - datetime.datetime.utcnow()
return int(round((timediff.days*86400 + timediff.seconds + timediff.microseconds/1000000.0)/60))
@classmethod
def parse_timestamp(cls, stamp):
+ if stamp is None:
+ return None
match = cls._timestamp_re.match(stamp)
if match is None:
raise ParserError("Timestamp %s is not in RFC3339 format" % stamp)
dct = match.groupdict()
if dct['UTC'] is not None:
secoffset = 0
else:
secoffset = int(dct['tzminute'])*60 + int(dct['tzhour'])*3600
if dct['tzsign'] == '-':
secoffset *= -1
if dct['secfrac'] is not None:
secfrac = dct['secfrac'][:6]
secfrac += '0'*(6-len(secfrac))
secfrac = int(secfrac)
else:
secfrac = 0
dt = datetime.datetime(year=int(dct['year']), month=int(dct['month']), day=int(dct['day']),
hour=int(dct['hour']), minute=int(dct['minute']), second=int(dct['second']),
microsecond=secfrac)
return dt - datetime.timedelta(seconds=secoffset) + datetime.timedelta(seconds=cls.utc_offset()*60)
@classmethod
def format_timestamp(cls, dt):
+ if dt is None:
+ return None
minutes = cls.utc_offset()
if minutes == 0:
tzspec = 'Z'
else:
if minutes < 0:
sign = '-'
minutes *= -1
else:
sign = '+'
hours = minutes / 60
minutes = minutes % 60
tzspec = '%s%02d:%02d' % (sign, hours, minutes)
return dt.replace(microsecond=0).isoformat()+tzspec
def __str__(self):
return str(self.timestamp)
PIDFMeta.register(Timestamp)
class Note(XMLStringElement):
_xml_tag = 'note'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
_xml_lang = True
_xml_attrs = {'since': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp, 'xml_attribute': 'from'},
'until': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp}}
PIDFMeta.register(Note)
class NoteList(object):
def __init__(self):
self.__notes = {}
def __getitem__(self, key):
return self.__notes[key]
def __delitem__(self, key):
del self.__notes[key]
def __iter__(self):
return self.__notes.itervalues()
def append(self, note):
self.__notes[note.lang] = note
class Basic(XMLStringElement):
_xml_tag = 'basic'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
_xml_lang = False
_xml_values = ('open', 'closed')
PIDFMeta.register(Note)
class Status(ExtensibleXMLElement):
_xml_tag = 'status'
_xml_namespace = _namespace_
_xml_attrs = {'id': {'id_attribute': True}}
_xml_meta = PIDFMeta
_xml_ext_type = StatusExtension
def __init__(self, basic=None, **kwargs):
ExtensibleXMLElement.__init__(self, **kwargs)
self.basic = basic
def _parse_element(self, element):
self.basic = None
for child in element:
if child.tag == Basic.qname:
self.basic = Basic.from_element(child, xml_meta=self._xml_meta)
def _build_element(self, element, nsmap):
if self.basic is not None:
self.basic.to_element(parent=element, nsmap=nsmap)
self._build_extensions(element, nsmap)
PIDFMeta.register(Status)
class Contact(XMLStringElement):
_xml_tag = 'contact'
_xml_namespace = _namespace_
_xml_attrs = {'priority': {}}
_xml_meta = PIDFMeta
_xml_lang = False
PIDFMeta.register(Contact)
class Tuple(ExtensibleXMLElement, PIDFTopElement):
_xml_tag = 'tuple'
_xml_namespace = _namespace_
_xml_attrs = {'id': {'id_attribute': True}}
_xml_meta = PIDFMeta
_xml_ext_type = TupleExtension
def __init__(self, id, notes=[], status=None, contact=None, timestamp=None, **kwargs):
ExtensibleXMLElement.__init__(self, **kwargs)
self.id = id
self.notes = NoteList()
for note in notes:
self.notes.append(note)
self.status = status
self.contact = contact
self.timestamp = timestamp
def _parse_element(self, element):
self.notes = NoteList()
self.status = None
self.contact = None
self.timestamp = None
for child in element:
if child.tag == Note.qname:
self.notes.append(Note.from_element(child, xml_meta=self._xml_meta))
elif child.tag == Status.qname:
self.status = Status.from_element(child, xml_meta=self._xml_meta)
elif child.tag == Contact.qname:
self.contact = Contact.from_element(child, xml_meta=self._xml_meta)
elif child.tag == Timestamp.qname:
self.timestamp = Timestamp.from_element(child, xml_meta=self._xml_meta)
def _build_element(self, element, nsmap):
if self.status is not None:
self.status.to_element(parent=element, nsmap=nsmap)
self._build_extensions(element, nsmap)
if self.contact is not None:
self.contact.to_element(parent=element, nsmap=nsmap)
for note in self.notes:
note.to_element(parent=element, nsmap=nsmap)
if self.timestamp is not None:
self.timestamp.to_element(parent=element, nsmap=nsmap)
PIDFMeta.register(Tuple)
class PIDF(ExtensibleXMLListApplication):
accept_types = ['application/pidf+xml']
build_types = ['application/pidf+xml']
_xml_tag = 'presence'
_xml_namespace = _namespace_
_xml_attrs = {'entity': {'id_attribute': True}}
_xml_meta = PIDFMeta
_xml_schema_file = 'pidf.xsd'
_xml_nsmap = {None: _namespace_}
_parser_opts = {'remove_blank_text': True}
def __init__(self, entity, elems=[], notes=[]):
self.entity = entity
self[0:0] = elems
self.notes = NoteList()
for note in notes:
self.notes.append(note)
def _parse_element(self, element):
self.notes = NoteList()
for child in element:
if child.tag == Note.qname:
self.notes.append(Note.from_element(child, xml_meta=self._xml_meta))
else:
child_cls = self._xml_meta.get(child.tag)
if child_cls is not None:
- self.append(chidl_cls.from_element(child, xml_meta=self._xml_meta))
+ self.append(child_cls.from_element(child, xml_meta=self._xml_meta))
def _build_element(self, element, nsmap):
for child in self:
if isinstance(child, Tuple):
child.to_element(parent=element, nsmap=nsmap)
for note in self.notes:
note.to_element(parent=element, nsmap=nsmap)
for child in self:
if not isinstance(child, Tuple):
child.to_element(parent=element, nsmap=nsmap)
def _before_add(self, value):
if not isinstance(value, PIDFTopElement):
raise TypeError("PIDF elements can only contain PIDFTopElement children, got %s instead" % value.__class__.__name__)
return value
PIDFMeta.register(PIDF)
diff --git a/pypjua/applications/presdm.py b/pypjua/applications/presdm.py
index 3665ab27..573bc48d 100644
--- a/pypjua/applications/presdm.py
+++ b/pypjua/applications/presdm.py
@@ -1,97 +1,112 @@
"""Presence data-model elements handling according to RFC4479
This module provides an extension to PIDF (module pypjua.applications.pidf) to
support the data module defined in RFC4479.
"""
from pypjua.applications import XMLExtension, XMLStringElement, ExtensibleXMLElement
-from pypjua.applications.pidf import PIDFTopElement, PIDF, PIDFMeta
+from pypjua.applications.pidf import PIDFTopElement, PIDF, PIDFMeta, NoteList, Note, Timestamp
+
+__all__ = ['_namespace_',
+ 'DeviceExtension',
+ 'PersonExtension',
+ 'DMNote',
+ 'DeviceID',
+ 'Device',
+ 'Person']
_namespace_ = 'urn:ietf:params:xml:ns:pidf:data-model'
class DeviceExtension(object): pass
class PersonExtension(object): pass
+class DMNote(Note):
+ _xml_tag = 'note'
+ _xml_namespace = _namespace_
+ _xml_meta = PIDFMeta
+
class DeviceID(XMLStringElement):
_xml_tag = 'deviceID'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
_xml_lang = False
class Device(ExtensibleXMLElement, PIDFTopElement):
_xml_tag = 'device'
_xml_namespace = _namespace_
_xml_attrs = {'id': {'id_attribute': True}}
_xml_meta = PIDFMeta
_xml_ext_type = DeviceExtension
def __init__(self, id, deviceID=None, notes=[], timestamp=None, **kwargs):
ExtensibleXMLElement.__init__(self, **kwargs)
self.id = id
self.deviceID = deviceID
self.notes = NoteList()
for note in notes:
self.notes.append(note)
self.timestamp = timestamp
def _parse_element(self, element):
self.deviceID = None
self.notes = NoteList()
self.timestamp = None
for child in element:
if child.tag == DeviceID.qname:
self.deviceID = DeviceID.from_element(child, xml_meta=self._xml_meta)
- elif child.tag == Note.qname:
- self.notes.append(Note.from_element(child, xml_meta=self._xml_meta))
+ elif child.tag == DMNote.qname:
+ self.notes.append(DMNote.from_element(child, xml_meta=self._xml_meta))
elif child.tag == Timestamp.qname:
self.timestamp = Timestamp.from_element(child, xml_meta=self._xml_meta)
def _build_element(self, element, nsmap):
self._build_extensions(element, nsmap)
if self.deviceID is not None:
self.deviceID.to_element(parent=element, nsmap=nsmap)
for note in self.notes:
note.to_element(parent=element, nsmap=nsmap)
if self.timestamp is not None:
self.timestamp.to_element(parent=element, nsmap=nsmap)
class Person(ExtensibleXMLElement, PIDFTopElement):
_xml_tag = 'person'
_xml_namespace = _namespace_
_xml_attrs = {'id': {'id_attribute': True}}
_xml_meta = PIDFMeta
_xml_ext_type = PersonExtension
def __init__(self, id, notes=[], timestamp=None, **kwargs):
ExtensibleXMLElement.__init__(self, **kwargs)
self.id = id
self.notes = NoteList()
for note in notes:
self.notes.append(note)
self.timestamp = timestamp
def _parse_element(self, element):
self.notes = NoteList()
self.timestamp = None
for child in element:
- if child.tag == Note.qname:
- self.notes.append(Note.from_element(child, xml_meta=self._xml_meta))
+ if child.tag == DMNote.qname:
+ self.notes.append(DMNote.from_element(child, xml_meta=self._xml_meta))
elif child.tag == Timestamp.qname:
self.timestamp = Timestamp.from_element(child, xml_meta=self._xml_meta)
def _build_element(self, element, nsmap):
self._build_extensions(element, nsmap)
for note in self.notes:
note.to_element(parent=element, nsmap=nsmap)
if self.timestamp is not None:
self.timestamp.to_element(parent=element, nsmap=nsmap)
class PresDMExtension(XMLExtension):
_xml_ext_def = [(Device, []),
- (Person, [])]
+ (Person, []),
+ (DeviceID, []),
+ (DMNote, [])]
_xml_namespace = _namespace_
_xml_prefix = 'dm'
_xml_schema_file = 'data-model.xsd'
PIDF.registerExtension(PresDMExtension)
diff --git a/pypjua/applications/rpid.py b/pypjua/applications/rpid.py
index 6f82c775..b3b336ff 100644
--- a/pypjua/applications/rpid.py
+++ b/pypjua/applications/rpid.py
@@ -1,361 +1,436 @@
"""RPID handling according to RFC4480
This module provides an extension to PIDF (module pypjua.applications.pidf) to
support rich presence.
"""
-from pypjua.applications import XMLExtension, XMLListElement, XMLEmptyElement, XMLStringElement, XMLChoiceElement, XMLGenerator
+from pypjua.applications import XMLExtension, XMLElement, XMLListElement, XMLEmptyElement, XMLStringElement, XMLChoiceElement
from pypjua.applications.pidf import PIDFTopElement, PIDF, PIDFMeta, TupleExtension, Timestamp, Note, NoteList, Tuple
from pypjua.applications.presdm import PersonExtension, DeviceExtension, Person, Device
__all__ = ['_namespace_',
- 'ActivityElement',
- 'MoodElement',
'PlaceTypeElement',
+ 'PrivacyElement',
+ 'RPIDNote',
'Activities',
'Mood',
'PlaceIs',
'Audio',
'Video',
'Text',
- 'Noisy',
- 'Quiet',
- 'TooBright',
- 'Dark',
- 'Uncomfortable',
- 'Inappropriate',
'PlaceType',
+ 'Privacy',
+ 'Relationship',
+ 'ServiceClass',
+ 'Sphere',
+ 'StatusIcon',
+ 'TimeOffset',
+ 'UserInput',
'Class',
- 'Ok',
- 'Unknown',
'Other']
_namespace_ = 'urn:ietf:params:xml:ns:pidf:rpid'
# Mixin types for extenisibility
-class ActivityElement(object): pass
-class MoodElement(object): pass
class PlaceTypeElement(object): pass
class PrivacyElement(object): pass
-# Mixin types just for internal use
-class AudioValueElement(object): pass
-class VideoValueElement(object): pass
-class TextValueElement(object): pass
+class RPIDNote(Note):
+ _xml_tag = 'note'
+ _xml_namespace = _namespace_
+ _xml_meta = PIDFMeta
-class Activities(XMLListElement, PersonExtension):
+class Activities(XMLChoiceElement, PersonExtension):
_xml_tag = 'activities'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
_xml_attrs = {'id': {'id_attribute': True},
'since': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp, 'xml_attribute': 'from'},
'until': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp}}
+ _xml_values = set(('appointment', 'away', 'breakfast', 'busy', 'dinner',
+ 'holiday', 'in transit', 'looking for work', 'meal', 'meeting',
+ 'on the phone', 'performance', 'permanent absence', 'playing',
+ 'presentation', 'shopping', 'sleeping', 'spectator', 'sterring',
+ 'travel', 'tv', 'vacation', 'working', 'worship', 'unknown'))
+ _xml_value_maps = {'in-transit': 'in transit', 'looking-for-work': 'looking for work',
+ 'on-the-phone': 'on the phone', 'permanent-absence': 'permanent absence'}
+ _xml_default_value = 'unknown'
+ _xml_allow_many = True
+ _xml_allow_other = True
def __init__(self, id=None, since=None, until=None, notes=[], activities=[]):
self.id = id
self.since = since
self.until = until
self.notes = NoteList()
- self[0:0] = activities
+ XMLChoiceElement.__init__(self, activities)
def _parse_element(self, element):
self.notes = NoteList()
for child in element:
- if child.tag == Note.qname:
+ if child.tag == RPIDNote.qname:
self.notes.append(Note.from_element(child, xml_meta=self._xml_meta))
- else:
- child_cls = self._xml_meta.get(child.tag)
- if child_cls is not None:
- self.append(child_cls.from_element(child, xml_meta=self._xml_meta))
+ element.remove(child)
+ XMLChoiceElement._parse_element(self, element)
def _build_element(self, element, nsmap):
for note in self.notes:
note.to_element(parent=element, nsmap=nsmap)
- for child in self:
- child.to_element(parent=element, nsmap=nsmap)
-
- def _before_add(self, value):
- if not isinstance(value, ActivityElement):
- raise TypeError("Activities elements can only contain ActivityElement children, got %s instead" % value.__class__.__name__)
- return value
+ XMLChoiceElement._build_element(self, element, nsmap)
-class ActivitiesGenerator(XMLGenerator):
- _xml_namespace = _namespace_
- _xml_meta = PIDFMeta
- _xml_bases = (XMLEmptyElement, ActivityElement)
- _xml_name_prefix = 'Activity'
- _xml_names = ['appointment', 'away', 'breakfast', 'busy', 'dinner',
- 'holiday', 'in-transit', 'looking-for-work', 'meal', 'meeting',
- 'on-the-phone', 'performance', 'permanent-absence', 'playing',
- 'presentation', 'shopping', 'sleeping', 'spectator', 'sterring',
- 'travel', 'tv', 'vacation', 'working', 'worship']
-
-class Mood(XMLListElement, PersonExtension):
+class Mood(XMLChoiceElement, PersonExtension):
_xml_tag = 'mood'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
_xml_attrs = {'id': {'id_attribute': True},
'since': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp, 'xml_attribute': 'from'},
'until': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp}}
+ _xml_values = set(('afraid', 'amazed', 'angry', 'annoyed', 'anxious', 'ashamed',
+ 'bored', 'brave', 'calm', 'cold', 'confused', 'contended',
+ 'cranky', 'curious', 'depressed', 'disappointed', 'disgusted',
+ 'distracted', 'embarrassed', 'excited', 'flirtatious',
+ 'frustrated', 'grumpy', 'guilty', 'happy', 'hot', 'humbled',
+ 'humiliated', 'hungry', 'hurt', 'impressed', 'in awe',
+ 'in_love', 'indignant', 'interested', 'invisible', 'jealous',
+ 'lonely', 'mean', 'moody', 'nervous', 'neutral', 'offended',
+ 'playful', 'proud', 'relieved', 'remorseful', 'restless',
+ 'sad', 'sarcastic', 'serious', 'shocked', 'shy', 'sick',
+ 'sleepy', 'stressed', 'surprised', 'thirsty', 'worried', 'unknown'))
+ _xml_value_maps = {'in_awe': 'in awe', 'in_love': 'in love'}
+ _xml_default_value = 'unknown'
+ _xml_allow_many = True
+ _xml_allow_other = True
def __init__(self, id=None, since=None, until=None, notes=[], moods=[]):
self.id = id
self.since = since
self.until = until
self.notes = NoteList()
- self[0:0] = moods
+ XMLChoiceElement.__init__(self, moods)
def _parse_element(self, element):
self.notes = NoteList()
for child in element:
- if child.tag == Note.qname:
+ if child.tag == RPIDNote.qname:
self.notes.append(Note.from_element(child, xml_meta=self._xml_meta))
- else:
- child_cls = self._xml_meta.get(child.tag)
- if child_cls is not None:
- self.append(child_cls.from_element(child, xml_meta=self._xml_meta))
+ element.remove(child)
+ XMLChoiceElement._parse_element(self, element)
def _build_element(self, element, nsmap):
for note in self.notes:
note.to_element(parent=element, nsmap=nsmap)
- for child in self:
- child.to_element(parent=element, nsmap=nsmap)
-
- def _before_add(self, value):
- if not isinstance(value, MoodElement):
- raise TypeError("Mood elements can only contain MoodElement children, got %s instead" % value.__class__.__name__)
- return value
-
-class MoodsGenerator(XMLGenerator):
- _xml_namespace = _namespace_
- _xml_meta = PIDFMeta
- _xml_bases = (XMLEmptyElement, MoodElement)
- _xml_name_prefix = 'Mood'
- _xml_names = ['afraid', 'amazed', 'angry', 'annoyed', 'anxious', 'ashamed',
- 'bored', 'brave', 'calm', 'cold', 'confused', 'contended',
- 'cranky', 'curious', 'depressed', 'disappointed', 'disgusted',
- 'distracted', 'embarrassed', 'excited', 'flirtatious',
- 'frustrated', 'grumpy', 'guilty', 'happy', 'hot', 'humbled',
- 'humiliated', 'hungry', 'hurt', 'impressed', 'in_awe',
- 'in_love', 'indignant', 'interested', 'invisible', 'jealous',
- 'lonely', 'mean', 'moody', 'nervous', 'neutral', 'offended',
- 'playful', 'proud', 'relieved', 'remorseful', 'restless',
- 'sad', 'sarcastic', 'serious', 'shocked', 'shy', 'sick',
- 'sleepy', 'stressed', 'surprised', 'thirsty', 'worried']
-
-class Noisy(XMLEmptyElement, AudioValueElement):
- _xml_tag = 'noisy'
- _xml_namespace = _namespace_
- _xml_meta = PIDFMeta
-
-class Quiet(XMLEmptyElement, AudioValueElement):
- _xml_tag = 'quiet'
- _xml_namespace = _namespace_
- _xml_meta = PIDFMeta
-
-class TooBright(XMLEmptyElement, VideoValueElement):
- _xml_tag = 'toobright'
- _xml_namespace = _namespace_
- _xml_meta = PIDFMeta
-
-class Dark(XMLEmptyElement, VideoValueElement):
- _xml_tag = 'dark'
- _xml_namespace = _namespace_
- _xml_meta = PIDFMeta
-
-class Uncomfortable(XMLEmptyElement, TextValueElement):
- _xml_tag = 'uncomfortable'
- _xml_namespace = _namespace_
- _xml_meta = PIDFMeta
-
-class Inappropriate(XMLEmptyElement, TextValueElement):
- _xml_tag = 'inappropriate'
- _xml_namespace = _namespace_
- _xml_meta = PIDFMeta
+ XMLChoiceElement._build_element(self, element, nsmap)
class Audio(XMLChoiceElement):
_xml_tag = 'audio'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
- _xml_type = AudioValueElement
+ _xml_values = set(('noisy', 'ok', 'quiet', 'unknown'))
+ _xml_default_value = 'unknown'
+ _xml_allow_many = False
+ _xml_allow_other = False
class Video(XMLChoiceElement):
_xml_tag = 'video'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
- _xml_type = VideoValueElement
+ _xml_values = set(('toobright', 'ok', 'dark', 'unknown'))
+ _xml_default_value = 'unknown'
+ _xml_allow_many = False
+ _xml_allow_other = False
class Text(XMLChoiceElement):
_xml_tag = 'text'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
- _xml_type = TextValueElement
+ _xml_values = set(('uncomfortable', 'inappropriate', 'ok', 'unknown'))
+ _xml_default_value = 'unknown'
+ _xml_allow_many = False
+ _xml_allow_other = False
class PlaceIs(XMLElement, PersonExtension):
_xml_tag = 'place-is'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
_xml_attrs = {'id': {'id_attribute': True},
'since': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp, 'xml_attribute': 'from'},
'until': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp}}
def __init__(self, id=None, since=None, until=None, audio=None, video=None, text=None, notes=[]):
self.id = id
self.since = since
self.until = until
self.audio = audio
self.video = video
self.text = text
self.notes = NoteList()
def _parse_element(self, element):
self.notes = NoteList()
for child in element:
- if child.tag == Note.qname:
+ if child.tag == RPIDNote.qname:
self.notes.append(Note.from_element(child, xml_meta=self._xml_meta))
elif child.tag == Audio.qname:
self.audio = Audio.from_element(child, xml_meta=self._xml_meta)
elif child.tag == Video.qname:
self.video = Video.from_element(child, xml_meta=self._xml_meta)
elif child.tag == Text.qname:
self.text = Text.from_element(child, xml_meta=self._xml_meta)
def _build_element(self, element, nsmap):
for note in self.notes:
note.to_element(parent=element, nsmap=nsmap)
- for child in self:
- child.to_element(parent=element, nsmap=nsmap)
class PlaceType(XMLListElement, PersonExtension):
_xml_tag = 'place-type'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
_xml_attrs = {'id': {'id_attribute': True},
'since': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp, 'xml_attribute': 'from'},
'until': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp}}
def __init__(self, id=None, since=None, until=None, notes=[], placetypes=[]):
self.id = id
self.since = since
self.until = until
self.notes = NoteList()
self[0:0] = placetypes
def _parse_element(self, element):
self.notes = NoteList()
for child in element:
- if child.tag == Note.qname:
+ if child.tag == RPIDNote.qname:
self.notes.append(Note.from_element(child, xml_meta=self._xml_meta))
else:
child_cls = self._xml_meta.get(child.tag)
if child_cls is not None:
self.append(child_cls.from_element(child, xml_meta=self._xml_meta))
def _build_element(self, element, nsmap):
for note in self.notes:
note.to_element(parent=element, nsmap=nsmap)
for child in self:
child.to_element(parent=element, nsmap=nsmap)
def _before_add(self, value):
if not isinstance(value, PlaceTypeElement):
raise TypeError("PlaceType elements can only contain PlaceTypeElement children, got %s instead" % value.__class__.__name__)
return value
+class Other(XMLStringElement, PlaceTypeElement):
+ _xml_tag = 'other'
+ _xml_namespace = _namespace_
+ _xml_meta = PIDFMeta
+ _xml_lang = True
+
class Privacy(XMLListElement, PersonExtension):
_xml_tag = 'privacy'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
_xml_attrs = {'id': {'id_attribute': True},
'since': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp, 'xml_attribute': 'from'},
'until': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp}}
def __init__(self, id=None, since=None, until=None, notes=[], audio=False, text=False, video=False, privacy=[]):
self.id = id
self.since = since
self.until = until
self.notes = NoteList()
self.audio = audio
self.text = text
self.video = video
self[0:0] = privacy
def _parse_element(self, element):
self.notes = NoteList()
self.audio = False
self.text = False
self.video = False
for child in element:
- if child.tag == Note.qname:
+ if child.tag == RPIDNote.qname:
self.notes.append(Note.from_element(child, xml_meta=self._xml_meta))
elif child.tag == '{%s}audio' % _namespace_:
self.audio = True
elif child.tag == '{%s}text' % _namespace_:
self.text = True
elif child.tag == '{%s}video' % _namespace_:
self.video = True
else:
child_cls = self._xml_meta.get(child.tag)
if child_cls is not None:
self.append(child_cls.from_element(child, xml_meta=self._xml_meta))
def _build_element(self, element, nsmap):
for note in self.notes:
note.to_element(parent=element, nsmap=nsmap)
if len(self) == 0 and not self.audio and not self.text and not self.video:
etree.SubElement(element, '{%s}unknown' % _namespace_, nsmap=nsmap)
else:
if self.audio:
etree.SubElement(element, '{%s}audio' % _namespace_, nsmap=nsmap)
if self.text:
etree.SubElement(element, '{%s}text' % _namespace_, nsmap=nsmap)
if self.video:
etree.SubElement(element, '{%s}video' % _namespace_, nsmap=nsmap)
for child in self:
child.to_element(parent=element, nsmap=nsmap)
def _before_add(self, value):
if not isinstance(value, PrivacyElement):
raise TypeError("Privacy elements can only contain PrivacyElement children, got %s instead" % value.__class__.__name__)
return value
-class Class(XMLStringElement, TupleExtension, PersonExtension, DeviceExtension):
- _xml_tag = 'class'
+class Relationship(XMLChoiceElement, TupleExtension):
+ _xml_tag = 'relationship'
+ _xml_namespace = _namespace_
+ _xml_meta = PIDFMeta
+ _xml_values = set(('assistant', 'associate', 'family', 'friend', 'self',
+ 'supervisor', 'unknown'))
+ _xml_default_value = 'self'
+ _xml_allow_many = False
+ _xml_allow_other = True
+
+ def __init__(self, relationship=None, notes=[]):
+ self.notes = NoteList()
+ Relationship.__init__(self, (relationship is None) and [] or [relationship])
+
+ def _parse_element(self, element):
+ self.notes = NoteList()
+ for child in element:
+ if child.tag == RPIDNote.qname:
+ self.notes.append(Note.from_element(child, xml_meta=self._xml_meta))
+ element.remove(child)
+ XMLChoiceElement._parse_element(self, element)
+
+ def _build_element(self, element, nsmap):
+ for note in self.notes:
+ note.to_element(parent=element, nsmap=nsmap)
+ XMLChoiceElement._build_element(self, element, nsmap)
+
+class ServiceClass(XMLChoiceElement, TupleExtension):
+ _xml_tag = 'service-class'
+ _xml_namespace = _namespace_
+ _xml_meta = PIDFMeta
+ _xml_values = set(('courier', 'electronic', 'freight', 'in person', 'postal', 'unknown'))
+ _xml_default_value = 'unknown'
+ _xml_allow_many = False
+ _xml_allow_other = False
+
+ def __init__(self, service_class=None, notes=[]):
+ self.notes = NoteList()
+ Relationship.__init__(self, (service_class is None) and [] or [service_class])
+
+ def _parse_element(self, element):
+ self.notes = NoteList()
+ for child in element:
+ if child.tag == RPIDNote.qname:
+ self.notes.append(Note.from_element(child, xml_meta=self._xml_meta))
+ element.remove(child)
+ XMLChoiceElement._parse_element(self, element)
+
+ def _build_element(self, element, nsmap):
+ for note in self.notes:
+ note.to_element(parent=element, nsmap=nsmap)
+ XMLChoiceElement._build_element(self, element, nsmap)
+
+class Sphere(XMLChoiceElement, PersonExtension):
+ _xml_tag = 'sphere'
+ _xml_namespace = _namespace_
+ _xml_meta = PIDFMeta
+ _xml_attrs = {'id': {'id_attribute': True},
+ 'since': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp, 'xml_attribute': 'from'},
+ 'until': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp}}
+ _xml_values = set(('home', 'work', 'unknown'))
+ _xml_default_value = 'unknown'
+ _xml_allow_many = False
+ _xml_allow_other = False
+
+ def __init__(self, sphere=None, id=None, since=None, until=None):
+ self.id = id
+ self.since = since
+ self.until = until
+ XMLChoiceElement.__init__(self, (sphere is None) and [] or [sphere])
+
+class StatusIcon(XMLStringElement, TupleExtension, PersonExtension):
+ _xml_tag = 'status-icon'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
_xml_lang = False
+ _xml_attrs = {'id': {'id_attribute': True},
+ 'since': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp, 'xml_attribute': 'from'},
+ 'until': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp}}
+
+ def __init__(self, value=None, id=None, since=None, until=None):
+ self.id = id
+ self.since = since
+ self.until = until
+ XMLStringElement.__init__(self, value)
-class Other(XMLStringElement, ActivityElement, MoodElement, PlaceTypeElement):
- _xml_tag = 'other'
+class TimeOffset(XMLStringElement, PersonExtension):
+ _xml_tag = 'time-offset'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
- _xml_lang = True
+ _xml_lang = False
+ _xml_attrs = {'id': {'id_attribute': True},
+ 'since': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp, 'xml_attribute': 'from'},
+ 'until': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp},
+ 'description': {}}
+
+ def __init__(self, value=None, description=None, id=None, since=None, until=None):
+ self.id = id
+ self.since = since
+ self.until = until
+ self.description = description
+ XMLStringElement.__init__(self, str(value))
-class Ok(XMLEmptyElement, AudioValueElement, VideoValueElement, TextValueElement):
- _xml_tag = 'ok'
+class UserInput(XMLStringElement, TupleExtension, PersonExtension, DeviceExtension):
+ _xml_tag = 'user-input'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
_xml_lang = False
+ _xml_values = ('active', 'idle')
+ _xml_attrs = {'id': {'id_attribute': True},
+ 'last_input': {'parse': Timestamp.parse_timestamp, 'build': Timestamp.format_timestamp, 'xml_attribute': 'last-input'},
+ 'idle_threshold': {'xml_attribute': 'idle-threshold'}}
+
+ def __init__(self, value=None, id=None, last_input=None, idle_threshold=None):
+ self.id = id
+ self.last_input = since
+ self.idle_threshold = idle_threshold
+ XMLStringElement.__init__(self, value)
-class Unknown(XMLEmptyElement, ActivityElement, MoodElement, AudioValueElement, VideoValueElement, TextValueElement):
- _xml_tag = 'unknown'
+class Class(XMLStringElement, TupleExtension, PersonExtension, DeviceExtension):
+ _xml_tag = 'class'
_xml_namespace = _namespace_
_xml_meta = PIDFMeta
_xml_lang = False
class RPIDExtension(XMLExtension):
_xml_ext_def = [(Activities, [(Person, {'attribute': 'activities'})]),
(Mood, [(Person, {'attribute': 'mood'})]),
- (PlaceIs, [(Person, {'attribute': 'placeis'})]),
- (PlaceType, [(Person, {'attribute': 'placetype'})]),
+ (PlaceIs, [(Person, {'attribute': 'place_is'})]),
+ (PlaceType, [(Person, {'attribute': 'place_type'})]),
(Privacy, [(Person, {'attribute': 'privacy'})]),
- (Class, [(Tuple, {'attribute': 'class'}),
- (Person, {'attribute': 'class'}),
- (Device, {'attribute': 'class'})]),
+ (Relationship, [(Tuple, {'attribute': 'relationship'})]),
+ (ServiceClass, [(Tuple, {'attribute': 'service_class'})]),
+ (Sphere, [(Person, {'attribute': 'sphere'})]),
+ (StatusIcon, [(Tuple, {'attribute': 'status_icon'}),
+ (Person, {'attribute': 'status_icon'})]),
+ (TimeOffset, [(Person, {'attribute': 'time_offset'})]),
+ (UserInput, [(Tuple, {'attribute': 'user_input'}),
+ (Person, {'attribute': 'user_input'}),
+ (Device, {'attribute': 'user_input'})]),
+ (Class, [(Tuple, {'attribute': 'rpid_class'}),
+ (Person, {'attribute': 'rpid_class'}),
+ (Device, {'attribute': 'rpid_class'})]),
+ (RPIDNote, []),
+ (Audio, []),
+ (Video, []),
+ (Text, []),
(Other, [])]
_xml_namespace = _namespace_
_xml_prefix = 'rpid'
_xml_schema_file = 'rpid.xsd'
PIDF.registerExtension(RPIDExtension)
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Dec 28, 7:19 PM (1 d, 6 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3454343
Default Alt Text
(39 KB)
Attached To
Mode
rPYNSIPSIMPLE python3-sipsimple
Attached
Detach File
Event Timeline
Log In to Comment