162 lines
5.3 KiB
Python
162 lines
5.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
# vi:si:et:sw=4:sts=4:ts=4
|
|
from __future__ import division
|
|
|
|
import os.path
|
|
import hashlib
|
|
import socket
|
|
import urllib2
|
|
|
|
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:
|
|
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 posters.keys():
|
|
if not posters[p]:
|
|
del posters[p]
|
|
return posters
|
|
|
|
def poster_path(url, filename):
|
|
if isinstance(url, unicode):
|
|
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 __unicode__(self):
|
|
return u'%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(url))
|
|
ox.makedirs(os.path.dirname(self.image.path))
|
|
with open(self.image.path, 'w') as f:
|
|
f.write(data)
|
|
self.save()
|
|
except urllib2.HTTPError, e:
|
|
#import traceback
|
|
#print traceback.print_exc()
|
|
self.status = e.code
|
|
self.failed = True
|
|
self.save()
|
|
except urllib2.URLError, e:
|
|
#import traceback
|
|
#print traceback.print_exc()
|
|
self.status = e.reason
|
|
self.failed = True
|
|
self.save()
|
|
except socket.error, e:
|
|
self.status = str(e)
|
|
self.failed = True
|
|
self.save()
|
|
if self.image:
|
|
try:
|
|
self.image.width
|
|
except:
|
|
self.failed = True
|
|
self.status = "invalid image"
|
|
self.image.delete()
|
|
self.save()
|
|
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?
|
|
|