diff --git a/bookwyrm/forms/lists.py b/bookwyrm/forms/lists.py index 647db3bfe..f5008baa3 100644 --- a/bookwyrm/forms/lists.py +++ b/bookwyrm/forms/lists.py @@ -24,7 +24,7 @@ class SortListForm(forms.Form): sort_by = ChoiceField( choices=( ("order", _("List Order")), - ("title", _("Book Title")), + ("sort_title", _("Book Title")), ("rating", _("Rating")), ), label=_("Sort By"), diff --git a/bookwyrm/migrations/0179_populate_sort_title.py b/bookwyrm/migrations/0179_populate_sort_title.py new file mode 100644 index 000000000..5c9ae39a3 --- /dev/null +++ b/bookwyrm/migrations/0179_populate_sort_title.py @@ -0,0 +1,41 @@ +import re +from itertools import chain + +from django.db import migrations, transaction +from django.db.models import Q + +from bookwyrm.settings import LANGUAGE_ARTICLES + + +@transaction.atomic +def populate_sort_title(apps, schema_editor): + Edition = apps.get_model("bookwyrm", "Edition") + db_alias = schema_editor.connection.alias + editions_wo_sort_title = Edition.objects.using(db_alias).filter( + Q(sort_title__isnull=True) | Q(sort_title__exact="") + ) + for edition in editions_wo_sort_title: + articles = chain( + *(LANGUAGE_ARTICLES.get(language, ()) for language in edition.languages) + ) + if articles: + icase_articles = ( + f"[{a[0].capitalize()}{a[0].lower()}]{a[1:]}" for a in articles + ) + edition.sort_title = re.sub( + f'^{" |^".join(icase_articles)} ', "", edition.title + ) + else: + edition.sort_title = edition.title + edition.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0178_auto_20230328_2132"), + ] + + operations = [ + migrations.RunPython(populate_sort_title), + ] diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index 4e7ffcad3..2bad36a50 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -1,4 +1,5 @@ """ database schema for books and shelves """ +from itertools import chain import re from django.contrib.postgres.search import SearchVectorField @@ -17,6 +18,7 @@ from bookwyrm.preview_images import generate_edition_preview_image_task from bookwyrm.settings import ( DOMAIN, DEFAULT_LANGUAGE, + LANGUAGE_ARTICLES, ENABLE_PREVIEW_IMAGES, ENABLE_THUMBNAIL_GENERATION, ) @@ -363,6 +365,16 @@ class Edition(Book): for author_id in self.authors.values_list("id", flat=True): cache.delete(f"author-books-{author_id}") + # Create sort title by removing articles from title + if self.sort_title is None: + articles = chain( + *(LANGUAGE_ARTICLES[language] for language in self.languages) + ) + icase_articles = ( + f"[{a[0].capitalize()}{a[0].lower()}]{a[1:]}" for a in articles + ) + self.sort_title = re.sub(f'^{" |^".join(icase_articles)} ', "", self.title) + return super().save(*args, **kwargs) @classmethod diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index 8dcf90fcb..f9940bcd5 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -312,6 +312,9 @@ LANGUAGES = [ ("zh-hant", _("繁體中文 (Traditional Chinese)")), ] +LANGUAGE_ARTICLES = { + "English": {"The", "A", "An"}, +} TIME_ZONE = "UTC" diff --git a/bookwyrm/templates/shelf/shelf.html b/bookwyrm/templates/shelf/shelf.html index 79ec241be..7d0035ed3 100644 --- a/bookwyrm/templates/shelf/shelf.html +++ b/bookwyrm/templates/shelf/shelf.html @@ -145,7 +145,7 @@ {% trans "Cover"%} - {% trans "Title" as text %}{% include 'snippets/table-sort-header.html' with field="title" sort=sort text=text %} + {% trans "Title" as text %}{% include 'snippets/table-sort-header.html' with field="sort_title" sort=sort text=text %} {% trans "Author" as text %}{% include 'snippets/table-sort-header.html' with field="author" sort=sort text=text %} {% if request.user.is_authenticated %} {% if is_self %}