cs2tracker 2.1.10__py3-none-any.whl → 2.1.12__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/app/__init__.py +3 -0
- cs2tracker/app/application.py +255 -0
- cs2tracker/app/editor_frame.py +247 -0
- cs2tracker/app/scraper_frame.py +76 -0
- cs2tracker/constants.py +101 -114
- cs2tracker/data/config.ini +107 -107
- cs2tracker/main.py +2 -2
- cs2tracker/scraper/__init__.py +9 -0
- cs2tracker/{background_task.py → scraper/background_task.py} +1 -1
- cs2tracker/{discord_notifier.py → scraper/discord_notifier.py} +1 -2
- cs2tracker/{scraper.py → scraper/scraper.py} +51 -20
- cs2tracker/util/__init__.py +9 -0
- cs2tracker/{validated_config.py → util/validated_config.py} +1 -1
- {cs2tracker-2.1.10.dist-info → cs2tracker-2.1.12.dist-info}/METADATA +3 -3
- cs2tracker-2.1.12.dist-info/RECORD +25 -0
- cs2tracker/application.py +0 -516
- cs2tracker-2.1.10.dist-info/RECORD +0 -20
- /cs2tracker/{padded_console.py → util/padded_console.py} +0 -0
- /cs2tracker/{price_logs.py → util/price_logs.py} +0 -0
- {cs2tracker-2.1.10.dist-info → cs2tracker-2.1.12.dist-info}/WHEEL +0 -0
- {cs2tracker-2.1.10.dist-info → cs2tracker-2.1.12.dist-info}/entry_points.txt +0 -0
- {cs2tracker-2.1.10.dist-info → cs2tracker-2.1.12.dist-info}/licenses/LICENSE.md +0 -0
- {cs2tracker-2.1.10.dist-info → cs2tracker-2.1.12.dist-info}/top_level.txt +0 -0
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import requests
|
|
2
2
|
from requests.exceptions import RequestException
|
|
3
3
|
|
|
4
|
-
from cs2tracker.
|
|
5
|
-
from cs2tracker.price_logs import PriceLogs
|
|
4
|
+
from cs2tracker.util import PaddedConsole, PriceLogs
|
|
6
5
|
|
|
7
6
|
DC_WEBHOOK_USERNAME = "CS2Tracker"
|
|
8
7
|
DC_WEBHOOK_AVATAR_URL = "https://img.icons8.com/?size=100&id=uWQJp2tLXUH6&format=png&color=000000"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import time
|
|
2
|
+
from datetime import datetime
|
|
2
3
|
from urllib.parse import unquote
|
|
3
4
|
|
|
4
5
|
from bs4 import BeautifulSoup
|
|
@@ -9,10 +10,8 @@ from requests.adapters import HTTPAdapter, Retry
|
|
|
9
10
|
from tenacity import RetryError, retry, stop_after_attempt
|
|
10
11
|
|
|
11
12
|
from cs2tracker.constants import AUTHOR_STRING, BANNER, CAPSULE_INFO, CASE_HREFS
|
|
12
|
-
from cs2tracker.discord_notifier import DiscordNotifier
|
|
13
|
-
from cs2tracker.
|
|
14
|
-
from cs2tracker.price_logs import PriceLogs
|
|
15
|
-
from cs2tracker.validated_config import ValidatedConfig
|
|
13
|
+
from cs2tracker.scraper.discord_notifier import DiscordNotifier
|
|
14
|
+
from cs2tracker.util import PaddedConsole, PriceLogs, ValidatedConfig
|
|
16
15
|
|
|
17
16
|
MAX_LINE_LEN = 72
|
|
18
17
|
SEPARATOR = "-"
|
|
@@ -49,9 +48,13 @@ class Scraper:
|
|
|
49
48
|
self.session.mount("http://", HTTPAdapter(max_retries=retries))
|
|
50
49
|
self.session.mount("https://", HTTPAdapter(max_retries=retries))
|
|
51
50
|
|
|
52
|
-
def scrape_prices(self):
|
|
53
|
-
"""
|
|
51
|
+
def scrape_prices(self, update_sheet_callback=None):
|
|
52
|
+
"""
|
|
53
|
+
Scrape prices for capsules and cases, calculate totals in USD and EUR, and
|
|
54
54
|
print/save the results.
|
|
55
|
+
|
|
56
|
+
:param update_sheet_callback: Optional callback function to update a tksheet
|
|
57
|
+
that is displayed in the GUI with the latest scraper price calculation.
|
|
55
58
|
"""
|
|
56
59
|
if not self.config.valid:
|
|
57
60
|
console.print(
|
|
@@ -59,15 +62,26 @@ class Scraper:
|
|
|
59
62
|
)
|
|
60
63
|
return
|
|
61
64
|
|
|
62
|
-
capsule_usd_total = self._scrape_capsule_section_prices()
|
|
63
|
-
case_usd_total = self._scrape_case_prices()
|
|
64
|
-
custom_item_usd_total = self._scrape_custom_item_prices()
|
|
65
|
+
capsule_usd_total = self._scrape_capsule_section_prices(update_sheet_callback)
|
|
66
|
+
case_usd_total = self._scrape_case_prices(update_sheet_callback)
|
|
67
|
+
custom_item_usd_total = self._scrape_custom_item_prices(update_sheet_callback)
|
|
65
68
|
|
|
66
69
|
self.usd_total += capsule_usd_total
|
|
67
70
|
self.usd_total += case_usd_total
|
|
68
71
|
self.usd_total += custom_item_usd_total
|
|
69
72
|
self.eur_total = CurrencyConverter().convert(self.usd_total, "USD", "EUR")
|
|
70
73
|
|
|
74
|
+
if update_sheet_callback:
|
|
75
|
+
update_sheet_callback(["", "", "", ""])
|
|
76
|
+
update_sheet_callback(
|
|
77
|
+
[
|
|
78
|
+
f"[{datetime.now().strftime('%Y-%m-%d')}] Total:",
|
|
79
|
+
f"${self.usd_total:.2f}",
|
|
80
|
+
f"€{self.eur_total:.2f}",
|
|
81
|
+
"",
|
|
82
|
+
]
|
|
83
|
+
)
|
|
84
|
+
|
|
71
85
|
self._print_total()
|
|
72
86
|
PriceLogs.save(self.usd_total, self.eur_total)
|
|
73
87
|
self._send_discord_notification()
|
|
@@ -158,11 +172,7 @@ class Scraper:
|
|
|
158
172
|
|
|
159
173
|
return price
|
|
160
174
|
|
|
161
|
-
def _scrape_capsule_prices(
|
|
162
|
-
self,
|
|
163
|
-
capsule_section,
|
|
164
|
-
capsule_info,
|
|
165
|
-
):
|
|
175
|
+
def _scrape_capsule_prices(self, capsule_section, capsule_info, update_sheet_callback=None):
|
|
166
176
|
"""
|
|
167
177
|
Scrape prices for a specific capsule section, printing the details to the
|
|
168
178
|
console.
|
|
@@ -170,6 +180,8 @@ class Scraper:
|
|
|
170
180
|
:param capsule_section: The section name in the config for the capsule.
|
|
171
181
|
:param capsule_info: A dictionary containing information about the capsule page,
|
|
172
182
|
hrefs, and names.
|
|
183
|
+
:param update_sheet_callback: Optional callback function to update a tksheet
|
|
184
|
+
that is displayed in the GUI with the latest scraper price calculation.
|
|
173
185
|
"""
|
|
174
186
|
capsule_title = capsule_section.center(MAX_LINE_LEN, SEPARATOR)
|
|
175
187
|
console.print(f"[bold magenta]{capsule_title}\n")
|
|
@@ -178,7 +190,7 @@ class Scraper:
|
|
|
178
190
|
try:
|
|
179
191
|
capsule_page = self._get_page(capsule_info["page"])
|
|
180
192
|
for capsule_name, capsule_href in zip(capsule_info["names"], capsule_info["items"]):
|
|
181
|
-
config_capsule_name = capsule_name.replace(" ", "_")
|
|
193
|
+
config_capsule_name = capsule_name.replace(" ", "_").lower()
|
|
182
194
|
owned = self.config.getint(capsule_section, config_capsule_name, fallback=0)
|
|
183
195
|
if owned == 0:
|
|
184
196
|
continue
|
|
@@ -188,6 +200,8 @@ class Scraper:
|
|
|
188
200
|
|
|
189
201
|
console.print(f"[bold deep_sky_blue4]{capsule_name}")
|
|
190
202
|
console.print(PRICE_INFO.format(owned, price_usd, price_usd_owned))
|
|
203
|
+
if update_sheet_callback:
|
|
204
|
+
update_sheet_callback([capsule_name, owned, price_usd, price_usd_owned])
|
|
191
205
|
capsule_usd_total += price_usd_owned
|
|
192
206
|
except (RetryError, ValueError):
|
|
193
207
|
console.print(
|
|
@@ -198,13 +212,20 @@ class Scraper:
|
|
|
198
212
|
|
|
199
213
|
return capsule_usd_total
|
|
200
214
|
|
|
201
|
-
def _scrape_capsule_section_prices(self):
|
|
202
|
-
"""
|
|
215
|
+
def _scrape_capsule_section_prices(self, update_sheet_callback=None):
|
|
216
|
+
"""
|
|
217
|
+
Scrape prices for all capsule sections defined in the configuration.
|
|
218
|
+
|
|
219
|
+
:param update_sheet_callback: Optional callback function to update a tksheet
|
|
220
|
+
that is displayed in the GUI with the latest scraper price calculation.
|
|
221
|
+
"""
|
|
203
222
|
capsule_usd_total = 0
|
|
204
223
|
for capsule_section, capsule_info in CAPSULE_INFO.items():
|
|
205
224
|
# Only scrape capsule sections where the user owns at least one item
|
|
206
225
|
if any(int(owned) > 0 for _, owned in self.config.items(capsule_section)):
|
|
207
|
-
capsule_usd_total += self._scrape_capsule_prices(
|
|
226
|
+
capsule_usd_total += self._scrape_capsule_prices(
|
|
227
|
+
capsule_section, capsule_info, update_sheet_callback
|
|
228
|
+
)
|
|
208
229
|
|
|
209
230
|
return capsule_usd_total
|
|
210
231
|
|
|
@@ -221,12 +242,15 @@ class Scraper:
|
|
|
221
242
|
|
|
222
243
|
return page_url
|
|
223
244
|
|
|
224
|
-
def _scrape_case_prices(self):
|
|
245
|
+
def _scrape_case_prices(self, update_sheet_callback=None):
|
|
225
246
|
"""
|
|
226
247
|
Scrape prices for all cases defined in the configuration.
|
|
227
248
|
|
|
228
249
|
For each case, it prints the case name, owned count, price per item, and total
|
|
229
250
|
price for owned items.
|
|
251
|
+
|
|
252
|
+
:param update_sheet_callback: Optional callback function to update a tksheet
|
|
253
|
+
that is displayed in the GUI with the latest scraper price calculation.
|
|
230
254
|
"""
|
|
231
255
|
case_usd_total = 0
|
|
232
256
|
for case_index, (config_case_name, owned) in enumerate(self.config.items("Cases")):
|
|
@@ -244,6 +268,8 @@ class Scraper:
|
|
|
244
268
|
price_usd_owned = round(float(int(owned) * price_usd), 2)
|
|
245
269
|
|
|
246
270
|
console.print(PRICE_INFO.format(owned, price_usd, price_usd_owned))
|
|
271
|
+
if update_sheet_callback:
|
|
272
|
+
update_sheet_callback([case_name, owned, price_usd, price_usd_owned])
|
|
247
273
|
case_usd_total += price_usd_owned
|
|
248
274
|
|
|
249
275
|
if not self.config.getboolean("App Settings", "use_proxy", fallback=False):
|
|
@@ -257,12 +283,15 @@ class Scraper:
|
|
|
257
283
|
|
|
258
284
|
return case_usd_total
|
|
259
285
|
|
|
260
|
-
def _scrape_custom_item_prices(self):
|
|
286
|
+
def _scrape_custom_item_prices(self, update_sheet_callback=None):
|
|
261
287
|
"""
|
|
262
288
|
Scrape prices for custom items defined in the configuration.
|
|
263
289
|
|
|
264
290
|
For each custom item, it prints the item name, owned count, price per item, and
|
|
265
291
|
total price for owned items.
|
|
292
|
+
|
|
293
|
+
:param update_sheet_callback: Optional callback function to update a tksheet
|
|
294
|
+
that is displayed in the GUI with the latest scraper price calculation.
|
|
266
295
|
"""
|
|
267
296
|
custom_item_usd_total = 0
|
|
268
297
|
for custom_item_href, owned in self.config.items("Custom Items"):
|
|
@@ -280,6 +309,8 @@ class Scraper:
|
|
|
280
309
|
price_usd_owned = round(float(int(owned) * price_usd), 2)
|
|
281
310
|
|
|
282
311
|
console.print(PRICE_INFO.format(owned, price_usd, price_usd_owned))
|
|
312
|
+
if update_sheet_callback:
|
|
313
|
+
update_sheet_callback([custom_item_name, owned, price_usd, price_usd_owned])
|
|
283
314
|
custom_item_usd_total += price_usd_owned
|
|
284
315
|
|
|
285
316
|
if not self.config.getboolean("App Settings", "use_proxy", fallback=False):
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from cs2tracker.util.padded_console import ( # noqa: F401 # pylint:disable=unused-import
|
|
2
|
+
PaddedConsole,
|
|
3
|
+
)
|
|
4
|
+
from cs2tracker.util.price_logs import ( # noqa: F401 # pylint:disable=unused-import
|
|
5
|
+
PriceLogs,
|
|
6
|
+
)
|
|
7
|
+
from cs2tracker.util.validated_config import ( # noqa: F401 # pylint:disable=unused-import
|
|
8
|
+
ValidatedConfig,
|
|
9
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cs2tracker
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.12
|
|
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
|
|
@@ -20,6 +20,7 @@ Requires-Dist: rich==13.6.0
|
|
|
20
20
|
Requires-Dist: tenacity==8.2.2
|
|
21
21
|
Requires-Dist: urllib3==2.1.0
|
|
22
22
|
Requires-Dist: sv_ttk==2.6.1
|
|
23
|
+
Requires-Dist: tksheet==7.5.12
|
|
23
24
|
Dynamic: license-file
|
|
24
25
|
|
|
25
26
|
<div align="center">
|
|
@@ -67,9 +68,8 @@ Dynamic: license-file
|
|
|
67
68
|
|
|
68
69
|
### Options
|
|
69
70
|
|
|
70
|
-
- `Run!` to gather the current market prices of your items and calculate the total amount in USD and EUR.
|
|
71
|
+
- `Run!` to gather the current market prices of your items and calculate the total amount in USD and EUR. The generated Excel sheet can be saved by right-clicking and then selecting `Save Sheet`.
|
|
71
72
|
- `Edit Config` to specify the numbers of items owned in the configuration. You can also add items other than cases and sticker capsules via `Add Custom Item`
|
|
72
|
-
- `Reset Config` to reset the configuration to its original state. This will remove any custom items you have added and reset the number of items owned for all items.
|
|
73
73
|
- `Show History` to see a price chart consisting of past calculations. A new data point is generated once a day upon running the program.
|
|
74
74
|
- `Export / Import History` to export the price history to a CSV file or import it from a CSV file. This may be used to back up your history data or perform further analysis on it.
|
|
75
75
|
- `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`.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
cs2tracker/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
cs2tracker/__main__.py,sha256=Ub--oSMv48YzfWF1CZqYlkn1-HvZ7Bhxoc7urn1oY6o,249
|
|
3
|
+
cs2tracker/_version.py,sha256=-B2mQZ--x6naZOZ9F0dSrWJNv2VV6u4VsADdB1kHH0k,513
|
|
4
|
+
cs2tracker/constants.py,sha256=G6OaunSpb-SjIgzRSJA9LFczx5MPrXS3Qcq8eHBMa7I,27393
|
|
5
|
+
cs2tracker/main.py,sha256=kyQC0qvUYvd6Cgso48WnDCA8mJRijHMdlV4CffLuoBI,1023
|
|
6
|
+
cs2tracker/app/__init__.py,sha256=uqAxdDzoR2-2IrDc1riIU3Pi9vLEDwr68eg93-0RFmM,105
|
|
7
|
+
cs2tracker/app/application.py,sha256=mlO1P8fs4H_GEhOVaViwX6g9Xw0697qqB_Ypmq3sZwA,9445
|
|
8
|
+
cs2tracker/app/editor_frame.py,sha256=g6DLAct7ZPREDNP4gN6KkFQKxgqjpFyyq18n5h-AOQg,9786
|
|
9
|
+
cs2tracker/app/scraper_frame.py,sha256=VXDl942Jm1gPnw8DRhsYaxmMt_2N6GA0kz259iEsmX0,2576
|
|
10
|
+
cs2tracker/data/config.ini,sha256=pnd-s5X3x73KnLfjvRg5mfs4qfpv0ieyF-4AKq1EXTs,5576
|
|
11
|
+
cs2tracker/data/output.csv,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
cs2tracker/scraper/__init__.py,sha256=kfUB9yfshSche92ZvTqQQYBkVqujRez46djPoa9u0YU,335
|
|
13
|
+
cs2tracker/scraper/background_task.py,sha256=zuMqAaWFbrwDNKtO3kwynp1Dq8ATUCdlJlfReZQS_48,3703
|
|
14
|
+
cs2tracker/scraper/discord_notifier.py,sha256=pVmQohhG_61Pvq2zzqDDfImT6l5lGc-nQ_LPwpOLa3k,2994
|
|
15
|
+
cs2tracker/scraper/scraper.py,sha256=gpKziIzOGu7916bslJ3r2dXvJl6mLR2etopaLm752ww,14658
|
|
16
|
+
cs2tracker/util/__init__.py,sha256=TId6-M-sVLjPcwc3XvtdnluvQOB8C4NsQx4NHHIIzUg,329
|
|
17
|
+
cs2tracker/util/padded_console.py,sha256=lPEa34p-8LTmTbpf-2S5uYPaA2UmsIOPq2_UoVhMRgU,674
|
|
18
|
+
cs2tracker/util/price_logs.py,sha256=JuZ2ptDtxA-NzKjpG_4q0eeOr1IaUvVah-Qth6GrDDU,4165
|
|
19
|
+
cs2tracker/util/validated_config.py,sha256=WCkAhLsh16oFiemUV0Uap0NuecAVSEv-ceXwybh_AYk,4790
|
|
20
|
+
cs2tracker-2.1.12.dist-info/licenses/LICENSE.md,sha256=G5wqQ_8KGA808kVuF-Fpu_Yhteg8K_5ux9n2v8eQK7s,1069
|
|
21
|
+
cs2tracker-2.1.12.dist-info/METADATA,sha256=5FcfWK5Wkg5751t5ewdJl1OavDr8kXf3tUGPObV3XvI,4014
|
|
22
|
+
cs2tracker-2.1.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
23
|
+
cs2tracker-2.1.12.dist-info/entry_points.txt,sha256=K8IwDIkg8QztSB9g9c89B9jR_2pG4QyJGrNs4z5RcZw,63
|
|
24
|
+
cs2tracker-2.1.12.dist-info/top_level.txt,sha256=2HB4xDDOxaU5BDc_yvdi9UlYLgL768n8aR-hRhFM6VQ,11
|
|
25
|
+
cs2tracker-2.1.12.dist-info/RECORD,,
|