oxdata/oxdata/poster/models.py
2017-10-25 10:47:51 +02:00

176 lines
5.9 KiB
Python

# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from __future__ import division, print_function, absolute_import
import hashlib
import os.path
import socket
import urllib
from django.db import models
import ox
import ox.web.criterion
import ox.web.movieposterdb
import ox.web.imdb
import ox.web.impawards
import ox.web.apple
import ox.web.piratecinema
from lookup.models import MovieId
def getPosters(movie_id, url_prefix='', limit=lambda x, y: 0.3 < x/y < 1):
if not movie_id:
return {}
get_poster_urls(movie_id)
posters = {}
if url_prefix.endswith('/'):
url_prefix = url_prefix[:-1]
for p in PosterCache.objects.all().filter(movie_id=movie_id, failed=False).order_by('-id'):
if p.site not in posters:
posters[p.site] = []
poster = p.get()
if poster and (not poster.width or not poster.height):
p.failed = True
p.status = "invalid image"
p.image.delete()
p.save()
poster = None
if poster:
pjson = {}
pjson['url'] = url_prefix + poster._get_url()
pjson['width'] = poster.width
pjson['height'] = poster.height
if p.site not in ['other', 'wikipedia.org'] or limit(poster.width, poster.height):
posters[p.site].append(pjson)
for p in list(posters):
if not posters[p]:
del posters[p]
return posters
def poster_path(url, filename):
if not isinstance(url, bytes):
url = url.encode('utf-8')
h = hashlib.sha1(url).hexdigest()
ext = 'jpg'
if filename.endswith('.png'):
ext = 'png'
name = "%s.%s" % (h, ext)
return os.path.join('posters', h[:2], h[2:4], h[4:6], name)
def postercache_path(i, f):
return poster_path(i.url.encode('utf-8'), f)
class PosterCache(models.Model):
class Meta:
unique_together = ("movie_id", "url")
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
movie_id = models.ForeignKey(MovieId, related_name='postercache')
url = models.CharField(max_length=1024)
site = models.CharField(max_length=255)
site_id = models.CharField(max_length=1024)
image = models.ImageField(max_length=255, upload_to=postercache_path)
status = models.CharField(max_length=1024, default='200')
failed = models.BooleanField(default=False)
def __str__(self):
return '%s' % self.url
def get(self):
if not self.image and not self.failed:
import ox.net
url = self.url.encode('utf-8')
name = hashlib.sha1(url).hexdigest()
try:
data = ox.net.read_url(url)
self.image.name = poster_path(self.url, os.path.basename(self.url))
ox.makedirs(os.path.dirname(self.image.path))
with open(self.image.path, 'wb') as f:
f.write(data)
self.save()
except urllib.error.HTTPError as e:
#import traceback
#print traceback.print_exc()
self.status = e.code
self.failed = True
self.save()
except urllib.error.URLError as e:
#import traceback
#print traceback.print_exc()
self.status = e.reason
self.failed = True
self.save()
except socket.error as e:
self.status = str(e)
self.failed = True
self.save()
except:
self.status = 'some error'
self.failed = True
self.save()
if self.image:
failed = False
try:
self.image.width
if not self.image.width or not self.image.width:
failed = True
except:
failed = True
if failed:
self.failed = True
self.status = "invalid image"
self.image.delete()
self.save()
if not self.failed:
return self.image
def get_poster_urls(m):
def addPoster(url, site, site_id):
if PosterCache.objects.all().filter(url=url, movie_id=m).count() == 0:
p = PosterCache(url=url, site=site, site_id=site_id, movie_id=m)
p.save()
if m.imdb_id:
#if settings.DEBUG:
# print 'imdb'
poster = ox.web.imdb.get_movie_poster(m.imdb_id)
if poster:
addPoster(poster, 'imdb.com', m.imdb_id)
#site is sometimes down
#for poster in ox.web.movieposterdb.get_data(m.imdb_id)['posters']:
# addPoster(poster, 'movieposterdb.com', m.imdb_id)
poster = ox.web.piratecinema.get_poster_url(m.imdb_id)
if poster:
addPoster(poster, 'piratecinema.org', m.imdb_id)
if m.criterion_id:
#if settings.DEBUG:
# print 'criterion', m.criterion_id
for poster in ox.web.criterion.get_data(m.criterion_id)['posters']:
addPoster(poster, 'criterion.com', m.criterion_id)
if m.wikipedia_id:
#if settings.DEBUG:
# print 'wikipedia'
poster = ox.web.wikipedia.get_poster_url(m.wikipedia_id)
if poster:
if PosterCache.objects.all().filter(url=poster).count() == 0:
addPoster(poster, 'wikipedia.org', m.wikipedia_id)
if m.impawards_id:
#if settings.DEBUG:
# print 'impawards'
data = ox.web.impawards.get_data(m.impawards_id)
if data and 'imdbId' in data:
for poster in data['posters']:
addPoster(poster, 'impawards.com', m.imdb_id)
'''
if m.title and m.director:
data = ox.web.apple.get_movie_data(m.title, m.director)
if data and 'poster' in data:
addPoster(data['poster'], 'apple.com', m.imdb_id)
'''
#fixme: get 0xdb still, possibly imdb still as fallback?