+ def get_first_text(self):
+ if self.html_file:
+ return self
+ child = self.children.all().order_by('parent_number').first()
+ if child is not None:
+ return child.get_first_text()
+
+ def get_last_text(self):
+ if self.html_file:
+ return self
+ child = self.children.all().order_by('parent_number').last()
+ if child is not None:
+ return child.get_last_text()
+
+ def get_prev_text(self):
+ if not self.parent:
+ return None
+ sibling = self.parent.children.filter(parent_number__lt=self.parent_number).order_by('-parent_number').first()
+ if sibling is not None:
+ return sibling.get_last_text()
+
+ if self.parent.html_file:
+ return self.parent
+
+ return self.parent.get_prev_text()
+
+ def get_next_text(self, inside=True):
+ if inside:
+ child = self.children.order_by('parent_number').first()
+ if child is not None:
+ return child.get_first_text()
+
+ if not self.parent:
+ return None
+ sibling = self.parent.children.filter(parent_number__gt=self.parent_number).order_by('parent_number').first()
+ if sibling is not None:
+ 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 []
+ return self.parent.children.all().order_by('parent_number')
+
+ def get_children(self):
+ return self.children.all().order_by('parent_number')
+