cs2tracker 2.1.4__py3-none-any.whl → 2.1.6__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 +148 -50
- cs2tracker/constants.py +388 -108
- cs2tracker/data/config.ini +150 -65
- cs2tracker/data/output.csv +0 -0
- cs2tracker/main.py +13 -22
- cs2tracker/padded_console.py +22 -0
- cs2tracker/scraper.py +51 -32
- {cs2tracker-2.1.4.dist-info → cs2tracker-2.1.6.dist-info}/METADATA +17 -11
- cs2tracker-2.1.6.dist-info/RECORD +16 -0
- cs2tracker-2.1.4.dist-info/RECORD +0 -14
- {cs2tracker-2.1.4.dist-info → cs2tracker-2.1.6.dist-info}/WHEEL +0 -0
- {cs2tracker-2.1.4.dist-info → cs2tracker-2.1.6.dist-info}/entry_points.txt +0 -0
- {cs2tracker-2.1.4.dist-info → cs2tracker-2.1.6.dist-info}/licenses/LICENSE.md +0 -0
- {cs2tracker-2.1.4.dist-info → cs2tracker-2.1.6.dist-info}/top_level.txt +0 -0
cs2tracker/data/config.ini
CHANGED
|
@@ -2,112 +2,197 @@
|
|
|
2
2
|
Use_Proxy = False
|
|
3
3
|
API_Key = None
|
|
4
4
|
|
|
5
|
+
[Cases]
|
|
6
|
+
Revolution_Case = 0
|
|
7
|
+
Recoil_Case = 0
|
|
8
|
+
Dreams_And_Nightmares_Case = 0
|
|
9
|
+
Operation_Riptide_Case = 0
|
|
10
|
+
Snakebite_Case = 0
|
|
11
|
+
Operation_Broken_Fang_Case = 0
|
|
12
|
+
Fracture_Case = 0
|
|
13
|
+
Chroma_Case = 0
|
|
14
|
+
Chroma_2_Case = 0
|
|
15
|
+
Chroma_3_Case = 0
|
|
16
|
+
Clutch_Case = 0
|
|
17
|
+
CSGO_Weapon_Case = 0
|
|
18
|
+
CSGO_Weapon_Case_2 = 0
|
|
19
|
+
CSGO_Weapon_Case_3 = 0
|
|
20
|
+
CS20_Case = 0
|
|
21
|
+
Danger_Zone_Case = 0
|
|
22
|
+
eSports_2013_Case = 0
|
|
23
|
+
eSports_2013_Winter_Case = 0
|
|
24
|
+
eSports_2014_Summer_Case = 0
|
|
25
|
+
Falchion_Case = 0
|
|
26
|
+
Gamma_Case = 0
|
|
27
|
+
Gamma_2_Case = 0
|
|
28
|
+
Glove_Case = 0
|
|
29
|
+
Horizon_Case = 0
|
|
30
|
+
Huntsman_Case = 0
|
|
31
|
+
Operation_Bravo_Case = 0
|
|
32
|
+
Operation_Breakout_Case = 0
|
|
33
|
+
Operation_Hydra_Case = 0
|
|
34
|
+
Operation_Phoenix_Case = 0
|
|
35
|
+
Operation_Vanguard_Case = 0
|
|
36
|
+
Operation_Wildfire_Case = 0
|
|
37
|
+
Prisma_Case = 0
|
|
38
|
+
Prisma_2_Case = 0
|
|
39
|
+
Revolver_Case = 0
|
|
40
|
+
Shadow_Case = 0
|
|
41
|
+
Shattered_Web_Case = 0
|
|
42
|
+
Spectrum_Case = 0
|
|
43
|
+
Spectrum_2_Case = 0
|
|
44
|
+
Winter_Offensive_Case = 0
|
|
45
|
+
Kilowatt_Case = 0
|
|
46
|
+
Gallery_Case = 0
|
|
47
|
+
Fever_Case = 0
|
|
48
|
+
|
|
49
|
+
[Katowice 2014 Sticker Capsule]
|
|
50
|
+
Katowice_Legends = 0
|
|
51
|
+
Katowice_Challengers = 0
|
|
52
|
+
|
|
53
|
+
[Cologne 2014 Sticker Capsule]
|
|
54
|
+
Cologne_Legends = 0
|
|
55
|
+
Cologne_Challengers = 0
|
|
56
|
+
|
|
57
|
+
[DreamHack 2014 Sticker Capsule]
|
|
58
|
+
DreamHack_Legends = 0
|
|
59
|
+
|
|
60
|
+
[Katowice 2015 Sticker Capsule]
|
|
61
|
+
Katowice_Legends = 0
|
|
62
|
+
Katowice_Challengers = 0
|
|
63
|
+
|
|
64
|
+
[Cologne 2015 Sticker Capsule]
|
|
65
|
+
Cologne_Legends = 0
|
|
66
|
+
Cologne_Challengers = 0
|
|
67
|
+
|
|
68
|
+
[Cluj-Napoca 2015 Sticker Capsule]
|
|
69
|
+
Cluj_Napoca_Legends = 0
|
|
70
|
+
Cluj_Napoca_Challengers = 0
|
|
71
|
+
Cluj_Napoca_Legends_Autographs = 0
|
|
72
|
+
Cluj_Napoca_Challengers_Autographs = 0
|
|
73
|
+
|
|
74
|
+
[Columbus 2016 Sticker Capsule]
|
|
75
|
+
Columbus_Legends = 0
|
|
76
|
+
Columbus_Challengers = 0
|
|
77
|
+
Columbus_Legends_Autographs = 0
|
|
78
|
+
Columbus_Challengers_Autographs = 0
|
|
79
|
+
|
|
80
|
+
[Cologne 2016 Sticker Capsule]
|
|
81
|
+
Cologne_Legends = 0
|
|
82
|
+
Cologne_Challengers = 0
|
|
83
|
+
Cologne_Legends_Autographs = 0
|
|
84
|
+
Cologne_Challengers_Autographs = 0
|
|
85
|
+
|
|
86
|
+
[Atlanta 2017 Sticker Capsule]
|
|
87
|
+
Atlanta_Legends = 0
|
|
88
|
+
Atlanta_Challengers = 0
|
|
89
|
+
Atlanta_Legends_Autographs = 0
|
|
90
|
+
Atlanta_Challengers_Autographs = 0
|
|
91
|
+
|
|
92
|
+
[Krakow 2017 Sticker Capsule]
|
|
93
|
+
Krakow_Legends = 0
|
|
94
|
+
Krakow_Challengers = 0
|
|
95
|
+
Krakow_Legends_Autographs = 0
|
|
96
|
+
Krakow_Challengers_Autographs = 0
|
|
97
|
+
|
|
98
|
+
[Boston 2018 Sticker Capsule]
|
|
99
|
+
Boston_Legends = 0
|
|
100
|
+
Boston_Minor_Challengers = 0
|
|
101
|
+
Boston_Returning_Challengers = 0
|
|
102
|
+
Boston_Attending_Legends = 0
|
|
103
|
+
Boston_Minor_Challengers_with_Flash_Gaming = 0
|
|
104
|
+
Boston_Legends_Autographs = 0
|
|
105
|
+
Boston_Minor_Challengers_Autographs = 0
|
|
106
|
+
Boston_Returning_Challengers_Autographs = 0
|
|
107
|
+
Boston_Attending_Legends_Autographs = 0
|
|
108
|
+
Boston_Minor_Challengers_with_Flash_Gaming_Autographs = 0
|
|
109
|
+
|
|
110
|
+
[London 2018 Sticker Capsule]
|
|
111
|
+
London_Legends = 0
|
|
112
|
+
London_Minor_Challengers = 0
|
|
113
|
+
London_Returning_Challengers = 0
|
|
114
|
+
London_Legends_Autographs = 0
|
|
115
|
+
London_Minor_Challengers_Autographs = 0
|
|
116
|
+
London_Returning_Challengers_Autographs = 0
|
|
117
|
+
|
|
118
|
+
[Katowice 2019 Sticker Capsule]
|
|
119
|
+
Katowice_Legends = 0
|
|
120
|
+
Katowice_Minor_Challengers = 0
|
|
121
|
+
Katowice_Returning_Challengers = 0
|
|
122
|
+
Katowice_Legends_Autographs = 0
|
|
123
|
+
Katowice_Minor_Challengers_Autographs = 0
|
|
124
|
+
Katowice_Returning_Challengers_Autographs = 0
|
|
125
|
+
|
|
126
|
+
[Berlin 2019 Sticker Capsule]
|
|
127
|
+
Berlin_Legends = 0
|
|
128
|
+
Berlin_Minor_Challengers = 0
|
|
129
|
+
Berlin_Returning_Challengers = 0
|
|
130
|
+
Berlin_Legends_Autographs = 0
|
|
131
|
+
Berlin_Minor_Challengers_Autographs = 0
|
|
132
|
+
Berlin_Returning_Challengers_Autographs = 0
|
|
133
|
+
|
|
5
134
|
[2020 RMR Sticker Capsule]
|
|
6
|
-
RMR_Challengers = 0
|
|
7
135
|
RMR_Legends = 0
|
|
136
|
+
RMR_Challengers = 0
|
|
8
137
|
RMR_Contenders = 0
|
|
9
138
|
|
|
10
|
-
[Stockholm Sticker Capsule]
|
|
11
|
-
Stockholm_Challengers = 0
|
|
139
|
+
[Stockholm 2021 Sticker Capsule]
|
|
12
140
|
Stockholm_Legends = 0
|
|
141
|
+
Stockholm_Challengers = 0
|
|
13
142
|
Stockholm_Contenders = 0
|
|
14
143
|
Stockholm_Champions_Autographs = 0
|
|
15
144
|
Stockholm_Finalists_Autographs = 0
|
|
16
145
|
|
|
17
|
-
[Antwerp Sticker Capsule]
|
|
18
|
-
Antwerp_Challengers = 0
|
|
146
|
+
[Antwerp 2022 Sticker Capsule]
|
|
19
147
|
Antwerp_Legends = 0
|
|
148
|
+
Antwerp_Challengers = 0
|
|
20
149
|
Antwerp_Contenders = 0
|
|
21
150
|
Antwerp_Champions_Autographs = 0
|
|
22
|
-
Antwerp_Contenders_Autographs = 0
|
|
23
151
|
Antwerp_Challengers_Autographs = 0
|
|
24
152
|
Antwerp_Legends_Autographs = 0
|
|
153
|
+
Antwerp_Contenders_Autographs = 0
|
|
25
154
|
|
|
26
|
-
[Rio Sticker Capsule]
|
|
27
|
-
Rio_Challengers = 0
|
|
155
|
+
[Rio 2022 Sticker Capsule]
|
|
28
156
|
Rio_Legends = 0
|
|
157
|
+
Rio_Challengers = 0
|
|
29
158
|
Rio_Contenders = 0
|
|
30
159
|
Rio_Champions_Autographs = 0
|
|
31
|
-
Rio_Contenders_Autographs = 0
|
|
32
160
|
Rio_Challengers_Autographs = 0
|
|
33
161
|
Rio_Legends_Autographs = 0
|
|
162
|
+
Rio_Contenders_Autographs = 0
|
|
34
163
|
|
|
35
|
-
[Paris Sticker Capsule]
|
|
36
|
-
Paris_Challengers = 0
|
|
164
|
+
[Paris 2023 Sticker Capsule]
|
|
37
165
|
Paris_Legends = 0
|
|
166
|
+
Paris_Challengers = 0
|
|
38
167
|
Paris_Contenders = 0
|
|
39
168
|
Paris_Champions_Autographs = 0
|
|
40
|
-
Paris_Contenders_Autographs = 0
|
|
41
169
|
Paris_Challengers_Autographs = 0
|
|
42
170
|
Paris_Legends_Autographs = 0
|
|
171
|
+
Paris_Contenders_Autographs = 0
|
|
43
172
|
|
|
44
|
-
[Copenhagen Sticker Capsule]
|
|
45
|
-
Copenhagen_Challengers = 0
|
|
173
|
+
[Copenhagen 2024 Sticker Capsule]
|
|
46
174
|
Copenhagen_Legends = 0
|
|
175
|
+
Copenhagen_Challengers = 0
|
|
47
176
|
Copenhagen_Contenders = 0
|
|
48
177
|
Copenhagen_Champions_Autographs = 0
|
|
49
|
-
Copenhagen_Contenders_Autographs = 0
|
|
50
178
|
Copenhagen_Challengers_Autographs = 0
|
|
51
179
|
Copenhagen_Legends_Autographs = 0
|
|
180
|
+
Copenhagen_Contenders_Autographs = 0
|
|
52
181
|
|
|
53
|
-
[Shanghai Sticker Capsule]
|
|
54
|
-
Shanghai_Challengers = 0
|
|
182
|
+
[Shanghai 2024 Sticker Capsule]
|
|
55
183
|
Shanghai_Legends = 0
|
|
184
|
+
Shanghai_Challengers = 0
|
|
56
185
|
Shanghai_Contenders = 0
|
|
57
186
|
Shanghai_Champions_Autographs = 0
|
|
58
|
-
Shanghai_Contenders_Autographs = 0
|
|
59
187
|
Shanghai_Challengers_Autographs = 0
|
|
60
188
|
Shanghai_Legends_Autographs = 0
|
|
189
|
+
Shanghai_Contenders_Autographs = 0
|
|
61
190
|
|
|
62
|
-
[Austin Sticker Capsule]
|
|
63
|
-
Austin_Challengers = 0
|
|
191
|
+
[Austin 2025 Sticker Capsule]
|
|
64
192
|
Austin_Legends = 0
|
|
193
|
+
Austin_Challengers = 0
|
|
65
194
|
Austin_Contenders = 0
|
|
66
195
|
Austin_Champions_Autographs = 0
|
|
67
|
-
Austin_Contenders_Autographs = 0
|
|
68
196
|
Austin_Challengers_Autographs = 0
|
|
69
197
|
Austin_Legends_Autographs = 0
|
|
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
|
|
198
|
+
Austin_Contenders_Autographs = 0
|
|
File without changes
|
cs2tracker/main.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
import sys
|
|
2
2
|
|
|
3
3
|
import urllib3
|
|
4
|
-
from rich.console import Console
|
|
5
4
|
|
|
6
|
-
from cs2tracker._version import version # pylint: disable=E0611
|
|
7
5
|
from cs2tracker.application import Application
|
|
6
|
+
from cs2tracker.constants import AUTHOR_STRING, BANNER
|
|
7
|
+
from cs2tracker.padded_console import PaddedConsole
|
|
8
|
+
from cs2tracker.scraper import Scraper
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
def main():
|
|
@@ -18,25 +19,15 @@ def main():
|
|
|
18
19
|
# Disable warnings for proxy requests
|
|
19
20
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
20
21
|
|
|
21
|
-
console =
|
|
22
|
-
console.print(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
\\ | \\ || | | | | . Y| | |\\ || . || T| . Y
|
|
31
|
-
\\____j \\___jl_____j l__j l__j\\_jl__j__j \\____jl__j\\_jl_____jl__j\\_j
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"""
|
|
35
|
-
+ f"Version: v{version} - {datetime.today().strftime('%Y/%m/%d')} - Jannik Novak @ashiven\n"
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
application = Application()
|
|
39
|
-
application.run()
|
|
22
|
+
console = PaddedConsole()
|
|
23
|
+
console.print(f"[bold yellow]{BANNER}\n{AUTHOR_STRING}\n")
|
|
24
|
+
|
|
25
|
+
if "--only-scrape" in sys.argv:
|
|
26
|
+
scraper = Scraper()
|
|
27
|
+
scraper.scrape_prices()
|
|
28
|
+
else:
|
|
29
|
+
application = Application()
|
|
30
|
+
application.run()
|
|
40
31
|
|
|
41
32
|
|
|
42
33
|
if __name__ == "__main__":
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from rich.console import Console
|
|
2
|
+
from rich.padding import Padding
|
|
3
|
+
|
|
4
|
+
PADDING_BOTTOM = 0
|
|
5
|
+
PADDING_TOP = 0
|
|
6
|
+
PADDING_LEFT = 4
|
|
7
|
+
PADDING_RIGHT = 0
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class PaddedConsole:
|
|
11
|
+
def __init__(self, padding=(PADDING_TOP, PADDING_RIGHT, PADDING_BOTTOM, PADDING_LEFT)):
|
|
12
|
+
"""Initialize a PaddedConsole with specified padding."""
|
|
13
|
+
self.console = Console()
|
|
14
|
+
self.padding = padding
|
|
15
|
+
|
|
16
|
+
def print(self, text):
|
|
17
|
+
"""Print text with padding to the console."""
|
|
18
|
+
self.console.print(Padding(text, self.padding))
|
|
19
|
+
|
|
20
|
+
def __getattr__(self, attr):
|
|
21
|
+
"""Ensure console methods can be called directly on PaddedConsole."""
|
|
22
|
+
return getattr(self.console, attr)
|
cs2tracker/scraper.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import csv
|
|
2
2
|
import os
|
|
3
|
-
import sys
|
|
4
3
|
import time
|
|
5
4
|
from configparser import ConfigParser
|
|
6
5
|
from datetime import datetime
|
|
@@ -11,23 +10,31 @@ from bs4.element import Tag
|
|
|
11
10
|
from currency_converter import CurrencyConverter
|
|
12
11
|
from requests import RequestException, Session
|
|
13
12
|
from requests.adapters import HTTPAdapter, Retry
|
|
14
|
-
from rich.console import Console
|
|
15
13
|
from tenacity import RetryError, retry, stop_after_attempt
|
|
16
14
|
|
|
17
15
|
from cs2tracker.constants import (
|
|
16
|
+
AUTHOR_STRING,
|
|
17
|
+
BANNER,
|
|
18
18
|
BATCH_FILE,
|
|
19
19
|
CAPSULE_INFO,
|
|
20
20
|
CASE_HREFS,
|
|
21
21
|
CASE_PAGES,
|
|
22
22
|
CONFIG_FILE,
|
|
23
|
+
OS,
|
|
23
24
|
OUTPUT_FILE,
|
|
24
25
|
PROJECT_DIR,
|
|
25
26
|
PYTHON_EXECUTABLE,
|
|
27
|
+
RUNNING_IN_EXE,
|
|
28
|
+
OSType,
|
|
26
29
|
)
|
|
30
|
+
from cs2tracker.padded_console import PaddedConsole
|
|
27
31
|
|
|
28
32
|
MAX_LINE_LEN = 72
|
|
29
33
|
SEPARATOR = "-"
|
|
30
|
-
PRICE_INFO = "Owned: {}
|
|
34
|
+
PRICE_INFO = "Owned: {:<10} Steam market price: ${:<10} Total: ${:<10}\n"
|
|
35
|
+
|
|
36
|
+
HTTP_PROXY_URL = "http://{}:@smartproxy.crawlbase.com:8012"
|
|
37
|
+
HTTPS_PROXY_URL = "http://{}:@smartproxy.crawlbase.com:8012"
|
|
31
38
|
|
|
32
39
|
WIN_BACKGROUND_TASK_NAME = "CS2Tracker Daily Calculation"
|
|
33
40
|
WIN_BACKGROUND_TASK_SCHEDULE = "DAILY"
|
|
@@ -40,7 +47,7 @@ WIN_BACKGROUND_TASK_CMD = (
|
|
|
40
47
|
class Scraper:
|
|
41
48
|
def __init__(self):
|
|
42
49
|
"""Initialize the Scraper class."""
|
|
43
|
-
self.console =
|
|
50
|
+
self.console = PaddedConsole()
|
|
44
51
|
self.parse_config()
|
|
45
52
|
self._start_session()
|
|
46
53
|
|
|
@@ -116,21 +123,33 @@ class Scraper:
|
|
|
116
123
|
This will append a new entry to the output file if no entry has been made for
|
|
117
124
|
today.
|
|
118
125
|
"""
|
|
119
|
-
if not os.path.isfile(OUTPUT_FILE):
|
|
120
|
-
open(OUTPUT_FILE, "w", encoding="utf-8").close()
|
|
121
|
-
|
|
122
126
|
with open(OUTPUT_FILE, "r", encoding="utf-8") as price_logs:
|
|
123
127
|
price_logs_reader = csv.reader(price_logs)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
last_log_date, _ = row
|
|
128
|
+
rows = list(price_logs_reader)
|
|
129
|
+
last_log_date, _, _ = rows[-1] if rows else ("", "", "")
|
|
127
130
|
|
|
128
131
|
today = datetime.now().strftime("%Y-%m-%d")
|
|
129
132
|
if last_log_date != today:
|
|
133
|
+
# Append first price calculation of the day
|
|
130
134
|
with open(OUTPUT_FILE, "a", newline="", encoding="utf-8") as price_logs:
|
|
131
135
|
price_logs_writer = csv.writer(price_logs)
|
|
132
|
-
price_logs_writer.writerow(
|
|
133
|
-
|
|
136
|
+
price_logs_writer.writerow(
|
|
137
|
+
[today, f"{self.usd_total:.2f}$", f"{self.eur_total:.2f}€"]
|
|
138
|
+
)
|
|
139
|
+
else:
|
|
140
|
+
# Replace the last calculation of today with the most recent one of today
|
|
141
|
+
with open(OUTPUT_FILE, "r+", newline="", encoding="utf-8") as price_logs:
|
|
142
|
+
price_logs_reader = csv.reader(price_logs)
|
|
143
|
+
rows = list(price_logs_reader)
|
|
144
|
+
rows_without_today = rows[:-1]
|
|
145
|
+
price_logs.seek(0)
|
|
146
|
+
price_logs.truncate()
|
|
147
|
+
|
|
148
|
+
price_logs_writer = csv.writer(price_logs)
|
|
149
|
+
price_logs_writer.writerows(rows_without_today)
|
|
150
|
+
price_logs_writer.writerow(
|
|
151
|
+
[today, f"{self.usd_total:.2f}$", f"{self.eur_total:.2f}€"]
|
|
152
|
+
)
|
|
134
153
|
|
|
135
154
|
def read_price_log(self):
|
|
136
155
|
"""
|
|
@@ -139,23 +158,18 @@ class Scraper:
|
|
|
139
158
|
|
|
140
159
|
:return: A tuple containing three lists: dates, dollar prices, and euro prices.
|
|
141
160
|
"""
|
|
142
|
-
if not os.path.isfile(OUTPUT_FILE):
|
|
143
|
-
open(OUTPUT_FILE, "w", encoding="utf-8").close()
|
|
144
|
-
|
|
145
161
|
dates, dollars, euros = [], [], []
|
|
146
162
|
with open(OUTPUT_FILE, "r", encoding="utf-8") as price_logs:
|
|
147
163
|
price_logs_reader = csv.reader(price_logs)
|
|
148
164
|
for row in price_logs_reader:
|
|
149
|
-
date,
|
|
165
|
+
date, price_usd, price_eur = row
|
|
150
166
|
date = datetime.strptime(date, "%Y-%m-%d")
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
# and we want the length of dates to match the lengths of dollars and euros
|
|
158
|
-
dates.append(date)
|
|
167
|
+
price_usd = float(price_usd.rstrip("$"))
|
|
168
|
+
price_eur = float(price_eur.rstrip("€"))
|
|
169
|
+
|
|
170
|
+
dates.append(date)
|
|
171
|
+
dollars.append(price_usd)
|
|
172
|
+
euros.append(price_eur)
|
|
159
173
|
|
|
160
174
|
return dates, dollars, euros
|
|
161
175
|
|
|
@@ -172,12 +186,13 @@ class Scraper:
|
|
|
172
186
|
"""
|
|
173
187
|
use_proxy = self.config.getboolean("Settings", "Use_Proxy", fallback=False)
|
|
174
188
|
api_key = self.config.get("Settings", "API_Key", fallback=None)
|
|
189
|
+
api_key = None if api_key in ("None", "") else api_key
|
|
175
190
|
if use_proxy and api_key:
|
|
176
191
|
page = self.session.get(
|
|
177
192
|
url=url,
|
|
178
193
|
proxies={
|
|
179
|
-
"http":
|
|
180
|
-
"https":
|
|
194
|
+
"http": HTTP_PROXY_URL.format(api_key),
|
|
195
|
+
"https": HTTPS_PROXY_URL.format(api_key),
|
|
181
196
|
},
|
|
182
197
|
verify=False,
|
|
183
198
|
)
|
|
@@ -315,7 +330,7 @@ class Scraper:
|
|
|
315
330
|
|
|
316
331
|
:return: True if a background task is found, False otherwise.
|
|
317
332
|
"""
|
|
318
|
-
if
|
|
333
|
+
if OS == OSType.WINDOWS:
|
|
319
334
|
cmd = ["schtasks", "/query", "/tn", WIN_BACKGROUND_TASK_NAME]
|
|
320
335
|
return_code = call(cmd, stdout=DEVNULL, stderr=DEVNULL)
|
|
321
336
|
found = return_code == 0
|
|
@@ -333,8 +348,13 @@ class Scraper:
|
|
|
333
348
|
"""
|
|
334
349
|
if enabled:
|
|
335
350
|
with open(BATCH_FILE, "w", encoding="utf-8") as batch_file:
|
|
336
|
-
|
|
337
|
-
|
|
351
|
+
if RUNNING_IN_EXE:
|
|
352
|
+
# The python executable is set to the executable itself
|
|
353
|
+
# for executables created with PyInstaller
|
|
354
|
+
batch_file.write(f"{PYTHON_EXECUTABLE} --only-scrape\n")
|
|
355
|
+
else:
|
|
356
|
+
batch_file.write(f"cd {PROJECT_DIR}\n")
|
|
357
|
+
batch_file.write(f"{PYTHON_EXECUTABLE} -m cs2tracker --only-scrape\n")
|
|
338
358
|
else:
|
|
339
359
|
if os.path.exists(BATCH_FILE):
|
|
340
360
|
os.remove(BATCH_FILE)
|
|
@@ -380,7 +400,7 @@ class Scraper:
|
|
|
380
400
|
:param enabled: If True, the task will be created; if False, the task will be
|
|
381
401
|
deleted.
|
|
382
402
|
"""
|
|
383
|
-
if
|
|
403
|
+
if OS == OSType.WINDOWS:
|
|
384
404
|
self._toggle_background_task_windows(enabled)
|
|
385
405
|
else:
|
|
386
406
|
# TODO: implement toggle for cron jobs
|
|
@@ -388,7 +408,6 @@ class Scraper:
|
|
|
388
408
|
|
|
389
409
|
|
|
390
410
|
if __name__ == "__main__":
|
|
391
|
-
# If this file is run as a script, create a Scraper instance and run the
|
|
392
|
-
# scrape_prices method.
|
|
393
411
|
scraper = Scraper()
|
|
412
|
+
scraper.console.print(f"[bold yellow]{BANNER}\n{AUTHOR_STRING}\n")
|
|
394
413
|
scraper.scrape_prices()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cs2tracker
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.6
|
|
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,29 +40,35 @@ Dynamic: license-file
|
|
|
40
40
|
|
|
41
41
|
### Prerequisites
|
|
42
42
|
|
|
43
|
-
-
|
|
44
|
-
-
|
|
43
|
+
- Download and install the latest versions of [Python](https://www.python.org/downloads/) and [Pip](https://pypi.org/project/pip/). (Required for Linux)
|
|
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
|
-
|
|
48
|
+
#### Windows Executable *(no color support)*
|
|
49
|
+
|
|
50
|
+
- Simply [download the latest executable](https://github.com/ashiven/cs2tracker/releases/latest/download/cs2tracker-windows.zip) and run it.
|
|
51
|
+
|
|
52
|
+
#### Install via Pip
|
|
53
|
+
|
|
54
|
+
1. Install the program:
|
|
49
55
|
|
|
50
56
|
```bash
|
|
51
|
-
pip install
|
|
57
|
+
pip install cs2tracker
|
|
52
58
|
```
|
|
53
59
|
|
|
54
|
-
2.
|
|
60
|
+
2. Run it:
|
|
55
61
|
```bash
|
|
56
62
|
cs2tracker
|
|
57
63
|
```
|
|
58
64
|
|
|
59
65
|
### Options
|
|
60
66
|
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
67
|
+
- `Run!` to gather the current market prices of your items and calculate the total amount in USD and EUR.
|
|
68
|
+
- `Edit Config` to change the specific numbers of each item you own and then save the config file.
|
|
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 Calculation` 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
|
+
- If you want to prevent your requests from being rate limited by the steamcommunity server, register for an API key on [Crawlbase](crawlbase.com) and enter it into the `API_Key` field in the config file. This will route every request through a different proxy server.
|
|
66
72
|
|
|
67
73
|
---
|
|
68
74
|
|
|
@@ -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=CPOcsx1R_s9lB3K-XQvmbXItD2EvuBASo_a4U-9_vJ0,511
|
|
4
|
+
cs2tracker/application.py,sha256=fuErv6Xit1iZpdjRhcjPqR1EZ8Nw4Yqtg3m8y9V3_vY,7363
|
|
5
|
+
cs2tracker/constants.py,sha256=1rI7GfaEVyPjzX3GLMGUCNkwSJLI0jWmW10wJj2JJME,29042
|
|
6
|
+
cs2tracker/main.py,sha256=-gw0n4Y2kpWyFrRGuK4ZHGTiCcEIlDUDKQGS4tK6gbc,833
|
|
7
|
+
cs2tracker/padded_console.py,sha256=lPEa34p-8LTmTbpf-2S5uYPaA2UmsIOPq2_UoVhMRgU,674
|
|
8
|
+
cs2tracker/scraper.py,sha256=RM7wxZpqawS6opb76zNPU2s1rxNHdDslJlW0NpDRiuQ,16206
|
|
9
|
+
cs2tracker/data/config.ini,sha256=5LUUn1ee5nt8C_ifHxROUsxbT9aSezVqQ5641gkov-I,4945
|
|
10
|
+
cs2tracker/data/output.csv,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
cs2tracker-2.1.6.dist-info/licenses/LICENSE.md,sha256=G5wqQ_8KGA808kVuF-Fpu_Yhteg8K_5ux9n2v8eQK7s,1069
|
|
12
|
+
cs2tracker-2.1.6.dist-info/METADATA,sha256=2GCEnxRYH6ShZzM2q7a1Uu0kWZy754lWyEr_DvJ44gA,3141
|
|
13
|
+
cs2tracker-2.1.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
14
|
+
cs2tracker-2.1.6.dist-info/entry_points.txt,sha256=K8IwDIkg8QztSB9g9c89B9jR_2pG4QyJGrNs4z5RcZw,63
|
|
15
|
+
cs2tracker-2.1.6.dist-info/top_level.txt,sha256=2HB4xDDOxaU5BDc_yvdi9UlYLgL768n8aR-hRhFM6VQ,11
|
|
16
|
+
cs2tracker-2.1.6.dist-info/RECORD,,
|
|
@@ -1,14 +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=cuCBChX_WW6rxX7DfFGzi-EJBf76bHcqGsjRlHgeMvg,511
|
|
4
|
-
cs2tracker/application.py,sha256=CYuvEV2PlAKQ0MD_9vLViTonzspQFWJBGN6rzAOpAQY,4212
|
|
5
|
-
cs2tracker/constants.py,sha256=VG4QBedqHT9kjehWU-Uop7MNlD1VuERgL_VA4oN3obc,15127
|
|
6
|
-
cs2tracker/main.py,sha256=YmWXza0lmDDvLbOWzkJ6n0B1c-tq7Ub-IpwXSeIoKuQ,1309
|
|
7
|
-
cs2tracker/scraper.py,sha256=XoRtTPwN2Lxzqqghvcp3TOe9VdRge7Y_JTGOOJJyd3g,15457
|
|
8
|
-
cs2tracker/data/config.ini,sha256=LbdwEMFlgD8ubuEvGhYZdPtYsWhlho3nX3SLWi4T7Kg,2637
|
|
9
|
-
cs2tracker-2.1.4.dist-info/licenses/LICENSE.md,sha256=G5wqQ_8KGA808kVuF-Fpu_Yhteg8K_5ux9n2v8eQK7s,1069
|
|
10
|
-
cs2tracker-2.1.4.dist-info/METADATA,sha256=CfTvVmloYwmxtvnu0UUeOY6CzO7W3gsBNjGdMFxkBbk,2954
|
|
11
|
-
cs2tracker-2.1.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
-
cs2tracker-2.1.4.dist-info/entry_points.txt,sha256=K8IwDIkg8QztSB9g9c89B9jR_2pG4QyJGrNs4z5RcZw,63
|
|
13
|
-
cs2tracker-2.1.4.dist-info/top_level.txt,sha256=2HB4xDDOxaU5BDc_yvdi9UlYLgL768n8aR-hRhFM6VQ,11
|
|
14
|
-
cs2tracker-2.1.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|