DEV Community

Cover image for Organize Your Downloads Folder with Ruby #2
Mattias Velamsson
Mattias Velamsson

Posted on

3

Organize Your Downloads Folder with Ruby #2

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)

Enter fullscreen mode Exit fullscreen mode

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 create_directory.

1 create_directory

In this method, we give it two attributes: directory and 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 final_folder path.

Now, back to organize_downloads and what happens in move_file

2 move_file

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 downloads_folder and 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.

3 check_type

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 move_file.


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? 👀

AWS Q Developer image

Your AI Code Assistant

Automate your code reviews. Catch bugs before your coworkers. Fix security issues in your code. Built to handle large projects, Amazon Q Developer works alongside you from idea to production code.

Get started free in your IDE

Top comments (0)

AWS GenAI LIVE image

Real challenges. Real solutions. Real talk.

From technical discussions to philosophical debates, AWS and AWS Partners examine the impact and evolution of gen AI.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay