From b71d86a5f16169bc53f86b86381700dfb5de0494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Zurcher?= Date: Sat, 20 Nov 2021 19:59:06 +0100 Subject: add tmdb.rb --- tmdb.rb | 229 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100755 tmdb.rb diff --git a/tmdb.rb b/tmdb.rb new file mode 100755 index 0000000..5c3084a --- /dev/null +++ b/tmdb.rb @@ -0,0 +1,229 @@ +#! /bin/ruby + +require 'json' +require 'open-uri' + +n = ARGV.size +mpath=File.dirname(__FILE__) +mpath = ARGV.shift if n > 0 +dbpath=File.join(mpath, 'db') +dbpath = ARGV.shift if n > 1 + +# TODO indicate if srt file is here + +puts " movies : #{mpath}\n db : #{dbpath}" + +API_KEY = 'c4202eaa738af60ae7a784c349a0cc63' +SEARCH_M="https://api.themoviedb.org/3/search/movie?api_key=#{API_KEY}&language=en-US&page=1&include_adult=true&query=" +FETCH_M="https://api.themoviedb.org/3/movie/ID?api_key=#{API_KEY}" +FETCH_C="https://api.themoviedb.org/3/movie/ID/credits?api_key=#{API_KEY}" +URL_M='https://www.themoviedb.org/movie/' +URL_A='https://www.themoviedb.org/person/' +URL_I='https://www.themoviedb.org/t/p/original/' +DB=File.join(dbpath, 'db.json') +FIX=File.join(dbpath, 'fix.json') +FAIL=File.join(dbpath, 'failed.json') +DBA=File.join(dbpath, 'a') +DBM=File.join(dbpath, 'm') +HTML_I=File.join(dbpath, 'index.html') +HTML_M=File.join(dbpath, 'movies.html') +HTML_A=File.join(dbpath, 'actors.html') +BLANK='blank.png' + +Dir.mkdir(dbpath) if not Dir.exist?(dbpath) +Dir.mkdir(DBA) if not Dir.exist?(DBA) +Dir.mkdir(DBM) if not Dir.exist?(DBM) + +failed = [] +fix = File.exist?(FIX) ? JSON.load(File.read(FIX)) : {} +prev_db = File.exist?(DB) ? JSON.load(File.read(DB)) : [] +idx = prev_db.collect { |m| m['filename'] } +current_db = [] + +def search fn + b,e = fn.split '.' + ar = b.split '-' + name = ar[0].gsub('_', ' ').downcase + if ar.size == 2 + year = ar[1] + elsif ar.size == 3 + sequel = ar[1] + year = ar[2] + else + return nil + end + puts "search : #{name} - #{year}" + begin + res = JSON.load URI.open(SEARCH_M+name).read + rescue + return nil + end + return nil if res['total_results'] == 0 + sel = res['results'].select { |r| (r['release_date']||'nope')[0..3] == year } + return nil if sel.size == 0 + if sel.size > 1 + puts " found #{sel.map {|s| s['title'] + ' ' + s['release_date']||'?' }}" + sel = sel.select { |r| r['title'].downcase == name } + if sel.size != 1 + return nil + end + puts " choose '#{sel[0]['title']}'" + end + sel[0] +end + +def download id, p, base + return nil if p.nil? + fn = id.to_s + File.extname(p) + dst = File.join(base, fn) + if not File.exist? dst + puts " download #{URL_I + p} -> #{dst}" + File.open(dst, 'wb') { |f| f.write URI.open(URL_I + p).read } + end + fn +end + +def fetch id, fn, m + m['filename'] = fn + m['img'] = download(id, m['poster_path'], DBM) + m['cast'] = [] + JSON.load(URI.open(FETCH_C.sub(/ID/, id.to_s)).read)['cast'].each_with_index do |a, i| + break if i > 6 + a['img'] = download(a['id'], a['profile_path'], DBA) + m['cast'] << a + end + m +end + +Dir.glob(File.join(mpath, '*')) do |fn| + next if File.directory? fn + next if fn =~ /\.srt/ or fn =~ /\.rb/ or fn =~ /\.sub/ or fn =~ /\.jpg/ + fn = fn.split('/')[1] + id = fix[fn] + if not id.nil? + m = prev_db.find{ |i| i['id'] == id and i['filename'] == fn } + m = JSON.load URI.open(FETCH_M.sub(/ID/, id.to_s)).read if m.nil? + current_db << fetch(id, fn, m) + next + end + if idx.include? fn + current_db << prev_db.find{ |i| i['filename'] == fn } + next + end + m = search fn + if m.nil? + failed << fn + else + current_db << fetch(m['id'], fn, m) + end +end + +CSS=-< b['title'].downcase } +File.open(DB, 'w') { |f| f << current_db.to_json } +File.open(HTML_I, 'w') do |f| + f << 'Movies Index\n\n
" + f << "
    " + ('A'..'Z').inject('') {|r,i| r+ "
  • #{i}
  • "} + '
' + letter=nil + current_db.each do |m| + l = m['title'][0].upcase + if l != letter + letter = l + f << '' if not letter.nil? + f << "
#{letter}
" + end + f << "" + end + f << '
#{m['release_date'][0..3]}
' +end +actors = {} +File.open(HTML_M, 'w') do |f| + f << 'My Movies\n" + current_db.each do |m| + img = m['img'] + img = (img.nil? ? BLANK : ('m/' + img)) + f << "
" + f << "
" + f << "
#{m['title']}
" + f << "
(#{m['original_title']})
" if m['title'] != m['original_title'] + f << "
- #{m['release_date'][0..3]}
" + f << "
[#{m['filename']}]
\n" + m['cast'].each do |a| + img = a['img'] + img = (img.nil? ? BLANK : ('a/' + img)) + f << "

#{a['original_name']}

\n" + actors[a['name']] ||= {'id'=>a['id'], 'movies'=>[]} + actors[a['name']]['movies'] << [m['id'], m['title'], m['release_date']] + end + f << "
#{m['overview']}
\n" + f << "
\n" + end + f << '' +end + +File.open(HTML_A, 'w') do |f| + f << 'Actors Index\n\n
" + f << "
    " + ('A'..'Z').inject('') {|r,i| r+ "
  • #{i}
  • "} + '
' + letter=nil + actors.keys.sort! {|a,b| a.downcase <=> b.downcase }.each do |aname| + l = aname[0].upcase + if l != letter + letter = l + f << '' if not letter.nil? + f << "
#{letter}
" + end + d = actors[aname] + d['movies'].sort! { |a,b| b[2] <=> a[2] } + m = d['movies'].shift + f << "" + f << "" + d['movies'].each do |m| + f << "" + end + end + f << '
#{m[2][0..3]}
 #{m[2][0..3]}
' +end + +puts "FAILED :" +File.open(FAIL, 'w') { |f| f << failed.to_json } +failed.each { |fn| puts " -> #{fn}" } -- cgit v1.1-2-g2b99