randrews-clean 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/bin/clean ADDED
@@ -0,0 +1,22 @@
1
+ #!/usr/local/bin/ruby
2
+
3
+ require 'rubygems'
4
+ require 'clean'
5
+
6
+ include Options
7
+ include Config
8
+ include Destinations
9
+ include CommandUtil
10
+
11
+ $OPTS=get_options(ARGV.dup)
12
+
13
+ ##################################################
14
+ ### Make and run commands ########################
15
+ ##################################################
16
+
17
+ $OPTS[:dirs].each do |dir|
18
+ cmds=dir_commands(dir)
19
+ cmds+=file_commands(dir)
20
+
21
+ cmds.sort.map &:run
22
+ end
data/lib/clean.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'yaml'
3
+ require 'activesupport'
4
+ require 'fileutils'
5
+ require 'trollop'
6
+
7
+ Dir[File.join(File.dirname(__FILE__),'*.rb')].each do |file|
8
+ require file
9
+ end
@@ -0,0 +1,46 @@
1
+ ##################################################
2
+ ### Make commands ################################
3
+ ##################################################
4
+
5
+ module CommandUtil
6
+ def make_file_command filename
7
+ dest=destination_for filename
8
+
9
+ return nil unless dest
10
+
11
+ if dest=="_rm"
12
+ RemoveCommand.new filename
13
+ else
14
+ MoveCommand.new filename, dest
15
+ end
16
+ end
17
+
18
+ def file_commands dir
19
+ dir=File.expand_path dir
20
+ cmds=Dir[File.join(dir, '*')].map do |filename|
21
+ nil if File.directory? filename
22
+ make_file_command(File.basename(filename))
23
+ end
24
+
25
+ cmds.compact.map { |c| c.path=dir ; c }
26
+ end
27
+
28
+ def dir_commands dir
29
+ dir=File.expand_path dir
30
+
31
+ cmds=config['directories'].keys.map do |dest|
32
+ next if dest=='_rm'
33
+ path=File.join(dir,dest)
34
+ if File.exists?(path)
35
+ if !File.directory?(path)
36
+ Trollop::die "#{path} already exists, and isn't a directory"
37
+ else
38
+ nil
39
+ end
40
+ else
41
+ CreateCommand.new dest,dir
42
+ end
43
+ end
44
+ cmds.compact
45
+ end
46
+ end
data/lib/commands.rb ADDED
@@ -0,0 +1,143 @@
1
+ class Command
2
+ attr_accessor :path
3
+
4
+ def priority ; nil ; end
5
+
6
+ def transform filename
7
+ if path
8
+ File.join path, filename
9
+ else
10
+ File.join '.', filename
11
+ end
12
+ end
13
+
14
+ def run
15
+ unless $OPTS[:silent]
16
+ dr=dry_run
17
+ puts(dry_run) if dry_run
18
+ end
19
+
20
+ real_run unless $OPTS[:dry_run]
21
+ end
22
+
23
+ def dry_run ; raise NotImplementedError ; end
24
+ def real_run ; raise NotImplementedError ; end
25
+
26
+ def <=> other
27
+ priority <=> other.priority
28
+ end
29
+ end
30
+
31
+ ##################################################
32
+ ### Move files ###################################
33
+ ##################################################
34
+
35
+ class MoveCommand < Command
36
+ def priority ; 2 ; end
37
+
38
+ def initialize *args
39
+ (@filename, @directory, @path)=args
40
+ end
41
+
42
+ def filename ; transform @filename ; end
43
+ def directory ; transform @directory ; end
44
+
45
+ def dry_run
46
+ case $OPTS[:on_collision]
47
+ when 'overwrite'
48
+ "mv #{filename} #{directory}"
49
+ when 'rename'
50
+ "mv #{filename} #{File.join(directory,unique_name)}"
51
+ else # 'ignore' also
52
+ # emit nothing
53
+ end
54
+ end
55
+
56
+ def real_run
57
+ case $OPTS[:on_collision]
58
+ when 'overwrite'
59
+ mv
60
+ when 'rename'
61
+ if collision?
62
+ FileUtils.mv filename, File.join(directory,unique_name)
63
+ else
64
+ mv
65
+ end
66
+ else # captures the 'ignore' option too
67
+ # do nothing
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def mv
74
+ FileUtils.mv filename, directory
75
+ end
76
+
77
+ def collision? fname=filename
78
+ File.exists?(File.join(directory,File.basename(fname)))
79
+ end
80
+
81
+ def unique_name
82
+ fname=filename
83
+
84
+ # make sure there's a real collision
85
+ return fname unless collision? fname
86
+
87
+ # ext is like ".jpg"
88
+ ext=File.extname(fname)
89
+
90
+ # Base is the filename - dir and extension, so /foo/bar.txt -> bar
91
+ base=File.basename(fname,ext)
92
+
93
+ # loop until we find an n that'll work. Start with bar-1.txt
94
+ n=1
95
+ n+=1 while collision?("#{base}-#{n}#{ext}")
96
+
97
+ "#{base}-#{n}#{ext}"
98
+ end
99
+ end
100
+
101
+ ##################################################
102
+ ### Create directories ###########################
103
+ ##################################################
104
+
105
+ class CreateCommand < Command
106
+ def priority ; 1 ; end
107
+
108
+ def initialize *args
109
+ (@dirname, @path)=args
110
+ end
111
+
112
+ def dirname ; transform @dirname ; end
113
+
114
+ def dry_run
115
+ "mkdir #{dirname}"
116
+ end
117
+
118
+ def real_run
119
+ FileUtils.mkdir_p dirname
120
+ end
121
+ end
122
+
123
+ ##################################################
124
+ ### Remove files #################################
125
+ ##################################################
126
+
127
+ class RemoveCommand < Command
128
+ def priority ; 3 ; end
129
+
130
+ def initialize *args
131
+ (@filename, @path)=args
132
+ end
133
+
134
+ def filename ; transform @filename ; end
135
+
136
+ def dry_run
137
+ "rm #{filename}"
138
+ end
139
+
140
+ def real_run
141
+ FileUtils.rm filename
142
+ end
143
+ end
data/lib/config.rb ADDED
@@ -0,0 +1,31 @@
1
+ ##################################################
2
+ ### Read config file #############################
3
+ ##################################################
4
+
5
+ module Config
6
+ def config
7
+ return @config if @config
8
+
9
+ file=File.expand_path($OPTS[:config_file])
10
+ if File.exists? file
11
+ @config||=YAML.load(File.open(file))
12
+ else
13
+ ex=File.expand_path(File.join(File.dirname(__FILE__),
14
+ '..','res','clean.yml'))
15
+ puts "Warning: config file #{file} not found; using default #{ex}"
16
+ @config||=YAML.load(File.open(ex))
17
+ end
18
+ end
19
+
20
+ def destination_map
21
+ unless @destination_map
22
+ @destination_map={}
23
+ config['directories'].each do |directory, extensions|
24
+ extensions.each do |ext|
25
+ @destination_map[ext]=directory
26
+ end
27
+ end
28
+ end
29
+ @destination_map
30
+ end
31
+ end
@@ -0,0 +1,21 @@
1
+ ##################################################
2
+ ### Find move destinations #######################
3
+ ##################################################
4
+
5
+ module Destinations
6
+ def all_extensions_for filename
7
+ destination_map.keys.map{ |extension|
8
+ safe_extension=Regexp.escape(extension)
9
+ (filename =~ Regexp.new("#{safe_extension}$")) ? extension : nil
10
+ }.compact
11
+ end
12
+
13
+ def destination_for filename
14
+ longest_extension=
15
+ all_extensions_for(filename).sort{|a,b|
16
+ -(a<=>b)
17
+ }[0]
18
+
19
+ destination_map[longest_extension]
20
+ end
21
+ end
data/lib/options.rb ADDED
@@ -0,0 +1,31 @@
1
+ ##################################################
2
+ ### Options ######################################
3
+ ##################################################
4
+
5
+ module Options
6
+ def get_options args=ARGV
7
+ opts=Trollop::options(args) do
8
+ version "cleaner 1.1.1"
9
+ banner <<-EOS
10
+ Cleaner is a program for automatically sorting files based on their extensions.
11
+
12
+ Usage:
13
+ clean [options] <dirs>+
14
+
15
+ where [options] are:
16
+ EOS
17
+ opt(:dry_run, "Just print commands, don't move anything",
18
+ :default=>false)
19
+ opt(:config_file, "Where to load mappings from",
20
+ :default=>'~/.clean.yml', :type=>String)
21
+ opt(:silent, "Don't print commands",
22
+ :default=>false)
23
+ opt(:on_collision, "If the destination file already exists, rename, overwrite, or ignore?",
24
+ :default=>'rename')
25
+ end
26
+
27
+ opts[:dirs]=( args.empty? ? ['.'] : args )
28
+
29
+ opts
30
+ end
31
+ end
data/res/clean.yml ADDED
@@ -0,0 +1,36 @@
1
+ directories:
2
+ images:
3
+ - .jpg
4
+ - .JPG
5
+ - .gif
6
+ - .GIF
7
+ - .png
8
+ - .jpeg
9
+
10
+ documents:
11
+ - .pdf
12
+ - .doc
13
+ - .ps
14
+
15
+ archives:
16
+ - .tar.gz
17
+ - .gz
18
+ - .zip
19
+ - .bzip
20
+
21
+ programs:
22
+ - .dmg
23
+ - .app
24
+ - .pkg
25
+
26
+ windows:
27
+ - .exe
28
+ - .EXE
29
+
30
+ code:
31
+ - .java
32
+ - .rb
33
+
34
+ _rm:
35
+ - .torrent
36
+ - "~"
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: randrews-clean
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Andrews, Ross
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-08 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 2.1.0
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: trollop
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.10.2
34
+ version:
35
+ description:
36
+ email: randrews@geekfu.org
37
+ executables:
38
+ - clean
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - res/clean.yml
45
+ - lib/clean.rb
46
+ - lib/command_util.rb
47
+ - lib/commands.rb
48
+ - lib/config.rb
49
+ - lib/destinations.rb
50
+ - lib/options.rb
51
+ has_rdoc: false
52
+ homepage: http://geekfu.org
53
+ licenses:
54
+ post_install_message:
55
+ rdoc_options: []
56
+
57
+ require_paths:
58
+ - lib
59
+ required_ruby_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: "0"
70
+ version:
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.3.5
75
+ signing_key:
76
+ specification_version: 2
77
+ summary: A utility for sorting messy folders
78
+ test_files: []
79
+