|
@@ -1,14 +1,15 @@
|
1
|
1
|
"""
|
2
|
2
|
Provides access to the models stored in the database, via the server.
|
3
|
3
|
"""
|
|
4
|
+from __future__ import annotations
|
|
5
|
+
|
4
|
6
|
import datetime
|
5
|
7
|
import logging
|
6
|
|
-from typing import NamedTuple, Sequence, Tuple, Any, Optional
|
|
8
|
+from typing import Any, List, NamedTuple, Optional, Sequence, Tuple
|
7
|
9
|
from urllib.parse import urljoin
|
8
|
10
|
|
9
|
11
|
import requests
|
10
|
12
|
|
11
|
|
-
|
12
|
13
|
LOG = logging.getLogger(__name__)
|
13
|
14
|
|
14
|
15
|
SERVER_URL = "http://127.0.0.1:5000"
|
|
@@ -60,7 +61,7 @@ class Person(NamedTuple):
|
60
|
61
|
def name(self) -> str:
|
61
|
62
|
return self.display_name or self.full_name
|
62
|
63
|
|
63
|
|
- def add_consumption(self, type_id: str) -> bool:
|
|
64
|
+ def add_consumption(self, type_id: str) -> Optional[Consumption]:
|
64
|
65
|
""" Register a consumption for this Person. """
|
65
|
66
|
req = requests.post(
|
66
|
67
|
urljoin(SERVER_URL, f"people/{self.person_id}/add_consumption/{type_id}")
|
|
@@ -75,7 +76,7 @@ class Person(NamedTuple):
|
75
|
76
|
req.status_code,
|
76
|
77
|
data,
|
77
|
78
|
)
|
78
|
|
- return False
|
|
79
|
+ return None
|
79
|
80
|
|
80
|
81
|
self.consumptions.update(data["person"]["consumptions"])
|
81
|
82
|
|
|
@@ -86,9 +87,9 @@ class Person(NamedTuple):
|
86
|
87
|
req.status_code,
|
87
|
88
|
req.content,
|
88
|
89
|
)
|
89
|
|
- return False
|
|
90
|
+ return None
|
90
|
91
|
|
91
|
|
- def create(self) -> "Person":
|
|
92
|
+ def create(self) -> Optional[Person]:
|
92
|
93
|
""" Create a new Person from the current attributes. As tuples are
|
93
|
94
|
immutable, a new Person with the correct id is returned. """
|
94
|
95
|
req = requests.post(
|
|
@@ -112,7 +113,7 @@ class Person(NamedTuple):
|
112
|
113
|
|
113
|
114
|
return Person.from_dict(data["person"])
|
114
|
115
|
|
115
|
|
- def set_active(self, new_state=True) -> "Person":
|
|
116
|
+ def set_active(self, new_state=True) -> Optional[Person]:
|
116
|
117
|
req = requests.patch(
|
117
|
118
|
urljoin(SERVER_URL, f"people/{self.person_id}"),
|
118
|
119
|
json={"person": {"active": new_state}},
|
|
@@ -135,7 +136,7 @@ class Person(NamedTuple):
|
135
|
136
|
return Person.from_dict(data["person"])
|
136
|
137
|
|
137
|
138
|
@classmethod
|
138
|
|
- def get(cls, person_id: int) -> "Person":
|
|
139
|
+ def get(cls, person_id: int) -> Optional[Person]:
|
139
|
140
|
""" Retrieve a Person by id. """
|
140
|
141
|
req = requests.get(urljoin(SERVER_URL, f"/people/{person_id}"))
|
141
|
142
|
|
|
@@ -159,7 +160,7 @@ class Person(NamedTuple):
|
159
|
160
|
return None
|
160
|
161
|
|
161
|
162
|
@classmethod
|
162
|
|
- def get_all(cls, active=None) -> ["Person"]:
|
|
163
|
+ def get_all(cls, active=None) -> Optional[List[Person]]:
|
163
|
164
|
""" Get all active People. """
|
164
|
165
|
params = {}
|
165
|
166
|
if active is not None:
|
|
@@ -212,7 +213,7 @@ class Export(NamedTuple):
|
212
|
213
|
)
|
213
|
214
|
|
214
|
215
|
@classmethod
|
215
|
|
- def get_all(cls) -> ["Export"]:
|
|
216
|
+ def get_all(cls) -> Optional[List[Export]]:
|
216
|
217
|
""" Get a list of all existing Exports. """
|
217
|
218
|
req = requests.get(urljoin(SERVER_URL, "exports"))
|
218
|
219
|
|
|
@@ -233,7 +234,7 @@ class Export(NamedTuple):
|
233
|
234
|
return [cls.from_dict(e) for e in data["exports"]]
|
234
|
235
|
|
235
|
236
|
@classmethod
|
236
|
|
- def get(cls, export_id: int) -> "Export":
|
|
237
|
+ def get(cls, export_id: int) -> Optional[Export]:
|
237
|
238
|
""" Retrieve one Export. """
|
238
|
239
|
req = requests.get(urljoin(SERVER_URL, f"exports/{export_id}"))
|
239
|
240
|
|
|
@@ -256,7 +257,7 @@ class Export(NamedTuple):
|
256
|
257
|
return cls.from_dict(data["export"])
|
257
|
258
|
|
258
|
259
|
@classmethod
|
259
|
|
- def create(cls) -> "Export":
|
|
260
|
+ def create(cls) -> Optional[Export]:
|
260
|
261
|
""" Create a new Export, containing all un-exported Settlements. """
|
261
|
262
|
req = requests.post(urljoin(SERVER_URL, "exports"))
|
262
|
263
|
|
|
@@ -283,10 +284,10 @@ class ConsumptionType(NamedTuple):
|
283
|
284
|
""" Represents a stored ConsumptionType. """
|
284
|
285
|
|
285
|
286
|
name: str
|
286
|
|
- consumption_type_id: int = None
|
287
|
|
- icon: str = None
|
|
287
|
+ consumption_type_id: Optional[int] = None
|
|
288
|
+ icon: Optional[str] = None
|
288
|
289
|
|
289
|
|
- def create(self) -> "ConsumptionType":
|
|
290
|
+ def create(self) -> Optional[ConsumptionType]:
|
290
|
291
|
""" Create a new ConsumptionType from the current attributes. As tuples
|
291
|
292
|
are immutable, a new ConsumptionType with the correct id is returned.
|
292
|
293
|
"""
|
|
@@ -314,7 +315,7 @@ class ConsumptionType(NamedTuple):
|
314
|
315
|
return ConsumptionType.from_dict(data["consumption_type"])
|
315
|
316
|
|
316
|
317
|
@classmethod
|
317
|
|
- def get(cls, consumption_type_id: int) -> "ConsumptionType":
|
|
318
|
+ def get(cls, consumption_type_id: int) -> Optional[ConsumptionType]:
|
318
|
319
|
""" Retrieve a ConsumptionType by id. """
|
319
|
320
|
req = requests.get(
|
320
|
321
|
urljoin(SERVER_URL, f"/consumption_types/{consumption_type_id}")
|
|
@@ -343,7 +344,7 @@ class ConsumptionType(NamedTuple):
|
343
|
344
|
return None
|
344
|
345
|
|
345
|
346
|
@classmethod
|
346
|
|
- def get_all(cls) -> ["ConsumptionType"]:
|
|
347
|
+ def get_all(cls) -> Optional[List[ConsumptionType]]:
|
347
|
348
|
""" Get all active ConsumptionTypes. """
|
348
|
349
|
req = requests.get(urljoin(SERVER_URL, "/consumption_types"))
|
349
|
350
|
|
|
@@ -383,7 +384,7 @@ class Consumption(NamedTuple):
|
383
|
384
|
consumption_type_id: int
|
384
|
385
|
created_at: datetime.datetime
|
385
|
386
|
reversed: bool = False
|
386
|
|
- settlement_id: int = None
|
|
387
|
+ settlement_id: Optional[int] = None
|
387
|
388
|
|
388
|
389
|
@classmethod
|
389
|
390
|
def from_dict(cls, data: dict) -> "Consumption":
|
|
@@ -397,7 +398,7 @@ class Consumption(NamedTuple):
|
397
|
398
|
reversed=data["reversed"],
|
398
|
399
|
)
|
399
|
400
|
|
400
|
|
- def reverse(self) -> "Consumption":
|
|
401
|
+ def reverse(self) -> Optional[Consumption]:
|
401
|
402
|
""" Reverse this consumption. """
|
402
|
403
|
req = requests.delete(
|
403
|
404
|
urljoin(SERVER_URL, f"/consumptions/{self.consumption_id}")
|
|
@@ -413,7 +414,7 @@ class Consumption(NamedTuple):
|
413
|
414
|
req.status_code,
|
414
|
415
|
data,
|
415
|
416
|
)
|
416
|
|
- return False
|
|
417
|
+ return None
|
417
|
418
|
|
418
|
419
|
return Consumption.from_dict(data["consumption"])
|
419
|
420
|
|
|
@@ -423,7 +424,7 @@ class Consumption(NamedTuple):
|
423
|
424
|
req.status_code,
|
424
|
425
|
req.content,
|
425
|
426
|
)
|
426
|
|
- return False
|
|
427
|
+ return None
|
427
|
428
|
|
428
|
429
|
|
429
|
430
|
class Settlement(NamedTuple):
|
|
@@ -452,7 +453,7 @@ class Settlement(NamedTuple):
|
452
|
453
|
return cls.from_dict(req.json()["settlement"])
|
453
|
454
|
|
454
|
455
|
@classmethod
|
455
|
|
- def get(cls, settlement_id: int) -> "Settlement":
|
|
456
|
+ def get(cls, settlement_id: int) -> Optional[Settlement]:
|
456
|
457
|
req = requests.get(urljoin(SERVER_URL, f"/settlements/{settlement_id}"))
|
457
|
458
|
|
458
|
459
|
try:
|