├── .idea
├── .gitignore
├── folder-automation.iml
├── inspectionProfiles
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── README.md
├── __pycache__
└── utils.cpython-38.pyc
├── config.json
├── main.py
├── requirements.txt
└── utils.py
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/folder-automation.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # folder-automation
2 |
3 | ## A Smart, Configurable and Cross-Platform piece of software that runs on all operating systems
4 |
5 | ---
6 |
7 | ### This software aims to solve the clutter in **any** of your folders by moving them to their respective folders
8 |
9 | ---
10 |
11 | ## Features
12 |
13 | 1. Cross-Platform
14 | 2. Configurable
15 | 3. Consumes Little Memory
16 |
17 | ---
18 |
19 | ## Installation Instructions
20 |
21 | ```terminal
22 | git clone https://github.com/P-arag/folder-automation
23 | cd folder-automation
24 | pip install -r requirements.txt
25 | python main.py
26 | ```
27 |
28 | ## Configure the `config.json` according to your needs
29 |
30 | # Happy Hacking!! :grin: :rocket:
31 |
--------------------------------------------------------------------------------
/__pycache__/utils.cpython-38.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/P-arag/folder-automation/583020d2564d00cd0140552336b5f1eb0db384a1/__pycache__/utils.cpython-38.pyc
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "watch_directory": "~/Downloads",
3 | "move_folders": [
4 | {
5 | "location": "~/Pictures",
6 | "print_text": "Images Detected",
7 | "Xtensions": ["jpg", "jpeg", "png", "gif"],
8 | "sleep": 2,
9 | "move_this_file?": true
10 | },
11 | {
12 | "location": "~/Documents",
13 | "print_text": "Document Detected",
14 | "Xtensions": ["docx", "txt", "pdf"],
15 | "sleep": 2,
16 | "move_this_file?": true
17 | },
18 | {
19 | "location": "~/Music",
20 | "print_text": "Audio files detected",
21 | "Xtensions": ["mp3", "wav"],
22 | "sleep": 2,
23 | "move_this_file?": true
24 | },
25 | {
26 | "location": "~/Videos",
27 | "print_text": "Videos Detected",
28 | "Xtensions": ["mp4", "avi", "mpv", "ogg"],
29 | "sleep": 2,
30 | "move_this_file?": true
31 | },
32 | {
33 | "location": "~/Code",
34 | "print_text": "Program Files Detected",
35 | "Xtensions": ["py", "json", "js", "c", "cs", "cpp", "java", "go"],
36 | "sleep": 2,
37 | "move_this_file?": true
38 | },
39 | {
40 | "location": "~/Public",
41 | "print_text": "Zip files detected",
42 | "Xtensions": ["zip"],
43 | "sleep": 100,
44 | "move_this_file?": true
45 | },
46 | {
47 | "location": "...",
48 | "print_text": "Large files detected, not doing anything",
49 | "Xtensions": ["tar", "gz", "tar.gz", "deb"],
50 | "sleep": 0,
51 | "move_this_file?": false
52 | }
53 | ]
54 | }
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import os
2 | import json
3 | import time
4 | from pprint import pprint
5 | from watchdog.observers import Observer
6 | from watchdog.events import FileSystemEventHandler
7 | from utils import *
8 |
9 |
10 | class OnMyWatch:
11 | def __init__(self, watch_directory):
12 | self.observer = Observer()
13 | self.watch_directory = os.path.expanduser(watch_directory)
14 | print(f"WatchDog Watching {self.watch_directory}")
15 |
16 | def run(self):
17 | event_handler = Handler()
18 | self.observer.schedule(
19 | event_handler, self.watch_directory, recursive=True)
20 | self.observer.start()
21 | try:
22 | while True:
23 | time.sleep(5)
24 | except:
25 | self.observer.stop()
26 | print(" Observer Stopped")
27 |
28 | self.observer.join()
29 |
30 |
31 | class Handler(FileSystemEventHandler):
32 | @staticmethod
33 | def on_any_event(event):
34 | print(event.event_type+" "+event.src_path)
35 |
36 | if event.is_directory:
37 | return None
38 | elif event.event_type == 'created':
39 | print("*created "+event.src_path)
40 | for folder_iterable in data["move_folders"]:
41 | extensions = ["." + extension for extension in folder_iterable["Xtensions"]]
42 | if event.src_path.endswith(tuple(extensions)):
43 | print(folder_iterable["print_text"])
44 | if folder_iterable["move_this_file?"]:
45 | time.sleep(folder_iterable["sleep"])
46 | move_file(event.src_path, folder_iterable["location"])
47 | print("moved")
48 | print(os.listdir(os.path.expanduser(folder_iterable["location"])))
49 | break
50 | else:
51 | print(folder_iterable["print_text"])
52 | break
53 |
54 |
55 |
56 | if __name__ == '__main__':
57 | data = json.load(open("./config.json"))
58 | watch = OnMyWatch(data["watch_directory"])
59 | watch.run()
60 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | watchdog~=2.0.2
--------------------------------------------------------------------------------
/utils.py:
--------------------------------------------------------------------------------
1 | import os
2 | import shutil
3 | from os.path import *
4 |
5 |
6 | def move_file(src: str, where: str) -> None:
7 | print("Moving %s to %s" % (src, where))
8 | # print(os.listdir(os.path.expanduser(where)))
9 | if check_if_exists(src, where):
10 | print(f"Oops, {src} file already exists in {where}")
11 | new_file_name = newname_if_present(src, where)
12 | # new_file_name = basename(new_file_name)
13 | print("mvfile " + new_file_name)
14 | shutil.move(src, join(expanduser(where), new_file_name))
15 | else:
16 | shutil.move(src, join(expanduser(where), basename(src)))
17 | # os.system("mv "+os.path.expanduser(src) + " " + os.path.expanduser(where))
18 |
19 |
20 | def check_if_exists(filename: str, where: str) -> bool:
21 | # filename = basename(filename)
22 | # is_present = exists(join(where, filename))
23 | # print(is_present)
24 | # print(filename)
25 | # print(os.listdir(expanduser(where)))
26 | if basename(filename) in os.listdir(expanduser(where)):
27 | return True
28 | return False
29 |
30 |
31 | def newname_if_present(filename: str, where: str) -> str:
32 | new_filename = filename
33 | i = 1
34 | while True:
35 | if check_if_exists(new_filename, where):
36 | filename_without_extension = splitext(new_filename)[0]
37 | extension = ""
38 | for xtension in splitext(new_filename)[1:]:
39 | extension += xtension
40 |
41 | new_filename = "%s(%d)%s" % (filename_without_extension, i, extension)
42 | else:
43 | print(new_filename)
44 | return basename(new_filename)
45 | i += 1
46 |
--------------------------------------------------------------------------------