Merge branch 'main' into review-rate
This commit is contained in:
commit
a73f51ad78
53 changed files with 1175 additions and 398 deletions
|
@ -26,11 +26,20 @@ def validate_remote_id(value):
|
|||
)
|
||||
|
||||
|
||||
def validate_localname(value):
|
||||
''' make sure localnames look okay '''
|
||||
if not re.match(r'^[A-Za-z\-_\.0-9]+$', value):
|
||||
raise ValidationError(
|
||||
_('%(value)s is not a valid username'),
|
||||
params={'value': value},
|
||||
)
|
||||
|
||||
|
||||
def validate_username(value):
|
||||
''' make sure usernames look okay '''
|
||||
if not re.match(r'^[A-Za-z\-_\.]+$', value):
|
||||
if not re.match(r'^[A-Za-z\-_\.0-9]+@[A-Za-z\-_\.0-9]+\.[a-z]{2,}$', value):
|
||||
raise ValidationError(
|
||||
_('%(value)s is not a valid remote_id'),
|
||||
_('%(value)s is not a valid username'),
|
||||
params={'value': value},
|
||||
)
|
||||
|
||||
|
@ -147,7 +156,7 @@ class RemoteIdField(ActivitypubFieldMixin, models.CharField):
|
|||
|
||||
class UsernameField(ActivitypubFieldMixin, models.CharField):
|
||||
''' activitypub-aware username field '''
|
||||
def __init__(self, activitypub_field='preferredUsername'):
|
||||
def __init__(self, activitypub_field='preferredUsername', **kwargs):
|
||||
self.activitypub_field = activitypub_field
|
||||
# I don't totally know why pylint is mad at this, but it makes it work
|
||||
super( #pylint: disable=bad-super-call
|
||||
|
|
|
@ -6,7 +6,7 @@ from django.contrib.postgres.fields import JSONField
|
|||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
||||
from bookwyrm import books_manager
|
||||
from bookwyrm.connectors import connector_manager
|
||||
from bookwyrm.models import ReadThrough, User, Book
|
||||
from .fields import PrivacyLevels
|
||||
|
||||
|
@ -71,7 +71,7 @@ class ImportItem(models.Model):
|
|||
|
||||
def get_book_from_isbn(self):
|
||||
''' search by isbn '''
|
||||
search_result = books_manager.first_search_result(
|
||||
search_result = connector_manager.first_search_result(
|
||||
self.isbn, min_confidence=0.999
|
||||
)
|
||||
if search_result:
|
||||
|
@ -86,7 +86,7 @@ class ImportItem(models.Model):
|
|||
self.data['Title'],
|
||||
self.data['Author']
|
||||
)
|
||||
search_result = books_manager.first_search_result(
|
||||
search_result = connector_manager.first_search_result(
|
||||
search_term, min_confidence=0.999
|
||||
)
|
||||
if search_result:
|
||||
|
|
|
@ -12,11 +12,24 @@ from .user import User
|
|||
class SiteSettings(models.Model):
|
||||
''' customized settings for this instance '''
|
||||
name = models.CharField(default='BookWyrm', max_length=100)
|
||||
instance_tagline = models.CharField(
|
||||
max_length=150, default='Social Reading and Reviewing')
|
||||
instance_description = models.TextField(
|
||||
default="This instance has no description.")
|
||||
default='This instance has no description.')
|
||||
registration_closed_text = models.TextField(
|
||||
default='Contact an administrator to get an invite')
|
||||
code_of_conduct = models.TextField(
|
||||
default="Add a code of conduct here.")
|
||||
default='Add a code of conduct here.')
|
||||
allow_registration = models.BooleanField(default=True)
|
||||
logo = models.ImageField(
|
||||
upload_to='logos/', null=True, blank=True
|
||||
)
|
||||
logo_small = models.ImageField(
|
||||
upload_to='logos/', null=True, blank=True
|
||||
)
|
||||
favicon = models.ImageField(
|
||||
upload_to='logos/', null=True, blank=True
|
||||
)
|
||||
support_link = models.CharField(max_length=255, null=True, blank=True)
|
||||
support_title = models.CharField(max_length=100, null=True, blank=True)
|
||||
admin_email = models.EmailField(max_length=255, null=True, blank=True)
|
||||
|
@ -52,7 +65,7 @@ class SiteInvite(models.Model):
|
|||
@property
|
||||
def link(self):
|
||||
''' formats the invite link '''
|
||||
return "https://{}/invite/{}".format(DOMAIN, self.code)
|
||||
return 'https://{}/invite/{}'.format(DOMAIN, self.code)
|
||||
|
||||
|
||||
def get_passowrd_reset_expiry():
|
||||
|
@ -74,4 +87,4 @@ class PasswordReset(models.Model):
|
|||
@property
|
||||
def link(self):
|
||||
''' formats the invite link '''
|
||||
return "https://{}/password-reset/{}".format(DOMAIN, self.code)
|
||||
return 'https://{}/password-reset/{}'.format(DOMAIN, self.code)
|
||||
|
|
|
@ -118,7 +118,7 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
|
|||
activity['attachment'] = [
|
||||
image_serializer(b.cover, b.alt_text) \
|
||||
for b in self.mention_books.all()[:4] if b.cover]
|
||||
if hasattr(self, 'book'):
|
||||
if hasattr(self, 'book') and self.book.cover:
|
||||
activity['attachment'].append(
|
||||
image_serializer(self.book.cover, self.book.alt_text)
|
||||
)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
''' database schema for user data '''
|
||||
import re
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from django.apps import apps
|
||||
|
@ -13,6 +14,7 @@ from bookwyrm.models.status import Status, Review
|
|||
from bookwyrm.settings import DOMAIN
|
||||
from bookwyrm.signatures import create_key_pair
|
||||
from bookwyrm.tasks import app
|
||||
from bookwyrm.utils import regex
|
||||
from .base_model import OrderedCollectionPageMixin
|
||||
from .base_model import ActivitypubMixin, BookWyrmModel
|
||||
from .federated_server import FederatedServer
|
||||
|
@ -49,7 +51,8 @@ class User(OrderedCollectionPageMixin, AbstractUser):
|
|||
localname = models.CharField(
|
||||
max_length=255,
|
||||
null=True,
|
||||
unique=True
|
||||
unique=True,
|
||||
validators=[fields.validate_localname],
|
||||
)
|
||||
# name is your display name, which you can change at will
|
||||
name = fields.CharField(max_length=100, null=True, blank=True)
|
||||
|
@ -167,20 +170,17 @@ class User(OrderedCollectionPageMixin, AbstractUser):
|
|||
def save(self, *args, **kwargs):
|
||||
''' populate fields for new local users '''
|
||||
# this user already exists, no need to populate fields
|
||||
if self.id:
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
if not self.local:
|
||||
if not self.local and not re.match(regex.full_username, self.username):
|
||||
# generate a username that uses the domain (webfinger format)
|
||||
actor_parts = urlparse(self.remote_id)
|
||||
self.username = '%s@%s' % (self.username, actor_parts.netloc)
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
if self.id or not self.local:
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
# populate fields for local users
|
||||
self.remote_id = 'https://%s/user/%s' % (DOMAIN, self.username)
|
||||
self.localname = self.username
|
||||
self.username = '%s@%s' % (self.username, DOMAIN)
|
||||
self.actor = self.remote_id
|
||||
self.remote_id = 'https://%s/user/%s' % (DOMAIN, self.localname)
|
||||
self.inbox = '%s/inbox' % self.remote_id
|
||||
self.shared_inbox = 'https://%s/inbox' % DOMAIN
|
||||
self.outbox = '%s/outbox' % self.remote_id
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue