oxdbarchive/oxdbarchive/oxdb_cache.py

273 lines
8.1 KiB
Python

# -*- Mode: Python; -*-
# -*- coding: utf-8 -*-
# vi:si:et:sw=2:sts=2:ts=2
import os
from os.path import abspath, exists, join, dirname, basename
import shutil
from glob import glob
import Image
from StringIO import StringIO
from scrapeit.utils import read_url
cache_root = join(dirname(abspath(__file__)), 'cache')
img_extension = "jpg"
frame_cache_root = join(cache_root, 'frame')
mini_movie_folder = '/mnt/storage/oil/oxdb/mini'
def loadFile(f_name):
f = open(f_name)
data = f.read()
f.close()
return data
def saveFile(f_name, data):
f = open(f_name, 'w')
f.write(data)
f.close()
def loadStaticFile(fname):
return loadFile(join(dirname(abspath(__file__)), "static", fname))
'''
returns name including a possible directory level for a given hash
'''
def imgName(imdb):
return "%s.%s" % (imdb, img_extension)
'''
returns path to an icon from iconType for given icon in the cache
'''
def iconPath(iconType, movie):
icon_root = join(cache_root, iconType)
icon = join(icon_root, imgName(movie.imdb))
if not exists(dirname(icon)):
os.makedirs(dirname(icon))
return icon
'''
render reflection of sourceFile on targetFile,
uses alpha, target files needs to support RGBA, i.e. png
'''
def _writeReflection(sourceFile, targetFile, height = 0.5, opacity = 0.25):
sourceImage = Image.open(sourceFile).convert('RGB')
sourceSource = sourceImage.size[0]
sourceHeight = sourceImage.size[1]
targetWidth = sourceImage.size[0]
targetHeight = int(round(sourceHeight * height))
targetImage = Image.new('RGBA', (targetWidth, targetHeight))
for y in range(0, targetHeight):
brightness = int(255 * (targetHeight - y) * opacity / targetHeight)
for x in range(0, targetWidth):
targetColor = sourceImage.getpixel((x, sourceHeight - 1 - y))
targetColor += (brightness, )
targetImage.putpixel((x, y), targetColor)
targetImage.save(targetFile, optimized = True)
def resizePoster(data, max_resolution, format = 'JPEG'):
posterIO = StringIO(data)
sourceImage = Image.open(posterIO)
sourceWidth = sourceImage.size[0]
sourceHeight = sourceImage.size[1]
if int(round((float(max_resolution[1]) * sourceWidth) / sourceHeight)) < max_resolution[0]:
max_resolution[0] = int(round((float(max_resolution[1]) * sourceWidth) / sourceHeight))
if int(round((float(max_resolution[0]) / sourceWidth) * sourceHeight)) < max_resolution[1]:
max_resolution[1] = int(round((float(max_resolution[0]) / sourceWidth) * sourceHeight))
if sourceWidth >= sourceHeight:
targetWidth = max_resolution[0]
targetHeight = int(round((float(max_resolution[0]) / sourceWidth) * sourceHeight))
else:
targetWidth = int(round((float(max_resolution[1]) * sourceWidth) / sourceHeight))
targetHeight = max_resolution[1]
if targetWidth < sourceWidth:
resizeMethod = Image.ANTIALIAS
else:
resizeMethod = Image.BICUBIC
targetSize = (targetWidth, targetHeight)
targetImage = sourceImage.resize(targetSize, resizeMethod)
f = StringIO()
if format == 'JPEG':
targetImage.save(f, 'JPEG', quality=90)
else:
targetImage.save(f, 'PNG')
return f.getvalue()
'''
download poster from imdb and resize it before saving into cache
returns poster data
'''
def downloadPoster(movie):
icon = iconPath('poster', movie)
if movie.posterFile:
data = loadFile(movie.posterFile)
else:
data = read_url(movie.poster)
posterIO = StringIO(data)
sourceImage = Image.open(posterIO)
sourceWidth = sourceImage.size[0]
sourceHeight = sourceImage.size[1]
if sourceWidth >= sourceHeight:
targetWidth = 128
targetHeight = int(round((128.0 / sourceWidth) * sourceHeight))
else:
targetWidth = int(round((128.0 * sourceWidth) / sourceHeight))
targetHeight = 128
if targetWidth < sourceWidth:
resizeMethod = Image.ANTIALIAS
else:
resizeMethod = Image.BICUBIC
targetSize = (targetWidth, targetHeight)
targetImage = sourceImage.resize(targetSize, resizeMethod).convert('RGB')
targetImage.save(icon)
return loadFile(icon)
'''
return icon data, reads from remote url if not cached
'''
def loadPoster(movie):
if not movie.hasPoster():
return ''
#return loadStaticFile('images/posterDark.png')
#return loadStaticFile('images/posterBlack.png')
icon = iconPath('poster', movie)
if exists(icon):
data = loadFile(icon)
else:
data = downloadPoster(movie)
return data
'''
return icon reflection data, renders reflection if it does not exists
'''
def loadPosterReflection(movie):
icon = iconPath('poster', movie)
iconReflection = iconPath('posterReflection', movie).replace('jpg', 'png')
if not exists(iconReflection):
if not exists(icon):
loadPoster(movie)
if exists(icon):
_writeReflection(icon, iconReflection)
else:
return loadStaticFile('images/posterDark.reflection.png')
return loadFile(iconReflection)
'''
returns path to a frame from type for given movie in the cache
'''
def framePath(frameType, movie, position):
position = position.replace(':', '.')
frame_root = join(cache_root, frameType)
frame = join(frame_root, imgName(join(movie.imdb, position)))
if not exists(dirname(frame)):
os.makedirs(dirname(frame))
return frame
def loadClip(movie, position):
position = basename(position)
flash = framePath('frame', movie, position).replace(img_extension, 'flv')
if not exists(flash):
movie.extractClip(position)
if exists(flash):
return loadFile(flash)
return ''
'''
returns png frame of the given position.
'''
def loadFrame(movie, position):
position = basename(position)
frame = framePath('frame', movie, position)
if not exists(frame):
#movie.extractClip(position)
movie.extractFrame(position)
if exists(frame):
return loadFile(frame)
return loadDefaultFrame(movie)
def loadDefaultFrameReflection(movie):
frame = framePath('frame', movie, 'default').replace('jpg', 'png')
frameReflection = framePath('frameReflection', movie, 'default').replace('jpg', 'png')
if not exists(frameReflection):
if not exists(frame):
loadDefaultFrame(movie)
if exists(frame):
_writeReflection(frame, frameReflection)
else:
return loadStaticFile('images/stillDark.reflection.png')
return loadFile(frameReflection)
def loadDefaultFrame(movie):
frame = framePath('frame', movie, 'default').replace('jpg', 'png')
if not exists(frame):
data = loadStaticFile('images/stillDark.png')
imageIO = StringIO(data)
sourceImage = Image.open(imageIO)
sourceWidth = sourceImage.size[0]
sourceHeight = sourceImage.size[1]
top = (sourceHeight - movie.sceneHeight) / 2
targetImage = sourceImage.crop((0, top, sourceWidth, top + movie.sceneHeight))
targetImage.save(frame, 'PNG')
return loadFile(frame)
'''
returns png frame reflection of the given position.
'''
def loadFrameReflection(movie, position):
position = basename(position)
frame = framePath('frame', movie, position)
frameReflection = framePath('frameReflection', movie, position).replace('jpg', 'png')
if not exists(frameReflection):
if not exists(frame):
loadFrame(movie, position)
if exists(frame):
_writeReflection(frame, frameReflection)
else:
return loadDefaultFrameReflection(movie)
return loadFile(frameReflection)
def loadTimeline(movie, position):
bar = framePath('timeline', movie, position).replace('jpg', 'png')
if exists(bar):
return loadFile(bar)
print bar
return ''
#FIXME load and return bar hre
'''
move cache files to new imdb
'''
def moveCache(old_imdb, new_imdb):
old = join(cache_root, 'frame', old_imdb)
new = join(cache_root, 'frame', new_imdb)
if exists(old) and not exists(new):
shutil.move(old, new)
if exists(old):
shutil.rmtree(old)
old = join(cache_root, 'frameReflection', old_imdb)
new = join(cache_root, 'frameReflection', new_imdb)
if exists(old) and not exists(new):
shutil.move(old, new)
if exists(old):
shutil.rmtree(old)
old = join(cache_root, 'timeline', old_imdb)
new = join(cache_root, 'timeline', new_imdb)
if exists(old) and not exists(new):
shutil.move(old, new)
if exists(old):
shutil.rmtree(old)