mass_renamer 0.9.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8cb99e36d38c302b2c0c096f491376f389478fdf
4
+ data.tar.gz: 7eb9b871ed283a1452f2b7d1448ef8dd0216139c
5
+ SHA512:
6
+ metadata.gz: d8c9a507a59b948f00924bdeec27c1223952494df820b971bde0cb887d5a077cb62cc54d7f27f4e9138a4f6e3d482c27ae3bdace67b9f3cda5a4f25497b0f99d
7
+ data.tar.gz: 341df60426ae34871af5780d633535c87ea230ebed06af7ccd1578a08fbf2ae31c3208a6e600e1abdf2bcc2b10feee96920d54337350c4d8b461618f8de3f477
data/bin/mass_renamer ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ load File.expand_path(File.dirname(__FILE__) + '/renamer')
data/bin/renamer ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'renamer'
4
+
5
+ begin
6
+ cli = Renamer::Command_Line.new ARGV
7
+ cli.rename!
8
+ rescue => e
9
+ STDERR.puts e.message
10
+ STDERR.puts e.backtrace
11
+ exit 1
12
+ end
@@ -0,0 +1,68 @@
1
+ require 'optparse'
2
+
3
+ module Renamer
4
+
5
+ class Command_Line
6
+ def initialize argv = ARGV
7
+ opts = parse argv
8
+ @driver = Driver.new opts
9
+ end
10
+
11
+ def rename!
12
+ @driver.rename!
13
+ end
14
+
15
+ def parse argv
16
+ opts = {}
17
+ OptionParser.new do |opt|
18
+ opt.banner = 'Usage: renamer [DIRECTORY] [OPTIONS]'
19
+ opt.separator ''
20
+ opt.separator 'DIRECTORY in which you want to rename. If not'
21
+ opt.separator 'provided, `pwd` is used.'
22
+ opt.separator ''
23
+ opt.separator 'Editor to use is determined by this priority:'
24
+ opt.separator ' --editor'
25
+ opt.separator ' $EDITOR'
26
+ opt.separator ' vim'
27
+ opt.separator ''
28
+ opt.separator 'Options:'
29
+
30
+ opt.on('-h', '--help', 'Print usage') do
31
+ puts opt
32
+ exit
33
+ end
34
+ opt.on('-d', '--dry', 'Dry run') do
35
+ opts[:dry] = true
36
+ end
37
+ opt.on('-r', '--recursive', 'Recurse into subdirectories') do
38
+ opts[:recursive] = true
39
+ end
40
+ opt.on('-D', '--no-delete', 'Complete disables delete function') do
41
+ opts[:no_delete] = true
42
+ end
43
+ opt.on('-v', '--verify', 'Ask for consent before doing each action') do
44
+ opts[:verify] = true
45
+ end
46
+ opt.on('-k', '--keep-going', 'Keep going after failure') do
47
+ opts[:keep_going] = true
48
+ end
49
+ opt.on('-V', '--verbose', 'Be verbose') do
50
+ opts[:verbose] = true
51
+ end
52
+ opt.on('--version', 'Print version') do
53
+ opts[:version] = true
54
+ end
55
+ opt.on('-e', '--editor EDITOR', 'Editor to use') do |editor|
56
+ opts[:editor] = editor
57
+ end
58
+ opt.on('-f', '--filter REGEX', Regexp, 'Regex used to filter files') do |filter|
59
+ opts[:filter] = filter
60
+ end
61
+ end.parse!(argv)
62
+ opts[:dir] = argv[0] || Dir::pwd
63
+ opts[:editor] ||= ENV['EDITOR'] || 'vim'
64
+ opts
65
+ end
66
+ end
67
+
68
+ end
@@ -0,0 +1,136 @@
1
+ require 'pathname'
2
+ require 'tempfile'
3
+
4
+ module Renamer
5
+
6
+ class Filesystem_Driver
7
+
8
+ def initialize ask: , dry:, verbose:, no_delete:
9
+ @ask = ask
10
+ @dry = dry
11
+ @verbose = verbose
12
+ @no_delete = no_delete
13
+ end
14
+
15
+ def ask msg, from, to = nil
16
+ print "#{msg} '#{from}'#{to ? " -> '#{to}'" : '' }? [YN]: "
17
+ gets.chomp.downcase == ?y
18
+ end
19
+
20
+ def remove! from
21
+ raise "Deletes were disables." if @no_delete
22
+ begin
23
+ puts "rm -r '#{from}'" if @dry or @verbose
24
+ if @ask
25
+ return unless ask("Remove file", from)
26
+ end
27
+ return if @dry
28
+ FileUtils.remove_entry from
29
+ rescue StandardError => e
30
+ STDERR.puts "remove of '#{from}' failed: #{e.message}"
31
+ raise
32
+ end
33
+ end
34
+
35
+ def copy! from, to
36
+ begin
37
+ puts "cp -r '#{from}' '#{to}'" if @dry or @verbose
38
+ if @ask
39
+ return unless ask("Copy", from, to)
40
+ end
41
+ return if @dry
42
+ FileUtils.mkdir_p File.dirname(to)
43
+ FileUtils.copy_entry from, to, preserve: true, remove_destination: true
44
+ rescue StandardError => e
45
+ STDERR.puts "copy '#{from}' -> '#{to}' failed: #{e.message}"
46
+ raise
47
+ end
48
+ end
49
+
50
+ def move! from, to
51
+ begin
52
+ puts "mv '#{from}' '#{to}'" if @dry or @verbose
53
+ if @ask
54
+ return unless ask("Move", from, to)
55
+ end
56
+ return if @dry
57
+ FileUtils.mkdir_p File.dirname(to)
58
+ File.rename from, to
59
+ rescue StandardError => e
60
+ STDERR.puts "move '#{from}' -> '#{to}' failed: #{e.message}"
61
+ raise
62
+ end
63
+ end
64
+
65
+ end
66
+
67
+ class Driver
68
+ include Free
69
+
70
+ def initialize opts
71
+ @opts = opts
72
+ validate_environment!
73
+ end
74
+
75
+ def rename!
76
+ files = gather_files(
77
+ @opts[:dir],
78
+ recursive: @opts[:recursive],
79
+ filter: @opts[:filter]
80
+ )
81
+ renames = invoke_editor files
82
+ do_renames! renames
83
+ end
84
+
85
+ def do_renames! renames
86
+ fd = Filesystem_Driver.new(
87
+ ask: @opts[:ask],
88
+ dry: @opts[:dry],
89
+ verbose: @opts[:verbose],
90
+ no_delete: @opts[:no_delete]
91
+ )
92
+
93
+ renames.each do |from, to|
94
+ from = File.expand_path from
95
+ to.map!(&File.method(:expand_path))
96
+
97
+ begin
98
+ case to.length
99
+ when 0
100
+ fd.remove! from
101
+ when 1
102
+ to = to.first
103
+ next if from == to
104
+ fd.move! from, to
105
+ else
106
+ to.each { |to| fd.copy! from, to }
107
+ fd.remove! from
108
+ end
109
+ rescue
110
+ next if @opts[:keep_going]
111
+ STDERR.puts "Something failed, stopping."
112
+ exit 1
113
+ end
114
+ end
115
+ end
116
+
117
+ def invoke_editor files
118
+ tmpfile = Tempfile.new
119
+ begin
120
+ tmpfile.write generate_file_to_edit(files)
121
+ tmpfile.flush
122
+ system(@opts[:editor], tmpfile.path)
123
+ tmpfile.rewind
124
+ parse_renames(tmpfile.read)
125
+ ensure
126
+ tmpfile.close
127
+ tmpfile.unlink
128
+ end
129
+ end
130
+
131
+ def validate_environment!
132
+ raise IOError, "Directory does not exist." unless File.exist? @opts[:dir]
133
+ end
134
+
135
+ end
136
+ end
@@ -0,0 +1,75 @@
1
+ require 'pathname'
2
+ require 'tempfile'
3
+
4
+ module Renamer
5
+ module Free
6
+
7
+ def gather_files_impl dir, recursive
8
+ children = dir.children false
9
+ sort_files! children
10
+ if recursive
11
+ children.collect! do |c|
12
+ filepath = dir + c
13
+ if filepath.directory?
14
+ [filepath, gather_files_impl(filepath, recursive)]
15
+ else
16
+ filepath
17
+ end
18
+ end.flatten!
19
+ end
20
+ children
21
+ end
22
+
23
+ def gather_files(dir, recursive: false, filter: nil)
24
+ files = gather_files_impl Pathname.new(dir), recursive
25
+ filter_files! files, filter if filter
26
+ exclude_weird_filenames! files
27
+ files
28
+ end
29
+
30
+ def filter_files! files, filter
31
+ files.select! { |i| i.to_s[filter] } if filter
32
+ end
33
+
34
+ def exclude_weird_filenames! files
35
+ files.reject! { |f| f = f.to_s; f.include?("\n") or f.start_with?(" ") }
36
+ end
37
+
38
+ def sort_files! files
39
+ files.sort! do |a,b|
40
+ if a.directory? and b.directory?
41
+ a <=> b
42
+ elsif a.directory?
43
+ -1
44
+ elsif b.directory?
45
+ 1
46
+ else
47
+ a <=> b
48
+ end
49
+ end
50
+ end
51
+
52
+ def generate_file_to_edit files
53
+ res = ""
54
+ files.each do |f|
55
+ res << f.to_s << "\n\t" << f.to_s << "\n"
56
+ end
57
+ res
58
+ end
59
+
60
+ def parse_renames str
61
+ lines = str.lines.map(&:chomp)
62
+ renames = []
63
+ until lines.empty?
64
+ filename = lines.shift
65
+ targets = []
66
+ while lines[0] and lines[0] =~ /^\s/
67
+ targets << lines.shift.strip
68
+ end
69
+ renames << [filename, targets]
70
+ end
71
+ renames
72
+ end
73
+
74
+ end
75
+ end
@@ -0,0 +1,3 @@
1
+ module Renamer
2
+ VERSION = '0.9.0'
3
+ end
data/lib/renamer.rb ADDED
@@ -0,0 +1,4 @@
1
+ require 'renamer/free'
2
+ require 'renamer/version'
3
+ require 'renamer/command_line'
4
+ require 'renamer/driver'
metadata ADDED
@@ -0,0 +1,55 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mass_renamer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ platform: ruby
6
+ authors:
7
+ - Gray Wolf
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-06-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: |
14
+ Tool for renaming multiple files at once with easy. By
15
+ employing external editor of your choice, you can use
16
+ all the power you editor offers.
17
+ email: wolf@wolfsden.cz
18
+ executables:
19
+ - renamer
20
+ - mass_renamer
21
+ extensions: []
22
+ extra_rdoc_files: []
23
+ files:
24
+ - bin/mass_renamer
25
+ - bin/renamer
26
+ - lib/renamer.rb
27
+ - lib/renamer/command_line.rb
28
+ - lib/renamer/driver.rb
29
+ - lib/renamer/free.rb
30
+ - lib/renamer/version.rb
31
+ homepage: https://github.com/graywolf/renamer
32
+ licenses:
33
+ - MIT
34
+ metadata: {}
35
+ post_install_message:
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubyforge_project:
51
+ rubygems_version: 2.6.11
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Rename multiple files with ease!
55
+ test_files: []