diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py index e92bc1802..c82127945 100644 --- a/bookwyrm/forms.py +++ b/bookwyrm/forms.py @@ -195,7 +195,14 @@ class ShelfForm(CustomForm): model = models.Shelf fields = ['user', 'name', 'privacy'] + class GoalForm(CustomForm): class Meta: model = models.AnnualGoal fields = ['user', 'year', 'goal', 'privacy'] + + +class SiteForm(CustomForm): + class Meta: + model = models.SiteSettings + exclude = [] diff --git a/bookwyrm/templates/layout.html b/bookwyrm/templates/layout.html index a696e2877..817829706 100644 --- a/bookwyrm/templates/layout.html +++ b/bookwyrm/templates/layout.html @@ -90,13 +90,23 @@ Import books + {% if perms.bookwyrm.create_invites or perms.bookwyrm.edit_instance_settings%} + + {% endif %} {% if perms.bookwyrm.create_invites %}
  • - + Invites
  • {% endif %} + {% if perms.bookwyrm.edit_instance_settings %} +
  • + + Site Configuration + +
  • + {% endif %}
  • diff --git a/bookwyrm/templates/settings/admin_layout.html b/bookwyrm/templates/settings/admin_layout.html new file mode 100644 index 000000000..59cfd1d40 --- /dev/null +++ b/bookwyrm/templates/settings/admin_layout.html @@ -0,0 +1,46 @@ +{% extends 'layout.html' %} +{% block content %} + +
    +

    {% block header %}{% endblock %}

    +
    + +
    + +
    + {% block panel %}{% endblock %} +
    +
    + +{% endblock %} diff --git a/bookwyrm/templates/settings/federation.html b/bookwyrm/templates/settings/federation.html new file mode 100644 index 000000000..e3bf23ce0 --- /dev/null +++ b/bookwyrm/templates/settings/federation.html @@ -0,0 +1,21 @@ +{% extends 'settings/admin_layout.html' %} +{% block header %}Federated Servers{% endblock %} + +{% block panel %} + + + + + + + + {% for server in servers %} + + + + + + {% endfor %} +
    Server nameSoftwareStatus
    {{ server.server_name }}{{ server.application_type }} ({{ server.application_version }}){{ server.status }}
    + +{% endblock %} diff --git a/bookwyrm/templates/manage_invites.html b/bookwyrm/templates/settings/manage_invites.html similarity index 83% rename from bookwyrm/templates/manage_invites.html rename to bookwyrm/templates/settings/manage_invites.html index a29ee5e47..03b68b202 100644 --- a/bookwyrm/templates/manage_invites.html +++ b/bookwyrm/templates/settings/manage_invites.html @@ -1,8 +1,8 @@ -{% extends 'layout.html' %} +{% extends 'settings/admin_layout.html' %} +{% block header %}Invites{% endblock %} {% load humanize %} -{% block content %} -
    -

    Invites

    +{% block panel %} +
    @@ -22,12 +22,12 @@ {% endfor %}
    Link
    -
    + -
    +

    Generate New Invite

    -
    + {% csrf_token %}
    @@ -46,5 +46,5 @@ -
    +
    {% endblock %} diff --git a/bookwyrm/templates/settings/site.html b/bookwyrm/templates/settings/site.html new file mode 100644 index 000000000..d071facf5 --- /dev/null +++ b/bookwyrm/templates/settings/site.html @@ -0,0 +1,84 @@ +{% extends 'settings/admin_layout.html' %} +{% block header %}Site Configuration{% endblock %} + +{% block panel %} + +
    + {% csrf_token %} +
    +

    Instance Info

    +
    + + {{ site_form.name }} +
    +
    + + {{ site_form.instance_tagline }} +
    +
    + + {{ site_form.instance_description }} +
    +
    + + {{ site_form.code_of_conduct }} +
    +
    + + + +
    +

    Images

    +
    +
    + + {{ site_form.logo }} +
    +
    + + {{ site_form.logo_small }} +
    +
    + + {{ site_form.favicon }} +
    +
    +
    + + + + + + + +
    +

    Registration

    +
    +
    +
    + + {{ site_form.registration_closed_text }} +
    +
    + +
    + +
    +
    +{% endblock %} diff --git a/bookwyrm/tests/views/test_federation.py b/bookwyrm/tests/views/test_federation.py new file mode 100644 index 000000000..2a182a21d --- /dev/null +++ b/bookwyrm/tests/views/test_federation.py @@ -0,0 +1,29 @@ +''' 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 +from bookwyrm import views + + +class FederationViews(TestCase): + ''' every response to a get request, html or json ''' + 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.mouse', 'password', + local=True, localname='mouse') + + + def test_federation_page(self): + ''' there are so many views, this just makes sure it LOADS ''' + view = views.Federation.as_view() + request = self.factory.get('') + request.user = self.local_user + request.user.is_superuser = True + result = view(request) + self.assertIsInstance(result, TemplateResponse) + self.assertEqual(result.template_name, 'settings/federation.html') + self.assertEqual(result.status_code, 200) diff --git a/bookwyrm/tests/views/test_invite.py b/bookwyrm/tests/views/test_invite.py index 57b7a34ae..857416881 100644 --- a/bookwyrm/tests/views/test_invite.py +++ b/bookwyrm/tests/views/test_invite.py @@ -44,5 +44,5 @@ class InviteViews(TestCase): request.user.is_superuser = True result = view(request) self.assertIsInstance(result, TemplateResponse) - self.assertEqual(result.template_name, 'manage_invites.html') + self.assertEqual(result.template_name, 'settings/manage_invites.html') self.assertEqual(result.status_code, 200) diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 6d759ac21..6387a4cd5 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -49,8 +49,13 @@ urlpatterns = [ re_path(r'^password-reset/(?P[A-Za-z0-9]+)/?$', views.PasswordReset.as_view()), - # invites - re_path(r'^invite/?$', views.ManageInvites.as_view()), + # admin + re_path(r'^settings/site-settings', + views.Site.as_view(), name='settings-site'), + re_path(r'^settings/federation', + views.Federation.as_view(), name='settings-federation'), + re_path(r'^settings/invites/?$', + views.ManageInvites.as_view(), name='settings-invites'), re_path(r'^invite/(?P[A-Za-z0-9]+)/?$', views.Invite.as_view()), # landing pages diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index 80520eb38..0b93f1640 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -5,6 +5,7 @@ from .block import Block, unblock from .books import Book, EditBook, Editions from .books import upload_cover, add_description, switch_edition, resolve_book from .error import not_found_page, server_error_page +from .federation import Federation from .feed import DirectMessage, Feed, Replies, Status from .follow import follow, unfollow from .follow import accept_follow_request, delete_follow_request, handle_accept @@ -24,6 +25,7 @@ from .search import Search from .shelf import Shelf from .shelf import user_shelves_page, create_shelf, delete_shelf from .shelf import shelve, unshelve +from .site import Site from .status import CreateStatus, DeleteStatus from .updates import Updates from .user import User, EditUser, Followers, Following diff --git a/bookwyrm/views/federation.py b/bookwyrm/views/federation.py new file mode 100644 index 000000000..0bd14dab3 --- /dev/null +++ b/bookwyrm/views/federation.py @@ -0,0 +1,24 @@ +''' manage federated servers ''' +from django.contrib.auth.decorators import login_required, permission_required +from django.template.response import TemplateResponse +from django.utils.decorators import method_decorator +from django.views import View + +from bookwyrm import models + + +# pylint: disable= no-self-use +@method_decorator(login_required, name='dispatch') +@method_decorator( + permission_required('bookwyrm.control_federation', raise_exception=True), + name='dispatch') +class Federation(View): + ''' what servers do we federate with ''' + def get(self, request): + ''' edit form ''' + servers = models.FederatedServer.objects.all() + data = { + 'title': 'Federated Servers', + 'servers': servers + } + return TemplateResponse(request, 'settings/federation.html', data) diff --git a/bookwyrm/views/invite.py b/bookwyrm/views/invite.py index 564858616..bd0715a0b 100644 --- a/bookwyrm/views/invite.py +++ b/bookwyrm/views/invite.py @@ -24,7 +24,7 @@ class ManageInvites(View): user=request.user).order_by('-created_date'), 'form': forms.CreateInviteForm(), } - return TemplateResponse(request, 'manage_invites.html', data) + return TemplateResponse(request, 'settings/manage_invites.html', data) def post(self, request): ''' creates an invite database entry ''' @@ -36,7 +36,7 @@ class ManageInvites(View): invite.user = request.user invite.save() - return redirect('/invite') + return redirect('/settings/invites') class Invite(View): diff --git a/bookwyrm/views/site.py b/bookwyrm/views/site.py new file mode 100644 index 000000000..0a5e270b9 --- /dev/null +++ b/bookwyrm/views/site.py @@ -0,0 +1,40 @@ +''' manage site settings ''' +from django.contrib.auth.decorators import login_required, permission_required +from django.shortcuts import redirect +from django.template.response import TemplateResponse +from django.utils.decorators import method_decorator +from django.views import View + +from bookwyrm import forms, models + + +# pylint: disable= no-self-use +@method_decorator(login_required, name='dispatch') +@method_decorator( + permission_required( + 'bookwyrm.edit_instance_settings', raise_exception=True), + name='dispatch') +class Site(View): + ''' manage things like the instance name ''' + def get(self, request): + ''' edit form ''' + site = models.SiteSettings.objects.get() + data = { + 'title': 'Site Settings', + 'site_form': forms.SiteForm(instance=site) + } + return TemplateResponse(request, 'settings/site.html', data) + + def post(self, request): + ''' edit the site settings ''' + site = models.SiteSettings.objects.get() + form = forms.SiteForm(request.POST, instance=site) + if not form.is_valid(): + data = { + 'title': 'Site Settings', + 'site_form': form + } + return TemplateResponse(request, 'settings/site.html', data) + form.save() + + return redirect('settings-site')