mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-24 00:50:35 +00:00
Merge branch 'main' into production
This commit is contained in:
commit
7dd1deb438
12 changed files with 78 additions and 25 deletions
|
@ -44,10 +44,9 @@ class ActivityObject:
|
|||
type: str
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
''' this lets you pass in an object with fields
|
||||
that aren't in the dataclass, which it ignores.
|
||||
Any field in the dataclass is required or has a
|
||||
default value '''
|
||||
''' this lets you pass in an object with fields that aren't in the
|
||||
dataclass, which it ignores. Any field in the dataclass is required or
|
||||
has a default value '''
|
||||
for field in fields(self):
|
||||
try:
|
||||
value = kwargs[field.name]
|
||||
|
@ -59,7 +58,7 @@ class ActivityObject:
|
|||
|
||||
|
||||
def to_model(self, model, instance=None):
|
||||
''' convert from an activity to a model '''
|
||||
''' convert from an activity to a model instance '''
|
||||
if not isinstance(self, model.activity_serializer):
|
||||
raise TypeError('Wrong activity type for model')
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ class Work(Book):
|
|||
type: str = 'Work'
|
||||
|
||||
|
||||
|
||||
@dataclass(init=False)
|
||||
class Author(ActivityObject):
|
||||
''' author of a book '''
|
||||
|
|
|
@ -6,6 +6,7 @@ from .base_activity import ActivityObject, Image
|
|||
|
||||
@dataclass(init=False)
|
||||
class Tombstone(ActivityObject):
|
||||
''' the placeholder for a deleted status '''
|
||||
url: str
|
||||
published: str
|
||||
deleted: str
|
||||
|
@ -23,7 +24,6 @@ class Note(ActivityObject):
|
|||
cc: List[str]
|
||||
content: str
|
||||
replies: Dict
|
||||
# TODO: this is wrong???
|
||||
attachment: List[Image] = field(default=lambda: [])
|
||||
sensitive: bool = False
|
||||
type: str = 'Note'
|
||||
|
|
|
@ -13,7 +13,6 @@ def get_public_recipients(user, software=None):
|
|||
''' everybody and their public inboxes '''
|
||||
followers = user.followers.filter(local=False)
|
||||
if software:
|
||||
# TODO: eventually we may want to handle particular software differently
|
||||
followers = followers.filter(bookwyrm_user=(software == 'bookwyrm'))
|
||||
|
||||
# we want shared inboxes when available
|
||||
|
@ -36,7 +35,6 @@ def broadcast(sender, activity, software=None, \
|
|||
# start with parsing the direct recipients
|
||||
recipients = [u.inbox for u in direct_recipients or []]
|
||||
# and then add any other recipients
|
||||
# TODO: other kinds of privacy
|
||||
if privacy == 'public':
|
||||
recipients += get_public_recipients(sender, software=software)
|
||||
broadcast_task.delay(
|
||||
|
@ -55,7 +53,6 @@ def broadcast_task(sender_id, activity, recipients):
|
|||
try:
|
||||
sign_and_send(sender, activity, recipient)
|
||||
except requests.exceptions.HTTPError as e:
|
||||
# TODO: maybe keep track of users who cause errors
|
||||
errors.append({
|
||||
'error': str(e),
|
||||
'recipient': recipient,
|
||||
|
|
|
@ -6,7 +6,6 @@ from bookwyrm.tasks import app
|
|||
|
||||
def password_reset_email(reset_code):
|
||||
''' generate a password reset email '''
|
||||
# TODO; this should be tempalted
|
||||
site = models.SiteSettings.get()
|
||||
send_email.delay(
|
||||
reset_code.user.email,
|
||||
|
|
|
@ -68,7 +68,7 @@ def shared_inbox(request):
|
|||
'Like': handle_unfavorite,
|
||||
},
|
||||
'Update': {
|
||||
'Person': None,# TODO: handle_update_user
|
||||
'Person': handle_update_user,
|
||||
'Document': handle_update_book,
|
||||
},
|
||||
}
|
||||
|
@ -308,6 +308,20 @@ def handle_tag(activity):
|
|||
status_builder.create_tag(user, book, activity['object']['name'])
|
||||
|
||||
|
||||
@app.task
|
||||
def handle_update_user(activity):
|
||||
''' receive an updated user Person activity object '''
|
||||
try:
|
||||
user = models.User.objects.get(remote_id=activity['object']['id'])
|
||||
except models.User.DoesNotExist:
|
||||
# who is this person? who cares
|
||||
return
|
||||
activitypub.Person(
|
||||
**activity['object']
|
||||
).to_model(models.User, instance=user)
|
||||
# model save() happens in the to_model function
|
||||
|
||||
|
||||
@app.task
|
||||
def handle_update_book(activity):
|
||||
''' a remote instance changed a book (Document) '''
|
||||
|
|
18
bookwyrm/migrations/0056_auto_20201021_0150.py
Normal file
18
bookwyrm/migrations/0056_auto_20201021_0150.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.0.7 on 2020-10-21 01:50
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('bookwyrm', '0055_merge_20201017_0011'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='status',
|
||||
name='deleted_date',
|
||||
field=models.DateTimeField(blank=True, null=True),
|
||||
),
|
||||
]
|
|
@ -23,7 +23,7 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
|
|||
# the created date can't be this, because of receiving federated posts
|
||||
published_date = models.DateTimeField(default=timezone.now)
|
||||
deleted = models.BooleanField(default=False)
|
||||
deleted_date = models.DateTimeField()
|
||||
deleted_date = models.DateTimeField(blank=True, null=True)
|
||||
favorites = models.ManyToManyField(
|
||||
'User',
|
||||
symmetrical=False,
|
||||
|
|
|
@ -15,9 +15,6 @@
|
|||
<div class="control">
|
||||
{{ login_form.username }}
|
||||
</div>
|
||||
{% for error in login_form.username.errors %}
|
||||
<p class="help is-danger">{{ error | escape }}</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="id_password">Password:</label>
|
||||
|
|
30
bookwyrm/tests/incoming/test_update_user.py
Normal file
30
bookwyrm/tests/incoming/test_update_user.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
import json
|
||||
import pathlib
|
||||
from django.test import TestCase
|
||||
|
||||
from bookwyrm import models, incoming
|
||||
|
||||
|
||||
class UpdateUser(TestCase):
|
||||
def setUp(self):
|
||||
self.user = models.User.objects.create_user(
|
||||
'mouse', 'mouse@mouse.com', 'mouseword',
|
||||
remote_id='https://example.com/user/mouse',
|
||||
local=False,
|
||||
localname='mouse'
|
||||
)
|
||||
|
||||
datafile = pathlib.Path(__file__).parent.joinpath(
|
||||
'../data/ap_user.json'
|
||||
)
|
||||
self.user_data = json.loads(datafile.read_bytes())
|
||||
|
||||
def test_handle_update_user(self):
|
||||
self.assertIsNone(self.user.name)
|
||||
self.assertEqual(self.user.localname, 'mouse')
|
||||
|
||||
incoming.handle_update_user({'object': self.user_data})
|
||||
self.user = models.User.objects.get(id=self.user.id)
|
||||
|
||||
self.assertEqual(self.user.name, 'MOUSE?? MOUSE!!')
|
||||
self.assertEqual(self.user.localname, 'mouse')
|
|
@ -11,7 +11,14 @@ localname_regex = r'(?P<username>[\w\-_]+)'
|
|||
user_path = r'^user/%s' % username_regex
|
||||
local_user_path = r'^user/%s' % localname_regex
|
||||
|
||||
status_types = ['status', 'review', 'comment', 'quotation', 'boost', 'generatedstatus']
|
||||
status_types = [
|
||||
'status',
|
||||
'review',
|
||||
'comment',
|
||||
'quotation',
|
||||
'boost',
|
||||
'generatedstatus'
|
||||
]
|
||||
status_path = r'%s/(%s)/(?P<status_id>\d+)' % \
|
||||
(local_user_path, '|'.join(status_types))
|
||||
|
||||
|
|
|
@ -24,14 +24,6 @@ def user_login(request):
|
|||
return redirect('/login')
|
||||
|
||||
login_form = forms.LoginForm(request.POST)
|
||||
register_form = forms.RegisterForm()
|
||||
if not login_form.is_valid():
|
||||
data = {
|
||||
'site_settings': models.SiteSettings.get(),
|
||||
'login_form': login_form,
|
||||
'register_form': register_form
|
||||
}
|
||||
return TemplateResponse(request, 'login.html', data)
|
||||
|
||||
username = login_form.data['username']
|
||||
username = '%s@%s' % (username, DOMAIN)
|
||||
|
@ -42,6 +34,7 @@ def user_login(request):
|
|||
return redirect(request.GET.get('next', '/'))
|
||||
|
||||
login_form.non_field_errors = 'Username or password are incorrect'
|
||||
register_form = forms.RegisterForm()
|
||||
data = {
|
||||
'site_settings': models.SiteSettings.get(),
|
||||
'login_form': login_form,
|
||||
|
|
Loading…
Reference in a new issue