diff --git a/.env.example b/.env.example index 2000a716..ca6f65bb 100644 --- a/.env.example +++ b/.env.example @@ -8,6 +8,8 @@ USE_HTTPS=true DOMAIN=your.domain.here EMAIL=your@email.here +# Instance defualt language (see options at bookwyrm/settings.py "LANGUAGES" +LANGUAGE_CODE="en-us" # Used for deciding which editions to prefer DEFAULT_LANGUAGE="English" diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py index ef9bbc15..e442dbf4 100644 --- a/bookwyrm/forms.py +++ b/bookwyrm/forms.py @@ -444,6 +444,12 @@ class ListForm(CustomForm): fields = ["user", "name", "description", "curation", "privacy", "group"] +class ListItemForm(CustomForm): + class Meta: + model = models.ListItem + fields = ["user", "book", "book_list", "notes"] + + class GroupForm(CustomForm): class Meta: model = models.Group diff --git a/bookwyrm/management/commands/initdb.py b/bookwyrm/management/commands/initdb.py index 37dd66af..09d86462 100644 --- a/bookwyrm/management/commands/initdb.py +++ b/bookwyrm/management/commands/initdb.py @@ -19,9 +19,7 @@ def init_permissions(): { "codename": "edit_instance_settings", "name": "change the instance info", - "groups": [ - "admin", - ], + "groups": ["admin"], }, { "codename": "set_user_group", @@ -55,7 +53,7 @@ def init_permissions(): }, ] - content_type = models.ContentType.objects.get_for_model(User) + content_type = ContentType.objects.get_for_model(models.User) for permission in permissions: permission_obj = Permission.objects.create( codename=permission["codename"], @@ -66,15 +64,12 @@ def init_permissions(): for group_name in permission["groups"]: Group.objects.get(name=group_name).permissions.add(permission_obj) - # while the groups and permissions shouldn't be changed because the code - # depends on them, what permissions go with what groups should be editable - def init_connectors(): """access book data sources""" models.Connector.objects.create( identifier="bookwyrm.social", - name="BookWyrm dot Social", + name="Bookwyrm.social", connector_file="bookwyrm_connector", base_url="https://bookwyrm.social", books_url="https://bookwyrm.social/book", @@ -84,6 +79,7 @@ def init_connectors(): priority=2, ) + # pylint: disable=line-too-long models.Connector.objects.create( identifier="inventaire.io", name="Inventaire", @@ -127,7 +123,7 @@ def init_settings(): ) -def init_link_domains(*_): +def init_link_domains(): """safe book links""" domains = [ ("standardebooks.org", "Standard EBooks"), @@ -144,10 +140,15 @@ def init_link_domains(*_): ) +# pylint: disable=no-self-use +# pylint: disable=unused-argument class Command(BaseCommand): + """command-line options""" + help = "Initializes the database with starter data" def add_arguments(self, parser): + """specify which function to run""" parser.add_argument( "--limit", default=None, @@ -155,6 +156,7 @@ class Command(BaseCommand): ) def handle(self, *args, **options): + """execute init""" limit = options.get("limit") tables = [ "group", @@ -164,7 +166,7 @@ class Command(BaseCommand): "settings", "linkdomain", ] - if limit not in tables: + if limit and limit not in tables: raise Exception("Invalid table limit:", limit) if not limit or limit == "group": diff --git a/bookwyrm/migrations/0130_alter_listitem_notes.py b/bookwyrm/migrations/0130_alter_listitem_notes.py new file mode 100644 index 00000000..a12efd40 --- /dev/null +++ b/bookwyrm/migrations/0130_alter_listitem_notes.py @@ -0,0 +1,21 @@ +# Generated by Django 3.2.10 on 2022-01-24 20:01 + +import bookwyrm.models.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0129_auto_20220117_1716"), + ] + + operations = [ + migrations.AlterField( + model_name="listitem", + name="notes", + field=bookwyrm.models.fields.TextField( + blank=True, max_length=300, null=True + ), + ), + ] diff --git a/bookwyrm/migrations/0130_alter_user_preferred_language.py b/bookwyrm/migrations/0130_alter_user_preferred_language.py new file mode 100644 index 00000000..cd5a07ea --- /dev/null +++ b/bookwyrm/migrations/0130_alter_user_preferred_language.py @@ -0,0 +1,37 @@ +# Generated by Django 3.2.10 on 2022-01-24 17:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0129_auto_20220117_1716"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="preferred_language", + field=models.CharField( + blank=True, + choices=[ + ("en-us", "English"), + ("de-de", "Deutsch (German)"), + ("es-es", "Español (Spanish)"), + ("gl-es", "Galego (Galician)"), + ("it-it", "Italiano (Italian)"), + ("fr-fr", "Français (French)"), + ("lt-lt", "Lietuvių (Lithuanian)"), + ("no-no", "Norsk (Norwegian)"), + ("pt-br", "Português do Brasil (Brazilian Portuguese)"), + ("pt-pt", "Português Europeu (European Portuguese)"), + ("sv-se", "Swedish (Svenska)"), + ("zh-hans", "简体中文 (Simplified Chinese)"), + ("zh-hant", "繁體中文 (Traditional Chinese)"), + ], + max_length=255, + null=True, + ), + ), + ] diff --git a/bookwyrm/migrations/0131_merge_20220125_1644.py b/bookwyrm/migrations/0131_merge_20220125_1644.py new file mode 100644 index 00000000..954ddacc --- /dev/null +++ b/bookwyrm/migrations/0131_merge_20220125_1644.py @@ -0,0 +1,13 @@ +# Generated by Django 3.2.10 on 2022-01-25 16:44 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0130_alter_listitem_notes"), + ("bookwyrm", "0130_alter_user_preferred_language"), + ] + + operations = [] diff --git a/bookwyrm/models/list.py b/bookwyrm/models/list.py index d159bc4a..7dff7214 100644 --- a/bookwyrm/models/list.py +++ b/bookwyrm/models/list.py @@ -2,6 +2,7 @@ import uuid from django.apps import apps +from django.core.exceptions import PermissionDenied from django.db import models from django.db.models import Q from django.utils import timezone @@ -74,6 +75,22 @@ class List(OrderedCollectionMixin, BookWyrmModel): return super().raise_not_editable(viewer) + def raise_not_submittable(self, viewer): + """can the user submit a book to the list?""" + # if you can't view the list you can't submit to it + self.raise_visible_to_user(viewer) + + # all good if you're the owner or the list is open + if self.user == viewer or self.curation in ["open", "curated"]: + return + if self.curation == "group": + is_group_member = GroupMember.objects.filter( + group=self.group, user=viewer + ).exists() + if is_group_member: + return + raise PermissionDenied() + @classmethod def followers_filter(cls, queryset, viewer): """Override filter for "followers" privacy level to allow non-following @@ -125,7 +142,7 @@ class ListItem(CollectionItemMixin, BookWyrmModel): user = fields.ForeignKey( "User", on_delete=models.PROTECT, activitypub_field="actor" ) - notes = fields.TextField(blank=True, null=True) + notes = fields.TextField(blank=True, null=True, max_length=300) approved = models.BooleanField(default=True) order = fields.IntegerField() endorsement = models.ManyToManyField("User", related_name="endorsers") diff --git a/bookwyrm/models/site.py b/bookwyrm/models/site.py index 5d91553e..b2119e23 100644 --- a/bookwyrm/models/site.py +++ b/bookwyrm/models/site.py @@ -90,6 +90,14 @@ class SiteSettings(models.Model): return get_absolute_url(uploaded) return urljoin(STATIC_FULL_URL, default_path) + def save(self, *args, **kwargs): + """if require_confirm_email is disabled, make sure no users are pending""" + if not self.require_confirm_email: + User.objects.filter(is_active=False, deactivation_reason="pending").update( + is_active=True, deactivation_reason=None + ) + super().save(*args, **kwargs) + class SiteInvite(models.Model): """gives someone access to create an account on the instance""" diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index 9f836278..282a0de3 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -14,7 +14,7 @@ VERSION = "0.2.0" PAGE_LENGTH = env("PAGE_LENGTH", 15) DEFAULT_LANGUAGE = env("DEFAULT_LANGUAGE", "English") -JS_CACHE = "76c5ff1f" +JS_CACHE = "7b5303af" # email EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend") @@ -245,7 +245,7 @@ AUTH_PASSWORD_VALIDATORS = [ # Internationalization # https://docs.djangoproject.com/en/3.2/topics/i18n/ -LANGUAGE_CODE = "en-us" +LANGUAGE_CODE = env("LANGUAGE_CODE", "en-us") LANGUAGES = [ ("en-us", _("English")), ("de-de", _("Deutsch (German)")), @@ -257,6 +257,7 @@ LANGUAGES = [ ("no-no", _("Norsk (Norwegian)")), ("pt-br", _("Português do Brasil (Brazilian Portuguese)")), ("pt-pt", _("Português Europeu (European Portuguese)")), + ("sv-se", _("Swedish (Svenska)")), ("zh-hans", _("简体中文 (Simplified Chinese)")), ("zh-hant", _("繁體中文 (Traditional Chinese)")), ] diff --git a/bookwyrm/static/js/bookwyrm.js b/bookwyrm/static/js/bookwyrm.js index 94163787..cf3ce303 100644 --- a/bookwyrm/static/js/bookwyrm.js +++ b/bookwyrm/static/js/bookwyrm.js @@ -122,39 +122,13 @@ let BookWyrm = new (class { */ updateCountElement(counter, data) { let count = data.count; - const count_by_type = data.count_by_type; + + if (count === undefined) { + return; + } + const currentCount = counter.innerText; const hasMentions = data.has_mentions; - const allowedStatusTypesEl = document.getElementById("unread-notifications-wrapper"); - - // If we're on the right counter element - if (counter.closest("[data-poll-wrapper]").contains(allowedStatusTypesEl)) { - const allowedStatusTypes = JSON.parse(allowedStatusTypesEl.textContent); - - // For keys in common between allowedStatusTypes and count_by_type - // This concerns 'review', 'quotation', 'comment' - count = allowedStatusTypes.reduce(function (prev, currentKey) { - const currentValue = count_by_type[currentKey] | 0; - - return prev + currentValue; - }, 0); - - // Add all the "other" in count_by_type if 'everything' is allowed - if (allowedStatusTypes.includes("everything")) { - // Clone count_by_type with 0 for reviews/quotations/comments - const count_by_everything_else = Object.assign({}, count_by_type, { - review: 0, - quotation: 0, - comment: 0, - }); - - count = Object.keys(count_by_everything_else).reduce(function (prev, currentKey) { - const currentValue = count_by_everything_else[currentKey] | 0; - - return prev + currentValue; - }, count); - } - } if (count != currentCount) { this.addRemoveClass(counter.closest("[data-poll-wrapper]"), "is-hidden", count < 1); @@ -517,7 +491,7 @@ let BookWyrm = new (class { duplicateInput(event) { const trigger = event.currentTarget; - const input_id = trigger.dataset["duplicate"]; + const input_id = trigger.dataset.duplicate; const orig = document.getElementById(input_id); const parent = orig.parentNode; const new_count = parent.querySelectorAll("input").length + 1; diff --git a/bookwyrm/templates/about/about.html b/bookwyrm/templates/about/about.html index acc89b0e..4e533b11 100644 --- a/bookwyrm/templates/about/about.html +++ b/bookwyrm/templates/about/about.html @@ -12,6 +12,7 @@ {% block about_content %} {# seven day cache #} {% cache 604800 about_page %} + {% get_book_superlatives as superlatives %}

@@ -26,7 +27,7 @@

- {% if top_rated %} + {% if superlatives.top_rated %} {% with book=superlatives.top_rated.default_edition rating=top_rated.rating %}
@@ -45,7 +46,7 @@ {% endwith %} {% endif %} - {% if wanted %} + {% if superlatives.wanted %} {% with book=superlatives.wanted.default_edition %}
@@ -64,7 +65,7 @@ {% endwith %} {% endif %} - {% if controversial %} + {% if superlatives.controversial %} {% with book=superlatives.controversial.default_edition %}
diff --git a/bookwyrm/templates/author/author.html b/bookwyrm/templates/author/author.html index 8061d580..afbf3178 100644 --- a/bookwyrm/templates/author/author.html +++ b/bookwyrm/templates/author/author.html @@ -141,12 +141,14 @@

{% blocktrans with name=author.name %}Books by {{ name }}{% endblocktrans %}

{% for book in books %} + {% with book=book.default_edition %}
{% include 'landing/small-book.html' with book=book %}
{% include 'snippets/shelve_button/shelve_button.html' with book=book %}
+ {% endwith %} {% endfor %}
diff --git a/bookwyrm/templates/feed/feed.html b/bookwyrm/templates/feed/feed.html index dbbc650f..9e625313 100644 --- a/bookwyrm/templates/feed/feed.html +++ b/bookwyrm/templates/feed/feed.html @@ -24,9 +24,12 @@ {# announcements and system messages #} {% if not activities.number > 1 %} - {% if request.user.show_goal and not goal and tab.key == 'home' %} diff --git a/bookwyrm/templates/get_started/layout.html b/bookwyrm/templates/get_started/layout.html index 32db56d5..b8e7c861 100644 --- a/bookwyrm/templates/get_started/layout.html +++ b/bookwyrm/templates/get_started/layout.html @@ -9,7 +9,7 @@