~cypheon/nextcloud-chores-app

nextcloud-chores-app/tools/import_chores_from_flatastic.py -rwxr-xr-x 1.9 KiB
d19a6603 — Johann Rudloff Make overdue sidebar badge dynamic, switch badges to `CounterBubble` component 6 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env python3

import datetime as dt
import json
import logging
import sys

log = logging.getLogger()
log.setLevel(logging.DEBUG)

def days_to_repeat(days):
    if days <= 6:
        return f'd:{days}'
    elif days < 30 and days % 7 == 0:
        return f'w:{days // 7}'
    elif days >= 30 and days % 30 == 0:
        return f'm:{days // 30}'
    elif days == 183:
        return f'm:6'
    elif days == 365:
        return f'm:12'

    raise ValueError(f"cannot convert {days} days to repeat schedule")

def schedule_is_weekly(schedule):
    return schedule.startswith('w:')

def make_schedule(raw):
    rt = int(raw['rotationTime'])
    if rt == -1:
        return 'o:1:-'
    rtdays = rt // (24 * 3600)
    repeat = days_to_repeat(rtdays)
    log.debug(f'rotation time {rt} => {rtdays} days => {repeat}')
    date = dt.datetime.fromtimestamp(raw['lastDoneDate'])
    log.debug(date.strftime('%A, %Y-%m-%d %H:%M:%S%z'))

    constraint = '-'
    if int(raw['fixed']) != 0:
        if schedule_is_weekly(repeat):
            log.debug(repr(raw))
            # isoweekday returns 1(monday) .. 7(sunday),
            # but we want 0(sunday) .. 6(saturday)
            constraint = date.isoweekday() % 7
        else:
            raise ValueError("cannot fixed-repeat non-weekly tasks")

    log.debug(f"  => constraint = {constraint}")

    schedule = f"{repeat}:{constraint}"
    log.debug('')
    return schedule

def convert(raw):
    schedule = make_schedule(raw)
    due = dt.datetime.fromtimestamp(int(raw['lastDoneDate']) + int(raw['rotationTime']))
    return {
        'name': raw['title'],
        'points': int(raw['points']),
        'repeat': schedule,
        'due': due.strftime('%Y-%m-%dT%H:%M:%S'),
    }

def main(args):
    filename = args[0]
    with open(filename, 'r') as f:
        raw = json.load(f)

    converted = {'chores': [convert(x) for x in raw]}
    print(json.dumps(converted, indent=2))

if __name__ == '__main__':
    main(sys.argv[1:])