Generate ical files from schedule data
This commit is contained in:
parent
5140730189
commit
01e0b17586
1
.gitignore
vendored
1
.gitignore
vendored
@ -223,3 +223,4 @@ __marimo__/
|
|||||||
airingdata.json
|
airingdata.json
|
||||||
listdata.json
|
listdata.json
|
||||||
config.toml
|
config.toml
|
||||||
|
anime.ics
|
||||||
|
|||||||
@ -4,6 +4,3 @@ mediaType = "ANIME"
|
|||||||
|
|
||||||
[anical]
|
[anical]
|
||||||
listNames = ["Completed", "Planning", "Watching", "Rewatching", "Paused"]
|
listNames = ["Completed", "Planning", "Watching", "Rewatching", "Paused"]
|
||||||
|
|
||||||
[ical]
|
|
||||||
# reserved for future use
|
|
||||||
46
main.py
46
main.py
@ -3,6 +3,8 @@ import time
|
|||||||
import tomllib
|
import tomllib
|
||||||
from os import path
|
from os import path
|
||||||
import json
|
import json
|
||||||
|
from icalendar import Calendar, Event
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
if path.exists("config.toml"):
|
if path.exists("config.toml"):
|
||||||
with open("config.toml", "rb") as f:
|
with open("config.toml", "rb") as f:
|
||||||
@ -305,6 +307,47 @@ def getAiringScheduleBatch(
|
|||||||
|
|
||||||
return (form, False)
|
return (form, False)
|
||||||
|
|
||||||
|
def createIcal(
|
||||||
|
schedules,
|
||||||
|
*,
|
||||||
|
name="Anime Airing Schedule",
|
||||||
|
duration=24 * 60
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Returns the .ics file contents (bytes) for every upcoming episode in schedules.
|
||||||
|
|
||||||
|
Takes the following arguments:
|
||||||
|
- schedules: the "response" dict from getAiringScheduleBatch (mediaId -> {"title", "schedule"})
|
||||||
|
- name: the calendar's display name (defaults to "Anime Airing Schedule")
|
||||||
|
- duration: event length in seconds (defaults to 24 minutes)
|
||||||
|
"""
|
||||||
|
|
||||||
|
cal = Calendar()
|
||||||
|
cal.add("prodid", "-//anical//AniList airing schedule//EN")
|
||||||
|
cal.add("version", "2.0")
|
||||||
|
cal.add("x-wr-calname", name) # display name in Google/Apple Calendar
|
||||||
|
|
||||||
|
now = time.time()
|
||||||
|
stamp = datetime.now(timezone.utc)
|
||||||
|
|
||||||
|
for mediaId, anime in schedules.items():
|
||||||
|
title = anime["title"].get("english") or anime["title"].get("romaji") or f"Anime {mediaId}"
|
||||||
|
|
||||||
|
for item in anime["schedule"]:
|
||||||
|
# the cache can be older than some of its episodes, so skip anything already aired
|
||||||
|
if item["airingAt"] <= now:
|
||||||
|
continue
|
||||||
|
|
||||||
|
ev = Event()
|
||||||
|
ev.add("uid", f"anilist-{item['id']}@anilist.co")
|
||||||
|
ev.add("summary", f"{title} - Episode {item['episode']}")
|
||||||
|
ev.add("dtstart", datetime.fromtimestamp(item["airingAt"], timezone.utc))
|
||||||
|
ev.add("dtend", datetime.fromtimestamp(item["airingAt"] + duration, timezone.utc))
|
||||||
|
ev.add("dtstamp", stamp)
|
||||||
|
cal.add_component(ev)
|
||||||
|
|
||||||
|
return cal.to_ical() # bytes
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
entries, cached = getMediaListCollection()
|
entries, cached = getMediaListCollection()
|
||||||
|
|
||||||
@ -337,3 +380,6 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
schedules = airing["response"]
|
schedules = airing["response"]
|
||||||
print(f"\nGot upcoming episodes for {len(schedules)} anime")
|
print(f"\nGot upcoming episodes for {len(schedules)} anime")
|
||||||
|
|
||||||
|
with open("anime.ics", "wb") as f:
|
||||||
|
f.write(createIcal(schedules))
|
||||||
Loading…
Reference in New Issue
Block a user