Skip to content

Commit 3b5ec3a

Browse files
authored
Merge pull request #81 from ashiven/classification
Classification
2 parents d997197 + 2c8419b commit 3b5ec3a

File tree

7 files changed

+241
-101
lines changed

7 files changed

+241
-101
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ cs2tracker.egg-info
1414
# Auto generated version file on build
1515
_version.py
1616

17-
# PyInstaller output
17+
# PyInstaller files
1818
output
19+
cs2tracker.spec
20+
build.ps1
1921

2022
# Files generated by the program
2123
cs2tracker_scraper.bat

cs2tracker/app/editor_frame.py

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from nodejs import node
99
from ttk_text import ThemedText
1010

11-
from cs2tracker.config import get_config
11+
from cs2tracker.config import CUSTOM_SECTIONS, get_config
1212
from cs2tracker.constants import (
1313
CONFIG_FILE,
1414
CONFIG_FILE_BACKUP,
@@ -131,7 +131,7 @@ def _delete_selection_value(self, _):
131131
if selected:
132132
item = selected[0]
133133
section_name = self.tree.parent(item)
134-
if section_name in ("Stickers", "Skins"):
134+
if section_name in CUSTOM_SECTIONS:
135135
next_option = self.tree.next(item)
136136
self.tree.delete(item)
137137
self.save_config()
@@ -169,31 +169,19 @@ def _load_config_into_tree(self):
169169
continue
170170

171171
section_level = self.tree.insert("", "end", iid=section, text=section)
172-
173-
# Items in the Stickers, Cases, and Skins sections should be displayed alphabetically sorted
174-
section_items = config.items(section)
175-
if section in ("Stickers", "Cases", "Skins"):
176-
section_items = sorted(section_items)
177-
178-
for config_option, value in section_items:
172+
sorted_section_items = sorted(config.items(section))
173+
for config_option, value in sorted_section_items:
179174
if section not in ("User Settings", "App Settings"):
180175
option_name = config.option_to_name(config_option, href=True)
181-
self.tree.insert(
182-
section_level,
183-
"end",
184-
iid=f"{section}-{option_name}",
185-
text=option_name,
186-
values=[value],
187-
)
188176
else:
189177
option_name = config.option_to_name(config_option)
190-
self.tree.insert(
191-
section_level,
192-
"end",
193-
iid=f"{section}-{option_name}",
194-
text=option_name,
195-
values=[value],
196-
)
178+
self.tree.insert(
179+
section_level,
180+
"end",
181+
iid=f"{section}-{option_name}",
182+
text=option_name,
183+
values=[value],
184+
)
197185

198186
self.tree.focus("User Settings")
199187
self.tree.selection_set("User Settings")
@@ -267,6 +255,25 @@ def _add_widgets(self):
267255
custom_item_button = ttk.Button(self, text="Add Item", command=self._add_custom_item)
268256
custom_item_button.pack(side="left", expand=True, padx=5)
269257

258+
def open_custom_enter(_):
259+
selected = self.editor_frame.tree.selection()
260+
if selected and not self.editor_frame.tree.parent(selected[0]):
261+
selected_section = self.editor_frame.tree.item(selected[0], "text")
262+
if selected_section in CUSTOM_SECTIONS and not self.editor_frame.tree.get_children(
263+
selected_section
264+
):
265+
custom_item_button.invoke()
266+
267+
def open_custom_click(event):
268+
selected_section = self.editor_frame.tree.identify_row(event.y)
269+
if selected_section in CUSTOM_SECTIONS and not self.editor_frame.tree.get_children(
270+
selected_section
271+
):
272+
custom_item_button.invoke()
273+
274+
self.editor_frame.tree.bind("<Return>", open_custom_enter, add="+")
275+
self.editor_frame.tree.bind("<Double-1>", open_custom_click, add="+")
276+
270277
import_inventory_button = ttk.Button(
271278
self, text="Import Steam Inventory", command=self._import_steam_inventory
272279
)
@@ -397,14 +404,38 @@ def _get_insert_index(self, item_name, section):
397404
break
398405
return insert_index
399406

407+
def _identify_custom_section(self, item_name):
408+
# pylint: disable=too-many-return-statements
409+
"""Given an item name, identify the custom section it belongs to."""
410+
if "Patch Pack" in item_name or "Patch Collection" in item_name:
411+
return "Patch Packs"
412+
elif "Patch |" in item_name:
413+
return "Patches"
414+
elif "Sticker |" in item_name:
415+
return "Stickers"
416+
elif "Charm |" in item_name:
417+
return "Charms"
418+
elif "Souvenir" in item_name and "|" not in item_name:
419+
return "Souvenirs"
420+
elif "★ " in item_name:
421+
return "Special Items"
422+
elif " | " in item_name and "(" in item_name and ")" in item_name:
423+
return "Skins"
424+
elif "Music Kit |" in item_name:
425+
return "Others"
426+
elif " | " in item_name:
427+
return "Agents"
428+
else:
429+
return "Others"
430+
400431
def _add_custom_item(self, item_href, item_owned):
401432
"""Add a custom item to the configuration."""
402433
if not item_href or not item_owned:
403434
messagebox.showerror(
404435
"Input Error", "All fields must be filled out.", parent=self.window
405436
)
406437
return
407-
if config.option_exists(item_href, exclude_sections=("Stickers", "Skins")):
438+
if config.option_exists(item_href, exclude_sections=CUSTOM_SECTIONS):
408439
messagebox.showerror(
409440
"Item Exists", "This item already exists in another section.", parent=self.window
410441
)
@@ -416,12 +447,11 @@ def _add_custom_item(self, item_href, item_owned):
416447
messagebox.showerror("Invalid URL", str(error), parent=self.window)
417448
return
418449

419-
if self._update_existing("Stickers", item_name, item_owned):
420-
return
421-
if self._update_existing("Skins", item_name, item_owned):
422-
return
450+
for section in CUSTOM_SECTIONS:
451+
if self._update_existing(section, item_name, item_owned):
452+
return
423453

424-
section = "Stickers" if item_name.startswith("Sticker") else "Skins"
454+
section = self._identify_custom_section(item_name)
425455
insert_index = self._get_insert_index(item_name, section)
426456
self.editor_frame.tree.insert(
427457
section,

cs2tracker/config.py

Lines changed: 61 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,53 @@
33
from configparser import ConfigParser, ParsingError
44
from urllib.parse import quote, unquote
55

6-
from cs2tracker.constants import CAPSULE_PAGES, CONFIG_FILE, INVENTORY_IMPORT_FILE
6+
from cs2tracker.constants import (
7+
CONFIG_FILE,
8+
INVENTORY_IMPORT_FILE,
9+
)
710
from cs2tracker.util.padded_console import get_console
811

912
STEAM_MARKET_LISTING_BASEURL_CS2 = "https://steamcommunity.com/market/listings/730/"
1013
STEAM_MARKET_LISTING_REGEX = r"^https://steamcommunity.com/market/listings/\d+/.+$"
1114

15+
CUSTOM_SECTIONS = [
16+
"Skins",
17+
"Special Items",
18+
"Agents",
19+
"Charms",
20+
"Patches",
21+
"Patch Packs",
22+
"Stickers",
23+
"Souvenirs",
24+
"Others",
25+
]
26+
27+
PREEXISTING_SECTIONS = [
28+
"Cases",
29+
"Katowice 2014 Sticker Capsule",
30+
"Cologne 2014 Sticker Capsule",
31+
"DreamHack 2014 Sticker Capsule",
32+
"Katowice 2015 Sticker Capsule",
33+
"Cologne 2015 Sticker Capsule",
34+
"Cluj-Napoca 2015 Sticker Capsule",
35+
"Columbus 2016 Sticker Capsule",
36+
"Cologne 2016 Sticker Capsule",
37+
"Atlanta 2017 Sticker Capsule",
38+
"Krakow 2017 Sticker Capsule",
39+
"Boston 2018 Sticker Capsule",
40+
"London 2018 Sticker Capsule",
41+
"Katowice 2019 Sticker Capsule",
42+
"Berlin 2019 Sticker Capsule",
43+
"2020 RMR Sticker Capsule",
44+
"Stockholm 2021 Sticker Capsule",
45+
"Antwerp 2022 Sticker Capsule",
46+
"Rio 2022 Sticker Capsule",
47+
"Paris 2023 Sticker Capsule",
48+
"Copenhagen 2024 Sticker Capsule",
49+
"Shanghai 2024 Sticker Capsule",
50+
"Austin 2025 Sticker Capsule",
51+
]
52+
1253
console = get_console()
1354

1455

@@ -46,19 +87,12 @@ def delete_display_sections(self):
4687

4788
def _validate_config_sections(self):
4889
"""Validate that the configuration file has all required sections."""
49-
if not self.has_section("User Settings"):
50-
raise ValueError("Missing 'User Settings' section in the configuration file.")
51-
if not self.has_section("App Settings"):
52-
raise ValueError("Missing 'App Settings' section in the configuration file.")
53-
if not self.has_section("Stickers"):
54-
raise ValueError("Missing 'Stickers' section in the configuration file.")
55-
if not self.has_section("Cases"):
56-
raise ValueError("Missing 'Cases' section in the configuration file.")
57-
if not self.has_section("Skins"):
58-
raise ValueError("Missing 'Skins' section in the configuration file.")
59-
for capsule_section in CAPSULE_PAGES:
60-
if not self.has_section(capsule_section):
61-
raise ValueError(f"Missing '{capsule_section}' section in the configuration file.")
90+
for section in CUSTOM_SECTIONS:
91+
if not self.has_section(section):
92+
raise ValueError(f"Missing '{section}' section in the configuration file.")
93+
for section in PREEXISTING_SECTIONS:
94+
if not self.has_section(section):
95+
raise ValueError(f"Missing '{section}' section in the configuration file.")
6296

6397
def _validate_config_values(self):
6498
# pylint: disable=too-many-branches
@@ -136,23 +170,22 @@ def read_from_inventory_file(self):
136170
try:
137171
with open(INVENTORY_IMPORT_FILE, "r", encoding="utf-8") as inventory_file:
138172
inventory_data = json.load(inventory_file)
139-
sorted_inventory_data = dict(sorted(inventory_data.items()))
140173

141174
added_to_config = set()
142-
for item_name, item_owned in sorted_inventory_data.items():
143-
option = self.name_to_option(item_name, href=True)
144-
for section in self.sections():
145-
if option in self.options(section):
146-
self.set(section, option, str(item_owned))
147-
added_to_config.add(item_name)
148-
149-
for item_name, item_owned in sorted_inventory_data.items():
150-
if item_name not in added_to_config:
175+
for _, item_infos in inventory_data.items():
176+
for item_name, item_owned in item_infos.items():
151177
option = self.name_to_option(item_name, href=True)
152-
if item_name.startswith("Sticker"):
153-
self.set("Stickers", option, str(item_owned))
154-
else:
155-
self.set("Skins", option, str(item_owned))
178+
for section in self.sections():
179+
if option in self.options(section):
180+
self.set(section, option, str(item_owned))
181+
added_to_config.add(item_name)
182+
183+
for section, item_infos in inventory_data.items():
184+
sorted_item_infos = dict(sorted(item_infos.items()))
185+
for item_name, item_owned in sorted_item_infos.items():
186+
if item_name not in added_to_config:
187+
option = self.name_to_option(item_name, href=True)
188+
self.set(section, option, str(item_owned))
156189

157190
self.write_to_file()
158191
except (FileNotFoundError, json.JSONDecodeError) as error:

cs2tracker/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ def copy_initial_files_with_popup():
187187
f"Version: {VERSION} - {datetime.today().strftime('%Y/%m/%d')} - Jannik Novak @ashiven\n"
188188
)
189189

190+
190191
CAPSULE_PAGES = {
191192
"Katowice 2014 Sticker Capsule": "https://steamcommunity.com/market/search?q=katowice+2014+legends+challengers",
192193
"Cologne 2014 Sticker Capsule": "https://steamcommunity.com/market/search?q=cologne+2014+legends+challengers",

cs2tracker/data/config.ini

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,22 @@ discord_webhook_url ~
99

1010
[Skins]
1111

12+
[Special Items]
13+
14+
[Agents]
15+
16+
[Charms]
17+
18+
[Patches]
19+
20+
[Patch Packs]
21+
1222
[Stickers]
1323

24+
[Souvenirs]
25+
26+
[Others]
27+
1428
[Cases]
1529
https://steamcommunity.com/market/listings/730/CS%3AGO%20Weapon%20Case ~ 0
1630
https://steamcommunity.com/market/listings/730/CS%3AGO%20Weapon%20Case%202 ~ 0

0 commit comments

Comments
 (0)