diff --git a/bookwyrm/templates/notifications.html b/bookwyrm/templates/notifications.html
index ae026a9f..faa91cc5 100644
--- a/bookwyrm/templates/notifications.html
+++ b/bookwyrm/templates/notifications.html
@@ -5,7 +5,7 @@
Notifications
-
diff --git a/bookwyrm/tests/test_views.py b/bookwyrm/tests/test_views.py
index 9729b0f1..49429c3d 100644
--- a/bookwyrm/tests/test_views.py
+++ b/bookwyrm/tests/test_views.py
@@ -75,26 +75,6 @@ class Views(TestCase):
self.assertFalse(views.is_api_request(request))
- def test_home_tab(self):
- ''' there are so many views, this just makes sure it LOADS '''
- request = self.factory.get('')
- request.user = self.local_user
- result = views.home_tab(request, 'local')
- self.assertIsInstance(result, TemplateResponse)
- self.assertEqual(result.template_name, 'feed.html')
- self.assertEqual(result.status_code, 200)
-
-
- def test_direct_messages_page(self):
- ''' there are so many views, this just makes sure it LOADS '''
- request = self.factory.get('')
- request.user = self.local_user
- result = views.direct_messages_page(request)
- self.assertIsInstance(result, TemplateResponse)
- self.assertEqual(result.template_name, 'direct_messages.html')
- self.assertEqual(result.status_code, 200)
-
-
def test_get_activity_feed(self):
''' loads statuses '''
rat = models.User.objects.create_user(
@@ -264,26 +244,6 @@ class Views(TestCase):
self.assertEqual(result.status_code, 200)
- def test_about_page(self):
- ''' there are so many views, this just makes sure it LOADS '''
- request = self.factory.get('')
- request.user = self.local_user
- result = views.about_page(request)
- self.assertIsInstance(result, TemplateResponse)
- self.assertEqual(result.template_name, 'about.html')
- self.assertEqual(result.status_code, 200)
-
-
- def test_notifications_page(self):
- ''' there are so many views, this just makes sure it LOADS '''
- request = self.factory.get('')
- request.user = self.local_user
- result = views.notifications_page(request)
- self.assertIsInstance(result, TemplateResponse)
- self.assertEqual(result.template_name, 'notifications.html')
- self.assertEqual(result.status_code, 200)
-
-
def test_user_page(self):
''' there are so many views, this just makes sure it LOADS '''
request = self.factory.get('')
diff --git a/bookwyrm/tests/views/test_direct_message.py b/bookwyrm/tests/views/test_direct_message.py
new file mode 100644
index 00000000..5c0bdcbf
--- /dev/null
+++ b/bookwyrm/tests/views/test_direct_message.py
@@ -0,0 +1,28 @@
+''' 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 DirectMessageViews(TestCase):
+ ''' dms '''
+ 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_direct_messages_page(self):
+ ''' there are so many views, this just makes sure it LOADS '''
+ view = views.DirectMessages.as_view()
+ request = self.factory.get('')
+ request.user = self.local_user
+ result = view(request)
+ self.assertIsInstance(result, TemplateResponse)
+ self.assertEqual(result.template_name, 'direct_messages.html')
+ self.assertEqual(result.status_code, 200)
diff --git a/bookwyrm/tests/views/test_notifications.py b/bookwyrm/tests/views/test_notifications.py
new file mode 100644
index 00000000..683424d5
--- /dev/null
+++ b/bookwyrm/tests/views/test_notifications.py
@@ -0,0 +1,41 @@
+''' 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 NotificationViews(TestCase):
+ ''' notifications '''
+ 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_notifications_page(self):
+ ''' there are so many views, this just makes sure it LOADS '''
+ view = views.Notifications.as_view()
+ request = self.factory.get('')
+ request.user = self.local_user
+ result = view(request)
+ self.assertIsInstance(result, TemplateResponse)
+ self.assertEqual(result.template_name, 'notifications.html')
+ self.assertEqual(result.status_code, 200)
+
+ def test_clear_notifications(self):
+ ''' erase notifications '''
+ models.Notification.objects.create(
+ user=self.local_user, notification_type='MENTION')
+ models.Notification.objects.create(
+ user=self.local_user, notification_type='MENTION', read=True)
+ self.assertEqual(models.Notification.objects.count(), 2)
+ view = views.Notifications.as_view()
+ request = self.factory.post('')
+ request.user = self.local_user
+ result = view(request)
+ self.assertEqual(result.status_code, 302)
+ self.assertEqual(models.Notification.objects.count(), 1)
diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py
index c1741397..46dd3f0f 100644
--- a/bookwyrm/urls.py
+++ b/bookwyrm/urls.py
@@ -61,11 +61,16 @@ urlpatterns = [
re_path(r'^(?Phome|local|federated)/?$', views.Feed.as_view()),
re_path(r'^discover/?$', views.Discover.as_view()),
- re_path(r'^notifications/?$', vviews.notifications_page),
- re_path(r'^direct-messages/?$', vviews.direct_messages_page),
+ re_path(r'^notifications/?$', views.Notifications.as_view()),
- re_path(r'^import/?$', vviews.import_page),
+ re_path(r'^direct-messages/?$', views.DirectMessage.as_view()),
+
+ re_path(r'^import/?$', views.Import.as_view()),
+ re_path(r'^import/?$', actions.import_data),
+ re_path(r'^retry-import/?$', actions.retry_import),
re_path(r'^import-status/(\d+)/?$', vviews.import_status),
+
+
re_path(r'^user-edit/?$', vviews.edit_profile_page),
# should return a ui view or activitypub json blob as requested
@@ -101,8 +106,6 @@ urlpatterns = [
# internal action endpoints
re_path(r'^edit-profile/?$', actions.edit_profile),
- re_path(r'^import-data/?$', actions.import_data),
- re_path(r'^retry-import/?$', actions.retry_import),
re_path(r'^resolve-book/?$', actions.resolve_book),
re_path(r'^edit-book/(?P\d+)/?$', actions.edit_book),
re_path(r'^upload-cover/(?P\d+)/?$', actions.upload_cover),
@@ -142,7 +145,6 @@ urlpatterns = [
re_path(r'^accept-follow-request/?$', actions.accept_follow_request),
re_path(r'^delete-follow-request/?$', actions.delete_follow_request),
- re_path(r'^clear-notifications/?$', actions.clear_notifications),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
diff --git a/bookwyrm/view_actions.py b/bookwyrm/view_actions.py
index 8af68e06..0db08ab7 100644
--- a/bookwyrm/view_actions.py
+++ b/bookwyrm/view_actions.py
@@ -559,13 +559,6 @@ def unfollow(request):
return redirect('/user/%s' % user_slug)
-@login_required
-def clear_notifications(request):
- ''' permanently delete notification for user '''
- request.user.notification_set.filter(read=True).delete()
- return redirect('/notifications')
-
-
@login_required
@require_POST
def accept_follow_request(request):
diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py
index 03a589dc..0173f565 100644
--- a/bookwyrm/views/__init__.py
+++ b/bookwyrm/views/__init__.py
@@ -3,3 +3,6 @@ from .authentication import Login, Register, Logout
from .password import PasswordResetRequest, PasswordReset, ChangePassword
from .invite import ManageInvites, Invite
from .landing import About, Home, Feed, Discover
+from .notifications import Notifications
+from .direct_message import DirectMessage
+from .import_datra import Import
diff --git a/bookwyrm/views/direct_message.py b/bookwyrm/views/direct_message.py
new file mode 100644
index 00000000..feb0c19a
--- /dev/null
+++ b/bookwyrm/views/direct_message.py
@@ -0,0 +1,36 @@
+''' non-interactive pages '''
+from django.contrib.auth.decorators import login_required
+from django.core.paginator import Paginator
+from django.template.response import TemplateResponse
+from django.utils.decorators import method_decorator
+from django.views import View
+
+from bookwyrm.settings import PAGE_LENGTH
+from .helpers import get_activity_feed
+
+
+# pylint: disable= no-self-use
+@method_decorator(login_required, name='dispatch')
+class DirectMessage(View):
+ ''' dm view '''
+ def get(self, request, page=1):
+ ''' like a feed but for dms only '''
+ activities = get_activity_feed(request.user, 'direct')
+ paginated = Paginator(activities, PAGE_LENGTH)
+ activity_page = paginated.page(page)
+
+ prev_page = next_page = None
+ if activity_page.has_next():
+ next_page = '/direct-message/?page=%d#feed' % \
+ activity_page.next_page_number()
+ if activity_page.has_previous():
+ prev_page = '/direct-messages/?page=%d#feed' % \
+ activity_page.previous_page_number()
+ data = {
+ 'title': 'Direct Messages',
+ 'user': request.user,
+ 'activities': activity_page.object_list,
+ 'next': next_page,
+ 'prev': prev_page,
+ }
+ return TemplateResponse(request, 'direct_messages.html', data)
diff --git a/bookwyrm/views/notifications.py b/bookwyrm/views/notifications.py
new file mode 100644
index 00000000..7d6a3149
--- /dev/null
+++ b/bookwyrm/views/notifications.py
@@ -0,0 +1,29 @@
+''' non-interactive pages '''
+from django.contrib.auth.decorators import login_required
+from django.template.response import TemplateResponse
+from django.utils.decorators import method_decorator
+from django.shortcuts import redirect
+from django.views import View
+
+
+# pylint: disable= no-self-use
+@method_decorator(login_required, name='dispatch')
+class Notifications(View):
+ ''' notifications view '''
+ def get(self, request):
+ ''' people are interacting with you, get hyped '''
+ notifications = request.user.notification_set.all() \
+ .order_by('-created_date')
+ unread = [n.id for n in notifications.filter(read=False)]
+ data = {
+ 'title': 'Notifications',
+ 'notifications': notifications,
+ 'unread': unread,
+ }
+ notifications.update(read=True)
+ return TemplateResponse(request, 'notifications.html', data)
+
+ def post(self, request):
+ ''' permanently delete notification for user '''
+ request.user.notification_set.filter(read=True).delete()
+ return redirect('/notifications')
diff --git a/bookwyrm/vviews.py b/bookwyrm/vviews.py
index 0b839561..d7e8c913 100644
--- a/bookwyrm/vviews.py
+++ b/bookwyrm/vviews.py
@@ -64,31 +64,6 @@ def not_found_page(request, _):
request, 'notfound.html', {'title': 'Not found'}, status=404)
-@login_required
-@require_GET
-def direct_messages_page(request, page=1):
- ''' like a feed but for dms only '''
- activities = get_activity_feed(request.user, 'direct')
- paginated = Paginator(activities, PAGE_LENGTH)
- activity_page = paginated.page(page)
-
- prev_page = next_page = None
- if activity_page.has_next():
- next_page = '/direct-message/?page=%d#feed' % \
- activity_page.next_page_number()
- if activity_page.has_previous():
- prev_page = '/direct-messages/?page=%d#feed' % \
- activity_page.previous_page_number()
- data = {
- 'title': 'Direct Messages',
- 'user': request.user,
- 'activities': activity_page.object_list,
- 'next': next_page,
- 'prev': prev_page,
- }
- return TemplateResponse(request, 'direct_messages.html', data)
-
-
def get_activity_feed(
user, privacy, local_only=False, following_only=False,
queryset=models.Status.objects):
@@ -216,22 +191,6 @@ def import_status(request, job_id):
})
-@login_required
-@require_GET
-def notifications_page(request):
- ''' list notitications '''
- notifications = request.user.notification_set.all() \
- .order_by('-created_date')
- unread = [n.id for n in notifications.filter(read=False)]
- data = {
- 'title': 'Notifications',
- 'notifications': notifications,
- 'unread': unread,
- }
- notifications.update(read=True)
- return TemplateResponse(request, 'notifications.html', data)
-
-
@csrf_exempt
@require_GET
def user_page(request, username):