Page MenuHomePhabricator

No OneTemporary

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

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)

Event Timeline