summaryrefslogtreecommitdiff
path: root/jimbrella/routine.py
blob: 692807e7d5654844f8ca4d5aeb2d4e62b7057941 (plain)
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
74
75
76
77
78
79
from .database import Database
from .jform import JForm
from .config import *
from .utils import local_now
from .exceptions import *

"""A set of routine methods, run at an interval (somewhere from ten minutes to one hour), to:
- sync JImbrella's databse against data pulled from jForm
- check if any umbrella is now overdue
- send an SMS where applicable, to a user or an admin
"""


def chronological_merge(*sheet_lists) -> list:
    """Merges all lists answer sheets passed in, in chronological order, into a single list.

    All lists of sheets in sheet_lists MUST be already in chronological order.
    By "chronological", we mean sorting by the value under key "date".
    """
    chronicle = []
    while any(sheet_lists):  # at least one list in `sheet_lists` is non-empty
        # for each list of sheets, read date from its first element, then find the earliest
        # is an instance of datetime.datetime
        # only pass non-empty lists to min():
        earliest_date = min(
            [sheet_list[0]["date"] for sheet_list in filter(None, sheet_lists)]
        )
        for idx, sheet_list in enumerate(sheet_lists):
            if not sheet_list:  # is empty
                continue
            if sheet_list[0]["date"] == earliest_date:
                # remove the first element and append it to `chronicle`, if it is the earliest
                chronicle.append(sheet_lists[idx].pop(0))
                # we do not directly break here because there exists a tiny chance
                # two answer sheets were submitted at the exact same millisecond
    return chronicle


def sync_database(takeaway: JForm, giveback: JForm, db: Database):
    takeaway_unread = takeaway.get_unread()
    giveback_unread = giveback.get_unread()
    unread = chronological_merge(takeaway_unread, giveback_unread)
    for sheet in unread:
        if sheet["jform_name"] == "takeaway":
            try:
                db.take_away(
                    sheet["key"],
                    sheet["date"],
                    sheet["name"],
                    sheet["id"],
                    sheet["phone"],
                )
            except UmbrellaStatusError:
                pass
            except UmbrellaNotFoundError:
                pass
        elif sheet["jform_name"] == "giveback":
            try:
                db.give_back(sheet["key"], sheet["date"])
            except UmbrellaStatusError:
                pass
            except UmbrellaNotFoundError:
                pass


def process_overdue(db: Database):
    overdue = Database.find_overdue(db.read())
    for umb in overdue:
        db.mark_overdue(umb["serial"], local_now())


if __name__ == "__main__":
    takeaway = JForm("takeaway", JFORM_TAKEAWAY_URL, JFORM_BOOKMARK_DIR)
    # giveback = JForm(
    #     "giveback", JFORM_GIVEBACK_URL, JFORM_BOOKMARK_DIR
    # )
    giveback = None
    db = Database(DATABASE_PATH)
    sync_database(takeaway, giveback, db)