Esempio n. 1
0
def tag(_tag, time="now") -> bool:
    time = XArrow.from_human(time)
    # time = human2arrow(time)
    if time > time.now():
        raise BadTime(f"in the future: {time}")
    work = store.load()
    idx = -1
    item = Entry(**work[idx])
    if time < item.start:
        # Tag something in the past
        idx = -1 * next(i for i, work in enumerate(reversed(work), 1)
                        if Entry(**work).start <= time)
        item_in_range = Entry(**work[idx])
        if not confirm(
                f'{item.name_colored} started only at {c.time(item.start.strftime("%X"))}, '
                f'Tag {item_in_range.name_colored} (started at {c.time(item_in_range.start.strftime("%X"))})?'
        ):
            return False
        item = item_in_range
    tag_colored = c.tag(_tag)
    if any(
            util.normalize_str(_tag) == t
            for t in map(util.normalize_str, item.tags)):
        print(f'{item.name_colored} already has tag {tag_colored}.')
        return False
    item.tags.add(_tag)
    work[idx]['tags'] = item.tags

    ok = store.dump(work)
    if ok:
        print(f"Okay, tagged {item.name_colored} with {tag_colored}.")
    else:
        print(f"Failed writing to sheet")
    return ok
Esempio n. 2
0
def note(content, time="now"):
    time = XArrow.from_human(time)
    # time = human2arrow(time)
    if time > XArrow.now():
        raise BadTime(f"in the future: {time}")
    content_and_time = content.strip() + f' ({time.HHmmss})'
    work = store.load()
    idx = -1
    item = Entry(**work[idx])
    if time < item.start:
        # Note for something in the past
        idx, item_in_range = next((i, item) for i, item in enumerate(map(lambda w: Entry(**w), reversed(work)), 1) if item.start.full == time.full)
        idx *= -1
        
        if item_in_range.name == item.name:
            item = item_in_range
        else:
            if not confirm(f'{item.name_colored} started only at {c.time(item.start.strftime("%X"))},\n'
                           f'note to {item_in_range.name_colored} (started at {c.time(item_in_range.start.strftime("%X"))})?'):
                return
            item = item_in_range
    
    for n in item.notes:
        if n.is_similar(content):
            if not confirm(f'{item.name_colored} already has this note: {c.b(c.note(n))}.\n'
                           'Add anyway?'):
                return
    
    item.notes.append(content_and_time)
    work[idx]['notes'] = item.notes
    store.dump(work)
    
    print(f'Noted {c.b(c.note(content_and_time))} to {item.name_colored}')
Esempio n. 3
0
 def test_from_human_static(self):
     now = XArrow.from_human('now')
     today = XArrow.from_human('today')
     assert now == today == XArrow.now()
     yesterday = XArrow.from_human('yesterday')
     assert yesterday == now.shift(days=-1)
     assert yesterday.day == now.day - 1
     eight_days_ago = XArrow.from_human('8 days ago')
     assert eight_days_ago == now.shift(days=-8)
     assert eight_days_ago.day == now.day - 8
     dec_first_21 = XArrow.from_human('01/12/21')
     assert dec_first_21.year == 2021
     assert dec_first_21.month == 12
     assert dec_first_21.day == 1
     thursday = XArrow.from_human('thursday')
     assert thursday.strftime('%A') == 'Thursday'
Esempio n. 4
0
def parse_args(argv=[]) -> tuple[Callable, dict]:
    if not argv:
        argv = sys.argv
    # *** log
    # ** timefred
    # timefred -> log(detailed=True)
    argv_len = len(argv)
    if argv_len == 1:
        return action.log, {'detailed': True}

    # ** timefred thursday
    if len(argv[1]) > 1:
        if argv[1].lower() == 'yesterday':
            return action.log, {'time': argv[1], 'detailed': True}
        with suppress(ValueError):
            isoweekday(argv[1])
            return action.log, {'time': argv[1], 'detailed': True}

    head = argv[1]
    tail: list[str] = argv[2:]

    # ** log
    if head in ('l', 'l-', 'log', 'log-'):
        groupby = None
        with suppress(ValueError, AttributeError):
            groupby_idx = tail.index('-g')
            groupby = tail[groupby_idx + 1]
            tail = tail[:groupby_idx]
        if tail:
            time = ' '.join(tail)
        else:
            time = 'today'
        args = {'time': time, 'detailed': '-' not in head, 'groupby': groupby}
        return action.log, args

    # *** help
    if 'help' in head or head in ('-h', 'h'):
        print(__doc__, file=sys.stderr)
        sys.exit(0)

    # *** edit
    elif head in ('e', 'edit'):
        return action.edit, {}

    # *** on
    elif head in ('+', 'o', 'on'):
        if not tail:
            raise BadArguments("Need the name of whatever you are working on.")

        name = tail.pop(0)
        _tag = None
        _note = None
        if tail:
            with suppress(ValueError):
                _tag_idx = tail.index('-t')
                _tag = tail[_tag_idx + 1]
                tail = tail[:_tag_idx]
            with suppress(ValueError):
                _note_idx = tail.index('-n')
                _note = tail[_note_idx + 1]
                tail = tail[:_note_idx]
            time = XArrow.from_human(' '.join(tail) if tail else 'now')
        else:
            time = XArrow.now()
        args = {'name': name, 'time': time, 'tag': _tag, 'note': _note}
        return action.on, args

    # *** stop
    elif head in ('-', 'stop'):
        args = {'time': XArrow.from_human(' '.join(tail) if tail else 'now')}
        return action.stop, args

    # *** status
    elif head in ('?', '??', 's', 's+', 'status', 'status+'):
        args = {'show_notes': '+' in head}
        return action.status, args

    # *** tag
    elif head in ('t', 'tag'):
        if not tail:
            raise BadArguments("Please provide a tag.")

        if len(tail) == 2:
            _tag, time = tail
            args = {'tag': _tag, 'time': time}
        elif len(tail) == 1:
            args = {'tag': tail[0]}
        else:
            args = {'tag': ' '.join(tail)}
        return action.tag, args

    # *** note
    elif head in ('n', 'note'):
        if not tail:
            raise BadArguments("Please provide some text to be noted.")

        if len(tail) == 2:
            content, time = tail
            args = {'content': content, 'time': time}
        elif len(tail) == 1:
            args = {'content': tail[0]}
        else:
            args = {'content': ' '.join(tail)}
        return action.note, args

    # *** interrupt
    # elif head in ('i', 'interrupt'):
    # 	if not tail:
    # 		raise BadArguments("Need the name of whatever you are working on.")
    #
    # 	name = tail.pop(0)
    # 	args = {
    # 		'name': name,
    # 		'time': human2formatted(' '.join(tail) if tail else 'now'),
    # 		}
    # 	return interrupt, args

    # *** aggregate
    elif head == 'a' or head.startswith('ag'):
        if not tail:
            raise BadArguments("Need at least <start> <stop>")
        if len(tail) == 1:
            times = tail[0]
            if '-' in times:
                start, stop = map(str.strip, times.partition('-'))
            elif ' ' in times:
                start, stop = map(str.strip, times.partition(' '))
            else:
                raise BadArguments("Need at least <start> <stop>")
        else:
            start, stop, *tail = tail
        # start_arw = human2arrow(start)
        # stop_arw = human2arrow(stop)
        start_arw = XArrow.from_human(start)
        stop_arw = XArrow.from_human(stop)
        breakpoint()

    # *** _dev
    if head == '_dev':
        if tail[0] == 'generate completion':
            from timefred._dev import generate_completion
            return generate_completion, {}

    raise BadArguments("I don't understand %r" % (head, ))