As a Python developer who spends half my life wrangling data, I’m all about automation. So when I stumbled across downloads-folder-automation on GitHub, a neat little script that organizes your Windows Downloads folder, I knew I’d found a gem. Better yet? It was open source, and I could make it my own.
On my job, I mostly sling Pandas and NumPy for data analysis, with some JavaScript on the side. This project spoke to me: clean code, a real-world problem, and a chance to contribute. My mission? Add support for rtf
, odt
, and ods
files—formats I bump into often, especially the OpenDocument ones from my data-crunching days. Here’s how I jumped into open source, made my mark, and turned a messy folder into a tidy win.
The Project: A Python-Powered Cleanup Crew
First, let’s break down what downloads-folder-automation does. It’s a Python script that scans your Downloads folder, reads a config.json file to map file extensions to subfolders (like “Documents” or “Pictures”), and moves everything where it belongs. Think .pdf files sliding into “Documents,” .jpg pics landing in “Pictures,” and anything weird getting dumped in “Miscellaneous.” It’s simple, elegant, and saves you from the dread of manual sorting.
The config file is the brains of the operation. Here’s a peek at the version I worked with, including my additions:
[
{
"name": "Documents",
"extensions": [
".doc",
".docx",
".txt",
".pdf",
".xls",
".ppt",
".xlsx",
".pptx",
".rtf",
".odt",
".ods"
]
},
{
"name": "Pictures",
"extensions": [
".jpg",
".jpeg",
".png",
".svg",
".gif",
".tif",
".tiff"
]
},
// ... other categories like "Programs," "Music," etc.
]
The script itself uses Python’s pathlib
for path handling, shutil
for moving files, and json to parse that config. It loops through files, checks their extensions, and shuffles them to the right spot. If a folder doesn’t exist (say, “Documents”), it creates it.
Adding More File Types
So why tweak it? As a data analyst, I deal with .ods
(OpenDocument Spreadsheet) files all the time—think LibreOffice’s answer to Excel. And .odt
(OpenDocument Text) and .rtf
(Rich Text Format) pop up in my world too. The original config covered a lot—.pdf
, .mp3
, .zip
—but missed these. I figured, why not make it more inclusive?
Here’s how it went down:
-
Fork and Clone: I forked
eric-mahasi/downloads-folder-automation
to my GitHub, cloned it locally, and opened it up. Git’s still a bit of a wild beast to me, but I managed! -
Edit the Config: In
config.json
, I added.rtf
,.odt
, and.ods
to the “Documents” category. Logical spot—spreadsheets could’ve gone elsewhere, but I kept it simple. -
Test It: I tossed some test files into my Downloads folder—an
.odt
note, an.ods
dataset, a random.rtf
. Ran the script (python main.py
), and bam—they zipped into a fresh “Documents” subfolder. -
Pull Request: I branched my changes (
git checkout -b add-more-extensions
), committed them (git commit -m "Add rtf, odt, ods to config
“), pushed to my fork, and opened a PR. Described it like: “Added support for .rtf, .odt, .ods—tested and working!” Now I wait for Eric’s feedback.
To give my spin on the code—and avoid just parroting the original—here’s how I’d write it today:
import shutil
from pathlib import Path
import json
def relocate_file(source_file, target_dir):
"""Moves a file to a specified folder, creating the folder if it doesn’t exist.
Args:
source_file (Path): Path to the file being moved
target_dir (Path): Path to the destination directory
"""
try:
if not target_dir.exists():
target_dir.mkdir(parents=True, exist_ok=True)
shutil.move(source_file, target_dir)
except shutil.Error as error:
print(f"Error moving file: {error}")
def organize_directory(directory_path):
"""Sorts files in a directory into subfolders based on their extensions.
Args:
directory_path (Path): Path to the directory to organize
"""
with open('config.json', encoding='utf-8') as config_file:
file_groups = json.load(config_file)
extension_to_folder = {}
for group in file_groups:
folder = group['name']
for ext in group['extensions']:
extension_to_folder[ext] = folder
for item in directory_path.iterdir():
if item.is_file() and not item.name.startswith('.'):
target_folder = extension_to_folder.get(item.suffix, 'Miscellaneous')
relocate_file(item, directory_path / target_folder)
if __name__ == '__main__':
user_home = Path.home()
downloads_dir = user_home / 'Downloads'
organize_directory(downloads_dir)
Try It Yourself
Want to tame your own Downloads folder or any folder? Fork the repo, grab my updated config.json, and run the script. Add your own file types—maybe .py
for “Scripts” or .csv
for “Data”? It’s yours to hack. And if you’re new to open source, this is a perfect sandbox—simple, useful, and welcoming.