Exemple #1
0
def _make_ics(event, etime):

    cal = Calendar()
    cal.add('prodid', 'N1-send-availability-package')
    cal.add('version', '1.0')

    evt = Event()
    evt.add('summary', event.title)
    evt.add('location', event.location)
    evt.add('description', event.description)
    evt.add('dtstart', etime.start)
    evt.add('dtend', etime.end)
    evt.add('dtstamp', datetime.now())

    evt['uid'] = '{timestamp}/{email}'.format(timestamp=time.mktime(
        datetime.now().timetuple()),
                                              email=event.organizer.email)
    evt.add('priority', 5)

    organizer = vCalAddress('MAILTO:{}'.format(event.organizer.email))
    organizer.params['cn'] = vText(event.organizer.name)
    organizer.params['role'] = vText('CHAIR')
    evt['organizer'] = organizer

    for attendee in event.attendees:
        atnd = vCalAddress('MAILTO:{}'.format(attendee.email))
        atnd.params['cn'] = vText(attendee.name)
        atnd.params['ROLE'] = vText('REQ-PARTICIPANT')
        evt.add('attendee', atnd, encode=0)

    cal.add_component(evt)

    return cal.to_ical()
Exemple #2
0
    def property_items(self, recursive=True, sorted=True):
        """Returns properties in this component and subcomponents as:
        [(name, value), ...]
        """
        vText = types_factory['text']
        properties = [('BEGIN', vText(self.name).to_ical())]
        if sorted:
            property_names = self.sorted_keys()
        else:
            property_names = self.keys()

        for name in property_names:
            values = self[name]
            if isinstance(values, list):
                # normally one property is one line
                for value in values:
                    properties.append((name, value))
            else:
                properties.append((name, values))
        if recursive:
            # recursion is fun!
            for subcomponent in self.subcomponents:
                properties += subcomponent.property_items(sorted=sorted)
        properties.append(('END', vText(self.name).to_ical()))
        return properties
def _make_ics(event, etime):

    cal = Calendar()
    cal.add('prodid', 'N1-send-availability-package')
    cal.add('version', '1.0')

    evt = Event()
    evt.add('summary', event.title)
    evt.add('location', event.location)
    evt.add('description', event.description)
    evt.add('dtstart', etime.start)
    evt.add('dtend', etime.end)
    evt.add('dtstamp', datetime.now())

    evt['uid'] = '{timestamp}/{email}'.format(
        timestamp=time.mktime(datetime.now().timetuple()),
        email=event.organizer.email
    )
    evt.add('priority', 5)

    organizer = vCalAddress('MAILTO:{}'.format(event.organizer.email))
    organizer.params['cn'] = vText(event.organizer.name)
    organizer.params['role'] = vText('CHAIR')
    evt['organizer'] = organizer

    for attendee in event.attendees:
        atnd = vCalAddress('MAILTO:{}'.format(attendee.email))
        atnd.params['cn'] = vText(attendee.name)
        atnd.params['ROLE'] = vText('REQ-PARTICIPANT')
        evt.add('attendee', atnd, encode=0)

    cal.add_component(evt)

    return cal.to_ical()
Exemple #4
0
    def property_items(self, recursive=True, sorted=True):
        """Returns properties in this component and subcomponents as:
        [(name, value), ...]
        """
        vText = types_factory['text']
        properties = [('BEGIN', vText(self.name).to_ical())]
        if sorted:
            property_names = self.sorted_keys()
        else:
            property_names = self.keys()

        for name in property_names:
            values = self[name]
            if isinstance(values, list):
                # normally one property is one line
                for value in values:
                    properties.append((name, value))
            else:
                properties.append((name, values))
        if recursive:
            # recursion is fun!
            for subcomponent in self.subcomponents:
                properties += subcomponent.property_items(sorted=sorted)
        properties.append(('END', vText(self.name).to_ical()))
        return properties
Exemple #5
0
def _make_ics(event, etime):

    cal = Calendar()
    cal.add("prodid", "N1-send-availability-package")
    cal.add("version", "2.0")

    cal.add("method", "REQUEST")  # also have PUBLISH or CANCEL

    evt = Event()
    evt.add("summary", event.title)
    evt.add("location", event.location)
    evt.add("description", event.description)
    evt.add("dtstart", etime.start.replace(tzinfo=pytz.UTC))
    evt.add("dtend", etime.end.replace(tzinfo=pytz.UTC))
    evt.add("dtstamp", datetime.now(pytz.UTC))

    evt["uid"] = "{timestamp}/{email}".format(
        timestamp=time.mktime(datetime.now(pytz.UTC).timetuple()), email=event.organizer.email
    )
    evt.add("priority", 5)

    organizer = vCalAddress("MAILTO:{}".format(event.organizer.email))
    organizer.params["cn"] = vText(event.organizer.name)
    organizer.params["role"] = vText("CHAIR")
    evt["organizer"] = organizer

    for attendee in event.attendees:
        atnd = vCalAddress("MAILTO:{}".format(attendee.email))
        atnd.params["cn"] = vText(attendee.name)
        atnd.params["ROLE"] = vText("REQ-PARTICIPANT")
        evt.add("attendee", atnd, encode=0)

    cal.add_component(evt)

    return cal.to_ical()
Exemple #6
0
 def uid(self, host_name='example.com', unique=''):
     """
     Generates a unique id consisting of:
     datetime-uniquevalue@host. Like:
     [email protected]
     """
     from icalendar.prop import vText, vDatetime
     unique = unique or self.rnd_string()
     return vText('%s-%s@%s' % (vDatetime(datetime.today()).to_ical(), unique, host_name))
Exemple #7
0
 def uid(self, host_name='example.com', unique=''):
     """Generates a unique id consisting of:
         datetime-uniquevalue@host.
     Like:
         [email protected]
     """
     host_name = to_unicode(host_name)
     unique = unique or self.rnd_string()
     today = to_unicode(vDatetime(datetime.today()).to_ical())
     return vText('%s-%s@%s' % (today, unique, host_name))
Exemple #8
0
 def uid(self, host_name='example.com', unique=''):
     """
     Generates a unique id consisting of:
     datetime-uniquevalue@host. Like:
     [email protected]
     """
     from icalendar.prop import vText, vDatetime
     unique = unique or self.rnd_string()
     return vText(
         '%s-%s@%s' %
         (vDatetime(datetime.today()).to_ical(), unique, host_name))
Exemple #9
0
 def property_items(self):
     """
     Returns properties in this component and subcomponents as:
     [(name, value), ...]
     """
     vText = types_factory["text"]
     properties = [("BEGIN", vText(self.name).ical())]
     property_names = self.sorted_keys()
     for name in property_names:
         values = self[name]
         if type(values) == ListType:
             # normally one property is one line
             for value in values:
                 properties.append((name, value))
         else:
             properties.append((name, values))
     # recursion is fun!
     for subcomponent in self.subcomponents:
         properties += subcomponent.property_items()
     properties.append(("END", vText(self.name).ical()))
     return properties
Exemple #10
0
 def uid(self, host_name='example.com', unique=''):
     """Generates a unique id consisting of:
         datetime-uniquevalue@host.
     Like:
         [email protected]
     """
     host_name = to_unicode(host_name)
     unique = unique or self.rnd_string()
     today = to_unicode(vDatetime(datetime.today()).to_ical())
     return vText('%s-%s@%s' % (today,
                                unique,
                                host_name))
 def property_items(self):
     """
     Returns properties in this component and subcomponents as:
     [(name, value), ...]
     """
     vText = types_factory['text']
     properties = [('BEGIN', vText(self.name).ical())]
     property_names = self.keys()
     property_names.sort()
     for name in property_names:
         values = self[name]
         if type(values) == ListType:
             # normally one property is one line
             for value in values:
                 properties.append((name, value))
         else:
             properties.append((name, values))
     # recursion is fun!
     for subcomponent in self.subcomponents:
         properties += subcomponent.property_items()
     properties.append(('END', vText(self.name).ical()))
     return properties
Exemple #12
0
def patched_categories(self):
    """ Patch categories to include our custom tags values """
    ret = []
    if self.context.tag:
        factory = getUtility(IVocabularyFactory,
                             'eionet.fullcalendar.categories')
        vocabulary = factory(self.context)
        ret.append(vText(vocabulary.getTerm(self.context.tag).title))
    for cat in self.event.subjects or []:
        ret.append(cat)
    if ret:
        return {'value': ret}
    return None
Exemple #13
0
def _make_ics(event, etime):

    cal = Calendar()
    cal.add('prodid', 'N1-quick-schedule-package')
    cal.add('version', '2.0')

    cal.add('method', 'REQUEST')   # also have PUBLISH or CANCEL

    evt = Event()
    evt.add('summary', event.title)
    evt.add('location', event.location)
    evt.add('description', event.description)
    evt.add('dtstart', etime.start.replace(tzinfo=pytz.UTC))
    evt.add('dtend', etime.end.replace(tzinfo=pytz.UTC))
    evt.add('dtstamp', datetime.now(pytz.UTC))

    evt['uid'] = '{timestamp}/{email}'.format(
        timestamp=time.mktime(datetime.now(pytz.UTC).timetuple()),
        email=event.organizer.email
    )
    evt.add('priority', 5)

    organizer = vCalAddress('MAILTO:{}'.format(event.organizer.email))
    organizer.params['cn'] = vText(event.organizer.name)
    organizer.params['role'] = vText('CHAIR')
    evt['organizer'] = organizer

    for attendee in event.attendees:
        atnd = vCalAddress('MAILTO:{}'.format(attendee.email))
        atnd.params['cn'] = vText(attendee.name)
        atnd.params['ROLE'] = vText('REQ-PARTICIPANT')
        evt.add('attendee', atnd, encode=0)

    cal.add_component(evt)

    return cal.to_ical()
Exemple #14
0
    def test_multiple(self):

        directory = os.path.dirname(__file__)
        cals = Calendar.from_ical(open(os.path.join(directory, 'multiple.ics'),
                                       'rb').read(),
                                  multiple=True)

        self.assertEqual(len(cals), 2)
        self.assertSequenceEqual([comp.name for comp in cals[0].walk()],
                                 ['VCALENDAR', 'VEVENT'])
        self.assertSequenceEqual([comp.name for comp in cals[1].walk()],
                                 ['VCALENDAR', 'VEVENT', 'VEVENT'])

        self.assertEqual(
            cals[0]['prodid'],
            vText('-//Mozilla.org/NONSGML Mozilla Calendar V1.0//EN'))
Exemple #15
0
    def test_multiple(self):

        directory = os.path.dirname(__file__)
        with open(os.path.join(directory, 'multiple.ics'), 'rb') as fp:
            data = fp.read()
        cals = Calendar.from_ical(data, multiple=True)

        self.assertEqual(len(cals), 2)
        self.assertSequenceEqual([comp.name for comp in cals[0].walk()],
                                 ['VCALENDAR', 'VEVENT'])
        self.assertSequenceEqual([comp.name for comp in cals[1].walk()],
                                 ['VCALENDAR', 'VEVENT', 'VEVENT'])

        self.assertEqual(
            cals[0]['prodid'],
            vText('-//Mozilla.org/NONSGML Mozilla Calendar V1.0//EN')
        )
Exemple #16
0
    def from_parts(parts):
        "Turns a tuple of parts into a content line"
        (name, params, values) = parts
        try:
            if hasattr(values, "to_ical"):
                values = values.to_ical()
            else:
                values = vText(values).to_ical()
            # elif isinstance(values, basestring):
            #    values = escape_char(values)

            if params:
                return Contentline("%s;%s:%s" % (name, params.to_ical(), values))
            return Contentline("%s:%s" % (name, values))
        except Exception as exc:
            logger.error(str(exc))
            raise ValueError(u'Property: %r Wrong values "%r" or "%r"' % (name, params, values))
Exemple #17
0
def generate_calendar(request):
    """http://codespeak.net/icalendar/"""

    cal = Calendar()
    cal.add("prodid", "-//Club Connect//ericleong.me//")
    cal.add("version", "2.0")
    posts = Post.objects.order_by("-created")

    cal["X-WR-CALNAME"] = "Club Connect Events"
    cal["X-PUBLISH-TTL"] = "PT12H"
    cal["CALSCALE"] = "GREGORIAN"
    cal["METHOD"] = "PUBLISH"

    # TODO: separate out private events using a private URL?
    # TODO: switch to using EDT
    for post in posts:
        if post.start_time:
            # Make sure we have a time
            event = Event()
            event.add("summary", vText(post.title))
            event.add("dtstart", post.start_time)
            event.add("dtend", post.end_time if post.end_time else post.start_time)
            # event.add('dtstamp', datetime(2005,4,4,0,10,0,tzinfo=UTC))
            event["uid"] = vText(post.id)
            event["organizer"] = vText(post.author.username)
            event["description"] = vText(post.description)
            event["url"] = vUri(post.get_absolute_url())

            if post.location:
                if post.location.room:
                    event["location"] = vText("%s (%s)" % (post.location.name, post.location.room))
                else:
                    event["location"] = vText(post.location.name)

            for commit in post.committed.all():
                attendee = vCalAddress("MAILTO:" + commit.email)
                name = (
                    ([commit.first_name, commit.last_name])
                    if (commit.first_name and commit.last_name)
                    else commit.username
                )
                attendee.params["cn"] = vText(name)
                event.add("attendee", attendee, encode=0)

            cal.add_component(event)

    return HttpResponse(cal.to_ical().replace("\n", "\r\n"), content_type="text/calendar")
Exemple #18
0
    def from_parts(parts):
        "Turns a tuple of parts into a content line"
        (name, params, values) = parts
        try:
            if hasattr(values, 'to_ical'):
                values = values.to_ical()
            else:
                values = vText(values).to_ical()
            #elif isinstance(values, basestring):
            #    values = escape_char(values)

            if params:
                return Contentline('%s;%s:%s' % (name, params.to_ical(), values))
            return Contentline('%s:%s' %  (name, values))
        except:
            raise ValueError(
                'Property: %s Wrong values "%s" or "%s"' % (repr(name),
                                                            repr(params),
                                                            repr(values)))
Exemple #19
0
    def from_parts(cls, name, params, values, sorted=True):
        """Turn a parts into a content line.
        """
        assert isinstance(params, Parameters)
        if hasattr(values, 'to_ical'):
            values = values.to_ical()
        else:
            values = vText(values).to_ical()
        # elif isinstance(values, basestring):
        #    values = escape_char(values)

        # TODO: after unicode only, remove this
        # Convert back to unicode, after to_ical encoded it.
        name = to_unicode(name)
        values = to_unicode(values)
        if params:
            params = to_unicode(params.to_ical(sorted=sorted))
            return cls(u'%s;%s:%s' % (name, params, values))
        return cls(u'%s:%s' % (name, values))
Exemple #20
0
    def handle(self, *args, **options):
        URL = r'http://contests.acmicpc.info/contests.json'
        TZ = timezone('Asia/Shanghai')

        cal = Calendar()
        cal.add('prodid', '-//ACM EVENTS CALENDAR//WHUACM TEAM//')
        cal.add('version', '2.0')
        events = requests.get(URL).json()

        for item in events:
            event = Event()
            fmt = '%Y-%m-%d %H:%M:%S'
            time = datetime.strptime(item['start_time'], fmt).replace(tzinfo=TZ)
            event.add('dtstart', time)
            event.add('summary', item['name'])
            event['location'] = vText(item['oj'])
            event['uid'] = item['id'] + '@whuctf.org'
            cal.add_component(event)
        f = open(os.path.join(settings.MEDIA_ROOT, 'acmevents.ics'), 'wb')
        f.write(cal.to_ical())
        f.close()
Exemple #21
0
    def test_cal_Component(self):
        from icalendar.cal import Component, Calendar, Event
        from icalendar import prop

        # 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 item. This can be set with a single value...
        c['prodid'] = '-//max m//icalendar.mxm.dk/'
        self.assertEqual(
            c,
            Calendar({'PRODID': '-//max m//icalendar.mxm.dk/'})
        )

        # or with a list
        c['ATTENDEE'] = ['Max M', 'Rasmussen']
        self.assertEqual(
            c,
            Calendar({'ATTENDEE': ['Max M', 'Rasmussen'],
                      'PRODID': '-//max m//icalendar.mxm.dk/'})
        )

        ### ADD MULTIPLE VALUES TO A PROPERTY

        # if you use the add method you don't have to considder if a value is
        # a list or not.
        c = Component()
        c.name = 'VEVENT'

        # add multiple values at once
        c.add('attendee',
              ['*****@*****.**', '*****@*****.**'])

        # or add one per line
        c.add('attendee', '*****@*****.**')
        c.add('attendee', '*****@*****.**')

        # add again multiple values at once to very concatenaton of lists
        c.add('attendee',
              ['*****@*****.**', '*****@*****.**'])

        self.assertEqual(
            c,
            Event({'ATTENDEE': [
                prop.vCalAddress('*****@*****.**'),
                prop.vCalAddress('*****@*****.**'),
                prop.vCalAddress('*****@*****.**'),
                prop.vCalAddress('*****@*****.**'),
                prop.vCalAddress('*****@*****.**'),
                prop.vCalAddress('*****@*****.**')
            ]})
        )

        ###

        # You can get the values back directly ...
        c.add('prodid', '-//my product//')
        self.assertEqual(c['prodid'], prop.vText(u'-//my product//'))

        # ... or decoded to a python type
        self.assertEqual(c.decoded('prodid'), b'-//my product//')

        # With default values for non existing properties
        self.assertEqual(c.decoded('version', 'No Version'), 'No Version')

        c.add('rdate', [datetime(2013, 3, 28), datetime(2013, 3, 27)])
        self.assertTrue(isinstance(c.decoded('rdate'), prop.vDDDLists))

        # The component can render itself in the RFC 2445 format.
        c = Component()
        c.name = 'VCALENDAR'
        c.add('attendee', 'Max M')
        self.assertEqual(
            c.to_ical(),
            b'BEGIN:VCALENDAR\r\nATTENDEE:Max M\r\nEND:VCALENDAR\r\n'
        )

        # Components can be nested, so You can add a subcompont. Eg a calendar
        # holds events.
        e = Component(summary='A brief history of time')
        e.name = 'VEVENT'
        e.add('dtend', '20000102T000000', encode=0)
        e.add('dtstart', '20000101T000000', encode=0)
        self.assertEqual(
            e.to_ical(),
            b'BEGIN:VEVENT\r\nDTEND:20000102T000000\r\n'
            + b'DTSTART:20000101T000000\r\nSUMMARY:A brief history of time\r'
            + b'\nEND:VEVENT\r\n'
        )

        c.add_component(e)
        self.assertEqual(
            c.subcomponents,
            [Event({'DTEND': '20000102T000000', 'DTSTART': '20000101T000000',
                    'SUMMARY': 'A brief history of time'})]
        )

        # We can walk over nested componentes with the walk method.
        self.assertEqual([i.name for i in c.walk()], ['VCALENDAR', 'VEVENT'])

        # We can also just walk over specific component types, by filtering
        # them on their name.
        self.assertEqual([i.name for i in c.walk('VEVENT')], ['VEVENT'])

        self.assertEqual(
            [i['dtstart'] for i in c.walk('VEVENT')],
            ['20000101T000000']
        )

        # We can enumerate property items recursively with the property_items
        # method.
        self.assertEqual(
            c.property_items(),
            [('BEGIN', b'VCALENDAR'), ('ATTENDEE', prop.vCalAddress('Max M')),
             ('BEGIN', b'VEVENT'), ('DTEND', '20000102T000000'),
             ('DTSTART', '20000101T000000'),
             ('SUMMARY', 'A brief history of time'), ('END', b'VEVENT'),
             ('END', b'VCALENDAR')]
        )

        # We can also enumerate property items just under the component.
        self.assertEqual(
            c.property_items(recursive=False),
            [('BEGIN', b'VCALENDAR'),
             ('ATTENDEE', prop.vCalAddress('Max M')),
             ('END', b'VCALENDAR')]
        )

        sc = c.subcomponents[0]
        self.assertEqual(
            sc.property_items(recursive=False),
            [('BEGIN', b'VEVENT'), ('DTEND', '20000102T000000'),
             ('DTSTART', '20000101T000000'),
             ('SUMMARY', 'A brief history of time'), ('END', b'VEVENT')]
        )

        # Text fields which span multiple mulitple lines require proper
        # indenting
        c = Calendar()
        c['description'] = u'Paragraph one\n\nParagraph two'
        self.assertEqual(
            c.to_ical(),
            b'BEGIN:VCALENDAR\r\nDESCRIPTION:Paragraph one\\n\\nParagraph two'
            + b'\r\nEND:VCALENDAR\r\n'
        )

        # INLINE properties have their values on one property line. Note the
        # double quoting of the value with a colon in it.
        c = Calendar()
        c['resources'] = 'Chair, Table, "Room: 42"'
        self.assertEqual(
            c,
            Calendar({'RESOURCES': 'Chair, Table, "Room: 42"'})
        )

        self.assertEqual(
            c.to_ical(),
            b'BEGIN:VCALENDAR\r\nRESOURCES:Chair\\, Table\\, "Room: 42"\r\n'
            + b'END:VCALENDAR\r\n'
        )

        # The inline values must be handled by the get_inline() and
        # set_inline() methods.
        self.assertEqual(
            c.get_inline('resources', decode=0),
            [u'Chair', u'Table', u'Room: 42']
        )

        # These can also be decoded
        self.assertEqual(
            c.get_inline('resources', decode=1),
            [b'Chair', b'Table', b'Room: 42']
        )

        # You can set them directly ...
        c.set_inline('resources', ['A', 'List', 'of', 'some, recources'],
                     encode=1)
        self.assertEqual(c['resources'], 'A,List,of,"some, recources"')

        # ... and back again
        self.assertEqual(
            c.get_inline('resources', decode=0),
            ['A', 'List', 'of', 'some, recources']
        )

        c['freebusy'] = '19970308T160000Z/PT3H,19970308T200000Z/PT1H,'\
                        + '19970308T230000Z/19970309T000000Z'
        self.assertEqual(
            c.get_inline('freebusy', decode=0),
            ['19970308T160000Z/PT3H', '19970308T200000Z/PT1H',
             '19970308T230000Z/19970309T000000Z']
        )

        freebusy = c.get_inline('freebusy', decode=1)
        self.assertTrue(isinstance(freebusy[0][0], datetime))
        self.assertTrue(isinstance(freebusy[0][1], timedelta))
Exemple #22
0
        datestr += time.strftime(' %Y')
    dtstart = datetime.datetime.strptime(datestr, "%d %b %Y")
    dtend = None
    duration = datetime.timedelta(1)


props = {
    'categories': opts.categories.split(','),
    'dtstart': vDate(dtstart.date()),
    'created': vDatetime(datetime.datetime.now()),
    'class': 'PUBLIC',
    }
if status is not None:
    props['status'] = status
if location is not None:
    props['location'] = vText(location)
if opts.event_url:
    props['url'] = vUri(opts.event_url)
if description is not None:
    props['summary'] = vText(description)
if dtend is not None:
    props['dtend'] = vDate(dtend.date())
if duration is not None:
    props['duration'] = vDuration(duration)

uid = str(uuid.uuid1())
props['UID'] = uid
ev = Event(**props)

c = Calendar()
c.add_component(ev)
Exemple #23
0
    def test_cal_Component(self):
        from icalendar.cal import Component, Calendar, Event
        from icalendar import prop

        # 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 item. This can be set with a single value...
        c['prodid'] = '-//max m//icalendar.mxm.dk/'
        self.assertEqual(c, Calendar({'PRODID':
                                      '-//max m//icalendar.mxm.dk/'}))

        # or with a list
        c['ATTENDEE'] = ['Max M', 'Rasmussen']
        self.assertEqual(
            c,
            Calendar({
                'ATTENDEE': ['Max M', 'Rasmussen'],
                'PRODID': '-//max m//icalendar.mxm.dk/'
            }))

        ### ADD MULTIPLE VALUES TO A PROPERTY

        # if you use the add method you don't have to considder if a value is
        # a list or not.
        c = Component()
        c.name = 'VEVENT'

        # add multiple values at once
        c.add('attendee', ['*****@*****.**', '*****@*****.**'])

        # or add one per line
        c.add('attendee', '*****@*****.**')
        c.add('attendee', '*****@*****.**')

        # add again multiple values at once to very concatenaton of lists
        c.add('attendee', ['*****@*****.**', '*****@*****.**'])

        self.assertEqual(
            c,
            Event({
                'ATTENDEE': [
                    prop.vCalAddress('*****@*****.**'),
                    prop.vCalAddress('*****@*****.**'),
                    prop.vCalAddress('*****@*****.**'),
                    prop.vCalAddress('*****@*****.**'),
                    prop.vCalAddress('*****@*****.**'),
                    prop.vCalAddress('*****@*****.**')
                ]
            }))

        ###

        # You can get the values back directly ...
        c.add('prodid', '-//my product//')
        self.assertEqual(c['prodid'], prop.vText(u'-//my product//'))

        # ... or decoded to a python type
        self.assertEqual(c.decoded('prodid'), b'-//my product//')

        # With default values for non existing properties
        self.assertEqual(c.decoded('version', 'No Version'), 'No Version')

        c.add('rdate', [datetime(2013, 3, 28), datetime(2013, 3, 27)])
        self.assertTrue(isinstance(c.decoded('rdate'), prop.vDDDLists))

        # The component can render itself in the RFC 2445 format.
        c = Component()
        c.name = 'VCALENDAR'
        c.add('attendee', 'Max M')
        self.assertEqual(
            c.to_ical(),
            b'BEGIN:VCALENDAR\r\nATTENDEE:Max M\r\nEND:VCALENDAR\r\n')

        # Components can be nested, so You can add a subcompont. Eg a calendar
        # holds events.
        e = Component(summary='A brief history of time')
        e.name = 'VEVENT'
        e.add('dtend', '20000102T000000', encode=0)
        e.add('dtstart', '20000101T000000', encode=0)
        self.assertEqual(
            e.to_ical(), b'BEGIN:VEVENT\r\nDTEND:20000102T000000\r\n' +
            b'DTSTART:20000101T000000\r\nSUMMARY:A brief history of time\r' +
            b'\nEND:VEVENT\r\n')

        c.add_component(e)
        self.assertEqual(c.subcomponents, [
            Event({
                'DTEND': '20000102T000000',
                'DTSTART': '20000101T000000',
                'SUMMARY': 'A brief history of time'
            })
        ])

        # We can walk over nested componentes with the walk method.
        self.assertEqual([i.name for i in c.walk()], ['VCALENDAR', 'VEVENT'])

        # We can also just walk over specific component types, by filtering
        # them on their name.
        self.assertEqual([i.name for i in c.walk('VEVENT')], ['VEVENT'])

        self.assertEqual([i['dtstart'] for i in c.walk('VEVENT')],
                         ['20000101T000000'])

        # We can enumerate property items recursively with the property_items
        # method.
        self.assertEqual(c.property_items(),
                         [('BEGIN', b'VCALENDAR'),
                          ('ATTENDEE', prop.vCalAddress('Max M')),
                          ('BEGIN', b'VEVENT'), ('DTEND', '20000102T000000'),
                          ('DTSTART', '20000101T000000'),
                          ('SUMMARY', 'A brief history of time'),
                          ('END', b'VEVENT'), ('END', b'VCALENDAR')])

        # We can also enumerate property items just under the component.
        self.assertEqual(c.property_items(recursive=False),
                         [('BEGIN', b'VCALENDAR'),
                          ('ATTENDEE', prop.vCalAddress('Max M')),
                          ('END', b'VCALENDAR')])

        sc = c.subcomponents[0]
        self.assertEqual(sc.property_items(recursive=False),
                         [('BEGIN', b'VEVENT'), ('DTEND', '20000102T000000'),
                          ('DTSTART', '20000101T000000'),
                          ('SUMMARY', 'A brief history of time'),
                          ('END', b'VEVENT')])

        # Text fields which span multiple mulitple lines require proper
        # indenting
        c = Calendar()
        c['description'] = u'Paragraph one\n\nParagraph two'
        self.assertEqual(
            c.to_ical(),
            b'BEGIN:VCALENDAR\r\nDESCRIPTION:Paragraph one\\n\\nParagraph two'
            + b'\r\nEND:VCALENDAR\r\n')

        # INLINE properties have their values on one property line. Note the
        # double quoting of the value with a colon in it.
        c = Calendar()
        c['resources'] = 'Chair, Table, "Room: 42"'
        self.assertEqual(c, Calendar({'RESOURCES':
                                      'Chair, Table, "Room: 42"'}))

        self.assertEqual(
            c.to_ical(),
            b'BEGIN:VCALENDAR\r\nRESOURCES:Chair\\, Table\\, "Room: 42"\r\n' +
            b'END:VCALENDAR\r\n')

        # The inline values must be handled by the get_inline() and
        # set_inline() methods.
        self.assertEqual(c.get_inline('resources', decode=0),
                         [u'Chair', u'Table', u'Room: 42'])

        # These can also be decoded
        self.assertEqual(c.get_inline('resources', decode=1),
                         [b'Chair', b'Table', b'Room: 42'])

        # You can set them directly ...
        c.set_inline('resources', ['A', 'List', 'of', 'some, recources'],
                     encode=1)
        self.assertEqual(c['resources'], 'A,List,of,"some, recources"')

        # ... and back again
        self.assertEqual(c.get_inline('resources', decode=0),
                         ['A', 'List', 'of', 'some, recources'])

        c['freebusy'] = '19970308T160000Z/PT3H,19970308T200000Z/PT1H,'\
                        + '19970308T230000Z/19970309T000000Z'
        self.assertEqual(c.get_inline('freebusy', decode=0), [
            '19970308T160000Z/PT3H', '19970308T200000Z/PT1H',
            '19970308T230000Z/19970309T000000Z'
        ])

        freebusy = c.get_inline('freebusy', decode=1)
        self.assertTrue(isinstance(freebusy[0][0], datetime))
        self.assertTrue(isinstance(freebusy[0][1], timedelta))
     elif cmd == 'S':
         sem = arg
     elif cmd == 'H':
         start, end = arg.split('-')
         shour, smin = start.split('.')
         ehour, emin = end.split('.')
     elif cmd == 'T':
         title = arg
     elif cmd == 'L':
         location = arg
     elif cmd == 'P':
         prof.append(arg)
 else:
     if title is not None and sem.startswith(chosen_sem):
         event = Event()
         event.add('summary', vText(title))
         description = vText(" ".join(prof))
         #event['description'] = description
         event.add('description', vText(description))
         event.add(
             'dtstart',
             datetime(year, month, daynum[day], int(shour), int(smin),
                      0))
         event.add(
             'dtend',
             datetime(year, month, daynum[day], int(ehour), int(emin),
                      0))
         event.add('dtstamp', datetime.now())
         event.add('location', vText(location))
         event.add('rrule', {
             "FREQ": "WEEKLY",
Exemple #25
0
def parse(html):
    """ htmlをパースする """

    root = lxml.html.fromstring(html)

    ical = Calendar()
    yyyymm = root.xpath('//td[@class="dateCell"]/b')[0].text
    year = yyyymm.split(u'年')[0]
    
    for events in root.find_class('eventcell'):

        for event_date in events.find_class('date'):
            event_date = event_date.text

        for event in events.find_class('eventInner'):
            event_line = {'time': '', 'detail': ''}
            ical_event = Event()

            for item in event:
                if (item.tag == 'li'):
                    event_line['time'] = ''
                    event_line['detail'] = item.find_class('event')[0].text

                if (item.tag == 'span'):
                    for time in item.find_class('eventDateTime'):
                        event_line['time'] = time.text

                    for detail in item.find_class('event'):
                        event_line['detail'] = detail.text

            mmdd = event_date.split('/')
            if (event_line['time'] != ''):
                startend_time = event_line['time'].split('-')
                start_time = startend_time[0]
                start_hhmm = start_time.split(':')
                if (len(startend_time) == 1):
                    event_line['time'] = event_line['time'].strip() + '-' + event_line['time'].strip()
                    end_time = startend_time[0]
                else:
                    end_time = startend_time[1]
                end_hhmm = end_time.split(':')
                ical_event.add('dtstart', datetime(int(year), int(mmdd[0]),
                    int(mmdd[1]), int(start_hhmm[0]), int(start_hhmm[1])))
                ical_event.add('dtend', datetime(int(year), int(mmdd[0]),
                    int(mmdd[1]), int(end_hhmm[0]), int(end_hhmm[1])))
            else:
                start_date = date(int(year), int(mmdd[0]), int(mmdd[1]))
                dtstart_prop = vDate(start_date)
                dtstart_prop.params['VALUE'] = vText('DATE')
                ical_event.add('dtstart',dtstart_prop)
                end_date = date(int(year), int(mmdd[0]), int(mmdd[1]))
                dtend_prop = vDate(end_date)
                dtend_prop.params['VALUE'] = vText('DATE')
                ical_event.add('dtend', dtend_prop)

            ical_event.add('summary', event_line['detail'])
            ical.add_component(ical_event)

    ical.add('version', '2.0')
    ical.add('prodid', '-//kuma//cycal.py//EN')

    return ical.to_ical()
Exemple #26
0
    seen += 1
    (old, todo, new, href, etag, ev) = utils.create_or_update_calendar_item(
        target_collection_url, "VEVENT", uid)
    out = Calendar()
    if import_url is not None:
        out['X-IMPORTED-FROM-URL'] = vUri(import_url)
    # If this is not an iTIP request, then make it one.
    if "METHOD" not in out and opts.invite:
        out["METHOD"] = "REQUEST"
    out.update(list(orig.items()))
    for c in other:
        out.add_component(c)
    if opts.category:
        if isinstance(ev.get('CATEGORIES', ''), vText):
            ev['CATEGORIES'] = [ev['CATEGORIES']]
        ev.setdefault('categories', []).append(vText(opts.category))
    if opts.status and 'STATUS' not in ev:
        ev['STATUS'] = opts.status.upper()
    out.add_component(ev)
    write = hasChanged(old, out)
    if write:
        if old is None:
           added += 1
           utils.add_member(target_collection_url, 'text/calendar', out.to_ical())
        else:
           changed += 1
           utils.put(href, 'text/calendar', out.to_ical(), if_match=[etag])

logger.info('Processed %s. Seen %d, updated %d, new %d', opts.prefix,
             seen, changed, added)
Exemple #27
0
    def get_calendar_entry(self):
        """
        Build the iCalendar string for the event
        iCal validator, useful for debugging: http://icalvalid.cloudapp.net/
        """
        event = self.event
        event_tz = event.timezone
        creation_time = django_timezone.now()

        # Generate some description strings
        title, desc_plain, _desc_html = self.get_invite_texts()

        # Generate the Calendar event
        cal = icalendar.Calendar()
        cal.add("prodid", "-//OneEvent event entry//onevent//EN")
        cal.add("version", "2.0")
        cal.add("calscale", "GREGORIAN")
        cal.add("method", "REQUEST")

        # Generate timezone infos relevant to the event
        tzmap = {}
        tzmap = add_to_zones_map(tzmap, event_tz.zone, event.start)
        tzmap = add_to_zones_map(tzmap, event_tz.zone, event.get_real_end())
        tzmap = add_to_zones_map(tzmap,
                                 django_timezone.get_default_timezone_name(),
                                 creation_time)

        for tzid, transitions in tzmap.items():
            cal_tz = icalendar.Timezone()
            cal_tz.add("tzid", tzid)
            cal_tz.add("x-lic-location", tzid)

            for transition, tzinfo in transitions.items():

                if tzinfo["dst"]:
                    cal_tz_sub = icalendar.TimezoneDaylight()
                else:
                    cal_tz_sub = icalendar.TimezoneStandard()

                cal_tz_sub.add("tzname", tzinfo["name"])
                cal_tz_sub.add("dtstart", transition)
                cal_tz_sub.add("tzoffsetfrom", tzinfo["tzoffsetfrom"])
                cal_tz_sub.add("tzoffsetto", tzinfo["tzoffsetto"])
                cal_tz.add_component(cal_tz_sub)
            cal.add_component(cal_tz)

        cal_evt = icalendar.Event()

        cal_evt.add("uid",
                    "event{0}-booking{1}@oneevent".format(event.id, self.id))
        cal_evt.add("dtstamp", creation_time)
        cal_evt.add("dtstart", event.start.astimezone(event_tz))
        cal_evt.add("dtend", event.get_real_end().astimezone(event_tz))
        cal_evt.add("created", creation_time)
        cal_evt.add("sequence", "1")

        cal_evt.add("summary", title)
        cal_evt.add("description", desc_plain)
        cal_evt.add("location", vText(event.location_name))

        cal_evt.add("category", "Event")
        cal_evt.add("status", "CONFIRMED")
        cal_evt.add("transp", "OPAQUE")
        cal_evt.add("priority", "5")
        cal_evt.add("class", "PUBLIC")

        organiser = vCalAddress("mailto:{0}".format(event.owner.email))
        organiser.params["cn"] = vText(event.owner.get_full_name())
        organiser.params["role"] = vText("CHAIR")
        cal_evt.add("organizer", organiser, encode=0)

        attendee = vCalAddress("mailto:{0}".format(self.person.email))
        attendee.params["cutype"] = vText("INDIVIDUAL")
        attendee.params["role"] = vText("REQ-PARTICIPANT")
        attendee.params["partstat"] = vText("NEEDS-ACTION")
        attendee.params["rsvp"] = vText("FALSE")
        attendee.params["cn"] = vText(self.person.get_full_name())
        cal_evt.add("attendee", attendee, encode=0)

        cal.add_component(cal_evt)

        return cal.to_ical()
Exemple #28
0
added = 0
seen = 0

for (uid, ev) in items.iteritems():
    seen += 1
    fname = "%s-%s.ics" % (opts.prefix, uid.replace("/", ""))
    path = os.path.join(opts.outdir, fname)
    out = Calendar()
    out['X-IMPORTED-FROM-URL'] = vUri(url)
    out.update(orig.items())
    for c in other:
        out.add_component(c)
    if opts.category:
        if isinstance(ev.get('categories', ''), vText):
            ev['categories'] = [ev['categories']]
        ev.setdefault('categories', []).append(vText(opts.category))
    if opts.status and not 'status' in ev:
        ev['status'] = opts.status.upper()
    out.add_component(ev)
    try:
        old = Calendar.from_ical(open(path, 'rb').read())
    except IOError:
        old = None
        write = True
    else:
        write = hasChanged(old, out)
    if write:
        if not os.path.exists(path):
           added += 1
        else:
           changed += 1
Exemple #29
0
        return True
    for item in curr.split (","):
        if item.upper () in filter:
            return True
    return False

# generate importance filter string
imp_list = []
for i in xrange(imp, 3):
    imp_list.append ("%d" % i)
imp_filter = "(" + ",".join (imp_list) + ")"

q = db.GqlQuery ("select * from News_Record_v2 where when > :1 and when < :2 and importance in %s order by when" % imp_filter, d_from, d_to)
id = 0
for ev in q:
    if not check_filter (curr_filter, ev.curr):
        continue
    event = Event ()
    event['uid'] = "*****@*****.**" % (id, time.mktime (ev.when.timetuple ()))
    event['summary'] = vText (u"%s, Imp: %s" % (norm_str (ev.title), news.val2imp (ev.importance)))
    event['description'] = vText ("Prev: %s\\, Fore: %s" % (norm_str (ev.pred), norm_str (ev.fore)))
    event['dtstamp'] = ev.when.strftime ("%Y%m%dT%H%M%SZ")
    event['dtstart'] = ev.when.strftime ("%Y%m%dT%H%M%SZ")
    event['dtend'] = (ev.when + datetime.timedelta (minutes = 10)).strftime ("%Y%m%dT%H%M%SZ")
    event['priority'] = 0
    cal.add_component (event)
    id += 1


print cal.as_string (),
Exemple #30
0
# generate importance filter string
imp_list = []
for i in xrange(imp, 3):
    imp_list.append("%d" % i)
imp_filter = "(" + ",".join(imp_list) + ")"

q = db.GqlQuery(
    "select * from News_Record_v2 where when > :1 and when < :2 and importance in %s order by when"
    % imp_filter, d_from, d_to)
id = 0
for ev in q:
    if not check_filter(curr_filter, ev.curr):
        continue
    event = Event()
    event['uid'] = "*****@*****.**" % (
        id, time.mktime(ev.when.timetuple()))
    event['summary'] = vText(u"%s, Imp: %s" %
                             (norm_str(ev.title), news.val2imp(ev.importance)))
    event['description'] = vText("Prev: %s\\, Fore: %s" %
                                 (norm_str(ev.pred), norm_str(ev.fore)))
    event['dtstamp'] = ev.when.strftime("%Y%m%dT%H%M%SZ")
    event['dtstart'] = ev.when.strftime("%Y%m%dT%H%M%SZ")
    event['dtend'] = (
        ev.when + datetime.timedelta(minutes=10)).strftime("%Y%m%dT%H%M%SZ")
    event['priority'] = 0
    cal.add_component(event)
    id += 1

print cal.as_string(),
Exemple #31
0
        datestr += time.strftime(' %Y')
    dtstart = datetime.datetime.strptime(datestr, "%d %b %Y")
    dtend = None
    duration = datetime.timedelta(1)


props = {
    'categories': opts.categories.split(','),
    'dtstart': vDate(dtstart.date()),
    'created': vDatetime(datetime.datetime.now()),
    'class': 'PUBLIC',
    }
if status is not None:
    props['status'] = status
if location is not None:
    props['location'] = vText(location)
if opts.url:
    props['url'] = vUri(opts.url)
if description is not None:
    props['summary'] = vText(description)
if dtend is not None:
    props['dtend'] = vDate(dtend.date())
if duration is not None:
    props['duration'] = vDuration(duration)

ev = Event(**props)

c = Calendar()
c.add_component(ev)

md5 = hashlib.md5()
Exemple #32
0
    def test_cal_Component(self):
        from icalendar.cal import Component, Calendar, Event
        from icalendar import prop

        # 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 item. This can be set with a single value...
        c["prodid"] = "-//max m//icalendar.mxm.dk/"
        self.assertEqual(c, Calendar({"PRODID": "-//max m//icalendar.mxm.dk/"}))

        # or with a list
        c["ATTENDEE"] = ["Max M", "Rasmussen"]
        self.assertEqual(c, Calendar({"ATTENDEE": ["Max M", "Rasmussen"], "PRODID": "-//max m//icalendar.mxm.dk/"}))

        ### ADD MULTIPLE VALUES TO A PROPERTY

        # if you use the add method you don't have to considder if a value is
        # a list or not.
        c = Component()
        c.name = "VEVENT"

        # add multiple values at once
        c.add("attendee", ["*****@*****.**", "*****@*****.**"])

        # or add one per line
        c.add("attendee", "*****@*****.**")
        c.add("attendee", "*****@*****.**")

        # add again multiple values at once to very concatenaton of lists
        c.add("attendee", ["*****@*****.**", "*****@*****.**"])

        self.assertEqual(
            c,
            Event(
                {
                    "ATTENDEE": [
                        prop.vCalAddress("*****@*****.**"),
                        prop.vCalAddress("*****@*****.**"),
                        prop.vCalAddress("*****@*****.**"),
                        prop.vCalAddress("*****@*****.**"),
                        prop.vCalAddress("*****@*****.**"),
                        prop.vCalAddress("*****@*****.**"),
                    ]
                }
            ),
        )

        ###

        # You can get the values back directly ...
        c.add("prodid", "-//my product//")
        self.assertEqual(c["prodid"], prop.vText(u"-//my product//"))

        # ... or decoded to a python type
        self.assertEqual(c.decoded("prodid"), b"-//my product//")

        # With default values for non existing properties
        self.assertEqual(c.decoded("version", "No Version"), "No Version")

        c.add("rdate", [datetime(2013, 3, 28), datetime(2013, 3, 27)])
        self.assertTrue(isinstance(c.decoded("rdate"), prop.vDDDLists))

        # The component can render itself in the RFC 2445 format.
        c = Component()
        c.name = "VCALENDAR"
        c.add("attendee", "Max M")
        self.assertEqual(c.to_ical(), b"BEGIN:VCALENDAR\r\nATTENDEE:Max M\r\nEND:VCALENDAR\r\n")

        # Components can be nested, so You can add a subcompont. Eg a calendar
        # holds events.
        e = Component(summary="A brief history of time")
        e.name = "VEVENT"
        e.add("dtend", "20000102T000000", encode=0)
        e.add("dtstart", "20000101T000000", encode=0)
        self.assertEqual(
            e.to_ical(),
            b"BEGIN:VEVENT\r\nDTEND:20000102T000000\r\n"
            + b"DTSTART:20000101T000000\r\nSUMMARY:A brief history of time\r"
            + b"\nEND:VEVENT\r\n",
        )

        c.add_component(e)
        self.assertEqual(
            c.subcomponents,
            [Event({"DTEND": "20000102T000000", "DTSTART": "20000101T000000", "SUMMARY": "A brief history of time"})],
        )

        # We can walk over nested componentes with the walk method.
        self.assertEqual([i.name for i in c.walk()], ["VCALENDAR", "VEVENT"])

        # We can also just walk over specific component types, by filtering
        # them on their name.
        self.assertEqual([i.name for i in c.walk("VEVENT")], ["VEVENT"])

        self.assertEqual([i["dtstart"] for i in c.walk("VEVENT")], ["20000101T000000"])

        # We can enumerate property items recursively with the property_items
        # method.
        self.assertEqual(
            c.property_items(),
            [
                ("BEGIN", b"VCALENDAR"),
                ("ATTENDEE", prop.vCalAddress("Max M")),
                ("BEGIN", b"VEVENT"),
                ("DTEND", "20000102T000000"),
                ("DTSTART", "20000101T000000"),
                ("SUMMARY", "A brief history of time"),
                ("END", b"VEVENT"),
                ("END", b"VCALENDAR"),
            ],
        )

        # We can also enumerate property items just under the component.
        self.assertEqual(
            c.property_items(recursive=False),
            [("BEGIN", b"VCALENDAR"), ("ATTENDEE", prop.vCalAddress("Max M")), ("END", b"VCALENDAR")],
        )

        sc = c.subcomponents[0]
        self.assertEqual(
            sc.property_items(recursive=False),
            [
                ("BEGIN", b"VEVENT"),
                ("DTEND", "20000102T000000"),
                ("DTSTART", "20000101T000000"),
                ("SUMMARY", "A brief history of time"),
                ("END", b"VEVENT"),
            ],
        )

        # Text fields which span multiple mulitple lines require proper
        # indenting
        c = Calendar()
        c["description"] = u"Paragraph one\n\nParagraph two"
        self.assertEqual(
            c.to_ical(), b"BEGIN:VCALENDAR\r\nDESCRIPTION:Paragraph one\\n\\nParagraph two" + b"\r\nEND:VCALENDAR\r\n"
        )

        # INLINE properties have their values on one property line. Note the
        # double quoting of the value with a colon in it.
        c = Calendar()
        c["resources"] = 'Chair, Table, "Room: 42"'
        self.assertEqual(c, Calendar({"RESOURCES": 'Chair, Table, "Room: 42"'}))

        self.assertEqual(
            c.to_ical(), b'BEGIN:VCALENDAR\r\nRESOURCES:Chair\\, Table\\, "Room: 42"\r\n' + b"END:VCALENDAR\r\n"
        )

        # The inline values must be handled by the get_inline() and
        # set_inline() methods.
        self.assertEqual(c.get_inline("resources", decode=0), [u"Chair", u"Table", u"Room: 42"])

        # These can also be decoded
        self.assertEqual(c.get_inline("resources", decode=1), [b"Chair", b"Table", b"Room: 42"])

        # You can set them directly ...
        c.set_inline("resources", ["A", "List", "of", "some, recources"], encode=1)
        self.assertEqual(c["resources"], 'A,List,of,"some, recources"')

        # ... and back again
        self.assertEqual(c.get_inline("resources", decode=0), ["A", "List", "of", "some, recources"])

        c["freebusy"] = "19970308T160000Z/PT3H,19970308T200000Z/PT1H," + "19970308T230000Z/19970309T000000Z"
        self.assertEqual(
            c.get_inline("freebusy", decode=0),
            ["19970308T160000Z/PT3H", "19970308T200000Z/PT1H", "19970308T230000Z/19970309T000000Z"],
        )

        freebusy = c.get_inline("freebusy", decode=1)
        self.assertTrue(isinstance(freebusy[0][0], datetime))
        self.assertTrue(isinstance(freebusy[0][1], timedelta))
    def get_calendar(self):
        # Create calendar object
        cal = icalendar.Calendar()

        for j in self.jobs:
            e = icalendar.Event()

            # Add title and description
            e.add('summary', j.title.encode('utf-8'))
            e.add('description', j.event.get_description().encode('utf-8'))

            # Add place
            e.add('location', vText(j.event.place).encode('utf-8'))

            # Now, get start and end-time
            for info in job_list:
                if info.name == j.t:
                    start_date = j.event.date
                    # Look for fixed start
                    if re.search('arb.*', j.event.time.additional, re.IGNORECASE):
                        start = self.format_time(j.event.time.t_start)
                        start_delta = 0
                    # Has introduction
                    elif info.t_einf and j.event.time.t_einf:
                        start = self.format_time(j.event.time.t_einf)
                        start_delta = - info.t_einf
                    # Has regular start
                    elif (info.t_start and j.event.time.t_start):
                        start = self.format_time(j.event.time.t_start)
                        start_delta = - info.t_start
                    # Has no start, no intro, but an end time! -> comp start time
                    elif j.event.time.t_end:
                        start_date = j.event.date_end  # Use different date!
                        start = self.format_time(j.event.time.t_end)
                        start_delta = - info.t_duration
                    else:
                        print('time data insufficient for:\n%s!' % str(j))
                        exit

                    e.add('dtstart', datetime.datetime.combine(start_date,
                          start) + datetime.timedelta(minutes=start_delta))

                    # Compute ending time
                    # # Case 1: there is a fixed ending
                    if not j.event.time.t_end == "":
                        end = self.format_time(j.event.time.t_end)
                        end_delta = 0
                    # # Case 2: no fixed end
                    else:
                        end = self.format_time(j.event.time.t_start)
                        end_delta = start_delta + info.t_duration

                    e.add('dtend', datetime.datetime.combine(j.event.date_end,
                          end) + datetime.timedelta(minutes=end_delta))

            # timestamp
            e.add('dtstamp', datetime.datetime.now())

            # Add to calendar
            cal.add_component(e)

        # give calendar
        return cal