2021-03-08 11:49:10 -05:00
""" the particulars for this instance of BookWyrm """
2020-10-02 16:32:19 -04:00
import datetime
2020-06-01 17:34:45 -04:00
2021-03-20 21:23:59 -04:00
from django . db import models , IntegrityError
2021-05-26 04:19:39 -04:00
from django . dispatch import receiver
2020-06-03 12:38:30 -04:00
from django . utils import timezone
2021-05-27 15:09:57 -04:00
from model_utils import FieldTracker
2020-06-01 17:34:45 -04:00
2021-05-26 04:19:39 -04:00
from bookwyrm . preview_images import generate_site_preview_image_task
2021-06-18 18:24:10 -04:00
from bookwyrm . settings import DOMAIN , ENABLE_PREVIEW_IMAGES
2021-08-06 17:42:18 -04:00
from . base_model import BookWyrmModel , new_access_code
2020-06-03 12:38:30 -04:00
from . user import User
2020-06-01 14:54:08 -04:00
2021-03-08 11:49:10 -05:00
2020-06-01 14:54:08 -04:00
class SiteSettings ( models . Model ) :
2021-04-26 12:15:42 -04:00
""" customized settings for this instance """
2021-03-08 11:49:10 -05:00
name = models . CharField ( default = " BookWyrm " , max_length = 100 )
2021-01-04 15:58:31 -05:00
instance_tagline = models . CharField (
2021-03-08 11:49:10 -05:00
max_length = 150 , default = " Social Reading and Reviewing "
2020-10-05 19:07:37 -04:00
)
2021-03-08 11:49:10 -05:00
instance_description = models . TextField ( default = " This instance has no description. " )
2021-09-10 15:13:24 -04:00
instance_short_description = models . CharField ( max_length = 255 , blank = True , null = True )
2021-04-30 13:42:27 -04:00
# about page
2021-03-08 11:49:10 -05:00
registration_closed_text = models . TextField (
2021-09-18 18:42:48 -04:00
default = ' We aren \' t taking new users at this time. You can find an open instance at <a href= " https://joinbookwyrm.com/instances " >joinbookwyrm.com/instances</a>. '
)
invite_request_text = models . TextField (
default = " If your request is approved, you will receive an email with a registration link. "
2020-10-05 19:07:37 -04:00
)
2021-03-08 11:49:10 -05:00
code_of_conduct = models . TextField ( default = " Add a code of conduct here. " )
privacy_policy = models . TextField ( default = " Add a privacy policy here. " )
2021-04-30 13:42:27 -04:00
# registration
2021-03-08 11:49:10 -05:00
allow_registration = models . BooleanField ( default = True )
2021-03-20 21:23:59 -04:00
allow_invite_requests = models . BooleanField ( default = True )
2021-08-06 19:24:57 -04:00
require_confirm_email = models . BooleanField ( default = True )
2021-04-30 13:42:27 -04:00
# images
2021-03-08 11:49:10 -05:00
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 )
2021-05-26 08:46:34 -04:00
preview_image = models . ImageField (
upload_to = " previews/logos/ " , null = True , blank = True
)
2021-04-30 13:42:27 -04:00
# footer
2020-12-11 15:31:02 -05:00
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 )
2021-04-30 13:42:27 -04:00
footer_item = models . TextField ( null = True , blank = True )
2020-06-01 14:54:08 -04:00
2021-05-27 15:40:23 -04:00
field_tracker = FieldTracker ( fields = [ " name " , " instance_tagline " , " logo " ] )
2021-05-27 15:09:57 -04:00
2020-06-01 14:54:08 -04:00
@classmethod
def get ( cls ) :
2021-04-26 12:15:42 -04:00
""" gets the site settings db entry or defaults """
2020-06-01 14:54:08 -04:00
try :
return cls . objects . get ( id = 1 )
except cls . DoesNotExist :
default_settings = SiteSettings ( id = 1 )
default_settings . save ( )
return default_settings
2020-06-01 17:34:45 -04:00
2021-03-08 11:49:10 -05:00
2020-06-01 17:34:45 -04:00
class SiteInvite ( models . Model ) :
2021-04-26 12:15:42 -04:00
""" gives someone access to create an account on the instance """
2021-03-08 11:49:10 -05:00
2021-01-05 14:37:48 -05:00
created_date = models . DateTimeField ( auto_now_add = True )
2020-10-02 16:32:19 -04:00
code = models . CharField ( max_length = 32 , default = new_access_code )
2020-06-01 17:34:45 -04:00
expiry = models . DateTimeField ( blank = True , null = True )
use_limit = models . IntegerField ( blank = True , null = True )
times_used = models . IntegerField ( default = 0 )
2020-06-03 12:38:30 -04:00
user = models . ForeignKey ( User , on_delete = models . CASCADE )
2021-04-01 20:19:29 -04:00
invitees = models . ManyToManyField ( User , related_name = " invitees " )
2020-06-01 17:34:45 -04:00
def valid ( self ) :
2021-04-26 12:15:42 -04:00
""" make sure it hasn ' t expired or been used """
2021-03-08 11:49:10 -05:00
return ( self . expiry is None or self . expiry > timezone . now ( ) ) and (
self . use_limit is None or self . times_used < self . use_limit
)
2020-06-03 12:38:30 -04:00
@property
def link ( self ) :
2021-04-26 12:15:42 -04:00
""" formats the invite link """
2021-03-08 11:49:10 -05:00
return " https:// {} /invite/ {} " . format ( DOMAIN , self . code )
2020-10-02 16:32:19 -04:00
2021-03-20 21:23:59 -04:00
class InviteRequest ( BookWyrmModel ) :
2021-04-26 12:15:42 -04:00
""" prospective users can request an invite """
2021-03-20 21:23:59 -04:00
email = models . EmailField ( max_length = 255 , unique = True )
invite = models . ForeignKey (
SiteInvite , on_delete = models . SET_NULL , null = True , blank = True
)
invite_sent = models . BooleanField ( default = False )
2021-03-20 23:15:50 -04:00
ignored = models . BooleanField ( default = False )
2021-03-20 21:23:59 -04:00
def save ( self , * args , * * kwargs ) :
2021-04-26 12:15:42 -04:00
""" don ' t create a request for a registered email """
2021-03-29 11:33:12 -04:00
if not self . id and User . objects . filter ( email = self . email ) . exists ( ) :
2021-03-20 21:23:59 -04:00
raise IntegrityError ( )
super ( ) . save ( * args , * * kwargs )
2020-10-02 16:32:19 -04:00
def get_passowrd_reset_expiry ( ) :
2021-04-26 12:15:42 -04:00
""" give people a limited time to use the link """
2020-11-27 19:24:53 -05:00
now = timezone . now ( )
2020-10-02 16:32:19 -04:00
return now + datetime . timedelta ( days = 1 )
class PasswordReset ( models . Model ) :
2021-04-26 12:15:42 -04:00
""" gives someone access to create an account on the instance """
2021-03-08 11:49:10 -05:00
2020-10-02 16:32:19 -04:00
code = models . CharField ( max_length = 32 , default = new_access_code )
expiry = models . DateTimeField ( default = get_passowrd_reset_expiry )
user = models . OneToOneField ( User , on_delete = models . CASCADE )
def valid ( self ) :
2021-04-26 12:15:42 -04:00
""" make sure it hasn ' t expired or been used """
2020-10-02 16:32:19 -04:00
return self . expiry > timezone . now ( )
@property
def link ( self ) :
2021-04-26 12:15:42 -04:00
""" formats the invite link """
2021-03-08 11:49:10 -05:00
return " https:// {} /password-reset/ {} " . format ( DOMAIN , self . code )
2021-05-26 04:19:39 -04:00
# pylint: disable=unused-argument
2021-06-18 18:24:10 -04:00
@receiver ( models . signals . post_save , sender = SiteSettings )
2021-05-26 04:19:39 -04:00
def preview_image ( instance , * args , * * kwargs ) :
2021-06-18 18:24:10 -04:00
""" Update image preview for the default site image """
if not ENABLE_PREVIEW_IMAGES :
return
2021-05-27 15:09:57 -04:00
changed_fields = instance . field_tracker . changed ( )
2021-05-26 04:19:39 -04:00
2021-05-27 15:09:57 -04:00
if len ( changed_fields ) > 0 :
2021-05-26 04:19:39 -04:00
generate_site_preview_image_task . delay ( )