diff --git a/bookwyrm/activitypub/person.py b/bookwyrm/activitypub/person.py index f1298b92..dafd1910 100644 --- a/bookwyrm/activitypub/person.py +++ b/bookwyrm/activitypub/person.py @@ -30,5 +30,5 @@ class Person(ActivityObject): icon: Image = field(default_factory=lambda: {}) bookwyrmUser: bool = False manuallyApprovesFollowers: str = False - discoverable: str = True + discoverable: str = False type: str = "Person" diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py index d330211c..4e92b32e 100644 --- a/bookwyrm/forms.py +++ b/bookwyrm/forms.py @@ -3,7 +3,6 @@ import datetime from collections import defaultdict from django import forms -from django.core.exceptions import ValidationError from django.forms import ModelForm, PasswordInput, widgets from django.forms.widgets import Textarea from django.utils import timezone @@ -130,8 +129,9 @@ class EditUserForm(CustomForm): "name", "email", "summary", - "manually_approves_followers", "show_goal", + "manually_approves_followers", + "discoverable", ] help_texts = {f: None for f in fields} diff --git a/bookwyrm/migrations/0057_user_discoverable.py b/bookwyrm/migrations/0057_user_discoverable.py new file mode 100644 index 00000000..c49592bf --- /dev/null +++ b/bookwyrm/migrations/0057_user_discoverable.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1.6 on 2021-03-21 21:44 + +import bookwyrm.models.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0056_auto_20210321_0303"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="discoverable", + field=bookwyrm.models.fields.BooleanField(default=False), + ), + ] diff --git a/bookwyrm/models/user.py b/bookwyrm/models/user.py index 46f08509..c2a74c63 100644 --- a/bookwyrm/models/user.py +++ b/bookwyrm/models/user.py @@ -103,6 +103,7 @@ class User(OrderedCollectionPageMixin, AbstractUser): last_active_date = models.DateTimeField(auto_now=True) manually_approves_followers = fields.BooleanField(default=False) show_goal = models.BooleanField(default=True) + discoverable = fields.BooleanField(default=False) name_field = "username" diff --git a/bookwyrm/templates/directory.html b/bookwyrm/templates/directory.html new file mode 100644 index 00000000..9323752f --- /dev/null +++ b/bookwyrm/templates/directory.html @@ -0,0 +1,67 @@ +{% extends 'layout.html' %} +{% load i18n %} +{% load bookwyrm_tags %} +{% load humanize %} + +{% block title %}{% trans "Directory" %}{% endblock %} + +{% block content %} +
+

+ {% trans "Directory" %} +

+
+
+ {% for user in users %} +
+
+
+
+ + {% include 'snippets/avatar.html' with user=user large=True %} + +
+ + {{ user.display_name }} + @{{ user|username }} + + {% include 'snippets/follow_button.html' with user=user %} +
+
+ + {% if user.summary %} +
+ {{ user.summary | to_markdown | safe | truncatechars_html:40 }} +
+ {% endif %} +
+ +
+
+ {% endfor %} +
+ +
+ {% include 'snippets/pagination.html' with page=users path="/directory" %} +
+ +{% endblock %} diff --git a/bookwyrm/templates/edit_author.html b/bookwyrm/templates/edit_author.html index 0316a66f..542b57f9 100644 --- a/bookwyrm/templates/edit_author.html +++ b/bookwyrm/templates/edit_author.html @@ -2,11 +2,11 @@ {% load i18n %} {% load humanize %} -{% block title %}{% trans "Edit Author" %}: {{ author.name }}{% endblock %} +{% block title %}{% trans "Edit Author:" %} {{ author.name }}{% endblock %} {% block content %}
-

+

Edit "{{ author.name }}"

diff --git a/bookwyrm/templates/layout.html b/bookwyrm/templates/layout.html index c7d10b57..e57f6152 100644 --- a/bookwyrm/templates/layout.html +++ b/bookwyrm/templates/layout.html @@ -83,18 +83,18 @@
+
+ + {% url 'directory' as path %} +

{% blocktrans %}Your account will show up in the directory, and may be recommended to other BookWyrm users.{% endblocktrans %}

+
{% endblock %} diff --git a/bookwyrm/templates/snippets/avatar.html b/bookwyrm/templates/snippets/avatar.html index 6d27cd85..d53acf2b 100644 --- a/bookwyrm/templates/snippets/avatar.html +++ b/bookwyrm/templates/snippets/avatar.html @@ -1,3 +1,3 @@ {% load bookwyrm_tags %} -{{ user.alt_text }} +{{ user.alt_text }} diff --git a/bookwyrm/tests/data/ap_user.json b/bookwyrm/tests/data/ap_user.json index b159ae65..bc4488e3 100644 --- a/bookwyrm/tests/data/ap_user.json +++ b/bookwyrm/tests/data/ap_user.json @@ -28,6 +28,9 @@ }, "bookwyrmUser": true, "manuallyApprovesFollowers": false, + "discoverable": true, + "devices": "https://friend.camp/users/tripofmice/collections/devices", + "tag": [], "icon": { "type": "Image", "mediaType": "image/png", diff --git a/bookwyrm/tests/models/test_user_model.py b/bookwyrm/tests/models/test_user_model.py index 618e4f78..bd5255ce 100644 --- a/bookwyrm/tests/models/test_user_model.py +++ b/bookwyrm/tests/models/test_user_model.py @@ -77,7 +77,7 @@ class User(TestCase): self.assertEqual(activity["inbox"], self.user.inbox) self.assertEqual(activity["outbox"], self.user.outbox) self.assertEqual(activity["bookwyrmUser"], False) - self.assertEqual(activity["discoverable"], True) + self.assertEqual(activity["discoverable"], False) self.assertEqual(activity["type"], "Person") def test_activitypub_outbox(self): diff --git a/bookwyrm/tests/views/test_directory.py b/bookwyrm/tests/views/test_directory.py new file mode 100644 index 00000000..80d9eaf7 --- /dev/null +++ b/bookwyrm/tests/views/test_directory.py @@ -0,0 +1,43 @@ +""" test for app action functionality """ +from django.template.response import TemplateResponse +from django.test import TestCase +from django.test.client import RequestFactory + +from bookwyrm import models, views + +# pylint: disable=unused-argument +class DirectoryViews(TestCase): + """ tag views""" + + def setUp(self): + """ we need basic test data and mocks """ + self.factory = RequestFactory() + self.local_user = models.User.objects.create_user( + "mouse@local.com", + "mouse@mouse.com", + "mouseword", + local=True, + localname="mouse", + remote_id="https://example.com/users/mouse", + ) + self.rat = models.User.objects.create_user( + "rat@local.com", + "rat@rat.com", + "ratword", + local=True, + localname="rat", + remote_id="https://example.com/users/rat", + discoverable=True, + ) + models.SiteSettings.objects.create() + + def test_directory_page(self): + """ there are so many views, this just makes sure it LOADS """ + view = views.Directory.as_view() + request = self.factory.get("") + request.user = self.local_user + + result = view(request) + self.assertIsInstance(result, TemplateResponse) + result.render() + self.assertEqual(result.status_code, 200) diff --git a/bookwyrm/tests/views/test_inbox.py b/bookwyrm/tests/views/test_inbox.py index b681b961..10f55f89 100644 --- a/bookwyrm/tests/views/test_inbox.py +++ b/bookwyrm/tests/views/test_inbox.py @@ -789,6 +789,7 @@ class Inbox(TestCase): self.assertEqual(user.name, "MOUSE?? MOUSE!!") self.assertEqual(user.username, "mouse@example.com") self.assertEqual(user.localname, "mouse") + self.assertTrue(user.discoverable) def test_handle_update_edition(self): """ update an existing edition """ diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 4aced6fe..76622799 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -96,6 +96,7 @@ urlpatterns = [ path("", views.Home.as_view(), name="landing"), re_path(r"^discover/?$", views.Discover.as_view()), re_path(r"^notifications/?$", views.Notifications.as_view()), + re_path(r"^directory/?", views.Directory.as_view(), name="directory"), # feeds re_path(r"^(?Phome|local|federated)/?$", views.Feed.as_view()), re_path( diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index 3402e65f..f1ebfc4c 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -4,6 +4,7 @@ from .author import Author, EditAuthor from .block import Block, unblock from .books import Book, EditBook, ConfirmEditBook, Editions from .books import upload_cover, add_description, switch_edition, resolve_book +from .directory import Directory from .error import not_found_page, server_error_page from .federation import Federation from .feed import DirectMessage, Feed, Replies, Status diff --git a/bookwyrm/views/directory.py b/bookwyrm/views/directory.py new file mode 100644 index 00000000..cc21baf2 --- /dev/null +++ b/bookwyrm/views/directory.py @@ -0,0 +1,32 @@ +""" who all's here? """ +from django.contrib.auth.decorators import login_required +from django.core.paginator import Paginator +from django.template.response import TemplateResponse +from django.views import View +from django.utils.decorators import method_decorator + +from bookwyrm import models + +# pylint: disable=no-self-use +@method_decorator(login_required, name="dispatch") +class Directory(View): + """ display of known bookwyrm users """ + + def get(self, request): + """ lets see your cute faces """ + try: + page = int(request.GET.get("page", 1)) + except ValueError: + page = 1 + + users = models.User.objects.filter( + discoverable=True, + bookwyrm_user=True, + is_active=True, + ).order_by("-last_active_date") + paginated = Paginator(users, 12) + + data = { + "users": paginated.page(page), + } + return TemplateResponse(request, "directory.html", data) diff --git a/bookwyrm/views/landing.py b/bookwyrm/views/landing.py index 86f7d3e9..407451fb 100644 --- a/bookwyrm/views/landing.py +++ b/bookwyrm/views/landing.py @@ -2,7 +2,7 @@ from django.template.response import TemplateResponse from django.views import View -from bookwyrm import forms, models +from bookwyrm import forms from .feed import Feed from . import helpers