使用python生成ical日历文件——将课程表导入到手机日历

  ics文件是日历软件中很常见的格式,可以将日历账户中的日程安排导出成.ics文件,也可以将.ics文件中的事件导入到日历中。那么我们如何使用python来生成Ics文件呢?我们可以先找一个ics文件,用文本的方式来打开这个文件,看看一个,ics文件里都包含了那些信息,我们使用python拼凑出相同格式的信息,写入文本文件并且使用ics后缀结尾不就可以了吗?

这是我在日历中创建日程事件之后导出的.ics文件中的片段:

 

BEGIN:VCALENDAR
PRODID:-//ZHONG_BAI_REN//APPGENIX-SOFTWARE//
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:my_schedule
X-WR-TIMEZONE:null
BEGIN:VEVENT
SUMMARY:工程电磁场
ORGANIZER;CN=My Calendar:mailto:nobody@gmail.com
DTSTART;TZID=Asia/Shanghai:20190513T082000
DTEND;TZID=Asia/Shanghai:20190513T095500
DTSTAMP:20190221T202219Z
UID:20190221T202219Z-11@appgenix-software.com
SEQUENCE:0
CREATED:20190221T202219Z
DESCRIPTION:李风从-主讲
LAST-MODIFIED:20190221T202219Z
LOCATION:2-006
STATUS:CONFIRMED
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
  从这个代码片段就可以看出ics文件的大致结构,文件以BEGIN:VCALENDAR开头,END:VCALENDAR结尾,事件以BEGIN:VEVENT开头,以END:VEVENT结尾。仔细查看了各个字段名称和字段后面的内容后可以猜知道
每个字段的含义,再根据每个字段的含义来编写python代码。
  贴上代码:
 1 import datetime,os
 2 
 3 class Event:
 4     """
 5     事件对象
 6     """
 7     def __init__(self,kwargs):
 8         self.event_data = kwargs
 9 
10     def __turn_to_string__(self):
11         self.event_text = "BEGIN:VEVENT\n"
12         for item,data in self.event_data.items():
13             item = str(item).replace("_","-")
14             if item not in ["ORGANIZER","DTSTART","DTEND"]:
15                 self.event_text += "%s:%s\n"%(item,data)
16             else:
17                 self.event_text += "%s;%s\n"%(item,data)
18         self.event_text += "END:VEVENT\n"
19         return self.event_text
20 
21 class Calendar:
22     """
23     日历对象
24     """
25     def __init__(self,calendar_name="My Calendar"):
26         self.__events__ = {}
27         self.__event_id__ = 0
28         self.calendar_name = calendar_name
29 
30     def add_event(self,**kwargs):
31         event = Event(kwargs)
32         event_id = self.__event_id__
33         self.__events__[self.__event_id__] = event
34         self.__event_id__ += 1
35         return event_id
36 
37     def modify_event(self,event_id,**kwargs):
38         for item,data in kwargs.items():
39             self.__events__[event_id].event_data[item] = data
40     
41     def remove_event(self,event_id):
42         self.__events__.pop(event_id)
43     
44     def get_ics_text(self):
45         self.__calendar_text__ = """BEGIN:VCALENDAR\nPRODID:-//ZHONG_BAI_REN//APPGENIX-SOFTWARE//\nVERSION:2.0\nCALSCALE:GREGORIAN\nMETHOD:PUBLISH\nX-WR-CALNAME:%s\nX-WR-TIMEZONE:null\n"""%self.calendar_name
46         for key,value in self.__events__.items():
47             self.__calendar_text__ += value.__turn_to_string__()
48         self.__calendar_text__ += "END:VCALENDAR"
49         return self.__calendar_text__
50     
51     def save_as_ics_file(self):
52         ics_text = self.get_ics_text()
53         open("%s.ics"%self.calendar_name,"w",encoding="utf8").write(ics_text)#使用utf8编码生成ics文件,否则日历软件打开是乱码
54 
55     def open_ics_file(self):
56         os.system("%s.ics"%self.calendar_name)
57 
58 def add_event(cal, SUMMARY, DTSTART, DTEND, DESCRIPTION, LOCATION):
59     """
60     向Calendar日历对象添加事件的方法
61     :param cal: calender日历实例
62     :param SUMMARY: 事件名
63     :param DTSTART: 事件开始时间
64     :param DTEND: 时间结束时间
65     :param DESCRIPTION: 备注
66     :param LOCATION: 时间地点
67     :return:
68     """
69     time_format = "TZID=Asia/Shanghai:{date.year}{date.month:0>2d}{date.day:0>2d}T{date.hour:0>2d}{date.minute:0>2d}00"
70     dt_start = time_format.format(date=DTSTART)
71     dt_end = time_format.format(date=DTEND)
72     create_time = datetime.datetime.today().strftime("%Y%m%dT%H%M%SZ")
73     cal.add_event(
74         SUMMARY=SUMMARY,
75         ORGANIZER="CN=My Calendar:mailto:nobody@gmail.com",
76         DTSTART=dt_start,
77         DTEND=dt_end,
78         DTSTAMP=create_time,
79         UID="{}-11@appgenix-software.com".format(create_time),
80         SEQUENCE="0",
81         CREATED=create_time,
82         DESCRIPTION=DESCRIPTION,
83         LAST_MODIFIED=create_time,
84         LOCATION=LOCATION,
85         STATUS="CONFIRMED",
86         TRANSP="OPAQUE"
87     )
88 
89 if __name__ == '__main__':
90     calendar = Calendar(calendar_name="test")
91     add_event(calendar,
92               SUMMARY="测试",
93               DTSTART=datetime.datetime(year=2019,month=2,day=19,hour=21,minute=21,second=00),
94               DTEND=datetime.datetime(year=2019,month=2,day=19,hour=21,minute=30,second=00),
95               DESCRIPTION="测试事件",
96               LOCATION="我也不知道在哪儿")
97     print(calendar.get_ics_text())
98     calendar.save_as_ics_file()

 代码的使用方法:

  1.创建Calendar日历对象,传入可选参数“calendar_name”(同时也是生成的ics文件名,不传入则为默认值“My Calendar”)
  2.调用add_event方法,第一个参数传入上一步的Calendar实例,然后依次传入
    
    参数作用   参数名     参数类型
    日历对象   cal      Calender对象
    事件名称   SUMMARY    字符串类型
    事件开始时间 DTSTART    datetime类型
    事件结束时间 DTEND     datetime类型
    事件发生地点 LOCATION    字符串类型
    事件备注   DESCRIPTION  字符串类型
  3.调用Calendar实例的save_as_ics_file()方法,即可在代码的工作目录里生成一个ics文件
  4.使用电脑或者手机等的日历软件的导入功能,即可将事件导入到日历的日程中。
posted @ 2019-02-25 20:37  钟摆人  阅读(5873)  评论(1编辑  收藏  举报