NOJIRA more restructuring
This commit is contained in:
0
src/__init__.py
Normal file
0
src/__init__.py
Normal file
58
src/main.py
Normal file
58
src/main.py
Normal file
@@ -0,0 +1,58 @@
|
||||
import datetime
|
||||
from typing import Optional
|
||||
|
||||
from flask import render_template
|
||||
|
||||
from models.dto import DTO
|
||||
from repository import Repository
|
||||
|
||||
_repository: Optional[Repository] = None
|
||||
|
||||
_cache_moment = datetime.datetime.now() - datetime.timedelta(days=1)
|
||||
_cache_value = DTO()
|
||||
|
||||
|
||||
def process(_) -> str:
|
||||
global _repository
|
||||
global _cache_value
|
||||
global _cache_moment
|
||||
|
||||
if not _repository:
|
||||
_repository = Repository(
|
||||
sa_file_name='token.json',
|
||||
spreadsheet_id='18vCgc5DGUiFZN1NX_GBmxSBCb47KdsBkV6Glf9Sx-wE',
|
||||
spreadsheet_range='Friet bestelling!A2:F',
|
||||
)
|
||||
|
||||
rerun_if_later_than = _cache_moment + datetime.timedelta(seconds=10)
|
||||
now = datetime.datetime.now()
|
||||
if now > rerun_if_later_than:
|
||||
_cache_value = _get_data()
|
||||
_cache_moment = datetime.datetime.now()
|
||||
return render_template('frietlijst.html', dto=_cache_value)
|
||||
|
||||
|
||||
def anonymize_name(name: str) -> str:
|
||||
parts = name.split(" ")
|
||||
result = parts[0]
|
||||
for part in parts[1:]:
|
||||
if part:
|
||||
result += " " + part[0]
|
||||
return result
|
||||
|
||||
|
||||
def _get_data() -> DTO:
|
||||
cutoff = datetime.datetime.now() - datetime.timedelta(days=4)
|
||||
|
||||
rows_to_process = [row for row in _repository.load_rows()
|
||||
if row and datetime.datetime.strptime(row[0], '%d-%m-%Y %H:%M:%S') > cutoff]
|
||||
|
||||
result = DTO()
|
||||
|
||||
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
|
||||
34
src/models/dto.py
Normal file
34
src/models/dto.py
Normal file
@@ -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)
|
||||
13
src/models/item.py
Normal file
13
src/models/item.py
Normal file
@@ -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
|
||||
10
src/models/order.py
Normal file
10
src/models/order.py
Normal file
@@ -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
|
||||
27
src/repository.py
Normal file
27
src/repository.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from typing import List
|
||||
|
||||
from google.oauth2.service_account import Credentials
|
||||
from googleapiclient.discovery import build
|
||||
|
||||
|
||||
class Repository:
|
||||
def __init__(self,
|
||||
sa_file_name: str,
|
||||
spreadsheet_id: str,
|
||||
spreadsheet_range: str,
|
||||
):
|
||||
credentials = Credentials.from_service_account_file(
|
||||
filename=sa_file_name,
|
||||
scopes=['https://www.googleapis.com/auth/spreadsheets.readonly'],
|
||||
)
|
||||
service = build('sheets', 'v4', credentials=credentials)
|
||||
self.__sheets = service.spreadsheets()
|
||||
self.__spreadsheet_id = spreadsheet_id
|
||||
self.__spreadsheet_range = spreadsheet_range
|
||||
|
||||
def load_rows(self) -> List[List[str]]:
|
||||
result = self.__sheets.values().get(
|
||||
spreadsheetId=self.__spreadsheet_id,
|
||||
range=self.__spreadsheet_range,
|
||||
).execute()
|
||||
return result.get('values', [])
|
||||
4
src/requirements.txt
Normal file
4
src/requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
flask==2.0.1
|
||||
google-api-python-client==2.20.0
|
||||
google-auth-httplib2==0.1.0
|
||||
google-auth-oauthlib==0.4.6
|
||||
43
src/templates/frietlijst.html
Normal file
43
src/templates/frietlijst.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Frietlijst by Ivo</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/github-markdown-css@4.0.0/github-markdown.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="markdown-body">
|
||||
<h1>Reeds besteld</h1>
|
||||
<ol>
|
||||
{% for applicant in dto.applicants %}
|
||||
<li>{{ applicant }}</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
|
||||
<h1>Streeplijst</h1>
|
||||
<ul>
|
||||
{% for item in dto.items %}
|
||||
<li>{{ item.name }}: {{ item.amount }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<h1>Totaaloverzicht</h1>
|
||||
<ul>
|
||||
{% for order in dto.orders %}
|
||||
<li>
|
||||
{{ order.name }}
|
||||
<ul>
|
||||
{% for item in order.items %}
|
||||
<li>{{ item }}</li>
|
||||
{% endfor%}
|
||||
</ul>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<p> Heb je feedback?
|
||||
<a href="https://docs.google.com/forms/d/e/1FAIpQLSddGpp9kbvW9QfLVATOM3pJqhq1ci0_gdZdpGmXmkPRMoiLEw/viewform?usp=sf_link"
|
||||
target="_blank">Klik hier!</a></p>
|
||||
<p>Wil je de code van deze pagina zien of hieraan bijdragen? <a href="https://github.com/spijkercenter/frietlijst"
|
||||
target="_blank">Klik hier!</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user