cs2tracker 2.1.5__py3-none-any.whl → 2.1.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cs2tracker might be problematic. Click here for more details.
- cs2tracker/_version.py +2 -2
- cs2tracker/application.py +102 -48
- cs2tracker/constants.py +339 -110
- cs2tracker/data/config.ini +186 -97
- cs2tracker/main.py +8 -4
- cs2tracker/scraper.py +119 -4
- {cs2tracker-2.1.5.dist-info → cs2tracker-2.1.7.dist-info}/METADATA +10 -9
- cs2tracker-2.1.7.dist-info/RECORD +16 -0
- cs2tracker-2.1.5.dist-info/RECORD +0 -16
- {cs2tracker-2.1.5.dist-info → cs2tracker-2.1.7.dist-info}/WHEEL +0 -0
- {cs2tracker-2.1.5.dist-info → cs2tracker-2.1.7.dist-info}/entry_points.txt +0 -0
- {cs2tracker-2.1.5.dist-info → cs2tracker-2.1.7.dist-info}/licenses/LICENSE.md +0 -0
- {cs2tracker-2.1.5.dist-info → cs2tracker-2.1.7.dist-info}/top_level.txt +0 -0
cs2tracker/data/config.ini
CHANGED
|
@@ -1,113 +1,202 @@
|
|
|
1
|
-
[Settings]
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
[User Settings]
|
|
2
|
+
api_key = None
|
|
3
|
+
discord_webhook_url = None
|
|
4
|
+
|
|
5
|
+
[App Settings]
|
|
6
|
+
use_proxy = False
|
|
7
|
+
discord_notifications = False
|
|
8
|
+
|
|
9
|
+
[Cases]
|
|
10
|
+
revolution_case = 0
|
|
11
|
+
recoil_case = 0
|
|
12
|
+
dreams_and_nightmares_case = 0
|
|
13
|
+
operation_riptide_case = 0
|
|
14
|
+
snakebite_case = 0
|
|
15
|
+
operation_broken_fang_case = 0
|
|
16
|
+
fracture_case = 0
|
|
17
|
+
chroma_case = 0
|
|
18
|
+
chroma_2_case = 0
|
|
19
|
+
chroma_3_case = 0
|
|
20
|
+
clutch_case = 0
|
|
21
|
+
csgo_weapon_case = 0
|
|
22
|
+
csgo_weapon_case_2 = 0
|
|
23
|
+
csgo_weapon_case_3 = 0
|
|
24
|
+
cs20_case = 0
|
|
25
|
+
danger_zone_case = 0
|
|
26
|
+
esports_2013_case = 0
|
|
27
|
+
esports_2013_winter_case = 0
|
|
28
|
+
esports_2014_summer_case = 0
|
|
29
|
+
falchion_case = 0
|
|
30
|
+
gamma_case = 0
|
|
31
|
+
gamma_2_case = 0
|
|
32
|
+
glove_case = 0
|
|
33
|
+
horizon_case = 0
|
|
34
|
+
huntsman_case = 0
|
|
35
|
+
operation_bravo_case = 0
|
|
36
|
+
operation_breakout_case = 0
|
|
37
|
+
operation_hydra_case = 0
|
|
38
|
+
operation_phoenix_case = 0
|
|
39
|
+
operation_vanguard_case = 0
|
|
40
|
+
operation_wildfire_case = 0
|
|
41
|
+
prisma_case = 0
|
|
42
|
+
prisma_2_case = 0
|
|
43
|
+
revolver_case = 0
|
|
44
|
+
shadow_case = 0
|
|
45
|
+
shattered_web_case = 0
|
|
46
|
+
spectrum_case = 0
|
|
47
|
+
spectrum_2_case = 0
|
|
48
|
+
winter_offensive_case = 0
|
|
49
|
+
kilowatt_case = 0
|
|
50
|
+
gallery_case = 0
|
|
51
|
+
fever_case = 0
|
|
52
|
+
|
|
53
|
+
[Katowice 2014 Sticker Capsule]
|
|
54
|
+
katowice_legends = 0
|
|
55
|
+
katowice_challengers = 0
|
|
56
|
+
|
|
57
|
+
[Cologne 2014 Sticker Capsule]
|
|
58
|
+
cologne_legends = 0
|
|
59
|
+
cologne_challengers = 0
|
|
60
|
+
|
|
61
|
+
[DreamHack 2014 Sticker Capsule]
|
|
62
|
+
dreamhack_legends = 0
|
|
63
|
+
|
|
64
|
+
[Katowice 2015 Sticker Capsule]
|
|
65
|
+
katowice_legends = 0
|
|
66
|
+
katowice_challengers = 0
|
|
67
|
+
|
|
68
|
+
[Cologne 2015 Sticker Capsule]
|
|
69
|
+
cologne_legends = 0
|
|
70
|
+
cologne_challengers = 0
|
|
71
|
+
|
|
72
|
+
[Cluj-Napoca 2015 Sticker Capsule]
|
|
73
|
+
cluj_napoca_legends = 0
|
|
74
|
+
cluj_napoca_challengers = 0
|
|
75
|
+
cluj_napoca_legends_autographs = 0
|
|
76
|
+
cluj_napoca_challengers_autographs = 0
|
|
77
|
+
|
|
78
|
+
[Columbus 2016 Sticker Capsule]
|
|
79
|
+
columbus_legends = 0
|
|
80
|
+
columbus_challengers = 0
|
|
81
|
+
columbus_legends_autographs = 0
|
|
82
|
+
columbus_challengers_autographs = 0
|
|
83
|
+
|
|
84
|
+
[Cologne 2016 Sticker Capsule]
|
|
85
|
+
cologne_legends = 0
|
|
86
|
+
cologne_challengers = 0
|
|
87
|
+
cologne_legends_autographs = 0
|
|
88
|
+
cologne_challengers_autographs = 0
|
|
89
|
+
|
|
90
|
+
[Atlanta 2017 Sticker Capsule]
|
|
91
|
+
atlanta_legends = 0
|
|
92
|
+
atlanta_challengers = 0
|
|
93
|
+
atlanta_legends_autographs = 0
|
|
94
|
+
atlanta_challengers_autographs = 0
|
|
95
|
+
|
|
96
|
+
[Krakow 2017 Sticker Capsule]
|
|
97
|
+
krakow_legends = 0
|
|
98
|
+
krakow_challengers = 0
|
|
99
|
+
krakow_legends_autographs = 0
|
|
100
|
+
krakow_challengers_autographs = 0
|
|
101
|
+
|
|
102
|
+
[Boston 2018 Sticker Capsule]
|
|
103
|
+
boston_legends = 0
|
|
104
|
+
boston_minor_challengers = 0
|
|
105
|
+
boston_returning_challengers = 0
|
|
106
|
+
boston_attending_legends = 0
|
|
107
|
+
boston_minor_challengers_with_flash_gaming = 0
|
|
108
|
+
boston_legends_autographs = 0
|
|
109
|
+
boston_minor_challengers_autographs = 0
|
|
110
|
+
boston_returning_challengers_autographs = 0
|
|
111
|
+
boston_attending_legends_autographs = 0
|
|
112
|
+
boston_minor_challengers_with_flash_gaming_autographs = 0
|
|
113
|
+
|
|
114
|
+
[London 2018 Sticker Capsule]
|
|
115
|
+
london_legends = 0
|
|
116
|
+
london_minor_challengers = 0
|
|
117
|
+
london_returning_challengers = 0
|
|
118
|
+
london_legends_autographs = 0
|
|
119
|
+
london_minor_challengers_autographs = 0
|
|
120
|
+
london_returning_challengers_autographs = 0
|
|
121
|
+
|
|
122
|
+
[Katowice 2019 Sticker Capsule]
|
|
123
|
+
katowice_legends = 0
|
|
124
|
+
katowice_minor_challengers = 0
|
|
125
|
+
katowice_returning_challengers = 0
|
|
126
|
+
katowice_legends_autographs = 0
|
|
127
|
+
katowice_minor_challengers_autographs = 0
|
|
128
|
+
katowice_returning_challengers_autographs = 0
|
|
129
|
+
|
|
130
|
+
[Berlin 2019 Sticker Capsule]
|
|
131
|
+
berlin_legends = 0
|
|
132
|
+
berlin_minor_challengers = 0
|
|
133
|
+
berlin_returning_challengers = 0
|
|
134
|
+
berlin_legends_autographs = 0
|
|
135
|
+
berlin_minor_challengers_autographs = 0
|
|
136
|
+
berlin_returning_challengers_autographs = 0
|
|
4
137
|
|
|
5
138
|
[2020 RMR Sticker Capsule]
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
139
|
+
rmr_legends = 0
|
|
140
|
+
rmr_challengers = 0
|
|
141
|
+
rmr_contenders = 0
|
|
9
142
|
|
|
10
143
|
[Stockholm 2021 Sticker Capsule]
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
144
|
+
stockholm_legends = 0
|
|
145
|
+
stockholm_challengers = 0
|
|
146
|
+
stockholm_contenders = 0
|
|
147
|
+
stockholm_champions_autographs = 0
|
|
148
|
+
stockholm_finalists_autographs = 0
|
|
16
149
|
|
|
17
150
|
[Antwerp 2022 Sticker Capsule]
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
151
|
+
antwerp_legends = 0
|
|
152
|
+
antwerp_challengers = 0
|
|
153
|
+
antwerp_contenders = 0
|
|
154
|
+
antwerp_champions_autographs = 0
|
|
155
|
+
antwerp_challengers_autographs = 0
|
|
156
|
+
antwerp_legends_autographs = 0
|
|
157
|
+
antwerp_contenders_autographs = 0
|
|
25
158
|
|
|
26
159
|
[Rio 2022 Sticker Capsule]
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
160
|
+
rio_legends = 0
|
|
161
|
+
rio_challengers = 0
|
|
162
|
+
rio_contenders = 0
|
|
163
|
+
rio_champions_autographs = 0
|
|
164
|
+
rio_challengers_autographs = 0
|
|
165
|
+
rio_legends_autographs = 0
|
|
166
|
+
rio_contenders_autographs = 0
|
|
34
167
|
|
|
35
168
|
[Paris 2023 Sticker Capsule]
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
169
|
+
paris_legends = 0
|
|
170
|
+
paris_challengers = 0
|
|
171
|
+
paris_contenders = 0
|
|
172
|
+
paris_champions_autographs = 0
|
|
173
|
+
paris_challengers_autographs = 0
|
|
174
|
+
paris_legends_autographs = 0
|
|
175
|
+
paris_contenders_autographs = 0
|
|
43
176
|
|
|
44
177
|
[Copenhagen 2024 Sticker Capsule]
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
178
|
+
copenhagen_legends = 0
|
|
179
|
+
copenhagen_challengers = 0
|
|
180
|
+
copenhagen_contenders = 0
|
|
181
|
+
copenhagen_champions_autographs = 0
|
|
182
|
+
copenhagen_challengers_autographs = 0
|
|
183
|
+
copenhagen_legends_autographs = 0
|
|
184
|
+
copenhagen_contenders_autographs = 0
|
|
52
185
|
|
|
53
186
|
[Shanghai 2024 Sticker Capsule]
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
187
|
+
shanghai_legends = 0
|
|
188
|
+
shanghai_challengers = 0
|
|
189
|
+
shanghai_contenders = 0
|
|
190
|
+
shanghai_champions_autographs = 0
|
|
191
|
+
shanghai_challengers_autographs = 0
|
|
192
|
+
shanghai_legends_autographs = 0
|
|
193
|
+
shanghai_contenders_autographs = 0
|
|
61
194
|
|
|
62
195
|
[Austin 2025 Sticker Capsule]
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
[Cases]
|
|
72
|
-
Revolution_Case = 0
|
|
73
|
-
Recoil_Case = 0
|
|
74
|
-
Dreams_And_Nightmares_Case = 0
|
|
75
|
-
Operation_Riptide_Case = 0
|
|
76
|
-
Snakebite_Case = 0
|
|
77
|
-
Operation_Broken_Fang_Case = 0
|
|
78
|
-
Fracture_Case = 0
|
|
79
|
-
Chroma_Case = 0
|
|
80
|
-
Chroma_2_Case = 0
|
|
81
|
-
Chroma_3_Case = 0
|
|
82
|
-
Clutch_Case = 0
|
|
83
|
-
CSGO_Weapon_Case = 0
|
|
84
|
-
CSGO_Weapon_Case_2 = 0
|
|
85
|
-
CSGO_Weapon_Case_3 = 0
|
|
86
|
-
CS20_Case = 0
|
|
87
|
-
Danger_Zone_Case = 0
|
|
88
|
-
eSports_2013_Case = 0
|
|
89
|
-
eSports_2013_Winter_Case = 0
|
|
90
|
-
eSports_2014_Summer_Case = 0
|
|
91
|
-
Falchion_Case = 0
|
|
92
|
-
Gamma_Case = 0
|
|
93
|
-
Gamma_2_Case = 0
|
|
94
|
-
Glove_Case = 0
|
|
95
|
-
Horizon_Case = 0
|
|
96
|
-
Huntsman_Case = 0
|
|
97
|
-
Operation_Bravo_Case = 0
|
|
98
|
-
Operation_Breakout_Case = 0
|
|
99
|
-
Operation_Hydra_Case = 0
|
|
100
|
-
Operation_Phoenix_Case = 0
|
|
101
|
-
Operation_Vanguard_Case = 0
|
|
102
|
-
Operation_Wildfire_Case = 0
|
|
103
|
-
Prisma_Case = 0
|
|
104
|
-
Prisma_2_Case = 0
|
|
105
|
-
Revolver_Case = 0
|
|
106
|
-
Shadow_Case = 0
|
|
107
|
-
Shattered_Web_Case = 0
|
|
108
|
-
Spectrum_Case = 0
|
|
109
|
-
Spectrum_2_Case = 0
|
|
110
|
-
Winter_Offensive_Case = 0
|
|
111
|
-
Kilowatt_Case = 0
|
|
112
|
-
Gallery_Case = 0
|
|
113
|
-
Fever_Case = 0
|
|
196
|
+
austin_legends = 0
|
|
197
|
+
austin_challengers = 0
|
|
198
|
+
austin_contenders = 0
|
|
199
|
+
austin_champions_autographs = 0
|
|
200
|
+
austin_challengers_autographs = 0
|
|
201
|
+
austin_legends_autographs = 0
|
|
202
|
+
austin_contenders_autographs = 0
|
cs2tracker/main.py
CHANGED
|
@@ -3,7 +3,7 @@ import sys
|
|
|
3
3
|
import urllib3
|
|
4
4
|
|
|
5
5
|
from cs2tracker.application import Application
|
|
6
|
-
from cs2tracker.constants import AUTHOR_STRING, BANNER
|
|
6
|
+
from cs2tracker.constants import AUTHOR_STRING, BANNER, OS, OSType
|
|
7
7
|
from cs2tracker.padded_console import PaddedConsole
|
|
8
8
|
from cs2tracker.scraper import Scraper
|
|
9
9
|
|
|
@@ -19,13 +19,17 @@ def main():
|
|
|
19
19
|
# Disable warnings for proxy requests
|
|
20
20
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
21
21
|
|
|
22
|
+
# Set output encoding to UTF-8 with BOM for Windows compatibility
|
|
23
|
+
if OS == OSType.WINDOWS:
|
|
24
|
+
sys.stdout.reconfigure(encoding="utf-8-sig") # type: ignore
|
|
25
|
+
|
|
26
|
+
console = PaddedConsole()
|
|
27
|
+
console.print(f"[bold yellow]{BANNER}\n{AUTHOR_STRING}\n")
|
|
28
|
+
|
|
22
29
|
if "--only-scrape" in sys.argv:
|
|
23
30
|
scraper = Scraper()
|
|
24
|
-
scraper.console.print(f"[bold yellow]{BANNER}\n{AUTHOR_STRING}\n")
|
|
25
31
|
scraper.scrape_prices()
|
|
26
32
|
else:
|
|
27
|
-
console = PaddedConsole()
|
|
28
|
-
console.print(f"[bold yellow]{BANNER}\n{AUTHOR_STRING}\n")
|
|
29
33
|
application = Application()
|
|
30
34
|
application.run()
|
|
31
35
|
|
cs2tracker/scraper.py
CHANGED
|
@@ -31,11 +31,15 @@ from cs2tracker.padded_console import PaddedConsole
|
|
|
31
31
|
|
|
32
32
|
MAX_LINE_LEN = 72
|
|
33
33
|
SEPARATOR = "-"
|
|
34
|
-
PRICE_INFO = "Owned: {}
|
|
34
|
+
PRICE_INFO = "Owned: {:<10} Steam market price: ${:<10} Total: ${:<10}\n"
|
|
35
35
|
|
|
36
36
|
HTTP_PROXY_URL = "http://{}:@smartproxy.crawlbase.com:8012"
|
|
37
37
|
HTTPS_PROXY_URL = "http://{}:@smartproxy.crawlbase.com:8012"
|
|
38
38
|
|
|
39
|
+
DC_WEBHOOK_USERNAME = "CS2Tracker"
|
|
40
|
+
DC_WEBHOOK_AVATAR_URL = "https://img.icons8.com/?size=100&id=uWQJp2tLXUH6&format=png&color=000000"
|
|
41
|
+
DC_RECENT_HISTORY_LIMIT = 5
|
|
42
|
+
|
|
39
43
|
WIN_BACKGROUND_TASK_NAME = "CS2Tracker Daily Calculation"
|
|
40
44
|
WIN_BACKGROUND_TASK_SCHEDULE = "DAILY"
|
|
41
45
|
WIN_BACKGROUND_TASK_TIME = "12:00"
|
|
@@ -97,6 +101,7 @@ class Scraper:
|
|
|
97
101
|
|
|
98
102
|
self._print_total()
|
|
99
103
|
self._save_price_log()
|
|
104
|
+
self._send_discord_notification()
|
|
100
105
|
|
|
101
106
|
# Reset totals for next run
|
|
102
107
|
self.usd_total, self.eur_total = 0, 0
|
|
@@ -122,6 +127,9 @@ class Scraper:
|
|
|
122
127
|
|
|
123
128
|
This will append a new entry to the output file if no entry has been made for
|
|
124
129
|
today.
|
|
130
|
+
|
|
131
|
+
:raises FileNotFoundError: If the output file does not exist.
|
|
132
|
+
:raises IOError: If there is an error writing to the output file.
|
|
125
133
|
"""
|
|
126
134
|
with open(OUTPUT_FILE, "r", encoding="utf-8") as price_logs:
|
|
127
135
|
price_logs_reader = csv.reader(price_logs)
|
|
@@ -157,6 +165,8 @@ class Scraper:
|
|
|
157
165
|
data is used for drawing the plot of past prices.
|
|
158
166
|
|
|
159
167
|
:return: A tuple containing three lists: dates, dollar prices, and euro prices.
|
|
168
|
+
:raises FileNotFoundError: If the output file does not exist.
|
|
169
|
+
:raises IOError: If there is an error reading the output file.
|
|
160
170
|
"""
|
|
161
171
|
dates, dollars, euros = [], [], []
|
|
162
172
|
with open(OUTPUT_FILE, "r", encoding="utf-8") as price_logs:
|
|
@@ -173,6 +183,82 @@ class Scraper:
|
|
|
173
183
|
|
|
174
184
|
return dates, dollars, euros
|
|
175
185
|
|
|
186
|
+
def _construct_recent_calculations_embeds(self):
|
|
187
|
+
"""
|
|
188
|
+
Construct the embeds for the Discord message that will be sent after a price
|
|
189
|
+
calculation has been made.
|
|
190
|
+
|
|
191
|
+
:return: A list of embeds for the Discord message.
|
|
192
|
+
"""
|
|
193
|
+
dates, usd_logs, eur_logs = self.read_price_log()
|
|
194
|
+
dates, usd_logs, eur_logs = reversed(dates), reversed(usd_logs), reversed(eur_logs)
|
|
195
|
+
|
|
196
|
+
date_history, usd_history, eur_history = [], [], []
|
|
197
|
+
for date, usd_log, eur_log in zip(dates, usd_logs, eur_logs):
|
|
198
|
+
if len(date_history) >= DC_RECENT_HISTORY_LIMIT:
|
|
199
|
+
break
|
|
200
|
+
date_history.append(date.strftime("%Y-%m-%d"))
|
|
201
|
+
usd_history.append(f"${usd_log:.2f}")
|
|
202
|
+
eur_history.append(f"€{eur_log:.2f}")
|
|
203
|
+
|
|
204
|
+
date_history = "\n".join(date_history)
|
|
205
|
+
usd_history = "\n".join(usd_history)
|
|
206
|
+
eur_history = "\n".join(eur_history)
|
|
207
|
+
|
|
208
|
+
embeds = [
|
|
209
|
+
{
|
|
210
|
+
"title": "📊 Recent Price History",
|
|
211
|
+
"color": 5814783,
|
|
212
|
+
"fields": [
|
|
213
|
+
{
|
|
214
|
+
"name": "Date",
|
|
215
|
+
"value": date_history,
|
|
216
|
+
"inline": True,
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"name": "USD Total",
|
|
220
|
+
"value": usd_history,
|
|
221
|
+
"inline": True,
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"name": "EUR Total",
|
|
225
|
+
"value": eur_history,
|
|
226
|
+
"inline": True,
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
}
|
|
230
|
+
]
|
|
231
|
+
|
|
232
|
+
return embeds
|
|
233
|
+
|
|
234
|
+
def _send_discord_notification(self):
|
|
235
|
+
"""Send a message to a Discord webhook if notifications are enabled in the
|
|
236
|
+
config file and a webhook URL is provided.
|
|
237
|
+
"""
|
|
238
|
+
discord_notifications = self.config.getboolean(
|
|
239
|
+
"App Settings", "discord_notifications", fallback=False
|
|
240
|
+
)
|
|
241
|
+
webhook_url = self.config.get("User Settings", "discord_webhook_url", fallback=None)
|
|
242
|
+
webhook_url = None if webhook_url in ("None", "") else webhook_url
|
|
243
|
+
|
|
244
|
+
if discord_notifications and webhook_url:
|
|
245
|
+
embeds = self._construct_recent_calculations_embeds()
|
|
246
|
+
try:
|
|
247
|
+
response = self.session.post(
|
|
248
|
+
url=webhook_url,
|
|
249
|
+
json={
|
|
250
|
+
"embeds": embeds,
|
|
251
|
+
"username": DC_WEBHOOK_USERNAME,
|
|
252
|
+
"avatar_url": DC_WEBHOOK_AVATAR_URL,
|
|
253
|
+
},
|
|
254
|
+
)
|
|
255
|
+
response.raise_for_status()
|
|
256
|
+
self.console.print("[bold steel_blue3][+] Discord notification sent.\n")
|
|
257
|
+
except RequestException as error:
|
|
258
|
+
self.console.print(f"[bold red][!] Failed to send Discord notification: {error}\n")
|
|
259
|
+
except Exception as error:
|
|
260
|
+
self.console.print(f"[bold red][!] An unexpected error occurred: {error}\n")
|
|
261
|
+
|
|
176
262
|
@retry(stop=stop_after_attempt(10))
|
|
177
263
|
def _get_page(self, url):
|
|
178
264
|
"""
|
|
@@ -184,8 +270,8 @@ class Scraper:
|
|
|
184
270
|
:raises RequestException: If the request fails.
|
|
185
271
|
:raises RetryError: If the retry limit is reached.
|
|
186
272
|
"""
|
|
187
|
-
use_proxy = self.config.getboolean("Settings", "
|
|
188
|
-
api_key = self.config.get("Settings", "
|
|
273
|
+
use_proxy = self.config.getboolean("App Settings", "use_proxy", fallback=False)
|
|
274
|
+
api_key = self.config.get("User Settings", "api_key", fallback=None)
|
|
189
275
|
api_key = None if api_key in ("None", "") else api_key
|
|
190
276
|
if use_proxy and api_key:
|
|
191
277
|
page = self.session.get(
|
|
@@ -319,7 +405,7 @@ class Scraper:
|
|
|
319
405
|
self.console.print(PRICE_INFO.format(owned, price_usd, price_usd_owned))
|
|
320
406
|
case_usd_total += price_usd_owned
|
|
321
407
|
|
|
322
|
-
if not self.config.getboolean("Settings", "
|
|
408
|
+
if not self.config.getboolean("App Settings", "use_proxy", fallback=False):
|
|
323
409
|
time.sleep(1)
|
|
324
410
|
|
|
325
411
|
return case_usd_total
|
|
@@ -406,6 +492,35 @@ class Scraper:
|
|
|
406
492
|
# TODO: implement toggle for cron jobs
|
|
407
493
|
pass
|
|
408
494
|
|
|
495
|
+
def toggle_use_proxy(self, enabled: bool):
|
|
496
|
+
"""
|
|
497
|
+
Toggle the use of proxies for requests. This will update the configuration file.
|
|
498
|
+
|
|
499
|
+
:param enabled: If True, proxies will be used; if False, they will not be used.
|
|
500
|
+
"""
|
|
501
|
+
self.config.set("App Settings", "use_proxy", str(enabled))
|
|
502
|
+
with open(CONFIG_FILE, "w", encoding="utf-8") as config_file:
|
|
503
|
+
self.config.write(config_file)
|
|
504
|
+
|
|
505
|
+
self.console.print(
|
|
506
|
+
f"[bold green]{'[+] Enabled' if enabled else '[-] Disabled'} proxy usage for requests."
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
def toggle_discord_webhook(self, enabled: bool):
|
|
510
|
+
"""
|
|
511
|
+
Toggle the use of a Discord webhook to notify users of price calculations.
|
|
512
|
+
|
|
513
|
+
:param enabled: If True, the webhook will be used; if False, it will not be
|
|
514
|
+
used.
|
|
515
|
+
"""
|
|
516
|
+
self.config.set("App Settings", "discord_notifications", str(enabled))
|
|
517
|
+
with open(CONFIG_FILE, "w", encoding="utf-8") as config_file:
|
|
518
|
+
self.config.write(config_file)
|
|
519
|
+
|
|
520
|
+
self.console.print(
|
|
521
|
+
f"[bold green]{'[+] Enabled' if enabled else '[-] Disabled'} Discord webhook notifications."
|
|
522
|
+
)
|
|
523
|
+
|
|
409
524
|
|
|
410
525
|
if __name__ == "__main__":
|
|
411
526
|
scraper = Scraper()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cs2tracker
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.7
|
|
4
4
|
Summary: Tracking the steam market prices of CS2 items
|
|
5
5
|
Home-page: https://github.com/ashiven/cs2tracker
|
|
6
6
|
Author: Jannik Novak
|
|
@@ -40,24 +40,24 @@ Dynamic: license-file
|
|
|
40
40
|
|
|
41
41
|
### Prerequisites
|
|
42
42
|
|
|
43
|
-
- Download and install the latest versions of [Python](https://www.python.org/downloads/) and [Pip](https://pypi.org/project/pip/). (Required
|
|
43
|
+
- Download and install the latest versions of [Python](https://www.python.org/downloads/) and [Pip](https://pypi.org/project/pip/). (Required on Linux)
|
|
44
44
|
- Register for the [Crawlbase Smart Proxy API](https://crawlbase.com/) and retrieve your API key. (Optional)
|
|
45
45
|
|
|
46
46
|
### Setup
|
|
47
47
|
|
|
48
|
-
#### Windows Executable (
|
|
48
|
+
#### Windows Executable _(no color support)_
|
|
49
49
|
|
|
50
|
-
- Simply download the
|
|
50
|
+
- Simply [download the latest executable](https://github.com/ashiven/cs2tracker/releases/latest/download/cs2tracker-windows.zip) and run it.
|
|
51
51
|
|
|
52
52
|
#### Install via Pip
|
|
53
53
|
|
|
54
|
-
1. Install the program
|
|
54
|
+
1. Install the program:
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
pip install
|
|
57
|
+
pip install cs2tracker
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
2.
|
|
60
|
+
2. Run it:
|
|
61
61
|
```bash
|
|
62
62
|
cs2tracker
|
|
63
63
|
```
|
|
@@ -67,8 +67,9 @@ Dynamic: license-file
|
|
|
67
67
|
- `Run!` to gather the current market prices of your items and calculate the total amount in USD and EUR.
|
|
68
68
|
- `Edit Config` to change the specific numbers of each item you own and then save the config file.
|
|
69
69
|
- `Show History` to see a price chart consisting of past calculations. A new data point is generated once a day upon running the program.
|
|
70
|
-
- `Daily Background
|
|
71
|
-
-
|
|
70
|
+
- `Daily Background Calculations` to automatically run a daily calculation of your investment in the background and save the results such that they can later be viewed via `Show History`.
|
|
71
|
+
- `Receive Discord Notifications` to receive a notification on your Discord server when the program has finished calculating your investment. You need to set up a [webhook](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) in your Discord server and enter the webhook url into the `discord_webhook_url` field in the config file.
|
|
72
|
+
- `Proxy Requests` to prevent your requests from being rate limited by the steamcommunity server. You need to register for a free API key on [Crawlbase](crawlbase.com) and enter it into the `api_key` field in the config file.
|
|
72
73
|
|
|
73
74
|
---
|
|
74
75
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
cs2tracker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
cs2tracker/__main__.py,sha256=Ub--oSMv48YzfWF1CZqYlkn1-HvZ7Bhxoc7urn1oY6o,249
|
|
3
|
+
cs2tracker/_version.py,sha256=THS-9QFidqyyR34eNGqu3fdLul8R-2jelw5ShM5U3hQ,511
|
|
4
|
+
cs2tracker/application.py,sha256=aIWNLi0ufq6R7Hi86mPWCqS_7Prr7tIzvvXcnx_6Sbs,8991
|
|
5
|
+
cs2tracker/constants.py,sha256=swkxVJQSwvavTorL3t_pBOHLtcgP3SaU9SU98XXuj48,29199
|
|
6
|
+
cs2tracker/main.py,sha256=6mlmpOhI7gCithWCLz-EVD1wabxRd-DWvnNku3s5DNs,1014
|
|
7
|
+
cs2tracker/padded_console.py,sha256=lPEa34p-8LTmTbpf-2S5uYPaA2UmsIOPq2_UoVhMRgU,674
|
|
8
|
+
cs2tracker/scraper.py,sha256=vARZSpYPKflPS7VBexFbtql3_b13QDwHxrzn8fUzu34,20887
|
|
9
|
+
cs2tracker/data/config.ini,sha256=ogy_g_UV4EUmwaMAoHTYO5NhkBkzU4dQo7um-d4kd_k,5027
|
|
10
|
+
cs2tracker/data/output.csv,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
cs2tracker-2.1.7.dist-info/licenses/LICENSE.md,sha256=G5wqQ_8KGA808kVuF-Fpu_Yhteg8K_5ux9n2v8eQK7s,1069
|
|
12
|
+
cs2tracker-2.1.7.dist-info/METADATA,sha256=21Ug5DWN90oXfZoCGXI3dmlu5wc2SoHJUHV8vTvIAaw,3452
|
|
13
|
+
cs2tracker-2.1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
14
|
+
cs2tracker-2.1.7.dist-info/entry_points.txt,sha256=K8IwDIkg8QztSB9g9c89B9jR_2pG4QyJGrNs4z5RcZw,63
|
|
15
|
+
cs2tracker-2.1.7.dist-info/top_level.txt,sha256=2HB4xDDOxaU5BDc_yvdi9UlYLgL768n8aR-hRhFM6VQ,11
|
|
16
|
+
cs2tracker-2.1.7.dist-info/RECORD,,
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
cs2tracker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
cs2tracker/__main__.py,sha256=Ub--oSMv48YzfWF1CZqYlkn1-HvZ7Bhxoc7urn1oY6o,249
|
|
3
|
-
cs2tracker/_version.py,sha256=ezuEPMmZBPsFTNec3uKYV6IfWrjNpfiIok1e_GQvZGQ,511
|
|
4
|
-
cs2tracker/application.py,sha256=pFmPRmm9OdYRLLl6qnmkHyV7oLI-Le4YSO26VX7eP4U,7180
|
|
5
|
-
cs2tracker/constants.py,sha256=er-YFaEe8WachO_q-RU6vik5SUcFEtacHxGYhD15Stk,17104
|
|
6
|
-
cs2tracker/main.py,sha256=kiTADEXXnX1y3kh0zII91mjadztMB145RBteXM2WG3I,915
|
|
7
|
-
cs2tracker/padded_console.py,sha256=lPEa34p-8LTmTbpf-2S5uYPaA2UmsIOPq2_UoVhMRgU,674
|
|
8
|
-
cs2tracker/scraper.py,sha256=hrL01_HWHpZZgkevj5JCmET0o2T1wSbmsxapuK11gv4,16202
|
|
9
|
-
cs2tracker/data/config.ini,sha256=q-T7_W3krPVJJoMcRJGGczNRvCZw-wJfNobpsdUEDNs,2672
|
|
10
|
-
cs2tracker/data/output.csv,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
cs2tracker-2.1.5.dist-info/licenses/LICENSE.md,sha256=G5wqQ_8KGA808kVuF-Fpu_Yhteg8K_5ux9n2v8eQK7s,1069
|
|
12
|
-
cs2tracker-2.1.5.dist-info/METADATA,sha256=zFEptkI_0AXDALL3uGqz0pTsRGn5OQMmnn-qAL6azfs,3126
|
|
13
|
-
cs2tracker-2.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
14
|
-
cs2tracker-2.1.5.dist-info/entry_points.txt,sha256=K8IwDIkg8QztSB9g9c89B9jR_2pG4QyJGrNs4z5RcZw,63
|
|
15
|
-
cs2tracker-2.1.5.dist-info/top_level.txt,sha256=2HB4xDDOxaU5BDc_yvdi9UlYLgL768n8aR-hRhFM6VQ,11
|
|
16
|
-
cs2tracker-2.1.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|