Example #1
0
    def __init__(self, collection, conf, date_list, location=None, repeat=None):
        try:
            event = aux.construct_event(
                date_list,
                location=location,
                repeat=repeat,
                **conf['locale'])
        except FatalError:
            sys.exit(1)
        event = Event(event,
                      collection.default_calendar_name,
                      locale=conf['locale'],
                      )

        try:
            collection.new(event)
        except ReadOnlyCalendarError:
            logger.fatal('ERROR: Cannot modify calendar "{}" as it is '
                         'read-only'.format(collection.default_calendar_name))
            sys.exit(1)
        if conf['default']['print_new'] == 'event':
            echo(event.long())
        elif conf['default']['print_new'] == 'path':
            path = collection._calnames[event.calendar].path + event.href
            echo(path.encode(conf['locale']['encoding']))
Example #2
0
 def test_raw_dt(self):
     event = Event(event_dt, **event_kwargs)
     assert event.raw.split('\r\n') == cal_dt
     assert event.compact(datetime.date(2014, 4, 9)) == u'09:30-10:30: An Event'
     event = Event(event_dt, unicode_symbols=False, **event_kwargs)
     assert event.compact(datetime.date(2014, 4, 9)) == u'09:30-10:30: An Event'
     assert event.recur is False
Example #3
0
def test_update_simple():
    event = Event.fromString(_get_text('event_dt_simple'), **EVENT_KWARGS)
    event_updated = Event.fromString(_get_text('event_dt_simple_updated'), **EVENT_KWARGS)
    event.update_summary('A not so simple Event')
    event.update_description('Everything has changed')
    event.update_location('anywhere')
    assert normalize_component(event.raw) == normalize_component(event_updated.raw)
Example #4
0
def test_dt_two_tz():
    event = Event(event_dt_two_tz, **event_kwargs)
    assert normalize_component(cal_dt_two_tz) == normalize_component(event.raw)

    # local (Berlin) time!
    assert event.compact(datetime.date(2014, 4, 9)) == u'09:30-16:30: An Event'
    assert event.long() == u'09:30-16:30 09.04.2014: An Event'
Example #5
0
 def test_event_rr(self):
     event = Event(event_dt_rr, **event_kwargs)
     assert event.recur is True
     assert event.compact(datetime.date(2014, 4, 9)) == u'09:30-10:30: An Event ⟳'
     event = Event(event_d_rr, **event_kwargs)
     assert event.recur is True
     assert event.compact(datetime.date(2014, 4, 9)) == u'Another Event ⟳'
Example #6
0
def test_cancelled_instance():
    orig_event_str = _get_text('event_rrule_recuid_cancelled')
    event = Event.fromString(orig_event_str, ref='1405314000', **EVENT_KWARGS)
    assert event.format(SEARCH_FORMAT, dt.date(2014, 7, 14)) == \
        'CANCELLED 14.07.2014 07:00-12:00 Arbeit ⟳\x1b[0m'
    event = Event.fromString(orig_event_str, ref='PROTO', **EVENT_KWARGS)
    assert event.format(SEARCH_FORMAT, dt.date(2014, 7, 14)) == \
        '30.06.2014 07:00-12:00 Arbeit ⟳\x1b[0m'
Example #7
0
def test_event_no_dst():
    """test the creation of a corect VTIMEZONE for timezones with no dst"""
    bogota_locale = locale.copy()
    bogota_locale['local_timezone'] = bogota
    bogota_locale['default_timezone'] = bogota

    event = Event(event_no_dst, calendar='foobar', locale=bogota_locale)
    assert event.raw.split('\r\n') == cal_no_dst
    assert event.long() == u'09:30-10:30 09.04.2014: An Event'
Example #8
0
def test_raw_dt():
    event = Event(event_dt, **event_kwargs)
    assert normalize_component(event.raw) == normalize_component(cal_dt)
    assert event.compact(datetime.date(2014, 4, 9)) == u'09:30-10:30: An Event'

    event = Event(event_dt, unicode_symbols=False, **event_kwargs)
    assert event.compact(datetime.date(2014, 4, 9)) == u'09:30-10:30: An Event'
    assert event.long() == u'09:30-10:30 09.04.2014: An Event'
    assert event.recur is False
Example #9
0
 def test_list(self, coll_vdirs):
     coll, vdirs = coll_vdirs
     event = Event.fromString(event_d, calendar=cal1, locale=aux.locale)
     coll.new(event)
     event = Event.fromString(event_today, calendar=cal1, locale=aux.locale)
     coll.new(event)
     hrefs = sorted(href for href, uid in coll._backend.list(cal1))
     assert set(str(coll._backend.get(href, calendar=cal1).uid) for href in hrefs) == set((
         '*****@*****.**',
         'V042MJ8B3SJNFXQOJL6P53OFMHJE8Z3VZWOU',
     ))
Example #10
0
 def test_list(self, cal_vdir):
     cal, vdir = cal_vdir
     event = Event.fromString(event_d, calendar=cal.name, locale=aux.locale)
     cal.new(event)
     event = Event.fromString(event_today, calendar=cal.name, locale=aux.locale)
     cal.new(event)
     hrefs = sorted(href for href, uid in cal._dbtool.list())
     assert set(str(cal._dbtool.get(href).uid) for href in hrefs) == set((
         '*****@*****.**',
         'V042MJ8B3SJNFXQOJL6P53OFMHJE8Z3VZWOU',
     ))
Example #11
0
 def test_list(self, cal_vdir):
     cal, vdir = cal_vdir
     event = Event.fromString(event_d, calendar=cal.name, locale=locale)
     cal.new(event)
     event = Event.fromString(event_today, calendar=cal.name, locale=locale)
     cal.new(event)
     hrefs = sorted(href for href, uid in cal._dbtool.list())
     assert hrefs == [
         'V042MJ8B3SJNFXQOJL6P53OFMHJE8Z3VZWOU.ics',
         '*****@*****.**'
     ]
     assert cal._dbtool.get('*****@*****.**').uid == '*****@*****.**'
Example #12
0
def test_event_dt_tz_missing():
    """localized event DTSTART;TZID=foo, but VTIMEZONE components missing"""
    event_str = _get_text('event_dt_local_missing_tz')
    event = Event.fromString(event_str, **EVENT_KWARGS)
    assert event.start == BERLIN.localize(datetime(2014, 4, 9, 9, 30))
    assert event.end == BERLIN.localize(datetime(2014, 4, 9, 10, 30))
    assert event.start_local == BERLIN.localize(datetime(2014, 4, 9, 9, 30))
    assert event.end_local == BERLIN.localize(datetime(2014, 4, 9, 10, 30))

    event = Event.fromString(event_str, calendar='foobar', locale=MIXED_LOCALE)
    assert event.start == BERLIN.localize(datetime(2014, 4, 9, 9, 30))
    assert event.end == BERLIN.localize(datetime(2014, 4, 9, 10, 30))
    assert event.start_local == BOGOTA.localize(datetime(2014, 4, 9, 2, 30))
    assert event.end_local == BOGOTA.localize(datetime(2014, 4, 9, 3, 30))
Example #13
0
def test_event_dt_tz_missing():
    """localized event DTSTART;TZID=foo, but VTIMEZONE components missing"""
    event_str = _get_text('event_dt_local_missing_tz')
    event = Event.fromString(event_str, **EVENT_KWARGS)
    assert event.start == BERLIN.localize(dt.datetime(2014, 4, 9, 9, 30))
    assert event.end == BERLIN.localize(dt.datetime(2014, 4, 9, 10, 30))
    assert event.start_local == BERLIN.localize(dt.datetime(2014, 4, 9, 9, 30))
    assert event.end_local == BERLIN.localize(dt.datetime(2014, 4, 9, 10, 30))
    assert event.format('{duration}', relative_to=dt.date.today()) == '1h\x1b[0m'

    event = Event.fromString(event_str, calendar='foobar', locale=LOCALE_MIXED)
    assert event.start == BERLIN.localize(dt.datetime(2014, 4, 9, 9, 30))
    assert event.end == BERLIN.localize(dt.datetime(2014, 4, 9, 10, 30))
    assert event.start_local == BOGOTA.localize(dt.datetime(2014, 4, 9, 2, 30))
    assert event.end_local == BOGOTA.localize(dt.datetime(2014, 4, 9, 3, 30))
Example #14
0
def test_transform_event():
    """test if transformation between different event types works"""
    event_d = _get_text('event_d')
    event = Event.fromString(event_d, **EVENT_KWARGS)
    assert isinstance(event, AllDayEvent)
    start = BERLIN.localize(datetime(2014, 4, 9, 9, 30))
    end = BERLIN.localize(datetime(2014, 4, 9, 10, 30))
    event.update_start_end(start, end)
    assert isinstance(event, LocalizedEvent)
    assert event.event_description == '09:30-10:30 09.04.2014: An Event'
    analog_event = Event.fromString(_get_text('event_dt_simple'), **EVENT_KWARGS)
    assert normalize_component(event.raw) == normalize_component(analog_event.raw)

    with pytest.raises(ValueError):
        event.update_start_end(start, date(2014, 4, 9))
Example #15
0
def test_event_d_rr():
    event_d_rr = _get_text('event_d_rr')
    event = Event.fromString(event_d_rr, **EVENT_KWARGS)
    assert event.recurring is True
    desc = 'Another Event ⟳'
    assert event.relative_to(date(2014, 4, 9)) == desc
    assert event.event_description == '09.04.2014: Another Event\nRepeat: FREQ=DAILY;COUNT=10'

    start = date(2014, 4, 10)
    end = date(2014, 4, 11)
    event = Event.fromString(event_d_rr, start=start, end=end, **EVENT_KWARGS)
    assert event.recurring is True
    desc = 'Another Event ⟳'
    assert event.relative_to(date(2014, 4, 10)) == desc
    assert event.event_description == '10.04.2014: Another Event\nRepeat: FREQ=DAILY;COUNT=10'
Example #16
0
def new_from_args(collection, calendar_name, conf, dtstart=None, dtend=None,
                  summary=None, description=None, allday=None, location=None,
                  categories=None, repeat=None, until=None, alarms=None,
                  timezone=None, format=None, env=None):

    try:
        event = aux.new_event(locale=conf['locale'], location=location,
                              categories=categories, repeat=repeat, until=until,
                              alarms=alarms, dtstart=dtstart, dtend=dtend,
                              summary=summary, description=description,
                              timezone=timezone)
    except ValueError as e:
        logger.fatal('ERROR: '+str(e))
        sys.exit(1)
    except FatalError:
        sys.exit(1)
    event = Event.fromVEvents(
        [event], calendar=calendar_name, locale=conf['locale'])

    try:
        collection.new(event)
    except ReadOnlyCalendarError:
        logger.fatal('ERROR: Cannot modify calendar "{}" as it is '
                     'read-only'.format(calendar_name))
        sys.exit(1)

    if conf['default']['print_new'] == 'event':
        if format is None:
            format = conf['view']['event_format']
        echo(event.format(format, datetime.now(), env=env))
    elif conf['default']['print_new'] == 'path':
        path = collection._calnames[event.calendar].path + event.href
        echo(path)
    return event
Example #17
0
def test_no_end():
    """reading an event with neither DTEND nor DURATION"""
    event = Event.fromString(_get_text('event_dt_no_end'), **EVENT_KWARGS)
    # TODO make sure the event also gets converted to an all day event, as we
    # usually do
    assert event.format(SEARCH_FORMAT, dt.date(2014, 4, 12)) == \
        '16.01.2016 08:00-17.01.2016 08:00 Test\x1b[0m'
Example #18
0
def test_remove_instance_from_two_rdate():
    """removing an instance from a recurring event which has two RDATE props"""
    event = Event.fromString(_get_text('event_dt_two_rd'), **EVENT_KWARGS)
    assert event.raw.count('RDATE') == 2
    event.delete_instance(datetime(2014, 4, 10, 9, 30))
    assert event.raw.count('RDATE') == 1
    assert 'RDATE:20140411T093000,20140412T093000' in event.raw.split('\r\n')
Example #19
0
def new_from_string(collection, calendar_name, conf, date_list, location=None, repeat=None,
                    until=None):
    """construct a new event from a string and add it"""
    try:
        event = aux.construct_event(
            date_list,
            location=location,
            repeat=repeat,
            until=until,
            locale=conf['locale'])
    except FatalError:
        sys.exit(1)
    event = Event.fromVEvents(
        [event], calendar=calendar_name, locale=conf['locale'])

    try:
        collection.new(event)
    except ReadOnlyCalendarError:
        logger.fatal('ERROR: Cannot modify calendar "{}" as it is '
                     'read-only'.format(calendar_name))
        sys.exit(1)
    if conf['default']['print_new'] == 'event':
        echo(event.event_description)
    elif conf['default']['print_new'] == 'path':
        path = collection._calnames[event.calendar].path + event.href
        echo(path.encode(conf['locale']['encoding']))
Example #20
0
 def test_search(self, coll_vdirs):
     coll, vdirs = coll_vdirs
     assert len(list(coll.search('Event'))) == 0
     event = Event.fromString(
         _get_text('event_dt_simple'), calendar=cal1, locale=aux.locale)
     coll.new(event, cal1)
     assert len(list(coll.search('Event'))) == 1
Example #21
0
def test_event_no_dst():
    """test the creation of a corect VTIMEZONE for timezones with no dst"""
    event_no_dst = _get_text('event_no_dst')
    cal_no_dst = _get_text('cal_no_dst')
    event = Event.fromString(event_no_dst, calendar='foobar', locale=BOGOTA_LOCALE)
    assert normalize_component(event.raw) == normalize_component(cal_no_dst)
    assert event.event_description == '09:30-10:30 09.04.2014: An Event'
Example #22
0
def test_remove_instance_from_rrule():
    """removing an instance from a recurring event"""
    event = Event.fromString(_get_text('event_dt_rr'), **EVENT_KWARGS)
    event.delete_instance(datetime(2014, 4, 10, 9, 30))
    assert 'EXDATE:20140410T093000' in event.raw.split('\r\n')
    event.delete_instance(datetime(2014, 4, 12, 9, 30))
    assert 'EXDATE:20140410T093000,20140412T093000' in event.raw.split('\r\n')
Example #23
0
def test_update_event_d():
    event_d = _get_text('event_d')
    event = Event.fromString(event_d, **EVENT_KWARGS)
    event.update_start_end(date(2014, 4, 20), date(2014, 4, 22))
    assert event.event_description == '20.04. - 22.04.2014: An Event'
    assert 'DTSTART;VALUE=DATE:20140420' in event.raw.split('\r\n')
    assert 'DTEND;VALUE=DATE:20140423' in event.raw.split('\r\n')
Example #24
0
def test_multi_uid():
    """test for support for events with consist of several sub events with
    the same uid"""
    orig_event_str = _get_text('event_rrule_recuid')
    event = Event.fromString(orig_event_str, **EVENT_KWARGS)
    for line in orig_event_str.split('\n'):
        assert line in event.raw.split('\r\n')
Example #25
0
def test_event_d_rr():
    event_d_rr = _get_text('event_d_rr')
    event = Event.fromString(event_d_rr, **EVENT_KWARGS)
    assert event.recurring is True
    assert event.format(LIST_FORMAT, date(2014, 4, 9)) == ' Another Event ⟳\x1b[0m'
    assert event.format(SEARCH_FORMAT, date(2014, 4, 9)) == \
        '09.04.2014 Another Event ⟳\x1b[0m'
    assert event.format('{repeat-pattern}', date(2014, 4, 9)) == 'FREQ=DAILY;COUNT=10\x1b[0m'

    start = date(2014, 4, 10)
    end = date(2014, 4, 11)
    event = Event.fromString(event_d_rr, start=start, end=end, **EVENT_KWARGS)
    assert event.recurring is True
    assert event.format(LIST_FORMAT, date(2014, 4, 10)) == ' Another Event ⟳\x1b[0m'
    assert event.format(SEARCH_FORMAT, date(2014, 4, 10)) == \
        '10.04.2014 Another Event ⟳\x1b[0m'
Example #26
0
def test_event_dt_duration():
    """event has no end, but duration"""
    event_dt_duration = _get_text('event_dt_duration')
    event = Event.fromString(event_dt_duration, **EVENT_KWARGS)
    assert event.relative_to(date(2014, 4, 9)) == u'09:30-10:30: An Event'
    assert event.end == BERLIN.localize(datetime(2014, 4, 9, 10, 30))
    assert event.event_description == u'09:30-10:30 09.04.2014: An Event'
Example #27
0
def test_event_no_dst():
    """test the creation of a corect VTIMEZONE for timezones with no dst"""
    event_no_dst = _get_text('event_no_dst')
    cal_no_dst = _get_text('cal_no_dst')
    event = Event.fromString(event_no_dst, calendar='foobar', locale=BOGOTA_LOCALE)
    assert normalize_component(event.raw) == normalize_component(cal_no_dst)
    assert event.format(SEARCH_FORMAT, date(2014, 4, 10)) == \
        '09.04.2014 09:30-10:30 An Event \x1b[0m'
Example #28
0
def test_raw_dt():
    event_dt = _get_text('event_dt_simple')
    start = BERLIN.localize(datetime(2014, 4, 9, 9, 30))
    end = BERLIN.localize(datetime(2014, 4, 9, 10, 30))
    event = Event.fromString(event_dt, start=start, end=end, **EVENT_KWARGS)
    with freeze_time('2016-1-1'):
        assert normalize_component(event.raw) == \
            normalize_component(_get_text('event_dt_simple_inkl_vtimezone'))

    event = Event.fromString(event_dt, **EVENT_KWARGS)
    assert event.format(LIST_FORMAT, date(2014, 4, 9)) == '09:30-10:30 An Event \x1b[0m'
    assert event.format(SEARCH_FORMAT, date(2014, 4, 9)) == \
        '09.04.2014 09:30-10:30 An Event \x1b[0m'
    assert event.recurring is False
    assert event.duration == timedelta(hours=1)
    assert event.uid == 'V042MJ8B3SJNFXQOJL6P53OFMHJE8Z3VZWOU'
    assert event.organizer == ''
Example #29
0
def test_event_dt_long():
    event_dt_long = _get_text('event_dt_long')
    event = Event.fromString(event_dt_long, **EVENT_KWARGS)
    assert event.relative_to(date(2014, 4, 9)) == '09:30→ : An Event'
    # FIXME ugly! replace with one arrow
    assert event.relative_to(date(2014, 4, 10)) == '→ → : An Event'
    assert event.relative_to(date(2014, 4, 12)) == '→ 10:30: An Event'
    assert event.event_description == '09.04.2014 09:30 - 12.04.2014 10:30: An Event'
Example #30
0
def test_remove_instance_from_recuid():
    """remove an istance from an event which is specified via an additional VEVENT
    with the same UID (which we call `recuid` here"""
    event = Event.fromString(_get_text('event_rrule_recuid'), **EVENT_KWARGS)
    assert event.raw.split('\r\n').count('UID:event_rrule_recurrence_id') == 2
    event.delete_instance(BERLIN.localize(datetime(2014, 7, 7, 7, 0)))
    assert event.raw.split('\r\n').count('UID:event_rrule_recurrence_id') == 1
    assert 'EXDATE;TZID=Europe/Berlin:20140707T070000' in event.raw.split('\r\n')
Example #31
0
def import_event(vevent, collection, locale, batch, format=None, env=None):
    """import one event into collection, let user choose the collection

    :type vevent: list of vevents, which can be more than one VEVENT, i.e., the
        same UID, i.e., one "master" event and (optionally) 1+ RECURRENCE-ID events
    :type vevent: list(str)
    """
    # print all sub-events
    if not batch:
        for item in cal_from_ics(vevent).walk():
            if item.name == 'VEVENT':
                event = Event.fromVEvents(
                    [item],
                    calendar=collection.default_calendar_name,
                    locale=locale)
                echo(event.format(format, dt.datetime.now(), env=env))

    # get the calendar to insert into
    if not collection.writable_names:
        raise ConfigurationError(
            'No writable calendars found, aborting import.')
    if len(collection.writable_names) == 1:
        calendar_name = collection.writable_names[0]
    elif batch:
        calendar_name = collection.default_calendar_name
    else:
        calendar_names = sorted(collection.writable_names)
        choices = ', '.join([
            '{}({})'.format(name, num)
            for num, name in enumerate(calendar_names)
        ])
        while True:
            value = prompt(
                "Which calendar do you want to import to? (unique prefixes are fine)\n"
                "{}".format(choices),
                default=collection.default_calendar_name,
            )
            try:
                calendar_name = calendar_names[int(value)]
                break
            except (ValueError, IndexError):
                matches = [
                    x for x in collection.writable_names if x.startswith(value)
                ]
                if len(matches) == 1:
                    calendar_name = matches[0]
                    break
            echo('invalid choice')
    assert calendar_name in collection.writable_names

    if batch or confirm("Do you want to import this event into `{}`?".format(
            calendar_name)):
        try:
            collection.new(Item(vevent), collection=calendar_name)
        except DuplicateUid:
            if batch or confirm(
                    "An event with the same UID already exists. Do you want to update it?"
            ):
                collection.force_update(Item(vevent), collection=calendar_name)
            else:
                logger.warning("Not importing event with UID `{}`".format(
                    event.uid))
Example #32
0
 def test_raw_d(self):
     assert Event(event_d, **event_kwargs).raw.split('\r\n') == cal_d