Ejemplo n.º 1
0
 def __init__(self, *args, **kwargs):
     """Set keys to upper for initial dict.
     """
     CaselessDict.__init__(self, *args, **kwargs)
     # set parameters here for properties that use non-default values
     self.subcomponents = []  # Components can be nested.
     self.is_broken = False  # True if we ignored an exception while
Ejemplo n.º 2
0
 def __init__(self, *args, **kwargs):
     """Set keys to upper for initial dict.
     """
     CaselessDict.__init__(self, *args, **kwargs)
     # set parameters here for properties that use non-default values
     self.subcomponents = []  # Components can be nested.
     self.is_broken = False  # True if we ignored an exception while
Ejemplo n.º 3
0
 def __init__(self, *args, **kwargs):
     "Set keys to upper for initial dict"
     CaselessDict.__init__(self, *args, **kwargs)
     self['VEVENT'] = Event
     self['VTODO'] = Todo
     self['VJOURNAL'] = Journal
     self['VFREEBUSY'] = FreeBusy
     self['VTIMEZONE'] = Timezone
     self['VALARM'] = Alarm
     self['VCALENDAR'] = Calendar
Ejemplo n.º 4
0
 def __init__(self, *args, **kwargs):
     "Set keys to upper for initial dict"
     CaselessDict.__init__(self, *args, **kwargs)
     self['VEVENT'] = Event
     self['VTODO'] = Todo
     self['VJOURNAL'] = Journal
     self['VFREEBUSY'] = FreeBusy
     self['VTIMEZONE'] = Timezone
     self['VALARM'] = Alarm
     self['VCALENDAR'] = Calendar
Ejemplo n.º 5
0
 def __init__(self, *args, **kwargs):
     "Set keys to upper for initial dict"
     CaselessDict.__init__(self, *args, **kwargs)
     self["VEVENT"] = Event
     self["VTODO"] = Todo
     self["VJOURNAL"] = Journal
     self["VFREEBUSY"] = FreeBusy
     self["VTIMEZONE"] = Timezone
     self["VALARM"] = Alarm
     self["VCALENDAR"] = Calendar
Ejemplo n.º 6
0
class vWeekday(compat.unicode_type):
    """This returns an unquoted weekday abbrevation.
    """
    week_days = CaselessDict({
        "SU": 0, "MO": 1, "TU": 2, "WE": 3, "TH": 4, "FR": 5, "SA": 6,
    })

    def __new__(cls, value, encoding=DEFAULT_ENCODING):
        value = to_unicode(value, encoding=encoding)
        self = super(vWeekday, cls).__new__(cls, value)
        match = WEEKDAY_RULE.match(self)
        if match is None:
            raise ValueError('Expected weekday abbrevation, got: %s' % self)
        match = match.groupdict()
        sign = match['signal']
        weekday = match['weekday']
        relative = match['relative']
        if weekday not in vWeekday.week_days or sign not in '+-':
            raise ValueError('Expected weekday abbrevation, got: %s' % self)
        self.relative = relative and int(relative) or None
        self.params = Parameters()
        return self

    def to_ical(self):
        return self.encode(DEFAULT_ENCODING).upper()

    @classmethod
    def from_ical(cls, ical):
        try:
            return cls(ical.upper())
        except:
            raise ValueError('Expected weekday abbrevation, got: %s' % ical)
Ejemplo n.º 7
0
class vFrequency(compat.unicode_type):
    """A simple class that catches illegal values.
    """

    frequencies = CaselessDict({
        "SECONDLY": "SECONDLY",
        "MINUTELY": "MINUTELY",
        "HOURLY": "HOURLY",
        "DAILY": "DAILY",
        "WEEKLY": "WEEKLY",
        "MONTHLY": "MONTHLY",
        "YEARLY": "YEARLY",
    })

    def __new__(cls, value, encoding=DEFAULT_ENCODING):
        value = to_unicode(value, encoding=encoding)
        self = super(vFrequency, cls).__new__(cls, value)
        if not self in vFrequency.frequencies:
            raise ValueError('Expected frequency, got: %s' % self)
        self.params = Parameters()
        return self

    def to_ical(self):
        return self.encode(DEFAULT_ENCODING).upper()

    @classmethod
    def from_ical(cls, ical):
        try:
            return cls(ical.upper())
        except:
            raise ValueError('Expected frequency, got: %s' % ical)
Ejemplo n.º 8
0
 def __init__(self, *args, **kwargs):
     "Set keys to upper for initial dict"
     CaselessDict.__init__(self, *args, **kwargs)
     self['binary'] = vBinary
     self['boolean'] = vBoolean
     self['cal-address'] = vCalAddress
     self['date'] = vDDDTypes
     self['date-time'] = vDDDTypes
     self['duration'] = vDDDTypes
     self['float'] = vFloat
     self['integer'] = vInt
     self['period'] = vPeriod
     self['recur'] = vRecur
     self['text'] = vText
     self['time'] = vTime
     self['uri'] = vUri
     self['utc-offset'] = vUTCOffset
     self['geo'] = vGeo
     self['inline'] = vInline
Ejemplo n.º 9
0
 def __init__(self, *args, **kwargs):
     "Set keys to upper for initial dict"
     CaselessDict.__init__(self, *args, **kwargs)
     self['binary'] = vBinary
     self['boolean'] = vBoolean
     self['cal-address'] = vCalAddress
     self['date'] = vDDDTypes
     self['date-time'] = vDDDTypes
     self['duration'] = vDDDTypes
     self['float'] = vFloat
     self['integer'] = vInt
     self['period'] = vPeriod
     self['recur'] = vRecur
     self['text'] = vText
     self['time'] = vTime
     self['uri'] = vUri
     self['utc-offset'] = vUTCOffset
     self['geo'] = vGeo
     self['inline'] = vInline
Ejemplo n.º 10
0
 def __init__(self, *args, **kwargs):
     "Set keys to upper for initial dict"
     CaselessDict.__init__(self, *args, **kwargs)
     self.all_types = (
         vBinary,
         vBoolean,
         vCalAddress,
         vDDDLists,
         vDDDTypes,
         vDate,
         vDatetime,
         vDuration,
         vFloat,
         vFrequency,
         vGeo,
         vInline,
         vInt,
         vPeriod,
         vRecur,
         vText,
         vTime,
         vUTCOffset,
         vUri,
         vWeekday
     )
     self['binary'] = vBinary
     self['boolean'] = vBoolean
     self['cal-address'] = vCalAddress
     self['date'] = vDDDTypes
     self['date-time'] = vDDDTypes
     self['duration'] = vDDDTypes
     self['float'] = vFloat
     self['integer'] = vInt
     self['period'] = vPeriod
     self['recur'] = vRecur
     self['text'] = vText
     self['time'] = vTime
     self['uri'] = vUri
     self['utc-offset'] = vUTCOffset
     self['geo'] = vGeo
     self['inline'] = vInline
     self['date-time-list'] = vDDDLists
Ejemplo n.º 11
0
 def __init__(self, *args, **kwargs):
     "Set keys to upper for initial dict"
     CaselessDict.__init__(self, *args, **kwargs)
     self["binary"] = vBinary
     self["boolean"] = vBoolean
     self["cal-address"] = vCalAddress
     self["date"] = vDDDTypes
     self["date-time"] = vDDDTypes
     self["duration"] = vDDDTypes
     self["float"] = vFloat
     self["integer"] = vInt
     self["period"] = vPeriod
     self["recur"] = vRecur
     self["text"] = vText
     self["time"] = vTime
     self["uri"] = vUri
     self["utc-offset"] = vUTCOffset
     self["geo"] = vGeo
     self["inline"] = vInline
     self["date-time-list"] = vDDDLists
Ejemplo n.º 12
0
 def __init__(self, *args, **kwargs):
     "Set keys to upper for initial dict"
     CaselessDict.__init__(self, *args, **kwargs)
     self.all_types = (vBinary, vBoolean, vCalAddress, vDDDLists, vDDDTypes,
                       vDate, vDatetime, vDuration, vFloat, vFrequency,
                       vGeo, vInline, vInt, vPeriod, vRecur, vText, vTime,
                       vUTCOffset, vUri, vWeekday)
     self['binary'] = vBinary
     self['boolean'] = vBoolean
     self['cal-address'] = vCalAddress
     self['date'] = vDDDTypes
     self['date-time'] = vDDDTypes
     self['duration'] = vDDDTypes
     self['float'] = vFloat
     self['integer'] = vInt
     self['period'] = vPeriod
     self['recur'] = vRecur
     self['text'] = vText
     self['time'] = vTime
     self['uri'] = vUri
     self['utc-offset'] = vUTCOffset
     self['geo'] = vGeo
     self['inline'] = vInline
     self['date-time-list'] = vDDDLists
Ejemplo n.º 13
0
class vFrequency(str):
    """
    A simple class that catches illegal values.
    >>> f = vFrequency('bad test')
    Traceback (most recent call last):
        ...
    ValueError: Expected frequency, got: BAD TEST
    >>> vFrequency('daily').ical()
    'DAILY'
    >>> vFrequency('daily').from_ical('MONTHLY')
    'MONTHLY'
    """

    frequencies = CaselessDict({
        "SECONDLY": "SECONDLY",
        "MINUTELY": "MINUTELY",
        "HOURLY": "HOURLY",
        "DAILY": "DAILY",
        "WEEKLY": "WEEKLY",
        "MONTHLY": "MONTHLY",
        "YEARLY": "YEARLY",
    })

    def __new__(cls, *args, **kwargs):
        self = super(vFrequency, cls).__new__(cls, *args, **kwargs)
        if not self in vFrequency.frequencies:
            raise ValueError, 'Expected frequency, got: %s' % self
        self.params = Parameters()
        return self

    def ical(self):
        return self.upper()

    def from_ical(ical):
        "Parses the data format from ical text format"
        try:
            return vFrequency(ical.upper())
        except:
            raise ValueError, 'Expected weekday abbrevation, got: %s' % ical

    from_ical = staticmethod(from_ical)

    def __str__(self):
        return self.ical()
Ejemplo n.º 14
0
class vBoolean(int):
    """Returns specific string according to state.
    """
    BOOL_MAP = CaselessDict(true=True, false=False)

    def __new__(cls, *args, **kwargs):
        self = super(vBoolean, cls).__new__(cls, *args, **kwargs)
        self.params = Parameters()
        return self

    def to_ical(self):
        if self:
            return b'TRUE'
        return b'FALSE'

    @classmethod
    def from_ical(cls, ical):
        try:
            return cls.BOOL_MAP[ical]
        except:
            raise ValueError("Expected 'TRUE' or 'FALSE'. Got %s" % ical)
Ejemplo n.º 15
0
class vBoolean(int):
    """
    Returns specific string according to state
    >>> bin = vBoolean(True)
    >>> bin.ical()
    'TRUE'
    >>> bin = vBoolean(0)
    >>> bin.ical()
    'FALSE'

    The roundtrip test
    >>> x = True
    >>> x == vBoolean.from_ical(vBoolean(x).ical())
    True
    >>> vBoolean.from_ical('true')
    True
    """
    def __new__(cls, *args, **kwargs):
        self = super(vBoolean, cls).__new__(cls, *args, **kwargs)
        self.params = Parameters()
        return self

    def ical(self):
        if self:
            return 'TRUE'
        return 'FALSE'

    bool_map = CaselessDict(true=True, false=False)

    def from_ical(ical):
        "Parses the data format from ical text format"
        try:
            return vBoolean.bool_map[ical]
        except:
            raise ValueError, "Expected 'TRUE' or 'FALSE'. Got %s" % ical

    from_ical = staticmethod(from_ical)

    def __str__(self):
        return self.ical()
class vRecur(CaselessDict):
    """
    Let's see how close we can get to one from the rfc:
    FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;BYMINUTE=30

    >>> r = dict(freq='yearly', interval=2)
    >>> r['bymonth'] = 1
    >>> r['byday'] = 'su'
    >>> r['byhour'] = [8,9]
    >>> r['byminute'] = 30
    >>> r = vRecur(r)
    >>> r.ical()
    'BYHOUR=8,9;BYDAY=SU;BYMINUTE=30;BYMONTH=1;FREQ=YEARLY;INTERVAL=2'

    >>> r = vRecur(FREQ='yearly', INTERVAL=2)
    >>> r['BYMONTH'] = 1
    >>> r['BYDAY'] = 'su'
    >>> r['BYHOUR'] = [8,9]
    >>> r['BYMINUTE'] = 30
    >>> r.ical()
    'BYDAY=SU;BYMINUTE=30;BYMONTH=1;INTERVAL=2;FREQ=YEARLY;BYHOUR=8,9'

    >>> r = vRecur(freq='DAILY', count=10)
    >>> r['bysecond'] = [0, 15, 30, 45]
    >>> r.ical()
    'COUNT=10;FREQ=DAILY;BYSECOND=0,15,30,45'

    >>> r = vRecur(freq='DAILY', until=datetime(2005,1,1,12,0,0))
    >>> r.ical()
    'FREQ=DAILY;UNTIL=20050101T120000'

    How do we fare with regards to parsing?
    >>> r = vRecur.from_ical('FREQ=DAILY;INTERVAL=2;COUNT=10')
    >>> r
    {'COUNT': [10], 'FREQ': ['DAILY'], 'INTERVAL': [2]}
    >>> vRecur(r).ical()
    'COUNT=10;FREQ=DAILY;INTERVAL=2'

    >>> r = vRecur.from_ical('FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=-SU;BYHOUR=8,9;BYMINUTE=30')
    >>> r
    {'BYHOUR': [8, 9], 'BYDAY': ['-SU'], 'BYMINUTE': [30], 'BYMONTH': [1], 'FREQ': ['YEARLY'], 'INTERVAL': [2]}
    >>> vRecur(r).ical()
    'BYDAY=-SU;BYMINUTE=30;INTERVAL=2;BYMONTH=1;FREQ=YEARLY;BYHOUR=8,9'

    Some examples from the spec

    >>> r = vRecur.from_ical('FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1')
    >>> vRecur(r).ical()
    'BYSETPOS=-1;FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR'

    >>> r = vRecur.from_ical('FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9;BYMINUTE=30')
    >>> vRecur(r).ical()
    'BYDAY=SU;BYMINUTE=30;INTERVAL=2;BYMONTH=1;FREQ=YEARLY;BYHOUR=8,9'

    and some errors
    >>> r = vRecur.from_ical('BYDAY=12')
    Traceback (most recent call last):
        ...
    ValueError: Error in recurrence rule: BYDAY=12

    """

    frequencies = [
        "SECONDLY", "MINUTELY", "HOURLY", "DAILY", "WEEKLY", "MONTHLY",
        "YEARLY"
    ]

    types = CaselessDict({
        'COUNT': vInt,
        'INTERVAL': vInt,
        'BYSECOND': vInt,
        'BYMINUTE': vInt,
        'BYHOUR': vInt,
        'BYMONTHDAY': vInt,
        'BYYEARDAY': vInt,
        'BYMONTH': vInt,
        'UNTIL': vDDDTypes,
        'BYSETPOS': vInt,
        'WKST': vWeekday,
        'BYDAY': vWeekday,
        'FREQ': vFrequency
    })

    def __init__(self, *args, **kwargs):
        CaselessDict.__init__(self, *args, **kwargs)
        self.params = Parameters()

    def ical(self):
        # SequenceTypes
        result = []
        for key, vals in self.items():
            typ = self.types[key]
            if not type(vals) in SequenceTypes:
                vals = [vals]
            vals = ','.join([typ(val).ical() for val in vals])
            result.append('%s=%s' % (key, vals))
        return ';'.join(result)

    def parse_type(key, values):
        # integers
        parser = vRecur.types.get(key, vText)
        return [parser.from_ical(v) for v in values.split(',')]

    parse_type = staticmethod(parse_type)

    def from_ical(ical):
        "Parses the data format from ical text format"
        try:
            recur = vRecur()
            for pairs in ical.split(';'):
                key, vals = pairs.split('=')
                recur[key] = vRecur.parse_type(key, vals)
            return dict(recur)
        except:
            raise ValueError, 'Error in recurrence rule: %s' % ical

    from_ical = staticmethod(from_ical)

    def __str__(self):
        return self.ical()
Ejemplo n.º 17
0
class TypesFactory(CaselessDict):
    """All Value types defined in rfc 2445 are registered in this factory
    class.

    The value and parameter names don't overlap. So one factory is enough for
    both kinds.
    """
    def __init__(self, *args, **kwargs):
        "Set keys to upper for initial dict"
        CaselessDict.__init__(self, *args, **kwargs)
        self.all_types = (vBinary, vBoolean, vCalAddress, vDDDLists, vDDDTypes,
                          vDate, vDatetime, vDuration, vFloat, vFrequency,
                          vGeo, vInline, vInt, vPeriod, vRecur, vText, vTime,
                          vUTCOffset, vUri, vWeekday)
        self['binary'] = vBinary
        self['boolean'] = vBoolean
        self['cal-address'] = vCalAddress
        self['date'] = vDDDTypes
        self['date-time'] = vDDDTypes
        self['duration'] = vDDDTypes
        self['float'] = vFloat
        self['integer'] = vInt
        self['period'] = vPeriod
        self['recur'] = vRecur
        self['text'] = vText
        self['time'] = vTime
        self['uri'] = vUri
        self['utc-offset'] = vUTCOffset
        self['geo'] = vGeo
        self['inline'] = vInline
        self['date-time-list'] = vDDDLists

    #################################################
    # Property types

    # These are the default types
    types_map = CaselessDict({
        ####################################
        # Property value types
        # Calendar Properties
        'calscale': 'text',
        'method': 'text',
        'prodid': 'text',
        'version': 'text',
        # Descriptive Component Properties
        'attach': 'uri',
        'categories': 'text',
        'class': 'text',
        'comment': 'text',
        'description': 'text',
        'geo': 'geo',
        'location': 'text',
        'percent-complete': 'integer',
        'priority': 'integer',
        'resources': 'text',
        'status': 'text',
        'summary': 'text',
        # Date and Time Component Properties
        'completed': 'date-time',
        'dtend': 'date-time',
        'due': 'date-time',
        'dtstart': 'date-time',
        'duration': 'duration',
        'freebusy': 'period',
        'transp': 'text',
        # Time Zone Component Properties
        'tzid': 'text',
        'tzname': 'text',
        'tzoffsetfrom': 'utc-offset',
        'tzoffsetto': 'utc-offset',
        'tzurl': 'uri',
        # Relationship Component Properties
        'attendee': 'cal-address',
        'contact': 'text',
        'organizer': 'cal-address',
        'recurrence-id': 'date-time',
        'related-to': 'text',
        'url': 'uri',
        'uid': 'text',
        # Recurrence Component Properties
        'exdate': 'date-time-list',
        'exrule': 'recur',
        'rdate': 'date-time-list',
        'rrule': 'recur',
        # Alarm Component Properties
        'action': 'text',
        'repeat': 'integer',
        'trigger': 'duration',
        # Change Management Component Properties
        'created': 'date-time',
        'dtstamp': 'date-time',
        'last-modified': 'date-time',
        'sequence': 'integer',
        # Miscellaneous Component Properties
        'request-status': 'text',
        ####################################
        # parameter types (luckily there is no name overlap)
        'altrep': 'uri',
        'cn': 'text',
        'cutype': 'text',
        'delegated-from': 'cal-address',
        'delegated-to': 'cal-address',
        'dir': 'uri',
        'encoding': 'text',
        'fmttype': 'text',
        'fbtype': 'text',
        'language': 'text',
        'member': 'cal-address',
        'partstat': 'text',
        'range': 'text',
        'related': 'text',
        'reltype': 'text',
        'role': 'text',
        'rsvp': 'boolean',
        'sent-by': 'cal-address',
        'tzid': 'text',
        'value': 'text',
    })

    def for_property(self, name):
        """Returns a the default type for a property or parameter
        """
        return self[self.types_map.get(name, 'text')]

    def to_ical(self, name, value):
        """Encodes a named value from a primitive python type to an icalendar
        encoded string.
        """
        type_class = self.for_property(name)
        return type_class(value).to_ical()

    def from_ical(self, name, value):
        """Decodes a named property or parameter value from an icalendar
        encoded string to a primitive python type.
        """
        type_class = self.for_property(name)
        decoded = type_class.from_ical(value)
        return decoded
Ejemplo n.º 18
0
 def __init__(self, *args, **kwargs):
     CaselessDict.__init__(self, *args, **kwargs)
     self.params = Parameters()
Ejemplo n.º 19
0
class vRecur(CaselessDict):
    """Recurrence definition.
    """

    frequencies = [
        "SECONDLY", "MINUTELY", "HOURLY", "DAILY", "WEEKLY", "MONTHLY",
        "YEARLY"
    ]

    # Mac iCal ignores RRULEs where FREQ is not the first rule part.
    # Sorts parts according to the order listed in RFC 5545, section 3.3.10.
    canonical_order = ("FREQ", "UNTIL", "COUNT", "INTERVAL", "BYSECOND",
                       "BYMINUTE", "BYHOUR", "BYDAY", "BYMONTHDAY",
                       "BYYEARDAY", "BYWEEKNO", "BYMONTH", "BYSETPOS", "WKST")

    types = CaselessDict({
        'COUNT': vInt,
        'INTERVAL': vInt,
        'BYSECOND': vInt,
        'BYMINUTE': vInt,
        'BYHOUR': vInt,
        'BYMONTHDAY': vInt,
        'BYYEARDAY': vInt,
        'BYMONTH': vInt,
        'UNTIL': vDDDTypes,
        'BYSETPOS': vInt,
        'WKST': vWeekday,
        'BYDAY': vWeekday,
        'FREQ': vFrequency,
    })

    def __init__(self, *args, **kwargs):
        CaselessDict.__init__(self, *args, **kwargs)
        self.params = Parameters()

    def to_ical(self):
        result = []
        for key, vals in self.sorted_items():
            typ = self.types[key]
            if not isinstance(vals, SEQUENCE_TYPES):
                vals = [vals]
            vals = b','.join(typ(val).to_ical() for val in vals)

            # CaselessDict keys are always unicode
            key = key.encode(DEFAULT_ENCODING)
            result.append(key + b'=' + vals)

        return b';'.join(result)

    @classmethod
    def parse_type(cls, key, values):
        # integers
        parser = cls.types.get(key, vText)
        return [parser.from_ical(v) for v in values.split(',')]

    @classmethod
    def from_ical(cls, ical):
        if isinstance(ical, cls):
            return ical
        try:
            recur = cls()
            for pairs in ical.split(';'):
                key, vals = pairs.split('=')
                recur[key] = cls.parse_type(key, vals)
            return dict(recur)
        except:
            raise ValueError('Error in recurrence rule: %s' % ical)
Ejemplo n.º 20
0
def item_to_ics(item):
    """
    Convert an etm item to an ical object and return a tuple (Success, object)
    """
    doc_id = item.doc_id
    if not doc_id:
        return False, None
    itemtype = item.get('itemtype')
    if not itemtype:
        return False, None
    element = item_types.get(itemtype) 
    if not element:
        return False, None
    summary = item['summary']

    element.add('uid', doc_id)
    if 'z' in item:
        # pytz is required to get the proper tzid into datetimes
        tz = pytz.timezone(item['z'])
    else:
        tz = None
    if 's' in item:
        dt = item['s']
        dz = dt.replace(tzinfo=tz)
        tzinfo = dz.tzinfo
        dt = dz
        dd = dz.date()
    else:
        dt = None
        tzinfo = None
        # tzname = None

    if 'r' in item:
        # repeating
        rlst = item['r']
        for r in rlst:
            ritem = {}
            for k in ical_rrule_keys:
                if k in r:
                    if k == 'f':
                        ritem[ical_item[k]] = freq_item[r[k]]
                    elif k == 'w':
                        if type(r[k]) == list:
                            ritem[ical_item[k]] = [x.upper() for x in r[k]]
                        else:
                            ritem[ical_item[k]] = r[k].upper()
                    elif k == 'u':
                        uz = parse_str(r[k], item['z']).replace(tzinfo=tzinfo)
                        ritem[ical_item[k]] = uz
                    else:
                        ritem[ical_item[k]] = r[k]
            citem = CaselessDict(ritem)
            element.add('rrule', citem)
        if '+' in item:
            for pd in item['+']:
                element.add('rdate', pd)
        if '-' in item:
            for md in item['-']:
                element.add('exdate', md)

    element.add('summary', summary)

    if 'p' in item:
        element.add('priority', item['p'])
    if 'l' in item:
        element.add('location', item['l'])
    if 't' in item:
        element.add('categories', item['t'])
    if 'd' in item:
        element.add('description', item['d'])
    if 'm' in item:
        element.add('comment', item['m'])
    if 'w' in item:
        element.add('organizer', item['w'])
    if 'i' in item:
        for x in item['i']:
            element.add('attendee', "MAILTO:{0}".format(x))


    if item['itemtype'] in ['-', '+', '%']:
        done, due, following = getDoneAndTwo(item)
        if 's' in item:
            element.add('dtstart', dt)
        if done:
            finz = done.replace(tzinfo=tzinfo)
            fint = vDatetime(finz)
            element.add('completed', fint)
        if due:
            duez = due.replace(tzinfo=tzinfo)
            dued = vDate(duez)
            element.add('due', dued)
    elif item['itemtype'] == '^':
        element.add('dtstart', dd)
    elif dt:
        try:
            element.add('dtstart', dt)
        except:
            logger.exception('exception adding dtstart: {0}'.format(dt))

    if item['itemtype'] == '*':
        if 'e' in item and item['e']:
            ez = dz + item['e']
        else:
            ez = dz
        try:
            element.add('dtend', ez)
        except:
            logger.exception('exception adding dtend: {0}, {1}'.format(ez, tz))
    elif item['itemtype'] == '~':
        if 'e' in item and item['e']:
            element.add('comment', timedelta2Str(item['e']))
    return True, element
Ejemplo n.º 21
0
    """
    def __init__(self, *args, **kwargs):
        "Set keys to upper for initial dict"
        CaselessDict.__init__(self, *args, **kwargs)
        self['VEVENT'] = Event
        self['VTODO'] = Todo
        self['VJOURNAL'] = Journal
        self['VFREEBUSY'] = FreeBusy
        self['VTIMEZONE'] = Timezone
        self['VALARM'] = Alarm
        self['VCALENDAR'] = Calendar


# These Properties have multiple property values inlined in one propertyline
# seperated by comma. Use CaselessDict as simple caseless set.
INLINE = CaselessDict([(cat, 1)
                       for cat in ('CATEGORIES', 'RESOURCES', 'FREEBUSY')])

_marker = []


class Component(CaselessDict):
    """
    Component is the base object for calendar, Event and the other components
    defined in RFC 2445. normally you will not use this class directy, but
    rather one of the subclasses.

    A component is like a dictionary with extra methods and attributes.
    >>> c = Component()
    >>> c.name = 'VCALENDAR'

    Every key defines a property. A property can consist of either a single
Ejemplo n.º 22
0
 def __init__(self, *args, **kwargs):
     "Set keys to upper for initial dict"
     CaselessDict.__init__(self, *args, **kwargs)
     # set parameters here for properties that use non-default values
     self.subcomponents = [] # Components can be nested.
 def __init__(self, *args, **kwargs):
     "Set keys to upper for initial dict"
     CaselessDict.__init__(self, *args, **kwargs)
     # set parameters here for properties that use non-default values
     self.subcomponents = [] # Components can be nested.
 def __init__(self, *args, **kwargs):
     CaselessDict.__init__(self, *args, **kwargs)
     self.params = Parameters()
class TypesFactory(CaselessDict):
    """
    All Value types defined in rfc 2445 are registered in this factory class. To
    get a type you can use it like this.
    >>> factory = TypesFactory()
    >>> datetime_parser = factory['date-time']
    >>> dt = datetime_parser(datetime(2001, 1, 1))
    >>> dt.ical()
    '20010101T000000'

    A typical use is when the parser tries to find a content type and use text
    as the default
    >>> value = '20050101T123000'
    >>> value_type = 'date-time'
    >>> typ = factory.get(value_type, 'text')
    >>> typ.from_ical(value)
    datetime.datetime(2005, 1, 1, 12, 30)

    It can also be used to directly encode property and parameter values
    >>> comment = factory.ical('comment', u'by Rasmussen, Max Møller')
    >>> str(comment)
    'by Rasmussen\\\\, Max M\\xc3\\xb8ller'
    >>> factory.ical('priority', 1)
    '1'
    >>> factory.ical('cn', u'Rasmussen, Max Møller')
    'Rasmussen\\\\, Max M\\xc3\\xb8ller'

    >>> factory.from_ical('cn', 'Rasmussen\\\\, Max M\\xc3\\xb8ller')
    u'Rasmussen, Max M\\xf8ller'

    The value and parameter names don't overlap. So one factory is enough for
    both kinds.
    """
    def __init__(self, *args, **kwargs):
        "Set keys to upper for initial dict"
        CaselessDict.__init__(self, *args, **kwargs)
        self['binary'] = vBinary
        self['boolean'] = vBoolean
        self['cal-address'] = vCalAddress
        self['date'] = vDDDTypes
        self['date-time'] = vDDDTypes
        self['duration'] = vDDDTypes
        self['float'] = vFloat
        self['integer'] = vInt
        self['period'] = vPeriod
        self['recur'] = vRecur
        self['text'] = vText
        self['time'] = vTime
        self['uri'] = vUri
        self['utc-offset'] = vUTCOffset
        self['geo'] = vGeo
        self['inline'] = vInline
        self['date-time-list'] = vDDDLists

    #################################################
    # Property types

    # These are the default types
    types_map = CaselessDict({
        ####################################
        # Property valye types
        # Calendar Properties
        'calscale': 'text',
        'method': 'text',
        'prodid': 'text',
        'version': 'text',
        # Descriptive Component Properties
        'attach': 'uri',
        'categories': 'text',
        'class': 'text',
        'comment': 'text',
        'description': 'text',
        'geo': 'geo',
        'location': 'text',
        'percent-complete': 'integer',
        'priority': 'integer',
        'resources': 'text',
        'status': 'text',
        'summary': 'text',
        # Date and Time Component Properties
        'completed': 'date-time',
        'dtend': 'date-time',
        'due': 'date-time',
        'dtstart': 'date-time',
        'duration': 'duration',
        'freebusy': 'period',
        'transp': 'text',
        # Time Zone Component Properties
        'tzid': 'text',
        'tzname': 'text',
        'tzoffsetfrom': 'utc-offset',
        'tzoffsetto': 'utc-offset',
        'tzurl': 'uri',
        # Relationship Component Properties
        'attendee': 'cal-address',
        'contact': 'text',
        'organizer': 'cal-address',
        'recurrence-id': 'date-time',
        'related-to': 'text',
        'url': 'uri',
        'uid': 'text',
        # Recurrence Component Properties
        'exdate': 'date-time-list',
        'exrule': 'recur',
        'rdate': 'date-time-list',
        'rrule': 'recur',
        # Alarm Component Properties
        'action': 'text',
        'repeat': 'integer',
        'trigger': 'duration',
        # Change Management Component Properties
        'created': 'date-time',
        'dtstamp': 'date-time',
        'last-modified': 'date-time',
        'sequence': 'integer',
        # Miscellaneous Component Properties
        'request-status': 'text',
        ####################################
        # parameter types (luckilly there is no name overlap)
        'altrep': 'uri',
        'cn': 'text',
        'cutype': 'text',
        'delegated-from': 'cal-address',
        'delegated-to': 'cal-address',
        'dir': 'uri',
        'encoding': 'text',
        'fmttype': 'text',
        'fbtype': 'text',
        'language': 'text',
        'member': 'cal-address',
        'partstat': 'text',
        'range': 'text',
        'related': 'text',
        'reltype': 'text',
        'role': 'text',
        'rsvp': 'boolean',
        'sent-by': 'cal-address',
        'tzid': 'text',
        'value': 'text',
    })

    def for_property(self, name):
        "Returns a the default type for a property or parameter"
        return self[self.types_map.get(name, 'text')]

    def ical(self, name, value):
        """
        Encodes a named value from a primitive python type to an
        icalendar encoded string.
        """
        type_class = self.for_property(name)
        return type_class(value).ical()

    def from_ical(self, name, value):
        """
        Decodes a named property or parameter value from an icalendar encoded
        string to a primitive python type.
        """
        type_class = self.for_property(name)
        decoded = type_class.from_ical(str(value))
        return decoded
class vWeekday(str):
    """
    This returns an unquoted weekday abbrevation
    >>> a = vWeekday('mo')
    >>> a.ical()
    'MO'

    >>> a = vWeekday('erwer')
    Traceback (most recent call last):
        ...
    ValueError: Expected weekday abbrevation, got: ERWER

    >>> vWeekday.from_ical('mo')
    'MO'

    >>> vWeekday.from_ical('+3mo')
    '+3MO'

    >>> vWeekday.from_ical('Saturday')
    Traceback (most recent call last):
        ...
    ValueError: Expected weekday abbrevation, got: Saturday

    >>> a = vWeekday('+mo')
    >>> a.ical()
    '+MO'

    >>> a = vWeekday('+3mo')
    >>> a.ical()
    '+3MO'

    >>> a = vWeekday('-tu')
    >>> a.ical()
    '-TU'
    """

    week_days = CaselessDict({
        "SU": 0,
        "MO": 1,
        "TU": 2,
        "WE": 3,
        "TH": 4,
        "FR": 5,
        "SA": 6
    })

    def __init__(self, *args, **kwargs):
        match = WEEKDAY_RULE.match(self)
        if match is None:
            raise ValueError, 'Expected weekday abbrevation, got: %s' % self
        match = match.groupdict()
        sign = match['signal']
        weekday = match['weekday']
        relative = match['relative']
        if not weekday in vWeekday.week_days or sign not in '+-':
            raise ValueError, 'Expected weekday abbrevation, got: %s' % self
        self.relative = relative and int(relative) or None
        self.params = Parameters()

    def ical(self):
        return self.upper()

    def from_ical(ical):
        "Parses the data format from ical text format"
        try:
            return vWeekday(ical.upper())
        except:
            raise ValueError, 'Expected weekday abbrevation, got: %s' % ical

    from_ical = staticmethod(from_ical)

    def __str__(self):
        return self.ical()
Ejemplo n.º 27
0
        self['VEVENT'] = Event
        self['VTODO'] = Todo
        self['VJOURNAL'] = Journal
        self['VFREEBUSY'] = FreeBusy
        self['VTIMEZONE'] = Timezone
        self['STANDARD'] = TimezoneStandard
        self['DAYLIGHT'] = TimezoneDaylight
        self['VALARM'] = Alarm
        self['VCALENDAR'] = Calendar


# These Properties have multiple property values inlined in one propertyline
# seperated by comma. Use CaselessDict as simple caseless set.
INLINE = CaselessDict({
    'CATEGORIES': 1,
    'RESOURCES': 1,
    'FREEBUSY': 1,
})

_marker = []


class Component(CaselessDict):
    """Component is the base object for calendar, Event and the other
    components defined in RFC 2445. normally you will not use this class
    directy, but rather one of the subclasses.
    """

    name = None  # should be defined in each component
    required = ()  # These properties are required
    singletons = ()  # These properties must only appear once