diff --git a/main.py b/main.py index 75c72cc..3f498c8 100644 --- a/main.py +++ b/main.py @@ -1,64 +1,11 @@ import datetime -from typing import List, Dict +from typing import List from flask import render_template from google.oauth2.service_account import Credentials from googleapiclient.discovery import build - -class Item: - def __init__(self, name: str, amount: int): - assert name == name.lower() - self.name = name - self.amount = amount - self.__contains_fries = 'friet' in self.name or 'twister' in self.name - - def __lt__(self: "Item", other: "Item") -> bool: - if self.__contains_fries and not other.__contains_fries: - return True - if not self.__contains_fries and other.__contains_fries: - return False - return self.name < other.name - - -class Order: - def __init__(self, value: List[str]): - self.name = _anonymize_name(value[1]) - self.items = [v for v in value[2:] if v] - - -class DTO: - def __init__(self): - self.__applicants: List[str] = [] - self.__items: Dict[str, int] = {} - self.__orders: List[Order] = [] - - def process_value(self, value: List[str]) -> None: - # applications - self.__applicants.append(_anonymize_name(value[1])) - # items - for item in value[2:]: - if item: - item_name = item.lower().strip() - if item_name in self.__items: - self.__items[item_name] += 1 - else: - self.__items[item_name] = 1 - # orders - self.__orders.append(Order(value)) - - @property - def items(self) -> List[Item]: - return sorted([Item(name, amount) for name, amount in self.__items.items()]) - - @property - def applicants(self) -> List[str]: - return sorted(self.__applicants) - - @property - def orders(self) -> List[Order]: - return sorted(self.__orders, key=lambda o: o.name) - +from models.dto import DTO _SCOPES = ['https://www.googleapis.com/auth/spreadsheets.readonly'] @@ -90,22 +37,27 @@ def _anonymize_name(name: str) -> str: return result -def _get_data() -> DTO: +def _load_values() -> List[List[str]]: credentials: Credentials = Credentials.from_service_account_file('token.json', scopes=_SCOPES) - service = build('sheets', 'v4', credentials=credentials) sheets = service.spreadsheets() result = sheets.values().get(spreadsheetId=_SHEET_ID, range=_RANGE).execute() values = result.get('values', []) + return values + +def _get_data() -> DTO: cutoff = datetime.datetime.now() - datetime.timedelta(days=4) + rows_to_process = [row for row in _load_values() + if row and datetime.datetime.strptime(row[0], '%d-%m-%Y %H:%M:%S') > cutoff] + result = DTO() - for value in values: - if value: - moment = datetime.datetime.strptime(value[0], '%d-%m-%Y %H:%M:%S') - if moment > cutoff: - result.process_value(value) + for row in rows_to_process: + result.add( + applicant_name=_anonymize_name(row[1]), + item_names=[item_name.lower().strip() for item_name in row[2:]], + ) return result diff --git a/models/dto.py b/models/dto.py new file mode 100644 index 0000000..6af7bf9 --- /dev/null +++ b/models/dto.py @@ -0,0 +1,34 @@ +from typing import List, Dict + +from models.item import Item +from models.order import Order + + +class DTO: + def __init__(self): + self.__applicants: List[str] = [] + self.__items: Dict[str, int] = {} + self.__orders: List[Order] = [] + + def add(self, applicant_name: str, item_names: List[str]): + self.__applicants.append(applicant_name) + + for item_name in item_names: + if item_name not in self.__items: + self.__items[item_name] = 0 + self.__items[item_name] += 1 + + order = Order(applicant_name, item_names) + self.__orders.append(order) + + @property + def items(self) -> List[Item]: + return sorted([Item(name, amount) for name, amount in self.__items.items()]) + + @property + def applicants(self) -> List[str]: + return sorted(self.__applicants) + + @property + def orders(self) -> List[Order]: + return sorted(self.__orders) diff --git a/models/item.py b/models/item.py new file mode 100644 index 0000000..ba4e0a6 --- /dev/null +++ b/models/item.py @@ -0,0 +1,13 @@ +class Item: + def __init__(self, name: str, amount: int): + assert name == name.lower() + self.name = name + self.amount = amount + self.__contains_fries = 'friet' in self.name or 'twister' in self.name + + def __lt__(self: "Item", other: "Item") -> bool: + if self.__contains_fries and not other.__contains_fries: + return True + if not self.__contains_fries and other.__contains_fries: + return False + return self.name < other.name diff --git a/models/order.py b/models/order.py new file mode 100644 index 0000000..6e6b2db --- /dev/null +++ b/models/order.py @@ -0,0 +1,10 @@ +from typing import List + + +class Order: + def __init__(self, name: str, items: List[str]): + self.name = name + self.items = items + + def __lt__(self: "Order", other: "Order") -> bool: + return self.name < other.name diff --git a/pack.sh b/pack.sh index 464bffa..53ccb85 100755 --- a/pack.sh +++ b/pack.sh @@ -1,6 +1,7 @@ #!/bin/bash zip deployable.zip \ - templates/frietlijst.html \ + templates/*.html \ + models/*.py \ main.py \ token.json \ requirements.txt \ No newline at end of file diff --git a/test.py b/test.py new file mode 100644 index 0000000..c799481 --- /dev/null +++ b/test.py @@ -0,0 +1,16 @@ +import unittest + +from main import _anonymize_name + + +class TestMain(unittest.TestCase): + def test_anonymize_name(self): + given = "Alice Bobbington Charlie" + expected = "Alice B C" + actual = _anonymize_name(given) + + self.assertEqual(expected, actual) + + +if __name__ == '__main__': + unittest.main()