Created
July 22, 2023 04:20
-
-
Save themacmarketer/5b48b660b0e5f0501916ba3a6d55b7d9 to your computer and use it in GitHub Desktop.
This is a Python script that uses the wxPython library to create a graphical user interface (GUI) application for sorting files in a specified directory based on a defined set of topics and associated keywords.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| This is a Python script that uses the wxPython library to create a graphical user interface (GUI) application for sorting files in a specified directory based on a defined set of topics and associated keywords. | |
| At the start, several libraries are imported: `os` and `shutil` for file and directory manipulation, `wx` for creating the GUI, `json` for reading and writing JSON data, and `re` for regular expression operations. | |
| A constant named `TOPICS_FILE` is defined, which is the name of the JSON file that stores topics and their associated keywords. | |
| The `load_topics` function checks if the `TOPICS_FILE` exists, and if it does, opens the file and loads the JSON data into a Python dictionary. If the file does not exist, it returns an empty dictionary. | |
| The `MainFrame` class is the main application window. It contains controls for directory selection (`DirPickerCtrl`), a text area to display the topics and keywords (`TextCtrl`), and three buttons ("Process Files", "Undo Sort", and "Exit"). | |
| The `process_files` method sorts files in the chosen directory. For each file, it compares the file name (sanitized to lower case and without special characters) against the keywords for each topic. If a match is found, the file is moved to a subdirectory named after the matched topic. If no match is found, the file is moved to a "Miscellaneous" subdirectory. | |
| The `undo_sort` method undoes the sorting operation by moving all files back to the original directory and removing the created subdirectories. | |
| The `sanitize` method is a helper method that removes special characters from a string and converts it to lower case. | |
| The `on_exit` method is bound to the Exit button and closes the application. | |
| The script concludes with a block that creates an instance of the `MainFrame` and starts the wxPython event loop, causing the application window to appear on the screen. | |
| */ | |
| import os | |
| import wx | |
| import json | |
| import shutil | |
| import re | |
| # Constants | |
| TOPICS_FILE = "topics.json" | |
| # Load topics and keywords from the JSON file | |
| def load_topics() -> dict: | |
| if os.path.exists(TOPICS_FILE): | |
| with open(TOPICS_FILE, "r") as file: | |
| return json.load(file) | |
| else: | |
| return {} | |
| class MainFrame(wx.Frame): | |
| def __init__(self): | |
| wx.Frame.__init__(self, None, title="File Processing App", size=(600,400)) | |
| # Set the panel | |
| self.panel = wx.Panel(self) | |
| # Folder Path | |
| self.folderPath = wx.DirPickerCtrl(self.panel, path=os.getcwd()) | |
| # Topics text | |
| self.topicText = wx.TextCtrl(self.panel, style=wx.TE_MULTILINE) | |
| self.topicText.SetValue(json.dumps(load_topics(), indent=4)) | |
| # Process Button | |
| self.processBtn = wx.Button(self.panel, label="Process Files") | |
| self.processBtn.Bind(wx.EVT_BUTTON, self.process_files) | |
| # Undo Button | |
| self.undoBtn = wx.Button(self.panel, label="Undo Sort") | |
| self.undoBtn.Bind(wx.EVT_BUTTON, self.undo_sort) | |
| # Exit Button | |
| self.exitBtn = wx.Button(self.panel, label="Exit") | |
| self.exitBtn.Bind(wx.EVT_BUTTON, self.on_exit) | |
| # Set sizer | |
| self.mainSizer = wx.BoxSizer(wx.VERTICAL) | |
| self.mainSizer.Add(self.folderPath, 0, wx.ALL|wx.EXPAND, 5) | |
| self.mainSizer.Add(self.topicText, 0, wx.ALL|wx.EXPAND, 5) | |
| self.mainSizer.Add(self.processBtn, 0, wx.ALL|wx.CENTER, 5) | |
| self.mainSizer.Add(self.undoBtn, 0, wx.ALL|wx.CENTER, 5) | |
| self.mainSizer.Add(self.exitBtn, 0, wx.ALL|wx.CENTER, 5) | |
| self.panel.SetSizer(self.mainSizer) | |
| def process_files(self, event): | |
| folder_path = self.folderPath.GetPath() | |
| for file in os.listdir(folder_path): | |
| file_path = os.path.join(folder_path, file) | |
| if os.path.isfile(file_path): | |
| sanitized_file = self.sanitize(file) | |
| matched_topic = None | |
| for topic, keywords in load_topics().items(): | |
| if any(self.sanitize(keyword) in sanitized_file for keyword in keywords): | |
| matched_topic = topic | |
| break | |
| if matched_topic: | |
| topic_dir = os.path.join(folder_path, matched_topic) | |
| os.makedirs(topic_dir, exist_ok=True) | |
| shutil.move(file_path, os.path.join(topic_dir, file)) | |
| else: | |
| miscellaneous_dir = os.path.join(folder_path, "Miscellaneous") | |
| os.makedirs(miscellaneous_dir, exist_ok=True) | |
| shutil.move(file_path, os.path.join(miscellaneous_dir, file)) | |
| def undo_sort(self, event): | |
| current_dir = self.folderPath.GetPath() | |
| for root, dirs, files in os.walk(current_dir, topdown=False): | |
| for file in files: | |
| file_path = os.path.join(root, file) | |
| shutil.move(file_path, os.path.join(current_dir, file)) | |
| for dir_name in dirs: | |
| dir_path = os.path.join(root, dir_name) | |
| if not os.listdir(dir_path): | |
| os.rmdir(dir_path) | |
| def sanitize(self, name: str) -> str: | |
| return re.sub(r'[_\W]+', ' ', name).lower() | |
| def on_exit(self, event): | |
| self.Close() | |
| if __name__ == "__main__": | |
| app = wx.App(False) | |
| frame = MainFrame() | |
| frame.Show() | |
| app.MainLoop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment