Skip to content

Commit c3b01da

Browse files
committed
attempt to implement recurring events
1 parent 37480b8 commit c3b01da

File tree

2 files changed

+400
-4
lines changed

2 files changed

+400
-4
lines changed
Lines changed: 381 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,381 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "ab102b23-6a89-4a21-bcb4-efa3b4b0c149",
6+
"metadata": {},
7+
"source": [
8+
"# Dev: Recurring Events in Calendar"
9+
]
10+
},
11+
{
12+
"cell_type": "markdown",
13+
"id": "a62a6d48-1209-497d-b4b6-26cc60fadc4f",
14+
"metadata": {},
15+
"source": [
16+
"## Preamble"
17+
]
18+
},
19+
{
20+
"cell_type": "code",
21+
"execution_count": 1,
22+
"id": "4f23acd4-bfc7-4dc6-9d61-cedadbeb1dd2",
23+
"metadata": {},
24+
"outputs": [],
25+
"source": [
26+
"from pathlib import Path\n",
27+
"import ipywidgets"
28+
]
29+
},
30+
{
31+
"cell_type": "markdown",
32+
"id": "11d81573-7f4d-46e9-9c5c-02f25cda5110",
33+
"metadata": {},
34+
"source": [
35+
"## Workflow"
36+
]
37+
},
38+
{
39+
"cell_type": "code",
40+
"execution_count": 2,
41+
"id": "784e2c72-2223-40a4-9790-a6ec6fd35c77",
42+
"metadata": {},
43+
"outputs": [
44+
{
45+
"data": {
46+
"application/vnd.jupyter.widget-view+json": {
47+
"model_id": "9adc637712b843c6919dcb89e13a94c1",
48+
"version_major": 2,
49+
"version_minor": 0
50+
},
51+
"text/plain": [
52+
"FileUpload(value={}, accept='*.ics', description='Upload')"
53+
]
54+
},
55+
"metadata": {},
56+
"output_type": "display_data"
57+
}
58+
],
59+
"source": [
60+
"cal_upload = ipywidgets.FileUpload(\n",
61+
" accept='*.ics', # Accepted file extension e.g. '.txt', '.pdf', 'image/*', 'image/*,.pdf'\n",
62+
" multiple=False # True to accept multiple files upload else False\n",
63+
")\n",
64+
"cal_upload"
65+
]
66+
},
67+
{
68+
"cell_type": "code",
69+
"execution_count": 4,
70+
"id": "26ac4e5c-ef37-4a36-874f-18454ba33d09",
71+
"metadata": {},
72+
"outputs": [],
73+
"source": [
74+
"cal_content = list(cal_upload.value.values())[0][\"content\"]"
75+
]
76+
},
77+
{
78+
"cell_type": "code",
79+
"execution_count": 5,
80+
"id": "05b26776-6e38-404b-b15a-753aa4c59382",
81+
"metadata": {},
82+
"outputs": [],
83+
"source": [
84+
"from tuttle.calendar import FileCalendar"
85+
]
86+
},
87+
{
88+
"cell_type": "code",
89+
"execution_count": 7,
90+
"id": "3b051220-1c0e-40b1-ab31-261cb8b6a08c",
91+
"metadata": {},
92+
"outputs": [],
93+
"source": [
94+
"test_calendar = FileCalendar(name=\"debug\", content=cal_content)"
95+
]
96+
},
97+
{
98+
"cell_type": "code",
99+
"execution_count": 8,
100+
"id": "8414d531-8640-435e-b165-da488754c632",
101+
"metadata": {},
102+
"outputs": [
103+
{
104+
"data": {
105+
"text/html": [
106+
"<div>\n",
107+
"<style scoped>\n",
108+
" .dataframe tbody tr th:only-of-type {\n",
109+
" vertical-align: middle;\n",
110+
" }\n",
111+
"\n",
112+
" .dataframe tbody tr th {\n",
113+
" vertical-align: top;\n",
114+
" }\n",
115+
"\n",
116+
" .dataframe thead th {\n",
117+
" text-align: right;\n",
118+
" }\n",
119+
"</style>\n",
120+
"<table border=\"1\" class=\"dataframe\">\n",
121+
" <thead>\n",
122+
" <tr style=\"text-align: right;\">\n",
123+
" <th></th>\n",
124+
" <th>title</th>\n",
125+
" <th>description</th>\n",
126+
" <th>end</th>\n",
127+
" <th>all_day</th>\n",
128+
" <th>duration</th>\n",
129+
" <th>tag</th>\n",
130+
" </tr>\n",
131+
" <tr>\n",
132+
" <th>begin</th>\n",
133+
" <th></th>\n",
134+
" <th></th>\n",
135+
" <th></th>\n",
136+
" <th></th>\n",
137+
" <th></th>\n",
138+
" <th></th>\n",
139+
" </tr>\n",
140+
" </thead>\n",
141+
" <tbody>\n",
142+
" <tr>\n",
143+
" <th>2022-01-14 09:00:00+01:00</th>\n",
144+
" <td>#slf</td>\n",
145+
" <td></td>\n",
146+
" <td>2022-01-14 12:00:00+01:00</td>\n",
147+
" <td>False</td>\n",
148+
" <td>0 days 03:00:00</td>\n",
149+
" <td>#slf</td>\n",
150+
" </tr>\n",
151+
" <tr>\n",
152+
" <th>2022-01-03 09:00:00+01:00</th>\n",
153+
" <td>#slf</td>\n",
154+
" <td></td>\n",
155+
" <td>2022-01-03 16:00:00+01:00</td>\n",
156+
" <td>False</td>\n",
157+
" <td>0 days 07:00:00</td>\n",
158+
" <td>#slf</td>\n",
159+
" </tr>\n",
160+
" </tbody>\n",
161+
"</table>\n",
162+
"</div>"
163+
],
164+
"text/plain": [
165+
" title description end \\\n",
166+
"begin \n",
167+
"2022-01-14 09:00:00+01:00 #slf 2022-01-14 12:00:00+01:00 \n",
168+
"2022-01-03 09:00:00+01:00 #slf 2022-01-03 16:00:00+01:00 \n",
169+
"\n",
170+
" all_day duration tag \n",
171+
"begin \n",
172+
"2022-01-14 09:00:00+01:00 False 0 days 03:00:00 #slf \n",
173+
"2022-01-03 09:00:00+01:00 False 0 days 07:00:00 #slf "
174+
]
175+
},
176+
"execution_count": 8,
177+
"metadata": {},
178+
"output_type": "execute_result"
179+
}
180+
],
181+
"source": [
182+
"test_calendar.to_data()"
183+
]
184+
},
185+
{
186+
"cell_type": "code",
187+
"execution_count": 9,
188+
"id": "b65dfca3-7462-421a-9b4b-90c3f190af2e",
189+
"metadata": {},
190+
"outputs": [
191+
{
192+
"data": {
193+
"text/html": [
194+
"<div>\n",
195+
"<style scoped>\n",
196+
" .dataframe tbody tr th:only-of-type {\n",
197+
" vertical-align: middle;\n",
198+
" }\n",
199+
"\n",
200+
" .dataframe tbody tr th {\n",
201+
" vertical-align: top;\n",
202+
" }\n",
203+
"\n",
204+
" .dataframe thead th {\n",
205+
" text-align: right;\n",
206+
" }\n",
207+
"</style>\n",
208+
"<table border=\"1\" class=\"dataframe\">\n",
209+
" <thead>\n",
210+
" <tr style=\"text-align: right;\">\n",
211+
" <th></th>\n",
212+
" <th>_duration</th>\n",
213+
" <th>_end_time</th>\n",
214+
" <th>_begin</th>\n",
215+
" <th>_begin_precision</th>\n",
216+
" <th>_status</th>\n",
217+
" <th>_classification</th>\n",
218+
" <th>organizer</th>\n",
219+
" <th>uid</th>\n",
220+
" <th>description</th>\n",
221+
" <th>created</th>\n",
222+
" <th>last_modified</th>\n",
223+
" <th>location</th>\n",
224+
" <th>url</th>\n",
225+
" <th>transparent</th>\n",
226+
" <th>alarms</th>\n",
227+
" <th>attendees</th>\n",
228+
" <th>categories</th>\n",
229+
" <th>_geo</th>\n",
230+
" <th>extra</th>\n",
231+
" <th>name</th>\n",
232+
" <th>_classmethod_args</th>\n",
233+
" <th>_classmethod_kwargs</th>\n",
234+
" </tr>\n",
235+
" </thead>\n",
236+
" <tbody>\n",
237+
" <tr>\n",
238+
" <th>0</th>\n",
239+
" <td>None</td>\n",
240+
" <td>2022-01-14T12:00:00+01:00</td>\n",
241+
" <td>2022-01-14T09:00:00+01:00</td>\n",
242+
" <td>second</td>\n",
243+
" <td>CONFIRMED</td>\n",
244+
" <td>None</td>\n",
245+
" <td>None</td>\n",
246+
" <td>[email protected]</td>\n",
247+
" <td></td>\n",
248+
" <td>2022-02-20T10:38:32+00:00</td>\n",
249+
" <td>2022-02-20T10:12:33+00:00</td>\n",
250+
" <td></td>\n",
251+
" <td>None</td>\n",
252+
" <td>False</td>\n",
253+
" <td>[]</td>\n",
254+
" <td>{}</td>\n",
255+
" <td>{}</td>\n",
256+
" <td>None</td>\n",
257+
" <td>[RECURRENCE-ID;TZID=Europe/Berlin:20220114T090...</td>\n",
258+
" <td>#slf</td>\n",
259+
" <td>()</td>\n",
260+
" <td>{'tz': {'Europe/Berlin': &lt;tzicalvtz 'Europe/Be...</td>\n",
261+
" </tr>\n",
262+
" <tr>\n",
263+
" <th>1</th>\n",
264+
" <td>None</td>\n",
265+
" <td>2022-01-03T16:00:00+01:00</td>\n",
266+
" <td>2022-01-03T09:00:00+01:00</td>\n",
267+
" <td>second</td>\n",
268+
" <td>CONFIRMED</td>\n",
269+
" <td>None</td>\n",
270+
" <td>None</td>\n",
271+
" <td>[email protected]</td>\n",
272+
" <td></td>\n",
273+
" <td>2022-02-20T10:38:32+00:00</td>\n",
274+
" <td>2022-02-20T10:12:33+00:00</td>\n",
275+
" <td></td>\n",
276+
" <td>None</td>\n",
277+
" <td>False</td>\n",
278+
" <td>[]</td>\n",
279+
" <td>{}</td>\n",
280+
" <td>{}</td>\n",
281+
" <td>None</td>\n",
282+
" <td>[RRULE:FREQ=WEEKLY;UNTIL=20220213T225959Z;BYDA...</td>\n",
283+
" <td>#slf</td>\n",
284+
" <td>()</td>\n",
285+
" <td>{'tz': {'Europe/Berlin': &lt;tzicalvtz 'Europe/Be...</td>\n",
286+
" </tr>\n",
287+
" </tbody>\n",
288+
"</table>\n",
289+
"</div>"
290+
],
291+
"text/plain": [
292+
" _duration _end_time _begin \\\n",
293+
"0 None 2022-01-14T12:00:00+01:00 2022-01-14T09:00:00+01:00 \n",
294+
"1 None 2022-01-03T16:00:00+01:00 2022-01-03T09:00:00+01:00 \n",
295+
"\n",
296+
" _begin_precision _status _classification organizer \\\n",
297+
"0 second CONFIRMED None None \n",
298+
"1 second CONFIRMED None None \n",
299+
"\n",
300+
" uid description \\\n",
301+
302+
303+
"\n",
304+
" created last_modified location url \\\n",
305+
"0 2022-02-20T10:38:32+00:00 2022-02-20T10:12:33+00:00 None \n",
306+
"1 2022-02-20T10:38:32+00:00 2022-02-20T10:12:33+00:00 None \n",
307+
"\n",
308+
" transparent alarms attendees categories _geo \\\n",
309+
"0 False [] {} {} None \n",
310+
"1 False [] {} {} None \n",
311+
"\n",
312+
" extra name _classmethod_args \\\n",
313+
"0 [RECURRENCE-ID;TZID=Europe/Berlin:20220114T090... #slf () \n",
314+
"1 [RRULE:FREQ=WEEKLY;UNTIL=20220213T225959Z;BYDA... #slf () \n",
315+
"\n",
316+
" _classmethod_kwargs \n",
317+
"0 {'tz': {'Europe/Berlin': <tzicalvtz 'Europe/Be... \n",
318+
"1 {'tz': {'Europe/Berlin': <tzicalvtz 'Europe/Be... "
319+
]
320+
},
321+
"execution_count": 9,
322+
"metadata": {},
323+
"output_type": "execute_result"
324+
}
325+
],
326+
"source": [
327+
"test_calendar.to_raw_data()"
328+
]
329+
},
330+
{
331+
"cell_type": "code",
332+
"execution_count": 10,
333+
"id": "9745a3a1-b57a-4fd9-8393-2f4bcb65a011",
334+
"metadata": {},
335+
"outputs": [
336+
{
337+
"data": {
338+
"text/plain": [
339+
"b'BEGIN:VCALENDAR\\r\\nPRODID:-//Google Inc//Google Calendar 70.9054//EN\\r\\nVERSION:2.0\\r\\nCALSCALE:GREGORIAN\\r\\nMETHOD:PUBLISH\\r\\nX-WR-CALNAME:wayfair\\r\\nX-WR-TIMEZONE:Europe/Berlin\\r\\nBEGIN:VTIMEZONE\\r\\nTZID:Europe/Berlin\\r\\nX-LIC-LOCATION:Europe/Berlin\\r\\nBEGIN:DAYLIGHT\\r\\nTZOFFSETFROM:+0100\\r\\nTZOFFSETTO:+0200\\r\\nTZNAME:CEST\\r\\nDTSTART:19700329T020000\\r\\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\\r\\nEND:DAYLIGHT\\r\\nBEGIN:STANDARD\\r\\nTZOFFSETFROM:+0200\\r\\nTZOFFSETTO:+0100\\r\\nTZNAME:CET\\r\\nDTSTART:19701025T030000\\r\\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\\r\\nEND:STANDARD\\r\\nEND:VTIMEZONE\\r\\nBEGIN:VEVENT\\r\\nDTSTART;TZID=Europe/Berlin:20220103T090000\\r\\nDTEND;TZID=Europe/Berlin:20220103T160000\\r\\nRRULE:FREQ=WEEKLY;UNTIL=20220213T225959Z;BYDAY=FR,MO,TH,TU,WE\\r\\nEXDATE;TZID=Europe/Berlin:20220104T090000\\r\\nDTSTAMP:20220220T103832Z\\r\\nUID:[email protected]\\r\\nCREATED:20220220T101129Z\\r\\nDESCRIPTION:\\r\\nLAST-MODIFIED:20220220T101233Z\\r\\nLOCATION:\\r\\nSEQUENCE:0\\r\\nSTATUS:CONFIRMED\\r\\nSUMMARY:#slf\\r\\nTRANSP:OPAQUE\\r\\nEND:VEVENT\\r\\nBEGIN:VEVENT\\r\\nDTSTART;TZID=Europe/Berlin:20220114T090000\\r\\nDTEND;TZID=Europe/Berlin:20220114T120000\\r\\nDTSTAMP:20220220T103832Z\\r\\nUID:[email protected]\\r\\nRECURRENCE-ID;TZID=Europe/Berlin:20220114T090000\\r\\nCREATED:20220220T101129Z\\r\\nDESCRIPTION:\\r\\nLAST-MODIFIED:20220220T101233Z\\r\\nLOCATION:\\r\\nSEQUENCE:0\\r\\nSTATUS:CONFIRMED\\r\\nSUMMARY:#slf\\r\\nTRANSP:OPAQUE\\r\\nEND:VEVENT\\r\\nEND:VCALENDAR\\r\\n'"
340+
]
341+
},
342+
"execution_count": 10,
343+
"metadata": {},
344+
"output_type": "execute_result"
345+
}
346+
],
347+
"source": [
348+
"cal_content"
349+
]
350+
},
351+
{
352+
"cell_type": "code",
353+
"execution_count": null,
354+
"id": "59343ae7-85da-46a7-921d-1fc99b19ebc2",
355+
"metadata": {},
356+
"outputs": [],
357+
"source": []
358+
}
359+
],
360+
"metadata": {
361+
"kernelspec": {
362+
"display_name": "tuttle",
363+
"language": "python",
364+
"name": "ex"
365+
},
366+
"language_info": {
367+
"codemirror_mode": {
368+
"name": "ipython",
369+
"version": 3
370+
},
371+
"file_extension": ".py",
372+
"mimetype": "text/x-python",
373+
"name": "python",
374+
"nbconvert_exporter": "python",
375+
"pygments_lexer": "ipython3",
376+
"version": "3.9.7"
377+
}
378+
},
379+
"nbformat": 4,
380+
"nbformat_minor": 5
381+
}

0 commit comments

Comments
 (0)