movie-renamer 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,3 @@
1
+ Copyright (c) 2010 Mattia Gheda
2
+
3
+ GPL v3
@@ -0,0 +1,17 @@
1
+ = movie-renamer
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 tha. See LICENSE for details.
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require File.join(File.dirname(__FILE__),'..','lib','movie-renamer')
4
+ require 'optparse'
5
+
6
+ options = {}
7
+
8
+ OptionParser.new do |opts|
9
+ opts.banner = "Usage: #{File.basename($0)} [opts] <name>\nOnly one options each run\nDefault behavior is -f on current working directory"
10
+
11
+ opts.on("-h","--help","Display this help") do
12
+ puts opts
13
+ exit 0
14
+ end
15
+
16
+ opts.on("-i","--imdb","Executes a query on imdb on <movie name>") do
17
+ options[:imdb] = true
18
+ end
19
+
20
+ opts.on("-s","--singlemovie","Acts on a single movie file <file name>") do
21
+ options[:single] = true
22
+ end
23
+
24
+ opts.on("-f","--folder","Acts on whole folder <folder>") do
25
+ options[:folder] = true
26
+ end
27
+
28
+ begin
29
+ opts.parse!(ARGV)
30
+ rescue OptionParser::ParseError =>
31
+ warn.message
32
+ puts opts
33
+ exit 1
34
+ end
35
+
36
+ end
37
+
38
+ if options.empty?
39
+ options[:folder] = true
40
+ end
41
+
42
+ name = ARGV.join(' ')
43
+
44
+ if options.length != 1
45
+ puts "Usage: #{File.basename($0)} [opts] <name>\nOnly one options each run\nDefault behavior is -f on current working directory"
46
+ end
47
+
48
+
49
+
50
+ if options[:folder]
51
+ if name
52
+ MovieRenamer::folderPath = File.expand_path(name)
53
+ else
54
+ Movierenamer::folderPath = Dir.pwd
55
+ end
56
+ MovieRenamer::folderLoop()
57
+ elsif options[:single]
58
+ if name && File.file?(name)
59
+ MovieRenamer::folderPath = File.dirname(File.expand_path(name))
60
+ MovieRenamer::editMovie(name)
61
+ else
62
+ puts "Usage: #{File.basename($0)} -s <filename>"
63
+ exit 1
64
+ end
65
+
66
+ elsif options[:imdb]
67
+ MovieRenamer::suggestMovies(name)
68
+ end
69
+
70
+ exit 0
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ #
4
+ #
5
+
6
+ require 'imdb'
7
+
8
+ module MovieRenamer
9
+
10
+ NEWPATH = 'tmp'
11
+ # TODO insert default
12
+ @folderpath = ''
13
+ @is_a_test = false
14
+ RENAMEPATTERN = ''
15
+ MOVIEPATTERN = %r{\.((avi)|(mkv)|(mpg))$}
16
+ @input = STDIN
17
+ @output = STDOUT
18
+
19
+
20
+
21
+ class Movie
22
+
23
+ def initialize(filename,year = '',director = '',title = '',part = '',imdb = nil)
24
+ @year = year
25
+ @director = director
26
+ @title = title
27
+ @part = part
28
+ @imdb = imdb
29
+ @filename = filename
30
+ end
31
+
32
+ attr_accessor :year, :director, :title, :part, :imdb, :filename
33
+
34
+ def == (movie)
35
+ if @year == movie.year and @director == movie.director and @title == movie.title and @part == movie.part and @imdb == movie.imdb and @filename == movie.filename
36
+ return true
37
+ else
38
+ return false
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+ # setters
45
+ def MovieRenamer::folderPath=(folderpath)
46
+ @folderpath = folderpath
47
+ end
48
+
49
+
50
+ #test helpers
51
+ def MovieRenamer::input=(input)
52
+ @input = input
53
+ end
54
+
55
+ def MovieRenamer::is_a_test=(input)
56
+ @is_a_test = input
57
+ end
58
+ def MovieRenamer::output=(output)
59
+ @output = output
60
+ end
61
+
62
+ # returns an array of filenames
63
+ # TODO recursive find?
64
+ def MovieRenamer::findMovies(folder = @folderpath)
65
+ ar = Array.new
66
+ Dir.open(folder) do |dir|
67
+ dir.each do |file|
68
+ if file =~ MOVIEPATTERN
69
+ ar << file
70
+ end
71
+ end
72
+ end
73
+ return ar.sort
74
+ end
75
+
76
+ # reads move filename and tries to initialize a movie object?
77
+ # returns the movie object
78
+ def MovieRenamer::readMovie(filename)
79
+ # TODO insert logic here
80
+ filename = File.basename(filename)
81
+ title = File.basename(filename,'.*')
82
+ return Movie.new(filename,'','', title)
83
+ end
84
+
85
+ # rename a movie according to movie data
86
+ # and moves it to the new path in filesystem
87
+ def MovieRenamer::renameMovie(movie,newpath = NEWPATH)
88
+ filename = MovieRenamer::newName(movie)
89
+ path = File.join(@folderpath,newpath)
90
+ unless File.exist?(path)
91
+ Dir.mkdir(path)
92
+ end
93
+
94
+ begin
95
+ require 'fileutils'
96
+ # remove noop
97
+ return FileUtils::mv(File.join(@folderpath,movie.filename), File.join(path,filename), :noop => @is_a_test) ? true : false
98
+ rescue SystemCallError => e
99
+ puts e
100
+ end
101
+ end
102
+
103
+ # plays the movie with mplayer
104
+ def MovieRenamer::playMovie(movie)
105
+
106
+ end
107
+
108
+ # edit a movie interactively
109
+ # read the movie
110
+ # print movie info
111
+ # ask movie data
112
+ # rename movie
113
+ # play movie option?
114
+ # XXX add part integer check
115
+ def MovieRenamer::editMovie(filename)
116
+ movie = MovieRenamer::readMovie(filename)
117
+ MovieRenamer::printMovieInfo(movie)
118
+ ans = askMore "would you like to edit this movie? [ yes, no, quit, info , play] "
119
+ if ans
120
+ if ans == 'info'
121
+ MovieRenamer::suggestMovies(movie.title)
122
+ elsif ans == 'play'
123
+ MovieRenamer::playMovie(movie)
124
+ end
125
+ #if ask "play movie with mplayer?"
126
+ # MovieRenamer::playMovie(movie)
127
+ #end
128
+
129
+ # TODO insert imdb suggestions here?
130
+
131
+ @output.puts "Enter a year"
132
+ movie.year = @input.gets.chomp.to_i
133
+
134
+ @output.puts "Enter a director"
135
+ movie.director = MovieRenamer::sanitizeInput(@input.gets.chomp)
136
+
137
+ @output.puts "Enter a title"
138
+ movie.title = MovieRenamer::sanitizeInput(@input.gets.chomp)
139
+
140
+ @output.puts "Enter a part (you can leave this blank)"
141
+ movie.part = MovieRenamer::sanitizeInput(@input.gets.chomp)
142
+
143
+
144
+ MovieRenamer::printMovieInfo(movie)
145
+
146
+ if ask "is this information correct"
147
+ return MovieRenamer::renameMovie(movie)
148
+ #return true
149
+ else
150
+ editMovie(filename)
151
+ end
152
+ else
153
+ return true
154
+ end
155
+
156
+ end
157
+
158
+
159
+ # invoke edit movie on a whole folder
160
+ def MovieRenamer::folderLoop(folder = @folderpath)
161
+ MovieRenamer::findMovies(folder).each do |file|
162
+ MovieRenamer::editMovie(file)
163
+ end
164
+ end
165
+
166
+
167
+ def MovieRenamer::ask(question)
168
+ @output.puts question
169
+ response = @input.gets.chomp
170
+ case response
171
+ when /^y(es)?$/i
172
+ true
173
+ when /^no?$/i
174
+ false
175
+ else
176
+ puts "I don't understand. Please retry"
177
+ ask(question)
178
+ end
179
+ end
180
+
181
+ def MovieRenamer::askMore(question)
182
+ @output.puts question
183
+ response = @input.gets.chomp
184
+ case response
185
+ when /^y(es)?$/i
186
+ true
187
+ when /^no?$/i
188
+ false
189
+ when /^q(uit)?$/i
190
+ exit 0
191
+ when /^i(nfo)?$/i
192
+ return "info"
193
+ when /^p(lay)?$/i
194
+ return "play"
195
+ else
196
+ puts "I don't understand. Please retry"
197
+ askMore(question)
198
+ end
199
+ end
200
+
201
+ def MovieRenamer::printMovieInfo(movie)
202
+ s = "Movie info is:\n"
203
+ s+= "@oldfilename: #{movie.filename}\n"
204
+ s+= "@year: #{movie.year}\n"
205
+ s+= "@director: #{movie.director}\n"
206
+ s+= "@title: #{movie.title}\n"
207
+ s+= "@part: #{movie.part}\n"
208
+ s+= "New filename = #{MovieRenamer::newName(movie)}\n"
209
+ @output.puts s
210
+ return s
211
+ end
212
+
213
+ # calculates new movie name based on a pattern? XXX
214
+ # TODO change this and include a globalpattern
215
+ def MovieRenamer::newName(movie)
216
+ s = "#{movie.year} - #{movie.director} - #{movie.title}"
217
+ if movie.part =~ /\w/
218
+ s+= " - part#{movie.part.to_i}"
219
+ end
220
+ s += File.extname(movie.filename)
221
+ return s
222
+ end
223
+
224
+
225
+ def MovieRenamer::sanitizeInput(input)
226
+ # XXX naive sanitize
227
+ # simply removing all non standard characters
228
+ input.gsub(/[^A-Za-z0-9\_\-\s]/,'').chomp.sub(/ +$/,'')
229
+ end
230
+
231
+ # makes a query to imdb database
232
+ def MovieRenamer::suggestMovies(name)
233
+ s = Imdb::Search.new(name)
234
+ s.movies.each do |m|
235
+ @output.puts "#{m.year} - #{m.director.to_s.gsub(/(\[")|("\])/,'')} - #{m.title.gsub(/ .*/,'')}"
236
+ end
237
+ end
238
+
239
+ # TODO output string variable
240
+ def MovieRenamer::suggestMovie(name)
241
+ s = Imdb::Search.new(name)
242
+ m = s.movies.first
243
+ @output.puts "#{m.year} - #{m.director} - #{m.title}"
244
+ end
245
+
246
+ # returns the first movie from imdb query
247
+
248
+ end
249
+
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+
7
+ require 'movie-renamer'
8
+
9
+
10
+ module Test::Unit
11
+ class TestCase
12
+
13
+ def self.must(name,&block)
14
+ test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
15
+ defined = instance_method(test_name) rescue false
16
+ raise "#{test_name} is already defined in #{self}" if defined
17
+ if block_given?
18
+ define_method(test_name,&block)
19
+ else
20
+ define_method(test_name) do
21
+ flunk "No implementation provided for #{name}"
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+
28
+
29
+ end
30
+ end
@@ -0,0 +1,113 @@
1
+ require 'helper'
2
+ require 'movie-renamer'
3
+ require 'stringio'
4
+
5
+ class TestMovieRenamer < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @folder = File.expand_path('temp')
9
+ MovieRenamer::folderPath = @folder
10
+ @movies = MovieRenamer::findMovies(@folder)
11
+ @input = StringIO.new
12
+ @output = StringIO.new
13
+ MovieRenamer::input = @input
14
+ MovieRenamer::output = @output
15
+ MovieRenamer::is_a_test = true
16
+ end
17
+
18
+ # test find movies
19
+ must "find avi movies in the folder" do
20
+ assert_equal %w{movie1.avi movie2.avi movie3.mkv movie4.mpg}, @movies
21
+
22
+ end
23
+
24
+ # test read movie
25
+ must "create a movie object" do
26
+ assert_equal MovieRenamer::Movie.new('movie1.avi','','','movie1'),MovieRenamer::readMovie(@movies.first)
27
+ end
28
+
29
+ # simple checks that rename is done
30
+ must "rename a file (and moves it) correctly" do
31
+ assert ! MovieRenamer::renameMovie(MovieRenamer::readMovie(@movies.first)), "file not renamed?"
32
+ end
33
+
34
+ # newname check
35
+ must "rename a movie correctly" do
36
+ movie = MovieRenamer::Movie.new('movie1.avi','2001','me','famous')
37
+ assert_equal "2001 - me - famous.avi",MovieRenamer::newName(movie)
38
+ end
39
+
40
+ must "rename a movie correctly with parts" do
41
+ movie = MovieRenamer::Movie.new('movie1.avi','2001','me','famous','1')
42
+ assert_equal "2001 - me - famous - part1.avi",MovieRenamer::newName(movie)
43
+ end
44
+
45
+ must "rename a movie correctly without part because part is wrong" do
46
+ movie = MovieRenamer::Movie.new('movie1.avi','2001','me','famous',' ')
47
+ assert_equal "2001 - me - famous.avi",MovieRenamer::newName(movie)
48
+ end
49
+
50
+ # print movie info check
51
+ # XXX usless check for now
52
+ must "print movie info correctly" do
53
+ movie = MovieRenamer::Movie.new('movie1.avi','2001','me','famous','1')
54
+ assert MovieRenamer::printMovieInfo(movie)
55
+
56
+ end
57
+
58
+ # test for ask function movie
59
+ must "return true on yes input" do
60
+ provide_input "yes\n"
61
+ assert MovieRenamer::ask("do you want to edit this movie")
62
+ expect_output "do you want to edit this movie\n"
63
+ end
64
+
65
+ must "return false on no input" do
66
+ provide_input "no\n"
67
+ assert ! MovieRenamer::ask("do you want to edit this movie")
68
+ expect_output "do you want to edit this movie\n"
69
+ end
70
+
71
+ # test input sanitize
72
+ must "sanitize input correctly" do
73
+ input = "very bad movie{}\@# son "
74
+ assert_equal "very bad movie son", MovieRenamer::sanitizeInput(input)
75
+ end
76
+
77
+ # test edit movie
78
+ must "edit a movie correctly" do
79
+ provide_input "yes\n1984\nOrwell James\nBig Brother\n\nyes\n"
80
+ assert ! MovieRenamer::editMovie(@movies.first)
81
+ end
82
+
83
+ must "edit a movie correctly testing recursion" do
84
+ provide_input "yes\n1984\nOrwell James\nBig Brother\n\nno\nyes\n1984\nOrwell James\nBig Brother\n1\nyes\n"
85
+ assert ! MovieRenamer::editMovie(@movies.first)
86
+ #expect_output("wow")
87
+ end
88
+
89
+
90
+ # test main loop over folder
91
+ must "ask for all movies in folder" do
92
+ provide_input "no\nno\nno\nno\n"
93
+ assert MovieRenamer::folderLoop()
94
+ end
95
+
96
+ # suggest movies XXX no test here
97
+ must "suggest a movie list from a movie title" do
98
+ MovieRenamer::suggestMovies("Kill Bill")
99
+ #expect_output "wow"
100
+ end
101
+
102
+ # helpers
103
+ def provide_input (string)
104
+ @input << string
105
+ @input.rewind
106
+ end
107
+
108
+ def expect_output(string)
109
+ assert_equal string, @output.string
110
+ end
111
+
112
+ end
113
+
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: movie-renamer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - ghedamat
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-06-20 00:00:00 +02:00
13
+ default_executable: movie-renamer
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: imdb
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: imdb
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:
35
+ description: rename movies in a folder
36
+ email: thamayor@gmail.com
37
+ executables:
38
+ - movie-renamer
39
+ extensions: []
40
+
41
+ extra_rdoc_files:
42
+ - LICENSE
43
+ - README.rdoc
44
+ files:
45
+ - bin/movie-renamer
46
+ - lib/movie-renamer.rb
47
+ - test/helper.rb
48
+ - test/test_movie-renamer.rb
49
+ - LICENSE
50
+ - README.rdoc
51
+ has_rdoc: true
52
+ homepage: http://github.com/ghedamat/movie-renamer
53
+ post_install_message:
54
+ rdoc_options:
55
+ - --charset=UTF-8
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: "0"
63
+ version:
64
+ required_rubygems_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: "0"
69
+ version:
70
+ requirements: []
71
+
72
+ rubyforge_project:
73
+ rubygems_version: 1.3.1
74
+ signing_key:
75
+ specification_version: 2
76
+ summary: rename movies in a folder asking questions
77
+ test_files:
78
+ - test/helper.rb
79
+ - test/test_movie-renamer.rb