oxdata/oxdata/poster/models.py
2011-10-14 21:10:37 +02:00

157 lines
5.4 KiB
Python

# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
from __future__ import division
import os.path
import hashlib
from django.conf import settings
from django.db import models
from django.db.models import Q
from django.contrib.auth.models import User
from django.core.files.base import ContentFile
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 oxdata.lookup.models import MovieId
def getPosters(movie_id, url_prefix='', limit=lambda x, y: 0.3 < x/y < 1):
if not movie_id:
return {}
getPosterUrls(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]
poster = Poster.objects.filter(movie_id=movie_id).exclude(poster='')
if poster.count() > 0:
posters['local'] = [p.poster.url]
return posters
def poster_path(url, filename):
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)
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=42)
image = models.ImageField(max_length=255, upload_to=lambda i, f: poster_path(i.url.encode('utf-8'), f))
status = models.CharField(max_length=1024, default='200')
failed = models.BooleanField(default=False)
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.readUrl(url)
self.image.save(name, ContentFile(data))
except ox.net.urllib2.HTTPError, e:
#import traceback
#print traceback.print_exc()
self.status = e.code
self.failed = True
self.save()
except ox.net.urllib2.URLError, e:
#import traceback
#print traceback.print_exc()
self.status = e.reason
self.failed = True
self.save()
if self.image:
try:
self.image.width
except IOError:
self.image.delete()
except TypeError:
self.failed = True
self.status = "invalid image"
self.image.delete()
return self.image
class Poster(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
movie_id = models.ForeignKey(MovieId, related_name='poster')
poster = models.ImageField(max_length=255, upload_to=lambda i, f: poster_path('upload/%s' % i.id, f))
def getPosterUrls(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.getMoviePoster(m.imdb_id)
if poster:
addPoster(poster, 'imdb.com', m.imdb_id)
#site is sometimes down
#for poster in ox.web.movieposterdb.getData(m.imdb_id)['posters']:
# addPoster(poster, 'movieposterdb.com', m.imdb_id)
poster = ox.web.piratecinema.getPosterUrl(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.getData(m.criterion_id)['posters']:
addPoster(poster, 'criterion.com', m.criterion_id)
if m.wikipedia_id:
#if settings.DEBUG:
# print 'wikipedia'
poster = ox.web.wikipedia.getPosterUrl(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.getData(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.getMovieData(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?