├── README.md
├── completion_rate_pie_chart.png
├── progress_pie_chart.png
└── thmprogress.py
/README.md:
--------------------------------------------------------------------------------
1 | # TryHackMe Room Progress Tracker 🚀
2 |
3 | This project fetches and visualizes the progress of completed rooms on TryHackMe for a given user. It uses the TryHackMe API to retrieve the data, processes it, and generates a pie chart showing the overall progress. Additionally, it saves the sorted progress data to a JSON file and the pie chart to an image file.
4 |
5 |
6 |
7 |
8 |
9 | ## Requirements 📋
10 |
11 | - Python 3.x
12 | - `requests` library
13 | - `matplotlib` library
14 |
15 | ## Installation 🛠️
16 |
17 | 1. **Clone the Repository**
18 |
19 | ```bash
20 | git clone https://github.com/pentestfunctions/tryhackme_progress.git
21 | cd tryhackme_progress
22 | ```
23 |
24 | 2. **Install Required Libraries**
25 |
26 | You can install the required libraries using `pip`:
27 |
28 | ```bash
29 | pip install requests matplotlib
30 | ```
31 |
32 | ## Usage 🚦
33 |
34 | 1. **Modify the Connect.sid (Cookie)**
35 |
36 | Update the `cookie on line 5` parameter in the thmprogress.py script (Get your connect.sid cookie from THM)
37 |
38 | ```python
39 | cookie = "RANDOM_SID"
40 | ```
41 |
42 | 2. **Run the Script**
43 |
44 | Execute the script to fetch data, process it, and generate the pie chart:
45 |
46 | ```bash
47 | python thmprogress.py
48 | ```
49 |
50 | 3. **Output Files**
51 |
52 | - `progress_data_sorted.json`: Contains the sorted progress data.
53 | - `progress_pie_chart.png`: Contains the pie chart image showing the progress.
54 |
--------------------------------------------------------------------------------
/completion_rate_pie_chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pentestfunctions/tryhackme_progress/f606eeddbc54cc5a097e1d04cb91ef073a7d9135/completion_rate_pie_chart.png
--------------------------------------------------------------------------------
/progress_pie_chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pentestfunctions/tryhackme_progress/f606eeddbc54cc5a097e1d04cb91ef073a7d9135/progress_pie_chart.png
--------------------------------------------------------------------------------
/thmprogress.py:
--------------------------------------------------------------------------------
1 | import requests
2 | import matplotlib.pyplot as plt
3 | import json
4 |
5 | # If you change all rooms, you might want to update line #82 which is the title of the output chart/image
6 | cookie = "RANDOM_SID"
7 |
8 | # Function to fetch free rooms from the API
9 | def fetch_free_rooms(exclude_windows):
10 | base_url = "https://tryhackme.com/api/v2/hacktivities/extended-search"
11 | params = {
12 | "kind": "all",
13 | "difficulty": "all",
14 | "order": "relevance",
15 | "roomType": "all",
16 | "contentSubType": "free", # Change to 'all' instead for all rooms.
17 | "limit": 100
18 | }
19 |
20 | free_rooms = []
21 |
22 | # Iterate through pages 1 to 20
23 | for page in range(1, 11):
24 | params["page"] = page
25 | response = requests.get(base_url, params=params)
26 | if response.status_code == 200:
27 | data = response.json()
28 | if 'data' in data and 'docs' in data['data']:
29 | for room in data['data']['docs']:
30 | if exclude_windows:
31 | if not any(tag['label'].lower() == 'windows' for tag in room['tagDocs']):
32 | free_rooms.append(room)
33 | else:
34 | free_rooms.append(room)
35 | else:
36 | print(f"Failed to fetch data for page {page}: {response.status_code}")
37 |
38 | return free_rooms
39 |
40 | # Function to fetch progress data for the given room codes
41 | def fetch_progress_data(room_codes, cookie):
42 | room_codes_str = "%2C".join(room_codes)
43 | url = f"https://tryhackme.com/api/v2/hacktivities/search-progress?roomCodes={room_codes_str}"
44 | headers = {
45 | "accept": "*/*",
46 | "accept-language": "en-US,en;q=0.5",
47 | "priority": "u=1, i",
48 | }
49 | cookies = {
50 | "connect.sid": cookie,
51 | }
52 |
53 | response = requests.get(url, headers=headers, cookies=cookies)
54 | if response.status_code == 200:
55 | return response.json()
56 | else:
57 | print(f"Failed to fetch progress data: {response.status_code}")
58 | return {}
59 |
60 | # Main script execution
61 | exclude_windows = False # Change this to False to include rooms with Windows rating
62 | free_rooms = fetch_free_rooms(exclude_windows)
63 |
64 | room_codes = [room['code'] for room in free_rooms]
65 |
66 | progress_data = fetch_progress_data(room_codes, cookie)
67 |
68 | if 'data' in progress_data and 'roomProgress' in progress_data['data']:
69 | progress_data = progress_data['data']['roomProgress']
70 | else:
71 | progress_data = []
72 |
73 | total_rooms = len(progress_data)
74 | completed_rooms = sum(1 for room in progress_data if room['progressPercentage'] == 100)
75 | in_progress_rooms = sum(1 for room in progress_data if 0 < room['progressPercentage'] < 100)
76 | not_started_rooms = total_rooms - completed_rooms - in_progress_rooms
77 |
78 | labels = [
79 | f'Completed ({completed_rooms})',
80 | f'In Progress ({in_progress_rooms})',
81 | f'Not Started ({not_started_rooms})'
82 | ]
83 | sizes = [completed_rooms, in_progress_rooms, not_started_rooms]
84 |
85 | # Chart title
86 | chart_title = 'Completion Rate of TryHackMe Free Rooms (Excluding Windows)' if exclude_windows else 'Completion Rate of TryHackMe Free Rooms'
87 |
88 | # Check if all sizes are zero
89 | if total_rooms == 0:
90 | print("No data to display in pie chart.")
91 | else:
92 | colors = ['#4caf50', '#ffeb3b', '#f44336']
93 | explode = (0.1, 0, 0) # explode the 1st slice (Completed)
94 |
95 | def autopct_format(pct, allvalues):
96 | absolute = int(pct / 100. * sum(allvalues))
97 | return "{:.1f}%\n({:d})".format(pct, absolute)
98 |
99 | # Plot the pie chart
100 | plt.figure(figsize=(10, 7))
101 | plt.pie(sizes, explode=explode, labels=labels, colors=colors, autopct=lambda pct: autopct_format(pct, sizes),
102 | shadow=True, startangle=140)
103 | plt.title(chart_title)
104 | plt.axis('equal')
105 |
106 | # Save the plot as an image file
107 | plt.savefig('completion_rate_pie_chart.png')
108 |
109 | # Show the plot
110 | plt.show()
111 |
112 | # Save the sorted progress data to a JSON file
113 | with open('progress_data_sorted.json', 'w') as f:
114 | json.dump(progress_data, f, indent=4)
115 |
--------------------------------------------------------------------------------