cs2tracker 2.1.14__py3-none-any.whl → 2.1.16__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 CHANGED
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '2.1.14'
21
- __version_tuple__ = version_tuple = (2, 1, 14)
20
+ __version__ = version = '2.1.16'
21
+ __version_tuple__ = version_tuple = (2, 1, 16)
@@ -1,3 +0,0 @@
1
- from cs2tracker.app.application import ( # noqa: F401 # pylint:disable=unused-import
2
- Application,
3
- )
@@ -3,30 +3,32 @@ import tkinter as tk
3
3
  from shutil import copy
4
4
  from tkinter import messagebox, ttk
5
5
  from tkinter.filedialog import askopenfilename, asksaveasfile
6
- from typing import cast
7
6
 
8
- import matplotlib.pyplot as plt
9
7
  import sv_ttk
10
- from matplotlib.axes import Axes
11
- from matplotlib.dates import DateFormatter
12
8
 
13
9
  from cs2tracker.app.editor_frame import ConfigEditorFrame
10
+ from cs2tracker.app.history_frame import PriceHistoryFrame
14
11
  from cs2tracker.app.scraper_frame import ScraperFrame
12
+ from cs2tracker.config import get_config
15
13
  from cs2tracker.constants import ICON_FILE, OS, OUTPUT_FILE, OSType
16
- from cs2tracker.scraper import BackgroundTask, Scraper
17
- from cs2tracker.util import PriceLogs
18
- from cs2tracker.util.validated_config import get_config
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
19
 
20
20
  APPLICATION_NAME = "CS2Tracker"
21
21
  WINDOW_SIZE = "630x335"
22
22
  DARK_THEME = True
23
23
 
24
- SCRAPER_WINDOW_TITLE = "CS2Tracker Scraper"
24
+ SCRAPER_WINDOW_TITLE = "Price Overview"
25
25
  SCRAPER_WINDOW_SIZE = "900x750"
26
26
 
27
27
  CONFIG_EDITOR_TITLE = "Config Editor"
28
- CONFIG_EDITOR_SIZE = "900x750"
28
+ CONFIG_EDITOR_SIZE = "850x750"
29
29
 
30
+ PRICE_HISTORY_TITLE = "Price History"
31
+ PRICE_HISTORY_SIZE = "900x700"
30
32
 
31
33
  config = get_config()
32
34
 
@@ -44,13 +46,16 @@ class Application:
44
46
  else:
45
47
  sv_ttk.use_light_theme()
46
48
 
49
+ fix_sv_ttk(ttk.Style())
50
+
47
51
  window.mainloop()
48
52
 
49
53
  def _configure_window(self):
50
54
  """Configure the main application window."""
51
55
  window = tk.Tk()
52
56
  window.title(APPLICATION_NAME)
53
- window.geometry(WINDOW_SIZE)
57
+ window.geometry(centered(window, WINDOW_SIZE))
58
+ window.minsize(*size_info(WINDOW_SIZE))
54
59
 
55
60
  if OS == OSType.WINDOWS:
56
61
  app_id = "cs2tracker.unique.id"
@@ -80,9 +85,9 @@ class MainFrame(ttk.Frame):
80
85
  self.rowconfigure(0, weight=1)
81
86
 
82
87
  self._configure_button_frame()
83
- self.button_frame.grid(row=0, column=0, padx=10, pady=(7, 20), sticky="nsew")
84
- self._configure_checkbox_frame()
85
- self.checkbox_frame.grid(row=0, column=1, padx=10, pady=(0, 20), sticky="nsew")
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")
86
91
 
87
92
  def _add_button(self, text, command, row):
88
93
  """Create and style a button for the button frame."""
@@ -97,7 +102,7 @@ class MainFrame(ttk.Frame):
97
102
 
98
103
  self._add_button("Run!", self.scrape_prices, 0)
99
104
  self._add_button("Edit Config", self._edit_config, 1)
100
- self._add_button("Show History", self._draw_plot, 2)
105
+ self._add_button("Show History", self._show_history, 2)
101
106
  self._add_button("Export History", self._export_log_file, 3)
102
107
  self._add_button("Import History", self._import_log_file, 4)
103
108
 
@@ -107,7 +112,7 @@ class MainFrame(ttk.Frame):
107
112
  """Create and style a checkbox for the checkbox frame."""
108
113
  grid_pos = {"row": row, "column": 0, "sticky": "w", "padx": (10, 0), "pady": 5}
109
114
  checkbox = ttk.Checkbutton(
110
- self.checkbox_frame,
115
+ self.settings_frame,
111
116
  text=text,
112
117
  variable=variable,
113
118
  command=command,
@@ -115,9 +120,10 @@ class MainFrame(ttk.Frame):
115
120
  )
116
121
  checkbox.grid(**grid_pos)
117
122
 
118
- def _configure_checkbox_frame(self):
119
- """Configure the checkbox frame for background tasks and settings."""
120
- self.checkbox_frame = ttk.LabelFrame(self, text="Settings", padding=15)
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)
121
127
 
122
128
  self.background_checkbox_value = tk.BooleanVar(value=BackgroundTask.identify())
123
129
  self._add_checkbox(
@@ -127,9 +133,7 @@ class MainFrame(ttk.Frame):
127
133
  0,
128
134
  )
129
135
 
130
- self.discord_webhook_checkbox_value = tk.BooleanVar(
131
- value=config.getboolean("App Settings", "discord_notifications", fallback=False)
132
- )
136
+ self.discord_webhook_checkbox_value = tk.BooleanVar(value=config.discord_notifications)
133
137
  self._add_checkbox(
134
138
  "Discord Notifications",
135
139
  self.discord_webhook_checkbox_value,
@@ -139,9 +143,7 @@ class MainFrame(ttk.Frame):
139
143
  1,
140
144
  )
141
145
 
142
- self.use_proxy_checkbox_value = tk.BooleanVar(
143
- value=config.getboolean("App Settings", "use_proxy", fallback=False)
144
- )
146
+ self.use_proxy_checkbox_value = tk.BooleanVar(value=config.use_proxy)
145
147
  self._add_checkbox(
146
148
  "Proxy Requests",
147
149
  self.use_proxy_checkbox_value,
@@ -152,14 +154,36 @@ class MainFrame(ttk.Frame):
152
154
  )
153
155
 
154
156
  self.dark_theme_checkbox_value = tk.BooleanVar(value=DARK_THEME)
155
- self._add_checkbox("Dark Theme", self.dark_theme_checkbox_value, sv_ttk.toggle_theme, 3)
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
+ )
156
179
 
157
180
  def scrape_prices(self):
158
181
  """Scrape prices from the configured sources, print the total, and save the
159
182
  results to a file.
160
183
  """
161
184
  scraper_window = tk.Toplevel(self.parent)
162
- scraper_window.geometry(SCRAPER_WINDOW_SIZE)
185
+ scraper_window.geometry(centered(scraper_window, SCRAPER_WINDOW_SIZE))
186
+ scraper_window.minsize(*size_info(SCRAPER_WINDOW_SIZE))
163
187
  scraper_window.title(SCRAPER_WINDOW_TITLE)
164
188
 
165
189
  run_frame = ScraperFrame(
@@ -174,31 +198,31 @@ class MainFrame(ttk.Frame):
174
198
  def _edit_config(self):
175
199
  """Open a new window with a config editor GUI."""
176
200
  config_editor_window = tk.Toplevel(self.parent)
177
- config_editor_window.geometry(CONFIG_EDITOR_SIZE)
201
+ config_editor_window.geometry(centered(config_editor_window, CONFIG_EDITOR_SIZE))
202
+ config_editor_window.minsize(*size_info(CONFIG_EDITOR_SIZE))
178
203
  config_editor_window.title(CONFIG_EDITOR_TITLE)
179
204
 
180
205
  editor_frame = ConfigEditorFrame(config_editor_window)
181
206
  editor_frame.pack(expand=True, fill="both")
182
207
 
183
- def _draw_plot(self):
184
- """Draw a plot of the scraped prices over time."""
185
- dates, usd_prices, eur_prices = PriceLogs.read()
186
-
187
- fig, ax_raw = plt.subplots(figsize=(10, 8), num="CS2Tracker Price History")
188
- fig.suptitle("CS2Tracker Price History", fontsize=16)
189
- fig.autofmt_xdate()
208
+ def _show_history(self):
209
+ """Show a chart consisting of past calculations."""
210
+ if PriceLogs.empty():
211
+ return
190
212
 
191
- ax = cast(Axes, ax_raw)
192
- ax.plot(dates, usd_prices, label="Dollars")
193
- ax.plot(dates, eur_prices, label="Euros")
194
- ax.legend()
195
- date_formatter = DateFormatter("%Y-%m-%d")
196
- ax.xaxis.set_major_formatter(date_formatter)
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)
197
217
 
198
- plt.show()
218
+ history_frame = PriceHistoryFrame(price_history_window)
219
+ history_frame.pack(expand=True, fill="both")
199
220
 
200
221
  def _export_log_file(self):
201
222
  """Lets the user export the log file to a different location."""
223
+ if PriceLogs.empty():
224
+ return
225
+
202
226
  export_path = asksaveasfile(
203
227
  title="Export Log File",
204
228
  defaultextension=".csv",
@@ -224,7 +248,7 @@ class MainFrame(ttk.Frame):
224
248
 
225
249
  def _toggle_use_proxy(self, enabled: bool):
226
250
  """Toggle whether the scraper should use proxy servers for requests."""
227
- proxy_api_key = config.get("User Settings", "proxy_api_key", fallback=None)
251
+ proxy_api_key = config.proxy_api_key
228
252
  if not proxy_api_key and enabled:
229
253
  messagebox.showerror(
230
254
  "Config Error",
@@ -233,12 +257,12 @@ class MainFrame(ttk.Frame):
233
257
  )
234
258
  return False
235
259
 
236
- config.toggle_use_proxy(enabled)
260
+ config.toggle_app_option("use_proxy", enabled)
237
261
  return True
238
262
 
239
263
  def _toggle_discord_webhook(self, enabled: bool):
240
264
  """Toggle whether the scraper should send notifications to a Discord webhook."""
241
- discord_webhook_url = config.get("User Settings", "discord_webhook_url", fallback=None)
265
+ discord_webhook_url = config.discord_webhook_url
242
266
  if not discord_webhook_url and enabled:
243
267
  messagebox.showerror(
244
268
  "Config Error",
@@ -247,5 +271,13 @@ class MainFrame(ttk.Frame):
247
271
  )
248
272
  return False
249
273
 
250
- config.toggle_discord_webhook(enabled)
274
+ config.toggle_app_option("discord_webhook", enabled)
251
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())