lib/dvdprofiler2xbmc/nfo.rb in royw-dvdprofiler2xbmc-0.0.3 vs lib/dvdprofiler2xbmc/nfo.rb in royw-dvdprofiler2xbmc-0.0.4

- old
+ new

@@ -1,83 +1,148 @@ + # == Synopsis # NFO (info) files +# +# the @movie hash has keys that map directly to the .nfo file +# the @dvd_hash has keys that map to DVD Profiler's Collection.xml file class NFO - def initialize(media, dvd_hash) + def initialize(media, collection) @media = media - @dvd_hash = dvd_hash - load + @collection = collection + @dvd_hash = {} + @movie = {} end # save as a .nfo file, creating a backup if the .nfo already exists def save begin - nfo_filespec = @media.path_to(:nfo_extension) - nfo_backup_filespec = @media.path_to(:nfo_backup_extension) - File.delete(nfo_backup_filespec) if File.exist?(nfo_backup_filespec) - File.rename(nfo_filespec, nfo_backup_filespec) if File.exist?(nfo_filespec) - File.open(nfo_filespec, "w") do |file| - file.puts(to_nfo(@dvd_hash)) + unless @movie.empty? + @movie['title'] = @media.title if @movie['title'].blank? + nfo_filespec = @media.path_to(:nfo_extension) + nfo_backup_filespec = @media.path_to(:nfo_backup_extension) + File.delete(nfo_backup_filespec) if File.exist?(nfo_backup_filespec) + File.rename(nfo_filespec, nfo_backup_filespec) if File.exist?(nfo_filespec) + File.open(nfo_filespec, "w") do |file| + file.puts(to_xml) + end end rescue Exception => e - AppConfig[:logger].error { "Error saving nfo file - " + e.to_s } + AppConfig[:logger].error { "Error saving nfo file - " + e.to_s + "\n" + e.backtrace.join("\n")} end end + # load the .nfo file into the @movie hash def load + nfo_filespec = @media.path_to(:nfo_extension) begin - nfo_filespec = @media.path_to(:nfo_extension) - @movie = XmlSimple.xml_in(nfo_filespec) if File.exist? nfo_filespec + if File.exist?(nfo_filespec) && (File.size(nfo_filespec) > 1) + File.open(nfo_filespec) do |file| + @movie = XmlSimple.xml_in(file) + end + end rescue Exception => e - AppConfig[:logger].error { "Error loading \"#{nfo_filespec}\" - " + e.to_s } + AppConfig[:logger].error { "Error loading \"#{nfo_filespec}\" - " + e.to_s + "\n" + e.backtrace.join("\n") } + raise e end end - # return a nfo xml String from the given dvd_hash (from Collection) - def to_nfo(dvd_hash) - @movie ||= {} - imdb_id = @movie['id'] - if AppConfig[:imdb_query] && imdb_id.blank? - unless File.exist?(@media.path_to(:no_imdb_extension)) - imdb_id = imdb_lookup(dvd_hash) + # merge meta-data from the DVD Profiler collection.xml and from IMDB + # into the @movie hash + def update + begin + load_from_collection + if AppConfig[:imdb_query] && imdb_id.blank? + load_from_imdb end + @movie.merge!(to_movie(@dvd_hash)) + rescue Exception => e + AppConfig[:logger].error { "Error updating \"#{nfo_filespec}\" - " + e.to_s + "\n" + e.backtrace.join("\n") } + raise e end - @movie['title'] = dvd_hash[:title] - @movie['mpaa'] = dvd_hash[:rating] - @movie['year'] = dvd_hash[:productionyear] - @movie['outline'] = dvd_hash[:overview] -# @movie['plot'] = dvd_hash[:overview] - @movie['runtime'] = dvd_hash[:runningtime] - @movie['genre'] = map_genres((dvd_hash[:genres] + @media.media_subdirs.split('/')).uniq) - @movie['actor'] = dvd_hash[:actors] - @movie['id'] = imdb_id unless imdb_id.nil? - @movie['isbn'] = dvd_hash[:isbn] + end - begin - XmlSimple.xml_out(@movie, 'NoAttr' => true, 'RootName' => 'movie') - rescue Exception => e - AppConfig[:logger].error { "Error creating nfo file - " + e.to_s } + # return the ISBN or nil + def isbn + if @dvd_hash[:isbn].blank? + @dvd_hash[:isbn] = @movie['isbn'] end + @dvd_hash[:isbn] end + # set the ISBN + def isbn=(isbn) + @dvd_hash[:isbn] = isbn + end + + # return the IMDB ID or nil + def imdb_id + if @dvd_hash[:imdb_id].nil? + @dvd_hash[:imdb_id] = @movie['id'] + end + unless @dvd_hash[:imdb_id].nil? + # make sure is not an array + @dvd_hash[:imdb_id] = [@dvd_hash[:imdb_id]].flatten.uniq.compact.first + end + end + + # set the IMDB ID + def imdb_id=(id) + @dvd_hash[:imdb_id] = id + end + protected - def map_genres(genres) - new_genres = [] - genres.each do |genre| - new_genres << (AppConfig[:genre_maps][genre].nil? ? genre : AppConfig[:genre_maps][genre]) + # load @dvd_hash from the collection + def load_from_collection + # find ISBN for each title and assign to the media + if isbn.nil? + title_pattern = Collection.title_pattern(@media.title) + unless @collection.title_isbn_hash[title_pattern].nil? + isbn = [@collection.title_isbn_hash[title_pattern]].flatten.uniq.compact.first + end end - new_genres.uniq.compact + + # merge the meta-data from the collection to dvd_hash + unless isbn.nil? + collection_hash = @collection.isbn_dvd_hash[isbn] + @dvd_hash.merge!(collection_hash) unless collection_hash.blank? + end end + # load data from IMDB.com and merge into the @dvd_hash + def load_from_imdb + unless File.exist?(@media.path_to(:no_imdb_extension)) + years = (@media.year.nil? ? released_years(@dvd_hash) : [@media.year]) + title = (@dvd_hash[:title].nil? ? @media.title : @dvd_hash[:title]) + self.imdb_id = imdb_lookup(title, years) if self.imdb_id.blank? + unless self.imdb_id.nil? + imdb_movie = ImdbMovie.new(self.imdb_id.gsub(/^tt/, '')) + @dvd_hash.merge!(to_dvd_hash(imdb_movie)) + end + end + end + + # convert the @movie hash into xml and return the xml as a String + def to_xml + xml = '' + begin + xml = XmlSimple.xml_out(@movie, 'NoAttr' => true, 'RootName' => 'movie') + rescue Exception => e + AppConfig[:logger].error { "Error creating nfo file - " + e.to_s} + raise e + end + xml + end + # try to find the imdb id for the movie - def imdb_lookup(dvd_hash) + def imdb_lookup(title, years) id = nil - AppConfig[:logger].info { "Searching IMDB for \"#{dvd_hash[:title]}\"" } - unless dvd_hash[:title].blank? - years = released_years(dvd_hash) + + AppConfig[:logger].info { "Searching IMDB for \"#{title}\"" } + unless title.blank? begin - imdb_search = ImdbSearch.new(dvd_hash[:title]) + imdb_search = ImdbSearch.new(title) id = imdb_search.find_id(:years => years, :media_path => @media.media_path) rescue Exception => e AppConfig[:logger].error { "Error searching IMDB - " + e.to_s } AppConfig[:logger].error { e.backtrace.join("\n") } end @@ -93,15 +158,59 @@ unless dvd_hash[:productionyear].blank? years += dvd_hash[:productionyear].collect{|y| [y.to_i - 1, y.to_i, y.to_i + 1]}.flatten end unless dvd_hash[:released].blank? years += dvd_hash[:released].collect do |date| - y = nil - y = $1.to_i if date =~ /(\d{4})\-/ - y + y = nil + y = $1.to_i if date =~ /(\d{4})\-/ + y end end years.flatten.uniq.compact.sort + end + + # given a ImdbMovie instance, extract meta-data into and return a dvd_hash + def to_dvd_hash(imdb_movie) + dvd_hash = {} + dvd_hash[:title] = imdb_movie.title + dvd_hash[:imdb_id] = 'tt' + imdb_movie.id.gsub(/^tt/,'') unless imdb_movie.id.blank? + dvd_hash[:rating] = imdb_movie.mpaa + dvd_hash[:rating] ||= imdb_movie.certifications['USA'] + dvd_hash[:productionyear] = imdb_movie.release_year + dvd_hash[:plot] = imdb_movie.plot + dvd_hash[:runningtime] = imdb_movie.length + dvd_hash[:genre] = imdb_movie.genres + dvd_hash[:actor] = imdb_movie.cast_members + dvd_hash + end + + # map the given dvd_hash into a @movie hash + def to_movie(dvd_hash) + dvd_hash[:genres] ||= [] + genres = map_genres((dvd_hash[:genres] + @media.media_subdirs.split('/')).uniq) + movie = {} + movie['title'] = dvd_hash[:title] + movie['mpaa'] = dvd_hash[:rating] unless dvd_hash[:rating].blank? + movie['year'] = dvd_hash[:productionyear] unless dvd_hash[:productionyear].blank? + movie['outline'] = dvd_hash[:overview] unless dvd_hash[:overview].blank? + movie['plot'] = dvd_hash[:plot] unless dvd_hash[:plot].blank? + movie['runtime'] = dvd_hash[:runningtime] unless dvd_hash[:runningtime].blank? + movie['actor'] = dvd_hash[:actors] unless dvd_hash[:actors].blank? + movie['isbn'] = dvd_hash[:isbn] unless dvd_hash[:isbn].blank? + movie['id'] = dvd_hash[:imdb_id] unless dvd_hash[:imdb_id].blank? + movie['genre'] = genres unless genres.blank? + movie + end + + # map the given genres using the AppConfig[:genre_maps]. + # given an Array of String genres + # returns an Array of String genres that have been mapped, are unique, and do not include any nils + def map_genres(genres) + new_genres = [] + genres.each do |genre| + new_genres << (AppConfig[:genre_maps][genre].nil? ? genre : AppConfig[:genre_maps][genre]) + end + new_genres.uniq.compact end end