forked from mattmccray/thor-tasks
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathorganize.thor
More file actions
108 lines (87 loc) · 3.94 KB
/
organize.thor
File metadata and controls
108 lines (87 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# organize.thor
#
# By M@ McCray -- www.mattmccray.com (matt at elucidata dot net)
#
# Usage:
#
# thor organize:files ~/Downloads
#
require 'rubygems'
require 'rake'
class Organize < Thor
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 .coffee .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 .less .scss),
"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 .obj),
"Other" => [],
"Scripts" => %w(.script .celtx .scriv),
"Torrents" => %w(.torrent),
"Videos" => %w(.avi .mvk .mov .wmv .flv .mp4 .mpg .mpeg .m4v .qtz)
} #unless defined? EXTENSIONS_FOR_TYPE
# The character to postfix any clashing filenames with...
FILE_POSTFIX = "_" #unless defined? FILE_POSTFIX
desc "files [FOLDER]", "Organize files in FOLDER based on file type"
method_options :postfix => "_", :force => :boolean, :verbose => :boolean
def files(folder)
full_path = File.expand_path folder
if File.exists?(full_path)
if options.force? or yes?(" > This will move all loose files in #{full_path} (postfix: #{options.postfix}). Continue?")
puts "Organizing folder: #{full_path}"
organize_files_within( full_path, options.verbose?, options.postfix )
puts "Done."
else
puts "OK, don't worry about it."
end
else
puts "Path does not exist! (#{full_path})"
end
end
no_tasks do
# Helper:
def organize_files_within(folder, verbose=false, postfix=FILE_POSTFIX)
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 => verbose ) 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}#{postfix}"
file_target = File.join(move_to, "#{file_name}#{file_ext}")
end
# Move the file...
FileUtils.mv(file, file_target, :verbose => verbose)
end
end
end
end