movie-renamer 0.0.12 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +19 -6
- data/bin/movie-renamer +29 -19
- data/lib/movie-renamer.rb +88 -39
- data/test/test_movie-renamer.rb +12 -8
- metadata +22 -2
data/README.rdoc
CHANGED
@@ -1,13 +1,22 @@
|
|
1
1
|
= movie-renamer
|
2
2
|
|
3
3
|
A simple command line interface to rename movies in a folder
|
4
|
+
and get your movies collection organized!
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
It works in an interactive way and
|
7
|
+
uses imdb gem to query imdb about current movie trying to obtain useful infos
|
7
8
|
|
8
9
|
to see the usage type
|
9
10
|
|
10
11
|
$ movie-renamer -h
|
12
|
+
Usage: movie-renamer [-i|-s|-f|-h|-p] <folder>
|
13
|
+
Default behavior is -f on current working directory
|
14
|
+
-h, --help Display this help
|
15
|
+
-i, --imdb Executes a query on imdb on <movie name>
|
16
|
+
-s, --singlemovie FILE Acts on a single movie file <file name>
|
17
|
+
-f, --folder FOLDER Acts on whole folder <folder>
|
18
|
+
-p, --path PATH path for moving renamed movies default is tmp/ in current working directory
|
19
|
+
|
11
20
|
|
12
21
|
== How it works
|
13
22
|
|
@@ -15,13 +24,17 @@ Default behavior is to scan the current working directory
|
|
15
24
|
For each movie in the folder a question about what to do is asked.
|
16
25
|
|
17
26
|
Then movie is renamed using input provided by the user
|
27
|
+
You can query imdb using the filename or enter use manual search
|
18
28
|
|
19
|
-
Each renamed movie is moved into a tmp/ subfolder of the current working directory
|
20
|
-
|
29
|
+
Each renamed movie is moved into a tmp/ subfolder of the current working directory or
|
30
|
+
in the folder specified with the -p option
|
21
31
|
|
22
|
-
|
32
|
+
By default Movies are renamed like this:
|
33
|
+
$year - $director - $title partXX.file_extension
|
34
|
+
You can set the rename pattern creating a .movie-renamer file in your home
|
23
35
|
|
24
|
-
|
36
|
+
example:
|
37
|
+
filename: ($year) - $title - $director
|
25
38
|
|
26
39
|
|
27
40
|
|
data/bin/movie-renamer
CHANGED
@@ -6,7 +6,7 @@ require 'optparse'
|
|
6
6
|
options = {}
|
7
7
|
|
8
8
|
OptionParser.new do |opts|
|
9
|
-
opts.banner = "Usage: #{File.basename($0)} [
|
9
|
+
opts.banner = "Usage: #{File.basename($0)} [-i|-s|-f|-h|-p] <folder>\nDefault behavior is -f on current working directory"
|
10
10
|
|
11
11
|
opts.on("-h","--help","Display this help") do
|
12
12
|
puts opts
|
@@ -17,12 +17,16 @@ OptionParser.new do |opts|
|
|
17
17
|
options[:imdb] = true
|
18
18
|
end
|
19
19
|
|
20
|
-
opts.on("-s","--singlemovie","Acts on a single movie file <file name>") do
|
21
|
-
options[:single] =
|
20
|
+
opts.on("-s","--singlemovie FILE","Acts on a single movie file <file name>") do |f|
|
21
|
+
options[:single] = f
|
22
22
|
end
|
23
23
|
|
24
|
-
opts.on("-f","--folder","Acts on whole folder <folder>") do
|
25
|
-
options[:folder] =
|
24
|
+
opts.on("-f","--folder FOLDER","Acts on whole folder <folder>") do |f|
|
25
|
+
options[:folder] = f
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on("-p","--path PATH", "path for moving renamed movies default is tmp/ in current working directory ") do |p|
|
29
|
+
options[:path] = p
|
26
30
|
end
|
27
31
|
|
28
32
|
begin
|
@@ -35,36 +39,42 @@ OptionParser.new do |opts|
|
|
35
39
|
|
36
40
|
end
|
37
41
|
|
38
|
-
if options.empty?
|
39
|
-
options[:folder] = true
|
40
|
-
end
|
41
|
-
|
42
42
|
name = ARGV.join(' ')
|
43
43
|
|
44
|
+
=begin
|
44
45
|
if options.length != 1
|
45
46
|
puts "Usage: #{File.basename($0)} [opts] <name>\nOnly one options each run\nDefault behavior is -f on current working directory"
|
46
47
|
end
|
48
|
+
=end
|
47
49
|
|
48
|
-
|
50
|
+
if options[:path]
|
51
|
+
MovieRenamer::newpath = options[:path]
|
52
|
+
end
|
49
53
|
|
50
54
|
if options[:folder]
|
51
|
-
|
52
|
-
MovieRenamer::folderPath = File.expand_path(name)
|
53
|
-
else
|
54
|
-
Movierenamer::folderPath = Dir.pwd
|
55
|
-
end
|
55
|
+
MovieRenamer::folderPath = File.expand_path(options[:folder])
|
56
56
|
MovieRenamer::folderLoop()
|
57
|
+
exit 0
|
57
58
|
elsif options[:single]
|
58
|
-
if
|
59
|
-
MovieRenamer::folderPath = File.dirname(File.expand_path(
|
60
|
-
MovieRenamer::editMovie(
|
59
|
+
if File.file?(File.expand_path(options[:single]))
|
60
|
+
MovieRenamer::folderPath = File.dirname(File.expand_path(options[:single]))
|
61
|
+
MovieRenamer::editMovie(options[:single])
|
61
62
|
else
|
62
63
|
puts "Usage: #{File.basename($0)} -s <filename>"
|
63
64
|
exit 1
|
64
65
|
end
|
66
|
+
exit 0
|
65
67
|
|
66
68
|
elsif options[:imdb]
|
67
69
|
MovieRenamer::suggestMovies(name)
|
70
|
+
exit 0
|
71
|
+
elsif name
|
72
|
+
MovieRenamer::folderPath = File.expand_path(name)
|
73
|
+
MovieRenamer::folderLoop()
|
74
|
+
exit 0
|
75
|
+
else
|
76
|
+
Movierenamer::folderPath = Dir.pwd
|
77
|
+
MovieRenamer::folderLoop()
|
78
|
+
exit 0
|
68
79
|
end
|
69
80
|
|
70
|
-
exit 0
|
data/lib/movie-renamer.rb
CHANGED
@@ -1,19 +1,45 @@
|
|
1
1
|
#!/usr/bin/ruby
|
2
2
|
|
3
3
|
require 'imdb'
|
4
|
+
require 'highline'
|
5
|
+
require 'highline/import'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
$config = ''
|
9
|
+
CONFIGFILE = File.join(File.expand_path(ENV['HOME']), '.movie-renamer')
|
10
|
+
begin
|
11
|
+
$config = YAML.load_file(CONFIGFILE)
|
12
|
+
rescue
|
13
|
+
=begin
|
14
|
+
raise "\nplease create a .movie-renamer file in your $HOME
|
15
|
+
example:
|
16
|
+
filename: /path/to/your/movies/dir"
|
17
|
+
exit
|
18
|
+
=end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
begin
|
23
|
+
require 'imdb'
|
24
|
+
rescue LoadError
|
25
|
+
$stderr.print "#{File.basename($0)} requires imdb gem to work\nPlease install it with gem install imdb\n"
|
26
|
+
exit
|
27
|
+
end
|
4
28
|
|
5
29
|
module MovieRenamer
|
6
30
|
|
7
|
-
|
31
|
+
@newpath = 'tmp'
|
8
32
|
# TODO insert default
|
9
33
|
@folderpath = ''
|
10
34
|
@is_a_test = false
|
11
|
-
|
35
|
+
@renamepattern = '$year - $director - $title'
|
12
36
|
MOVIEPATTERN = %r{\.((avi|AVI)|(mkv|MKV)|(mpg|MPG|mpeg|MPEG))$}
|
13
37
|
@input = STDIN
|
14
38
|
@output = STDOUT
|
15
|
-
|
16
|
-
|
39
|
+
|
40
|
+
if $config['filename']
|
41
|
+
@renamepattern = $config['filename']
|
42
|
+
end
|
17
43
|
|
18
44
|
class Movie
|
19
45
|
|
@@ -44,6 +70,9 @@ module MovieRenamer
|
|
44
70
|
@folderpath = folderpath
|
45
71
|
end
|
46
72
|
|
73
|
+
def MovieRenamer::newpath=(newpath)
|
74
|
+
@newpath = newpath
|
75
|
+
end
|
47
76
|
|
48
77
|
#test helpers
|
49
78
|
def MovieRenamer::input=(input)
|
@@ -82,7 +111,7 @@ module MovieRenamer
|
|
82
111
|
|
83
112
|
# attempt to remove the divx part from a filename
|
84
113
|
def MovieRenamer::titleExtract(filename)
|
85
|
-
r1 = %r{\s*\[?\(?\s*(
|
114
|
+
r1 = %r{\s*\[?\(?\s*[dD](i|I)(v|V)(x|X)\s?(-|_)?\s?\w+\s*\)?\]?\s*}
|
86
115
|
r2 = %r{\s*\[?\(?\s*(x|X)(v|V)(i|I)(d|D)\s?(-|_)?\s?\w+\s*\)?\]?\s*}
|
87
116
|
r3 = %r{\s*\[?\(?\s*(d|D)(v|V)(d|D)(r|R)(i|I)(p|P)\s?(-|_)?\s*\)?\]?\s*}
|
88
117
|
r = /(#{r1}|#{r2}|#{r3})/
|
@@ -91,9 +120,9 @@ module MovieRenamer
|
|
91
120
|
|
92
121
|
# rename a movie according to movie data
|
93
122
|
# and moves it to the new path in filesystem
|
94
|
-
def MovieRenamer::renameMovie(movie,newpath =
|
123
|
+
def MovieRenamer::renameMovie(movie,newpath = @newpath)
|
95
124
|
filename = MovieRenamer::newName(movie)
|
96
|
-
path = File.
|
125
|
+
path = File.expand_path(newpath)
|
97
126
|
unless File.exist?(path)
|
98
127
|
Dir.mkdir(path)
|
99
128
|
end
|
@@ -122,11 +151,11 @@ module MovieRenamer
|
|
122
151
|
def MovieRenamer::editMovie(filename)
|
123
152
|
movie = MovieRenamer::readMovie(filename)
|
124
153
|
MovieRenamer::printMovieInfo(movie)
|
125
|
-
ans = askMore "would you like to edit this movie? [
|
154
|
+
ans = askMore "would you like to edit this movie? [ Yes, No, Quit, Info]"# , play] "
|
126
155
|
if ans
|
127
|
-
if ans ==
|
128
|
-
MovieRenamer::suggestMovies(movie
|
129
|
-
elsif ans ==
|
156
|
+
if ans == :info
|
157
|
+
MovieRenamer::suggestMovies(movie)
|
158
|
+
elsif ans == :play
|
130
159
|
MovieRenamer::playMovie(movie)
|
131
160
|
end
|
132
161
|
#if ask "play movie with mplayer?"
|
@@ -134,23 +163,27 @@ module MovieRenamer
|
|
134
163
|
#end
|
135
164
|
|
136
165
|
# TODO insert imdb suggestions here?
|
137
|
-
|
138
|
-
|
139
|
-
|
166
|
+
|
167
|
+
if movie.year == ''
|
168
|
+
@output.puts "Enter a year"
|
169
|
+
movie.year = @input.gets.chomp.to_i
|
140
170
|
|
141
|
-
|
142
|
-
|
171
|
+
@output.puts "Enter a director"
|
172
|
+
movie.director = MovieRenamer::sanitizeInput(@input.gets.chomp)
|
143
173
|
|
144
|
-
|
145
|
-
|
174
|
+
@output.puts "Enter a title"
|
175
|
+
movie.title = MovieRenamer::sanitizeInput(@input.gets.chomp)
|
146
176
|
|
147
|
-
|
148
|
-
|
149
|
-
|
177
|
+
@output.puts "Enter a part (you can leave this blank)"
|
178
|
+
movie.part = MovieRenamer::sanitizeInput(@input.gets.chomp)
|
179
|
+
end
|
150
180
|
|
151
181
|
MovieRenamer::printMovieInfo(movie)
|
152
182
|
|
153
|
-
|
183
|
+
ans = ask("is this information correct: Yes, No") do |q|
|
184
|
+
q.validate = /^y(es)?|^n(o)?/
|
185
|
+
end
|
186
|
+
if ans =~/^y(es)?/
|
154
187
|
return MovieRenamer::renameMovie(movie)
|
155
188
|
#return true
|
156
189
|
else
|
@@ -170,6 +203,7 @@ module MovieRenamer
|
|
170
203
|
end
|
171
204
|
end
|
172
205
|
|
206
|
+
=begin
|
173
207
|
# yes or no questioner
|
174
208
|
def MovieRenamer::ask(question)
|
175
209
|
@output.puts question
|
@@ -181,9 +215,10 @@ module MovieRenamer
|
|
181
215
|
false
|
182
216
|
else
|
183
217
|
puts "I don't understand. Please retry"
|
184
|
-
ask(question)
|
218
|
+
MovieRenamer::ask(question)
|
185
219
|
end
|
186
220
|
end
|
221
|
+
=end
|
187
222
|
|
188
223
|
# yes no quit info play questioner
|
189
224
|
def MovieRenamer::askMore(question)
|
@@ -197,9 +232,9 @@ module MovieRenamer
|
|
197
232
|
when /^q(uit)?$/i
|
198
233
|
exit 0
|
199
234
|
when /^i(nfo)?$/i
|
200
|
-
return
|
235
|
+
return :info
|
201
236
|
when /^p(lay)?$/i
|
202
|
-
return
|
237
|
+
return :play
|
203
238
|
else
|
204
239
|
puts "I don't understand. Please retry"
|
205
240
|
askMore(question)
|
@@ -207,21 +242,22 @@ module MovieRenamer
|
|
207
242
|
end
|
208
243
|
|
209
244
|
def MovieRenamer::printMovieInfo(movie)
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
return s
|
245
|
+
say("Movie info is:
|
246
|
+
<%= color('old filename:', :red) %> #{movie.filename}
|
247
|
+
<%= color('year:', :red) %> #{movie.year}
|
248
|
+
<%= color('director:', :red) %> #{movie.director}
|
249
|
+
<%= color('title:', :red) %> #{movie.title}
|
250
|
+
<%= color('part:', :red) %> #{movie.part}
|
251
|
+
<%= color('filename:', :red) %> #{MovieRenamer::newName(movie)}")
|
252
|
+
#@output.puts s
|
253
|
+
#return s
|
219
254
|
end
|
220
255
|
|
221
256
|
# calculates new movie name based on a pattern? XXX
|
222
257
|
# TODO change this and include a globalpattern
|
223
258
|
def MovieRenamer::newName(movie)
|
224
|
-
|
259
|
+
@renamepattern.gsub!(/\$[a-z]*/) { |m| ;'#{movie.'+m.sub(/\$/,'').chomp+'}' }
|
260
|
+
s = eval( '"' + @renamepattern + '"')
|
225
261
|
if movie.part =~ /\w/
|
226
262
|
s+= " - part#{movie.part.to_i}"
|
227
263
|
end
|
@@ -239,11 +275,24 @@ module MovieRenamer
|
|
239
275
|
end
|
240
276
|
|
241
277
|
# makes a query to imdb database
|
242
|
-
def MovieRenamer::suggestMovies(
|
243
|
-
s = Imdb::Search.new(
|
244
|
-
s.movies[0..
|
245
|
-
@output.puts "#{m.year} - #{m.director.to_s.gsub(/(\[")|("\])/,'')} - #{m.title.gsub(/ .*/,'')}"
|
278
|
+
def MovieRenamer::suggestMovies(movie)
|
279
|
+
s = Imdb::Search.new(movie.title)
|
280
|
+
s.movies[0..4].each_with_index do |m,i|
|
281
|
+
@output.puts "#{i}, #{m.year} - #{m.director.to_s.gsub(/(\[")|("\])/,'')} - #{m.title.gsub(/ .*/,'')}"
|
282
|
+
end
|
283
|
+
cmd = ask("pick a choice [0..4], Manual search, Edit Manually", %w{0 1 2 3 4 m e}) do |q|
|
284
|
+
q.readline = true
|
285
|
+
end
|
286
|
+
if %w{0 1 2 3 4}.include?(cmd)
|
287
|
+
m = s.movies[cmd.to_i]
|
288
|
+
movie.title = m.title.gsub(/ .*/,'').gsub(/\s*\([0-9]+\)/,'')
|
289
|
+
movie.year = m.year
|
290
|
+
movie.director = m.director.to_s.gsub(/(\[")|("\])/,'')
|
291
|
+
elsif cmd == "m"
|
292
|
+
movie.title = ask("enter title")
|
293
|
+
MovieRenamer::suggestMovies(movie )
|
246
294
|
end
|
295
|
+
return movie
|
247
296
|
end
|
248
297
|
|
249
298
|
# TODO output string variable
|
data/test/test_movie-renamer.rb
CHANGED
@@ -58,6 +58,7 @@ class TestMovieRenamer < Test::Unit::TestCase
|
|
58
58
|
assert_equal "2001 - me - famous.avi",MovieRenamer::newName(movie)
|
59
59
|
end
|
60
60
|
|
61
|
+
=begin
|
61
62
|
# print movie info check
|
62
63
|
# XXX usless check for now
|
63
64
|
must "print movie info correctly" do
|
@@ -78,14 +79,7 @@ class TestMovieRenamer < Test::Unit::TestCase
|
|
78
79
|
assert ! MovieRenamer::ask("do you want to edit this movie")
|
79
80
|
expect_output "do you want to edit this movie\n"
|
80
81
|
end
|
81
|
-
|
82
|
-
# test input sanitize
|
83
|
-
must "sanitize input correctly" do
|
84
|
-
input = "ain't a very bad movie{}\@# son "
|
85
|
-
assert_equal "ain't a very bad movie son", MovieRenamer::sanitizeInput(input)
|
86
|
-
end
|
87
|
-
|
88
|
-
# test edit movie
|
82
|
+
# test edit movie
|
89
83
|
must "edit a movie correctly" do
|
90
84
|
provide_input "yes\n1984\nOrwell James\nBig Brother\n\nyes\n"
|
91
85
|
assert ! MovieRenamer::editMovie(@movies.first)
|
@@ -97,7 +91,16 @@ class TestMovieRenamer < Test::Unit::TestCase
|
|
97
91
|
#expect_output("wow")
|
98
92
|
end
|
99
93
|
|
94
|
+
=end
|
95
|
+
# test input sanitize
|
96
|
+
must "sanitize input correctly" do
|
97
|
+
input = "ain't a very bad movie{}\@# son "
|
98
|
+
assert_equal "ain't a very bad movie son", MovieRenamer::sanitizeInput(input)
|
99
|
+
end
|
100
|
+
|
101
|
+
|
100
102
|
|
103
|
+
=begin
|
101
104
|
# test main loop over folder
|
102
105
|
must "ask for all movies in folder" do
|
103
106
|
provide_input "no\nno\nno\nno\n"
|
@@ -109,6 +112,7 @@ class TestMovieRenamer < Test::Unit::TestCase
|
|
109
112
|
MovieRenamer::suggestMovies("Kill Bill")
|
110
113
|
#expect_output "wow"
|
111
114
|
end
|
115
|
+
=end
|
112
116
|
|
113
117
|
# helpers
|
114
118
|
def provide_input (string)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: movie-renamer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ghedamat
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-09-04 00:00:00 +02:00
|
13
13
|
default_executable: movie-renamer
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,6 +22,16 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: "0"
|
24
24
|
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: highlight
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
25
35
|
- !ruby/object:Gem::Dependency
|
26
36
|
name: imdb
|
27
37
|
type: :runtime
|
@@ -32,6 +42,16 @@ dependencies:
|
|
32
42
|
- !ruby/object:Gem::Version
|
33
43
|
version: "0"
|
34
44
|
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: highlight
|
47
|
+
type: :runtime
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
35
55
|
description: rename movies in a folder
|
36
56
|
email: thamayor@gmail.com
|
37
57
|
executables:
|