def test_invalid(self): with pytest.raises(DateTimeParseError): guessrangefstr('3d', locale=LOCALE_BERLIN) with pytest.raises(DateTimeParseError): guessrangefstr('35.1.2016', locale=LOCALE_BERLIN) with pytest.raises(DateTimeParseError): guessrangefstr('1.1.2016 2x', locale=LOCALE_BERLIN) with pytest.raises(DateTimeParseError): guessrangefstr('1.1.2016x', locale=LOCALE_BERLIN) with pytest.raises(DateTimeParseError): guessrangefstr('xxx yyy zzz', locale=LOCALE_BERLIN)
def start_end_from_daterange(daterange, locale, default_timedelta_date=dt.timedelta(days=1), default_timedelta_datetime=dt.timedelta(hours=1)): """ convert a string description of a daterange into start and end datetime if no description is given, return (today, today + default_timedelta_date) :param daterange: an iterable of strings that describes `daterange` :type daterange: tuple :param locale: locale settings :type locale: dict """ if not daterange: start = dt.datetime(*dt.date.today().timetuple()[:3]) end = start + default_timedelta_date else: start, end, allday = parse_datetime.guessrangefstr( daterange, locale, default_timedelta_date=default_timedelta_date, default_timedelta_datetime=default_timedelta_datetime, ) return start, end
def new_interactive(collection, calendar_name, conf, info, location=None, categories=None, repeat=None, until=None, alarms=None, format=None, env=None): try: info = parse_datetime.eventinfofstr( info, conf['locale'], adjust_reasonably=True, localize=False, ) except DateTimeParseError: info = dict() while True: summary = info.get('summary') if not summary: summary = None info['summary'] = prompt('summary', default=summary) if info['summary']: break echo("a summary is required") while True: range_string = None if info.get('dtstart') and info.get('dtend'): start_string = info["dtstart"].strftime(conf['locale']['datetimeformat']) end_string = info["dtend"].strftime(conf['locale']['datetimeformat']) range_string = start_string + ' ' + end_string daterange = prompt("datetime range", default=range_string) start, end, allday = parse_datetime.guessrangefstr( daterange, conf['locale'], adjust_reasonably=True) info['dtstart'] = start info['dtend'] = end info['allday'] = allday if info['dtstart'] and info['dtend']: break echo("invalid datetime range") while True: tz = info.get('timezone') or conf['locale']['default_timezone'] timezone = prompt("timezone", default=str(tz)) try: tz = pytz.timezone(timezone) info['timezone'] = tz break except pytz.UnknownTimeZoneError: echo("unknown timezone") info['description'] = prompt("description (or 'None')", default=info.get('description')) if info['description'] == 'None': info['description'] = '' event = new_from_args( collection, calendar_name, conf, format=format, env=env, location=location, categories=categories, repeat=repeat, until=until, alarms=alarms, **info) echo("event saved") term_width, _ = get_terminal_size() edit_event(event, collection, conf['locale'], width=term_width)
def test_short_format_contains_year(self): """if the non long versions of date(time)format contained a year, the current year would be used instead of the given one, see #545 same as above, but for guessrangefstr """ locale = { 'timeformat': '%H:%M', 'dateformat': '%Y-%m-%d', 'longdateformat': '%Y-%m-%d', 'datetimeformat': '%Y-%m-%d %H:%M', 'longdatetimeformat': '%Y-%m-%d %H:%M', } assert (dt.datetime(2017, 1, 1), dt.datetime(2017, 1, 2), True) == \ guessrangefstr('2017-1-1 2017-1-1', locale=locale)
def test_tomorrow(self): # XXX remove this funtionality, we shouldn't support this anyway assert (dt.datetime(2016, 9, 19), dt.datetime(2016, 9, 21, 16), True) == \ guessrangefstr('today tomorrow 16:00', locale=LOCALE_BERLIN)
def test_start_and_week(self): assert (dt.datetime(2015, 12, 28), dt.datetime(2016, 1, 5), True) == \ guessrangefstr('1.1.2016 week', locale=LOCALE_BERLIN)
def test_time_tomorrow(self): assert (dt.datetime(2016, 9, 19, 16), dt.datetime(2016, 9, 19, 17), False) == \ guessrangefstr('16:00', locale=LOCALE_BERLIN) assert (dt.datetime(2016, 9, 19, 16), dt.datetime(2016, 9, 19, 17), False) == \ guessrangefstr('16:00 17:00', locale=LOCALE_BERLIN)
def test_start_zero_day_delta(self): with pytest.raises(FatalError): guessrangefstr('1.1.2016 0d', locale=LOCALE_BERLIN)
def test_start_dt_and_delta(self): assert (dt.datetime(2016, 1, 1, 10), dt.datetime(2016, 1, 4, 10), False) == \ guessrangefstr('1.1.2016 10:00 3d', locale=LOCALE_BERLIN)
def test_start_and_end_date_time(self): assert (dt.datetime(2016, 1, 1, 10), dt.datetime(2017, 1, 1, 22), False) == \ guessrangefstr( '1.1.2016 10:00 1.1.2017 22:00', locale=LOCALE_BERLIN)
def test_week(self): assert (dt.datetime(2016, 2, 15), dt.datetime(2016, 2, 23), True) == \ guessrangefstr('week', locale=LOCALE_BERLIN)
def test_start_allday_and_delta_datetime(self): with pytest.raises(FatalError): guessrangefstr('1.1.2016 3d3m', locale=LOCALE_BERLIN)
def test_start_and_delta_3d(self): assert (dt.datetime(2016, 1, 1), dt.datetime(2016, 1, 4), True) == \ guessrangefstr('1.1.2016 3d', locale=LOCALE_BERLIN)
def test_start_and_no_end_date(self): assert (dt.datetime(2016, 1, 1), dt.datetime(2016, 1, 2), True) == \ guessrangefstr('1.1.2016', locale=LOCALE_BERLIN)
def test_start_and_eod(self): start, end = dt.datetime(2016, 1, 1, 10), dt.datetime(2016, 1, 1, 23, 59, 59, 999999) assert (start, end, False) == guessrangefstr('1.1.2016 10:00 eod', locale=LOCALE_BERLIN)
def test_tomorrow(self): # XXX remove me, we shouldn't support this anyway with freeze_time('2016-9-19 16:34'): assert (dt.datetime(2016, 9, 19), dt.datetime(2016, 9, 21, 16), True) == \ guessrangefstr('today tomorrow 16:00', locale=LOCALE_BERLIN)
def edit_event(event, collection, locale, allow_quit=False, width=80): options = OrderedDict() if allow_quit: options["no"] = {"short": "n"} options["quit"] = {"short": "q"} else: options["done"] = {"short": "n"} options["summary"] = {"short": "s", "attr": "summary"} options["description"] = { "short": "d", "attr": "description", "none": True } options["datetime range"] = {"short": "t"} options["repeat"] = {"short": "p"} options["location"] = {"short": "l", "attr": "location", "none": True} options["categories"] = {"short": "c", "attr": "categories", "none": True} options["alarm"] = {"short": "a"} options["Delete"] = {"short": "D"} now = dt.datetime.now() while True: choice = present_options(options, prefix="Edit?", width=width) if choice is None: echo("unknown choice") continue if choice == 'no': return True if choice in ['quit', 'done']: return False edited = False if choice == "Delete": if confirm("Delete all occurences of event?"): collection.delete(event.href, event.etag, event.calendar) return True elif choice == "datetime range": current = event.format("{start} {end}", relative_to=now) value = prompt("datetime range", default=current) try: start, end, allday = parse_datetime.guessrangefstr( value, locale) event.update_start_end(start, end) edited = True except: echo("error parsing range") elif choice == "repeat": recur = event.recurobject freq = recur["freq"] if "freq" in recur else "" until = recur["until"] if "until" in recur else "" if not freq: freq = 'None' freq = prompt('frequency (or "None")', freq) if freq == 'None': event.update_rrule(None) else: until = prompt('until (or "None")', until) if until == 'None': until = None rrule = parse_datetime.rrulefstr(freq, until, locale) event.update_rrule(rrule) edited = True elif choice == "alarm": default_alarms = [] for a in event.alarms: s = parse_datetime.timedelta2str(-1 * a[0]) default_alarms.append(s) default = ', '.join(default_alarms) if not default: default = 'None' alarm = prompt('alarm (or "None")', default) if alarm == "None": alarm = "" alarm_list = [] for a in alarm.split(","): alarm_trig = -1 * parse_datetime.guesstimedeltafstr(a.strip()) new_alarm = (alarm_trig, event.description) alarm_list += [new_alarm] event.update_alarms(alarm_list) edited = True else: attr = options[choice]["attr"] default = getattr(event, attr) question = choice allow_none = False if "none" in options[choice] and options[choice]["none"]: question += ' (or "None")' allow_none = True if not default: default = 'None' value = prompt(question, default) if allow_none and value == "None": value = "" getattr(event, "update_" + attr)(value) edited = True if edited: event.increment_sequence() collection.update(event)
def test_today(self): assert (dt.datetime(2016, 9, 19, 13), dt.datetime(2016, 9, 19, 14), False) == \ guessrangefstr('13:00 14:00', locale=LOCALE_BERLIN) assert (dt.datetime(2016, 9, 19), dt.datetime(2016, 9, 21), True) == \ guessrangefstr('today tomorrow', LOCALE_BERLIN)