reader package

The app that handles configuration.

Submodules

reader.admin module

Admin models for the reader app.

reader.admin.alias_inline(model)[source]

Get an inline admin model for Alias.

Parameters:

model (str) – The name of the model that holds the alias.

Return type:

Type[GenericStackedInline]

class reader.admin.ChapterAdmin(model, admin_site)[source]

Bases: ModelAdmin

Admin model for Chapter.

inlines = (<class 'reader.admin.PageInline'>,)
date_hierarchy = 'published'
list_display = ('preview', 'title', 'series', 'volume', '_number', 'published', 'modified', 'views', 'final')
ordering = ('-modified',)
sortable_by = ('title', 'series', 'volume', 'number', 'published', 'modified', 'views')
search_fields = ('title', 'series__title')
list_filter = (('series', <class 'django.contrib.admin.filters.RelatedFieldListFilter'>), ('groups', <class 'MangAdventure.filters.title_filter.<locals>._GenericFilter'>), <class 'MangAdventure.filters.boolean_filter.<locals>._BooleanFilter'>, ('published', <class 'reader.admin.DateFilter'>), ('series__manager', <class 'MangAdventure.filters.title_filter.<locals>._GenericFilter'>))
actions = ('toggle_final',)
empty_value_display = 'N/A'
preview(obj)[source]

Get the first image of the chapter as an HTML <img>.

Parameters:

obj (Chapter) – A Chapter model instance.

Return type:

str

Returns:

An <img> tag with the chapter preview.

toggle_final(request, queryset)[source]

Toggle the status of the selected chapters.

Parameters:
  • request (HttpRequest) – The original request.

  • queryset (QuerySet) – The original queryset.

get_form(request, obj, **kwargs)[source]

Return a Form class for use in the admin add view. This is used by add_view and change_view.

Parameters:
Return type:

Type[ModelForm]

has_change_permission(request, obj=None)[source]

Return True if editing the object is permitted.

Superusers can edit any chapter.
Scanlators can only edit chapters of series they manage.
Parameters:
Return type:

bool

Returns:

True if the user is allowed to edit the chapter.

has_delete_permission(request, obj=None)[source]

Return True if deleting the object is permitted.

Superusers delete edit any chapter.
Scanlators can only delete chapters of series they manage.
Parameters:
Return type:

bool

Returns:

True if the user is allowed to delete the chapter.

class reader.admin.SeriesAdmin(model, admin_site)[source]

Bases: ModelAdmin

Admin model for Series.

inlines = (<class 'reader.admin.alias_inline.<locals>._AliasInline'>,)
list_display = ('cover_image', 'title', 'manager', 'created', 'modified', 'views', 'status', 'licensed')
date_hierarchy = 'created'
ordering = ('-modified',)
sortable_by = ('title', 'created', 'modified', 'views')
search_fields = ('title', 'aliases__name')
autocomplete_fields = ('categories',)
list_filter = ('status', ('authors', <class 'MangAdventure.filters.title_filter.<locals>._GenericFilter'>), ('artists', <class 'MangAdventure.filters.title_filter.<locals>._GenericFilter'>), ('categories', <class 'MangAdventure.filters.title_filter.<locals>._GenericFilter'>), ('manager', <class 'MangAdventure.filters.title_filter.<locals>._GenericFilter'>))
actions = ('toggle_licensed',)
empty_value_display = 'N/A'
get_form(request, obj=None, change=False, **kwargs)[source]

Return a Form class for use in the admin add view. This is used by add_view and change_view.

Parameters:
Return type:

Type[ModelForm]

get_queryset(request)[source]

Return a QuerySet of all model instances that can be edited by the admin site. This is used by changelist_view.

Parameters:

request (HttpRequest) –

Return type:

QuerySet

views(obj)[source]

Get the total views of all chapters of the series.

Parameters:

obj (Series) – A Series model instance.

Return type:

int

Returns:

The sum of chapter views.

cover_image(obj)[source]

Get the cover of the series as an HTML <img>.

Parameters:

obj (Series) – A Series model instance.

Return type:

str

Returns:

An <img> tag with the series cover.

toggle_licensed(request, queryset)[source]

Toggle the licensing status of the selected series.

Parameters:
  • request (HttpRequest) – The original request.

  • queryset (QuerySet) – The original queryset.

has_change_permission(request, obj=None)[source]

Return True if editing the object is permitted.

Superusers can edit any series.
Scanlators can only edit series they manage.
Parameters:
Return type:

bool

Returns:

True if the user is allowed to edit the series.

has_delete_permission(request, obj=None)[source]

Return True if deleting the object is permitted.

Superusers can delete any series.
Scanlators can only delete series they manage.
Parameters:
Return type:

bool

Returns:

True if the user is allowed to delete the series.

class reader.admin.AuthorAdmin(model, admin_site)[source]

Bases: ModelAdmin

Admin model for Author.

inlines = (<class 'reader.admin.alias_inline.<locals>._AliasInline'>,)
list_display = ('name', 'aliases')
search_fields = ('name', 'aliases__name')
aliases(obj)[source]

Get the author’s aliases as a string.

Parameters:

obj (Author) – An Author model instance.

Return type:

str

Returns:

A comma-separated list of aliases.

class reader.admin.ArtistAdmin(*args, **kwargs)[source]

Bases: ModelAdmin

Admin model for Artist.

inlines = (<class 'reader.admin.alias_inline.<locals>._AliasInline'>,)
exclude = ('aliases',)
list_display = ('name', 'aliases')
search_fields = ('name', 'aliases__name')
aliases(obj)[source]

Get the artist’s aliases as a string.

Parameters:

obj (Artist) – An Artist model instance.

Return type:

str

Returns:

A comma-separated list of aliases.

class reader.admin.CategoryAdmin(model, admin_site)[source]

Bases: ModelAdmin

Admin model for Category.

exclude = ('id',)
ordering = ('id',)
sortable_by = ()
list_display = ('name', 'description')
search_fields = ('name', 'description')
get_readonly_fields(request, obj=None)[source]

Return the fields that cannot be changed.

Once a Category object has been created, its name cannot be altered.

Parameters:
Return type:

Tuple

Returns:

A tuple of readonly fields.

reader.api module

API viewsets for the reader app.

class reader.api.ArtistViewSet(**kwargs)[source]

Bases: CORSMixin, ModelViewSet

API endpoints for artists.

  • list: List artists.

  • read: View a certain artist.

  • create: Create a new artist.

  • patch: Edit the given artist.

  • delete: Delete the given artist.

schema

OpenAPISchema – Custom OpenAPI schema class.

queryset = QuerySet
serializer_class

alias of ArtistSerializer

http_method_names = ['get', 'post', 'patch', 'delete', 'head', 'options']
basename = None
description = None
detail = None
dispatch(request, *args, **kwargs)

.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.

name = None
suffix = None
class reader.api.AuthorViewSet(**kwargs)[source]

Bases: CORSMixin, ModelViewSet

API endpoints for authors.

  • list: List authors.

  • read: View a certain author.

  • create: Create a new author.

  • patch: Edit the given author.

  • delete: Delete the given author.

schema

OpenAPISchema – Custom OpenAPI schema class.

queryset = QuerySet
serializer_class

alias of AuthorSerializer

http_method_names = ['get', 'post', 'patch', 'delete', 'head', 'options']
basename = None
description = None
detail = None
dispatch(request, *args, **kwargs)

.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.

name = None
suffix = None
class reader.api.CategoryViewSet(**kwargs)[source]

Bases: CORSMixin, ModelViewSet

API endpoints for categories.

  • list: List categories.

  • read: View a certain category.

  • create: Create a new category.

  • patch: Edit the given category.

  • delete: Delete the given category.

schema

OpenAPISchema – Custom OpenAPI schema class.

serializer_class

alias of CategorySerializer

queryset = QuerySet
lookup_field = 'name'
http_method_names = ['get', 'post', 'patch', 'delete', 'head', 'options']
basename = None
description = None
detail = None
dispatch(request, *args, **kwargs)

.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.

name = None
suffix = None
class reader.api.PageViewSet(**kwargs)[source]

Bases: CreateModelMixin, DestroyModelMixin, ListModelMixin, UpdateModelMixin, CORSMixin, GenericViewSet

API endpoints for pages.

  • list: List a chapter’s pages.

  • create: Create a new page.

  • patch: Edit the given page.

  • delete: Delete the given page.

schema

OpenAPISchema – Custom OpenAPI schema class.

queryset = QuerySet
serializer_class

alias of PageSerializer

filter_backends = [<class 'reader.filters.PageFilter'>]
parser_classes = (<class 'rest_framework.parsers.MultiPartParser'>,)
http_method_names = ['get', 'post', 'patch', 'delete', 'head', 'options']
basename = None
description = None
detail = None
dispatch(request, *args, **kwargs)

.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.

name = None
suffix = None
class reader.api.ChapterViewSet(**kwargs)[source]

Bases: CORSMixin, ModelViewSet

API endpoints for chapters.

  • list: List chapters.

  • read: View a certain chapter.

  • create: Create a new chapter.

  • patch: Edit the given chapter.

  • delete: Delete the given chapter.

schema

OpenAPISchema – Custom OpenAPI schema class.

serializer_class

alias of ChapterSerializer

filter_backends = [<class 'reader.filters.ChapterFilter'>, <class 'reader.filters.DateFormat'>]
parser_classes = (<class 'rest_framework.parsers.MultiPartParser'>,)
http_method_names = ['get', 'post', 'patch', 'delete', 'head', 'options']
pages(request, pk)[source]

Get the pages of the chapter.

Parameters:
  • request (Request) –

  • pk (int) –

Return type:

Response

read(request, pk)[source]

Redirect to the reader.

Parameters:
  • request (Request) –

  • pk (int) –

Return type:

Response

retrieve(request, *args, **kwargs)[source]
Parameters:

request (Request) –

Return type:

Response

get_queryset()[source]

Get the list of items for this view. This must be an iterable, and may be a queryset. Defaults to using self.queryset.

This method should always be used rather than accessing self.queryset directly, as self.queryset gets evaluated only once, and those results are cached for all subsequent requests.

You may want to override this if you need to provide different querysets depending on the incoming request.

(Eg. return a list of items that is specific to the user)

Return type:

QuerySet

basename = None
description = None
detail = None
dispatch(request, *args, **kwargs)

.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.

name = None
suffix = None
class reader.api.SeriesViewSet(**kwargs)[source]

Bases: CORSMixin, ModelViewSet

API endpoints for series.

  • list: List or search for series.

  • read: View the details of a series.

  • create: Create a new series.

  • patch: Edit the given series.

  • delete: Delete the given series.

schema

OpenAPISchema – Custom OpenAPI schema class.

filter_backends = [<class 'reader.filters.TitleFilter'>, <class 'reader.filters.AuthorFilter'>, <class 'reader.filters.ArtistFilter'>, <class 'reader.filters.StatusFilter'>, <class 'reader.filters.CategoriesFilter'>, <class 'reader.filters.SlugFilter'>, <class 'reader.filters.SeriesSort'>]
parser_classes = (<class 'rest_framework.parsers.MultiPartParser'>,)
pagination_class

alias of PageLimitPagination

ordering = ('title',)
lookup_field = 'slug'
http_method_names = ['get', 'post', 'patch', 'delete', 'head', 'options']
chapters(request, slug)[source]

Get the chapters of the series.

Parameters:
  • request (Request) –

  • slug (str) –

Return type:

Response

get_queryset()[source]

Get the list of items for this view. This must be an iterable, and may be a queryset. Defaults to using self.queryset.

This method should always be used rather than accessing self.queryset directly, as self.queryset gets evaluated only once, and those results are cached for all subsequent requests.

You may want to override this if you need to provide different querysets depending on the incoming request.

(Eg. return a list of items that is specific to the user)

Return type:

QuerySet

get_serializer_class()[source]

Return the class to use for the serializer. Defaults to using self.serializer_class.

You may want to override this if you need to provide different serializations depending on the incoming request.

(Eg. admins get full serialization, others get basic serialization)

Return type:

Type[SeriesSerializer]

basename = None
description = None
detail = None
dispatch(request, *args, **kwargs)

.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.

name = None
suffix = None
class reader.api.CubariViewSet(**kwargs)[source]

Bases: RetrieveModelMixin, CORSMixin, GenericViewSet

API endpoints for Cubari.

  • read: Generate JSON for cubari.moe.

schema

OpenAPISchema – Custom OpenAPI schema class.

serializer_class

alias of CubariSerializer

lookup_field = 'slug'
http_method_names = ['get', 'head', 'options']
retrieve(request, *args, **kwargs)[source]
Parameters:

request (Request) –

Return type:

Response

get_queryset()[source]

Get the list of items for this view. This must be an iterable, and may be a queryset. Defaults to using self.queryset.

This method should always be used rather than accessing self.queryset directly, as self.queryset gets evaluated only once, and those results are cached for all subsequent requests.

You may want to override this if you need to provide different querysets depending on the incoming request.

(Eg. return a list of items that is specific to the user)

Return type:

QuerySet

basename = None
description = None
detail = None
dispatch(request, *args, **kwargs)

.dispatch() is pretty much the same as Django’s regular dispatch, but with extra hooks for startup, finalize, and exception handling.

name = None
suffix = None

reader.apps module

App configuration.

class reader.apps.ReaderConfig(app_name, app_module)[source]

Bases: AppConfig

Configuration for the users app.

name = 'reader'

str – The name of the app.

ready()[source]

Register the receivers when the app is ready.

reader.feeds module

RSS and Atom feeds for the reader app.

class reader.feeds.LibraryRSS[source]

Bases: Feed

RSS feed for the series library.

ttl = 600
description = 'Updates when a new series is added'
author_name = 'MangAdventure'
title = 'Library - MangAdventure'
items()[source]

Get an iterable of the feed’s items.

Return type:

Iterable[Series]

Returns:

An iterable of Series objects.

item_description(item)[source]

Get the description of the item.

Parameters:

item (Series) – A Series object.

Return type:

str

Returns:

The description of the series.

item_categories(item)[source]

Get the categories of the item.

Parameters:

item (Series) – A Series object.

Return type:

Iterable[str]

Returns:

The names of the series’ categories.

item_pubdate(item)[source]

Get the publication date of the item.

Parameters:

item (Series) – A Series object.

Return type:

datetime

Returns:

The date the series was created.

item_updateddate(item)[source]

Get the update date of the item.

Parameters:

item (Series) – A Series object.

Return type:

datetime

Returns:

The date the series was modified.

item_enclosure_url(item)[source]

Get the enclosure URL of the item.

Parameters:

item (Series) – A Series object.

Return type:

Optional[str]

Returns:

The URL of the series’ cover image, if available.

item_enclosure_length(item)[source]

Get the enclosure length of the item.

Parameters:

item (Series) – A Series object.

Return type:

Optional[int]

Returns:

The size of the series’ cover image, if available.

item_enclosure_mime_type(item)[source]

Get the enclosure type of the item.

Parameters:

item (Series) – A Series object.

Return type:

Optional[str]

Returns:

The mime type of the series’ cover image, if available.

__call__(request, *args, **kwargs)

Call self as a function.

class reader.feeds.LibraryAtom[source]

Bases: LibraryRSS

Atom feed for the series library.

feed_type

alias of Atom1Feed

subtitle = 'Updates when a new series is added'
__call__(request, *args, **kwargs)

Call self as a function.

class reader.feeds.ReleasesRSS[source]

Bases: Feed

RSS feed for chapter releases.

ttl = 600
author_name = 'MangAdventure'
get_object(request, slug=None)[source]

Get a Series object from the request.

Parameters:
Return type:

Optional[Series]

Returns:

The series that has the given slug, or None if the slug is None.

Get the link of the feed’s page.

Parameters:

obj (Optional[Series]) – The object of the feed.

Return type:

str

Returns:

The URL of the series, or the home page.

title(obj)[source]

Get the title of the feed.

Parameters:

obj (Optional[Series]) – The object of the feed.

Return type:

str

Returns:

The title of the series, or Releases.

description(obj)[source]

Get the description of the feed.

Parameters:

obj (Optional[Series]) – The object of the feed.

Return type:

str

Returns:

A description with the title of the series, if available.

items(obj)[source]

Get an iterable of the feed’s items.

Parameters:

obj (Optional[Series]) – The object of the feed.

Return type:

Iterable[Chapter]

Returns:

An iterable of Chapter objects.

item_description(item)[source]

Get the description of the item.

Parameters:

item (Chapter) – A Chapter object.

Return type:

str

Returns:

The Chapter object as a string.

item_pubdate(item)[source]

Get the publication date of the item.

Parameters:

item (Chapter) – A Chapter object.

Return type:

datetime

Returns:

The date the chapter was published.

item_updateddate(item)[source]

Get the update date of the item.

Parameters:

item (Chapter) – A Chapter object.

Return type:

datetime

Returns:

The date the chapter was modified.

__call__(request, *args, **kwargs)

Call self as a function.

class reader.feeds.ReleasesAtom[source]

Bases: ReleasesRSS

Atom feed for chapter releases.

feed_type

alias of Atom1Feed

subtitle(obj)

Get the description of the feed.

Parameters:

obj (Optional[Series]) – The object of the feed.

Return type:

str

Returns:

A description with the title of the series, if available.

__call__(request, *args, **kwargs)

Call self as a function.

reader.filters module

Custom filter backends for the API.

reader.filters.SERIES_FILTERS = [<class 'reader.filters.TitleFilter'>, <class 'reader.filters.AuthorFilter'>, <class 'reader.filters.ArtistFilter'>, <class 'reader.filters.StatusFilter'>, <class 'reader.filters.CategoriesFilter'>, <class 'reader.filters.SlugFilter'>, <class 'reader.filters.SeriesSort'>]

The filters used in the series endpoint.

reader.filters.CHAPTER_FILTERS = [<class 'reader.filters.ChapterFilter'>, <class 'reader.filters.DateFormat'>]

The filters used in the chapters endpoint.

reader.filters.PAGE_FILTERS = [<class 'reader.filters.PageFilter'>]

The filters used in the pages endpoint.

reader.models module

Database models for the reader app.

TODO

Support multiple languages.

class reader.models.Author(*args, **kwargs)[source]

Bases: Model

A model representing an author.

name

CharField – The name of the author.

__str__()[source]

Return a string representing the object.

Return type:

str

Returns:

The name of the author.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

objects = <django.db.models.manager.Manager object>
class reader.models.Artist(*args, **kwargs)[source]

Bases: Model

A model representing an artist.

name

CharField – The name of the artist.

__str__()[source]

Return a string representing the object.

Return type:

str

Returns:

The name of the artist.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

objects = <django.db.models.manager.Manager object>
class reader.models.Series(*args, **kwargs)[source]

Bases: Model

A model representing a series.

TODO

Add age rating & reading mode fields.

title

CharField – The title of the series.

slug

SlugField – The unique slug of the series.

description

TextField – The description of the series.

cover

ImageField – The cover image of the series.

status

CharField – The publication status of the series.

licensed

BooleanField – The licensing status of the series.

created

DateTimeField – The date the series was created.

modified

DateTimeField – The modification date of the series.

format

CharField – The chapter name format of the series.

manager

ForeignKey – The person who manages this series.

get_absolute_url()[source]

Get the absolute URL of the object.

Return type:

str

Returns:

The URL of reader.views.series().

get_directory()[source]

Get the storage directory of the object.

Return type:

PurePath

Returns:

A path relative to MEDIA_ROOT.

save(*args, **kwargs)[source]

Save the current instance.

__str__()[source]

Return a string representing the object.

Return type:

str

Returns:

The title of the series.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

get_next_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=True, **kwargs)
get_next_by_modified(*, field=<django.db.models.fields.DateTimeField: modified>, is_next=True, **kwargs)
get_previous_by_created(*, field=<django.db.models.fields.DateTimeField: created>, is_next=False, **kwargs)
get_previous_by_modified(*, field=<django.db.models.fields.DateTimeField: modified>, is_next=False, **kwargs)
get_status_display(*, field=<django.db.models.CharField: status>)
objects = <django.db.models.manager.Manager object>
class reader.models.Status(value)[source]

Bases: TextChoices

The possible Series.status values.

ONGOING = 'ongoing'
COMPLETED = 'completed'
HIATUS = 'hiatus'
CANCELED = 'canceled'
class reader.models.Chapter(*args, **kwargs)[source]

Bases: Model

A model representing a chapter.

title

CharField – The title of the chapter.

number

FloatField – The number of the chapter.

volume

_NonZeroIntegerField – The volume of the chapter.

series

ForeignKey – The series this chapter belongs to.

file

FileField – The file which contains the chapter’s pages.

final

BooleanField – The status of the chapter.

published

DateTimeField – The publication date of the chapter.

modified

DateTimeField – The modification date of the chapter.

views

PositiveIntegerField – The total views of the chapter.

classmethod track_view(**kwargs)[source]

Increment the chapter views in a new thread.

Parameters:

kwargs – The arguments given to the queryset filter.

save(*args, **kwargs)[source]

Save the current instance.

get_absolute_url()[source]

Get the absolute URL of the object.

Return type:

str

Returns:

The URL of reader.views.chapter_redirect().

get_directory()[source]

Get the storage directory of the object.

Return type:

PurePath

Returns:

A path relative to MEDIA_ROOT.

unzip()[source]

Unzip the chapter and save its images.

zip()[source]

Generate a zip file containing the pages of this chapter.

Return type:

BytesIO

Returns:

The file-like object of the generated file.

comicinfo()[source]

Generate an XML file containing the chapter’s metadata.

Return type:

Element

Returns:

The root XML element.

__str__()[source]

Return a string representing the object.

Return type:

str

Returns:

The chapter formatted according to the format.

__eq__(other)[source]

Check whether this object is equal to another.

If the other object is a tuple, the objects are equal if the tuple consists of the volume and number of the chapter.

Otherwise, the objects are equal if they have the same base model and their primary keys are equal.

Parameters:

other (Any) – Any other object.

Return type:

bool

Returns:

True if the objects are equal.

__gt__(other)[source]

Check whether this object is greater than another.

If the other object is a tuple, this object is greater if its volume and number is greater than the tuple.

Otherwise, it’s greater if the objects have the same base model and the tuple of its volume and number is greater than the other’s.

Parameters:

other (Any) – Any other object.

Return type:

bool

Returns:

True if this object is greater.

Raises:

TypeError – If the other object is neither a tuple, nor a Chapter model.

__lt__(other)[source]

Check whether this object is less than another.

If the other object is a tuple, this object is lesser if its volume and number is less than the tuple.

Otherwise, it’s lesser if the objects have the same base model and the tuple of its volume and number is less than the other’s.

Parameters:

other (Any) – Any other object.

Return type:

bool

Returns:

True if this object is lesser.

Raises:

TypeError – If the other object is neither a tuple, nor a Chapter model.

__hash__()[source]

Return the hash of the object.

Return type:

int

Returns:

An integer hash value.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

get_next_by_modified(*, field=<django.db.models.fields.DateTimeField: modified>, is_next=True, **kwargs)
get_next_by_published(*, field=<django.db.models.fields.DateTimeField: published>, is_next=True, **kwargs)
get_previous_by_modified(*, field=<django.db.models.fields.DateTimeField: modified>, is_next=False, **kwargs)
get_previous_by_published(*, field=<django.db.models.fields.DateTimeField: published>, is_next=False, **kwargs)
objects = <django.db.models.manager.Manager object>
class reader.models.Page(*args, **kwargs)[source]

Bases: Model

A model representing a page.

TODO

Add page type, double page, width/height fields.

chapter

ForeignKey – The chapter this page belongs to.

image

ImageField – The image of the page.

number

_NonZeroIntegerField – The number of the page.

delete(using=None, keep_parents=False)[source]
Parameters:
Return type:

Tuple[int, Dict[str, int]]

get_absolute_url()[source]

Get the absolute URL of the object.

Return type:

str

Returns:

The URL of reader.views.chapter_page().

__str__()[source]

Return a string representing the object.

Return type:

str

Returns:

The title of the series, the volume, number, title of the chapter, and the file name of the page.

__eq__(other)[source]

Check whether this object is equal to another.

If the other object is a number, the objects are equal if the number of this object is equal to the other object.

Otherwise, the objects are equal if they have the same base model and their chapter and number are respectively equal.

Parameters:

other (Any) – Any other object.

Return type:

bool

Returns:

True if the objects are equal.

__gt__(other)[source]

Check whether this object is greater than another.

If the other object is a number, this object is greater if its number is greater than the other object.

Otherwise, it’s greater if the objects have the same base model and the number of this object is greater than the other’s.

Parameters:

other (Any) – Any other object.

Return type:

bool

Returns:

True if this object is greater.

Raises:

TypeError – If the other object is neither a tuple, nor a Page model.

__lt__(other)[source]

Check whether this object is less than another.

If the other object is a number, this object is lesser if its number is less than the other object.

Otherwise, it’s lesser if the objects have the same base model and the number of this object is less than the other’s.

Parameters:

other (Any) – Any other object.

Return type:

bool

Returns:

True if this object is lesser.

Raises:

TypeError – If the other object is neither a tuple, nor a Page model.

__hash__()[source]

Return the hash of the object.

Return type:

int

Returns:

An integer hash value.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

objects = <django.db.models.manager.Manager object>
class reader.models.Category(*args, **kwargs)[source]

Bases: Model

A model representing a category.

id

CharField – The category’s ID.

name

CharField – The unique name of the category.

description

TextField – The description of the category.

save(*args, **kwargs)[source]

Save the current instance.

__str__()[source]

Return a string representing the object.

Return type:

str

Returns:

The name of the category.

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

objects = <django.db.models.manager.Manager object>
class reader.models.Alias(*args, **kwargs)[source]

Bases: Model

A generic alias Model.

name

CharField – A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

object_id

PositiveIntegerField – A wrapper for a deferred-loading field. When the value is read from this object the first time, the query is executed.

content_type

ForeignKey – Accessor to the related object on the forward side of a many-to-one or one-to-one (via ForwardOneToOneDescriptor subclass) relation.

In the example:

class Child(Model):
    parent = ForeignKey(Parent, related_name='children')

Child.parent is a ForwardManyToOneDescriptor instance.

content_object

GenericForeignKey – Provide a generic many-to-one relation through the content_type and object_id fields.

This class also doubles as an accessor to the related object (similar to ForwardManyToOneDescriptor) by adding itself as a model attribute.

objects = <reader.models.AliasManager object>
__str__()[source]

Return the alias of the instance.

Return type:

str

exception DoesNotExist

Bases: ObjectDoesNotExist

exception MultipleObjectsReturned

Bases: MultipleObjectsReturned

reader.receivers module

Signal receivers for the reader app.

reader.receivers.redirect_series(sender, instance, **kwargs)[source]

Receive a signal when a series is about to be saved.

If the series exists and its slug has changed, rename its directory and create a new Redirect.

Parameters:
  • sender (Type[Series]) – The model class that sent the signal.

  • instance (Series) – The instance of the model.

reader.receivers.redirect_chapter(sender, instance, **kwargs)[source]

Receive a signal when a chapter is about to be saved.

If the chapter exists and the slug of the series it belongs to has changed, rename its directory.

Parameters:
  • sender (Type[Chapter]) – The model class that sent the signal.

  • instance (Chapter) – The instance of the model.

reader.receivers.complete_series(sender, instance, **kwargs)[source]

Receive a signal when a chapter is about to be saved.

If the chapter is new and has been marked as final, set the status of the series it belongs to as “Completed”.

Parameters:
  • sender (Type[Chapter]) – The model class that sent the signal.

  • instance (Chapter) – The instance of the model.

reader.receivers.track_view(sender, environ, **kwargs)[source]

Receive a signal when a request is processed.

Track the chapter view if necessary.

Parameters:
  • sender (Type[WSGIHandler]) – The request handler class that sent the signal.

  • environ (Dict[str, str]) – The metadata dictionary provided to the request.

reader.serializers module

Model serializers for the reader app.

class reader.serializers.ArtistSerializer(*args, **kwargs)[source]

Bases: ModelSerializer

Serializer for artists.

class Meta[source]

Bases: object

model

alias of Artist

fields = ('id', 'name')
read_only_fields = ('id',)
class reader.serializers.AuthorSerializer(*args, **kwargs)[source]

Bases: ModelSerializer

Serializer for authors.

class Meta[source]

Bases: object

model

alias of Author

fields = ('id', 'name')
read_only_fields = ('id',)
class reader.serializers.CategorySerializer(*args, **kwargs)[source]

Bases: ModelSerializer

Serializer for categories.

class Meta[source]

Bases: object

model

alias of Category

fields = ('name', 'description')
class reader.serializers.ChapterSerializer(*args, **kwargs)[source]

Bases: ModelSerializer

Serializer for chapters.

to_representation(instance)[source]

Object instance -> Dict of primitive datatypes.

Parameters:

instance (Chapter) –

Return type:

Dict

class Meta[source]

Bases: object

model

alias of Chapter

fields = ('id', 'title', 'number', 'volume', 'published', 'views', 'final', 'series', 'groups', 'full_title', 'url', 'file')
extra_kwargs = {'file': {'write_only': True}}
class reader.serializers.PageSerializer(*args, **kwargs)[source]

Bases: ModelSerializer

Serializer for chapter pages.

class Meta[source]

Bases: object

model

alias of Page

fields = ('id', 'chapter', 'image', 'number', 'url')
extra_kwargs = {'image': {'help_text': 'The image of the page.'}, 'number': {'help_text': 'The number of the page.'}}
validators = (<UniqueTogetherValidator(queryset=QuerySet, fields=('chapter', 'number'))>,)
class reader.serializers.SeriesSerializer(*args, **kwds)[source]

Bases: Generic[TSeriesSerializer]

Generic series serializer.

classmethod __class_getitem__(action)[source]

Adapt the series schema based on the action.

Parameters:

action (str) – An API view action.

Return type:

TypeVar[Type[_SeriesListSerializer], Type[_SeriesDetailSerializer]]

Returns:

The actual type of the serializer.

__orig_bases__ = (typing.Generic[~TSeriesSerializer],)
__parameters__ = (~TSeriesSerializer,)
class reader.serializers.CubariSerializer(*args, **kwargs)[source]

Bases: ModelSerializer

Serializer for cubari.moe.

class Meta[source]

Bases: object

model

alias of Series

fields = ('title', 'cover', 'original_url', 'description', 'author', 'artist', 'alt_titles', 'metadata', 'chapters')

reader.sitemaps module

Sitemaps for the reader app.

class reader.sitemaps.SeriesSitemap[source]

Bases: Sitemap

Sitemap for series.

priority = 0.7

float – The priority of the sitemap.

changefreq = 'weekly'

str – The change frequency of the items.

items()[source]

Get an iterable of the sitemap’s items.

Return type:

Iterable[Series]

Returns:

An iterable of Series objects.

lastmod(item)[source]

Get the last modified date of the item.

Parameters:

item (Series) – A Series object.

Return type:

datetime

Returns:

The date the series was modified.

class reader.sitemaps.ChapterSitemap[source]

Bases: Sitemap

Sitemap for chapters.

priority = 0.6

float – The priority of the sitemap.

changefreq = 'never'

str – The change frequency of the items.

limit = 1000

int – The maximum number of items allowed.

items()[source]

Get an iterable of the sitemap’s items.

Return type:

Iterable[Chapter]

Returns:

An iterable of Chapter objects.

lastmod(item)[source]

Get the last modified date of the item.

Parameters:

item (Chapter) – A Series object.

Return type:

datetime

Returns:

The date the chapter was modified.

reader.urls module

The URLconf of the reader app.

reader.urls.app_name = 'reader'

The URL namespace of the reader app.

reader.urls.urlpatterns = [<URLPattern '' [name='directory']>, <URLPattern '<slug:slug>/' [name='series']>, <URLPattern '<slug:slug>/<int:vol>/<float:num>/' [name='chapter']>, <URLPattern '<slug:slug>/<int:vol>/<float:num>/<int:page>/' [name='page']>, <URLPattern '<slug:slug>.atom' [name='series.atom']>, <URLPattern '<slug:slug>.rss' [name='series.rss']>, <URLPattern '<section>-sitemap.xml' [name='sitemap.xml']>, <URLPattern '<slug:slug>/<int:vol>/<float:num>.cbz' [name='cbz']>]

The URL namespace of the reader app.

reader.views module

The views of the reader app.

reader.views.directory(request)[source]

View that serves a page which lists all the series.

Parameters:

request (HttpRequest) – The original request.

Return type:

HttpResponse

Returns:

A response with the rendered all_series.html template.

reader.views.series(request, slug)[source]

View that serves the page of a single series.

If the series doesn’t have any published chapters, only staff members will be able to see it.

Parameters:
  • request (HttpRequest) – The original request.

  • slug (str) – The slug of the series.

Return type:

HttpResponse

Returns:

A response with the rendered series.html template.

Raises:

Http404 – If there is no series with the specified slug.

reader.views.chapter_page(request, slug, vol, num, page)[source]

View that serves a chapter page.

Parameters:
  • request (HttpRequest) – The original request.

  • slug (str) – The slug of the series.

  • vol (int) – The volume of the chapter.

  • num (float) – The number of the chapter.

  • page (int) – The number of the page.

Return type:

HttpResponse

Returns:

A response with the rendered chapter.html template.

Raises:

Http404 – If there is no matching chapter or page.

reader.views.chapter_redirect(request, slug, vol, num)[source]

View that redirects a chapter to its first page.

Parameters:
  • request (HttpRequest) – The original request.

  • slug (str) – The slug of the series.

  • vol (int) – The volume of the chapter.

  • num (float) – The number of the chapter.

Return type:

HttpResponsePermanentRedirect

Returns:

A redirect to chapter_page().

Raises:

Http404 – If the chapter does not exist.

reader.views.chapter_download(request, slug, vol, num)[source]

View that generates a .cbz file from a chapter.

Parameters:
  • request (HttpRequest) – The original request.

  • slug (str) – The slug of the chapter’s series.

  • vol (int) – The volume of the chapter.

  • num (float) – The number of the chapter.

Return type:

Union[FileResponse, HttpResponseUnauthorized]

Returns:

A response with the .cbz file if the user is logged in.

Raises:

Http404 – If the chapter does not exist.