oxdata/oxdata/poster/models.py

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?