Skip to content

Instantly share code, notes, and snippets.

@mattmccray
Created October 10, 2008 23:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattmccray/16180 to your computer and use it in GitHub Desktop.
Save mattmccray/16180 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
#
# file_organizer.rb
# (http://gist.github.com/16180)
#
# By M@ McCray -- www.mattmccray.com (matt at elucidata dot net)
#
# Usage:
#
# organize_files_within( target_folder )
#
# For example, I created a script (that runs daily) that looks like this:
#
# organize_downloads.rb:
#
# #!/usr/bin/env ruby
# downloads_folder = "/Users/darthapo/Downloads"
# require File.join(File.dirname(__FILE__), 'file_organizer.rb')
# organize_files_within(downloads_folder)
#
# Also, one for any random folder:
#
# organize_folder_by_type.rb:
#
# #!/usr/bin/env ruby
# unless ARGV.size == 1
# puts "Usage: $0 folder"
# exit(1)
# end
# require File.join(File.dirname(__FILE__), 'file_organizer.rb')
# folder = ARGV[0]
# organize_files_within(folder)
#
EXTENSIONS_FOR_TYPE = {
"Applications" => %w(.app .jar .exe .pkg .mpkg .air),
"Archives" => %w(.dmg .zip .rar .sit .sitx .tar .gz .bz2),
"Audio" => %w(.wav .mp3 .ogg .m3u .m4a .wma),
"Code" => %w(.sh .rb .js .java .c .m .h .py .php .css .haml .sass .erb .html .rhtml .xhtml .htm .bat .patch .diff .gem .xul .shy .sql .nib .xib .cib .j .sj .nu .rake .thor .nuke .mxml),
"Comics" => %w(.cbr .cbz),
"Data" => %w(.xml .yaml .yml .json .sqlite .sqlite3 .db .csv .opml),
"Documents" => %w(.pdf .doc .ppt .txt .text .rtf .rtfd .xls .oo3 .tables .taskpaper .textile .markdown .graffle .pages .vpdoc),
"Folders" => [],
"Fonts" => %w(.ttf .otf .suit),
"Links" => %w(.webloc),
"Images" => %w(.jpg .jpe .jpeg .png .gif .bmp .svg .psd .ai .ps .ico .icns .lineform .eps .acorn .pxm .ptn .fla .tiff),
"Models" => %w(.3ds .blend .dxf .skp),
"Other" => [],
"Scripts" => %w(.script .celtx .scriv),
"Torrents" => %w(.torrent),
"Videos" => %w(.avi .mvk .mov .wmv .flv .mp4 .mpg .mpeg .m4v .qtz)
}
# The character to postfix any clashing filenames with...
FILE_POSTFIX = "_"
# =========================================================================================
# = No need to edit anything below this line =
# =========================================================================================
require 'rubygems'
require 'rake'
def organize_files_within(folder)
types_by_ext = {}
# Create organizational folders, and invert Category/Extension hash
EXTENSIONS_FOR_TYPE.each do |ftype, exts|
folder_name = File.join(folder, ftype)
exts.each do |ext|
types_by_ext[ext.downcase] = folder_name
end
end
FileList[folder + "/*"].each do |downloaded_file|
file = File.expand_path(downloaded_file)
# Skip our organization folders...
next if File.directory?(file) && EXTENSIONS_FOR_TYPE.keys.include?( File.basename(file) )
# Figure out our target folder...
move_to = if types_by_ext.keys.include?( File.extname(file).downcase )
types_by_ext[ File.extname(file).downcase ] # Folder by extension...
elsif File.directory?(file)
File.join(folder, "Folders") # Move folders into correct place...
else
File.join(folder, 'Other') # Otherwise, put in 'Other' folder...
end
# Create organizational folder, unless it already exists...
FileUtils.mkdir( move_to, :verbose => true ) unless File.exists?( move_to )
# Ensure the filename doesn't clash with an already organized file...
file_ext = File.extname(file) # ie. ".js"
file_base = File.basename(file) # ie. "test.js"
file_name = file_base.gsub(file_ext, '') # ie. "test"
file_target = File.join(move_to, file_base)
while File.exists?(file_target)
file_name = "#{file_name}#{FILE_POSTFIX}"
file_target = File.join(move_to, "#{file_name}#{file_ext}")
end
# Move the file...
FileUtils.mv(file, file_target, :verbose => true)
end
puts "Done."
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment