Skip to content

Commit b66c370

Browse files
authored
Merge pull request #3 from RutgerRauws/feature/event
Add events retrieval
2 parents 96985ca + 4567170 commit b66c370

File tree

8 files changed

+19033
-7
lines changed

8 files changed

+19033
-7
lines changed

.vscode/settings.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"python.analysis.extraPaths": [
3+
"./notubiz"
4+
],
5+
"python.testing.pytestArgs": [
6+
"test"
7+
],
8+
"python.testing.unittestEnabled": false,
9+
"python.testing.pytestEnabled": true
10+
}

examples/get_events.py

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Add the notubiz folder to the path
2+
import sys, os
3+
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
4+
5+
from datetime import datetime
6+
7+
import notubiz
8+
import notubiz.api.event
9+
10+
configuration = notubiz.Configuration(organisation_id = 686) # Gemeente Eindhoven
11+
12+
api_client = notubiz.ApiClient(configuration)
13+
14+
event_client = notubiz.api.event.EventApi(api_client)
15+
16+
start_date = datetime(2019, 1, 1)
17+
end_date = datetime(2020, 3, 31, 23, 59, 59)
18+
19+
events = event_client.get(start_date, end_date)
20+
21+
for event in events:
22+
print("{} - {} ({})".format(event.plannings[0].start_date, event.title, event.location))

notubiz/api/_helpers.py

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from datetime import datetime
2+
from typing import Optional
23

34
def get_attribute(attributes, id) -> str:
45
attribute = [attribute for attribute in attributes if attribute["id"] == id]
@@ -10,17 +11,23 @@ def get_attribute(attributes, id) -> str:
1011

1112
return attribute[0]["value"]
1213

13-
def get_title(attributes) -> str:
14-
return get_attribute(attributes, 1)
14+
def get_title(attributes) -> Optional[str]:
15+
try:
16+
return get_attribute(attributes, 1)
17+
except Exception:
18+
return None
1519

16-
def get_description(attributes):
20+
def get_description(attributes) -> Optional[str]:
1721
try:
1822
return get_attribute(attributes, 3)
1923
except Exception:
20-
return ""
24+
return None
2125

22-
def get_location(attributes):
23-
return get_attribute(attributes, 50)
26+
def get_location(attributes) -> Optional[str]:
27+
try:
28+
return get_attribute(attributes, 50)
29+
except Exception:
30+
return None
2431

2532
def parse_date(date_string : str) -> datetime:
2633
return datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")

notubiz/api/event.py

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
2+
from attrs import define, field
3+
import cattrs
4+
from cattrs import transform_error
5+
6+
from typing import Optional
7+
8+
from datetime import datetime
9+
from notubiz.api._helpers import parse_date, get_title, get_location
10+
11+
from notubiz import ApiClient
12+
13+
@define
14+
class Planning:
15+
# Auto-filled
16+
start_date : datetime
17+
end_date : Optional[datetime]
18+
19+
@define
20+
class Event:
21+
# Auto-filled
22+
id: int
23+
type: str
24+
permission_group: str
25+
body: str
26+
confidential: bool
27+
announcement: bool
28+
canceled: bool
29+
inactive: bool
30+
creation_date: datetime
31+
last_modified: datetime
32+
live: bool
33+
archive_state: str
34+
archive_state_last_modified: Optional[datetime]
35+
allow_subscriptions: bool
36+
plannings: list[Planning]
37+
38+
# Manually filled
39+
title: str = field(init=False)
40+
location: str = field(init=False)
41+
gremium_id: int = field(init=False)
42+
43+
@staticmethod
44+
def from_json(json_object : any) -> 'Event':
45+
c = cattrs.Converter()
46+
47+
c.register_structure_hook(datetime, lambda date_string, _: parse_date(date_string))
48+
49+
try:
50+
meeting = c.structure(json_object, Event)
51+
except Exception as exc:
52+
print("\n".join(transform_error(exc)))
53+
quit()
54+
55+
attributes = json_object.get("attributes", [])
56+
meeting.title = get_title(attributes)
57+
meeting.location = get_location(attributes)
58+
meeting.gremium_id = json_object["gremium"]["id"]
59+
60+
return meeting
61+
62+
class EventApi:
63+
api_client : ApiClient
64+
65+
def __init__(self, api_client : ApiClient):
66+
self.api_client = api_client
67+
68+
69+
def get(self, date_from: datetime, date_to: datetime, gremia: list[int] = None) -> list[Event]:
70+
71+
json_events : list[dict] = []
72+
has_more_pages = True
73+
page = 1 # Notubiz uses 1-based paging
74+
75+
# We loop over the pages until no more pages are left
76+
while has_more_pages:
77+
78+
additional_payload = {
79+
'date_from': date_from.strftime("%Y-%m-%d %H:%M:%S"),
80+
'date_to': date_to.strftime("%Y-%m-%d %H:%M:%S"),
81+
# For some reason this endpoint requires 'organisation_id' instead of 'organisation"
82+
'organisation_id': self.api_client.configuration.organisation_id,
83+
'gremia': gremia,
84+
'page': page
85+
}
86+
87+
json_events_page = self.api_client.get("events/", additional_payload)
88+
json_events.extend(json_events_page["events"])
89+
90+
has_more_pages = json_events_page["pagination"]["has_more_pages"]
91+
page += 1
92+
93+
# Now run the deserialization based on the merged events
94+
return [Event.from_json(json_event) for json_event in json_events]

0 commit comments

Comments
 (0)