diff --git a/boiiiwd_package/src/library_tab.py b/boiiiwd_package/src/library_tab.py index 2bd5c6f..3a2b550 100644 --- a/boiiiwd_package/src/library_tab.py +++ b/boiiiwd_package/src/library_tab.py @@ -36,6 +36,7 @@ class LibraryTab(ctk.CTkScrollableFrame): self.item_block_list = set() self.added_folders = set() self.ids_added = set() + self.refresh_next_time = False def add_item(self, item, image=None, workshop_id=None, folder=None, invalid_warn=False): label = ctk.CTkLabel(self, text=item, image=image, compound="left", padx=5, anchor="w") @@ -195,7 +196,14 @@ class LibraryTab(ctk.CTkScrollableFrame): button_view_list.grid_remove() button.grid_remove() - def load_items(self, boiiiFolder): + def load_items(self, boiiiFolder, dont_add=False): + if self.refresh_next_time and not dont_add: + self.refresh_next_time = False + self.refresh_items() + + if dont_add: + self.refresh_next_time = True + maps_folder = Path(boiiiFolder) / "mods" mods_folder = Path(boiiiFolder) / "usermaps" mod_img = os.path.join(RESOURCES_DIR, "mod_image.png") @@ -262,9 +270,9 @@ class LibraryTab(ctk.CTkScrollableFrame): text_to_add += " | ⚠️" self.added_items.add(text_to_add) - if image_path is b_mod_img or image_path is b_map_img: + if image_path is b_mod_img or image_path is b_map_img and not dont_add: self.add_item(text_to_add, image=ctk.CTkImage(Image.open(image_path)), workshop_id=workshop_id, folder=zone_path.parent, invalid_warn=True) - else: + elif not dont_add: self.add_item(text_to_add, image=ctk.CTkImage(Image.open(image_path)), workshop_id=workshop_id, folder=zone_path.parent) id_found, folder_found = self.item_exists_in_file(items_file, workshop_id, curr_folder_name) item_info = { @@ -381,7 +389,7 @@ class LibraryTab(ctk.CTkScrollableFrame): self.button_view_list.remove(button_view_list) self.remove_item_by_option(items_file, id) - def refresh_items(self): + def refresh_items(self, skip_load=False): main_app.app.title("BOIII Workshop Downloader - Library ➜ Loading... ⏳") for label, button, button_view_list in zip(self.label_list, self.button_list, self.button_view_list): label.destroy() @@ -393,8 +401,9 @@ class LibraryTab(ctk.CTkScrollableFrame): self.added_items.clear() self.added_folders.clear() self.ids_added.clear() - status = self.load_items(main_app.app.edit_destination_folder.get().strip()) - main_app.app.title(f"BOIII Workshop Downloader - Library ➜ {status}") + if not skip_load: + status = self.load_items(main_app.app.edit_destination_folder.get().strip()) + main_app.app.title(f"BOIII Workshop Downloader - Library ➜ {status}") def view_item(self, workshop_id): url = f"https://steamcommunity.com/sharedfiles/filedetails/?id={workshop_id}" diff --git a/boiiiwd_package/src/main.py b/boiiiwd_package/src/main.py index 4109b95..5db0a4b 100644 --- a/boiiiwd_package/src/main.py +++ b/boiiiwd_package/src/main.py @@ -629,7 +629,7 @@ class BOIIIWD(ctk.CTk): image_size = image.size self.toplevel_info_window(map_name, map_mod_type, map_size, image, image_size, date_created , - date_updated, stars_image, stars_image_size, ratings_text, url) + date_updated, stars_image, stars_image_size, ratings_text, url, workshop_id) except requests.exceptions.RequestException as e: show_message("Error", f"Failed to fetch map information.\nError: {e}", icon="cancel") @@ -639,7 +639,7 @@ class BOIIIWD(ctk.CTk): info_thread.start() def toplevel_info_window(self, map_name, map_mod_type, map_size, image, image_size, - date_created ,date_updated, stars_image, stars_image_size, ratings_text, url): + date_created ,date_updated, stars_image, stars_image_size, ratings_text, url, workshop_id): def main_thread(): top = ctk.CTkToplevel(self) top.after(210, lambda: top.iconbitmap(os.path.join(RESOURCES_DIR, "ryuk.ico"))) @@ -680,7 +680,15 @@ class BOIIIWD(ctk.CTk): date_created_label = ctk.CTkLabel(info_frame, text=f"Posted: {date_created}") date_created_label.grid(row=3, column=0, columnspan=2, sticky="w", padx=20, pady=5) - date_updated_label = ctk.CTkLabel(info_frame, text=f"Updated: {date_updated}") + if date_updated != "Not updated": + date_updated_label = ctk.CTkLabel(info_frame, text=f"Updated: {date_updated} 🔗") + date_updated_label_tooltip = CTkToolTip(date_updated_label, message="View changelogs", topmost=True) + date_updated_label.configure(cursor="hand2") + date_updated_label.bind("", lambda e: + webbrowser.open(f"https://steamcommunity.com/sharedfiles/filedetails/changelog/{workshop_id}")) + else: + date_updated_label = ctk.CTkLabel(info_frame, text=f"Updated: {date_updated}") + date_updated_label.grid(row=4, column=0, columnspan=2, sticky="w", padx=20, pady=5) stars_image_label = ctk.CTkLabel(stars_frame) diff --git a/boiiiwd_package/src/settings_tab.py b/boiiiwd_package/src/settings_tab.py index 5ab3183..bd494d1 100644 --- a/boiiiwd_package/src/settings_tab.py +++ b/boiiiwd_package/src/settings_tab.py @@ -1,4 +1,5 @@ from src.update_window import check_for_updates_func +from src.library_tab import LibraryTab as LT from src.imports import * from src.helpers import * @@ -113,7 +114,8 @@ class SettingsTab(ctk.CTkFrame): self.folder_options_label_var.trace_add("write", self.enable_save_button) self.folder_options_label = ctk.CTkLabel(left_frame, text="Items Folder Naming:", anchor="nw") self.folder_options_label.grid(row=10, column=1, padx=20, pady=(10, 0), sticky="nw") - self.folder_options = ctk.CTkOptionMenu(left_frame, values=["PublisherID", "FolderName"], variable=self.folder_options_label_var) + self.folder_options = ctk.CTkOptionMenu(left_frame, values=["PublisherID", "FolderName"], command=self.change_folder_naming, + variable=self.folder_options_label_var) self.folder_options.grid(row=10, column=1, padx=(150, 0), pady=(3, 0), sticky="nw") self.folder_options.set(value=self.load_settings("folder_naming", "PublisherID")) @@ -400,6 +402,49 @@ class SettingsTab(ctk.CTkFrame): def settings_check_for_updates(self): check_for_updates_func(self, ignore_up_todate=False) + def rename_all_folders(self, option): + boiiiFolder = main_app.app.edit_destination_folder.get() + maps_folder = Path(boiiiFolder) / "mods" + mods_folder = Path(boiiiFolder) / "usermaps" + folders_to_process = [mods_folder, maps_folder] + processed_names = set() + for folder_path in folders_to_process: + for zone_path in folder_path.glob("**/zone"): + if zone_path.parent.name in main_app.app.library_tab.item_block_list: + continue + json_path = zone_path / "workshop.json" + if json_path.exists(): + folder_to_rename = zone_path.parent + new_folder_name = extract_json_data(json_path, option) + while new_folder_name in processed_names: + new_folder_name += f"_{extract_json_data(json_path, 'PublisherID')}" + folder_to_rename.rename(os.path.join(folder_path, new_folder_name)) + processed_names.add(new_folder_name) + return new_folder_name + + def change_folder_naming(self, option): + main_app.app.title("BOIII Workshop Downloader - Settings ➜ Loading... ⏳") + try: + if os.path.exists(main_app.app.edit_destination_folder.get()): + lib = main_app.app.library_tab.load_items(main_app.app.edit_destination_folder.get(), dont_add=True) + if not "No items" in lib: + if show_message("Renaming", "Would you like to rename all your exisiting item folders now?", _return=True): + main_app.app.title("BOIII Workshop Downloader - Settings ➜ Renaming... ⏳") + try :self.rename_all_folders(option) + except Exception as er: show_message("Error!", f"Error occured when renaming\n{er}"); return + show_message("Done", "All folders have been renamed") + else: + show_message("Heads up!", "Only newly downloaded items will be affected", icon="info") + else: + show_message("Warning -> Check boiii path", f"You don't have any items yet ,from now on item's folders will be named as their {option}") + else: + show_message("Warning -> Check boiii path", f"You don't have any items yet ,from now on item's folders will be named as their {option}") + except Exception as e: + show_message("Error", f"Error occured \n{e}") + finally: + main_app.app.title("BOIII Workshop Downloader - Settings") + self.save_settings() + def load_on_switch_screen(self): self.check_updates_var.set(self.load_settings("checkforupdtes")) self.console_var.set(self.load_settings("console"))