cs2tracker 2.1.14__tar.gz → 2.1.16__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.

Files changed (50) hide show
  1. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/.gitignore +1 -0
  2. cs2tracker-2.1.16/.pre-commit-config.yaml +30 -0
  3. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/PKG-INFO +15 -16
  4. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/README.md +14 -15
  5. cs2tracker-2.1.16/assets/demo.gif +0 -0
  6. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/_version.py +2 -2
  7. cs2tracker-2.1.14/cs2tracker/app/application.py → cs2tracker-2.1.16/cs2tracker/app/app.py +77 -45
  8. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/app/editor_frame.py +223 -108
  9. cs2tracker-2.1.16/cs2tracker/app/history_frame.py +61 -0
  10. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/app/scraper_frame.py +13 -7
  11. cs2tracker-2.1.14/cs2tracker/util/validated_config.py → cs2tracker-2.1.16/cs2tracker/config.py +97 -52
  12. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/constants.py +20 -3
  13. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/data/config.ini +24 -21
  14. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/data/convert_inventory.js +108 -28
  15. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/data/get_inventory.js +34 -13
  16. cs2tracker-2.1.16/cs2tracker/data/output.csv +0 -0
  17. cs2tracker-2.1.16/cs2tracker/logs.py +143 -0
  18. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/main.py +3 -3
  19. cs2tracker-2.1.16/cs2tracker/scraper/__init__.py +0 -0
  20. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/scraper/background_task.py +80 -6
  21. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/scraper/discord_notifier.py +34 -32
  22. cs2tracker-2.1.14/cs2tracker/scraper/parsers.py → cs2tracker-2.1.16/cs2tracker/scraper/parser.py +35 -32
  23. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/scraper/scraper.py +113 -83
  24. cs2tracker-2.1.16/cs2tracker/util/__init__.py +0 -0
  25. cs2tracker-2.1.16/cs2tracker/util/currency_conversion.py +84 -0
  26. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/util/padded_console.py +5 -0
  27. cs2tracker-2.1.16/cs2tracker/util/tkinter.py +55 -0
  28. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker.egg-info/PKG-INFO +15 -16
  29. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker.egg-info/SOURCES.txt +8 -4
  30. cs2tracker-2.1.14/.pre-commit-config.yaml +0 -30
  31. cs2tracker-2.1.14/cs2tracker/app/__init__.py +0 -3
  32. cs2tracker-2.1.14/cs2tracker/scraper/__init__.py +0 -9
  33. cs2tracker-2.1.14/cs2tracker/util/__init__.py +0 -9
  34. cs2tracker-2.1.14/cs2tracker/util/price_logs.py +0 -100
  35. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/.flake8 +0 -0
  36. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/.isort.cfg +0 -0
  37. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/.pylintrc +0 -0
  38. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/LICENSE +0 -0
  39. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/MANIFEST.in +0 -0
  40. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/assets/icon.png +0 -0
  41. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/__init__.py +0 -0
  42. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker/__main__.py +0 -0
  43. /cs2tracker-2.1.14/cs2tracker/data/output.csv → /cs2tracker-2.1.16/cs2tracker/app/__init__.py +0 -0
  44. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker.egg-info/dependency_links.txt +0 -0
  45. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker.egg-info/entry_points.txt +0 -0
  46. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker.egg-info/requires.txt +0 -0
  47. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/cs2tracker.egg-info/top_level.txt +0 -0
  48. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/pyproject.toml +0 -0
  49. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/requirements.txt +0 -0
  50. {cs2tracker-2.1.14 → cs2tracker-2.1.16}/setup.cfg +0 -0
@@ -4,6 +4,7 @@
4
4
  __pycache__
5
5
  venv
6
6
  venv-test
7
+ venv-wsl
7
8
 
8
9
  # Python build output
9
10
  build
@@ -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.14
3
+ Version: 2.1.16
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
@@ -41,17 +41,16 @@ Dynamic: license-file
41
41
  [![PyPI version](https://badge.fury.io/py/cs2tracker.svg)](https://badge.fury.io/py/cs2tracker)
42
42
  [![GitHub Issues or Pull Requests](https://img.shields.io/github/issues/ashiven/cs2tracker)](https://github.com/ashiven/cs2tracker/issues)
43
43
  [![GitHub Issues or Pull Requests](https://img.shields.io/github/issues-pr/ashiven/cs2tracker)](https://github.com/ashiven/cs2tracker/pulls)
44
- ![GitHub Repo stars](https://img.shields.io/github/stars/ashiven/cs2tracker)
45
44
 
46
- <img src="https://github.com/user-attachments/assets/9585afb2-bf1a-473c-be5d-cccbb3349b9a"/>
45
+ <img src="./assets/demo.gif"/>
47
46
  </div>
48
47
 
49
48
  ## Table of Contents
50
49
 
51
50
  - [Features](#features)
52
51
  - [Getting Started](#getting-started)
53
- - [Prerequisites](#prerequisites)
54
52
  - [Installation](#installation)
53
+ - [Additional Setup](#additional-setup)
55
54
  - [Usage](#usage)
56
55
  - [Configuration](#configuration)
57
56
  - [Advanced Features](#advanced-features)
@@ -61,28 +60,24 @@ Dynamic: license-file
61
60
  ## Features
62
61
 
63
62
  - ⚡ Rapidly import your Storage Units
64
- - 🔍 Track CS2 Steam Market prices
63
+ - 🔍 Track prices on Steam, Buff163, CSFloat
65
64
  - 📈 View investment price history
66
- - 🧾 Export/Import price data
65
+ - 🧾 Export/Import history data
67
66
  - 📤 Discord notifications on updates
68
67
  - 📅 Daily background calculations
69
68
  - 🛡️ Proxy support to avoid rate limits
70
69
 
71
70
  ## Getting Started
72
71
 
73
- ### Prerequisites
74
-
75
- - Download and install the latest versions of [Python](https://www.python.org/downloads/) and [Pip](https://pypi.org/project/pip/). (Required on Linux)
76
- - Register for the [Crawlbase Smart Proxy API](https://crawlbase.com/) and retrieve your API key. (Optional)
77
- - Create a [Discord Webhook](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) to be notified about recent price updates. (Optional)
78
-
79
72
  ### Installation
80
73
 
81
- #### Option 1: Windows Executable
74
+ #### Method 1: Executable
82
75
 
83
- - Simply [download the latest executable](https://github.com/ashiven/cs2tracker/releases/latest/download/cs2tracker-windows.zip) and run it.
76
+ Simply download the program and run it:
77
+ - [Windows](https://github.com/ashiven/cs2tracker/releases/latest/download/cs2tracker-windows.zip)
78
+ - [Linux](https://github.com/ashiven/cs2tracker/releases/latest/download/cs2tracker-linux.zip)
84
79
 
85
- #### Option 2: Install via Pip
80
+ #### Method 2: Install via Pip
86
81
 
87
82
  1. Install the program:
88
83
 
@@ -95,10 +90,14 @@ Dynamic: license-file
95
90
  ```bash
96
91
  cs2tracker
97
92
  ```
93
+ ### Additional Setup
94
+
95
+ - Register for the [Crawlbase Smart Proxy API](https://crawlbase.com/) and retrieve your API key. (Optional)
96
+ - Create a [Discord Webhook](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) to be notified about recent price updates. (Optional)
98
97
 
99
98
  ## Usage
100
99
 
101
- - Click **Run!** to gather the current market prices of your items and calculate the total amount in USD and EUR.
100
+ - Click **Run!** to gather the current market prices of your items and calculate the total amount in USD and your selected currency.
102
101
  - The generated Excel sheet can be saved by right-clicking and then selecting **Save Sheet**.
103
102
  - Use **Edit Config** to specify the numbers of items owned in the configuration.
104
103
  - Click **Show History** to see a price chart consisting of past calculations.
@@ -13,17 +13,16 @@
13
13
  [![PyPI version](https://badge.fury.io/py/cs2tracker.svg)](https://badge.fury.io/py/cs2tracker)
14
14
  [![GitHub Issues or Pull Requests](https://img.shields.io/github/issues/ashiven/cs2tracker)](https://github.com/ashiven/cs2tracker/issues)
15
15
  [![GitHub Issues or Pull Requests](https://img.shields.io/github/issues-pr/ashiven/cs2tracker)](https://github.com/ashiven/cs2tracker/pulls)
16
- ![GitHub Repo stars](https://img.shields.io/github/stars/ashiven/cs2tracker)
17
16
 
18
- <img src="https://github.com/user-attachments/assets/9585afb2-bf1a-473c-be5d-cccbb3349b9a"/>
17
+ <img src="./assets/demo.gif"/>
19
18
  </div>
20
19
 
21
20
  ## Table of Contents
22
21
 
23
22
  - [Features](#features)
24
23
  - [Getting Started](#getting-started)
25
- - [Prerequisites](#prerequisites)
26
24
  - [Installation](#installation)
25
+ - [Additional Setup](#additional-setup)
27
26
  - [Usage](#usage)
28
27
  - [Configuration](#configuration)
29
28
  - [Advanced Features](#advanced-features)
@@ -33,28 +32,24 @@
33
32
  ## Features
34
33
 
35
34
  - ⚡ Rapidly import your Storage Units
36
- - 🔍 Track CS2 Steam Market prices
35
+ - 🔍 Track prices on Steam, Buff163, CSFloat
37
36
  - 📈 View investment price history
38
- - 🧾 Export/Import price data
37
+ - 🧾 Export/Import history data
39
38
  - 📤 Discord notifications on updates
40
39
  - 📅 Daily background calculations
41
40
  - 🛡️ Proxy support to avoid rate limits
42
41
 
43
42
  ## Getting Started
44
43
 
45
- ### Prerequisites
46
-
47
- - Download and install the latest versions of [Python](https://www.python.org/downloads/) and [Pip](https://pypi.org/project/pip/). (Required on Linux)
48
- - Register for the [Crawlbase Smart Proxy API](https://crawlbase.com/) and retrieve your API key. (Optional)
49
- - Create a [Discord Webhook](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) to be notified about recent price updates. (Optional)
50
-
51
44
  ### Installation
52
45
 
53
- #### Option 1: Windows Executable
46
+ #### Method 1: Executable
54
47
 
55
- - Simply [download the latest executable](https://github.com/ashiven/cs2tracker/releases/latest/download/cs2tracker-windows.zip) and run it.
48
+ Simply download the program and run it:
49
+ - [Windows](https://github.com/ashiven/cs2tracker/releases/latest/download/cs2tracker-windows.zip)
50
+ - [Linux](https://github.com/ashiven/cs2tracker/releases/latest/download/cs2tracker-linux.zip)
56
51
 
57
- #### Option 2: Install via Pip
52
+ #### Method 2: Install via Pip
58
53
 
59
54
  1. Install the program:
60
55
 
@@ -67,10 +62,14 @@
67
62
  ```bash
68
63
  cs2tracker
69
64
  ```
65
+ ### Additional Setup
66
+
67
+ - Register for the [Crawlbase Smart Proxy API](https://crawlbase.com/) and retrieve your API key. (Optional)
68
+ - Create a [Discord Webhook](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks) to be notified about recent price updates. (Optional)
70
69
 
71
70
  ## Usage
72
71
 
73
- - Click **Run!** to gather the current market prices of your items and calculate the total amount in USD and EUR.
72
+ - Click **Run!** to gather the current market prices of your items and calculate the total amount in USD and your selected currency.
74
73
  - The generated Excel sheet can be saved by right-clicking and then selecting **Save Sheet**.
75
74
  - Use **Edit Config** to specify the numbers of items owned in the configuration.
76
75
  - Click **Show History** to see a price chart consisting of past calculations.
Binary file
@@ -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)
@@ -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())