renmov 0.0.3 → 0.1.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.
- data/bin/renmov +2 -2
- data/features/options.feature +36 -0
- data/features/rename_files.feature +5 -0
- data/lib/renmov.rb +1 -0
- data/lib/renmov/basic_renamer.rb +2 -1
- data/lib/renmov/cli.rb +64 -37
- data/lib/renmov/errors.rb +7 -0
- data/lib/renmov/version.rb +1 -1
- data/spec/renmov/cli_spec.rb +102 -57
- metadata +3 -2
data/bin/renmov
CHANGED
data/features/options.feature
CHANGED
@@ -67,3 +67,39 @@ Feature: Options
|
|
67
67
|
|
68
68
|
Usage: renmov [options] filename...
|
69
69
|
"""
|
70
|
+
|
71
|
+
Scenario: no arguments/options
|
72
|
+
Given a blank slate
|
73
|
+
When I run `renmov`
|
74
|
+
Then the exit status should be 1
|
75
|
+
And the stderr should contain:
|
76
|
+
"""
|
77
|
+
renmov: no filename(s) provided
|
78
|
+
Rename video files to a consistent format.
|
79
|
+
|
80
|
+
Usage: renmov [options] filename...
|
81
|
+
"""
|
82
|
+
|
83
|
+
Scenario: invalid option (short)
|
84
|
+
Given a blank slate
|
85
|
+
When I run `renmov -i`
|
86
|
+
Then the exit status should be 1
|
87
|
+
And the stderr should contain:
|
88
|
+
"""
|
89
|
+
renmov: invalid option: -i
|
90
|
+
Rename video files to a consistent format.
|
91
|
+
|
92
|
+
Usage: renmov [options] filename...
|
93
|
+
"""
|
94
|
+
|
95
|
+
Scenario: invalid option (long)
|
96
|
+
Given a blank slate
|
97
|
+
When I run `renmov --invalid`
|
98
|
+
Then the exit status should be 1
|
99
|
+
And the stderr should contain:
|
100
|
+
"""
|
101
|
+
renmov: invalid option: --invalid
|
102
|
+
Rename video files to a consistent format.
|
103
|
+
|
104
|
+
Usage: renmov [options] filename...
|
105
|
+
"""
|
@@ -14,3 +14,8 @@ Feature: Rename Files
|
|
14
14
|
| TV.Show.S01E02.HDTV.x264-LOL.[VTV].mp4 | tv.show.s01e02.mp4 |
|
15
15
|
| The.TV.Show.S01E02.[VTV].avi | tv.show.s01e02.avi |
|
16
16
|
| TV.Show.2012.S01E02.x264-LOL.mp4 | tv.show.s01e02.mp4 |
|
17
|
+
|
18
|
+
Scenario: same file name
|
19
|
+
Given an empty file named "tv.show.s01e01.mp4"
|
20
|
+
When I successfully run `renmov tv.show.s01e01.mp4`
|
21
|
+
Then a file named "tv.show.s01e01.mp4" should exist
|
data/lib/renmov.rb
CHANGED
data/lib/renmov/basic_renamer.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Renmov
|
2
2
|
class BasicRenamer
|
3
3
|
attr_reader :filename
|
4
|
+
|
4
5
|
def initialize(filename)
|
5
6
|
@filename = filename.downcase
|
6
7
|
end
|
@@ -38,7 +39,7 @@ module Renmov
|
|
38
39
|
|
39
40
|
def get_format
|
40
41
|
format = filename.dup
|
41
|
-
format.gsub!(/.*\.(
|
42
|
+
format.gsub!(/.*\.(.*)\z/, '\1')
|
42
43
|
|
43
44
|
format
|
44
45
|
end
|
data/lib/renmov/cli.rb
CHANGED
@@ -1,65 +1,92 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
require 'fileutils'
|
3
3
|
require 'renmov/basic_renamer'
|
4
|
+
require 'renmov/errors'
|
4
5
|
|
5
6
|
module Renmov
|
6
7
|
class CLI
|
7
|
-
attr_reader :args
|
8
|
-
attr_accessor :
|
9
|
-
attr_accessor :filenames
|
10
|
-
attr_accessor :renamer
|
8
|
+
attr_reader :executable_name, :args, :options, :optparse
|
9
|
+
attr_accessor :filenames, :renamer
|
11
10
|
|
12
11
|
def initialize(args = ARGV, renamer = BasicRenamer)
|
12
|
+
@executable_name = File.basename($PROGRAM_NAME, '.rb')
|
13
13
|
@args = args
|
14
|
-
@filenames = []
|
15
14
|
@options = { verbose: false, noop: false }
|
15
|
+
@optparse = OptionParser.new
|
16
|
+
@filenames = []
|
16
17
|
@renamer = renamer
|
17
18
|
end
|
18
19
|
|
19
|
-
def
|
20
|
-
|
21
|
-
executable_name = File.basename($PROGRAM_NAME, '.rb')
|
22
|
-
opts.banner = <<EOL
|
23
|
-
Rename video files to a consistent format.
|
20
|
+
def run
|
21
|
+
exit_status = 0
|
24
22
|
|
25
|
-
|
26
|
-
|
23
|
+
begin
|
24
|
+
parse_options
|
25
|
+
raise NoFilenameError if filenames.empty?
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
filenames.each do |filename|
|
28
|
+
dirname = "#{File.dirname(filename)}/"
|
29
|
+
dirname.gsub!(/\A\.\/\z/, '')
|
30
|
+
|
31
|
+
basename = File.basename(filename)
|
32
|
+
renamer_i = renamer.new(basename)
|
33
|
+
newname = "#{dirname}#{renamer_i.rename}"
|
31
34
|
|
32
|
-
|
33
|
-
options[:noop] = true
|
34
|
-
options[:verbose] = true
|
35
|
+
rename_file(filename, newname)
|
35
36
|
end
|
37
|
+
rescue OptionParser::InvalidOption => e
|
38
|
+
output_error_message(e)
|
39
|
+
exit_status = 1
|
40
|
+
rescue NoFilenameError => e
|
41
|
+
output_error_message(e)
|
42
|
+
exit_status = 1
|
43
|
+
end
|
36
44
|
|
37
|
-
|
38
|
-
|
39
|
-
exit
|
40
|
-
end
|
45
|
+
exit_status
|
46
|
+
end
|
41
47
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
48
|
+
def parse_options
|
49
|
+
optparse.banner =
|
50
|
+
['Rename video files to a consistent format.', '',
|
51
|
+
"Usage: #{executable_name} [options] filename..."].join("\n")
|
52
|
+
|
53
|
+
optparse.on('-v', '--verbose',
|
54
|
+
'Output more information') do
|
55
|
+
options[:verbose] = true
|
56
|
+
end
|
57
|
+
|
58
|
+
optparse.on('-n', '--noop',
|
59
|
+
'Output actions without invoking them') do
|
60
|
+
options[:noop] = true
|
61
|
+
options[:verbose] = true
|
62
|
+
end
|
63
|
+
|
64
|
+
optparse.on_tail('-h', '--help',
|
65
|
+
'Show this message') do
|
66
|
+
puts optparse
|
67
|
+
exit
|
68
|
+
end
|
69
|
+
|
70
|
+
optparse.on_tail('--version',
|
71
|
+
'Show version') do
|
72
|
+
puts Renmov::VERSION
|
73
|
+
exit
|
46
74
|
end
|
47
75
|
|
48
76
|
self.filenames = optparse.parse! args
|
49
77
|
end
|
50
78
|
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
newname,
|
79
|
+
def output_error_message(msg)
|
80
|
+
$stderr.puts "#{executable_name}: #{msg}"
|
81
|
+
$stderr.puts optparse
|
82
|
+
end
|
83
|
+
|
84
|
+
def rename_file(old, new)
|
85
|
+
unless old == new
|
86
|
+
FileUtils.mv(old,
|
87
|
+
new,
|
61
88
|
verbose: options[:verbose],
|
62
|
-
noop:
|
89
|
+
noop: options[:noop])
|
63
90
|
end
|
64
91
|
end
|
65
92
|
end
|
data/lib/renmov/version.rb
CHANGED
data/spec/renmov/cli_spec.rb
CHANGED
@@ -3,22 +3,107 @@ require 'fileutils'
|
|
3
3
|
|
4
4
|
module Renmov
|
5
5
|
describe CLI do
|
6
|
-
describe '#
|
7
|
-
let(:
|
6
|
+
describe '#run' do
|
7
|
+
let(:tmpdir) { File.expand_path('../../../tmp', __FILE__) }
|
8
8
|
|
9
|
+
before(:each) do
|
10
|
+
filenames.each { |f| FileUtils.rm(f) if File.exists?(f) }
|
11
|
+
newnames.each { |f| FileUtils.rm(f) if File.exists?(f) }
|
12
|
+
|
13
|
+
FileUtils.touch(filenames) unless filenames.empty?
|
14
|
+
cli = CLI.new(filenames)
|
15
|
+
@exit_status = cli.run
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'no filename provided' do
|
19
|
+
let(:filenames) { [] }
|
20
|
+
let(:newnames) { [] }
|
21
|
+
|
22
|
+
it 'exits with a status of 1' do
|
23
|
+
@exit_status.should == 1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'one filename provided' do
|
28
|
+
context 'filename different than newname' do
|
29
|
+
let(:filenames) { ["#{tmpdir}/TV.Show.S01E02.HDTV.test.mp4"] }
|
30
|
+
let(:newnames) { ["#{tmpdir}/tv.show.s01e02.mp4"] }
|
31
|
+
|
32
|
+
it 'properly renames file' do
|
33
|
+
File.should_not exist(filenames[0])
|
34
|
+
File.should exist(newnames[0])
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'exits with a status of 0' do
|
38
|
+
@exit_status.should == 0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'filename same as newname' do
|
43
|
+
let(:filenames) { ["#{tmpdir}/tv.show.s01e02.mp4"] }
|
44
|
+
let(:newnames) { ["#{tmpdir}/tv.show.s01e02.mp4"] }
|
45
|
+
|
46
|
+
it 'does not rename file' do
|
47
|
+
File.should exist(newnames[0])
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'exits with a status of 0' do
|
51
|
+
@exit_status.should == 0
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'multiple filenames provided' do
|
57
|
+
context 'filenames different than newnames' do
|
58
|
+
let(:filenames) { ["#{tmpdir}/TV.Show.S01E02.HDTV.test.mp4",
|
59
|
+
"#{tmpdir}/The.TV.Show.S02E03.LOL.avi"] }
|
60
|
+
let(:newnames) { ["#{tmpdir}/tv.show.s01e02.mp4",
|
61
|
+
"#{tmpdir}/tv.show.s02e03.avi"] }
|
62
|
+
|
63
|
+
it 'properly renames all files' do
|
64
|
+
filenames.each { |f| File.should_not exist(f) }
|
65
|
+
newnames.each { |n| File.should exist(n) }
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'exits with a status of 0' do
|
69
|
+
@exit_status.should == 0
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'one filename same as and one filename different than newnames' do
|
74
|
+
let(:filenames) { ["#{tmpdir}/TV.Show.S01E02.HDTV.test.mp4",
|
75
|
+
"#{tmpdir}/tv.show.s02e03.avi"] }
|
76
|
+
let(:newnames) { ["#{tmpdir}/tv.show.s01e02.mp4",
|
77
|
+
"#{tmpdir}/tv.show.s02e03.avi"] }
|
78
|
+
|
79
|
+
it 'properly renames first file and not second file' do
|
80
|
+
File.should_not exist(filenames[0])
|
81
|
+
File.should exist(filenames[1])
|
82
|
+
newnames.each { |n| File.should exist(n) }
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'exits with a status of 0' do
|
86
|
+
@exit_status.should == 0
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#parse_options' do
|
9
93
|
before(:each) do
|
10
94
|
@cli = CLI.new(options + filenames)
|
95
|
+
@default_options = @cli.options
|
11
96
|
@cli.parse_options
|
12
97
|
end
|
13
98
|
|
14
|
-
context '
|
99
|
+
context 'no options provided' do
|
15
100
|
let(:options) { [] }
|
16
101
|
|
17
|
-
context '
|
102
|
+
context 'no filenames provided' do
|
18
103
|
let(:filenames) { [] }
|
19
104
|
|
20
105
|
it 'keeps default options' do
|
21
|
-
@cli.options.should == default_options
|
106
|
+
@cli.options.should == @default_options
|
22
107
|
end
|
23
108
|
|
24
109
|
it 'sets filenames to []' do
|
@@ -26,11 +111,11 @@ module Renmov
|
|
26
111
|
end
|
27
112
|
end
|
28
113
|
|
29
|
-
context '
|
114
|
+
context 'one filename provided' do
|
30
115
|
let(:filenames) { ['TV.Show.S01E02.HDTV.test.mp4'] }
|
31
116
|
|
32
117
|
it 'keeps default options' do
|
33
|
-
@cli.options.should == default_options
|
118
|
+
@cli.options.should == @default_options
|
34
119
|
end
|
35
120
|
|
36
121
|
it 'sets filenames to filename provided' do
|
@@ -39,14 +124,14 @@ module Renmov
|
|
39
124
|
end
|
40
125
|
end
|
41
126
|
|
42
|
-
context '
|
127
|
+
context 'verbose option provided' do
|
43
128
|
let(:options) { ['-v'] }
|
44
129
|
|
45
|
-
context '
|
130
|
+
context 'no filenames provided' do
|
46
131
|
let(:filenames) { [] }
|
47
132
|
|
48
133
|
it 'merges verbose with default options' do
|
49
|
-
@cli.options.should == default_options.merge(verbose: true)
|
134
|
+
@cli.options.should == @default_options.merge(verbose: true)
|
50
135
|
end
|
51
136
|
|
52
137
|
it 'sets filenames to []' do
|
@@ -54,11 +139,11 @@ module Renmov
|
|
54
139
|
end
|
55
140
|
end
|
56
141
|
|
57
|
-
context '
|
142
|
+
context 'one filename provided' do
|
58
143
|
let(:filenames) { ['TV.Show.S01E02.HDTV.test.mp4'] }
|
59
144
|
|
60
145
|
it 'merges verbose with default options' do
|
61
|
-
@cli.options.should == default_options.merge(verbose: true)
|
146
|
+
@cli.options.should == @default_options.merge(verbose: true)
|
62
147
|
end
|
63
148
|
|
64
149
|
it 'sets filenames to filename provided' do
|
@@ -67,14 +152,14 @@ module Renmov
|
|
67
152
|
end
|
68
153
|
end
|
69
154
|
|
70
|
-
context '
|
155
|
+
context 'noop option provided' do
|
71
156
|
let(:options) { ['-n'] }
|
72
157
|
|
73
|
-
context '
|
158
|
+
context 'no filenames provided' do
|
74
159
|
let(:filenames) { [] }
|
75
160
|
|
76
161
|
it 'merges verbose and noop with default options' do
|
77
|
-
@cli.options.should == default_options.merge(verbose: true,
|
162
|
+
@cli.options.should == @default_options.merge(verbose: true,
|
78
163
|
noop: true)
|
79
164
|
end
|
80
165
|
|
@@ -83,11 +168,11 @@ module Renmov
|
|
83
168
|
end
|
84
169
|
end
|
85
170
|
|
86
|
-
context '
|
171
|
+
context 'one filename provided' do
|
87
172
|
let(:filenames) { ['TV.Show.S01E02.HDTV.test.mp4'] }
|
88
173
|
|
89
174
|
it 'merges verbose and noop with default options' do
|
90
|
-
@cli.options.should == default_options.merge(verbose: true,
|
175
|
+
@cli.options.should == @default_options.merge(verbose: true,
|
91
176
|
noop: true)
|
92
177
|
end
|
93
178
|
|
@@ -97,45 +182,5 @@ module Renmov
|
|
97
182
|
end
|
98
183
|
end
|
99
184
|
end
|
100
|
-
|
101
|
-
describe '#run' do
|
102
|
-
let(:tmpdir) { File.expand_path('../../../tmp', __FILE__) }
|
103
|
-
|
104
|
-
before(:each) do
|
105
|
-
filenames.each do |filename|
|
106
|
-
FileUtils.rm(filename) if File.exists?(filename)
|
107
|
-
end
|
108
|
-
newnames.each do |newname|
|
109
|
-
FileUtils.rm(newname) if File.exists?(newname)
|
110
|
-
end
|
111
|
-
|
112
|
-
FileUtils.touch(filenames)
|
113
|
-
cli = CLI.new(filenames)
|
114
|
-
cli.parse_options
|
115
|
-
cli.run
|
116
|
-
end
|
117
|
-
|
118
|
-
context 'with one filename provided' do
|
119
|
-
let(:filenames) { ["#{tmpdir}/TV.Show.S01E02.HDTV.test.mp4"] }
|
120
|
-
let(:newnames) { ["#{tmpdir}/tv.show.s01e02.mp4"] }
|
121
|
-
|
122
|
-
it 'properly renames file' do
|
123
|
-
File.exists?(filenames[0]).should_not be_true
|
124
|
-
File.exists?(newnames[0]).should be_true
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
context 'with multiple filenames provided' do
|
129
|
-
let(:filenames) { ["#{tmpdir}/TV.Show.S01E02.HDTV.test.mp4",
|
130
|
-
"#{tmpdir}/The.TV.Show.S02E03.LOL.avi"] }
|
131
|
-
let(:newnames) { ["#{tmpdir}/tv.show.s01e02.mp4",
|
132
|
-
"#{tmpdir}/tv.show.s02e03.avi"] }
|
133
|
-
|
134
|
-
it 'properly renames all files' do
|
135
|
-
filenames.each { |f| File.exists?(f).should_not be_true }
|
136
|
-
newnames.each { |n| File.exists?(n).should be_true }
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
185
|
end
|
141
186
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: renmov
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -75,6 +75,7 @@ files:
|
|
75
75
|
- lib/renmov.rb
|
76
76
|
- lib/renmov/basic_renamer.rb
|
77
77
|
- lib/renmov/cli.rb
|
78
|
+
- lib/renmov/errors.rb
|
78
79
|
- lib/renmov/version.rb
|
79
80
|
- renmov.gemspec
|
80
81
|
- spec/renmov/basic_renamer_spec.rb
|
@@ -104,7 +105,7 @@ rubyforge_project:
|
|
104
105
|
rubygems_version: 1.8.24
|
105
106
|
signing_key:
|
106
107
|
specification_version: 3
|
107
|
-
summary: renmov-0.0
|
108
|
+
summary: renmov-0.1.0
|
108
109
|
test_files:
|
109
110
|
- features/options.feature
|
110
111
|
- features/rename_files.feature
|