84 lines
2.0 KiB
Python
84 lines
2.0 KiB
Python
import datetime
|
|
from icalendar import Event, Calendar, Timezone, TimezoneStandard
|
|
|
|
|
|
def create_timezone():
|
|
tz = Timezone()
|
|
tz.add("TZID", "Asia/Shanghai")
|
|
|
|
tz_standard = TimezoneStandard()
|
|
tz_standard.add("DTSTART", datetime.datetime(1970, 1, 1))
|
|
tz_standard.add("TZOFFSETFROM", datetime.timedelta(hours=8))
|
|
tz_standard.add("TZOFFSETTO", datetime.timedelta(hours=8))
|
|
|
|
tz.add_component(tz_standard)
|
|
return tz
|
|
|
|
|
|
def create_event(event_name, start, end):
|
|
# 创建事件/日程
|
|
event = Event()
|
|
event.add("SUMMARY", event_name)
|
|
|
|
event.add("DTSTART", start)
|
|
event.add("DTEND", end)
|
|
# 创建时间
|
|
event.add("DTSTAMP", start)
|
|
|
|
# UID保证唯一
|
|
event["UID"] = f"{start}/{end}/NateScarlet/holiday-cn"
|
|
|
|
return event
|
|
|
|
|
|
def ranger(lst):
|
|
if len(lst) == 0:
|
|
return []
|
|
|
|
if len(lst) == 1:
|
|
return [(lst[0], lst[0])]
|
|
|
|
fr, to = lst[0], lst[0]
|
|
for cur in lst[1:]:
|
|
if (cur.get("date") - to.get("date")).days == 1 and cur.get(
|
|
"isOffDay"
|
|
) == to.get("isOffDay"):
|
|
to = cur
|
|
else:
|
|
yield fr, to
|
|
fr, to = cur, cur
|
|
yield fr, to
|
|
|
|
|
|
def conv_json_to_ics(data, filename):
|
|
"""
|
|
将爬取的节假日JSON数据转换为ICS
|
|
|
|
Args:
|
|
filename: str
|
|
data: from `fetch_holiday`
|
|
"""
|
|
cal = Calendar()
|
|
cal.add("VERSION", "2.0")
|
|
cal.add("METHOD", "PUBLISH")
|
|
cal.add("CLASS", "PUBLIC")
|
|
|
|
cal.add_component(create_timezone())
|
|
|
|
days = data.get("days", [])
|
|
for day in days:
|
|
if isinstance(day.get("date"), str):
|
|
day["date"] = datetime.date(*map(int, day["date"].split("-")))
|
|
|
|
for fr, to in ranger(days):
|
|
start = fr.get("date")
|
|
end = to.get("date") + datetime.timedelta(days=1)
|
|
|
|
name = fr.get("name") + "假期"
|
|
if not fr.get("isOffDay"):
|
|
name = "上班(补" + name + ")"
|
|
cal.add_component(create_event(name, start, end))
|
|
|
|
with open(f"{filename}.ics", "wb") as ics:
|
|
ics.write(cal.to_ical())
|