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 %}
+
+
+
+
+
+ {% 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 %}
-
+
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