mass_renamer 1.0.1 → 1.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 237cf3dbfca3c8fa49985903062bd78afc5d5fd7
4
- data.tar.gz: 3e0e3e5dfcbebc667a0d6270491fbfd01779bc67
2
+ SHA256:
3
+ metadata.gz: 0bb62c98bf86b0179ff0bbb977095e5ca508d83b36381ddb3d2e0df0e6d44de0
4
+ data.tar.gz: '0798754ad301d478b23da28eed974c295b3f23818571352f208c0558afe60694'
5
5
  SHA512:
6
- metadata.gz: d7e79d2784454fe018ad40f805b52832e1959e3474770aec52ec04dcabe62c116a48921dca429800d00c5dc2ff807d38d938802351b937697e09f673f28b6540
7
- data.tar.gz: ca2528824e3bffba17ec7807e88012ecd460b446ccb5b8ac69486a77e9c18a36987b10cc473533f1f201768968697ff1619be4f2905a91545738e297b192be1a
6
+ metadata.gz: f5f17e53aecab501f25984baca26c89f4afee3d7dcfc6c88ac5a34e3d72d34797cb405f947f1513fbb935aafd876096728c20e0af7b64adb84827dacbc66585b
7
+ data.tar.gz: ce973c05053608d44d833be3c7ef57e277c66cc8d39cfd5f8695f5750fde07fa008c4aea49f8c045a36ffaeeeb0226056251c44c9c4cd41a3648148093438531
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ load File.expand_path(File.dirname(__FILE__) + '/mass_renamer')
@@ -0,0 +1,4 @@
1
+ require 'mass_renamer/free'
2
+ require 'mass_renamer/version'
3
+ require 'mass_renamer/command_line'
4
+ require 'mass_renamer/driver'
@@ -0,0 +1,71 @@
1
+ require 'optparse'
2
+
3
+ module MassRenamer
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('-F', '--force', 'Don\'t ask if target exists') do
41
+ opts[:force] = true
42
+ end
43
+ opt.on('-D', '--no-delete', 'Completely disables delete function') do
44
+ opts[:no_delete] = true
45
+ end
46
+ opt.on('-v', '--verify', 'Ask for consent before doing each action') do
47
+ opts[:verify] = true
48
+ end
49
+ opt.on('-k', '--keep-going', 'Keep going after failure') do
50
+ opts[:keep_going] = true
51
+ end
52
+ opt.on('-V', '--verbose', 'Be verbose') do
53
+ opts[:verbose] = true
54
+ end
55
+ opt.on('--version', 'Print version') do
56
+ opts[:version] = true
57
+ end
58
+ opt.on('-e', '--editor EDITOR', 'Editor to use') do |editor|
59
+ opts[:editor] = editor
60
+ end
61
+ opt.on('-f', '--filter REGEX', Regexp, 'Regex used to filter files') do |filter|
62
+ opts[:filter] = filter
63
+ end
64
+ end.parse!(argv)
65
+ opts[:dir] = argv[0] || Dir::pwd
66
+ opts[:editor] ||= ENV['EDITOR'] || 'vim'
67
+ opts
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,177 @@
1
+ require 'pathname'
2
+ require 'tempfile'
3
+
4
+ module MassRenamer
5
+
6
+ class Filesystem_Driver
7
+
8
+ def initialize ask: , dry:, verbose:, no_delete:, force:
9
+ @ask = ask
10
+ @dry = dry
11
+ @verbose = verbose
12
+ @no_delete = no_delete
13
+ @force = force
14
+ end
15
+
16
+ def ask msg, from, to = nil
17
+ print "#{msg} '#{from}'#{to ? " -> '#{to}'" : '' }? [YN]: "
18
+ gets.chomp.downcase == ?y
19
+ end
20
+
21
+ def overwrite to
22
+ loop do
23
+ print "Overwrite #{to}? [Y(es)/N(o)/A(bort)]: "
24
+ case gets.chomp.downcase
25
+ when ?a
26
+ puts "Aborting."
27
+ return :abort
28
+ when ?y
29
+ return :yes
30
+ when ?n
31
+ puts "Not overwriting, skipping."
32
+ return :no
33
+ else
34
+ puts "Unexpected answer, try again."
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ def remove! from
41
+ raise "Deletes were disables." if @no_delete
42
+ begin
43
+ puts "rm -r '#{from}'" if @dry or @verbose
44
+ if @ask
45
+ return unless ask("Remove file", from)
46
+ end
47
+ return if @dry
48
+ FileUtils.remove_entry from
49
+ rescue StandardError => e
50
+ STDERR.puts "remove of '#{from}' failed: #{e.message}"
51
+ raise
52
+ end
53
+ end
54
+
55
+ def copy! from, to
56
+ begin
57
+ puts "cp -r '#{from}' '#{to}'" if @dry or @verbose
58
+ if @ask
59
+ return unless ask("Copy", from, to)
60
+ end
61
+ return if @dry
62
+ if File.exist?(to) and not @force
63
+ case overwrite(to)
64
+ when :abort
65
+ exit 1
66
+ when :no
67
+ return
68
+ when :yes
69
+ end
70
+ end
71
+ FileUtils.mkdir_p File.dirname(to)
72
+ FileUtils.copy_entry from, to, preserve: true, remove_destination: true
73
+ rescue StandardError => e
74
+ STDERR.puts "copy '#{from}' -> '#{to}' failed: #{e.message}"
75
+ raise
76
+ end
77
+ end
78
+
79
+ def move! from, to
80
+ begin
81
+ puts "mv '#{from}' '#{to}'" if @dry or @verbose
82
+ if @ask
83
+ return unless ask("Move", from, to)
84
+ end
85
+ return if @dry
86
+ if File.exist?(to) and not @force
87
+ case overwrite(to)
88
+ when :abort
89
+ exit 1
90
+ when :no
91
+ return
92
+ when :yes
93
+ end
94
+ end
95
+ FileUtils.mkdir_p File.dirname(to)
96
+ File.rename from, to
97
+ rescue StandardError => e
98
+ STDERR.puts "move '#{from}' -> '#{to}' failed: #{e.message}"
99
+ raise
100
+ end
101
+ end
102
+
103
+ end
104
+
105
+ class Driver
106
+ include Free
107
+
108
+ def initialize opts
109
+ @opts = opts
110
+ validate_environment!
111
+ end
112
+
113
+ def rename!
114
+ files = gather_files(
115
+ @opts[:dir],
116
+ recursive: @opts[:recursive],
117
+ filter: @opts[:filter]
118
+ )
119
+ renames = invoke_editor files
120
+ do_renames! renames
121
+ end
122
+
123
+ def do_renames! renames
124
+ fd = Filesystem_Driver.new(
125
+ ask: @opts[:ask],
126
+ dry: @opts[:dry],
127
+ verbose: @opts[:verbose],
128
+ no_delete: @opts[:no_delete],
129
+ force: @opts[:force]
130
+ )
131
+
132
+ renames.each do |from, to|
133
+ from = File.expand_path from
134
+ to.map!(&File.method(:expand_path))
135
+
136
+ begin
137
+ case to.length
138
+ when 0
139
+ fd.remove! from
140
+ when 1
141
+ to = to.first
142
+ next if from == to
143
+ fd.move! from, to
144
+ else
145
+ to.each { |dst| fd.copy! from, dst unless from == dst }
146
+ fd.remove! from unless to.include? from
147
+ end
148
+ rescue
149
+ next if @opts[:keep_going]
150
+ STDERR.puts "Something failed, stopping."
151
+ exit 1
152
+ end
153
+ end
154
+ end
155
+
156
+ def invoke_editor files
157
+ tmpfile = Tempfile.new
158
+ begin
159
+ tmpfile.write generate_file_to_edit(files)
160
+ tmpfile.close
161
+ unless system(@opts[:editor], tmpfile.path)
162
+ raise "Cannot open editor (not in path?). Fix it."
163
+ end
164
+ tmpfile.open
165
+ parse_renames(tmpfile.read)
166
+ ensure
167
+ tmpfile.close
168
+ tmpfile.unlink
169
+ end
170
+ end
171
+
172
+ def validate_environment!
173
+ raise IOError, "Directory does not exist." unless File.exist? @opts[:dir]
174
+ end
175
+
176
+ end
177
+ end
@@ -0,0 +1,75 @@
1
+ require 'pathname'
2
+ require 'tempfile'
3
+
4
+ module MassRenamer
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).reject { |l| l[/^\s*$/] }
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 MassRenamer
2
+ VERSION = '1.0.2'
3
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mass_renamer
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gray Wolf
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-30 00:00:00.000000000 Z
11
+ date: 2018-10-27 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  Tool for renaming multiple files at once with easy. By
@@ -16,19 +16,17 @@ description: |
16
16
  all the power you editor offers.
17
17
  email: wolf@wolfsden.cz
18
18
  executables:
19
- - renamer
20
- - mass_renamer
19
+ - mass-renamer
21
20
  extensions: []
22
21
  extra_rdoc_files: []
23
22
  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
23
+ - bin/mass-renamer
24
+ - lib/mass_renamer.rb
25
+ - lib/mass_renamer/command_line.rb
26
+ - lib/mass_renamer/driver.rb
27
+ - lib/mass_renamer/free.rb
28
+ - lib/mass_renamer/version.rb
29
+ homepage: https://github.com/graywolf/mass-renamer
32
30
  licenses:
33
31
  - MIT
34
32
  metadata: {}
@@ -48,7 +46,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
48
46
  version: '0'
49
47
  requirements: []
50
48
  rubyforge_project:
51
- rubygems_version: 2.6.11
49
+ rubygems_version: 2.7.6
52
50
  signing_key:
53
51
  specification_version: 4
54
52
  summary: Rename multiple files with ease!
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- load File.expand_path(File.dirname(__FILE__) + '/renamer')
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
4
-
5
- require 'renamer'
6
-
7
- begin
8
- cli = Renamer::Command_Line.new ARGV
9
- cli.rename!
10
- rescue => e
11
- STDERR.puts e.message
12
- STDERR.puts
13
- STDERR.puts "Backtrace:"
14
- STDERR.puts e.backtrace
15
- exit 1
16
- end
@@ -1,4 +0,0 @@
1
- require 'renamer/free'
2
- require 'renamer/version'
3
- require 'renamer/command_line'
4
- require 'renamer/driver'
@@ -1,71 +0,0 @@
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('-F', '--force', 'Don\'t ask if target exists') do
41
- opts[:force] = true
42
- end
43
- opt.on('-D', '--no-delete', 'Completely disables delete function') do
44
- opts[:no_delete] = true
45
- end
46
- opt.on('-v', '--verify', 'Ask for consent before doing each action') do
47
- opts[:verify] = true
48
- end
49
- opt.on('-k', '--keep-going', 'Keep going after failure') do
50
- opts[:keep_going] = true
51
- end
52
- opt.on('-V', '--verbose', 'Be verbose') do
53
- opts[:verbose] = true
54
- end
55
- opt.on('--version', 'Print version') do
56
- opts[:version] = true
57
- end
58
- opt.on('-e', '--editor EDITOR', 'Editor to use') do |editor|
59
- opts[:editor] = editor
60
- end
61
- opt.on('-f', '--filter REGEX', Regexp, 'Regex used to filter files') do |filter|
62
- opts[:filter] = filter
63
- end
64
- end.parse!(argv)
65
- opts[:dir] = argv[0] || Dir::pwd
66
- opts[:editor] ||= ENV['EDITOR'] || 'vim'
67
- opts
68
- end
69
- end
70
-
71
- end
@@ -1,177 +0,0 @@
1
- require 'pathname'
2
- require 'tempfile'
3
-
4
- module Renamer
5
-
6
- class Filesystem_Driver
7
-
8
- def initialize ask: , dry:, verbose:, no_delete:, force:
9
- @ask = ask
10
- @dry = dry
11
- @verbose = verbose
12
- @no_delete = no_delete
13
- @force = force
14
- end
15
-
16
- def ask msg, from, to = nil
17
- print "#{msg} '#{from}'#{to ? " -> '#{to}'" : '' }? [YN]: "
18
- gets.chomp.downcase == ?y
19
- end
20
-
21
- def overwrite to
22
- loop do
23
- print "Overwrite #{to}? [Y(es)/N(o)/A(bort)]: "
24
- case gets.chomp.downcase
25
- when ?a
26
- puts "Aborting."
27
- return :abort
28
- when ?y
29
- return :yes
30
- when ?n
31
- puts "Not overwriting, skipping."
32
- return :no
33
- else
34
- puts "Unexpected answer, try again."
35
- end
36
- end
37
-
38
- end
39
-
40
- def remove! from
41
- raise "Deletes were disables." if @no_delete
42
- begin
43
- puts "rm -r '#{from}'" if @dry or @verbose
44
- if @ask
45
- return unless ask("Remove file", from)
46
- end
47
- return if @dry
48
- FileUtils.remove_entry from
49
- rescue StandardError => e
50
- STDERR.puts "remove of '#{from}' failed: #{e.message}"
51
- raise
52
- end
53
- end
54
-
55
- def copy! from, to
56
- begin
57
- puts "cp -r '#{from}' '#{to}'" if @dry or @verbose
58
- if @ask
59
- return unless ask("Copy", from, to)
60
- end
61
- return if @dry
62
- if File.exist?(to) and not @force
63
- case overwrite(to)
64
- when :abort
65
- exit 1
66
- when :no
67
- return
68
- when :yes
69
- end
70
- end
71
- FileUtils.mkdir_p File.dirname(to)
72
- FileUtils.copy_entry from, to, preserve: true, remove_destination: true
73
- rescue StandardError => e
74
- STDERR.puts "copy '#{from}' -> '#{to}' failed: #{e.message}"
75
- raise
76
- end
77
- end
78
-
79
- def move! from, to
80
- begin
81
- puts "mv '#{from}' '#{to}'" if @dry or @verbose
82
- if @ask
83
- return unless ask("Move", from, to)
84
- end
85
- return if @dry
86
- if File.exist?(to) and not @force
87
- case overwrite(to)
88
- when :abort
89
- exit 1
90
- when :no
91
- return
92
- when :yes
93
- end
94
- end
95
- FileUtils.mkdir_p File.dirname(to)
96
- File.rename from, to
97
- rescue StandardError => e
98
- STDERR.puts "move '#{from}' -> '#{to}' failed: #{e.message}"
99
- raise
100
- end
101
- end
102
-
103
- end
104
-
105
- class Driver
106
- include Free
107
-
108
- def initialize opts
109
- @opts = opts
110
- validate_environment!
111
- end
112
-
113
- def rename!
114
- files = gather_files(
115
- @opts[:dir],
116
- recursive: @opts[:recursive],
117
- filter: @opts[:filter]
118
- )
119
- renames = invoke_editor files
120
- do_renames! renames
121
- end
122
-
123
- def do_renames! renames
124
- fd = Filesystem_Driver.new(
125
- ask: @opts[:ask],
126
- dry: @opts[:dry],
127
- verbose: @opts[:verbose],
128
- no_delete: @opts[:no_delete],
129
- force: @opts[:force]
130
- )
131
-
132
- renames.each do |from, to|
133
- from = File.expand_path from
134
- to.map!(&File.method(:expand_path))
135
-
136
- begin
137
- case to.length
138
- when 0
139
- fd.remove! from
140
- when 1
141
- to = to.first
142
- next if from == to
143
- fd.move! from, to
144
- else
145
- to.each { |to| fd.copy! from, to unless from == to }
146
- fd.remove! from unless to.include? from
147
- end
148
- rescue
149
- next if @opts[:keep_going]
150
- STDERR.puts "Something failed, stopping."
151
- exit 1
152
- end
153
- end
154
- end
155
-
156
- def invoke_editor files
157
- tmpfile = Tempfile.new
158
- begin
159
- tmpfile.write generate_file_to_edit(files)
160
- tmpfile.close
161
- unless system(@opts[:editor], tmpfile.path)
162
- raise "Cannot open editor (not in path?). Fix it."
163
- end
164
- tmpfile.open
165
- parse_renames(tmpfile.read)
166
- ensure
167
- tmpfile.close
168
- tmpfile.unlink
169
- end
170
- end
171
-
172
- def validate_environment!
173
- raise IOError, "Directory does not exist." unless File.exist? @opts[:dir]
174
- end
175
-
176
- end
177
- end
@@ -1,75 +0,0 @@
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).reject { |l| l[/^\s*$/] }
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
@@ -1,3 +0,0 @@
1
- module Renamer
2
- VERSION = '1.0.1'
3
- end