From 709c8bf0e3427991b7f69d68d9e54df53fdfd5fb Mon Sep 17 00:00:00 2001 From: Hasan Shinnar Date: Tue, 7 Apr 2026 18:37:29 +0300 Subject: [PATCH 1/5] Update Dockerfile and add activate.bat for environment setup --- Dockerfile | 9 +++++-- activate.bat | 53 +++++++++++++++++++++++++++++++++++++++ organise_desktop/Clean.py | 2 +- 3 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 activate.bat diff --git a/Dockerfile b/Dockerfile index aedf3cd..e41b92e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Pull base image -FROM python:3 +FROM python:3.11-slim # Set the working directory to /code WORKDIR /code @@ -9,7 +9,12 @@ ADD . /code # Udate and install all in the container RUN apt-get update && \ - apt-get install -y + apt-get install -y \\ + xvfb \\ + libx11-6 \\ + libxext6 \\ + xauth \\ + && rm -rf /var/lib/apt/lists/* # Install pipenv and install all dependency RUN pip install --upgrade pip diff --git a/activate.bat b/activate.bat new file mode 100644 index 0000000..f7902c6 --- /dev/null +++ b/activate.bat @@ -0,0 +1,53 @@ +@echo off +:: START ADMIN AUTO-ELEVATE - IT CHECKS IF THE USER HAS ADMIN PRIVILEGES AND RESTARTS THE SCRIPT WITH ELEVATED PRIVILEGES IF NOT +>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" +if '%errorlevel%' NEQ '0' ( + echo Requesting administrative privileges... + goto UACPrompt +) else ( goto gotAdmin ) + +:UACPrompt + echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs" + echo UAC.ShellExecute "%~s0", "", "", "runas", 1 >> "%temp%\getadmin.vbs" + "%temp%\getadmin.vbs" + exit /b + +:gotAdmin + if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" ) + :: IMPORTANT: Move to the directory where the script is located + cd /d "%~dp0" + + +:: Your original logic starts here +if exist organise_desktop_env\ ( + call :load_env +) else ( + echo Creating new virtual environment... + pip install virtualenv + virtualenv organise_desktop_env + + if not exist virtual_desktop mkdir virtual_desktop + + call :load_env + + if %ERRORLEVEL% EQU 0 ( + if exist requirements.txt ( + pip install -r requirements.txt + ) else ( + echo. + echo [INFO] requirements.txt not found. Skipping library installation. + echo. + ) + ) else ( + echo Loading the environment has failed + ) +) + +pause +exit /b + +:load_env +call organise_desktop_env\Scripts\activate.bat +set TEST_DIR=%CD%\virtual_desktop +echo Environment loaded as Admin in: %CD% +exit /b 0 \ No newline at end of file diff --git a/organise_desktop/Clean.py b/organise_desktop/Clean.py index f5dcdee..722a94f 100644 --- a/organise_desktop/Clean.py +++ b/organise_desktop/Clean.py @@ -1,8 +1,8 @@ import sys import json import os -from .cronController import schedule_end, schedule_start from .organiseDesktop import undo, organise_desktop +from .cronController import schedule_end, schedule_start if sys.version_info >= (3,): from tkinter import * From 16a786f00cb44fa9c20a90bcdcd44930aca1c5ec Mon Sep 17 00:00:00 2001 From: Hasan Shinnar Date: Tue, 7 Apr 2026 19:40:22 +0300 Subject: [PATCH 2/5] Refactor Dockerfile and activate.bat for improved clarity and efficiency --- Dockerfile | 16 +++++++--------- activate.bat | 5 ++--- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/Dockerfile b/Dockerfile index e41b92e..56078b4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,10 +4,7 @@ FROM python:3.11-slim # Set the working directory to /code WORKDIR /code -# Copy the current directory content into the container at /code -ADD . /code - -# Udate and install all in the container +# Update and install all in the container and clean up apt cache to reduce image size RUN apt-get update && \ apt-get install -y \\ xvfb \\ @@ -16,12 +13,13 @@ RUN apt-get update && \ xauth \\ && rm -rf /var/lib/apt/lists/* -# Install pipenv and install all dependency -RUN pip install --upgrade pip -RUN pip install pipenv -COPY ./Pipfile /code/Pipfile -RUN pipenv install --deploy --system --skip-lock --dev +# Install and update pip and pipenv and install all dependency +RUN pip install --upgrade pip pipenv +COPY Pipfile Pipfile.lock /code/ +RUN pipenv install --deploy --system +# Copy the current directory content into the container at /code +ADD . /code # Set enviroment variables ENV PYTHONDONTWRITEBYTECODE 1 ENV PYTHONUNBUFFERED 1 \ No newline at end of file diff --git a/activate.bat b/activate.bat index f7902c6..77b8617 100644 --- a/activate.bat +++ b/activate.bat @@ -1,5 +1,5 @@ @echo off -:: START ADMIN AUTO-ELEVATE - IT CHECKS IF THE USER HAS ADMIN PRIVILEGES AND RESTARTS THE SCRIPT WITH ELEVATED PRIVILEGES IF NOT +:: Check for administrative privileges if not, relaunch the script with admin rights >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system" if '%errorlevel%' NEQ '0' ( echo Requesting administrative privileges... @@ -17,8 +17,7 @@ if '%errorlevel%' NEQ '0' ( :: IMPORTANT: Move to the directory where the script is located cd /d "%~dp0" - -:: Your original logic starts here +:: Check if the virtual environment folder exists if not create it and load the environment if exist organise_desktop_env\ ( call :load_env ) else ( From 12eb4027053ccf9e6e683aff9048eab90bf54390 Mon Sep 17 00:00:00 2001 From: Hasan Shinnar Date: Tue, 7 Apr 2026 21:39:50 +0300 Subject: [PATCH 3/5] Refactor code for improved readability and maintainability across multiple files --- organise_desktop/Clean.py | 64 +++++++++++++++--------------- organise_desktop/__init__.py | 2 + organise_desktop/cronCleanUp.py | 14 ++----- organise_desktop/cronController.py | 57 ++++++++++---------------- run.py | 4 ++ setup.py | 8 ++-- 6 files changed, 68 insertions(+), 81 deletions(-) create mode 100644 run.py diff --git a/organise_desktop/Clean.py b/organise_desktop/Clean.py index 722a94f..df21732 100644 --- a/organise_desktop/Clean.py +++ b/organise_desktop/Clean.py @@ -1,34 +1,29 @@ -import sys -import json -import os +import sys, json, os from .organiseDesktop import undo, organise_desktop from .cronController import schedule_end, schedule_start - -if sys.version_info >= (3,): - from tkinter import * - from tkinter import messagebox as tkMessageBox -else: - from tkinter import * - import tkMessageBox +from tkinter import * +from tkinter import messagebox as tkMessageBox pwd = os.path.dirname(os.path.abspath(__file__)) -Extensions = json.load(open(pwd+'/Extension.json', 'r')) -folders = [x for x in Extensions] +Extensions = json.load(open(os.path.join(pwd, 'Extension.json'), 'r')) +folders = list(Extensions.keys()) + class App(Frame): """define the GUI""" + def clean(self): checked_extensions = {} for x in folders: checked_extensions[x] = Extensions[x] organise_desktop(checked_extensions) - tkMessageBox.showinfo('Complete', 'Desktop clean finished.') + tkMessageBox.showinfo("Complete", "Desktop clean finished.") def quit_all(self): sys.exit(0) def check(self, item): - global folders + self.folders = folders if item in folders: folders.remove(item) else: @@ -40,27 +35,28 @@ def on_schedule_start(self): def make_checkbutton(self, text): cb = Checkbutton(self, text=text, command=lambda: self.check(text)) cb.select() - cb.pack({'side': 'top'}) + cb.pack({"side": "top"}) return cb def make_button(self, text, command): btn = Button(self, text=text, command=command) - btn.pack({'side': 'left'}) + btn.pack({"side": "left"}) return btn def create(self): - self.winfo_toplevel().title('Desktop Cleaner') + self.winfo_toplevel().title("Desktop Cleaner") for ext in sorted(Extensions.keys()): self.make_checkbutton(ext) # buttons and their respective functions - buttons = {'Clean': self.clean, - 'Exit': self.quit_all, - 'Undo': undo, - 'Schedule': self.on_schedule_start, - 'Remove\nSchedule': schedule_end - } + buttons = { + "Clean": self.clean, + "Exit": self.quit_all, + "Undo": undo, + "Schedule": self.on_schedule_start, + "Remove\nSchedule": schedule_end, + } for key in buttons: self.make_button(key, buttons[key]) @@ -70,23 +66,29 @@ def __init__(self, master=None): self.pack() self.create() + def main(): root = Tk() # root.resizable = False # commenting this approach and applying the below one. - root.resizable(FALSE,FALSE) # To make the application's size constant and restore button in windows as greyed out(with width=350 and height=330 as mentioned below) + root.resizable( + FALSE, FALSE + ) # To make the application's size constant and restore button in windows as greyed out(with width=350 and height=330 as mentioned below) root.minsize(width=350, height=330) root.maxsize(width=350, height=330) - '''Logic to launch the app in center - start''' - positionRight = int(root.winfo_screenwidth() / 2 - 330 / 2) #considering width=330 - positionDown = int(root.winfo_screenheight() / 2 - 350 / 2) #considering height=350 + """Logic to launch the app in center - start""" + positionRight = int(root.winfo_screenwidth() / 2 - 330 / 2) # considering width=330 + positionDown = int( + root.winfo_screenheight() / 2 - 350 / 2 + ) # considering height=350 root.geometry("+{}+{}".format(positionRight, positionDown)) - '''Logic to launch the app in center - end''' + """Logic to launch the app in center - end""" app = App(root) - root.protocol('WM_DELETE_WINDOW', app.quit_all) + root.protocol("WM_DELETE_WINDOW", app.quit_all) app.mainloop() root.destroy() -if __name__ == '__main__': - main() \ No newline at end of file + +if __name__ == "__main__": + main() diff --git a/organise_desktop/__init__.py b/organise_desktop/__init__.py index e69de29..d0358d2 100644 --- a/organise_desktop/__init__.py +++ b/organise_desktop/__init__.py @@ -0,0 +1,2 @@ +import os +from organise_desktop import organise_desktop diff --git a/organise_desktop/cronCleanUp.py b/organise_desktop/cronCleanUp.py index 0ca3887..983f65d 100644 --- a/organise_desktop/cronCleanUp.py +++ b/organise_desktop/cronCleanUp.py @@ -1,14 +1,8 @@ -import Clean -import pickle -import os -import sys +import Clean, pickle, os -separator = "" -if sys.platform == 'win32': - separator = '\\' -else: - separator = '/' -with open(os.path.dirname(os.path.join(os.path.abspath(__file__), 'settings.txt'), 'rb') as setting_file: +settings_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "settings.txt") + +with open(settings_path, "rb") as setting_file: folders = pickle.load(setting_file) Clean.main(folders) diff --git a/organise_desktop/cronController.py b/organise_desktop/cronController.py index 488839e..c64cd37 100644 --- a/organise_desktop/cronController.py +++ b/organise_desktop/cronController.py @@ -1,54 +1,41 @@ __author__ = "Remigius Kalimba" """Add a timer so it does this automatically everyday at a set time""" - -import pickle -import crontab as CronTab -import json -import os -import sys +import pickle, os, sys, getpass +from crontab import CronTab from subprocess import call -import getpass - - pwd = os.path.dirname(os.path.abspath(__file__)) +settings_path = os.path.join(pwd, "settings.txt") def schedule_start(folders): - """Starts a schedule to organise the desktop once a day""" - - with open('./settings.txt', 'wb') as setting_file: - pickle.dump(folders, setting_file) - - if sys.platform == 'darwin' or sys.platform == 'linux': - my_cron = CronTab(user=getpass.getuser()) - - job = my_cron.new(command=str(sys.executable + ' ' + pwd + '/cronCleanUp.py'), - comment='OrganiseDesktop') - + if sys.platform == "darwin" or sys.platform.startswith("linux"): + cron = CronTab(user=getpass.getuser()) + job = cron.new( + command=f'"{sys.executable}" "{os.path.join(pwd,"cronCleanUp.py")}"', + comment="OrganiseDesktop", + ) job.day.every(1) - - my_cron.write() + cron.write() else: - if not os.path.isfile(pwd + '\\cronCleanUp.pyw'): - call('copy' + pwd + '\\cronCleanUp.py' + pwd + '\\cronCleanUp.pyw', shell=True) - - call('SCHTASKS /Create /SC DAILY /TN OrganiseDesktop /TR' + pwd + '\\cronCleanUp.pyw /F', - shell=True) + if not os.path.isfile(pwd + "\\cronCleanUp.pyw"): + call(f'copy "{pwd}\\cronCleanUp.py" "{pwd}\\cronCleanUp.pyw"', shell=True) + call( + f'SCHTASKS /Create /SC DAILY /TN OrganiseDesktop /TR "{pwd}\\cronCleanUp.pyw" /F' + ) -def schedule_end(): +def schedule_end(): """Removes the schedule if one is defined""" - os.remove('./settings.txt') - - if sys.platform == 'darwin' or sys.platform == 'linux': + os.remove(settings_path) + + if sys.platform == "darwin" or sys.platform.startswith("linux"): my_cron = CronTab(user=getpass.getuser()) - my_cron.remove_all(comment='OrganiseDesktop') + my_cron.remove_all(comment="OrganiseDesktop") my_cron.write() - + else: - call('SCHTASKS /Delete /TN OrganiseDesktop /F', - shell=True) + call("SCHTASKS /Delete /TN OrganiseDesktop /F", shell=True) diff --git a/run.py b/run.py new file mode 100644 index 0000000..e17e9dc --- /dev/null +++ b/run.py @@ -0,0 +1,4 @@ +from organise_desktop import app + +if __name__ == "__main__": + app.run(debug=True) diff --git a/setup.py b/setup.py index 55cfeec..6e7067d 100644 --- a/setup.py +++ b/setup.py @@ -1,15 +1,13 @@ # -*- coding: utf-8 -*- from setuptools import setup, find_packages -from codecs import open -from sys import exit, version import sys -if version < '1.0.0': - print("Python 1 is not supported...") +if sys.version_info < (3, 6): + print("Python 3.6 or higher is required...") sys.exit(1) -with open('README.md') as f: +with open('README.md', encoding='utf-8') as f: longd = f.read() setup( From 47a9a24c0649b033ae4b91e24d9cf59c9907cede Mon Sep 17 00:00:00 2001 From: Hasan Shinnar Date: Thu, 9 Apr 2026 19:30:26 +0300 Subject: [PATCH 4/5] Refactor desktop organization logic and improve environment setup - Removed unnecessary imports and streamlined the code in organiseDesktop.py. - Introduced a function to get the desktop path based on the operating system. - Simplified the initialization of the OrganiseDesktop class and its methods. - Enhanced the mover method to prioritize sorting based on patterns and extensions. - Updated the logging mechanism to write to a log file more efficiently. - Created a new environment.py file to handle environment setup and package configuration. - Removed the setup.py file and integrated its functionality into environment.py. - Added Extension_Sources.md to document sources for file extensions. - Updated run.py to launch the desktop organizer with improved environment checks. --- Extension_Sources.md | 17 + environment.py | 48 + organise_desktop/Clean.py | 25 +- organise_desktop/Extension.json | 2455 +++++++++++++++++++++++++-- organise_desktop/__init__.py | 2 - organise_desktop/organiseDesktop.py | 373 ++-- run.py | 22 +- setup.py | 29 - 8 files changed, 2576 insertions(+), 395 deletions(-) create mode 100644 Extension_Sources.md create mode 100644 environment.py delete mode 100644 setup.py diff --git a/Extension_Sources.md b/Extension_Sources.md new file mode 100644 index 0000000..3727c25 --- /dev/null +++ b/Extension_Sources.md @@ -0,0 +1,17 @@ +# Image extensions source: + +[Raster_Image] (https://fileinfo.com/filetypes/raster_image) +[Vector_Image](https://fileinfo.com/filetypes/vector_image) +[Camera_Raw](https://fileinfo.com/filetypes/camera_raw) + +# Music extensions source: + +[Audio](https://fileinfo.com/filetypes/audio) + +# Movie extensions source: + +[Movie](http://bit.ly/2wvYjyr) + +# Text extensions source: + +[Text](http://bit.ly/2wwcfZs) diff --git a/environment.py b/environment.py new file mode 100644 index 0000000..7926e30 --- /dev/null +++ b/environment.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +from setuptools import setup, find_packages +import sys, os + + +def setup_environment(): + + if sys.version_info < (3, 6): + print("Python 3.6 or higher is required...") + sys.exit(1) + with open("README.md", encoding="utf-8") as f: + longd = f.read() + + base_path = os.path.dirname(os.path.abspath(__file__)) + ext_path = os.path.join(base_path, "organise_desktop", "Extension.json") + if __name__ == "__main__": + setup( + name="OrganiseDesktop", + include_package_data=True, + packages=find_packages(), + data_files=[("OrganiseDesktop", [ext_path])], + entry_points={ + "console_scripts": ["organise_desktop = organise_desktop.Cli:main"] + }, + install_requires=[ + "BeautifulSoup4", + "requests", + "colorama", + "Py-stackExchange", + "urwid", + "crontab", + ], + requires=[ + "os", + "getpass", + "time", + "sys", + "tkinter", + ], + version="1.0", + url="https://github.com/blavejr/OrganiseDesktop.git", + keywords="Desktop Organiser", + license="MIT", + author="Remigius Kalimba", + author_email="kalimbatech@gmail.com", + description="Organise your desktop with one click.", + long_description="\n\n{}".format(longd), + ) diff --git a/organise_desktop/Clean.py b/organise_desktop/Clean.py index df21732..8ba6782 100644 --- a/organise_desktop/Clean.py +++ b/organise_desktop/Clean.py @@ -1,11 +1,12 @@ import sys, json, os from .organiseDesktop import undo, organise_desktop from .cronController import schedule_end, schedule_start + from tkinter import * from tkinter import messagebox as tkMessageBox pwd = os.path.dirname(os.path.abspath(__file__)) -Extensions = json.load(open(os.path.join(pwd, 'Extension.json'), 'r')) +Extensions = json.load(open(os.path.join(pwd, "Extension.json"), "r")) folders = list(Extensions.keys()) @@ -70,25 +71,35 @@ def __init__(self, master=None): def main(): root = Tk() # root.resizable = False # commenting this approach and applying the below one. - root.resizable( + """root.resizable( FALSE, FALSE ) # To make the application's size constant and restore button in windows as greyed out(with width=350 and height=330 as mentioned below) root.minsize(width=350, height=330) root.maxsize(width=350, height=330) - +""" """Logic to launch the app in center - start""" - positionRight = int(root.winfo_screenwidth() / 2 - 330 / 2) # considering width=330 + """ positionRight = int(root.winfo_screenwidth() / 2 - 330 / 2) # considering width=330 positionDown = int( root.winfo_screenheight() / 2 - 350 / 2 ) # considering height=350 - root.geometry("+{}+{}".format(positionRight, positionDown)) + root.geometry("+{}+{}".format(positionRight, positionDown))""" """Logic to launch the app in center - end""" - app = App(root) root.protocol("WM_DELETE_WINDOW", app.quit_all) app.mainloop() root.destroy() +def clean_desktop(): + root = Tk() + app = App(root) + root.protocol("WM_DELETE_WINDOW", app.quit_all) + app.mainloop() + try: + root.destroy() + except TclError: + pass # Handle cases where root is already destroyed + + if __name__ == "__main__": - main() + clean_desktop() diff --git a/organise_desktop/Extension.json b/organise_desktop/Extension.json index c229dc9..76201ca 100644 --- a/organise_desktop/Extension.json +++ b/organise_desktop/Extension.json @@ -1,152 +1,2307 @@ { - "Shortcuts": - [".kys",".lnk",".mat",".pif",".shb",".url",".xnk", ".desktop"], - - "Executables": - [".action",".apk",".app",".bin",".dmg",".eham",".exe",".ham",".msi",".osx",".out",".pex",".plx",".prg",".run",".scr",".upx"], - - "Malware": - [".APPLICATION",".GADGET",".CPL",".MSC",".JS",".JSE",".WS","WSF",".REG",".CSH"], - - "Folders": - [".0",".000",".7z",".7z.001",".7z.002",".a00",".a01",".a02",".ace",".agg",".ain",".alz",".apz",".ar",".arc",".archiver",".arduboy",".arh", - ".ari",".arj",".ark",".asr",".b1",".b64",".ba",".bdoc",".bh",".bndl",".boo",".bundle",".bz",".bz2",".bza",".bzip",".bzip2",".c00",".c01", - ".c02",".c10",".car",".cb7",".cba",".cbr",".cbt",".cbz",".cdz",".comppkg.hauptwerk.rar",".comppkg_hauptwerk_rar",".cp9",".cpgz",".cpt", - ".cxarchive",".czip",".dar",".dd",".deb",".dgc",".dist",".dl_",".dz",".ecs",".edz",".efw",".egg",".epi",".f",".fdp",".fp8",".fzbz",".fzpz", - ".gca",".gmz",".gz",".gz2",".gza",".gzi",".gzip",".ha",".hbc",".hbc2",".hbe",".hki",".hki1",".hki2",".hki3",".hpk",".hyp",".iadproj",".ice", - ".ipg",".ipk",".ish",".isx",".ita",".ize",".j",".jar.pack",".jgz",".jic",".jsonlz4",".kgb",".kz",".layout",".lbr",".lemon",".lha",".lhzd", - ".libzip",".lnx",".lqr",".lz",".lzh",".lzm",".lzma",".lzo",".lzx",".md",".mint",".mou",".mpkg",".mzp",".nex",".nz",".oar",".oz",".p01", - ".p19",".pack.gz",".package",".pae",".pak",".paq6",".paq7",".paq8",".paq8f",".paq8l",".paq8p",".par",".par2",".pax",".pbi",".pcv",".pea", - ".pet",".pf",".pim",".pit",".piz",".pkg",".pkg.tar.xz",".psz",".pup",".puz",".pwa",".qda",".r0",".r00",".r01",".r02",".r03",".r04",".r1", - ".r2",".r21",".r30",".rar",".rev",".rk",".rnc",".rp9",".rpm",".rss",".rte",".rz",".s00",".s01",".s02",".s7z",".sar",".sbx",".sdc",".sdn", - ".sea",".sen",".sfg",".sfs",".sfx",".sh",".shar",".shk",".shr",".sifz",".sit",".sitx",".smpf",".snappy",".snb",".spt",".sqx",".srep", - ".stproj",".sy_",".tar.bz2",".tar.gz",".tar.gz2",".tar.lz",".tar.lzma",".tar.xz",".tar.z",".taz",".tbz",".tbz2",".tg",".tgz",".tlz", - ".tlzma",".trs",".tx_",".txz",".tz",".uc2",".ufs.uzip",".uha",".uzip",".vem",".vip",".voca",".vsi",".wa",".waff",".war",".wlb",".wot", - ".xapk",".xar",".xef",".xez",".xip",".xmcdz",".xx",".xz",".xzm",".y",".yz",".yz1",".z",".z01",".z02",".z03",".z04",".zap",".zfsendtotarget", - ".zi",".zip",".zipx",".zix",".zl",".zoo",".zpi",".zsplit",".zw",".zz"], - - "Images": - [".3fr",".ai",".ari",".arr",".arw",".avatar",".awd",".bmp",".bpg",".cdmz",".cdr",".cr2",".crw",".ct",".dcr",".dds", - ".ded",".djvu",".dng",".eip",".eps",".exr",".fff",".fpx",".gif",".hdr",".hpgl",".i3d",".ico",".icon",".itc2",".iwi", - ".j2c",".j2k",".jbig2",".jfif",".jif",".jp2",".jpc",".jpe",".jpeg",".jpg",".jpg-large",".jpx",".jxr",".k25",".kdc", - ".lip",".mfw",".mos",".msp",".nef",".nrw",".orf",".ota",".pat",".pcd",".pcx",".pdn",".pi2",".pic",".picnc",".piskel", - ".png",".ppf",".psb",".psd",".pspbrush",".pwp",".pxd",".pxr",".raf",".raw",".rw2",".rwz",".sai",".spr",".sprite", - ".sprite2",".srf",".sumo",".svg",".tbn",".tga",".tif",".tiff",".tn",".tn3",".ufo",".vsdx",".webp",".x3f",".xcf",".xpm"], - - "Music": - [".5xe",".aac",".abm",".ac3",".act",".afc",".aif",".aiff",".aimppl",".alac",".als",".amr",".ang",".aup",".bidule",".bnk", - ".bun",".bww",".cgrp",".csh",".cwb",".dfc",".dff",".dig",".dm",".dmsa",".dmse",".dsf",".dsm",".dtm",".f4a",".fev",".flac", - ".flm",".flp",".frg",".gp5",".gsm",".h5b",".h5s",".ins",".isma",".krz",".kt3",".m3u",".m3u8",".m4r",".mbr",".mid",".midi", - ".minigsf",".mmlp",".mmm",".mtp",".mp3",".mpga",".mscz",".mui",".nbs","nkm",".nsa",".ogg",".omf",".omg",".ovw",".pca", - ".pcast",".pcg",".pkf",".pla",".ply",".ptxt",".qcp",".r1m",".ram",".rip",".rns",".rol",".rso",".rx2",".saf",".sbi",".sbg", - ".sdat",".sdt",".sf2",".sfk",".sfpack",".sgp",".slp",".sng",".sou",".sprg",".sseq",".sxt",".syn",".syw",".tg",".toc",".trak", - ".ust",".vag",".vsqx",".vdj",".vyf",".w64",".wav",".wma",".wus",".xfs",".xspf",".zpa",".zvd"], - - "Movies": - [".264",".3g2",".3gp",".3gp2",".3gpp",".3gpp2",".3mm",".3p2",".60d",".787",".890",".aaf",".aec",".aecap",".aegraphic",".aep", - ".aepx",".aet",".aetx",".ajp",".ale",".am",".amc",".amv",".amx",".anim",".anx",".aqt",".arcut",".arf",".asf",".asx",".avb", - ".avc",".avchd",".avd",".avi",".avm",".avp",".avs",".avv",".awlive",".axm",".axv",".bdm",".bdmv",".bdt2",".bdt3",".bik",".bin", - ".bix",".bmc",".bmk",".bnp",".box",".bs4",".bsf",".bu",".bvr",".byu",".camproj",".camrec",".camv",".cdz",".ced",".cel",".cine", - ".cip",".clk",".clpi",".cmmp",".cmmtpl",".cmproj",".cmrec",".cmv",".cpi",".cpvc",".crec",".cst",".cvc",".cx3",".d2v",".d3v", - ".dash",".dat",".dav",".db2",".dce",".dck",".dcr",".ddat",".dif",".dir",".divx",".dlx",".dmb",".dmsd",".dmsd3d",".dmsm", - ".dmsm3d",".dmss",".dmx",".dnc",".dpa",".dpg",".dream",".dsy",".dv",".dv-avi",".dv4",".dvdmedia",".dvr",".dvr-ms",".dvx", - ".dxr",".dzm",".dzp",".dzt",".edl",".evo",".exo",".eye",".eyetv",".ezt",".f4f",".f4m",".f4p",".f4v",".fbr",".fbz",".fcarch", - ".fcp",".fcproject",".ffd",".ffm",".flc",".flh",".fli",".flic",".flv",".flx",".fpdx",".ftc",".fvt",".g2m",".g64",".gcs", - ".gfp",".gifv",".gl",".gom",".grasp",".gts",".gvi",".gvp",".gxf",".h264",".hdmov",".hdv",".hkm",".ifo",".imovielibrary", - ".imoviemobile",".imovieproj",".imovieproject",".inp",".int",".ircp",".irf",".ism",".ismc",".ismclip",".ismv",".iva",".ivf", - ".ivr",".ivs",".izz",".izzy",".jdr",".jmv",".jss",".jts",".jtv",".k3g",".kdenlive",".kmv",".ktn",".lrec",".lrv",".lsf", - ".lsx",".lvix",".m15",".m1pg",".m1v",".m21",".m2a",".m2p",".m2t",".m2ts",".m2v",".m4e",".m4u",".m4v",".m75",".mani",".meta", - ".mgv",".mj2",".mjp",".mjpeg",".mjpg",".mk3d",".mkv",".mmv",".mnv",".mob",".mod",".modd",".moff",".moi",".moov",".mov", - ".movie",".mp21",".mp2v",".mp4",".mp4.infovid",".mp4v",".mpe",".mpeg",".mpeg1",".mpeg2",".mpeg4",".mpf",".mpg",".mpg2", - ".mpg4",".mpgindex",".mpl",".mpls",".mproj",".mpsub",".mpv",".mpv2",".mqv",".msdvd",".mse",".msh",".mswmm",".mt2s",".mts", - ".mtv",".mvb",".mvc",".mvd",".mve",".mvex",".mvp",".mvy",".mxf",".mxv",".mys",".n3r",".ncor",".nfv",".nsv",".ntp",".nut", - ".nuv",".nvc",".ogm",".ogv",".ogx",".orv",".osp",".otrkey",".pac",".par",".pds",".pgi",".photoshow",".piv",".pjs",".playlist", - ".plproj",".pmf",".pmv",".pns",".ppj",".prel",".pro",".pro4dvd",".pro5dvd",".proqc",".prproj",".prtl",".psb",".psh",".pssd", - ".pva",".pvr",".pxv",".qt",".qtch",".qtindex",".qtl",".qtm",".qtz",".r3d",".rcd",".rcproject",".rcrec",".rcut",".rdb",".rec", - ".rm",".rmd",".rmp",".rms",".rmv",".rmvb",".roq",".rp",".rsx",".rts",".rum",".rv",".rvid",".rvl",".san",".sbk",".sbt",".sbz", - ".scc",".scm",".scn",".screenflow",".sdv",".sec",".sedprj",".seq",".sfd",".sfera",".sfvidcap",".siv",".smi",".smil",".smk", - ".sml",".smv",".snagproj",".spl",".sqz",".srt",".ssf",".ssm",".stl",".str",".stx",".svi",".swf",".swi",".swt",".tda3mt",".tdt", - ".tdx",".theater",".thp",".tid",".tivo",".tix",".tod",".tp",".tp0",".tpd",".tpr",".trec",".trp",".ts",".tsp",".ttxt",".tvlayer", - ".tvrecording",".tvs",".tvshow",".usf",".usm",".v264",".vbc",".vc1",".vcpf",".vcr",".vcv",".vdo",".vdr",".vdx",".veg",".vem", - ".vep",".vf",".vft",".vfw",".vfz",".vgz",".vid",".video",".viewlet",".viv",".vivo",".vix",".vlab",".vmlf",".vmlt",".vob",".vp3", - ".vp6",".vp7",".vpj",".vr",".vro",".vs4",".vse",".vsp",".vtt",".w32",".wcp",".webm",".wfsp",".wgi",".wlmp",".wm",".wmd",".wmmp", - ".wmv",".wmx",".wot",".wp3",".wpl",".wsve",".wtv",".wve",".wvm",".wvx",".wxp",".xej",".xel",".xesc",".xfl",".xlmv",".xml",".xmv", - ".xvid",".y4m",".yog",".yuv",".zeg",".zm1",".zm2",".zm3",".zmv"], - - "Text": - [ ".1st",".abw",".accdb",".act",".adoc",".aim",".ans",".apkg",".apt",".arff",".asc",".ascii",".ase",".aty",".awp",".awt",".aww",".bad", - ".bbs",".bdp",".bdr",".bean",".bib",".bibtex",".bml",".bna",".boc",".brx",".btd",".bzabw",".calca",".cdz",".charset",".chart", - ".chord",".cnm",".cod",".crwl",".css",".csv",".cws",".cyi",".dca",".dfti",".dgs",".diz",".dne",".doc",".docm",".docx",".docxml", - ".docz",".dox",".dropbox",".dsc",".dvi",".dwd",".dx",".dxb",".dxp",".eio",".eit",".emf",".eml",".emlx",".emulecollection",".epp",".err", - ".etf",".etx",".euc",".fadein.template",".faq",".fbl",".fcf",".fdf",".fdr",".fds",".fdt",".fdx",".fdxt",".fft",".fgs",".flr",".fodt", - ".fountain",".fpt",".frt",".fwd",".fwdn",".gmd",".gpd",".gpn",".gsd",".gthr",".gv",".hbk",".hht",".hs",".html",".hwp",".hz",".idx", - ".iil",".ini",".ipf",".ipspot",".jarvis",".jis",".jnp",".jnt",".joe",".jp1",".jrtf",".kes",".key",".klg",".knt",".kon",".kwd",".latex",".lbt", - ".lis",".lnt",".log",".log",".pub",".lp2",".lst",".ltr",".ltx",".lue",".luf",".lwp",".lxfml",".lyt",".lyx",".man",".mbox",".mcw",".md5.txt", - ".me",".mell",".mellel",".min",".mnt",".msg",".mw",".mwd",".mwp",".nb",".ndoc",".nfo",".ngloss",".njx",".notes",".now",".numbers",".nwctxt",".nwm",".nwp", - ".ocr",".odif",".odm",".odo",".odt",".ofl",".opeico",".openbsd",".org",".ort",".ott",".p7s",".pages",".pages-tef",".pdf",".pdpcmd",".pfx",".pjt",".plantuml", - ".pmo",".pptx",".prt",".psw",".ptt",".pu",".pub",".pvj",".pvm",".pwd",".pwdp",".pwdpl",".pwi",".pwr",".qdl",".qpf",".rad",".readme",".rft", - ".ris",".rpt",".rst",".rtd",".rtf",".rtfd",".rtx",".run",".rvf",".rzk",".rzn",".saf",".safetext",".sam",".save",".scc",".scm",".scriv", - ".scrivx",".sct",".scw",".sdm",".sdoc",".sdw",".se",".session",".sgm",".sig",".skcard",".sla",".sla.gz",".smf",".sms",".ssa", - ".story",".strings",".stw",".sty",".sub",".sublime-project",".sublime-workspace",".sxg",".sxw",".tab",".tdf",".template",".tex", - ".text",".textclipping",".thp",".tlb",".tm",".tmd",".tmv",".tpc",".trelby",".tvj",".txt",".u3i",".unauth",".unx",".uof",".uot", - ".upd",".utf8",".utxt",".vct",".vnt",".vw",".wbk",".webdoc",".wn",".wp",".wp4",".wp5",".wp6",".wp7",".wpa",".wpd",".wpl",".wps", - ".wpt",".wpw",".wri",".wsd",".wtt",".wtx",".xbdoc",".xbplate",".xdl",".xlsx",".xwp",".xy",".xy3",".xyp",".xyw",".zabw",".zrtf",".zw", "xls"], - - "CAD": - [".ma", ".dxe", ".gpw", ".mb", ".mnx", ".shx", ".dwk", ".apj", ".sld", ".hdi", ".dwg", ".lli", ".aws", ".dwz", ".slb", ".dxx", ".dw2l", - ".dwt", ".dws", ".shp", ".dbt", ".dxf", ".schematic", ".pwt", ".mvi", ".blk", ".fbx", ".blend", ".chc"], - - "Programming": - [".gmo", ".dcu", ".wixmst", ".csproj", ".r", ".pjx", ".lgo", ".bcp", ".vbp", ".vdm", ".diff", ".mv", ".pyw", ".ilk", ".vdproj", ".mdzip", - ".bpg", ".resx", ".agi", ".gmd", ".proto", ".resjson", ".pri", ".gorm", ".f", ".vtv", ".xcappdata", ".groupproj", ".mf", ".sln", ".ccn", - ".sup", ".xquery", ".a", ".cob", ".java", ".wdgtproj", ".edml", ".py", ".ppc", ".scc", ".xap", ".rdlc", ".lnt", ".bluej", ".fgl", ".clw", - ".gs3", ".ypr", ".ads", ".vcp", ".sud", ".nib", ".s", ".tlh", ".dcproj", ".textfactory", ".ssc", ".bb", ".dsgm", ".msha", ".vtml", ".inc", - ".lsproj", ".fxc", ".ui", ".erb", ".iml", ".ccp", ".fpm", ".octest", ".kdevprj", ".addin", ".dec", ".psm1", ".wixproj", ".bbc", ".csn", - ".rbc", ".tpu", ".clips", ".xcdatamodeld", ".vspx", ".awk", ".cd", ".wdgt", ".dex", ".dpkw", ".gfar", ".xql", ".caf", ".cod", ".edmx", - ".mss", ".pb", ".vc", ".rodl", ".cpp", ".xcarchive", ".m4", ".vsp", ".def", ".for", ".nbc", ".sas", ".tli", ".ist", ".rpy", ".vspscc", - ".gemspec", ".vdp", ".wsp", ".tld", ".sma", ".gem", ".lisp", ".framework", ".src", ".markdown", ".pbk", ".ftn", ".wixout", ".iwb", ".ctl", - ".md", ".csx", ".forth", ".o", ".fsproj", ".cxp", ".refresh", ".qpr", ".dob", ".msl", ".pkgundef", ".idt", ".ise", ".licx", ".swd", ".caproj", - ".bf", ".nk", ".mshc", ".pde", ".rbp", ".a2w", ".capx", ".class", ".hh", ".inl", ".dox", ".v12", ".nxc", ".nw", ".mod", ".bsc", - ".pdm", ".gs", ".ned", ".aps", ".appxupload", ".aidl", ".sb2", ".abc", ".tns", ".twig", ".rc2", ".vgc", ".ymp", ".dtd", ".c", - ".fxpl", ".sltng", ".magik", ".vcxproj", ".iws", ".dmd", ".bpl", ".dpr", ".jspf", ".lit", ".mm", ".xaml", ".cu", ".tu", ".wxl", - ".sdef", ".exw", ".vb", ".bdsproj", ".am5", ".pl", ".eql", ".uml", ".cbl", ".config", ".dba", ".luc", ".ss", ".pli", ".dsp", ".rexx", - ".nsh", ".wixpdb", ".greenfoot", ".ccs", ".vsmproj", ".tmlanguage", ".mpr", ".targets", ".pbg", ".ml", ".psc", ".nuspec", ".v11", - ".trx", ".has", ".dbml", ".mo", ".testsettings", ".rsrc", ".cp", ".fbp", ".pbxuser", ".y", ".idl", ".df1", ".asc", ".dfm", ".resw", - ".omo", ".nls", ".oca", ".gm81", ".frx", ".lucidsnippet", ".as3proj", ".dm1", ".xsd", ".vm", ".mak", ".msp", ".rav", ".spec", ".l", - ".swift", ".dcuil", ".rkt", ".vsmacros", ".ccgame", ".cc", ".fsi", ".ple", ".lbs", ".playground", ".ged", ".ncb", ".snippet", ".am4", - ".xcworkspace", ".licenses", ".sym", ".lbi", ".cxx", ".lds", ".xib", ".wdp", ".h", ".smali", ".gmx", ".ocx", ".ino", ".workspace", - ".pod", ".vbz", ".p3d", ".yml", ".pro", ".cdf", ".ctxt", ".xojo_project", ".plc", ".fxcproj", ".entitlements", ".au3", ".groovy", - ".idb", ".apa", ".ism", ".v", ".bet", ".hxx", ".pbxproj", ".pxd", ".xoml", ".rbw", ".testrunconfig", ".cs", ".t", ".pcp", ".lua", - ".xq", ".wxi", ".pl1", ".gch", ".prg", ".fxl", ".xpp", ".asvf", ".p", ".jic", ".suo", ".wxs", ".hal", ".i", ".m", ".cfc", ".pkgdef", - ".yaml", ".vbx", ".mom", ".xcconfig", ".wpw", ".kpl", ".pm", ".w", ".wdl", ".nqc", ".ipr", ".cbp", ".lxsproj", ".pwn", - ".scriptsuite", ".xamlx", ".tcl", ".iconset", ".rul", ".vbproj", ".rss", ".rnc", ".fsscript", ".ent", ".vtm", ".f90", - ".artproj", ".asm", ".pbxbtree", ".sqlproj", ".acd", ".tur", ".jcp", ".as2proj", ".d", ".ex", ".lproj", ".scriptterminology", - ".cls", ".myapp", ".tds", ".ane", ".hs", ".lhs", ".res", ".gm6", ".pas", ".ptl", ".mfa", ".dcp", ".vbg", ".jpr", ".vhd", ".dpk", - ".mrt", ".exp", ".pyd", ".xojo_xml_project", ".deviceids", ".sh", ".livecode", ".fbz7", ".as", ".pot", ".xqm", ".nvv", ".pika", - ".jsfl", ".ftl", ".mer", ".alb", ".s19", ".resources", ".patch", ".sb", ".wixobj", ".gitignore", ".hpp", ".nsi", ".gmk", ".hbs", - ".vsz", ".wixmsp", ".xcsnapshots", ".haml", ".xojo_binary_project", ".rb", ".wsc", ".jpx", ".vcproj", ".bbprojectd", ".am6", ".arsc", - ".bbproject", ".ap_", ".4db", ".swc", ".sc", ".am7", ".bs2", ".tk", ".pbj", ".asi", ".mcp", ".dbo", ".ipch", ".ph", ".dproj", - ".mxml", ".xcodeproj", ".wiq", ".slogo", ".nfm", ".aia", ".ltb", ".sbproj", ".ctp", ".dbpro", ".mk", ".wixlib", ".w32", - ".dbproj", ".fsx", ".pyx", ".tmproj", ".csi", ".brx", ".gld", ".wdw", ".4th", ".svn", ".xt", ".ahk", ".dgml", ".xojo_menu", - ".gszip", ".odl", ".appx", ".fla", ".gameproj", ".fxml", ".so", ".csp", ".nupkg", ".bas", ".storyboard", ".owl", ".vssscc", - ".erl", ".pch", ".rise", ".gitattributes", ".fs", ".autoplay", ".tt", ".hpf", ".dpl", ".po", ".b", ".ssi", ".dgsl", - ".cvsrc", ".mshi", ".rc", ".vsps", ".kdevelop", ".vsmdi", ".json", ".brM", ".c"], - - "Misc": - [".crx", ".jar", ".mht", ".tar", ".3ga", ".aa", ".aax", ".aifc", ".ape", ".au", ".awb", ".cda", ".iff", ".kar", ".koz", ".m4a", ".m4p", - ".mmf", ".mp2", ".mpa", ".mpc", ".nfa", ".oma", ".opus", ".ra", ".rta", ".Format", ".3dm", ".3ds", ".max", ".obj", ".aae", ".adt", - ".clp", ".cma", ".efx", ".fcpevent", ".flo", ".gbr", ".gcw", ".gms", ".i5z", ".ip", ".itl", ".mtw", ".nfi", ".nfs", ".one", ".qb2011", - ".quickendata", ".sdf", ".tax2012", ".tax2014", ".tax2016", ".vcf", ".vcs", ".bup", ".crypt", ".db", ".dbf", ".mdb", ".pdb", ".sql", ".kv", - ".Xib", ".chm", ".csk", ".dot", ".dotx", ".oxps", ".pmd", ".shs", ".vmg", ".xps", ".acsm", ".apnx", ".azw", ".azw3", ".epub", ".fb2", ".lrf", - ".mbp", ".mobi", ".opf", ".prc", ".tcr", ".vbk", ".air", ".bat", ".cgi", ".cmd", ".com", ".ds", ".gadget", ".ipa", ".wsf", ".8bi", ".bak", ".bfc", - ".cmf", ".crdownload", ".cue", ".dao", ".dbx", ".dem", ".dic", ".epc", ".flt", ".fnt", ".fon", ".gam", ".gho", ".gpx", ".grp", ".hex", ".hqx", - ".ics", ".img", ".iso", ".jad", ".kml", ".kmz", ".map", ".mdf", ".mim", ".mtb", ".nes", ".ori", ".otf", ".part", ".pes", ".plugin", ".ps", ".qxp", - ".rem", ".rom", ".sav", ".t65", ".tec", ".tmp", ".toast", ".torrent", ".ttf", ".uue", ".vcd", ".xll", ".dtp", ".indd", ".mdi", ".p65", ".qxd", ".rels", - ".flipchart", ".odp", ".pps", ".ppsx", ".ppt", ".pptm", ".art", ".dcm", ".flif", ".heic", ".ithmb", ".mac", ".pct", ".pef", ".pgm", ".pict", ".plist", - ".pspimage", ".rwl", ".sfw", ".sr2", ".thm", ".wbmp", ".api", ".cdt", ".cfg", ".dun", ".fm3", ".gid", ".ht", ".icm", ".inf", ".prf", ".ods", ".wk3", - ".wks", ".xlr", ".xlsb", ".xlsm", ".ani", ".bashrc", ".bash_history", ".bash_profile", ".bud", ".cab", ".cat", ".cpl", ".cur", ".deskthemepack", - ".dev", ".dit", ".dll", ".dmp", ".drv", ".dvd", ".ebd", ".ffl", ".ffo", ".fota", ".hiv", ".hlp", ".htt", ".icl", ".icns", ".iconpackage", ".ion", - ".iptheme", ".mlc", ".nb0", ".nt", ".pck", ".pnf", ".pol", ".prop", ".qvm", ".reg", ".sys", ".cvs", ".emz", ".mix", ".odg", ".pd", ".vsd", ".wmf", - ".wpg", ".dvsd", ".esp3", ".mepx", ".vproj", ".asp", ".aspx", ".cer", ".cfm", ".cfml", ".csr", ".do", ".htm", ".js", ".jsp", ".nzb", ".php", ".webloc", - ".xfdl", ".xhtml", ".!BT", ".UT", ".1", ".ADADOWNLOAD"] + "Shortcuts": [ + ".kys", + ".lnk", + ".mat", + ".pif", + ".shb", + ".url", + ".xnk", + ".desktop" + ], + "Executables": [ + ".action", + ".apk", + ".app", + ".bin", + ".dmg", + ".eham", + ".exe", + ".ham", + ".msi", + ".osx", + ".out", + ".pex", + ".plx", + ".prg", + ".run", + ".scr", + ".upx" + ], + "Malware": [ + ".APPLICATION", + ".GADGET", + ".CPL", + ".MSC", + ".JS", + ".JSE", + ".WS", + "WSF", + ".REG", + ".CSH" + ], + "Folders": [ + ".0", + ".000", + ".7z", + ".7z.001", + ".7z.002", + ".a00", + ".a01", + ".a02", + ".ace", + ".agg", + ".ain", + ".alz", + ".apz", + ".ar", + ".arc", + ".archiver", + ".arduboy", + ".arh", + ".ari", + ".arj", + ".ark", + ".asr", + ".b1", + ".b64", + ".ba", + ".bdoc", + ".bh", + ".bndl", + ".boo", + ".bundle", + ".bz", + ".bz2", + ".bza", + ".bzip", + ".bzip2", + ".c00", + ".c01", + ".c02", + ".c10", + ".car", + ".cb7", + ".cba", + ".cbr", + ".cbt", + ".cbz", + ".cdz", + ".comppkg.hauptwerk.rar", + ".comppkg_hauptwerk_rar", + ".cp9", + ".cpgz", + ".cpt", + ".cxarchive", + ".czip", + ".dar", + ".dd", + ".deb", + ".dgc", + ".dist", + ".dl_", + ".dz", + ".ecs", + ".edz", + ".efw", + ".egg", + ".epi", + ".f", + ".fdp", + ".fp8", + ".fzbz", + ".fzpz", + ".gca", + ".gmz", + ".gz", + ".gz2", + ".gza", + ".gzi", + ".gzip", + ".ha", + ".hbc", + ".hbc2", + ".hbe", + ".hki", + ".hki1", + ".hki2", + ".hki3", + ".hpk", + ".hyp", + ".iadproj", + ".ice", + ".ipg", + ".ipk", + ".ish", + ".isx", + ".ita", + ".ize", + ".j", + ".jar.pack", + ".jgz", + ".jic", + ".jsonlz4", + ".kgb", + ".kz", + ".layout", + ".lbr", + ".lemon", + ".lha", + ".lhzd", + ".libzip", + ".lnx", + ".lqr", + ".lz", + ".lzh", + ".lzm", + ".lzma", + ".lzo", + ".lzx", + ".md", + ".mint", + ".mou", + ".mpkg", + ".mzp", + ".nex", + ".nz", + ".oar", + ".oz", + ".p01", + ".p19", + ".pack.gz", + ".package", + ".pae", + ".pak", + ".paq6", + ".paq7", + ".paq8", + ".paq8f", + ".paq8l", + ".paq8p", + ".par", + ".par2", + ".pax", + ".pbi", + ".pcv", + ".pea", + ".pet", + ".pf", + ".pim", + ".pit", + ".piz", + ".pkg", + ".pkg.tar.xz", + ".psz", + ".pup", + ".puz", + ".pwa", + ".qda", + ".r0", + ".r00", + ".r01", + ".r02", + ".r03", + ".r04", + ".r1", + ".r2", + ".r21", + ".r30", + ".rar", + ".rev", + ".rk", + ".rnc", + ".rp9", + ".rpm", + ".rss", + ".rte", + ".rz", + ".s00", + ".s01", + ".s02", + ".s7z", + ".sar", + ".sbx", + ".sdc", + ".sdn", + ".sea", + ".sen", + ".sfg", + ".sfs", + ".sfx", + ".sh", + ".shar", + ".shk", + ".shr", + ".sifz", + ".sit", + ".sitx", + ".smpf", + ".snappy", + ".snb", + ".spt", + ".sqx", + ".srep", + ".stproj", + ".sy_", + ".tar.bz2", + ".tar.gz", + ".tar.gz2", + ".tar.lz", + ".tar.lzma", + ".tar.xz", + ".tar.z", + ".taz", + ".tbz", + ".tbz2", + ".tg", + ".tgz", + ".tlz", + ".tlzma", + ".trs", + ".tx_", + ".txz", + ".tz", + ".uc2", + ".ufs.uzip", + ".uha", + ".uzip", + ".vem", + ".vip", + ".voca", + ".vsi", + ".wa", + ".waff", + ".war", + ".wlb", + ".wot", + ".xapk", + ".xar", + ".xef", + ".xez", + ".xip", + ".xmcdz", + ".xx", + ".xz", + ".xzm", + ".y", + ".yz", + ".yz1", + ".z", + ".z01", + ".z02", + ".z03", + ".z04", + ".zap", + ".zfsendtotarget", + ".zi", + ".zip", + ".zipx", + ".zix", + ".zl", + ".zoo", + ".zpi", + ".zsplit", + ".zw", + ".zz" + ], + "Images": [ + ".3fr", + ".ai", + ".ari", + ".arr", + ".arw", + ".avatar", + ".awd", + ".bmp", + ".bpg", + ".cdmz", + ".cdr", + ".cr2", + ".crw", + ".ct", + ".dcr", + ".dds", + ".ded", + ".djvu", + ".dng", + ".eip", + ".eps", + ".exr", + ".fff", + ".fpx", + ".gif", + ".hdr", + ".hpgl", + ".i3d", + ".ico", + ".icon", + ".itc2", + ".iwi", + ".j2c", + ".j2k", + ".jbig2", + ".jfif", + ".jif", + ".jp2", + ".jpc", + ".jpe", + ".jpeg", + ".jpg", + ".jpg-large", + ".jpx", + ".jxr", + ".k25", + ".kdc", + ".lip", + ".mfw", + ".mos", + ".msp", + ".nef", + ".nrw", + ".orf", + ".ota", + ".pat", + ".pcd", + ".pcx", + ".pdn", + ".pi2", + ".pic", + ".picnc", + ".piskel", + ".png", + ".ppf", + ".psb", + ".psd", + ".pspbrush", + ".pwp", + ".pxd", + ".pxr", + ".raf", + ".raw", + ".rw2", + ".rwz", + ".sai", + ".spr", + ".sprite", + ".sprite2", + ".srf", + ".sumo", + ".svg", + ".tbn", + ".tga", + ".tif", + ".tiff", + ".tn", + ".tn3", + ".ufo", + ".vsdx", + ".webp", + ".x3f", + ".xcf", + ".xpm" + ], + "Music": [ + ".5xe", + ".aac", + ".abm", + ".ac3", + ".act", + ".afc", + ".aif", + ".aiff", + ".aimppl", + ".alac", + ".als", + ".amr", + ".ang", + ".aup", + ".bidule", + ".bnk", + ".bun", + ".bww", + ".cgrp", + ".csh", + ".cwb", + ".dfc", + ".dff", + ".dig", + ".dm", + ".dmsa", + ".dmse", + ".dsf", + ".dsm", + ".dtm", + ".f4a", + ".fev", + ".flac", + ".flm", + ".flp", + ".frg", + ".gp5", + ".gsm", + ".h5b", + ".h5s", + ".ins", + ".isma", + ".krz", + ".kt3", + ".m3u", + ".m3u8", + ".m4r", + ".mbr", + ".mid", + ".midi", + ".minigsf", + ".mmlp", + ".mmm", + ".mtp", + ".mp3", + ".mpga", + ".mscz", + ".mui", + ".nbs", + "nkm", + ".nsa", + ".ogg", + ".omf", + ".omg", + ".ovw", + ".pca", + ".pcast", + ".pcg", + ".pkf", + ".pla", + ".ply", + ".ptxt", + ".qcp", + ".r1m", + ".ram", + ".rip", + ".rns", + ".rol", + ".rso", + ".rx2", + ".saf", + ".sbi", + ".sbg", + ".sdat", + ".sdt", + ".sf2", + ".sfk", + ".sfpack", + ".sgp", + ".slp", + ".sng", + ".sou", + ".sprg", + ".sseq", + ".sxt", + ".syn", + ".syw", + ".tg", + ".toc", + ".trak", + ".ust", + ".vag", + ".vsqx", + ".vdj", + ".vyf", + ".w64", + ".wav", + ".wma", + ".wus", + ".xfs", + ".xspf", + ".zpa", + ".zvd" + ], + "Movies": [ + ".264", + ".3g2", + ".3gp", + ".3gp2", + ".3gpp", + ".3gpp2", + ".3mm", + ".3p2", + ".60d", + ".787", + ".890", + ".aaf", + ".aec", + ".aecap", + ".aegraphic", + ".aep", + ".aepx", + ".aet", + ".aetx", + ".ajp", + ".ale", + ".am", + ".amc", + ".amv", + ".amx", + ".anim", + ".anx", + ".aqt", + ".arcut", + ".arf", + ".asf", + ".asx", + ".avb", + ".avc", + ".avchd", + ".avd", + ".avi", + ".avm", + ".avp", + ".avs", + ".avv", + ".awlive", + ".axm", + ".axv", + ".bdm", + ".bdmv", + ".bdt2", + ".bdt3", + ".bik", + ".bin", + ".bix", + ".bmc", + ".bmk", + ".bnp", + ".box", + ".bs4", + ".bsf", + ".bu", + ".bvr", + ".byu", + ".camproj", + ".camrec", + ".camv", + ".cdz", + ".ced", + ".cel", + ".cine", + ".cip", + ".clk", + ".clpi", + ".cmmp", + ".cmmtpl", + ".cmproj", + ".cmrec", + ".cmv", + ".cpi", + ".cpvc", + ".crec", + ".cst", + ".cvc", + ".cx3", + ".d2v", + ".d3v", + ".dash", + ".dat", + ".dav", + ".db2", + ".dce", + ".dck", + ".dcr", + ".ddat", + ".dif", + ".dir", + ".divx", + ".dlx", + ".dmb", + ".dmsd", + ".dmsd3d", + ".dmsm", + ".dmsm3d", + ".dmss", + ".dmx", + ".dnc", + ".dpa", + ".dpg", + ".dream", + ".dsy", + ".dv", + ".dv-avi", + ".dv4", + ".dvdmedia", + ".dvr", + ".dvr-ms", + ".dvx", + ".dxr", + ".dzm", + ".dzp", + ".dzt", + ".edl", + ".evo", + ".exo", + ".eye", + ".eyetv", + ".ezt", + ".f4f", + ".f4m", + ".f4p", + ".f4v", + ".fbr", + ".fbz", + ".fcarch", + ".fcp", + ".fcproject", + ".ffd", + ".ffm", + ".flc", + ".flh", + ".fli", + ".flic", + ".flv", + ".flx", + ".fpdx", + ".ftc", + ".fvt", + ".g2m", + ".g64", + ".gcs", + ".gfp", + ".gifv", + ".gl", + ".gom", + ".grasp", + ".gts", + ".gvi", + ".gvp", + ".gxf", + ".h264", + ".hdmov", + ".hdv", + ".hkm", + ".ifo", + ".imovielibrary", + ".imoviemobile", + ".imovieproj", + ".imovieproject", + ".inp", + ".int", + ".ircp", + ".irf", + ".ism", + ".ismc", + ".ismclip", + ".ismv", + ".iva", + ".ivf", + ".ivr", + ".ivs", + ".izz", + ".izzy", + ".jdr", + ".jmv", + ".jss", + ".jts", + ".jtv", + ".k3g", + ".kdenlive", + ".kmv", + ".ktn", + ".lrec", + ".lrv", + ".lsf", + ".lsx", + ".lvix", + ".m15", + ".m1pg", + ".m1v", + ".m21", + ".m2a", + ".m2p", + ".m2t", + ".m2ts", + ".m2v", + ".m4e", + ".m4u", + ".m4v", + ".m75", + ".mani", + ".meta", + ".mgv", + ".mj2", + ".mjp", + ".mjpeg", + ".mjpg", + ".mk3d", + ".mkv", + ".mmv", + ".mnv", + ".mob", + ".mod", + ".modd", + ".moff", + ".moi", + ".moov", + ".mov", + ".movie", + ".mp21", + ".mp2v", + ".mp4", + ".mp4.infovid", + ".mp4v", + ".mpe", + ".mpeg", + ".mpeg1", + ".mpeg2", + ".mpeg4", + ".mpf", + ".mpg", + ".mpg2", + ".mpg4", + ".mpgindex", + ".mpl", + ".mpls", + ".mproj", + ".mpsub", + ".mpv", + ".mpv2", + ".mqv", + ".msdvd", + ".mse", + ".msh", + ".mswmm", + ".mt2s", + ".mts", + ".mtv", + ".mvb", + ".mvc", + ".mvd", + ".mve", + ".mvex", + ".mvp", + ".mvy", + ".mxf", + ".mxv", + ".mys", + ".n3r", + ".ncor", + ".nfv", + ".nsv", + ".ntp", + ".nut", + ".nuv", + ".nvc", + ".ogm", + ".ogv", + ".ogx", + ".orv", + ".osp", + ".otrkey", + ".pac", + ".par", + ".pds", + ".pgi", + ".photoshow", + ".piv", + ".pjs", + ".playlist", + ".plproj", + ".pmf", + ".pmv", + ".pns", + ".ppj", + ".prel", + ".pro", + ".pro4dvd", + ".pro5dvd", + ".proqc", + ".prproj", + ".prtl", + ".psb", + ".psh", + ".pssd", + ".pva", + ".pvr", + ".pxv", + ".qt", + ".qtch", + ".qtindex", + ".qtl", + ".qtm", + ".qtz", + ".r3d", + ".rcd", + ".rcproject", + ".rcrec", + ".rcut", + ".rdb", + ".rec", + ".rm", + ".rmd", + ".rmp", + ".rms", + ".rmv", + ".rmvb", + ".roq", + ".rp", + ".rsx", + ".rts", + ".rum", + ".rv", + ".rvid", + ".rvl", + ".san", + ".sbk", + ".sbt", + ".sbz", + ".scc", + ".scm", + ".scn", + ".screenflow", + ".sdv", + ".sec", + ".sedprj", + ".seq", + ".sfd", + ".sfera", + ".sfvidcap", + ".siv", + ".smi", + ".smil", + ".smk", + ".sml", + ".smv", + ".snagproj", + ".spl", + ".sqz", + ".srt", + ".ssf", + ".ssm", + ".stl", + ".str", + ".stx", + ".svi", + ".swf", + ".swi", + ".swt", + ".tda3mt", + ".tdt", + ".tdx", + ".theater", + ".thp", + ".tid", + ".tivo", + ".tix", + ".tod", + ".tp", + ".tp0", + ".tpd", + ".tpr", + ".trec", + ".trp", + ".ts", + ".tsp", + ".ttxt", + ".tvlayer", + ".tvrecording", + ".tvs", + ".tvshow", + ".usf", + ".usm", + ".v264", + ".vbc", + ".vc1", + ".vcpf", + ".vcr", + ".vcv", + ".vdo", + ".vdr", + ".vdx", + ".veg", + ".vem", + ".vep", + ".vf", + ".vft", + ".vfw", + ".vfz", + ".vgz", + ".vid", + ".video", + ".viewlet", + ".viv", + ".vivo", + ".vix", + ".vlab", + ".vmlf", + ".vmlt", + ".vob", + ".vp3", + ".vp6", + ".vp7", + ".vpj", + ".vr", + ".vro", + ".vs4", + ".vse", + ".vsp", + ".vtt", + ".w32", + ".wcp", + ".webm", + ".wfsp", + ".wgi", + ".wlmp", + ".wm", + ".wmd", + ".wmmp", + ".wmv", + ".wmx", + ".wot", + ".wp3", + ".wpl", + ".wsve", + ".wtv", + ".wve", + ".wvm", + ".wvx", + ".wxp", + ".xej", + ".xel", + ".xesc", + ".xfl", + ".xlmv", + ".xml", + ".xmv", + ".xvid", + ".y4m", + ".yog", + ".yuv", + ".zeg", + ".zm1", + ".zm2", + ".zm3", + ".zmv" + ], + "Text": [ + ".1st", + ".abw", + ".accdb", + ".act", + ".adoc", + ".aim", + ".ans", + ".apkg", + ".apt", + ".arff", + ".asc", + ".ascii", + ".ase", + ".aty", + ".awp", + ".awt", + ".aww", + ".bad", + ".bbs", + ".bdp", + ".bdr", + ".bean", + ".bib", + ".bibtex", + ".bml", + ".bna", + ".boc", + ".brx", + ".btd", + ".bzabw", + ".calca", + ".cdz", + ".charset", + ".chart", + ".chord", + ".cnm", + ".cod", + ".crwl", + ".css", + ".csv", + ".cws", + ".cyi", + ".dca", + ".dfti", + ".dgs", + ".diz", + ".dne", + ".doc", + ".docm", + ".docx", + ".docxml", + ".docz", + ".dox", + ".dropbox", + ".dsc", + ".dvi", + ".dwd", + ".dx", + ".dxb", + ".dxp", + ".eio", + ".eit", + ".emf", + ".eml", + ".emlx", + ".emulecollection", + ".epp", + ".err", + ".etf", + ".etx", + ".euc", + ".fadein.template", + ".faq", + ".fbl", + ".fcf", + ".fdf", + ".fdr", + ".fds", + ".fdt", + ".fdx", + ".fdxt", + ".fft", + ".fgs", + ".flr", + ".fodt", + ".fountain", + ".fpt", + ".frt", + ".fwd", + ".fwdn", + ".gmd", + ".gpd", + ".gpn", + ".gsd", + ".gthr", + ".gv", + ".hbk", + ".hht", + ".hs", + ".html", + ".hwp", + ".hz", + ".idx", + ".iil", + ".ini", + ".ipf", + ".ipspot", + ".jarvis", + ".jis", + ".jnp", + ".jnt", + ".joe", + ".jp1", + ".jrtf", + ".kes", + ".key", + ".klg", + ".knt", + ".kon", + ".kwd", + ".latex", + ".lbt", + ".lis", + ".lnt", + ".log", + ".log", + ".pub", + ".lp2", + ".lst", + ".ltr", + ".ltx", + ".lue", + ".luf", + ".lwp", + ".lxfml", + ".lyt", + ".lyx", + ".man", + ".mbox", + ".mcw", + ".md5.txt", + ".me", + ".mell", + ".mellel", + ".min", + ".mnt", + ".msg", + ".mw", + ".mwd", + ".mwp", + ".nb", + ".ndoc", + ".nfo", + ".ngloss", + ".njx", + ".notes", + ".now", + ".numbers", + ".nwctxt", + ".nwm", + ".nwp", + ".ocr", + ".odif", + ".odm", + ".odo", + ".odt", + ".ofl", + ".opeico", + ".openbsd", + ".org", + ".ort", + ".ott", + ".p7s", + ".pages", + ".pages-tef", + ".pdf", + ".pdpcmd", + ".pfx", + ".pjt", + ".plantuml", + ".pmo", + ".pptx", + ".prt", + ".psw", + ".ptt", + ".pu", + ".pub", + ".pvj", + ".pvm", + ".pwd", + ".pwdp", + ".pwdpl", + ".pwi", + ".pwr", + ".qdl", + ".qpf", + ".rad", + ".readme", + ".rft", + ".ris", + ".rpt", + ".rst", + ".rtd", + ".rtf", + ".rtfd", + ".rtx", + ".run", + ".rvf", + ".rzk", + ".rzn", + ".saf", + ".safetext", + ".sam", + ".save", + ".scc", + ".scm", + ".scriv", + ".scrivx", + ".sct", + ".scw", + ".sdm", + ".sdoc", + ".sdw", + ".se", + ".session", + ".sgm", + ".sig", + ".skcard", + ".sla", + ".sla.gz", + ".smf", + ".sms", + ".ssa", + ".story", + ".strings", + ".stw", + ".sty", + ".sub", + ".sublime-project", + ".sublime-workspace", + ".sxg", + ".sxw", + ".tab", + ".tdf", + ".template", + ".tex", + ".text", + ".textclipping", + ".thp", + ".tlb", + ".tm", + ".tmd", + ".tmv", + ".tpc", + ".trelby", + ".tvj", + ".txt", + ".u3i", + ".unauth", + ".unx", + ".uof", + ".uot", + ".upd", + ".utf8", + ".utxt", + ".vct", + ".vnt", + ".vw", + ".wbk", + ".webdoc", + ".wn", + ".wp", + ".wp4", + ".wp5", + ".wp6", + ".wp7", + ".wpa", + ".wpd", + ".wpl", + ".wps", + ".wpt", + ".wpw", + ".wri", + ".wsd", + ".wtt", + ".wtx", + ".xbdoc", + ".xbplate", + ".xdl", + ".xlsx", + ".xwp", + ".xy", + ".xy3", + ".xyp", + ".xyw", + ".zabw", + ".zrtf", + ".zw", + "xls" + ], + "CAD": [ + ".ma", + ".dxe", + ".gpw", + ".mb", + ".mnx", + ".shx", + ".dwk", + ".apj", + ".sld", + ".hdi", + ".dwg", + ".lli", + ".aws", + ".dwz", + ".slb", + ".dxx", + ".dw2l", + ".dwt", + ".dws", + ".shp", + ".dbt", + ".dxf", + ".schematic", + ".pwt", + ".mvi", + ".blk", + ".fbx", + ".blend", + ".chc" + ], + "Programming": [ + ".gmo", + ".dcu", + ".wixmst", + ".csproj", + ".r", + ".pjx", + ".lgo", + ".bcp", + ".vbp", + ".vdm", + ".diff", + ".mv", + ".pyw", + ".ilk", + ".vdproj", + ".mdzip", + ".bpg", + ".resx", + ".agi", + ".gmd", + ".proto", + ".resjson", + ".pri", + ".gorm", + ".f", + ".vtv", + ".xcappdata", + ".groupproj", + ".mf", + ".sln", + ".ccn", + ".sup", + ".xquery", + ".a", + ".cob", + ".java", + ".wdgtproj", + ".edml", + ".py", + ".ppc", + ".scc", + ".xap", + ".rdlc", + ".lnt", + ".bluej", + ".fgl", + ".clw", + ".gs3", + ".ypr", + ".ads", + ".vcp", + ".sud", + ".nib", + ".s", + ".tlh", + ".dcproj", + ".textfactory", + ".ssc", + ".bb", + ".dsgm", + ".msha", + ".vtml", + ".inc", + ".lsproj", + ".fxc", + ".ui", + ".erb", + ".iml", + ".ccp", + ".fpm", + ".octest", + ".kdevprj", + ".addin", + ".dec", + ".psm1", + ".wixproj", + ".bbc", + ".csn", + ".rbc", + ".tpu", + ".clips", + ".xcdatamodeld", + ".vspx", + ".awk", + ".cd", + ".wdgt", + ".dex", + ".dpkw", + ".gfar", + ".xql", + ".caf", + ".cod", + ".edmx", + ".mss", + ".pb", + ".vc", + ".rodl", + ".cpp", + ".xcarchive", + ".m4", + ".vsp", + ".def", + ".for", + ".nbc", + ".sas", + ".tli", + ".ist", + ".rpy", + ".vspscc", + ".gemspec", + ".vdp", + ".wsp", + ".tld", + ".sma", + ".gem", + ".lisp", + ".framework", + ".src", + ".markdown", + ".pbk", + ".ftn", + ".wixout", + ".iwb", + ".ctl", + ".md", + ".csx", + ".forth", + ".o", + ".fsproj", + ".cxp", + ".refresh", + ".qpr", + ".dob", + ".msl", + ".pkgundef", + ".idt", + ".ise", + ".licx", + ".swd", + ".caproj", + ".bf", + ".nk", + ".mshc", + ".pde", + ".rbp", + ".a2w", + ".capx", + ".class", + ".hh", + ".inl", + ".dox", + ".v12", + ".nxc", + ".nw", + ".mod", + ".bsc", + ".pdm", + ".gs", + ".ned", + ".aps", + ".appxupload", + ".aidl", + ".sb2", + ".abc", + ".tns", + ".twig", + ".rc2", + ".vgc", + ".ymp", + ".dtd", + ".c", + ".fxpl", + ".sltng", + ".magik", + ".vcxproj", + ".iws", + ".dmd", + ".bpl", + ".dpr", + ".jspf", + ".lit", + ".mm", + ".xaml", + ".cu", + ".tu", + ".wxl", + ".sdef", + ".exw", + ".vb", + ".bdsproj", + ".am5", + ".pl", + ".eql", + ".uml", + ".cbl", + ".config", + ".dba", + ".luc", + ".ss", + ".pli", + ".dsp", + ".rexx", + ".nsh", + ".wixpdb", + ".greenfoot", + ".ccs", + ".vsmproj", + ".tmlanguage", + ".mpr", + ".targets", + ".pbg", + ".ml", + ".psc", + ".nuspec", + ".v11", + ".trx", + ".has", + ".dbml", + ".mo", + ".testsettings", + ".rsrc", + ".cp", + ".fbp", + ".pbxuser", + ".y", + ".idl", + ".df1", + ".asc", + ".dfm", + ".resw", + ".omo", + ".nls", + ".oca", + ".gm81", + ".frx", + ".lucidsnippet", + ".as3proj", + ".dm1", + ".xsd", + ".vm", + ".mak", + ".msp", + ".rav", + ".spec", + ".l", + ".swift", + ".dcuil", + ".rkt", + ".vsmacros", + ".ccgame", + ".cc", + ".fsi", + ".ple", + ".lbs", + ".playground", + ".ged", + ".ncb", + ".snippet", + ".am4", + ".xcworkspace", + ".licenses", + ".sym", + ".lbi", + ".cxx", + ".lds", + ".xib", + ".wdp", + ".h", + ".smali", + ".gmx", + ".ocx", + ".ino", + ".workspace", + ".pod", + ".vbz", + ".p3d", + ".yml", + ".pro", + ".cdf", + ".ctxt", + ".xojo_project", + ".plc", + ".fxcproj", + ".entitlements", + ".au3", + ".groovy", + ".idb", + ".apa", + ".ism", + ".v", + ".bet", + ".hxx", + ".pbxproj", + ".pxd", + ".xoml", + ".rbw", + ".testrunconfig", + ".cs", + ".t", + ".pcp", + ".lua", + ".xq", + ".wxi", + ".pl1", + ".gch", + ".prg", + ".fxl", + ".xpp", + ".asvf", + ".p", + ".jic", + ".suo", + ".wxs", + ".hal", + ".i", + ".m", + ".cfc", + ".pkgdef", + ".yaml", + ".vbx", + ".mom", + ".xcconfig", + ".wpw", + ".kpl", + ".pm", + ".w", + ".wdl", + ".nqc", + ".ipr", + ".cbp", + ".lxsproj", + ".pwn", + ".scriptsuite", + ".xamlx", + ".tcl", + ".iconset", + ".rul", + ".vbproj", + ".rss", + ".rnc", + ".fsscript", + ".ent", + ".vtm", + ".f90", + ".artproj", + ".asm", + ".pbxbtree", + ".sqlproj", + ".acd", + ".tur", + ".jcp", + ".as2proj", + ".d", + ".ex", + ".lproj", + ".scriptterminology", + ".cls", + ".myapp", + ".tds", + ".ane", + ".hs", + ".lhs", + ".res", + ".gm6", + ".pas", + ".ptl", + ".mfa", + ".dcp", + ".vbg", + ".jpr", + ".vhd", + ".dpk", + ".mrt", + ".exp", + ".pyd", + ".xojo_xml_project", + ".deviceids", + ".sh", + ".livecode", + ".fbz7", + ".as", + ".pot", + ".xqm", + ".nvv", + ".pika", + ".jsfl", + ".ftl", + ".mer", + ".alb", + ".s19", + ".resources", + ".patch", + ".sb", + ".wixobj", + ".gitignore", + ".hpp", + ".nsi", + ".gmk", + ".hbs", + ".vsz", + ".wixmsp", + ".xcsnapshots", + ".haml", + ".xojo_binary_project", + ".rb", + ".wsc", + ".jpx", + ".vcproj", + ".bbprojectd", + ".am6", + ".arsc", + ".bbproject", + ".ap_", + ".4db", + ".swc", + ".sc", + ".am7", + ".bs2", + ".tk", + ".pbj", + ".asi", + ".mcp", + ".dbo", + ".ipch", + ".ph", + ".dproj", + ".mxml", + ".xcodeproj", + ".wiq", + ".slogo", + ".nfm", + ".aia", + ".ltb", + ".sbproj", + ".ctp", + ".dbpro", + ".mk", + ".wixlib", + ".w32", + ".dbproj", + ".fsx", + ".pyx", + ".tmproj", + ".csi", + ".brx", + ".gld", + ".wdw", + ".4th", + ".svn", + ".xt", + ".ahk", + ".dgml", + ".xojo_menu", + ".gszip", + ".odl", + ".appx", + ".fla", + ".gameproj", + ".fxml", + ".so", + ".csp", + ".nupkg", + ".bas", + ".storyboard", + ".owl", + ".vssscc", + ".erl", + ".pch", + ".rise", + ".gitattributes", + ".fs", + ".autoplay", + ".tt", + ".hpf", + ".dpl", + ".po", + ".b", + ".ssi", + ".dgsl", + ".cvsrc", + ".mshi", + ".rc", + ".vsps", + ".kdevelop", + ".vsmdi", + ".json", + ".brM", + ".c" + ], + "Misc": [ + ".crx", + ".jar", + ".mht", + ".tar", + ".3ga", + ".aa", + ".aax", + ".aifc", + ".ape", + ".au", + ".awb", + ".cda", + ".iff", + ".kar", + ".koz", + ".m4a", + ".m4p", + ".mmf", + ".mp2", + ".mpa", + ".mpc", + ".nfa", + ".oma", + ".opus", + ".ra", + ".rta", + ".Format", + ".3dm", + ".3ds", + ".max", + ".obj", + ".aae", + ".adt", + ".clp", + ".cma", + ".efx", + ".fcpevent", + ".flo", + ".gbr", + ".gcw", + ".gms", + ".i5z", + ".ip", + ".itl", + ".mtw", + ".nfi", + ".nfs", + ".one", + ".qb2011", + ".quickendata", + ".sdf", + ".tax2012", + ".tax2014", + ".tax2016", + ".vcf", + ".vcs", + ".bup", + ".crypt", + ".db", + ".dbf", + ".mdb", + ".pdb", + ".sql", + ".kv", + ".Xib", + ".chm", + ".csk", + ".dot", + ".dotx", + ".oxps", + ".pmd", + ".shs", + ".vmg", + ".xps", + ".acsm", + ".apnx", + ".azw", + ".azw3", + ".epub", + ".fb2", + ".lrf", + ".mbp", + ".mobi", + ".opf", + ".prc", + ".tcr", + ".vbk", + ".air", + ".bat", + ".cgi", + ".cmd", + ".com", + ".ds", + ".gadget", + ".ipa", + ".wsf", + ".8bi", + ".bak", + ".bfc", + ".cmf", + ".crdownload", + ".cue", + ".dao", + ".dbx", + ".dem", + ".dic", + ".epc", + ".flt", + ".fnt", + ".fon", + ".gam", + ".gho", + ".gpx", + ".grp", + ".hex", + ".hqx", + ".ics", + ".img", + ".iso", + ".jad", + ".kml", + ".kmz", + ".map", + ".mdf", + ".mim", + ".mtb", + ".nes", + ".ori", + ".otf", + ".part", + ".pes", + ".plugin", + ".ps", + ".qxp", + ".rem", + ".rom", + ".sav", + ".t65", + ".tec", + ".tmp", + ".toast", + ".torrent", + ".ttf", + ".uue", + ".vcd", + ".xll", + ".dtp", + ".indd", + ".mdi", + ".p65", + ".qxd", + ".rels", + ".flipchart", + ".odp", + ".pps", + ".ppsx", + ".ppt", + ".pptm", + ".art", + ".dcm", + ".flif", + ".heic", + ".ithmb", + ".mac", + ".pct", + ".pef", + ".pgm", + ".pict", + ".plist", + ".pspimage", + ".rwl", + ".sfw", + ".sr2", + ".thm", + ".wbmp", + ".api", + ".cdt", + ".cfg", + ".dun", + ".fm3", + ".gid", + ".ht", + ".icm", + ".inf", + ".prf", + ".ods", + ".wk3", + ".wks", + ".xlr", + ".xlsb", + ".xlsm", + ".ani", + ".bashrc", + ".bash_history", + ".bash_profile", + ".bud", + ".cab", + ".cat", + ".cpl", + ".cur", + ".deskthemepack", + ".dev", + ".dit", + ".dll", + ".dmp", + ".drv", + ".dvd", + ".ebd", + ".ffl", + ".ffo", + ".fota", + ".hiv", + ".hlp", + ".htt", + ".icl", + ".icns", + ".iconpackage", + ".ion", + ".iptheme", + ".mlc", + ".nb0", + ".nt", + ".pck", + ".pnf", + ".pol", + ".prop", + ".qvm", + ".reg", + ".sys", + ".cvs", + ".emz", + ".mix", + ".odg", + ".pd", + ".vsd", + ".wmf", + ".wpg", + ".dvsd", + ".esp3", + ".mepx", + ".vproj", + ".asp", + ".aspx", + ".cer", + ".cfm", + ".cfml", + ".csr", + ".do", + ".htm", + ".js", + ".jsp", + ".nzb", + ".php", + ".webloc", + ".xfdl", + ".xhtml", + ".!BT", + ".UT", + ".1", + ".ADADOWNLOAD" + ], + "Games": [ + ".sav", + ".save", + ".gam", + ".mcworld", + ".pak", + ".vpk", + ".gcf", + ".nca", + ".xci", + ".nsp" + ], + "Dev Tools": [ + ".vsix", + ".crx", + ".xpi", + ".nupkg", + ".whl", + ".gem", + ".jar", + ".war", + ".ear", + ".ipa" + ], + "System Tools": [ + ".msi", + ".msix", + ".appx", + ".appinstaller", + ".cab", + ".inf", + ".cat", + ".sys", + ".drv", + ".ocx" + ], + "_PatternRules": { + "Games": [ + "steam", + "Riot", + "EA", + "Ubisoft", + "epic", + "gog", + "FINALS", + "Simulator", + "Resident Evil", + "Assassin's Creed", + "origin", + "uplay", + "ubisoft", + "battlenet", + "battle.net", + "minecraft", + "roblox", + "fortnite", + "valorant", + "league", + "dota", + "csgo", + "counter-strike", + "overwatch", + "warcraft", + "starcraft", + "diablo", + "hearthstone", + "fifa", + "Need for Speed", + "Metro", + "F1", + "pes", + "gta", + "cyberpunk", + "witcher", + "skyrim", + "fallout", + "elden ring", + "dark souls", + "sekiro", + "hollow knight", + "terraria", + "stardew", + "among us", + "pubg", + "apex", + "cod", + "call of duty", + "halo", + "destiny", + "borderlands", + "bioshock", + "portal", + "half-life", + "doom", + "quake", + "unreal", + "unity editor", + "godot", + "rpg maker", + "game", + "launcher", + "play", + "gamepass" + ], + "Dev Tools": [ + "vscode", + "visual studio", + "vs code", + "pycharm", + "intellij", + "webstorm", + "phpstorm", + "clion", + "goland", + "rider", + "datagrip", + "rubymine", + "eclipse", + "netbeans", + "android studio", + "xcode", + "vim", + "neovim", + "sublime", + "atom", + "notepad++", + "emacs", + "jetbrains", + "cursor", + "github", + "git", + "sourcetree", + "gitkraken", + "fork", + "docker", + "postman", + "insomnia", + "dbeaver", + "tableplus", + "datagrip", + "wsl", + "terminal", + "powershell", + "cmd", + "bash", + "putty", + "winscp", + "filezilla", + "vmware", + "virtualbox", + "vagrant", + "ansible", + "nodejs", + "node", + "python", + "ruby", + "java", + "rust", + "golang", + "kubectl", + "helm", + "terraform", + "vagrant", + "cmake", + "make", + "devenv", + "msbuild", + "xcode", + "sdk", + "ndk", + "ide", + "debugger", + "MobaXterm", + "cmder", + "conemu", + "terminator", + "alacritty", + "kitty", + "windows terminal", + "hyper" + ], + "System Tools": [ + "ccleaner", + "Fantech", + "remot desktop", + "ASRRGBLED", + "Razer", + "MSI", + "OBS", + "Notion", + "KDE", + "malwarebytes", + "avast", + "avg", + "kaspersky", + "norton", + "bitdefender", + "eset", + "mcafee", + "defender", + "antivirus", + "cpu-z", + "gpu-z", + "hwinfo", + "hwmonitor", + "speccy", + "aida64", + "crystaldiskinfo", + "crystaldiskmark", + "diskpart", + "teamviewer", + "anydesk", + "rustdesk", + "remote", + "winrar", + "7-zip", + "7zip", + "bandizip", + "peazip", + "rufus", + "etcher", + "ventoy", + "driver", + "update", + "setup", + "install", + "uninstall", + "control panel", + "registry", + "regedit", + "task manager", + "process", + "autoruns", + "procexp", + "sysinternals", + "backup", + "restore", + "recover", + "repair" + ] + } } diff --git a/organise_desktop/__init__.py b/organise_desktop/__init__.py index d0358d2..e69de29 100644 --- a/organise_desktop/__init__.py +++ b/organise_desktop/__init__.py @@ -1,2 +0,0 @@ -import os -from organise_desktop import organise_desktop diff --git a/organise_desktop/organiseDesktop.py b/organise_desktop/organiseDesktop.py index 7633c4b..d0d29f9 100644 --- a/organise_desktop/organiseDesktop.py +++ b/organise_desktop/organiseDesktop.py @@ -1,272 +1,235 @@ -import sys -import os -import json +import sys, os, json from os import path, mkdir, listdir, rename, environ, rmdir -class OrganiseDesktop(): +def get_desktop_path(): + if sys.platform == "win32": + return path.join(environ["USERPROFILE"], "Desktop") + + elif sys.platform in ["linux", "darwin"]: + return environ.get("TEST_DIR") or path.join(environ["HOME"], "Desktop") + raise NotImplementedError(f"{sys.platform} not supported") + + +class OrganiseDesktop: """ - Contains desktop organisation helper functions - """ + + pattern_rules = {} # filename keyword → category overrides extensions = {} - separator = '/' - desktopdir = '' + separator = "/" + desktopdir = "" Alldesktopdir = None def __init__(self, extensions): - - """ - Obtains various localised information about the platform and user, and performs system checks upon initialization. - """ - - # References: https://en.wikipedia.org/wiki/Environment_variable - # Default_values - # https://en.wikipedia.org/wiki/Windows_NT#Releases + self.desktopdir = get_desktop_path() + # Pull out _PatternRules before passing to extension logic + self.pattern_rules = extensions.pop("_PatternRules", {}) self.extensions = extensions - - - if sys.platform == 'win32': - self.desktopdir = path.join(environ['USERPROFILE'], 'Desktop') - # TODO: Set desktopdir to Virtual Directory for testing on Windows - - # Determine Windows version; check if this is XP; - # read target folders accordingly - if not sys.getwindowsversion() == 10: - if sys.getwindowsversion().major < 6: - self.Alldesktopdir = path.join(environ['ALLUSERSPROFILE'], 'Desktop') # noqa - else: - self.Alldesktopdir = path.join(environ['PUBLIC'], 'Desktop') # noqa - '''list of folders to be created''' - - - elif sys.platform in ['linux', 'darwin']: - - if environ.get('TEST_DIR'): - self.desktopdir = environ.get('TEST_DIR') - - else: - self.desktopdir = path.join(environ['HOME'], 'Desktop') - - else: - print("{} version not implemented".format(sys.platform)) - raise NotImplementedError - - - - def _create_dir_path(self, directory): + + def create_dir_path(self, directory): return os.path.join(self.desktopdir, directory) - - def makedir(self, folders_to_make): - """ This function makes the needed folders if they are not already found. - For all the folders in the folder_to_make list, if that folder does not exist on the main_desktop, create that folder. """ - - directories = [self._create_dir_path(directory) for directory in folders_to_make] - + directories = [self.create_dir_path(directory) for directory in folders_to_make] for directory in directories: if not path.isdir(directory): mkdir(directory) def removedir(self, folders_i_made): - """ This function will check folders that this program made. If the folder is empty, it will delete that folder. simple job. """ - - directories = [self._create_dir_path(directory) for directory in folders_i_made] + directories = [self.create_dir_path(directory) for directory in folders_i_made] for directory in directories: if not listdir(directory): rmdir(directory) - def list_directory_content(self): - + def match_by_pattern(self, filename): """ - This function checks the two folders - (current user desktop and all user desktop), - if on windows, only checks one folder if on linux or macOS, - it takes all the items there and puts them into two respective - lists which are returned and used by the mover function + Check filename (case-insensitive) against PatternRules keywords. + Returns the matching category name, or None if no match found. + Runs BEFORE extension matching, so game/IDE/tool shortcuts are + routed correctly instead of falling into generic Shortcuts/. """ - - # TODO: Is this really necessary? To be removed at PR stage - content = [listdir(self.desktopdir)] - if self.Alldesktopdir: - content += [listdir(self.Alldesktopdir)] - return content - - def mover(self, content): - + name_lower = filename.lower() + for category, keywords in self.pattern_rules.items(): + # Only match if this category folder actually exists in extensions + if category not in self.extensions: + continue + for keyword in keywords: + if keyword.lower() in name_lower: + return category + return None + + def mover(self): """ - This function gets two lists with all the things on the desktops - and copies them into their respective folders + Moves desktop files into their sorted folders. + + Priority: + 1. Skip this program's own shortcuts + 2. PatternRules keyword match (Games, Dev Tools, System Tools) + 3. Extension match (Images, Music, Text, etc.) + 4. Folder catch-all (unrecognised directories → Folders/) + 5. Log anything that didn't sort """ - - # image extensions source: https://fileinfo.com/filetypes/raster_image, - # https://fileinfo.com/filetypes/vector_image, - # https://fileinfo.com/filetypes/camera_raw - # music extensions source: https://fileinfo.com/filetypes/audio - # movie extensions source: http://bit.ly/2wvYjyr - # text extensions source: http://bit.ly/2wwcfZs - - user_dir_content = content[0] - - # Anything from the All_users_desktop goes to shortcuts, mainly because - # that's all that's ever there (I think) - if self.separator != '/' and not sys.getwindowsversion()[0] == 10: - all_users_content = content[1] - - for item in all_users_content: - # This is a cmd command to move items from one folder to other - rename( os.path.join(self.Alldesktopdir, item), os.path.join(self.desktopdir, item)) # noqa - - to_be_cleaned = [entry for entry in user_dir_content - if entry not in self.extensions and not (entry.startswith('.') or entry.startswith('..'))] # noqa + content = listdir(self.desktopdir) + + # On older Windows, merge All Users desktop first + if sys.platform == "win32" and self.Alldesktopdir: + try: + if sys.getwindowsversion().major < 10: + for item in listdir(self.Alldesktopdir): + rename( + os.path.join(self.Alldesktopdir, item), + os.path.join(self.desktopdir, item), + ) + except AttributeError: + pass + + # Only process items that aren't already category folders + to_be_cleaned = [ + entry + for entry in content + if entry not in self.extensions and not entry.startswith(".") + ] for item in to_be_cleaned: + # Skip this program's own shortcuts + if item in ("Clean.lnk", "Clean.exe.lnk"): + continue + + src = os.path.join(self.desktopdir, item) found = False - - for sorting_folder in self.extensions: - folder = os.path.join(self.desktopdir, item) - - if os.path.isdir(folder) and item not in self.extensions and "Folders" in self.extensions: # noqa - try: - rename(src= os.path.join(self.desktopdir, item), - dst=os.path.join(self.desktopdir, 'Folders', item)) # noqa - - found = True - break - - except PermissionError: - print("File is being used by some other process") - - for extension in self.extensions[sorting_folder]: - - if (str(item.lower()).endswith(extension) and - str(item) != 'Clean.lnk' and str(item) != 'Clean.exe.lnk'): # noqa - - rename(src=os.path.join(self.desktopdir, item), - dst=os.path.join(self.desktopdir, sorting_folder, item)) # noqa - - found = True - break + + # ── Priority 1: Pattern match (keyword in filename) ────────────── + pattern_category = self.match_by_pattern(item) + if pattern_category: + dst = os.path.join(self.desktopdir, pattern_category, item) + try: + rename(src=src, dst=dst) + found = True + print(f"[Pattern] {item!r} → {pattern_category}/") + except PermissionError: + print(f"[Locked] {item!r} (file in use)") + except Exception as e: + print(f"[Error] {item!r} {e}") + + # ── Priority 2: Extension match ─────────────────────────────────── if not found: - print('Did not sort ' + item) + item_lower = item.lower() + for sorting_folder, ext_list in self.extensions.items(): + for extension in ext_list: + if item_lower.endswith(extension): + dst = os.path.join(self.desktopdir, sorting_folder, item) + try: + rename(src=src, dst=dst) + found = True + except PermissionError: + print(f"[Locked] {item!r} (file in use)") + except Exception as e: + print(f"[Error] {item!r} {e}") + break # stop checking extensions for this folder + if found: + break # stop checking sorting folders + + # ── Priority 3: Folder catch-all ────────────────────────────────── + if not found and os.path.isdir(src) and "Folders" in self.extensions: + dst = os.path.join(self.desktopdir, "Folders", item) + try: + rename(src=src, dst=dst) + found = True + except PermissionError: + print(f"[Locked] {item!r} (folder in use)") + except Exception as e: + print(f"[Error] {item!r} {e}") - def writter(self, content): + if not found: + print(f"Did not sort: {item!r}") + def write_log(self, content): """ This function writes the two lists of all the items left on the desktop just in case something isn't right and we need a log. """ + log_dir = path.dirname(os.getcwd()) + "/log" + if not os.path.isdir(log_dir): + os.makedirs(log_dir) - if not os.path.isdir(path.dirname(os.getcwd())+'/log'): # Create log folder if non exists # noqa - os.makedirs(path.dirname(os.getcwd())+'/log') - - writeOB = open(path.dirname(os.getcwd()) + '/log/modifications.log', 'w') # noqa - - writeOB.write('This is a list of all items on your desktop before it was cleaned.\n' # noqa - 'Email this list to kalimbatech@gmail.com if anything is not working as planned, it will help with debugging\n' # noqa - 'Together we can make a better app\n\n') # noqa - - for desktop_entry in content: - for i in desktop_entry: - writeOB.write(i) - writeOB.write('\n') - - writeOB.close() + with open(log_dir + "/modifications.log", "w") as f: + f.write( + "This is a list of all items on your desktop before it was cleaned.\n" + "Email this list to kalimbatech@gmail.com if anything is not working as planned.\n\n" + ) + for desktop_entry in content: + for i in desktop_entry: + f.write(i + "\n") def organise_desktop(extensions): - """ Cleans up the desktop """ - #Find working directory + # Find working directory pwd = os.path.dirname(os.path.abspath(__file__)) # The oh-so-magnificent main function keeping the stuff in order - - #Initialize the OrganiseDesktop class - projectOB = OrganiseDesktop(extensions) - - #Make the directories - projectOB.makedir(extensions) - - #Get the maps of the directories - maps = projectOB.list_directory_content() - - #Move the files to their appropriate locations - projectOB.mover(maps) - - #Remove directories created by this program but empty - projectOB.removedir(extensions) - - #Log the original files - projectOB.writter(maps) + # Initialize the OrganiseDesktop class + organizer = OrganiseDesktop(extensions) -def undo(): + # Make the directories + organizer.makedir(organizer.extensions) + # Move the files to their appropriate locations + organizer.mover() + + # Remove directories created by this program but empty + organizer.removedir(organizer.extensions) + + # Get the maps of the directories + maps = organizer.list_directory_content() + + # Log the original files + organizer.write_log(maps) + + +def undo(): """ Restores the changes from organising your desktop """ - Extensions = json.load( open( os.path.dirname( os.path.abspath(__file__) ) + '/Extension.json') ) # noqa - - if sys.platform == 'win32': - desk_to_dir = path.join( environ['USERPROFILE'], 'Desktop' ) - - # Determine Windows version; check if this is XP; accordingly, - # read target folders - if not sys.getwindowsversion()[0] == 10: - - if sys.getwindowsversion().major < 6: - desk_to_dir = path.join(environ['ALLUSERSPROFILE'], 'Desktop') - else: - desk_to_dir = path.join(environ['PUBLIC'], 'Desktop') - - # list of folders to be created - elif sys.platform == 'linux' or sys.platform == 'darwin': - if environ.get('TEST_DIR') is not None: - desk_to_dir = environ.get('TEST_DIR') - - else: - desk_to_dir = path.join(environ['HOME'], 'Desktop') - else: - print('{} version not implemented'.format(sys.platform)) - raise NotImplementedError - - map1 = listdir(desk_to_dir) - - if sys.platform == 'win32': - separator = '\\' - else: - separator = '/' - - for folder in map1: - if folder in Extensions: - contents = listdir( path.join(desk_to_dir, folder) ) - - for thing in contents: - try: - rename(src=os.path.join(desk_to_dir, folder, thing), - dst=os.path.join(desk_to_dir, thing)) - except: - print('File is being used by some other process') - - rmdir(os.path.join(desk_to_dir, folder)) + Extensions = json.load( + open(os.path.dirname(os.path.abspath(__file__)) + "/Extension.json") + ) # noqa + desk_to_dir = get_desktop_path() + desktop_items = listdir(desk_to_dir) -#Run the app -if __name__ == '__main__': + for folder in desktop_items: + if folder in Extensions: + contents = listdir(path.join(desk_to_dir, folder)) + for file_name in contents: + try: + rename( + src=os.path.join(desk_to_dir, folder, file_name), + dst=os.path.join(desk_to_dir, file_name), + ) + except Exception: + print(f"File is being used by another process: {file_name}") + try: + rmdir(os.path.join(desk_to_dir, folder)) + except Exception: + pass + + +if __name__ == "__main__": organise_desktop() diff --git a/run.py b/run.py index e17e9dc..24cfbb4 100644 --- a/run.py +++ b/run.py @@ -1,4 +1,22 @@ -from organise_desktop import app +import os +from environment import setup_environment +from organise_desktop.Clean import clean_desktop + + +def main(): + print("--- Desktop Organiser Starting ---") + + # 1. Prepare the environment (Create folders, etc.) + try: + setup_environment() + print("Environment check: OK") + except Exception as exception: + print(f"Warning: Setup encountered an issue: {exception}") + + # 2. Launch the GUI + print("Launching interface...") + clean_desktop() + if __name__ == "__main__": - app.run(debug=True) + main() diff --git a/setup.py b/setup.py deleted file mode 100644 index 6e7067d..0000000 --- a/setup.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -from setuptools import setup, find_packages -import sys - - -if sys.version_info < (3, 6): - print("Python 3.6 or higher is required...") - sys.exit(1) - -with open('README.md', encoding='utf-8') as f: - longd = f.read() - -setup( - name = 'OrganiseDesktop', - include_package_data = True, - packages = find_packages(), - data_files = [('OrganiseDesktop', ['organise_desktop/Extension.json'])], - entry_points = {'console_scripts': ['organise_desktop = organise_desktop.Cli:main']}, - install_requires = [ 'BeautifulSoup4', 'requests','colorama', 'Py-stackExchange', 'urwid', 'crontab'], - requires = ['os', 'getpass', 'time', 'sys', 'tkinter', ], - version = '1.0', - url = 'https://github.com/blavejr/OrganiseDesktop.git', - keywords = "Desktop Organiser", - license = 'MIT', - author = 'Remigius Kalimba', - author_email = 'kalimbatech@gmail.com', - description = 'Organise your desktop with one click.', - long_description = '\n\n{}'.format(longd) - ) From be442f3624649f21e3a29ee1fc28e3ec0e1a026c Mon Sep 17 00:00:00 2001 From: Hasan Shinnar Date: Thu, 9 Apr 2026 20:07:26 +0300 Subject: [PATCH 5/5] updated README.md file with the lateset update --- README.md | 82 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 3bbe8d2..0177c6a 100644 --- a/README.md +++ b/README.md @@ -17,39 +17,47 @@ The setup file is not yet configured (work in progress). To run the program, dow the repo and install the required packages then run the `Clean.py` file. # Technologies Used -Python 3.7 -### Python Libraries Used ### -beautifulsoup4 - 4.6.0 | certifi - 2018.1.18 | chardet - 3.0.4 | colorama - 0.3.9 | crontab - 0.22.0 | idna - 2.6 | py-stackexchange - 2.2.7 | requests - 2.18.4 -six - 1.11.0 | urllib3 - 1.22 | urwid - 2.0.1 +Python 3.7 + +### Python Libraries Used + +beautifulsoup4 - 4.6.0 | certifi - 2018.1.18 | chardet - 3.0.4 | colorama - 0.3.9 | crontab - 0.22.0 | idna - 2.6 | py-stackexchange - 2.2.7 | requests - 2.18.4 +six - 1.11.0 | urllib3 - 1.22 | urwid - 2.0.1 # Demo + ![Screenshot](demo1.png) The buttons are `Clean`, `Exit`, `Undo`, `Schedule`, `Remove Schedule` and do exactly as they are implied. `Clean` - will move the files to the correct folder based on extension. If the folder does not exist, it will create one. `Exit` - will close out of the program -`Undo` - undos where the files were placed in the folders when `Clean` was used +`Undo` - undos where the files were placed in the folders when `Clean` was used `Schedule` - schedules when the program will run every day in the users command line/ terminal `Remove Schedule` - removes the previously established schedule # Prerequisites -### Running a Virtual Environment ### -All the necessary packages are mentioned in `requirements.txt`. They can be installed by running `pip install -r requirements.txt` or using ``pipenv install`` and it will automatically detect the `requirements.txt` and setup an enviroment for you. For development purposes, I suggest you create a -virtual environment or use a dependency manager like [pipenv](https://github.com/pypa/pipenv) to keep a clear state, separate from your own setup. -To create a virual environment yourself in pipenv, follow the steps below: +### Running a Virtual Environment + +All the necessary packages are mentioned in `requirements.txt`. They can be installed by running `pip install -r requirements.txt` or using `pipenv install` and it will automatically detect the `requirements.txt` and setup an enviroment for you. For development purposes, I suggest you create a +virtual environment or use a dependency manager like [pipenv](https://github.com/pypa/pipenv) to keep a clear state, separate from your own setup. + +To create a virual environment yourself in pipenv, follow the steps below: + 1. Make a project directory `mkdir project && cd project` where "project" would be the name of the project 2. Initiate the virtual environment `pipenv --three` 3. Start the virtual enviroment `pipenv shell` -If the `pipenv install` does not work, insert the following `pipenv install -r requirements.txt` + If the `pipenv install` does not work, insert the following `pipenv install -r requirements.txt` 4. To exit the virtual environment run `exit` The `activate.sh` script has been provided to ensure a standard development environment. To create the environment if it doesn't already exist, or simply load it otherwise, run `source ./activate.sh` You can also use docker in combination with pipenv, [here](https://github.com/dfederschmidt/docker-pipenv-sample) you have an example. -### Not Running from Virtual Environment ### + +### Not Running from Virtual Environment + If you do not want to create a virtual environment, just run the pip command above and ignore the following. Otherwise, the `activate.sh` script will handle the creation and loading of the virtual environment with all the necessary dependencies. Furthermore, once a new dependency is established, remove `requirements.txt` and please run `pip freeze > requirements.txt` to generate a new file that should be committed to version control. Python3 Instructions: @@ -64,6 +72,7 @@ Navigate to the repo and run the following command: `$ pip install -r requirements.txt` # Contributing + Please read the [Contributing Guidlines](https://github.com/blavejr/OrganiseDesktop/blob/master/CONTRIBUTING.md) for details about pull requests, bug reports or opening an issue. Believe in the tech, use the tech, buy a dev coffee. @@ -71,5 +80,54 @@ Btc: 3GiHDAed4UFcE9itaVxQnTrKbW4Uw2kq3o Ether: 0x14fe9256e1a0d35AB57FdE974E44C1Eaee8005d6 Ltc:MJNKM9SYannnrFuAcMubzEvKBgVPFeBaKm Bat:0x744de3A9b1882C44dCB3AFD1e6f2dB459b64c45c -USDC:0x8EC9ae0DC0147422c1e9e46124d0BfeE7d16a3e7 USDC:0x8EC9ae0DC0147422c1e9e46124d0BfeE7d16a3e7 +USDC:0x8EC9ae0DC0147422c1e9e46124d0BfeE7d16a3e7 + +--- + +## Fork Modifications + +> This is a fork of [blavejr/OrganiseDesktop](https://github.com/blavejr/OrganiseDesktop). The following changes were made on top of the original project. + +### Changes by [@hasanshinnar](https://github.com/hasanshinnar) + +#### 2026-04-07 + +**`activate.bat`** _(new file)_ + +- Added a Windows-friendly activation script as an alternative to `activate.sh`, following the same setup/activation flow. + +**`Dockerfile`** + +- Optimized the build to reduce unnecessary layers and improve build performance. + +**`organise_desktop/Clean.py`** + +- Removed `root.resizable` and `position` constraints for better layout flexibility. +- General code modernization and performance improvements. + +**`organise_desktop/CronController.py`** + +- Modernized and refactored code for efficiency. +- Fixed bugs in the Windows-specific code path. + +**`organise_desktop/organiseDesktop.py`** + +- Merged `list_directory_content()` into `mover()` to reduce function overhead. +- Extracted extension definitions into `Extension_Sources.md` for cleaner separation. +- Added `_PatternRules` support: matches files by exact name rather than extension alone. +- General logic and performance improvements. + +**`Extension.json`** + +- Added `_PatternRules` entries to support exact filename matching. + +#### 2026-04-09 + +**`run.py`** _(new file)_ + +- Single entry point that runs both setup and the main script, replacing the need to invoke two files manually. + +**`setup.py` → `environment.py`** _(renamed)_ + +- Renamed to avoid conflict with Python's built-in `setup.py` convention, which caused import resolution issues.