- simplify metadata db structure
- better sort values if field is empty - switch to python-ox, faster imdb import - move files backend into own app
This commit is contained in:
parent
d6a95727a6
commit
9defcd3c9f
16 changed files with 1493 additions and 914 deletions
182
pandora/archive/models.py
Normal file
182
pandora/archive/models.py
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# vi:si:et:sw=4:sts=4:ts=4
|
||||
from datetime import datetime
|
||||
import os.path
|
||||
import random
|
||||
import re
|
||||
from decimal import Decimal
|
||||
|
||||
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
|
||||
from django.utils import simplejson as json
|
||||
from django.conf import settings
|
||||
|
||||
from oxdjango import fields
|
||||
import ox
|
||||
from ox import stripTags
|
||||
from ox.normalize import canonicalTitle, canonicalName
|
||||
from firefogg import Firefogg
|
||||
|
||||
from backend import utils
|
||||
from backend import extract
|
||||
from pandora.backend.models import Movie
|
||||
|
||||
def parse_decimal(string):
|
||||
string = string.replace(':', '/')
|
||||
if '/' not in string:
|
||||
string = '%s/1' % string
|
||||
d = string.split('/')
|
||||
return Decimal(d[0]) / Decimal(d[1])
|
||||
|
||||
#ARCHIVE stuff
|
||||
class Volume(models.Model):
|
||||
start = models.CharField(max_length=1)
|
||||
end = models.CharField(max_length=1)
|
||||
name = models.CharField(max_length=255)
|
||||
|
||||
class Archive(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
published = models.DateTimeField(default=datetime.now, editable=False)
|
||||
|
||||
name = models.CharField(max_length=255)
|
||||
user = models.ForeignKey(User, related_name='owned_archives')
|
||||
|
||||
users = models.ManyToManyField(User, related_name='archives')
|
||||
volumes = models.ManyToManyField(Volume, related_name='archives')
|
||||
|
||||
def editable(self, user):
|
||||
return self.users.filter(username=user.username).count() > 0
|
||||
|
||||
class File(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
|
||||
verified = models.BooleanField(default = False)
|
||||
|
||||
oshash = models.CharField(max_length=16)
|
||||
movie = models.ForeignKey(Movie, related_name='files')
|
||||
|
||||
name = models.CharField(max_length=2048, default="") # canoncial path/file
|
||||
sort_name = models.CharField(max_length=2048, default="") # sort path/file name
|
||||
|
||||
part = models.CharField(default="", max_length=255)
|
||||
version = models.CharField(default="", max_length=255) # sort path/file name
|
||||
language = models.CharField(default="", max_length=8)
|
||||
|
||||
season = models.IntegerField(default = -1)
|
||||
episode = models.IntegerField(default = -1)
|
||||
|
||||
size = models.BigIntegerField(default = 0)
|
||||
duration = models.IntegerField(default = 0)
|
||||
|
||||
info = fields.DictField(default={})
|
||||
|
||||
video_codec = models.CharField(max_length=255)
|
||||
pixel_format = models.CharField(max_length=255)
|
||||
display_aspect_ratio = models.CharField(max_length=255)
|
||||
width = models.IntegerField(default = 0)
|
||||
height = models.IntegerField(default = 0)
|
||||
framerate = models.CharField(max_length=255)
|
||||
|
||||
audio_codec = models.CharField(max_length=255)
|
||||
channels = models.IntegerField(default = 0)
|
||||
samplerate = models.IntegerField(default = 0)
|
||||
|
||||
bits_per_pixel = models.FloatField(default=-1)
|
||||
pixels = models.BigIntegerField(default=0)
|
||||
|
||||
is_audio = models.BooleanField(default = False)
|
||||
is_video = models.BooleanField(default = False)
|
||||
is_extra = models.BooleanField(default = False)
|
||||
is_main = models.BooleanField(default = False)
|
||||
is_subtitle = models.BooleanField(default = False)
|
||||
is_version = models.BooleanField(default = False)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.name and not self.sort_name:
|
||||
self.sort_name = canonicalTitle(self.name)
|
||||
if self.info:
|
||||
for key in ('duration', 'size'):
|
||||
setattr(self, key, self.info.get(key, 0))
|
||||
|
||||
if 'video' in self.info and self.info['video']:
|
||||
self.video_codec = self.info['video'][0]['codec']
|
||||
self.width = self.info['video'][0]['width']
|
||||
self.height = self.info['video'][0]['height']
|
||||
self.framerate = self.info['video'][0]['framerate']
|
||||
if 'display_aspect_ratio' in self.info['video'][0]:
|
||||
self.display_aspect_ratio = self.info['video'][0]['display_aspect_ratio']
|
||||
else:
|
||||
self.display_aspect_ratio = "%s:%s" % (self.width, self.height)
|
||||
self.is_video = True
|
||||
self.is_audio = False
|
||||
else:
|
||||
self.is_video = False
|
||||
if 'audio' in self.info and self.info['audio']:
|
||||
self.audio_codec = self.info['audio'][0]['codec']
|
||||
self.samplerate = self.info['audio'][0]['samplerate']
|
||||
self.channels = self.info['audio'][0]['channels']
|
||||
|
||||
if not self.is_video:
|
||||
self.is_audio = True
|
||||
else:
|
||||
self.is_audio = False
|
||||
|
||||
if self.framerate:
|
||||
self.pixels = int(self.width * self.height * float(parse_decimal(self.framerate)) * self.duration)
|
||||
|
||||
if not self.is_audio and not self.is_video and self.name.endswith('.srt'):
|
||||
self.is_subtitle = True
|
||||
|
||||
if self.name and self.name.startswith('Extra/'):
|
||||
self.is_extra = True
|
||||
self.is_main = False
|
||||
else:
|
||||
self.is_extra = False
|
||||
self.is_main = True
|
||||
|
||||
super(File, self).save(*args, **kwargs)
|
||||
|
||||
def json(self):
|
||||
r = {}
|
||||
for k in self:
|
||||
r[k] = unicode(self[k])
|
||||
return r
|
||||
|
||||
class FileInstance(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
published = models.DateTimeField(default=datetime.now, editable=False)
|
||||
accessed = models.DateTimeField(default=datetime.now, editable=False)
|
||||
|
||||
path = models.CharField(max_length=2048)
|
||||
folder = models.CharField(max_length=255)
|
||||
|
||||
file = models.ForeignKey(File, related_name='instances')
|
||||
archive = models.ForeignKey(Archive, related_name='files')
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s <%s> in %s'% (self.path, self.oshash, self.archive.name)
|
||||
|
||||
@property
|
||||
def movieId(self):
|
||||
return File.objects.get(oshash=self.oshash).movieId
|
||||
|
||||
class Frame(models.Model):
|
||||
created = models.DateTimeField(auto_now_add=True)
|
||||
modified = models.DateTimeField(auto_now=True)
|
||||
file = models.ForeignKey(File, related_name="frames")
|
||||
position = models.FloatField()
|
||||
frame = models.ImageField(default=None, null=True, upload_to=lambda f, x: frame_path(f))
|
||||
|
||||
#FIXME: frame path should be renamed on save to match current position
|
||||
|
||||
def __unicode__(self):
|
||||
return '%s at %s' % (self.file, self.position)
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue