from random import randint
import os.path
import re
+from slugify import slugify
+from sortify import sortify
from urllib.request import urlretrieve
from django.apps import apps
from django.conf import settings
tags = managers.TagDescriptor(Tag)
tag_relations = GenericRelation(Tag.intermediary_table_model)
translators = models.ManyToManyField(Tag, blank=True)
+ narrators = models.ManyToManyField(Tag, blank=True, related_name='narrated')
+ has_audio = models.BooleanField(default=False)
html_built = django.dispatch.Signal()
published = django.dispatch.Signal()
return sibling.get_first_text()
return self.parent.get_next_text(inside=False)
- def get_child_audiobook(self):
- BookMedia = apps.get_model('catalogue', 'BookMedia')
- if not BookMedia.objects.filter(book__ancestor=self).exists():
- return None
- for child in self.children.order_by('parent_number').all():
- if child.has_mp3_file():
- return child
- child_sub = child.get_child_audiobook()
- if child_sub is not None:
- return child_sub
-
def get_siblings(self):
if not self.parent:
return []
else:
return self.media.filter(type=type_).exists()
- def has_audio(self):
- return self.has_media('mp3')
-
def get_media(self, type_):
if self.has_media(type_):
if type_ in Book.formats:
def media_audio_epub(self):
return self.get_media('audio.epub')
- def get_audiobooks(self):
+ def get_audiobooks(self, with_children=False, processing=False):
ogg_files = {}
for m in self.media.filter(type='ogg').order_by().iterator():
ogg_files[m.name] = m
media['ogg'] = ogg
audiobooks.append(media)
- projects = sorted(projects)
- total_duration = '%d:%02d' % (
- total_duration // 60,
- total_duration % 60
- )
+ if with_children:
+ for child in self.get_children():
+ ch_audiobooks, ch_projects, ch_duration = child.get_audiobooks(
+ with_children=True, processing=True)
+ audiobooks.append({'part': child})
+ audiobooks += ch_audiobooks
+ projects.update(ch_projects)
+ total_duration += ch_duration
+
+ if not processing:
+ projects = sorted(projects)
+ total_duration = '%d:%02d' % (
+ total_duration // 60,
+ total_duration % 60
+ )
+
return audiobooks, projects, total_duration
+ def get_audiobooks_with_children(self):
+ return self.get_audiobooks(with_children=True)
+
def wldocument(self, parse_dublincore=True, inherit=True):
from catalogue.import_utils import ORMDocProvider
from librarian.parser import WLDocument
def references(self):
return self.reference_set.all().select_related('entity')
+ def update_has_audio(self):
+ self.has_audio = False
+ if self.media.filter(type='mp3').exists():
+ self.has_audio = True
+ if self.descendant.filter(has_audio=True).exists():
+ self.has_audio = True
+ self.save(update_fields=['has_audio'])
+ if self.parent is not None:
+ self.parent.update_has_audio()
+
+ def update_narrators(self):
+ narrator_names = set()
+ for bm in self.media.filter(type='mp3'):
+ narrator_names.update(set(
+ a.strip() for a in re.split(r',|\si\s', bm.artist)
+ ))
+ narrators = []
+
+ for name in narrator_names:
+ if not name: continue
+ slug = slugify(name)
+ try:
+ t = Tag.objects.get(category='author', slug=slug)
+ except Tag.DoesNotExist:
+ sort_key = sortify(
+ ' '.join(name.rsplit(' ', 1)[::-1]).lower()
+ )
+ t = Tag.objects.create(
+ category='author',
+ name_pl=name,
+ slug=slug,
+ sort_key=sort_key,
+ )
+ narrators.append(t)
+ self.narrators.set(narrators)
+
@classmethod
@transaction.atomic
def repopulate_ancestors(cls):