So, after working with a side-project for about 6 hours today, pulling my hair because CSS makes absolutely no sense to me sometimes, I decided to improve on the
Downloads Organizer I made in Ruby the other week.
This is part two / version two. You can view the first article here: Organize Your Downloads Folder with Ruby
So what I added was a way of checking the type of the files, and also organizing them into their own subfolders. To achieve this I used
regex to the check the file-endings of the files.
After getting it to work, I had to refactor.. A LOT.. But here are the final results, a couple of functions doing bits and pieces I'll walk you through under the codeblock.
require 'find' require 'fileutils' downloads_folder = File.join(Dir.home, 'Downloads') ## Arrays used in the filtering logic. yearly_folders = ["2019", "2020", "2021", "2022", "2023", "2024", "2025"] def check_type(file) case file when /^.*\.(pdf|doc|docx|PAGES|txt)$/i 'documents' when /^.*\.(gif|jpg|jpeg|png|svg|mp4|mov|mp3|mpeg4|heic)$/i 'media' when /^.*\.(dmg|exe|jar)$/i 'programs' when /^.*\.(zip|tar|rar)$/i 'archives' else 'other' end end def create_directory(directory, subfolder) final_directory = File.join(directory, subfolder) Dir.mkdir(final_directory) unless File.directory?(final_directory) final_directory end def move_file(file, directory) final_directory = create_directory(directory, check_type(file)) FileUtils.mv(file, final_directory) unless file === directory end def organize_downloads(downloads_folder, yearly_folders) Dir.foreach(downloads_folder) do |file| next if file == '.' || file == '..' || yearly_folders.include?(file) path = File.join(downloads_folder, file) next unless File.exist?(path) last_edited = File.mtime(path) year = last_edited.strftime('%Y') new_directory = create_directory(downloads_folder, year) move_file(path, new_directory) end end organize_downloads(downloads_folder, yearly_folders)
So, when the app is started, running the
organize_downloads method, the same old logic used for getting the files, and year modified as explained in part 1.
When it starts to differ is when assigning
new_directory to the value of
In this method, we give it two attributes:
year, which is set in
organize_downloads. It then creates a new variable, that eventually just returns a path to the location we want to put the file in.
From there we create a new folder with the new path,
UNLESS the folder already exist.
And finally, we return the
Now, back to
organize_downloads and what happens in
Here, we give it two attributes:
path, which basically is the pointer to the file itself, and
new_directory which is the return that we got from the
create_directory in step 1.
In here, we again create a
final_directory, but this time to also include subfolders.
This one is pretty easy, it re-uses the
create_directory method again, but to create the subfolder. But instead of having the
year, we instead give it the updated directory(
directory) and the return of whatever
check_type does (explained in step 3).
And after getting these values, we run the same
FileUtils.mvto just move it to its new location.
The last piece of the puzzle to explain, and the easiest. A switch condition that checks if the letters/digits after "." at the end of the filename matches a specific set of filetypes set by me.
How I decided to structure mine was:
- Media (images/videos)
- Programs (apps, installers)
- Documents (PDFs, docs)
- Archives (rar-files etc)
- Other (The rest)
I'm sure I've probably missed filetypes etc, but I just wanted to get it to work really.
It then returns a string for whatever match it gets, and then goes on with the logic back in
And that's it! Version 2.0 of my Ruby app organizing the downloads folder. Good times.
In the future I would like to look at:
- Add more structure
- Potentially make it even more dynamic and take inputs
- GUI? 👀
Top comments (0)