forked from mirrors/bookwyrm
Removes outgoing and view_actions
This commit is contained in:
parent
a385aa4cb5
commit
3e5ed19643
8 changed files with 199 additions and 169 deletions
|
@ -2,10 +2,11 @@
|
|||
import csv
|
||||
import logging
|
||||
|
||||
from bookwyrm import outgoing
|
||||
from bookwyrm.tasks import app
|
||||
from bookwyrm import models
|
||||
from bookwyrm.broadcast import broadcast
|
||||
from bookwyrm.models import ImportJob, ImportItem
|
||||
from bookwyrm.status import create_notification
|
||||
from bookwyrm.tasks import app
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -62,7 +63,7 @@ def import_data(job_id):
|
|||
item.save()
|
||||
|
||||
# shelves book and handles reviews
|
||||
outgoing.handle_imported_book(
|
||||
handle_imported_book(
|
||||
job.user, item, job.include_reviews, job.privacy)
|
||||
else:
|
||||
item.fail_reason = 'Could not find a match for book'
|
||||
|
@ -71,3 +72,57 @@ def import_data(job_id):
|
|||
create_notification(job.user, 'IMPORT', related_import=job)
|
||||
job.complete = True
|
||||
job.save()
|
||||
|
||||
|
||||
def handle_imported_book(user, item, include_reviews, privacy):
|
||||
''' process a goodreads csv and then post about it '''
|
||||
if isinstance(item.book, models.Work):
|
||||
item.book = item.book.default_edition
|
||||
if not item.book:
|
||||
return
|
||||
|
||||
existing_shelf = models.ShelfBook.objects.filter(
|
||||
book=item.book, added_by=user).exists()
|
||||
|
||||
# shelve the book if it hasn't been shelved already
|
||||
if item.shelf and not existing_shelf:
|
||||
desired_shelf = models.Shelf.objects.get(
|
||||
identifier=item.shelf,
|
||||
user=user
|
||||
)
|
||||
shelf_book = models.ShelfBook.objects.create(
|
||||
book=item.book, shelf=desired_shelf, added_by=user)
|
||||
broadcast(user, shelf_book.to_add_activity(user), privacy=privacy)
|
||||
|
||||
for read in item.reads:
|
||||
# check for an existing readthrough with the same dates
|
||||
if models.ReadThrough.objects.filter(
|
||||
user=user, book=item.book,
|
||||
start_date=read.start_date,
|
||||
finish_date=read.finish_date
|
||||
).exists():
|
||||
continue
|
||||
read.book = item.book
|
||||
read.user = user
|
||||
read.save()
|
||||
|
||||
if include_reviews and (item.rating or item.review):
|
||||
review_title = 'Review of {!r} on Goodreads'.format(
|
||||
item.book.title,
|
||||
) if item.review else ''
|
||||
|
||||
# we don't know the publication date of the review,
|
||||
# but "now" is a bad guess
|
||||
published_date_guess = item.date_read or item.date_added
|
||||
review = models.Review.objects.create(
|
||||
user=user,
|
||||
book=item.book,
|
||||
name=review_title,
|
||||
content=item.review,
|
||||
rating=item.rating,
|
||||
published_date=published_date_guess,
|
||||
privacy=privacy,
|
||||
)
|
||||
# we don't need to send out pure activities because non-bookwyrm
|
||||
# instances don't need this data
|
||||
broadcast(user, review.to_create_activity(user), privacy=privacy)
|
||||
|
|
|
@ -9,7 +9,7 @@ from django.views.decorators.csrf import csrf_exempt
|
|||
from django.views.decorators.http import require_POST
|
||||
import requests
|
||||
|
||||
from bookwyrm import activitypub, models, outgoing
|
||||
from bookwyrm import activitypub, models, views
|
||||
from bookwyrm import status as status_builder
|
||||
from bookwyrm.tasks import app
|
||||
from bookwyrm.signatures import Signature
|
||||
|
@ -133,7 +133,7 @@ def handle_follow(activity):
|
|||
related_user=relationship.user_subject
|
||||
)
|
||||
if not manually_approves:
|
||||
outgoing.handle_accept(relationship)
|
||||
views.handle_accept(relationship)
|
||||
|
||||
|
||||
@app.task
|
||||
|
|
|
@ -1,161 +0,0 @@
|
|||
''' handles all the activity coming out of the server '''
|
||||
from django.db import transaction
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.decorators.http import require_GET
|
||||
from requests import HTTPError
|
||||
|
||||
from bookwyrm import activitypub
|
||||
from bookwyrm import models
|
||||
from bookwyrm.connectors import get_data, ConnectorException
|
||||
from bookwyrm.broadcast import broadcast
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@require_GET
|
||||
def outbox(request, username):
|
||||
''' outbox for the requested user '''
|
||||
user = get_object_or_404(models.User, localname=username)
|
||||
filter_type = request.GET.get('type')
|
||||
if filter_type not in models.status_models:
|
||||
filter_type = None
|
||||
|
||||
return JsonResponse(
|
||||
user.to_outbox(**request.GET, filter_type=filter_type),
|
||||
encoder=activitypub.ActivityEncoder
|
||||
)
|
||||
|
||||
|
||||
def handle_remote_webfinger(query):
|
||||
''' webfingerin' other servers '''
|
||||
user = None
|
||||
|
||||
# usernames could be @user@domain or user@domain
|
||||
if not query:
|
||||
return None
|
||||
|
||||
if query[0] == '@':
|
||||
query = query[1:]
|
||||
|
||||
try:
|
||||
domain = query.split('@')[1]
|
||||
except IndexError:
|
||||
return None
|
||||
|
||||
try:
|
||||
user = models.User.objects.get(username=query)
|
||||
except models.User.DoesNotExist:
|
||||
url = 'https://%s/.well-known/webfinger?resource=acct:%s' % \
|
||||
(domain, query)
|
||||
try:
|
||||
data = get_data(url)
|
||||
except (ConnectorException, HTTPError):
|
||||
return None
|
||||
|
||||
for link in data.get('links'):
|
||||
if link.get('rel') == 'self':
|
||||
try:
|
||||
user = activitypub.resolve_remote_id(
|
||||
models.User, link['href']
|
||||
)
|
||||
except KeyError:
|
||||
return None
|
||||
return user
|
||||
|
||||
|
||||
def handle_follow(user, to_follow):
|
||||
''' someone local wants to follow someone '''
|
||||
relationship, _ = models.UserFollowRequest.objects.get_or_create(
|
||||
user_subject=user,
|
||||
user_object=to_follow,
|
||||
)
|
||||
activity = relationship.to_activity()
|
||||
broadcast(user, activity, privacy='direct', direct_recipients=[to_follow])
|
||||
|
||||
|
||||
def handle_unfollow(user, to_unfollow):
|
||||
''' someone local wants to follow someone '''
|
||||
relationship = models.UserFollows.objects.get(
|
||||
user_subject=user,
|
||||
user_object=to_unfollow
|
||||
)
|
||||
activity = relationship.to_undo_activity(user)
|
||||
broadcast(user, activity, privacy='direct', direct_recipients=[to_unfollow])
|
||||
to_unfollow.followers.remove(user)
|
||||
|
||||
|
||||
def handle_accept(follow_request):
|
||||
''' send an acceptance message to a follow request '''
|
||||
user = follow_request.user_subject
|
||||
to_follow = follow_request.user_object
|
||||
with transaction.atomic():
|
||||
relationship = models.UserFollows.from_request(follow_request)
|
||||
follow_request.delete()
|
||||
relationship.save()
|
||||
|
||||
activity = relationship.to_accept_activity()
|
||||
broadcast(to_follow, activity, privacy='direct', direct_recipients=[user])
|
||||
|
||||
|
||||
def handle_reject(follow_request):
|
||||
''' a local user who managed follows rejects a follow request '''
|
||||
user = follow_request.user_subject
|
||||
to_follow = follow_request.user_object
|
||||
activity = follow_request.to_reject_activity()
|
||||
follow_request.delete()
|
||||
broadcast(to_follow, activity, privacy='direct', direct_recipients=[user])
|
||||
|
||||
|
||||
def handle_imported_book(user, item, include_reviews, privacy):
|
||||
''' process a goodreads csv and then post about it '''
|
||||
if isinstance(item.book, models.Work):
|
||||
item.book = item.book.default_edition
|
||||
if not item.book:
|
||||
return
|
||||
|
||||
existing_shelf = models.ShelfBook.objects.filter(
|
||||
book=item.book, added_by=user).exists()
|
||||
|
||||
# shelve the book if it hasn't been shelved already
|
||||
if item.shelf and not existing_shelf:
|
||||
desired_shelf = models.Shelf.objects.get(
|
||||
identifier=item.shelf,
|
||||
user=user
|
||||
)
|
||||
shelf_book = models.ShelfBook.objects.create(
|
||||
book=item.book, shelf=desired_shelf, added_by=user)
|
||||
broadcast(user, shelf_book.to_add_activity(user), privacy=privacy)
|
||||
|
||||
for read in item.reads:
|
||||
# check for an existing readthrough with the same dates
|
||||
if models.ReadThrough.objects.filter(
|
||||
user=user, book=item.book,
|
||||
start_date=read.start_date,
|
||||
finish_date=read.finish_date
|
||||
).exists():
|
||||
continue
|
||||
read.book = item.book
|
||||
read.user = user
|
||||
read.save()
|
||||
|
||||
if include_reviews and (item.rating or item.review):
|
||||
review_title = 'Review of {!r} on Goodreads'.format(
|
||||
item.book.title,
|
||||
) if item.review else ''
|
||||
|
||||
# we don't know the publication date of the review,
|
||||
# but "now" is a bad guess
|
||||
published_date_guess = item.date_read or item.date_added
|
||||
review = models.Review.objects.create(
|
||||
user=user,
|
||||
book=item.book,
|
||||
name=review_title,
|
||||
content=item.review,
|
||||
rating=item.rating,
|
||||
published_date=published_date_guess,
|
||||
privacy=privacy,
|
||||
)
|
||||
# we don't need to send out pure activities because non-bookwyrm
|
||||
# instances don't need this data
|
||||
broadcast(user, review.to_create_activity(user), privacy=privacy)
|
|
@ -3,7 +3,7 @@ from django.conf.urls.static import static
|
|||
from django.contrib import admin
|
||||
from django.urls import path, re_path
|
||||
|
||||
from bookwyrm import incoming, outgoing, settings, views, wellknown
|
||||
from bookwyrm import incoming, settings, views, wellknown
|
||||
from bookwyrm.utils import regex
|
||||
|
||||
user_path = r'^user/(?P<username>%s)' % regex.username
|
||||
|
@ -30,7 +30,7 @@ urlpatterns = [
|
|||
# federation endpoints
|
||||
re_path(r'^inbox/?$', incoming.shared_inbox),
|
||||
re_path(r'%s/inbox/?$' % local_user_path, incoming.inbox),
|
||||
re_path(r'%s/outbox/?$' % local_user_path, outgoing.outbox),
|
||||
re_path(r'%s/outbox/?$' % local_user_path, views.Outbox.as_view()),
|
||||
|
||||
# .well-known endpoints
|
||||
re_path(r'^.well-known/webfinger/?$', wellknown.webfinger),
|
||||
|
|
|
@ -6,12 +6,13 @@ from .books import upload_cover, add_description, switch_edition, resolve_book
|
|||
from .direct_message import DirectMessage
|
||||
from .error import not_found_page, server_error_page
|
||||
from .follow import follow, unfollow
|
||||
from .follow import accept_follow_request, delete_follow_request
|
||||
from .follow import accept_follow_request, delete_follow_request, handle_accept
|
||||
from .import_data import Import, ImportStatus
|
||||
from .interaction import Favorite, Unfavorite, Boost, Unboost
|
||||
from .invite import ManageInvites, Invite
|
||||
from .landing import About, Home, Feed, Discover
|
||||
from .notifications import Notifications
|
||||
from .outbox import Outbox
|
||||
from .reading import edit_readthrough, create_readthrough, delete_readthrough
|
||||
from .reading import start_reading, finish_reading
|
||||
from .password import PasswordResetRequest, PasswordReset, ChangePassword
|
||||
|
|
113
bookwyrm/views/follow.py
Normal file
113
bookwyrm/views/follow.py
Normal file
|
@ -0,0 +1,113 @@
|
|||
''' views for actions you can take in the application '''
|
||||
from django.db import transaction
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.http import HttpResponseBadRequest
|
||||
from django.shortcuts import redirect
|
||||
from django.views.decorators.http import require_POST
|
||||
|
||||
from bookwyrm import models
|
||||
from bookwyrm.broadcast import broadcast
|
||||
from .helpers import get_user_from_username
|
||||
|
||||
@login_required
|
||||
@require_POST
|
||||
def follow(request):
|
||||
''' follow another user, here or abroad '''
|
||||
username = request.POST['user']
|
||||
try:
|
||||
to_follow = get_user_from_username(username)
|
||||
except models.User.DoesNotExist:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
relationship, _ = models.UserFollowRequest.objects.get_or_create(
|
||||
user_subject=request.user,
|
||||
user_object=to_follow,
|
||||
)
|
||||
activity = relationship.to_activity()
|
||||
broadcast(
|
||||
request.user, activity, privacy='direct', direct_recipients=[to_follow])
|
||||
return redirect(to_follow.local_path)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_POST
|
||||
def unfollow(request):
|
||||
''' unfollow a user '''
|
||||
username = request.POST['user']
|
||||
try:
|
||||
to_unfollow = get_user_from_username(username)
|
||||
except models.User.DoesNotExist:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
relationship = models.UserFollows.objects.get(
|
||||
user_subject=request.user,
|
||||
user_object=to_unfollow
|
||||
)
|
||||
activity = relationship.to_undo_activity(request.user)
|
||||
broadcast(
|
||||
request.user, activity,
|
||||
privacy='direct', direct_recipients=[to_unfollow])
|
||||
|
||||
to_unfollow.followers.remove(request.user)
|
||||
return redirect(to_unfollow.local_path)
|
||||
|
||||
|
||||
@login_required
|
||||
@require_POST
|
||||
def accept_follow_request(request):
|
||||
''' a user accepts a follow request '''
|
||||
username = request.POST['user']
|
||||
try:
|
||||
requester = get_user_from_username(username)
|
||||
except models.User.DoesNotExist:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
try:
|
||||
follow_request = models.UserFollowRequest.objects.get(
|
||||
user_subject=requester,
|
||||
user_object=request.user
|
||||
)
|
||||
except models.UserFollowRequest.DoesNotExist:
|
||||
# Request already dealt with.
|
||||
return redirect(request.user.local_path)
|
||||
handle_accept(follow_request)
|
||||
|
||||
return redirect(request.user.local_path)
|
||||
|
||||
|
||||
def handle_accept(follow_request):
|
||||
''' send an acceptance message to a follow request '''
|
||||
user = follow_request.user_subject
|
||||
to_follow = follow_request.user_object
|
||||
with transaction.atomic():
|
||||
relationship = models.UserFollows.from_request(follow_request)
|
||||
follow_request.delete()
|
||||
relationship.save()
|
||||
|
||||
activity = relationship.to_accept_activity()
|
||||
broadcast(to_follow, activity, privacy='direct', direct_recipients=[user])
|
||||
|
||||
|
||||
@login_required
|
||||
@require_POST
|
||||
def delete_follow_request(request):
|
||||
''' a user rejects a follow request '''
|
||||
username = request.POST['user']
|
||||
try:
|
||||
requester = get_user_from_username(username)
|
||||
except models.User.DoesNotExist:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
try:
|
||||
follow_request = models.UserFollowRequest.objects.get(
|
||||
user_subject=requester,
|
||||
user_object=request.user
|
||||
)
|
||||
except models.UserFollowRequest.DoesNotExist:
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
activity = follow_request.to_reject_activity()
|
||||
follow_request.delete()
|
||||
broadcast(
|
||||
request.user, activity, privacy='direct', direct_recipients=[requester])
|
||||
return redirect('/user/%s' % request.user.localname)
|
22
bookwyrm/views/outbox.py
Normal file
22
bookwyrm/views/outbox.py
Normal file
|
@ -0,0 +1,22 @@
|
|||
''' the good stuff! the books! '''
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.views import View
|
||||
|
||||
from bookwyrm import activitypub, models
|
||||
|
||||
|
||||
# pylint: disable= no-self-use
|
||||
class Outbox(View):
|
||||
''' outbox '''
|
||||
def get(self, request, username):
|
||||
''' outbox for the requested user '''
|
||||
user = get_object_or_404(models.User, localname=username)
|
||||
filter_type = request.GET.get('type')
|
||||
if filter_type not in models.status_models:
|
||||
filter_type = None
|
||||
|
||||
return JsonResponse(
|
||||
user.to_outbox(**request.GET, filter_type=filter_type),
|
||||
encoder=activitypub.ActivityEncoder
|
||||
)
|
Loading…
Reference in a new issue