| 1 | import argparse, datetime |
| 2 | |
| 3 | def date(s): |
| 4 | try: |
| 5 | return datetime.datetime.strptime(s, "%Y-%m-%d") |
| 6 | except ValueError: |
| 7 | raise argparse.ArgumentTypeError("Not a valid date: '{0}'. Date must be in format 'YYYY-MM-DD'".format(s)) |
| 8 | |
| 9 | parser = argparse.ArgumentParser(description='Generate a P90X3 schedule in iCalendar format.') |
| 10 | parser.add_argument('--start', type=date, default=datetime.date.today(), help='start date (YYYY-MM-DD) (default: today)') |
| 11 | parser.add_argument('--variant', choices=["classic", "lean", "mass"], default="classic", help="calendar variant (default: classic)") |
| 12 | parser.add_argument('--prefix', type=str, default='', help="prefix to add to all event names") |
| 13 | parser.add_argument('--suffix', type=str, default='', help="suffix to add to all event names") |
| 14 | args = parser.parse_args() |
| 15 | |
| 16 | TOTAL = "Total Synergistics" |
| 17 | CVX = "CVX" |
| 18 | AGILITY = "Agility X" |
| 19 | TRIO = "Triometrics" |
| 20 | CHALLENGE = "The Challenge" |
| 21 | INCINERATOR = "Incinerator" |
| 22 | WARRIOR = "The Warrior" |
| 23 | MMX = "MMX" |
| 24 | YOGA = "X3 Yoga" |
| 25 | PILATES = "Pilates X" |
| 26 | ISOMETRICS = "Isometrics" |
| 27 | DYNAMIX = "Dynamix" |
| 28 | ACCELERATOR = "Accelerator" |
| 29 | DECELERATOR = "Decelerator" |
| 30 | UPPER = "Eccentric Upper" |
| 31 | LOWER = "Eccentric Lower" |
| 32 | REST = "Rest or Dynamix" |
| 33 | |
| 34 | SCHEDULES = { |
| 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 | |
| 82 | prefix = '' if args.prefix == '' else args.prefix + ' ' |
| 83 | suffix = '' if args.suffix == '' else ' ' + args.suffix |
| 84 | |
| 85 | print("BEGIN:VCALENDAR") |
| 86 | print("VERSION:2.0") |
| 87 | print("PRODID:-//jonb.io//p90x3iCalgen 1.0//EN") |
| 88 | schedule = SCHEDULES[args.variant] |
| 89 | date = args.start |
| 90 | |
| 91 | for 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(f'DTSTAMP:') |
| 99 | print("END:VEVENT") |
| 100 | |
| 101 | date = date + datetime.timedelta(days=1) |
| 102 | |
| 103 | print("END:VCALENDAR") |
jblu / p90x3cal.py
Last active 6 months ago
Revision fc37e2c19c62a03665bda3339a30b2bfcb05792a