+ @classmethod
+ def book_list(cls, filter=None):
+ """Generates a hierarchical listing of all books.
+
+ Books are optionally filtered with a test function.
+
+ """
+
+ books_by_parent = {}
+ books = cls.objects.all().order_by('parent_number', 'sort_key').only('title', 'parent', 'slug')
+ if filter:
+ books = books.filter(filter).distinct()
+ book_ids = set((book.pk for book in books))
+ for book in books:
+ parent = book.parent_id
+ if parent not in book_ids:
+ parent = None
+ books_by_parent.setdefault(parent, []).append(book)
+ else:
+ for book in books:
+ books_by_parent.setdefault(book.parent_id, []).append(book)
+
+ orphans = []
+ books_by_author = SortedDict()
+ for tag in Tag.objects.filter(category='author'):
+ books_by_author[tag] = []
+
+ for book in books_by_parent.get(None,()):
+ authors = list(book.tags.filter(category='author'))
+ if authors:
+ for author in authors:
+ books_by_author[author].append(book)
+ else:
+ orphans.append(book)
+
+ return books_by_author, orphans, books_by_parent
+
+ _audiences_pl = {
+ "SP1": (1, u"szkoła podstawowa"),
+ "SP2": (1, u"szkoła podstawowa"),
+ "P": (1, u"szkoła podstawowa"),
+ "G": (2, u"gimnazjum"),
+ "L": (3, u"liceum"),
+ "LP": (3, u"liceum"),
+ }
+ def audiences_pl(self):
+ audiences = self.get_extra_info_value().get('audiences', [])
+ audiences = sorted(set([self._audiences_pl[a] for a in audiences]))
+ return [a[1] for a in audiences]
+