jblu

jblu / p90x3cal.py

Last active 6 months ago

Like 0
p90x3.ics Raw
1BEGIN:VCALENDAR
2VERSION:2.0
3PRODID:-//jonb.io//p90x3iCalgen 1.0//EN
4BEGIN:VEVENT
5SUMMARY:Total Synergistics
6DTSTART:20250616
7DTEND:20250616
8END:VEVENT
9BEGIN:VEVENT
10SUMMARY:Agility X
11DTSTART:20250617
12DTEND:20250617
13END:VEVENT
14BEGIN:VEVENT
15SUMMARY:X3 Yoga
16DTSTART:20250618
17DTEND:20250618
18END:VEVENT
19BEGIN:VEVENT
20SUMMARY:The Challenge
21DTSTART:20250619
22DTEND:20250619
23END:VEVENT
24BEGIN:VEVENT
25SUMMARY:CVX
26DTSTART:20250620
27DTEND:20250620
28END:VEVENT
29BEGIN:VEVENT
30SUMMARY:The Warrior
31DTSTART:20250621
32DTEND:20250621
33END:VEVENT
34BEGIN:VEVENT
35SUMMARY:Rest or Dynamix
36DTSTART:20250622
37DTEND:20250622
38END:VEVENT
39BEGIN:VEVENT
40SUMMARY:Total Synergistics
41DTSTART:20250623
42DTEND:20250623
43END:VEVENT
44BEGIN:VEVENT
45SUMMARY:Agility X
46DTSTART:20250624
47DTEND:20250624
48END:VEVENT
49BEGIN:VEVENT
50SUMMARY:X3 Yoga
51DTSTART:20250625
52DTEND:20250625
53END:VEVENT
54BEGIN:VEVENT
55SUMMARY:The Challenge
56DTSTART:20250626
57DTEND:20250626
58END:VEVENT
59BEGIN:VEVENT
60SUMMARY:CVX
61DTSTART:20250627
62DTEND:20250627
63END:VEVENT
64BEGIN:VEVENT
65SUMMARY:The Warrior
66DTSTART:20250628
67DTEND:20250628
68END:VEVENT
69BEGIN:VEVENT
70SUMMARY:Rest or Dynamix
71DTSTART:20250629
72DTEND:20250629
73END:VEVENT
74BEGIN:VEVENT
75SUMMARY:Total Synergistics
76DTSTART:20250630
77DTEND:20250630
78END:VEVENT
79BEGIN:VEVENT
80SUMMARY:Agility X
81DTSTART:20250701
82DTEND:20250701
83END:VEVENT
84BEGIN:VEVENT
85SUMMARY:X3 Yoga
86DTSTART:20250702
87DTEND:20250702
88END:VEVENT
89BEGIN:VEVENT
90SUMMARY:The Challenge
91DTSTART:20250703
92DTEND:20250703
93END:VEVENT
94BEGIN:VEVENT
95SUMMARY:CVX
96DTSTART:20250704
97DTEND:20250704
98END:VEVENT
99BEGIN:VEVENT
100SUMMARY:The Warrior
101DTSTART:20250705
102DTEND:20250705
103END:VEVENT
104BEGIN:VEVENT
105SUMMARY:Rest or Dynamix
106DTSTART:20250706
107DTEND:20250706
108END:VEVENT
109BEGIN:VEVENT
110SUMMARY:Isometrics
111DTSTART:20250707
112DTEND:20250707
113END:VEVENT
114BEGIN:VEVENT
115SUMMARY:Dynamix
116DTSTART:20250708
117DTEND:20250708
118END:VEVENT
119BEGIN:VEVENT
120SUMMARY:Accelerator
121DTSTART:20250709
122DTEND:20250709
123END:VEVENT
124BEGIN:VEVENT
125SUMMARY:Pilates X
126DTSTART:20250710
127DTEND:20250710
128END:VEVENT
129BEGIN:VEVENT
130SUMMARY:CVX
131DTSTART:20250711
132DTEND:20250711
133END:VEVENT
134BEGIN:VEVENT
135SUMMARY:X3 Yoga
136DTSTART:20250712
137DTEND:20250712
138END:VEVENT
139BEGIN:VEVENT
140SUMMARY:Rest or Dynamix
141DTSTART:20250713
142DTEND:20250713
143END:VEVENT
144BEGIN:VEVENT
145SUMMARY:Eccentric Upper
146DTSTART:20250714
147DTEND:20250714
148END:VEVENT
149BEGIN:VEVENT
150SUMMARY:Triometrics
151DTSTART:20250715
152DTEND:20250715
153END:VEVENT
154BEGIN:VEVENT
155SUMMARY:X3 Yoga
156DTSTART:20250716
157DTEND:20250716
158END:VEVENT
159BEGIN:VEVENT
160SUMMARY:Eccentric Lower
161DTSTART:20250717
162DTEND:20250717
163END:VEVENT
164BEGIN:VEVENT
165SUMMARY:Incinerator
166DTSTART:20250718
167DTEND:20250718
168END:VEVENT
169BEGIN:VEVENT
170SUMMARY:MMX
171DTSTART:20250719
172DTEND:20250719
173END:VEVENT
174BEGIN:VEVENT
175SUMMARY:Rest or Dynamix
176DTSTART:20250720
177DTEND:20250720
178END:VEVENT
179BEGIN:VEVENT
180SUMMARY:Eccentric Upper
181DTSTART:20250721
182DTEND:20250721
183END:VEVENT
184BEGIN:VEVENT
185SUMMARY:Triometrics
186DTSTART:20250722
187DTEND:20250722
188END:VEVENT
189BEGIN:VEVENT
190SUMMARY:X3 Yoga
191DTSTART:20250723
192DTEND:20250723
193END:VEVENT
194BEGIN:VEVENT
195SUMMARY:Eccentric Lower
196DTSTART:20250724
197DTEND:20250724
198END:VEVENT
199BEGIN:VEVENT
200SUMMARY:Incinerator
201DTSTART:20250725
202DTEND:20250725
203END:VEVENT
204BEGIN:VEVENT
205SUMMARY:MMX
206DTSTART:20250726
207DTEND:20250726
208END:VEVENT
209BEGIN:VEVENT
210SUMMARY:Rest or Dynamix
211DTSTART:20250727
212DTEND:20250727
213END:VEVENT
214BEGIN:VEVENT
215SUMMARY:Eccentric Upper
216DTSTART:20250728
217DTEND:20250728
218END:VEVENT
219BEGIN:VEVENT
220SUMMARY:Triometrics
221DTSTART:20250729
222DTEND:20250729
223END:VEVENT
224BEGIN:VEVENT
225SUMMARY:X3 Yoga
226DTSTART:20250730
227DTEND:20250730
228END:VEVENT
229BEGIN:VEVENT
230SUMMARY:Eccentric Lower
231DTSTART:20250731
232DTEND:20250731
233END:VEVENT
234BEGIN:VEVENT
235SUMMARY:Incinerator
236DTSTART:20250801
237DTEND:20250801
238END:VEVENT
239BEGIN:VEVENT
240SUMMARY:MMX
241DTSTART:20250802
242DTEND:20250802
243END:VEVENT
244BEGIN:VEVENT
245SUMMARY:Rest or Dynamix
246DTSTART:20250803
247DTEND:20250803
248END:VEVENT
249BEGIN:VEVENT
250SUMMARY:Isometrics
251DTSTART:20250804
252DTEND:20250804
253END:VEVENT
254BEGIN:VEVENT
255SUMMARY:Dynamix
256DTSTART:20250805
257DTEND:20250805
258END:VEVENT
259BEGIN:VEVENT
260SUMMARY:Accelerator
261DTSTART:20250806
262DTEND:20250806
263END:VEVENT
264BEGIN:VEVENT
265SUMMARY:Pilates X
266DTSTART:20250807
267DTEND:20250807
268END:VEVENT
269BEGIN:VEVENT
270SUMMARY:CVX
271DTSTART:20250808
272DTEND:20250808
273END:VEVENT
274BEGIN:VEVENT
275SUMMARY:X3 Yoga
276DTSTART:20250809
277DTEND:20250809
278END:VEVENT
279BEGIN:VEVENT
280SUMMARY:Rest or Dynamix
281DTSTART:20250810
282DTEND:20250810
283END:VEVENT
284BEGIN:VEVENT
285SUMMARY:Decelerator
286DTSTART:20250811
287DTEND:20250811
288END:VEVENT
289BEGIN:VEVENT
290SUMMARY:Agility X
291DTSTART:20250812
292DTEND:20250812
293END:VEVENT
294BEGIN:VEVENT
295SUMMARY:The Challenge
296DTSTART:20250813
297DTEND:20250813
298END:VEVENT
299BEGIN:VEVENT
300SUMMARY:X3 Yoga
301DTSTART:20250814
302DTEND:20250814
303END:VEVENT
304BEGIN:VEVENT
305SUMMARY:Triometrics
306DTSTART:20250815
307DTEND:20250815
308END:VEVENT
309BEGIN:VEVENT
310SUMMARY:Total Synergistics
311DTSTART:20250816
312DTEND:20250816
313END:VEVENT
314BEGIN:VEVENT
315SUMMARY:Rest or Dynamix
316DTSTART:20250817
317DTEND:20250817
318END:VEVENT
319BEGIN:VEVENT
320SUMMARY:Decelerator
321DTSTART:20250818
322DTEND:20250818
323END:VEVENT
324BEGIN:VEVENT
325SUMMARY:MMX
326DTSTART:20250819
327DTEND:20250819
328END:VEVENT
329BEGIN:VEVENT
330SUMMARY:Eccentric Upper
331DTSTART:20250820
332DTEND:20250820
333END:VEVENT
334BEGIN:VEVENT
335SUMMARY:Triometrics
336DTSTART:20250821
337DTEND:20250821
338END:VEVENT
339BEGIN:VEVENT
340SUMMARY:Pilates X
341DTSTART:20250822
342DTEND:20250822
343END:VEVENT
344BEGIN:VEVENT
345SUMMARY:Eccentric Lower
346DTSTART:20250823
347DTEND:20250823
348END:VEVENT
349BEGIN:VEVENT
350SUMMARY:Rest or Dynamix
351DTSTART:20250824
352DTEND:20250824
353END:VEVENT
354BEGIN:VEVENT
355SUMMARY:Decelerator
356DTSTART:20250825
357DTEND:20250825
358END:VEVENT
359BEGIN:VEVENT
360SUMMARY:Agility X
361DTSTART:20250826
362DTEND:20250826
363END:VEVENT
364BEGIN:VEVENT
365SUMMARY:The Challenge
366DTSTART:20250827
367DTEND:20250827
368END:VEVENT
369BEGIN:VEVENT
370SUMMARY:X3 Yoga
371DTSTART:20250828
372DTEND:20250828
373END:VEVENT
374BEGIN:VEVENT
375SUMMARY:Triometrics
376DTSTART:20250829
377DTEND:20250829
378END:VEVENT
379BEGIN:VEVENT
380SUMMARY:Total Synergistics
381DTSTART:20250830
382DTEND:20250830
383END:VEVENT
384BEGIN:VEVENT
385SUMMARY:Rest or Dynamix
386DTSTART:20250831
387DTEND:20250831
388END:VEVENT
389BEGIN:VEVENT
390SUMMARY:Decelerator
391DTSTART:20250901
392DTEND:20250901
393END:VEVENT
394BEGIN:VEVENT
395SUMMARY:MMX
396DTSTART:20250902
397DTEND:20250902
398END:VEVENT
399BEGIN:VEVENT
400SUMMARY:Eccentric Upper
401DTSTART:20250903
402DTEND:20250903
403END:VEVENT
404BEGIN:VEVENT
405SUMMARY:Triometrics
406DTSTART:20250904
407DTEND:20250904
408END:VEVENT
409BEGIN:VEVENT
410SUMMARY:Pilates X
411DTSTART:20250905
412DTEND:20250905
413END:VEVENT
414BEGIN:VEVENT
415SUMMARY:Eccentric Lower
416DTSTART:20250906
417DTEND:20250906
418END:VEVENT
419BEGIN:VEVENT
420SUMMARY:Rest or Dynamix
421DTSTART:20250907
422DTEND:20250907
423END:VEVENT
424BEGIN:VEVENT
425SUMMARY:Isometrics
426DTSTART:20250908
427DTEND:20250908
428END:VEVENT
429BEGIN:VEVENT
430SUMMARY:Accelerator
431DTSTART:20250909
432DTEND:20250909
433END:VEVENT
434BEGIN:VEVENT
435SUMMARY:Pilates X
436DTSTART:20250910
437DTEND:20250910
438END:VEVENT
439BEGIN:VEVENT
440SUMMARY:X3 Yoga
441DTSTART:20250911
442DTEND:20250911
443END:VEVENT
444BEGIN:VEVENT
445SUMMARY:Dynamix
446DTSTART:20250912
447DTEND:20250912
448END:VEVENT
449BEGIN:VEVENT
450SUMMARY:Rest or Dynamix
451DTSTART:20250913
452DTEND:20250913
453END:VEVENT
454END:VCALENDAR
p90x3cal.py Raw
1import argparse, datetime
2
3def date(s):
4 try:
5 return datetime.datetime.strptime(s, "%Y-%m-%d")
6 except ValueError:
7 raise argparse.ArgumentTypeError(f"Not a valid date: '{s}'. Date must be in format 'YYYY-MM-DD'")
8
9parser = argparse.ArgumentParser(description='Generate a P90X3 schedule in iCalendar format.')
10parser.add_argument('--start', type=date, default=datetime.date.today(), help='start date (YYYY-MM-DD) (default: today)')
11parser.add_argument('--variant', choices=["classic", "lean", "mass"], default="classic", help="calendar variant (default: classic)")
12parser.add_argument('--prefix', type=str, default='', help="prefix to add to all event names")
13parser.add_argument('--suffix', type=str, default='', help="suffix to add to all event names")
14args = parser.parse_args()
15
16TOTAL = "Total Synergistics"
17CVX = "CVX"
18AGILITY = "Agility X"
19TRIO = "Triometrics"
20CHALLENGE = "The Challenge"
21INCINERATOR = "Incinerator"
22WARRIOR = "The Warrior"
23MMX = "MMX"
24YOGA = "X3 Yoga"
25PILATES = "Pilates X"
26ISOMETRICS = "Isometrics"
27DYNAMIX = "Dynamix"
28ACCELERATOR = "Accelerator"
29DECELERATOR = "Decelerator"
30UPPER = "Eccentric Upper"
31LOWER = "Eccentric Lower"
32REST = "Rest or Dynamix"
33
34SCHEDULES = {
35 "classic": [
36 TOTAL, AGILITY, YOGA, CHALLENGE, CVX, WARRIOR, REST,
37 TOTAL, AGILITY, YOGA, CHALLENGE, CVX, WARRIOR, REST,
38 TOTAL, AGILITY, YOGA, CHALLENGE, CVX, WARRIOR, REST,
39 ISOMETRICS, DYNAMIX, ACCELERATOR, PILATES, CVX, YOGA, REST,
40 UPPER, TRIO, YOGA, LOWER, INCINERATOR, MMX, REST,
41 UPPER, TRIO, YOGA, LOWER, INCINERATOR, MMX, REST,
42 UPPER, TRIO, YOGA, LOWER, INCINERATOR, MMX, REST,
43 ISOMETRICS, DYNAMIX, ACCELERATOR, PILATES, CVX, YOGA, REST,
44 DECELERATOR, AGILITY, CHALLENGE, YOGA, TRIO, TOTAL, REST,
45 DECELERATOR, MMX, UPPER, TRIO, PILATES, LOWER, REST,
46 DECELERATOR, AGILITY, CHALLENGE, YOGA, TRIO, TOTAL, REST,
47 DECELERATOR, MMX, UPPER, TRIO, PILATES, LOWER, REST,
48 ISOMETRICS, ACCELERATOR, PILATES, YOGA, DYNAMIX, REST,
49 ],
50 "lean": [
51 ACCELERATOR, WARRIOR, YOGA, CVX, ISOMETRICS, AGILITY, REST,
52 ACCELERATOR, WARRIOR, YOGA, CVX, ISOMETRICS, AGILITY, REST,
53 ACCELERATOR, WARRIOR, YOGA, CVX, ISOMETRICS, AGILITY, REST,
54 ISOMETRICS, DYNAMIX, ACCELERATOR, PILATES, AGILITY, YOGA, REST,
55 TRIO, WARRIOR, YOGA, MMX, INCINERATOR, CVX, REST,
56 TRIO, WARRIOR, YOGA, MMX, INCINERATOR, CVX, REST,
57 TRIO, WARRIOR, YOGA, MMX, INCINERATOR, CVX, REST,
58 ISOMETRICS, DYNAMIX, ACCELERATOR, PILATES, DECELERATOR, YOGA, REST,
59 DECELERATOR, MMX, LOWER, YOGA, TRIO, UPPER, REST,
60 MMX, DECELERATOR, TRIO, PILATES, DECELERATOR, CVX, REST,
61 DECELERATOR, MMX, LOWER, YOGA, TRIO, UPPER, REST,
62 MMX, DECELERATOR, TRIO, PILATES, DECELERATOR, CVX, REST,
63 ISOMETRICS, ACCELERATOR, PILATES, YOGA, DYNAMIX, REST,
64 ],
65 "mass": [
66 TOTAL, AGILITY, YOGA, CHALLENGE, PILATES, INCINERATOR, REST,
67 TOTAL, AGILITY, YOGA, CHALLENGE, PILATES, INCINERATOR, REST,
68 TOTAL, AGILITY, YOGA, CHALLENGE, PILATES, INCINERATOR, REST,
69 ISOMETRICS, DYNAMIX, WARRIOR, PILATES, AGILITY, YOGA, REST,
70 UPPER, LOWER, YOGA, UPPER, LOWER, MMX, REST,
71 UPPER, LOWER, YOGA, UPPER, LOWER, MMX, REST,
72 UPPER, LOWER, YOGA, UPPER, LOWER, MMX, REST,
73 ISOMETRICS, DYNAMIX, WARRIOR, PILATES, DECELERATOR, YOGA, REST,
74 UPPER, LOWER, YOGA, UPPER, LOWER, MMX, REST,
75 TOTAL, AGILITY, YOGA, CHALLENGE, PILATES, INCINERATOR, REST,
76 UPPER, LOWER, YOGA, UPPER, LOWER, MMX, REST,
77 TOTAL, AGILITY, YOGA, CHALLENGE, PILATES, INCINERATOR, REST,
78 ISOMETRICS, YOGA, DECELERATOR, UPPER, LOWER, REST,
79 ]
80}
81
82prefix = '' if args.prefix == '' else args.prefix + ' '
83suffix = '' if args.suffix == '' else ' ' + args.suffix
84
85print("BEGIN:VCALENDAR")
86print("VERSION:2.0")
87print("PRODID:-//jonb.io//p90x3iCalgen 1.0//EN")
88schedule = SCHEDULES[args.variant]
89date = args.start
90
91for workout in schedule:
92 print("BEGIN:VEVENT")
93 print(f'SUMMARY:{prefix}{workout}{suffix}')
94
95 formattedDate = date.strftime("%Y%m%d")
96 print(f'DTSTART:{formattedDate}')
97 print(f'DTEND:{formattedDate}')
98 print("END:VEVENT")
99
100 date = date + datetime.timedelta(days=1)
101
102print("END:VCALENDAR")