Skip to content

Commit 5793e7c

Browse files
committed
added repeat events
1 parent c5ed3ae commit 5793e7c

File tree

2 files changed

+103
-82
lines changed

2 files changed

+103
-82
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ instance/
99
# ignore archive for importing
1010
archive/
1111
errors.txt
12-
tags.csv
12+
tags.txt

import.py

Lines changed: 102 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
api_key = "testing"
1313
base_url = "http://127.0.0.1:5000/api/events/"
1414
events_folder = Path("archive")
15-
tags_file = "tags.csv"
15+
tags_file = "tags.txt"
1616
tags = {}
1717
error_files = []
1818
error_file = "errors.txt"
@@ -92,7 +92,7 @@ def get_date_time(date_str: str, path: Path) -> datetime:
9292
return time
9393

9494

95-
def parse_event(path: Path) -> dict:
95+
def parse_event(path: Path, repeat: bool) -> dict:
9696
"""Parse an event and return it as a dictionary."""
9797

9898
with path.open("rb") as f:
@@ -111,28 +111,31 @@ def parse_event(path: Path) -> dict:
111111
# add description
112112
event["description"] = parts[2].strip() if parts[2].strip() else event["title"]
113113

114-
# parse start time
115-
start_time = get_date_time(event["date"], path)
116-
event["start_time"] = start_time
114+
if not repeat:
115+
# parse start time
116+
start_time = get_date_time(event["date"], path)
117+
event["start_time"] = start_time
117118

118-
# parse end time if supplied
119-
if "end_time" in event:
120-
try:
121-
# attempt to parse as ISO-8601 format
122-
event["end_time"] = datetime.fromisoformat(event["end_time"]).astimezone(
123-
pytz.timezone("Europe/London")
124-
)
125-
except ValueError:
126-
# if that fails, use custom parsing
127-
time, _ = parsedatetime.Calendar().parseDT(
128-
event["end_time"], event["start_time"], pytz.timezone("Europe/London")
129-
)
130-
event["end_time"] = time
131-
132-
if event["end_time"] < event["start_time"]:
133-
raise ValueError(
134-
f"End ({event["end_time"]}) is before start ({event["start_time"]})"
135-
)
119+
# parse end time if supplied
120+
if "end_time" in event:
121+
try:
122+
# attempt to parse as ISO-8601 format
123+
event["end_time"] = datetime.fromisoformat(
124+
event["end_time"]
125+
).astimezone(pytz.timezone("Europe/London"))
126+
except ValueError:
127+
# if that fails, use custom parsing
128+
time, _ = parsedatetime.Calendar().parseDT(
129+
event["end_time"],
130+
event["start_time"],
131+
pytz.timezone("Europe/London"),
132+
)
133+
event["end_time"] = time
134+
135+
if event["end_time"] < event["start_time"]:
136+
raise ValueError(
137+
f"End ({event["end_time"]}) is before start ({event["start_time"]})"
138+
)
136139

137140
# process icon to convert icons/<icon>.svg to <icon>
138141
if "icon" in event:
@@ -141,76 +144,94 @@ def parse_event(path: Path) -> dict:
141144
return event
142145

143146

144-
def import_events() -> None: # noqa: PLR0912
147+
def add_event(file: Path, event: dict) -> None: # noqa: PLR0912
148+
"""Add an event to the API"""
149+
150+
if "tags" in event:
151+
event_tags = event.pop("tags")
152+
for tag in event_tags:
153+
if tag not in tags:
154+
# if tag doesn't exist, create it
155+
tags[tag] = [str(file)]
156+
else:
157+
# otherwise, append to existing tag
158+
tags[tag].append(str(file))
159+
160+
# create colour and icon if not present
161+
if "colour" not in event:
162+
if "gaming" in event["title"].lower():
163+
event["colour"] = "gaming"
164+
event["icon"] = "fng" if not event.get("icon") else event["icon"]
165+
if "social" in event["title"].lower():
166+
event["colour"] = "social"
167+
if any(word in event["location"].lower() for word in ["duck", "coach"]):
168+
event["colour"] = "social"
169+
event["icon"] = "hamburger" if not event.get("icon") else event["icon"]
170+
171+
# prepare event and send to API
172+
event_json = {
173+
"name": event["title"],
174+
"description": event["description"],
175+
"location": event["location"],
176+
"start_time": event["start_time"].strftime("%Y-%m-%dT%H:%M"),
177+
}
178+
if "draft" in event:
179+
event_json["draft"] = event["draft"]
180+
if "location_url" in event:
181+
event_json["location_url"] = event["location_url"]
182+
if "icon" in event:
183+
event_json["icon"] = event["icon"]
184+
if "colour" in event:
185+
event_json["colour"] = event["colour"]
186+
if "end_time" in event:
187+
event_json["end_time"] = event["end_time"].strftime("%Y-%m-%dT%H:%M")
188+
189+
response = requests.post(
190+
base_url + "create/",
191+
json=event_json,
192+
headers={"Authorization": api_key},
193+
timeout=5,
194+
)
195+
196+
if response.status_code == 201: # noqa: PLR2004
197+
print(f"Successfully imported {file}")
198+
else:
199+
print(f"Failed to import {file}: {response.text.replace("\n", " ")}")
200+
error_files.append((file, response.text))
201+
202+
203+
def import_events() -> None:
145204
"""Import events from the archive folder and add them to the new API"""
146205

147206
print("Importing events...")
148207
for file in events_folder.rglob("*.md"):
149208
print(f"Importing {file}...")
150209

151210
try:
152-
if "repeat" in str(file.parent):
153-
# skip for now
154-
continue
155-
else:
156-
event = parse_event(file)
157-
except Exception as e:
211+
event = parse_event(file, "repeat" in file.parts)
212+
except ValueError as e:
158213
print(f"Error parsing {file}: {e}")
159214
error_files.append((file, str(e)))
160215
continue
161216

162-
# tags processing
163-
if "tags" in event:
164-
event_tags = event.pop("tags")
165-
for tag in event_tags:
166-
if tag not in tags:
167-
# if tag doesnt exist, create it
168-
tags[tag] = [event["title"]]
169-
else:
170-
# otherwise, append to existing tag
171-
tags[tag].append(event["title"])
172-
173-
# create colour
174-
if "colour" not in event:
175-
if "gaming" in event["title"].lower():
176-
event["colour"] = "gaming"
177-
event["icon"] = "fng"
178-
if "social" in event["title"].lower():
179-
event["colour"] = "social"
180-
if any(word in event["location"].lower() for word in ["duck", "coach"]):
181-
event["colour"] = "social"
182-
event["icon"] = "hamburger"
183-
184-
# prepare event and send to API
185-
event_json = {
186-
"name": event["title"],
187-
"description": event["description"],
188-
"location": event["location"],
189-
"start_time": event["start_time"].strftime("%Y-%m-%dT%H:%M"),
190-
}
191-
if "draft" in event:
192-
event_json["draft"] = event["draft"]
193-
if "location_url" in event:
194-
event_json["location_url"] = event["location_url"]
195-
if "icon" in event:
196-
event_json["icon"] = event["icon"]
197-
if "colour" in event:
198-
event_json["colour"] = event["colour"]
199-
if "end_time" in event:
200-
event_json["end_time"] = event["end_time"].strftime("%Y-%m-%dT%H:%M")
201-
202-
response = requests.post(
203-
base_url + "create/",
204-
json=event_json,
205-
headers={"Authorization": api_key},
206-
timeout=5,
207-
)
208-
209-
if response.status_code == 201: # noqa: PLR2004
210-
print(f"Successfully imported {file}")
217+
if "repeat" in file.parts:
218+
for week in event["weeks"]:
219+
event_copy = event.copy()
220+
event_date = get_date_from_week(file.parts[1], file.parts[2], week)
221+
time, _ = parsedatetime.Calendar().parseDT(
222+
event["date"], event_date, pytz.timezone("Europe/London")
223+
)
224+
event_copy["start_time"] = time
225+
if "end_time" in event_copy:
226+
time, _ = parsedatetime.Calendar().parseDT(
227+
event["end_time"],
228+
event_copy["start_time"],
229+
pytz.timezone("Europe/London"),
230+
)
231+
event_copy["end_time"] = time
232+
add_event(file, event_copy)
211233
else:
212-
print(f"Failed to import {file}: {response.text.replace("\n", " ")}")
213-
error_files.append((file, response.text))
234+
add_event(file, event)
214235

215236
# write tags to file
216237
with Path(tags_file).open("w", encoding="utf-8") as f:

0 commit comments

Comments
 (0)