2012-09-08 12 views
9

Ich versuche, eine Wiederholungsregel als Zeichenfolge durch iCalendar-Format (siehe RFC 5545) zu drucken. Im mit Python DateUtils, insbesondere dateutil.rrule die Wiederholungsregel zu erstellen, und ich möchte dies als eine Zeichenfolge drucken wie:Python dateutils Druck Wiederholungsregel nach iCalendar-Format (siehe RFC 5545)

"RRULE:FREQ=DAILY;COUNT=5" 

Kann mir jemand sagen, ob es ein Verfahren, um dies zu erreichen ist?

Ich denke, ich benutze die Labix Dateutils BTW.

Vielen Dank!

Antwort

7

Es gibt keine Methode oder Funktion im python-dateutil Paket, um dies zu tun. Siehe diesen Fehler für einen Patch, der helfen kann: https://bugs.launchpad.net/dateutil/+bug/943512.

+0

Vorsicht sollte Zeilenfaltung http: // www genommen werden .apps.ietf.org/rfc/rfc2445.html # sec-4.1 – oberron

0

Hier ist eine Unterklasse von rrule, die zwei vorgeschlagene python-dateutil Patches enthält, die rrule Ausgabe ermöglicht. Bedenken Sie, dass es gute Gründe dafür gibt, dass die Patches nicht akzeptiert wurden, und ich habe dies nur für die einfachsten Fälle getestet. Zeilenumbruch wird nicht behandelt.

Siehe Bug-Tracker für die Diskussion: https://bugs.launchpad.net/dateutil/+bug/943512
https://bugs.launchpad.net/dateutil/+bug/943509

FREQNAMES = ['YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY', 'HOURLY', 'MINUTELY', 'SECONDLY'] 


class ConvertibleRRule(rrule.rrule): 
    # Subclass of the `rrule class that provides a sensible __str__() 
    # method, outputting ical formatted rrules. 
    # Combined from the patches in these dateutil issues: 
    # https://bugs.launchpad.net/dateutil/+bug/943512 
    # https://bugs.launchpad.net/dateutil/+bug/943509 
    _bysecond_internal = False 
    _byminute_internal = False 
    _byhour = False 
    _bymonth_internal = False 
    _bymonthday_internal = False 
    _byweekday_internal = False 

    def __init__(self, freq, dtstart=None, 
       interval=1, wkst=None, count=None, until=None, bysetpos=None, 
       bymonth=None, bymonthday=None, byyearday=None, byeaster=None, 
       byweekno=None, byweekday=None, 
       byhour=None, byminute=None, bysecond=None, 
       cache=False): 
     super(ConvertibleRRule, self).__init__(
      freq, dtstart=dtstart, 
      interval=interval, wkst=wkst, count=count, until=until, bysetpos=bysetpos, 
      bymonth=bymonth, bymonthday=bymonthday, byyearday=byyearday, byeaster=byeaster, 
      byweekno=byweekno, byweekday=byweekday, 
      byhour=byhour, byminute=byminute, bysecond=bysecond, 
      cache=cache) 

     if (byweekno is None and byyearday is None and bymonthday is None and 
        byweekday is None and byeaster is None): 
      if freq == rrule.YEARLY: 
       if not bymonth: 
        self._bymonth_internal = True 
       self._bymonthday_internal = True 
      elif freq == rrule.MONTHLY: 
       self._bymonthday_internal = True 
      elif freq == rrule.WEEKLY: 
       self._byweekday_internal = True 

     # byhour 
     if byhour is None: 
      if freq < rrule.HOURLY: 
       self._byhour_internal = True 

     # byminute 
     if byminute is None: 
      if freq < rrule.MINUTELY: 
       self._byminute_internal = True 

     # bysecond 
     if bysecond is None: 
      if freq < rrule.SECONDLY: 
       self._bysecond_internal = True 

    freq = property(lambda s: s._freq) 
    dtstart = property(lambda s: s._dtstart) 
    interval = property(lambda s: s._interval) 

    @property 
    def wkst(self): 
     if self._wkst == rrule.calendar.firstweekday(): 
      return None 
     return rrule.weekday(self._wkst) 

    count = property(lambda s: s._count) 
    until = property(lambda s: s._until) 
    bysetpos = property(lambda s: s._bysetpos) 

    @property 
    def bymonth(self): 
     if self._bymonth_internal: 
      return None 
     return self._bymonth 

    @property 
    def bymonthday(self): 
     if self._bymonthday_internal: 
      return None 
     return self._bymonthday + self._bynmonthday 

    byyearday = property(lambda s: s._byyearday) 
    byeaster = property(lambda s: s._byeaster) 
    byweekno = property(lambda s: s._byweekno) 

    @property 
    def byweekday(self): 
     if self._byweekday_internal: 
      return None 
     bynweekday, byweekday =(),() 
     if self._bynweekday: 
      bynweekday = tuple(rrule.weekday(d, n) for d, n in self._bynweekday) 
     if self._byweekday: 
      byweekday = tuple(rrule.weekday(d) for d in self._byweekday) 
     return bynweekday + byweekday 

    @property 
    def byhour(self): 
     if self._byhour_internal: 
      return None 
     return self._byhour 

    @property 
    def byminute(self): 
     if self._byminute_internal: 
      return None 
     return self._byminute 

    @property 
    def bysecond(self): 
     if self._bysecond_internal: 
      return None 
     return self._bysecond 

    def __str__(self): 
     parts = ['FREQ=' + FREQNAMES[self.freq]] 

     if self.interval != 1: 
      parts.append('INTERVAL=' + str(self.interval)) 
     if self.wkst: 
      parts.append('WKST=' + str(self.wkst)) 
     if self.count: 
      parts.append('COUNT=' + str(self.count)) 

     for name, value in [ 
      ('BYSETPOS', self.bysetpos), 
      ('BYMONTH', self.bymonth), 
      ('BYMONTHDAY', self.bymonthday), 
      ('BYYEARDAY', self.byyearday), 
      ('BYWEEKNO', self.byweekno), 
      ('BYWEEKDAY', self.byweekday), 
      ('BYHOUR', self.byhour), 
      ('BYMINUTE', self.byminute), 
      ('BYSECOND', self.bysecond), 
     ]: 
      if value: 
       parts.append(name + '=' + ','.join(str(v) for v in value)) 

     return ';'.join(parts) 
0

Obwohl dies 4 Jahre geschrieben, nachdem die Frage gestellt wurde, dateutil mittlerweile eine __str__ Methode hat (siehe source code), die man erlaubt print seine Objekte in einer solchen Form:

In [1]: from dateutil.rrule import * 

In [2]: my_rrule = rrule(DAILY, count=5) 

In [3]: print(my_rrule) 
DTSTART:20161202T184513 
FREQ=DAILY;COUNT=5