1
+ import csv
2
+ import json
3
+ from datetime import datetime , timedelta
4
+
5
+ import requests
6
+
7
+ # Replace <SECRET> with your actual secret token
8
+ headers = {
9
+ "accept" : "application/json" ,
10
+ "cookie" : "" , # get from the cult website, any curl call, get the value of header `Cookie`...
11
+ "clientversion" : "10.08" ,
12
+ "connection" : "Keep-Alive" ,
13
+ "content-type" : "application/json; charset=utf-8"
14
+ }
15
+
16
+ start_date_str = "2022-04-25"
17
+ end_date_str = "2023-08-04"
18
+ current_date = datetime .strptime (start_date_str , "%Y-%m-%d" )
19
+
20
+ csv_filename = f"fitness_report.csv"
21
+ with open (csv_filename , "w" , newline = "" ) as csvfile :
22
+ csv_writer = csv .writer (csvfile , delimiter = "\t " )
23
+ csv_writer .writerow (["StartDate" , "EndDate" , "ClassesAttended" , "CaloriesBurnt" , "ExercisesDone" , "FocusedOn" , "NotFocusedOn" , "Summary" ])
24
+ while current_date <= datetime .strptime (end_date_str , "%Y-%m-%d" ):
25
+ current_date_str = current_date .strftime ("%Y-%m-%d" )
26
+ this_week_end_date = current_date + timedelta (days = 6 )
27
+ this_week_end_date_str = this_week_end_date .strftime ("%Y-%m-%d" )
28
+
29
+ url = f"https://www.cult.fit/api/cult/fitnessReport?reportType=WEEKLY&startDate={ current_date_str } "
30
+ response = requests .get (url , headers = headers )
31
+ data = response .json ()
32
+
33
+ try :
34
+ widgets = data ["widgets" ]
35
+ classMissedWidgets = [w for w in widgets if w ["widgetType" ] == "CLASS_MISSED_WIDGET" ]
36
+ classMissedWidget = classMissedWidgets [0 ] if len (classMissedWidgets ) > 0 else None
37
+ if classMissedWidget :
38
+ csv_writer .writerow ([current_date_str , this_week_end_date_str , 0 , 0 , "" , "" , "" , classMissedWidget ["title" ]["value" ]])
39
+ print (f"Processed week { current_date_str } to { this_week_end_date_str } " )
40
+ current_date += timedelta (days = 7 )
41
+ continue
42
+ fitnessReportSummary = [w for w in widgets if w ["widgetType" ] == "FITNESS_REPORT_SUMMARY_CARD_WIDGET" ][0 ]
43
+ metricWidget = [w for w in widgets if w ["widgetType" ] == "REPORT_METRIC_DETAIL_WIDGET" ][0 ]
44
+ tagViewWidgets = [w for w in widgets if w ["widgetType" ] == "TAG_VIEW_WIDGET" ]
45
+ exercisesDoneWidgets = [w for w in tagViewWidgets if "header" not in w ]
46
+ exercisesDoneWidget = exercisesDoneWidgets [0 ] if len (exercisesDoneWidgets ) > 0 else None
47
+ youFocusedOnWidgets = [w for w in tagViewWidgets if "header" in w and w ["header" ] == "YOU FOCUSSED ON" ]
48
+ youFocusedOnWidget = youFocusedOnWidgets [0 ] if len (youFocusedOnWidgets ) > 0 else None
49
+ start_date = fitnessReportSummary ["startDate" ]
50
+ end_date = fitnessReportSummary ["endDate" ]
51
+ classes_attended = metricWidget ["metricSection" ]["metricDisplayValue" ]
52
+ calories_burnt = fitnessReportSummary ["caloriesBurnt" ]
53
+
54
+ exercises_done = ""
55
+ if exercisesDoneWidget :
56
+ exercises_done = "\n " .join (tag ["title" ] + "(" + tag ["value" ] + ")" for tag in exercisesDoneWidget ["tags" ] if not tag ["disabled" ])
57
+ focused_on = ""
58
+ not_focused_on = ""
59
+ summary = ""
60
+ if youFocusedOnWidget :
61
+ focused_on = "\n " .join ([tag ["title" ] for tag in youFocusedOnWidget ["tags" ] if not tag ["disabled" ]])
62
+ not_focused_on = "\n " .join ([tag ["title" ] for tag in youFocusedOnWidget ["tags" ] if tag ["disabled" ]])
63
+ summary = youFocusedOnWidget ["footer" ]["dataText" ]
64
+ csv_writer .writerow ([start_date , end_date , classes_attended , calories_burnt , exercises_done , focused_on , not_focused_on , summary ])
65
+ print (f"Processed week { start_date } to { end_date } " )
66
+ # Move to the next week
67
+ current_date += timedelta (days = 7 )
68
+ except Exception as e :
69
+ print (f"Error processing week { current_date_str } to { this_week_end_date_str } " )
70
+ print (f"data json = { json .dumps (data , indent = 4 )} " )
71
+ raise e
72
+
73
+
74
+ print (f"CSV file '{ csv_filename } ' created successfully." )
0 commit comments