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.
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: clean
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 1
8
+ - 1
9
+ version: 1.1.1
10
+ platform: ruby
11
+ authors:
12
+ - Andrews, Ross
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2009-03-08 00:00:00 -06:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activesupport
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 2
29
+ - 1
30
+ - 0
31
+ version: 2.1.0
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: trollop
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 1
43
+ - 10
44
+ - 2
45
+ version: 1.10.2
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ description:
49
+ email: randrews@geekfu.org
50
+ executables:
51
+ - clean
52
+ extensions: []
53
+
54
+ extra_rdoc_files: []
55
+
56
+ files:
57
+ - res/clean.yml
58
+ - lib/clean.rb
59
+ - lib/command_util.rb
60
+ - lib/commands.rb
61
+ - lib/config.rb
62
+ - lib/destinations.rb
63
+ - lib/options.rb
64
+ has_rdoc: true
65
+ homepage: http://geekfu.org
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options: []
70
+
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ requirements: []
88
+
89
+ rubyforge_project:
90
+ rubygems_version: 1.3.6
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: A utility for sorting messy folders
94
+ test_files: []
95
+