cs2tracker 2.1.13__tar.gz → 2.1.15__tar.gz
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-2.1.13 → cs2tracker-2.1.15}/.isort.cfg +1 -1
- cs2tracker-2.1.15/.pre-commit-config.yaml +30 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/PKG-INFO +6 -6
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/README.md +4 -5
- cs2tracker-2.1.15/assets/demo.gif +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker/_version.py +2 -2
- cs2tracker-2.1.15/cs2tracker/app/app.py +283 -0
- cs2tracker-2.1.15/cs2tracker/app/editor_frame.py +670 -0
- cs2tracker-2.1.15/cs2tracker/app/history_frame.py +61 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker/app/scraper_frame.py +34 -11
- cs2tracker-2.1.15/cs2tracker/config.py +263 -0
- cs2tracker-2.1.15/cs2tracker/constants.py +136 -0
- cs2tracker-2.1.15/cs2tracker/data/config.ini +207 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker/data/convert_inventory.js +108 -28
- cs2tracker-2.1.15/cs2tracker/data/get_inventory.js +212 -0
- cs2tracker-2.1.15/cs2tracker/data/output.csv +0 -0
- cs2tracker-2.1.15/cs2tracker/logs.py +143 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker/main.py +4 -19
- cs2tracker-2.1.15/cs2tracker/scraper/__init__.py +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker/scraper/background_task.py +1 -1
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker/scraper/discord_notifier.py +34 -32
- cs2tracker-2.1.15/cs2tracker/scraper/parser.py +189 -0
- cs2tracker-2.1.15/cs2tracker/scraper/scraper.py +300 -0
- cs2tracker-2.1.15/cs2tracker/util/__init__.py +0 -0
- cs2tracker-2.1.15/cs2tracker/util/currency_conversion.py +84 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker/util/padded_console.py +24 -0
- cs2tracker-2.1.15/cs2tracker/util/tkinter.py +55 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker.egg-info/PKG-INFO +6 -6
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker.egg-info/SOURCES.txt +8 -3
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker.egg-info/requires.txt +1 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/requirements.txt +1 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/setup.cfg +1 -0
- cs2tracker-2.1.13/.pre-commit-config.yaml +0 -30
- cs2tracker-2.1.13/cs2tracker/app/__init__.py +0 -3
- cs2tracker-2.1.13/cs2tracker/app/application.py +0 -255
- cs2tracker-2.1.13/cs2tracker/app/editor_frame.py +0 -474
- cs2tracker-2.1.13/cs2tracker/constants.py +0 -399
- cs2tracker-2.1.13/cs2tracker/data/config.ini +0 -204
- cs2tracker-2.1.13/cs2tracker/data/get_inventory.js +0 -148
- cs2tracker-2.1.13/cs2tracker/scraper/__init__.py +0 -9
- cs2tracker-2.1.13/cs2tracker/scraper/scraper.py +0 -380
- cs2tracker-2.1.13/cs2tracker/util/__init__.py +0 -9
- cs2tracker-2.1.13/cs2tracker/util/price_logs.py +0 -100
- cs2tracker-2.1.13/cs2tracker/util/validated_config.py +0 -164
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/.flake8 +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/.gitignore +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/.pylintrc +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/LICENSE +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/MANIFEST.in +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/assets/icon.png +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker/__init__.py +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker/__main__.py +0 -0
- /cs2tracker-2.1.13/cs2tracker/data/output.csv → /cs2tracker-2.1.15/cs2tracker/app/__init__.py +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker.egg-info/dependency_links.txt +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker.egg-info/entry_points.txt +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/cs2tracker.egg-info/top_level.txt +0 -0
- {cs2tracker-2.1.13 → cs2tracker-2.1.15}/pyproject.toml +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
[settings]
|
|
2
|
-
known_third_party = bs4,currency_converter,matplotlib,nodejs,requests,rich,sv_ttk,tenacity,tksheet,ttk_text,urllib3
|
|
2
|
+
known_third_party = bs4,currency_converter,matplotlib,nodejs,requests,requests_cache,rich,sv_ttk,tenacity,tksheet,ttk_text,urllib3
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v5.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: check-yaml
|
|
6
|
+
- id: end-of-file-fixer
|
|
7
|
+
- id: trailing-whitespace
|
|
8
|
+
- repo: https://github.com/asottile/seed-isort-config
|
|
9
|
+
rev: v2.2.0
|
|
10
|
+
hooks:
|
|
11
|
+
- id: seed-isort-config
|
|
12
|
+
- repo: https://github.com/ambv/black
|
|
13
|
+
rev: 25.1.0
|
|
14
|
+
hooks:
|
|
15
|
+
- id: black
|
|
16
|
+
- repo: https://github.com/PyCQA/flake8
|
|
17
|
+
rev: 7.3.0
|
|
18
|
+
hooks:
|
|
19
|
+
- id: flake8
|
|
20
|
+
- repo: https://github.com/timothycrosley/isort
|
|
21
|
+
rev: 6.0.1
|
|
22
|
+
hooks:
|
|
23
|
+
- id: isort
|
|
24
|
+
args: ["--profile=black"]
|
|
25
|
+
- repo: https://github.com/PyCQA/docformatter
|
|
26
|
+
rev: v1.7.6
|
|
27
|
+
hooks:
|
|
28
|
+
- id: docformatter
|
|
29
|
+
additional_dependencies: [tomli]
|
|
30
|
+
args: [--in-place]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cs2tracker
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.15
|
|
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
|
|
@@ -23,6 +23,7 @@ Requires-Dist: sv_ttk==2.6.1
|
|
|
23
23
|
Requires-Dist: tksheet==7.5.12
|
|
24
24
|
Requires-Dist: nodejs-bin==18.4.0a4
|
|
25
25
|
Requires-Dist: ttk-text==0.2.0
|
|
26
|
+
Requires-Dist: requests-cache==1.2.1
|
|
26
27
|
Dynamic: license-file
|
|
27
28
|
|
|
28
29
|
<p align="center">
|
|
@@ -40,9 +41,8 @@ Dynamic: license-file
|
|
|
40
41
|
[](https://badge.fury.io/py/cs2tracker)
|
|
41
42
|
[](https://github.com/ashiven/cs2tracker/issues)
|
|
42
43
|
[](https://github.com/ashiven/cs2tracker/pulls)
|
|
43
|
-

|
|
44
44
|
|
|
45
|
-
<img src="
|
|
45
|
+
<img src="./assets/demo.gif"/>
|
|
46
46
|
</div>
|
|
47
47
|
|
|
48
48
|
## Table of Contents
|
|
@@ -60,9 +60,9 @@ Dynamic: license-file
|
|
|
60
60
|
## Features
|
|
61
61
|
|
|
62
62
|
- ⚡ Rapidly import your Storage Units
|
|
63
|
-
- 🔍 Track
|
|
63
|
+
- 🔍 Track prices on Steam, Buff163, Youpin898
|
|
64
64
|
- 📈 View investment price history
|
|
65
|
-
- 🧾 Export/Import
|
|
65
|
+
- 🧾 Export/Import history data
|
|
66
66
|
- 📤 Discord notifications on updates
|
|
67
67
|
- 📅 Daily background calculations
|
|
68
68
|
- 🛡️ Proxy support to avoid rate limits
|
|
@@ -106,7 +106,7 @@ Dynamic: license-file
|
|
|
106
106
|
## Configuration
|
|
107
107
|
|
|
108
108
|
You can configure the app settings via the **Edit Config** option.
|
|
109
|
-
This will open the config editor where you can change any setting by
|
|
109
|
+
This will open the config editor where you can change any setting by double clicking on it or navigating to it with the arrow keys and hitting enter. On top of that, the config editor allows you to:
|
|
110
110
|
|
|
111
111
|
- Automatically import items from your Storage Units
|
|
112
112
|
- Manually Specify the number of items you own
|
|
@@ -13,9 +13,8 @@
|
|
|
13
13
|
[](https://badge.fury.io/py/cs2tracker)
|
|
14
14
|
[](https://github.com/ashiven/cs2tracker/issues)
|
|
15
15
|
[](https://github.com/ashiven/cs2tracker/pulls)
|
|
16
|
-

|
|
17
16
|
|
|
18
|
-
<img src="
|
|
17
|
+
<img src="./assets/demo.gif"/>
|
|
19
18
|
</div>
|
|
20
19
|
|
|
21
20
|
## Table of Contents
|
|
@@ -33,9 +32,9 @@
|
|
|
33
32
|
## Features
|
|
34
33
|
|
|
35
34
|
- ⚡ Rapidly import your Storage Units
|
|
36
|
-
- 🔍 Track
|
|
35
|
+
- 🔍 Track prices on Steam, Buff163, Youpin898
|
|
37
36
|
- 📈 View investment price history
|
|
38
|
-
- 🧾 Export/Import
|
|
37
|
+
- 🧾 Export/Import history data
|
|
39
38
|
- 📤 Discord notifications on updates
|
|
40
39
|
- 📅 Daily background calculations
|
|
41
40
|
- 🛡️ Proxy support to avoid rate limits
|
|
@@ -79,7 +78,7 @@
|
|
|
79
78
|
## Configuration
|
|
80
79
|
|
|
81
80
|
You can configure the app settings via the **Edit Config** option.
|
|
82
|
-
This will open the config editor where you can change any setting by
|
|
81
|
+
This will open the config editor where you can change any setting by double clicking on it or navigating to it with the arrow keys and hitting enter. On top of that, the config editor allows you to:
|
|
83
82
|
|
|
84
83
|
- Automatically import items from your Storage Units
|
|
85
84
|
- Manually Specify the number of items you own
|
|
Binary file
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import ctypes
|
|
2
|
+
import tkinter as tk
|
|
3
|
+
from shutil import copy
|
|
4
|
+
from tkinter import messagebox, ttk
|
|
5
|
+
from tkinter.filedialog import askopenfilename, asksaveasfile
|
|
6
|
+
|
|
7
|
+
import sv_ttk
|
|
8
|
+
|
|
9
|
+
from cs2tracker.app.editor_frame import ConfigEditorFrame
|
|
10
|
+
from cs2tracker.app.history_frame import PriceHistoryFrame
|
|
11
|
+
from cs2tracker.app.scraper_frame import ScraperFrame
|
|
12
|
+
from cs2tracker.config import get_config
|
|
13
|
+
from cs2tracker.constants import ICON_FILE, OS, OUTPUT_FILE, OSType
|
|
14
|
+
from cs2tracker.logs import PriceLogs
|
|
15
|
+
from cs2tracker.scraper.background_task import BackgroundTask
|
|
16
|
+
from cs2tracker.scraper.scraper import Scraper
|
|
17
|
+
from cs2tracker.util.currency_conversion import CURRENCY_SYMBOLS
|
|
18
|
+
from cs2tracker.util.tkinter import centered, fix_sv_ttk, size_info
|
|
19
|
+
|
|
20
|
+
APPLICATION_NAME = "CS2Tracker"
|
|
21
|
+
WINDOW_SIZE = "630x335"
|
|
22
|
+
DARK_THEME = True
|
|
23
|
+
|
|
24
|
+
SCRAPER_WINDOW_TITLE = "Price Overview"
|
|
25
|
+
SCRAPER_WINDOW_SIZE = "900x750"
|
|
26
|
+
|
|
27
|
+
CONFIG_EDITOR_TITLE = "Config Editor"
|
|
28
|
+
CONFIG_EDITOR_SIZE = "850x750"
|
|
29
|
+
|
|
30
|
+
PRICE_HISTORY_TITLE = "Price History"
|
|
31
|
+
PRICE_HISTORY_SIZE = "900x700"
|
|
32
|
+
|
|
33
|
+
config = get_config()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class Application:
|
|
37
|
+
def __init__(self):
|
|
38
|
+
self.scraper = Scraper()
|
|
39
|
+
|
|
40
|
+
def run(self):
|
|
41
|
+
"""Run the main application window."""
|
|
42
|
+
window = self._configure_window()
|
|
43
|
+
|
|
44
|
+
if DARK_THEME:
|
|
45
|
+
sv_ttk.use_dark_theme()
|
|
46
|
+
else:
|
|
47
|
+
sv_ttk.use_light_theme()
|
|
48
|
+
|
|
49
|
+
fix_sv_ttk(ttk.Style())
|
|
50
|
+
|
|
51
|
+
window.mainloop()
|
|
52
|
+
|
|
53
|
+
def _configure_window(self):
|
|
54
|
+
"""Configure the main application window."""
|
|
55
|
+
window = tk.Tk()
|
|
56
|
+
window.title(APPLICATION_NAME)
|
|
57
|
+
window.geometry(centered(window, WINDOW_SIZE))
|
|
58
|
+
window.minsize(*size_info(WINDOW_SIZE))
|
|
59
|
+
|
|
60
|
+
if OS == OSType.WINDOWS:
|
|
61
|
+
app_id = "cs2tracker.unique.id"
|
|
62
|
+
ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(app_id)
|
|
63
|
+
|
|
64
|
+
icon = tk.PhotoImage(file=ICON_FILE)
|
|
65
|
+
window.wm_iconphoto(True, icon)
|
|
66
|
+
|
|
67
|
+
main_frame = MainFrame(window, self.scraper)
|
|
68
|
+
main_frame.pack(expand=True, fill="both")
|
|
69
|
+
|
|
70
|
+
return window
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class MainFrame(ttk.Frame):
|
|
74
|
+
# pylint: disable=too-many-instance-attributes,attribute-defined-outside-init
|
|
75
|
+
def __init__(self, parent, scraper):
|
|
76
|
+
super().__init__(parent, padding=15)
|
|
77
|
+
self.parent = parent
|
|
78
|
+
self.scraper = scraper
|
|
79
|
+
self._add_widgets()
|
|
80
|
+
|
|
81
|
+
def _add_widgets(self):
|
|
82
|
+
"""Add widgets to the main frame."""
|
|
83
|
+
self.columnconfigure(0, weight=1)
|
|
84
|
+
self.columnconfigure(1, weight=1)
|
|
85
|
+
self.rowconfigure(0, weight=1)
|
|
86
|
+
|
|
87
|
+
self._configure_button_frame()
|
|
88
|
+
self.button_frame.grid(row=0, column=0, padx=10, pady=(0, 20), sticky="nsew")
|
|
89
|
+
self._configure_settings_frame()
|
|
90
|
+
self.settings_frame.grid(row=0, column=1, padx=10, pady=(0, 20), sticky="nsew")
|
|
91
|
+
|
|
92
|
+
def _add_button(self, text, command, row):
|
|
93
|
+
"""Create and style a button for the button frame."""
|
|
94
|
+
grid_pos = {"row": row, "column": 0, "sticky": "ew", "padx": 10, "pady": 10}
|
|
95
|
+
button = ttk.Button(self.button_frame, text=text, command=command)
|
|
96
|
+
button.grid(**grid_pos)
|
|
97
|
+
|
|
98
|
+
def _configure_button_frame(self):
|
|
99
|
+
"""Configure the button frame of the application main frame."""
|
|
100
|
+
self.button_frame = ttk.Frame(self, style="Card.TFrame", padding=15)
|
|
101
|
+
self.button_frame.columnconfigure(0, weight=1)
|
|
102
|
+
|
|
103
|
+
self._add_button("Run!", self.scrape_prices, 0)
|
|
104
|
+
self._add_button("Edit Config", self._edit_config, 1)
|
|
105
|
+
self._add_button("Show History", self._show_history, 2)
|
|
106
|
+
self._add_button("Export History", self._export_log_file, 3)
|
|
107
|
+
self._add_button("Import History", self._import_log_file, 4)
|
|
108
|
+
|
|
109
|
+
def _add_checkbox(
|
|
110
|
+
self, text, variable, command, row
|
|
111
|
+
): # pylint: disable=too-many-arguments,too-many-positional-arguments,attribute-defined-outside-init
|
|
112
|
+
"""Create and style a checkbox for the checkbox frame."""
|
|
113
|
+
grid_pos = {"row": row, "column": 0, "sticky": "w", "padx": (10, 0), "pady": 5}
|
|
114
|
+
checkbox = ttk.Checkbutton(
|
|
115
|
+
self.settings_frame,
|
|
116
|
+
text=text,
|
|
117
|
+
variable=variable,
|
|
118
|
+
command=command,
|
|
119
|
+
style="Switch.TCheckbutton",
|
|
120
|
+
)
|
|
121
|
+
checkbox.grid(**grid_pos)
|
|
122
|
+
|
|
123
|
+
def _configure_settings_frame(self):
|
|
124
|
+
"""Configure the settings frame for background tasks and other settings."""
|
|
125
|
+
self.settings_frame = ttk.LabelFrame(self, text="Settings", padding=15)
|
|
126
|
+
self.settings_frame.columnconfigure(0, weight=1)
|
|
127
|
+
|
|
128
|
+
self.background_checkbox_value = tk.BooleanVar(value=BackgroundTask.identify())
|
|
129
|
+
self._add_checkbox(
|
|
130
|
+
"Background Task",
|
|
131
|
+
self.background_checkbox_value,
|
|
132
|
+
lambda: self._toggle_background_task(self.background_checkbox_value.get()),
|
|
133
|
+
0,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
self.discord_webhook_checkbox_value = tk.BooleanVar(value=config.discord_notifications)
|
|
137
|
+
self._add_checkbox(
|
|
138
|
+
"Discord Notifications",
|
|
139
|
+
self.discord_webhook_checkbox_value,
|
|
140
|
+
lambda: self.discord_webhook_checkbox_value.set(
|
|
141
|
+
self._toggle_discord_webhook(self.discord_webhook_checkbox_value.get())
|
|
142
|
+
),
|
|
143
|
+
1,
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
self.use_proxy_checkbox_value = tk.BooleanVar(value=config.use_proxy)
|
|
147
|
+
self._add_checkbox(
|
|
148
|
+
"Proxy Requests",
|
|
149
|
+
self.use_proxy_checkbox_value,
|
|
150
|
+
lambda: self.use_proxy_checkbox_value.set(
|
|
151
|
+
self._toggle_use_proxy(self.use_proxy_checkbox_value.get())
|
|
152
|
+
),
|
|
153
|
+
2,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
self.dark_theme_checkbox_value = tk.BooleanVar(value=DARK_THEME)
|
|
157
|
+
self._add_checkbox("Dark Theme", self.dark_theme_checkbox_value, self._toggle_theme, 3)
|
|
158
|
+
|
|
159
|
+
self.currency_selection_label = ttk.Label(self.settings_frame, text="Currency:")
|
|
160
|
+
self.currency_selection_label.grid(row=4, column=0, sticky="w", padx=(20, 0), pady=5)
|
|
161
|
+
self.currency_selection = ttk.Combobox(
|
|
162
|
+
self.settings_frame,
|
|
163
|
+
state="readonly",
|
|
164
|
+
values=list(CURRENCY_SYMBOLS),
|
|
165
|
+
postcommand=self.parent.focus_set,
|
|
166
|
+
)
|
|
167
|
+
self.currency_selection.set(config.conversion_currency)
|
|
168
|
+
self.currency_selection.grid(row=5, column=0, sticky="w", padx=(20, 0), pady=5)
|
|
169
|
+
|
|
170
|
+
def on_currency_change(_):
|
|
171
|
+
config.set_app_option("conversion_currency", self.currency_selection.get())
|
|
172
|
+
self.currency_selection.selection_clear()
|
|
173
|
+
self.parent.focus_set()
|
|
174
|
+
|
|
175
|
+
self.currency_selection.bind(
|
|
176
|
+
"<<ComboboxSelected>>",
|
|
177
|
+
on_currency_change,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
def scrape_prices(self):
|
|
181
|
+
"""Scrape prices from the configured sources, print the total, and save the
|
|
182
|
+
results to a file.
|
|
183
|
+
"""
|
|
184
|
+
scraper_window = tk.Toplevel(self.parent)
|
|
185
|
+
scraper_window.geometry(centered(scraper_window, SCRAPER_WINDOW_SIZE))
|
|
186
|
+
scraper_window.minsize(*size_info(SCRAPER_WINDOW_SIZE))
|
|
187
|
+
scraper_window.title(SCRAPER_WINDOW_TITLE)
|
|
188
|
+
|
|
189
|
+
run_frame = ScraperFrame(
|
|
190
|
+
scraper_window,
|
|
191
|
+
self.scraper,
|
|
192
|
+
sheet_size=SCRAPER_WINDOW_SIZE,
|
|
193
|
+
dark_theme=self.dark_theme_checkbox_value.get(),
|
|
194
|
+
)
|
|
195
|
+
run_frame.pack(expand=True, fill="both")
|
|
196
|
+
run_frame.start()
|
|
197
|
+
|
|
198
|
+
def _edit_config(self):
|
|
199
|
+
"""Open a new window with a config editor GUI."""
|
|
200
|
+
config_editor_window = tk.Toplevel(self.parent)
|
|
201
|
+
config_editor_window.geometry(centered(config_editor_window, CONFIG_EDITOR_SIZE))
|
|
202
|
+
config_editor_window.minsize(*size_info(CONFIG_EDITOR_SIZE))
|
|
203
|
+
config_editor_window.title(CONFIG_EDITOR_TITLE)
|
|
204
|
+
|
|
205
|
+
editor_frame = ConfigEditorFrame(config_editor_window)
|
|
206
|
+
editor_frame.pack(expand=True, fill="both")
|
|
207
|
+
|
|
208
|
+
def _show_history(self):
|
|
209
|
+
"""Show a chart consisting of past calculations."""
|
|
210
|
+
if PriceLogs.empty():
|
|
211
|
+
return
|
|
212
|
+
|
|
213
|
+
price_history_window = tk.Toplevel(self.parent)
|
|
214
|
+
price_history_window.geometry(centered(price_history_window, PRICE_HISTORY_SIZE))
|
|
215
|
+
price_history_window.minsize(*size_info(PRICE_HISTORY_SIZE))
|
|
216
|
+
price_history_window.title(PRICE_HISTORY_TITLE)
|
|
217
|
+
|
|
218
|
+
history_frame = PriceHistoryFrame(price_history_window)
|
|
219
|
+
history_frame.pack(expand=True, fill="both")
|
|
220
|
+
|
|
221
|
+
def _export_log_file(self):
|
|
222
|
+
"""Lets the user export the log file to a different location."""
|
|
223
|
+
if PriceLogs.empty():
|
|
224
|
+
return
|
|
225
|
+
|
|
226
|
+
export_path = asksaveasfile(
|
|
227
|
+
title="Export Log File",
|
|
228
|
+
defaultextension=".csv",
|
|
229
|
+
filetypes=[("CSV File", "*.csv")],
|
|
230
|
+
)
|
|
231
|
+
if export_path:
|
|
232
|
+
copy(OUTPUT_FILE, export_path.name)
|
|
233
|
+
|
|
234
|
+
def _import_log_file(self):
|
|
235
|
+
"""Lets the user import a log file from a different location."""
|
|
236
|
+
import_path = askopenfilename(
|
|
237
|
+
title="Import Log File",
|
|
238
|
+
defaultextension=".csv",
|
|
239
|
+
filetypes=[("CSV files", "*.csv")],
|
|
240
|
+
)
|
|
241
|
+
if not PriceLogs.validate_file(import_path):
|
|
242
|
+
return
|
|
243
|
+
copy(import_path, OUTPUT_FILE)
|
|
244
|
+
|
|
245
|
+
def _toggle_background_task(self, enabled: bool):
|
|
246
|
+
"""Toggle whether a daily price calculation should run in the background."""
|
|
247
|
+
BackgroundTask.toggle(enabled)
|
|
248
|
+
|
|
249
|
+
def _toggle_use_proxy(self, enabled: bool):
|
|
250
|
+
"""Toggle whether the scraper should use proxy servers for requests."""
|
|
251
|
+
proxy_api_key = config.proxy_api_key
|
|
252
|
+
if not proxy_api_key and enabled:
|
|
253
|
+
messagebox.showerror(
|
|
254
|
+
"Config Error",
|
|
255
|
+
"You need to enter a valid crawlbase API key into the configuration to use this feature.",
|
|
256
|
+
parent=self.parent,
|
|
257
|
+
)
|
|
258
|
+
return False
|
|
259
|
+
|
|
260
|
+
config.toggle_app_option("use_proxy", enabled)
|
|
261
|
+
return True
|
|
262
|
+
|
|
263
|
+
def _toggle_discord_webhook(self, enabled: bool):
|
|
264
|
+
"""Toggle whether the scraper should send notifications to a Discord webhook."""
|
|
265
|
+
discord_webhook_url = config.discord_webhook_url
|
|
266
|
+
if not discord_webhook_url and enabled:
|
|
267
|
+
messagebox.showerror(
|
|
268
|
+
"Config Error",
|
|
269
|
+
"You need to enter a valid Discord webhook URL into the configuration to use this feature.",
|
|
270
|
+
parent=self.parent,
|
|
271
|
+
)
|
|
272
|
+
return False
|
|
273
|
+
|
|
274
|
+
config.toggle_app_option("discord_webhook", enabled)
|
|
275
|
+
return True
|
|
276
|
+
|
|
277
|
+
def _toggle_theme(self):
|
|
278
|
+
"""Toggle the theme of the application."""
|
|
279
|
+
if self.dark_theme_checkbox_value.get():
|
|
280
|
+
sv_ttk.use_dark_theme()
|
|
281
|
+
else:
|
|
282
|
+
sv_ttk.use_light_theme()
|
|
283
|
+
fix_sv_ttk(ttk.Style())
|