royw-tmdb 0.0.1
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/LICENSE +22 -0
- data/README.rdoc +9 -0
- data/Rakefile +48 -0
- data/VERSION.yml +4 -0
- data/lib/file_extensions.rb +14 -0
- data/lib/object_extensions.rb +19 -0
- data/lib/string_extensions.rb +16 -0
- data/lib/tmdb.rb +11 -0
- data/lib/tmdb/optional_logger.rb +31 -0
- data/lib/tmdb/tmdb_movie.rb +136 -0
- data/lib/tmdb/tmdb_profile.rb +112 -0
- data/spec/cache_extensions.rb +91 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/tmdb_movie_spec.rb +74 -0
- data/spec/tmdb_profile_spec.rb +140 -0
- metadata +71 -0
    
        data/LICENSE
    ADDED
    
    | @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            (The MIT License)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Copyright (c) 2009 Roy Wright
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Permission is hereby granted, free of charge, to any person obtaining
         | 
| 6 | 
            +
            a copy of this software and associated documentation files (the
         | 
| 7 | 
            +
            'Software'), to deal in the Software without restriction, including
         | 
| 8 | 
            +
            without limitation the rights to use, copy, modify, merge, publish,
         | 
| 9 | 
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         | 
| 10 | 
            +
            permit persons to whom the Software is furnished to do so, subject to
         | 
| 11 | 
            +
            the following conditions:
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            The above copyright notice and this permission notice shall be
         | 
| 14 | 
            +
            included in all copies or substantial portions of the Software.
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
         | 
| 17 | 
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         | 
| 18 | 
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
         | 
| 19 | 
            +
            IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
         | 
| 20 | 
            +
            CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
         | 
| 21 | 
            +
            TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
         | 
| 22 | 
            +
            SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         | 
    
        data/README.rdoc
    ADDED
    
    
    
        data/Rakefile
    ADDED
    
    | @@ -0,0 +1,48 @@ | |
| 1 | 
            +
            require 'rubygems'
         | 
| 2 | 
            +
            require 'rake'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            begin
         | 
| 5 | 
            +
              require 'jeweler'
         | 
| 6 | 
            +
              Jeweler::Tasks.new do |gem|
         | 
| 7 | 
            +
                gem.name = "tmdb"
         | 
| 8 | 
            +
                gem.summary = %Q{TODO}
         | 
| 9 | 
            +
                gem.email = "roy@wright.org"
         | 
| 10 | 
            +
                gem.homepage = "http://github.com/royw/tmdb"
         | 
| 11 | 
            +
                gem.authors = ["Roy Wright"]
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
            rescue LoadError
         | 
| 16 | 
            +
              puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
         | 
| 17 | 
            +
            end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            require 'spec/rake/spectask'
         | 
| 20 | 
            +
            Spec::Rake::SpecTask.new(:spec) do |spec|
         | 
| 21 | 
            +
              spec.libs << 'lib' << 'spec'
         | 
| 22 | 
            +
              spec.spec_files = FileList['spec/**/*_spec.rb']
         | 
| 23 | 
            +
            end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            Spec::Rake::SpecTask.new(:rcov) do |spec|
         | 
| 26 | 
            +
              spec.libs << 'lib' << 'spec'
         | 
| 27 | 
            +
              spec.pattern = 'spec/**/*_spec.rb'
         | 
| 28 | 
            +
              spec.rcov = true
         | 
| 29 | 
            +
            end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
             | 
| 32 | 
            +
            task :default => :spec
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            require 'rake/rdoctask'
         | 
| 35 | 
            +
            Rake::RDocTask.new do |rdoc|
         | 
| 36 | 
            +
              if File.exist?('VERSION.yml')
         | 
| 37 | 
            +
                config = YAML.load(File.read('VERSION.yml'))
         | 
| 38 | 
            +
                version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
         | 
| 39 | 
            +
              else
         | 
| 40 | 
            +
                version = ""
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              rdoc.rdoc_dir = 'rdoc'
         | 
| 44 | 
            +
              rdoc.title = "tmdb #{version}"
         | 
| 45 | 
            +
              rdoc.rdoc_files.include('README*')
         | 
| 46 | 
            +
              rdoc.rdoc_files.include('lib/**/*.rb')
         | 
| 47 | 
            +
            end
         | 
| 48 | 
            +
             | 
    
        data/VERSION.yml
    ADDED
    
    
| @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            # == Synopsis
         | 
| 2 | 
            +
            # add a mkdirs method to the File class
         | 
| 3 | 
            +
            class File
         | 
| 4 | 
            +
              ##
         | 
| 5 | 
            +
              # make directories including any missing in the path
         | 
| 6 | 
            +
              #
         | 
| 7 | 
            +
              # @param [String] dirspec the path to make sure exists
         | 
| 8 | 
            +
              def File.mkdirs(dirspec)
         | 
| 9 | 
            +
                unless File.exists?(dirspec)
         | 
| 10 | 
            +
                  mkdirs(File.dirname(dirspec))
         | 
| 11 | 
            +
                  Dir.mkdir(dirspec)
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
            end
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            # == Synopsis
         | 
| 2 | 
            +
            # add a blank? method to all Objects
         | 
| 3 | 
            +
            class Object
         | 
| 4 | 
            +
              # return asserted if object is nil or empty
         | 
| 5 | 
            +
              # TODO: not the safest coding, probably should dup before stripping.  Maybe should also compact
         | 
| 6 | 
            +
              def blank?
         | 
| 7 | 
            +
                result = nil?
         | 
| 8 | 
            +
                unless result
         | 
| 9 | 
            +
                  if respond_to? 'empty?'
         | 
| 10 | 
            +
                    if respond_to? 'strip'
         | 
| 11 | 
            +
                      result = strip.empty?
         | 
| 12 | 
            +
                    else
         | 
| 13 | 
            +
                      result = empty?
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
                result
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
            end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require 'cgi'
         | 
| 2 | 
            +
            require 'iconv'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module ImdbStringExtensions
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              def unescape_html
         | 
| 7 | 
            +
                Iconv.conv("UTF-8", 'ISO-8859-1', CGI::unescapeHTML(self))
         | 
| 8 | 
            +
              end
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
              def strip_tags
         | 
| 11 | 
            +
                gsub(/<\/?[^>]*>/, "")
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
              
         | 
| 14 | 
            +
            end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            String.send :include, ImdbStringExtensions
         | 
    
        data/lib/tmdb.rb
    ADDED
    
    | @@ -0,0 +1,11 @@ | |
| 1 | 
            +
            require 'rubygems'
         | 
| 2 | 
            +
            require 'open-uri'
         | 
| 3 | 
            +
            require 'date'
         | 
| 4 | 
            +
            require 'xmlsimple'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            require File.dirname(__FILE__) + '/tmdb/optional_logger'
         | 
| 7 | 
            +
            require File.dirname(__FILE__) + '/tmdb/tmdb_movie'
         | 
| 8 | 
            +
            require File.dirname(__FILE__) + '/tmdb/tmdb_profile'
         | 
| 9 | 
            +
            require File.dirname(__FILE__) + '/string_extensions'
         | 
| 10 | 
            +
            require File.dirname(__FILE__) + '/file_extensions'
         | 
| 11 | 
            +
            require File.dirname(__FILE__) + '/object_extensions'
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            # An optional logger.
         | 
| 2 | 
            +
            # If initialized with a logger instance, uses the logger
         | 
| 3 | 
            +
            # otherwise doesn't do anything.
         | 
| 4 | 
            +
            # Basically trying to not require a particular logger class.
         | 
| 5 | 
            +
            class OptionalLogger
         | 
| 6 | 
            +
              # logger may be nil or a logger instance
         | 
| 7 | 
            +
              def initialize(logger)
         | 
| 8 | 
            +
                @logger = logger
         | 
| 9 | 
            +
              end
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              # debug {...}
         | 
| 12 | 
            +
              def debug(&blk)
         | 
| 13 | 
            +
                @logger.debug(blk.call) unless @logger.nil?
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              # info {...}
         | 
| 17 | 
            +
              def info(&blk)
         | 
| 18 | 
            +
                @logger.info(blk.call) unless @logger.nil?
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              # warn {...}
         | 
| 22 | 
            +
              def warn(&blk)
         | 
| 23 | 
            +
                @logger.warn(blk.call) unless @logger.nil?
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              # error {...}
         | 
| 27 | 
            +
              def error(&blk)
         | 
| 28 | 
            +
                @logger.error(blk.call) unless @logger.nil?
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| 31 | 
            +
             | 
| @@ -0,0 +1,136 @@ | |
| 1 | 
            +
            class TmdbMovie
         | 
| 2 | 
            +
             | 
| 3 | 
            +
              attr_reader :query, :document
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              API_KEY = '7a2f6eb9b6aa01651000f0a9324db835'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              def initialize(ident)
         | 
| 8 | 
            +
                @imdb_id = 'tt' + ident.gsub(/^tt/, '') unless ident.blank?
         | 
| 9 | 
            +
                @query = "http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=#{@imdb_id}&api_key=#{API_KEY}"
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              def fanarts
         | 
| 13 | 
            +
                result = []
         | 
| 14 | 
            +
                begin
         | 
| 15 | 
            +
                  document['moviematches'].each do |moviematches|
         | 
| 16 | 
            +
                    moviematches['movie'].each do |movie|
         | 
| 17 | 
            +
                      backdrop = movie['backdrop']
         | 
| 18 | 
            +
                      unless backdrop.blank?
         | 
| 19 | 
            +
                        result += backdrop
         | 
| 20 | 
            +
                      end
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                  end
         | 
| 23 | 
            +
                rescue
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
                result
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              def posters
         | 
| 29 | 
            +
                result = []
         | 
| 30 | 
            +
                begin
         | 
| 31 | 
            +
                  document['moviematches'].each do |moviematches|
         | 
| 32 | 
            +
                    moviematches['movie'].each do |movie|
         | 
| 33 | 
            +
                      result += movie['poster']
         | 
| 34 | 
            +
                    end
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                rescue
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
                result
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              def idents
         | 
| 42 | 
            +
                document['moviematches'].first['movie'].first['id']  rescue nil
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              def urls
         | 
| 46 | 
            +
                document['moviematches'].first['movie'].first['url']  rescue nil
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
              def imdb_ids
         | 
| 50 | 
            +
                document['moviematches'].first['movie'].first['imdb']  rescue nil
         | 
| 51 | 
            +
              end
         | 
| 52 | 
            +
             | 
| 53 | 
            +
              def titles
         | 
| 54 | 
            +
                document['moviematches'].first['movie'].first['title']  rescue nil
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              def short_overviews
         | 
| 58 | 
            +
                document['moviematches'].first['movie'].first['short_overview']  rescue nil
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              def types
         | 
| 62 | 
            +
                document['moviematches'].first['movie'].first['type']  rescue nil
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
             | 
| 65 | 
            +
              def alternative_titles
         | 
| 66 | 
            +
                document['moviematches'].first['movie'].first['alternative_title']  rescue nil
         | 
| 67 | 
            +
              end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
              def releases
         | 
| 70 | 
            +
                document['moviematches'].first['movie'].first['release']  rescue nil
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
              def scores
         | 
| 74 | 
            +
                document['moviematches'].first['movie'].first['score']  rescue nil
         | 
| 75 | 
            +
              end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
              def to_hash
         | 
| 78 | 
            +
                hash = {}
         | 
| 79 | 
            +
                [:fanarts, :posters, :idents, :urls, :imdb_ids, :titles, :short_overviews,
         | 
| 80 | 
            +
                 :types, :alternative_titles, :releases, :scores
         | 
| 81 | 
            +
                ].each do |sym|
         | 
| 82 | 
            +
                  begin
         | 
| 83 | 
            +
                    value = send(sym.to_s)
         | 
| 84 | 
            +
                    hash[sym.to_s] = value unless value.nil?
         | 
| 85 | 
            +
                  rescue Exception => e
         | 
| 86 | 
            +
                    puts "Error getting data for hash for #{sym} - #{e.to_s}"
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
                hash
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
              def to_xml
         | 
| 93 | 
            +
                XmlSimple.xml_out(document, 'NoAttr' => true, 'RootName' => 'movie')
         | 
| 94 | 
            +
              end
         | 
| 95 | 
            +
             | 
| 96 | 
            +
              def to_yaml
         | 
| 97 | 
            +
                YAML.dump(document)
         | 
| 98 | 
            +
              end
         | 
| 99 | 
            +
             | 
| 100 | 
            +
              private
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                # Fetch the document with retry to handle the occasional glitches
         | 
| 103 | 
            +
              def document
         | 
| 104 | 
            +
                if @document.nil?
         | 
| 105 | 
            +
                  html = fetch(self.query)
         | 
| 106 | 
            +
                  @document = XmlSimple.xml_in(html)
         | 
| 107 | 
            +
                  @document = nil if @document['totalResults'] == ['0']
         | 
| 108 | 
            +
                end
         | 
| 109 | 
            +
                @document
         | 
| 110 | 
            +
              end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
              MAX_ATTEMPTS = 3
         | 
| 113 | 
            +
              SECONDS_BETWEEN_RETRIES = 1.0
         | 
| 114 | 
            +
             | 
| 115 | 
            +
              def fetch(page)
         | 
| 116 | 
            +
                doc = nil
         | 
| 117 | 
            +
                attempts = 0
         | 
| 118 | 
            +
                begin
         | 
| 119 | 
            +
                  doc = read_page(page)
         | 
| 120 | 
            +
                rescue Exception => e
         | 
| 121 | 
            +
                  attempts += 1
         | 
| 122 | 
            +
                  if attempts > MAX_ATTEMPTS
         | 
| 123 | 
            +
                    raise
         | 
| 124 | 
            +
                  else
         | 
| 125 | 
            +
                    sleep SECONDS_BETWEEN_RETRIES
         | 
| 126 | 
            +
                    retry
         | 
| 127 | 
            +
                  end
         | 
| 128 | 
            +
                end
         | 
| 129 | 
            +
                doc
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
              def read_page(page)
         | 
| 133 | 
            +
                open(page).read
         | 
| 134 | 
            +
              end
         | 
| 135 | 
            +
             | 
| 136 | 
            +
            end
         | 
| @@ -0,0 +1,112 @@ | |
| 1 | 
            +
            # This is the model for the themovieDb profile which is used
         | 
| 2 | 
            +
            # to find TmdbMovie meta data from either online or from
         | 
| 3 | 
            +
            # a cached file.
         | 
| 4 | 
            +
            #
         | 
| 5 | 
            +
            # Usage:
         | 
| 6 | 
            +
            #
         | 
| 7 | 
            +
            # profile = TmdbProfile.first(:imdb_id => 'tt0123456')
         | 
| 8 | 
            +
            #
         | 
| 9 | 
            +
            # puts profile.movie['key'].first
         | 
| 10 | 
            +
            # puts profile.to_xml
         | 
| 11 | 
            +
            # puts profile.imdb_id
         | 
| 12 | 
            +
            #
         | 
| 13 | 
            +
            class TmdbProfile
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              # options:
         | 
| 16 | 
            +
              #  :imdb_id  => String (either with or without leading 'tt')
         | 
| 17 | 
            +
              #  :filespec => nil or a valid pathspec
         | 
| 18 | 
            +
              #  :logger   => nil or a logger instance
         | 
| 19 | 
            +
              def self.all(options={})
         | 
| 20 | 
            +
                result = []
         | 
| 21 | 
            +
                if has_option?(options, :imdb_id) || (has_option?(options, :filespec) && File.exist?(options[:filespec]))
         | 
| 22 | 
            +
                  result << TmdbProfile.new(options[:imdb_id], options[:filespec], options[:logger])
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
                result
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              # see TmdbProfile.all for description of options
         | 
| 28 | 
            +
              def self.first(options={})
         | 
| 29 | 
            +
                self.all(options).first
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              protected
         | 
| 33 | 
            +
             | 
| 34 | 
            +
              def self.has_option?(options, key)
         | 
| 35 | 
            +
                options.has_key?(key) && !options[key].blank?
         | 
| 36 | 
            +
              end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              def initialize(ident, filespec, logger)
         | 
| 39 | 
            +
                @imdb_id = ident
         | 
| 40 | 
            +
                @filespec = filespec
         | 
| 41 | 
            +
                @logger = OptionalLogger.new(logger)
         | 
| 42 | 
            +
                load
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
             | 
| 46 | 
            +
              public
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              attr_reader :imdb_id, :movie
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              def to_xml
         | 
| 51 | 
            +
                xml = ''
         | 
| 52 | 
            +
                unless @movie.blank?
         | 
| 53 | 
            +
                  @movie.delete_if { |key, value| value.nil? }
         | 
| 54 | 
            +
                  xml = XmlSimple.xml_out(@movie, 'NoAttr' => true, 'RootName' => 'movie')
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
                xml
         | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              protected
         | 
| 60 | 
            +
             | 
| 61 | 
            +
              def load
         | 
| 62 | 
            +
                @movie = nil
         | 
| 63 | 
            +
                if !@filespec.blank? && File.exist?(@filespec)
         | 
| 64 | 
            +
                  @logger.debug { "loading movie filespec=> #{@filespec.inspect}" }
         | 
| 65 | 
            +
                  @movie = from_xml(open(@filespec).read)
         | 
| 66 | 
            +
                elsif !@imdb_id.blank?
         | 
| 67 | 
            +
                  @logger.debug { "loading movie from tmdb.com, filespec=> #{@filespec.inspect}" }
         | 
| 68 | 
            +
                  @movie = TmdbMovie.new(@imdb_id.gsub(/^tt/, '')).to_hash
         | 
| 69 | 
            +
                  save(@filespec) unless @filespec.blank?
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
                unless @movie.blank?
         | 
| 72 | 
            +
                  @imdb_id = @movie['imdb_ids']
         | 
| 73 | 
            +
                  @imdb_id = @imdb_id.first if @imdb_id.respond_to?('[]') && @imdb_id.length == 1
         | 
| 74 | 
            +
                else
         | 
| 75 | 
            +
                  @movie = nil
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
              def from_xml(xml)
         | 
| 80 | 
            +
                begin
         | 
| 81 | 
            +
                  movie = XmlSimple.xml_in(xml)
         | 
| 82 | 
            +
                rescue Exception => e
         | 
| 83 | 
            +
                  @logger.warn { "Error converting from xml: #{e.to_s}" }
         | 
| 84 | 
            +
                  movie = nil
         | 
| 85 | 
            +
                end
         | 
| 86 | 
            +
                movie
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
              def save(filespec)
         | 
| 90 | 
            +
                begin
         | 
| 91 | 
            +
                  xml = self.to_xml
         | 
| 92 | 
            +
                  unless xml.blank?
         | 
| 93 | 
            +
                    @logger.debug { "saving #{filespec}" }
         | 
| 94 | 
            +
                    save_to_file(filespec, xml)
         | 
| 95 | 
            +
                  end
         | 
| 96 | 
            +
                rescue Exception => e
         | 
| 97 | 
            +
                  @logger.error { "Unable to save tmdb profile to #{filespec} - #{e.to_s}" }
         | 
| 98 | 
            +
                end
         | 
| 99 | 
            +
              end
         | 
| 100 | 
            +
             | 
| 101 | 
            +
              def save_to_file(filespec, data)
         | 
| 102 | 
            +
                new_filespec = filespec + '.new'
         | 
| 103 | 
            +
                File.open(new_filespec, "w") do |file|
         | 
| 104 | 
            +
                  file.puts(data)
         | 
| 105 | 
            +
                end
         | 
| 106 | 
            +
                backup_filespec = filespec + '~'
         | 
| 107 | 
            +
                File.delete(backup_filespec) if File.exist?(backup_filespec)
         | 
| 108 | 
            +
                File.rename(filespec, backup_filespec) if File.exist?(filespec)
         | 
| 109 | 
            +
                File.rename(new_filespec, filespec)
         | 
| 110 | 
            +
                File.delete(new_filespec) if File.exist?(new_filespec)
         | 
| 111 | 
            +
              end
         | 
| 112 | 
            +
            end
         | 
| @@ -0,0 +1,91 @@ | |
| 1 | 
            +
            # NOTE extremely ugly and non-DRY.  Probably good candidate for meta programming.
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # override the classes' read_page method and replace with one
         | 
| 4 | 
            +
            # that will cache pages in spec/samples/{url}
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            class ImdbMovie
         | 
| 7 | 
            +
              private
         | 
| 8 | 
            +
              def read_page(page)
         | 
| 9 | 
            +
                html = nil
         | 
| 10 | 
            +
                filespec = page.gsub(/^http:\//, 'spec/samples').gsub(/\/$/, '.html')
         | 
| 11 | 
            +
                if File.exist?(filespec)
         | 
| 12 | 
            +
                  html = open(filespec).read
         | 
| 13 | 
            +
                else
         | 
| 14 | 
            +
                  html = open(page).read
         | 
| 15 | 
            +
                  cache_html_files(page, html)
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
                html
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              # this is used to save imdb pages so they may be used by rspec
         | 
| 21 | 
            +
              def cache_html_files(page, html)
         | 
| 22 | 
            +
                begin
         | 
| 23 | 
            +
                  filespec = page.gsub(/^http:\//, 'spec/samples').gsub(/\/$/, '.html')
         | 
| 24 | 
            +
                  unless File.exist?(filespec)
         | 
| 25 | 
            +
                    puts "caching #{filespec}"
         | 
| 26 | 
            +
                    File.mkdirs(File.dirname(filespec))
         | 
| 27 | 
            +
                    File.open(filespec, 'w') { |f| f.puts html }
         | 
| 28 | 
            +
                  end
         | 
| 29 | 
            +
                rescue Exception => eMsg
         | 
| 30 | 
            +
                  puts eMsg.to_s
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            class ImdbSearch
         | 
| 36 | 
            +
              private
         | 
| 37 | 
            +
              def read_page(page)
         | 
| 38 | 
            +
                html = nil
         | 
| 39 | 
            +
                filespec = page.gsub(/^http:\//, 'spec/samples').gsub(/\/$/, '.html')
         | 
| 40 | 
            +
                if File.exist?(filespec)
         | 
| 41 | 
            +
                  html = open(filespec).read
         | 
| 42 | 
            +
                else
         | 
| 43 | 
            +
                  html = open(page).read
         | 
| 44 | 
            +
                  cache_html_files(page, html)
         | 
| 45 | 
            +
                end
         | 
| 46 | 
            +
                html
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
              # this is used to save imdb pages so they may be used by rspec
         | 
| 50 | 
            +
              def cache_html_files(page, html)
         | 
| 51 | 
            +
                begin
         | 
| 52 | 
            +
                  filespec = page.gsub(/^http:\//, 'spec/samples').gsub(/\/$/, '.html')
         | 
| 53 | 
            +
                  unless File.exist?(filespec)
         | 
| 54 | 
            +
                    puts "caching #{filespec}"
         | 
| 55 | 
            +
                    File.mkdirs(File.dirname(filespec))
         | 
| 56 | 
            +
                    File.open(filespec, 'w') { |f| f.puts html }
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
                rescue Exception => eMsg
         | 
| 59 | 
            +
                  puts eMsg.to_s
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
              end
         | 
| 62 | 
            +
            end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
            class ImdbImage
         | 
| 65 | 
            +
              private
         | 
| 66 | 
            +
              def read_page(page)
         | 
| 67 | 
            +
                html = nil
         | 
| 68 | 
            +
                filespec = page.gsub(/^http:\//, 'spec/samples').gsub(/\/$/, '.html')
         | 
| 69 | 
            +
                if File.exist?(filespec)
         | 
| 70 | 
            +
                  html = open(filespec).read
         | 
| 71 | 
            +
                else
         | 
| 72 | 
            +
                  html = open(page).read
         | 
| 73 | 
            +
                  cache_html_files(page, html)
         | 
| 74 | 
            +
                end
         | 
| 75 | 
            +
                html
         | 
| 76 | 
            +
              end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
              # this is used to save imdb pages so they may be used by rspec
         | 
| 79 | 
            +
              def cache_html_files(page, html)
         | 
| 80 | 
            +
                begin
         | 
| 81 | 
            +
                  filespec = page.gsub(/^http:\//, 'spec/samples').gsub(/\/$/, '.html')
         | 
| 82 | 
            +
                  unless File.exist?(filespec)
         | 
| 83 | 
            +
                    puts "caching #{filespec}"
         | 
| 84 | 
            +
                    File.mkdirs(File.dirname(filespec))
         | 
| 85 | 
            +
                    File.open(filespec, 'w') { |f| f.puts html }
         | 
| 86 | 
            +
                  end
         | 
| 87 | 
            +
                rescue Exception => eMsg
         | 
| 88 | 
            +
                  puts eMsg.to_s
         | 
| 89 | 
            +
                end
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    ADDED
    
    | @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            require 'spec'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            $LOAD_PATH.unshift(File.dirname(__FILE__))
         | 
| 4 | 
            +
            $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
         | 
| 5 | 
            +
            require 'tmdb'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            require 'cache_extensions'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            $samples_dir = File.dirname(__FILE__) + '/samples'
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            TMPDIR = File.join(File.dirname(__FILE__), '../tmp')
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            Spec::Runner.configure do |config|
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            end
         | 
| 16 | 
            +
             | 
| @@ -0,0 +1,74 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            # Time to add your specs!
         | 
| 4 | 
            +
            # http://rspec.info/
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            describe "TmdbMovie" do
         | 
| 7 | 
            +
             | 
| 8 | 
            +
              before(:all) do
         | 
| 9 | 
            +
                File.mkdirs(TMPDIR)
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              before(:each) do
         | 
| 13 | 
            +
                @profile = TmdbMovie.new('tt0465234')
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              after(:each) do
         | 
| 17 | 
            +
                Dir.glob(File.join(TMPDIR,'tmdb_movie_spec*')).each { |filename| File.delete(filename) }
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
              it "should find by imdb_id" do
         | 
| 21 | 
            +
                @profile.should_not == nil
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              it "should find tmdb id" do
         | 
| 25 | 
            +
                @profile.idents.first.should == '6637'
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
              it "should find fanarts" do
         | 
| 29 | 
            +
                @profile.fanarts.size.should == 3
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              it "should find posters" do
         | 
| 33 | 
            +
                @profile.posters.size.should == 4
         | 
| 34 | 
            +
              end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
              it "should find the tmdb url" do
         | 
| 37 | 
            +
                @profile.urls.first.should == 'http://www.themoviedb.org/movie/6637'
         | 
| 38 | 
            +
              end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              it "should find the imdb_id" do
         | 
| 41 | 
            +
                @profile.imdb_ids.first.should == 'tt0465234'
         | 
| 42 | 
            +
              end
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              it "should find the title" do
         | 
| 45 | 
            +
                @profile.titles.first.should == 'National Treasure: Book of Secrets'
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              it "should find the short_overview" do
         | 
| 49 | 
            +
                @profile.short_overviews.first.should =~ /Benjamin Franklin Gates/
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              it "should find the type" do
         | 
| 53 | 
            +
                @profile.types.first.should == 'movie'
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              it "should find the alternative_titles" do
         | 
| 57 | 
            +
                @profile.alternative_titles.first.should == 'National Treasure 2'
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              it "should find the release" do
         | 
| 61 | 
            +
                @profile.releases.first.should == '2007-12-13'
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
              it "should find the  score" do
         | 
| 65 | 
            +
                @profile.scores.first.should == '1.0'
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              it "should handle The Sand Pebble" do
         | 
| 69 | 
            +
                profile = TmdbMovie.new('tt0060934')
         | 
| 70 | 
            +
                profile.idents.should be_nil
         | 
| 71 | 
            +
              end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
            end
         | 
| 74 | 
            +
             | 
| @@ -0,0 +1,140 @@ | |
| 1 | 
            +
            require 'spec_helper'
         | 
| 2 | 
            +
            require 'tempfile'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            # Time to add your specs!
         | 
| 5 | 
            +
            # http://rspec.info/
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            describe "TmdbProfile" do
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              before(:all) do
         | 
| 10 | 
            +
                File.mkdirs(TMPDIR)
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              before(:each) do
         | 
| 14 | 
            +
                # tt0465234 => National Treasure: Book of Secrets
         | 
| 15 | 
            +
                @profile = TmdbProfile.first(:imdb_id => 'tt0465234')
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              after(:each) do
         | 
| 19 | 
            +
                Dir.glob(File.join(TMPDIR,'tmdb_profile_spec*')).each { |filename| File.delete(filename) }
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              it "should find by imdb_id" do
         | 
| 23 | 
            +
                @profile.should_not == nil
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              it "should save the profile to a file" do
         | 
| 27 | 
            +
                filespec = get_temp_filename
         | 
| 28 | 
            +
                profile = TmdbProfile.first(:imdb_id => 'tt0465234', :filespec => filespec)
         | 
| 29 | 
            +
                (File.exist?(filespec).should be_true) && (File.size(filespec).should > 0)
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              it "should be able to convert to xml" do
         | 
| 33 | 
            +
                xml = @profile.to_xml
         | 
| 34 | 
            +
                (xml.should_not be_nil) && (xml.length.should > 0)
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              it "should be able to convert to xml and then from xml" do
         | 
| 38 | 
            +
                hash = nil
         | 
| 39 | 
            +
                begin
         | 
| 40 | 
            +
                  xml = @profile.to_xml
         | 
| 41 | 
            +
                  hash = XmlSimple.xml_in(xml)
         | 
| 42 | 
            +
                rescue
         | 
| 43 | 
            +
                  hash = nil
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
                hash.should_not be_nil
         | 
| 46 | 
            +
              end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
              it "should find tmdb id" do
         | 
| 49 | 
            +
                @profile.movie['idents'].first.should == '6637'
         | 
| 50 | 
            +
              end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
              it "should find fanarts" do
         | 
| 53 | 
            +
                @profile.movie['fanarts'].size.should == 3
         | 
| 54 | 
            +
              end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              it "should find posters" do
         | 
| 57 | 
            +
                @profile.movie['posters'].size.should == 4
         | 
| 58 | 
            +
              end
         | 
| 59 | 
            +
             | 
| 60 | 
            +
              it "should find the tmdb url" do
         | 
| 61 | 
            +
                @profile.movie['urls'].first.should == 'http://www.themoviedb.org/movie/6637'
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
             | 
| 64 | 
            +
              it "should find the imdb_id" do
         | 
| 65 | 
            +
                @profile.movie['imdb_ids'].first.should == 'tt0465234'
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
              it "should find the title" do
         | 
| 69 | 
            +
                @profile.movie['titles'].first.should == 'National Treasure: Book of Secrets'
         | 
| 70 | 
            +
              end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
              it "should find the short_overview" do
         | 
| 73 | 
            +
                @profile.movie['short_overviews'].first.should =~ /Benjamin Franklin Gates/
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
              it "should find the type" do
         | 
| 77 | 
            +
                @profile.movie['types'].first.should == 'movie'
         | 
| 78 | 
            +
              end
         | 
| 79 | 
            +
             | 
| 80 | 
            +
              it "should find the alternative_titles" do
         | 
| 81 | 
            +
                @profile.movie['alternative_titles'].first.should == 'National Treasure 2'
         | 
| 82 | 
            +
              end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
              it "should find the release" do
         | 
| 85 | 
            +
                @profile.movie['releases'].first.should == '2007-12-13'
         | 
| 86 | 
            +
              end
         | 
| 87 | 
            +
             | 
| 88 | 
            +
              it "should find the  score" do
         | 
| 89 | 
            +
                @profile.movie['scores'].first.should == '1.0'
         | 
| 90 | 
            +
              end
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                # let's make sure the generated xml from to_xml() is valid
         | 
| 93 | 
            +
             | 
| 94 | 
            +
              it "should be able to convert to xml and then from xml" do
         | 
| 95 | 
            +
                hash = nil
         | 
| 96 | 
            +
                begin
         | 
| 97 | 
            +
                  profile = TmdbProfile.first(:imdb_id => 'tt0465234')
         | 
| 98 | 
            +
                  xml = profile.to_xml
         | 
| 99 | 
            +
                  hash = XmlSimple.xml_in(xml)
         | 
| 100 | 
            +
                rescue
         | 
| 101 | 
            +
                  hash = nil
         | 
| 102 | 
            +
                end
         | 
| 103 | 
            +
                hash.should_not be_nil
         | 
| 104 | 
            +
              end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
              # now let's test caching the profile to/from a file
         | 
| 107 | 
            +
             | 
| 108 | 
            +
              it "should not create a file if a :filespec option is passed that is nil" do
         | 
| 109 | 
            +
                profile = TmdbProfile.first(:imdb_id => 'tt0465234', :filespec => nil)
         | 
| 110 | 
            +
                Dir.glob(File.join(TMPDIR, "imdb_profile_spec*")).empty?.should be_true
         | 
| 111 | 
            +
              end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
              it "should create a file if a :filespec option is passed" do
         | 
| 114 | 
            +
                filespec = get_temp_filename
         | 
| 115 | 
            +
                profile = TmdbProfile.first(:imdb_id => 'tt0465234', :filespec => filespec)
         | 
| 116 | 
            +
                (File.exist?(filespec) && (File.size(filespec) > 0)).should be_true
         | 
| 117 | 
            +
              end
         | 
| 118 | 
            +
             | 
| 119 | 
            +
              it "should load from a file if a :filespec option is passed and the file exists" do
         | 
| 120 | 
            +
                filespec = get_temp_filename
         | 
| 121 | 
            +
                profile1 = TmdbProfile.first(:imdb_id => 'tt0465234', :filespec => filespec)
         | 
| 122 | 
            +
                profile2 = TmdbProfile.first(:filespec => filespec)
         | 
| 123 | 
            +
                profile1.imdb_id.should == profile2.imdb_id
         | 
| 124 | 
            +
              end
         | 
| 125 | 
            +
             | 
| 126 | 
            +
              it "should not load from a file if a :filespec option is passed and the file does not exists" do
         | 
| 127 | 
            +
                filespec = get_temp_filename
         | 
| 128 | 
            +
                profile = TmdbProfile.first(:filespec => filespec)
         | 
| 129 | 
            +
                profile.should be_nil
         | 
| 130 | 
            +
              end
         | 
| 131 | 
            +
             | 
| 132 | 
            +
              def get_temp_filename
         | 
| 133 | 
            +
                outfile = Tempfile.new('tmdb_profile_spec', TMPDIR)
         | 
| 134 | 
            +
                filespec = outfile.path
         | 
| 135 | 
            +
                outfile.unlink
         | 
| 136 | 
            +
                filespec
         | 
| 137 | 
            +
              end
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            end
         | 
| 140 | 
            +
             | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,71 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification 
         | 
| 2 | 
            +
            name: royw-tmdb
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version 
         | 
| 4 | 
            +
              version: 0.0.1
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors: 
         | 
| 7 | 
            +
            - Roy Wright
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            date: 2009-04-15 00:00:00 -07:00
         | 
| 13 | 
            +
            default_executable: 
         | 
| 14 | 
            +
            dependencies: []
         | 
| 15 | 
            +
             | 
| 16 | 
            +
            description: 
         | 
| 17 | 
            +
            email: roy@wright.org
         | 
| 18 | 
            +
            executables: []
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            extensions: []
         | 
| 21 | 
            +
             | 
| 22 | 
            +
            extra_rdoc_files: 
         | 
| 23 | 
            +
            - LICENSE
         | 
| 24 | 
            +
            - README.rdoc
         | 
| 25 | 
            +
            files: 
         | 
| 26 | 
            +
            - LICENSE
         | 
| 27 | 
            +
            - README.rdoc
         | 
| 28 | 
            +
            - Rakefile
         | 
| 29 | 
            +
            - VERSION.yml
         | 
| 30 | 
            +
            - lib/file_extensions.rb
         | 
| 31 | 
            +
            - lib/object_extensions.rb
         | 
| 32 | 
            +
            - lib/string_extensions.rb
         | 
| 33 | 
            +
            - lib/tmdb.rb
         | 
| 34 | 
            +
            - lib/tmdb/optional_logger.rb
         | 
| 35 | 
            +
            - lib/tmdb/tmdb_movie.rb
         | 
| 36 | 
            +
            - lib/tmdb/tmdb_profile.rb
         | 
| 37 | 
            +
            - spec/cache_extensions.rb
         | 
| 38 | 
            +
            - spec/spec_helper.rb
         | 
| 39 | 
            +
            - spec/tmdb_movie_spec.rb
         | 
| 40 | 
            +
            - spec/tmdb_profile_spec.rb
         | 
| 41 | 
            +
            has_rdoc: true
         | 
| 42 | 
            +
            homepage: http://github.com/royw/tmdb
         | 
| 43 | 
            +
            post_install_message: 
         | 
| 44 | 
            +
            rdoc_options: 
         | 
| 45 | 
            +
            - --charset=UTF-8
         | 
| 46 | 
            +
            require_paths: 
         | 
| 47 | 
            +
            - lib
         | 
| 48 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         | 
| 49 | 
            +
              requirements: 
         | 
| 50 | 
            +
              - - ">="
         | 
| 51 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 52 | 
            +
                  version: "0"
         | 
| 53 | 
            +
              version: 
         | 
| 54 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         | 
| 55 | 
            +
              requirements: 
         | 
| 56 | 
            +
              - - ">="
         | 
| 57 | 
            +
                - !ruby/object:Gem::Version 
         | 
| 58 | 
            +
                  version: "0"
         | 
| 59 | 
            +
              version: 
         | 
| 60 | 
            +
            requirements: []
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            rubyforge_project: 
         | 
| 63 | 
            +
            rubygems_version: 1.2.0
         | 
| 64 | 
            +
            signing_key: 
         | 
| 65 | 
            +
            specification_version: 2
         | 
| 66 | 
            +
            summary: TODO
         | 
| 67 | 
            +
            test_files: 
         | 
| 68 | 
            +
            - spec/cache_extensions.rb
         | 
| 69 | 
            +
            - spec/tmdb_profile_spec.rb
         | 
| 70 | 
            +
            - spec/spec_helper.rb
         | 
| 71 | 
            +
            - spec/tmdb_movie_spec.rb
         |