cleanup files, round 1
This commit is contained in:
parent
66302e0ded
commit
5001e9a808
4 changed files with 70 additions and 105 deletions
|
@ -29,9 +29,11 @@ class File(models.Model):
|
||||||
item = models.ForeignKey(Item, related_name='files')
|
item = models.ForeignKey(Item, related_name='files')
|
||||||
|
|
||||||
name = models.CharField(max_length=2048, default="") # canoncial path/file
|
name = models.CharField(max_length=2048, default="") # canoncial path/file
|
||||||
|
folder = models.CharField(max_length=2048, default="") # canoncial path/file
|
||||||
sort_name = models.CharField(max_length=2048, default="") # sort name
|
sort_name = models.CharField(max_length=2048, default="") # sort name
|
||||||
|
|
||||||
part = models.CharField(default="", max_length=255)
|
type = models.CharField(default="", max_length=255)
|
||||||
|
part = models.IntegerField(null=True)
|
||||||
version = models.CharField(default="", max_length=255) # sort path/file name
|
version = models.CharField(default="", max_length=255) # sort path/file name
|
||||||
language = models.CharField(default="", max_length=8)
|
language = models.CharField(default="", max_length=8)
|
||||||
|
|
||||||
|
@ -39,7 +41,7 @@ class File(models.Model):
|
||||||
episode = models.IntegerField(default=-1)
|
episode = models.IntegerField(default=-1)
|
||||||
|
|
||||||
size = models.BigIntegerField(default=0)
|
size = models.BigIntegerField(default=0)
|
||||||
duration = models.BigIntegerField(default=0)
|
duration = models.BigIntegerField(null=True)
|
||||||
|
|
||||||
info = fields.DictField(default={})
|
info = fields.DictField(default={})
|
||||||
|
|
||||||
|
@ -72,7 +74,7 @@ class File(models.Model):
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if self.name and not self.sort_name:
|
if self.name and not self.sort_name:
|
||||||
self.sort_name = canonicalTitle(self.name)
|
self.sort_name = utils.sort_string(canonicalTitle(self.name))
|
||||||
if self.info:
|
if self.info:
|
||||||
for key in ('duration', 'size'):
|
for key in ('duration', 'size'):
|
||||||
setattr(self, key, self.info.get(key, 0))
|
setattr(self, key, self.info.get(key, 0))
|
||||||
|
@ -110,6 +112,11 @@ class File(models.Model):
|
||||||
if self.framerate:
|
if self.framerate:
|
||||||
self.pixels = int(self.width * self.height * float(utils.parse_decimal(self.framerate)) * self.duration)
|
self.pixels = int(self.width * self.height * float(utils.parse_decimal(self.framerate)) * self.duration)
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.is_video = os.path.splitext(self.name)[-1] in ('.avi', '.mkv', '.dv', '.ogv', '.mpeg', '.mov')
|
||||||
|
self.is_audio = os.path.splitext(self.name)[-1] in ('.mp3', '.wav', '.ogg', '.flac')
|
||||||
|
self.is_subtitle= os.path.splitext(self.name)[-1] in ('.srt', '.sub', '.idx')
|
||||||
|
|
||||||
if not self.is_audio and not self.is_video and self.name.endswith('.srt'):
|
if not self.is_audio and not self.is_video and self.name.endswith('.srt'):
|
||||||
self.is_subtitle = True
|
self.is_subtitle = True
|
||||||
|
|
||||||
|
@ -120,6 +127,11 @@ class File(models.Model):
|
||||||
self.is_extra = False
|
self.is_extra = False
|
||||||
self.is_main = True
|
self.is_main = True
|
||||||
|
|
||||||
|
self.part = self.get_part()
|
||||||
|
self.type = self.get_type()
|
||||||
|
self.folder = self.get_folder()
|
||||||
|
if self.type not in ('audio', 'video'):
|
||||||
|
self.duration = None
|
||||||
super(File, self).save(*args, **kwargs)
|
super(File, self).save(*args, **kwargs)
|
||||||
|
|
||||||
#upload and data handling
|
#upload and data handling
|
||||||
|
@ -216,12 +228,19 @@ class File(models.Model):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def json(self, keys=None, user=None):
|
def json(self, keys=None, user=None):
|
||||||
|
resolution = (self.width, self.height)
|
||||||
|
if resolution == (0, 0):
|
||||||
|
resolution = None
|
||||||
|
duration = self.duration
|
||||||
|
if self.get_type() != 'video':
|
||||||
|
duration = None
|
||||||
data = {
|
data = {
|
||||||
'available': self.available,
|
'available': self.available,
|
||||||
'duration': self.duration,
|
'duration': duration,
|
||||||
'framerate': self.framerate,
|
'framerate': self.framerate,
|
||||||
'height': self.height,
|
'height': self.height,
|
||||||
'width': self.width,
|
'width': self.width,
|
||||||
|
'resolution': resolution,
|
||||||
'oshash': self.oshash,
|
'oshash': self.oshash,
|
||||||
'samplerate': self.samplerate,
|
'samplerate': self.samplerate,
|
||||||
'video_codec': self.video_codec,
|
'video_codec': self.video_codec,
|
||||||
|
@ -229,8 +248,12 @@ class File(models.Model):
|
||||||
'name': self.name,
|
'name': self.name,
|
||||||
'size': self.size,
|
'size': self.size,
|
||||||
'info': self.info,
|
'info': self.info,
|
||||||
'instances': self.instances.count(),
|
'users': list(set([i.volume.user.username for i in self.instances.all()])),
|
||||||
'is_main': self.is_main
|
'instances': [i.json() for i in self.instances.all()],
|
||||||
|
'folder': self.get_folder(),
|
||||||
|
'type': self.get_type(),
|
||||||
|
'is_main': self.is_main,
|
||||||
|
'part': self.get_part()
|
||||||
}
|
}
|
||||||
if keys:
|
if keys:
|
||||||
for k in data.keys():
|
for k in data.keys():
|
||||||
|
@ -238,6 +261,25 @@ class File(models.Model):
|
||||||
del data[k]
|
del data[k]
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def get_part(self):
|
||||||
|
if self.is_extra:
|
||||||
|
return None
|
||||||
|
files = list(self.item.files.filter(type=self.type, is_main=self.is_main).order_by('sort_name'))
|
||||||
|
return files.index(self) + 1
|
||||||
|
|
||||||
|
def get_type(self):
|
||||||
|
if self.is_video:
|
||||||
|
return 'video'
|
||||||
|
if self.is_audio:
|
||||||
|
return 'audio'
|
||||||
|
if self.is_subtitle or os.path.splitext(self.name)[-1] in ('.sub', '.idx'):
|
||||||
|
return 'subtitle'
|
||||||
|
return 'unknown'
|
||||||
|
|
||||||
|
def get_folder(self):
|
||||||
|
if self.instances.count() > 0:
|
||||||
|
return self.instances.all()[0].folder
|
||||||
|
return ''
|
||||||
|
|
||||||
class Volume(models.Model):
|
class Volume(models.Model):
|
||||||
|
|
||||||
|
@ -279,6 +321,13 @@ class Instance(models.Model):
|
||||||
def itemId(self):
|
def itemId(self):
|
||||||
return File.objects.get(oshash=self.oshash).itemId
|
return File.objects.get(oshash=self.oshash).itemId
|
||||||
|
|
||||||
|
def json(self):
|
||||||
|
return {
|
||||||
|
'user': self.volume.user.username,
|
||||||
|
'volume': self.volume.name,
|
||||||
|
'folder': self.folder,
|
||||||
|
'name': self.name
|
||||||
|
}
|
||||||
|
|
||||||
def frame_path(frame, name):
|
def frame_path(frame, name):
|
||||||
ext = os.path.splitext(name)[-1]
|
ext = os.path.splitext(name)[-1]
|
||||||
|
|
|
@ -264,7 +264,7 @@ def lookup_file(request, oshash):
|
||||||
def _order_query(qs, sort, prefix=''):
|
def _order_query(qs, sort, prefix=''):
|
||||||
order_by = []
|
order_by = []
|
||||||
if len(sort) == 1:
|
if len(sort) == 1:
|
||||||
sort.append({'operator': '+', 'key': 'name'})
|
sort.append({'operator': '+', 'key': 'sort_name'})
|
||||||
sort.append({'operator': '-', 'key': 'created'})
|
sort.append({'operator': '-', 'key': 'created'})
|
||||||
'''
|
'''
|
||||||
if sort[0]['key'] == 'title':
|
if sort[0]['key'] == 'title':
|
||||||
|
@ -287,7 +287,12 @@ def _order_query(qs, sort, prefix=''):
|
||||||
operator = e['operator']
|
operator = e['operator']
|
||||||
if operator != '-':
|
if operator != '-':
|
||||||
operator = ''
|
operator = ''
|
||||||
key = {'id': 'item__itemId', 'name': 'sort_name'}.get(e['key'], e['key'])
|
key = {
|
||||||
|
'id': 'item__itemId',
|
||||||
|
'users': 'instances__volume__user__username',
|
||||||
|
'resolution': 'width',
|
||||||
|
'name': 'sort_name'
|
||||||
|
}.get(e['key'], e['key'])
|
||||||
#if operator=='-' and '%s_desc'%key in models.ItemSort.descending_fields:
|
#if operator=='-' and '%s_desc'%key in models.ItemSort.descending_fields:
|
||||||
# key = '%s_desc' % key
|
# key = '%s_desc' % key
|
||||||
order = '%s%s%s' % (operator, prefix, key)
|
order = '%s%s%s' % (operator, prefix, key)
|
||||||
|
@ -419,7 +424,7 @@ Positions
|
||||||
elif 'keys' in query:
|
elif 'keys' in query:
|
||||||
response['data']['items'] = []
|
response['data']['items'] = []
|
||||||
qs = models.File.objects.filter(item__in=query['qs'])
|
qs = models.File.objects.filter(item__in=query['qs'])
|
||||||
#qs = _order_query(qs, query['sort'])
|
qs = _order_query(qs, query['sort'])
|
||||||
keys = query['keys']
|
keys = query['keys']
|
||||||
qs = qs[query['range'][0]:query['range'][1]]
|
qs = qs[query['range'][0]:query['range'][1]]
|
||||||
response['data']['items'] = [f.json(keys) for f in qs]
|
response['data']['items'] = [f.json(keys) for f in qs]
|
||||||
|
|
|
@ -194,6 +194,8 @@ def parse_path(path):
|
||||||
|
|
||||||
def sort_string(string):
|
def sort_string(string):
|
||||||
string = string.replace(u'Þ', 'Th')
|
string = string.replace(u'Þ', 'Th')
|
||||||
|
#pad numbered titles
|
||||||
|
string = re.sub('(\d+)', lambda x: '%010d' % int(x.group(0)), string)
|
||||||
return unicodedata.normalize('NFKD', string)
|
return unicodedata.normalize('NFKD', string)
|
||||||
|
|
||||||
|
|
||||||
|
@ -206,8 +208,6 @@ def sort_title(title):
|
||||||
title = unicode(title)
|
title = unicode(title)
|
||||||
title = sort_string(title)
|
title = sort_string(title)
|
||||||
|
|
||||||
#pad numbered titles
|
|
||||||
title = re.sub('(\d+)', lambda x: '%010d' % int(x.group(0)), title)
|
|
||||||
return title.strip()
|
return title.strip()
|
||||||
|
|
||||||
def get_positions(ids, pos):
|
def get_positions(ids, pos):
|
||||||
|
|
|
@ -636,99 +636,6 @@
|
||||||
})
|
})
|
||||||
return that;
|
return that;
|
||||||
},
|
},
|
||||||
files: function() {
|
|
||||||
var that = new Ox.TextList({
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "name",
|
|
||||||
operator: "+",
|
|
||||||
title: "Name",
|
|
||||||
unique: true,
|
|
||||||
visible: true,
|
|
||||||
width: 400
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "oshash",
|
|
||||||
operator: "+",
|
|
||||||
title: "oshash",
|
|
||||||
visible: true,
|
|
||||||
width: 120
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "instances",
|
|
||||||
operator: "+",
|
|
||||||
title: "Instances",
|
|
||||||
visible: true,
|
|
||||||
width: 60
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "width",
|
|
||||||
operator: "+",
|
|
||||||
title: "Width",
|
|
||||||
visible: true,
|
|
||||||
width: 60
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "height",
|
|
||||||
operator: "+",
|
|
||||||
title: "Height",
|
|
||||||
visible: true,
|
|
||||||
width: 60
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "duration",
|
|
||||||
operator: "+",
|
|
||||||
title: "Duration",
|
|
||||||
visible: true,
|
|
||||||
width: 80,
|
|
||||||
format: {type: "duration", args: [0, "medium"]}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "size",
|
|
||||||
operator: "+",
|
|
||||||
title: "Size",
|
|
||||||
visible: true,
|
|
||||||
width: 80,
|
|
||||||
format: {type: "value", args: ["B"]}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
align: "left",
|
|
||||||
id: "is_main",
|
|
||||||
operator: "+",
|
|
||||||
title: "Main",
|
|
||||||
visible: true,
|
|
||||||
width: 140
|
|
||||||
}
|
|
||||||
],
|
|
||||||
columnsMovable: true,
|
|
||||||
columnsRemovable: true,
|
|
||||||
columnsResizable: true,
|
|
||||||
columnsVisible: true,
|
|
||||||
id: 'files',
|
|
||||||
request: function(data, callback) {
|
|
||||||
//Ox.print('data, Query.toObject', data, Query.toObject())
|
|
||||||
pandora.api.findFiles($.extend(data, {
|
|
||||||
query: {
|
|
||||||
conditions: [{
|
|
||||||
key: 'id',
|
|
||||||
value: app.user.ui.item,
|
|
||||||
operator: '='
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}), callback);
|
|
||||||
},
|
|
||||||
scrollbarVisible: true,
|
|
||||||
sort: [{key: 'name', operator:'+'}]
|
|
||||||
});
|
|
||||||
return that;
|
|
||||||
},
|
|
||||||
filter: function() {
|
filter: function() {
|
||||||
var that = new Ox.Filter({
|
var that = new Ox.Filter({
|
||||||
findKeys: $.map(app.config.itemKeys, function(key) {
|
findKeys: $.map(app.config.itemKeys, function(key) {
|
||||||
|
@ -1936,7 +1843,11 @@
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
} else if (app.user.ui.itemView == 'files') {
|
} else if (app.user.ui.itemView == 'files') {
|
||||||
app.$ui.contentPanel.replace(1, app.$ui.files = ui.files());
|
app.$ui.contentPanel.replace(1,
|
||||||
|
app.$ui.item = new Ox.FilesView({
|
||||||
|
id: result.data.item.id
|
||||||
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
app.$ui.total.html(result.data.item.title + ' (' + result.data.item.director.join(', ') + ')')
|
app.$ui.total.html(result.data.item.title + ' (' + result.data.item.director.join(', ') + ')')
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue