custom questions
This commit is contained in:
		@@ -1,4 +1,5 @@
 | 
				
			|||||||
""" using django model forms """
 | 
					""" using django model forms """
 | 
				
			||||||
 | 
					from dataclasses import field
 | 
				
			||||||
import datetime
 | 
					import datetime
 | 
				
			||||||
from collections import defaultdict
 | 
					from collections import defaultdict
 | 
				
			||||||
from urllib.parse import urlparse
 | 
					from urllib.parse import urlparse
 | 
				
			||||||
@@ -50,7 +51,7 @@ class LoginForm(CustomForm):
 | 
				
			|||||||
class RegisterForm(CustomForm):
 | 
					class RegisterForm(CustomForm):
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = models.User
 | 
					        model = models.User
 | 
				
			||||||
        fields = ["localname", "email", "password"]
 | 
					        fields = ["localname", "email", "password", "answer"]
 | 
				
			||||||
        help_texts = {f: None for f in fields}
 | 
					        help_texts = {f: None for f in fields}
 | 
				
			||||||
        widgets = {"password": PasswordInput()}
 | 
					        widgets = {"password": PasswordInput()}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -404,7 +405,7 @@ class InviteRequestForm(CustomForm):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = models.InviteRequest
 | 
					        model = models.InviteRequest
 | 
				
			||||||
        fields = ["email"]
 | 
					        fields = ["email", "answer"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CreateInviteForm(CustomForm):
 | 
					class CreateInviteForm(CustomForm):
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								bookwyrm/migrations/0145_user_question.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								bookwyrm/migrations/0145_user_question.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					# Generated by Django 3.2.12 on 2022-03-04 22:38
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('bookwyrm', '0144_alter_announcement_display_type'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='user',
 | 
				
			||||||
 | 
					            name='question',
 | 
				
			||||||
 | 
					            field=models.TextField(blank=True, max_length=500, verbose_name='question'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										19
									
								
								bookwyrm/migrations/0146_alter_user_question.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								bookwyrm/migrations/0146_alter_user_question.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					# Generated by Django 3.2.12 on 2022-03-04 23:15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import bookwyrm.models.fields
 | 
				
			||||||
 | 
					from django.db import migrations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('bookwyrm', '0145_user_question'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='user',
 | 
				
			||||||
 | 
					            name='question',
 | 
				
			||||||
 | 
					            field=bookwyrm.models.fields.TextField(blank=True, max_length=500, verbose_name='question'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										19
									
								
								bookwyrm/migrations/0147_alter_user_question.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								bookwyrm/migrations/0147_alter_user_question.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					# Generated by Django 3.2.12 on 2022-03-04 23:19
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import bookwyrm.models.fields
 | 
				
			||||||
 | 
					from django.db import migrations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('bookwyrm', '0146_alter_user_question'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='user',
 | 
				
			||||||
 | 
					            name='question',
 | 
				
			||||||
 | 
					            field=bookwyrm.models.fields.TextField(blank=True, max_length=500),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										18
									
								
								bookwyrm/migrations/0148_rename_question_user_answer.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								bookwyrm/migrations/0148_rename_question_user_answer.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					# Generated by Django 3.2.12 on 2022-03-05 11:08
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('bookwyrm', '0147_alter_user_question'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.RenameField(
 | 
				
			||||||
 | 
					            model_name='user',
 | 
				
			||||||
 | 
					            old_name='question',
 | 
				
			||||||
 | 
					            new_name='answer',
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										19
									
								
								bookwyrm/migrations/0149_inviterequest_answer.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								bookwyrm/migrations/0149_inviterequest_answer.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					# Generated by Django 3.2.12 on 2022-03-05 11:39
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('bookwyrm', '0148_rename_question_user_answer'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='inviterequest',
 | 
				
			||||||
 | 
					            name='answer',
 | 
				
			||||||
 | 
					            field=models.TextField(default='yyyyy', max_length=512),
 | 
				
			||||||
 | 
					            preserve_default=False,
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
							
								
								
									
										18
									
								
								bookwyrm/migrations/0150_alter_inviterequest_answer.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								bookwyrm/migrations/0150_alter_inviterequest_answer.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					# Generated by Django 3.2.12 on 2022-03-05 12:46
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('bookwyrm', '0149_inviterequest_answer'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='inviterequest',
 | 
				
			||||||
 | 
					            name='answer',
 | 
				
			||||||
 | 
					            field=models.TextField(max_length=50),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -48,8 +48,14 @@ class SiteSettings(models.Model):
 | 
				
			|||||||
    # registration
 | 
					    # registration
 | 
				
			||||||
    allow_registration = models.BooleanField(default=False)
 | 
					    allow_registration = models.BooleanField(default=False)
 | 
				
			||||||
    allow_invite_requests = models.BooleanField(default=True)
 | 
					    allow_invite_requests = models.BooleanField(default=True)
 | 
				
			||||||
 | 
					    invite_request_question = models.BooleanField(default=False)
 | 
				
			||||||
    require_confirm_email = models.BooleanField(default=True)
 | 
					    require_confirm_email = models.BooleanField(default=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    invite_question_text = models.CharField(
 | 
				
			||||||
 | 
							max_length=255,
 | 
				
			||||||
 | 
							null=not(invite_request_question),
 | 
				
			||||||
 | 
					        default="What is your favourite book?"
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
    # images
 | 
					    # images
 | 
				
			||||||
    logo = models.ImageField(upload_to="logos/", null=True, blank=True)
 | 
					    logo = models.ImageField(upload_to="logos/", null=True, blank=True)
 | 
				
			||||||
    logo_small = models.ImageField(upload_to="logos/", null=True, blank=True)
 | 
					    logo_small = models.ImageField(upload_to="logos/", null=True, blank=True)
 | 
				
			||||||
@@ -149,6 +155,7 @@ class InviteRequest(BookWyrmModel):
 | 
				
			|||||||
    invite = models.ForeignKey(
 | 
					    invite = models.ForeignKey(
 | 
				
			||||||
        SiteInvite, on_delete=models.SET_NULL, null=True, blank=True
 | 
					        SiteInvite, on_delete=models.SET_NULL, null=True, blank=True
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					    answer = models.TextField(max_length=50, unique=False, null=False)
 | 
				
			||||||
    invite_sent = models.BooleanField(default=False)
 | 
					    invite_sent = models.BooleanField(default=False)
 | 
				
			||||||
    ignored = models.BooleanField(default=False)
 | 
					    ignored = models.BooleanField(default=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
""" database schema for user data """
 | 
					""" database schema for user data """
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
 | 
					import string
 | 
				
			||||||
from urllib.parse import urlparse
 | 
					from urllib.parse import urlparse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.apps import apps
 | 
					from django.apps import apps
 | 
				
			||||||
@@ -52,6 +53,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    username = fields.UsernameField()
 | 
					    username = fields.UsernameField()
 | 
				
			||||||
    email = models.EmailField(unique=True, null=True)
 | 
					    email = models.EmailField(unique=True, null=True)
 | 
				
			||||||
 | 
					    answer = fields.TextField(max_length=500, blank=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    key_pair = fields.OneToOneField(
 | 
					    key_pair = fields.OneToOneField(
 | 
				
			||||||
        "KeyPair",
 | 
					        "KeyPair",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,6 +70,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                            {% include 'snippets/form_errors.html' with errors_list=request_form.email.errors id="desc_request_email" %}
 | 
					                            {% include 'snippets/form_errors.html' with errors_list=request_form.email.errors id="desc_request_email" %}
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
 | 
											{% if site.invite_request_question %}
 | 
				
			||||||
 | 
												<div class="block">
 | 
				
			||||||
 | 
													<label for="id_answer_register" class="label">{{ site.invite_question_text }}</label>
 | 
				
			||||||
 | 
													<input type="answer" name="answer" maxlength="50" class="input" required="true" id="id_answer_register" aria-describedby="desc_answer_register">
 | 
				
			||||||
 | 
													{% include 'snippets/form_errors.html' with errors_list=request_form.answer.errors id="desc_answer_register" %}
 | 
				
			||||||
 | 
												</div>
 | 
				
			||||||
 | 
											{% endif %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        <button type="submit" class="button is-link">{% trans "Submit" %}</button>
 | 
					                        <button type="submit" class="button is-link">{% trans "Submit" %}</button>
 | 
				
			||||||
                    </form>
 | 
					                    </form>
 | 
				
			||||||
                {% endif %}
 | 
					                {% endif %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,7 @@
 | 
				
			|||||||
                {% include 'snippets/table-sort-header.html' with field="invite__invitees__created_date" sort=sort text=text %}
 | 
					                {% include 'snippets/table-sort-header.html' with field="invite__invitees__created_date" sort=sort text=text %}
 | 
				
			||||||
            </th>
 | 
					            </th>
 | 
				
			||||||
            <th>{% trans "Email" %}</th>
 | 
					            <th>{% trans "Email" %}</th>
 | 
				
			||||||
 | 
					            <th>{% trans "Answer" %}</th>
 | 
				
			||||||
            <th>
 | 
					            <th>
 | 
				
			||||||
                {% trans "Status" as text %}
 | 
					                {% trans "Status" as text %}
 | 
				
			||||||
                {% include 'snippets/table-sort-header.html' with field="invite__times_used" sort=sort text=text %}
 | 
					                {% include 'snippets/table-sort-header.html' with field="invite__times_used" sort=sort text=text %}
 | 
				
			||||||
@@ -54,6 +55,7 @@
 | 
				
			|||||||
            <td>{{ req.created_date | naturaltime }}</td>
 | 
					            <td>{{ req.created_date | naturaltime }}</td>
 | 
				
			||||||
            <td>{{ req.invite.invitees.first.created_date | naturaltime }}</td>
 | 
					            <td>{{ req.invite.invitees.first.created_date | naturaltime }}</td>
 | 
				
			||||||
            <td>{{ req.email }}</td>
 | 
					            <td>{{ req.email }}</td>
 | 
				
			||||||
 | 
					            <td>{{ req.answer }}</td>
 | 
				
			||||||
            <td>
 | 
					            <td>
 | 
				
			||||||
                {% if req.invite.times_used %}
 | 
					                {% if req.invite.times_used %}
 | 
				
			||||||
                {% trans "Accepted" %}
 | 
					                {% trans "Accepted" %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -145,6 +145,18 @@
 | 
				
			|||||||
                    {% trans "Allow invite requests" %}
 | 
					                    {% trans "Allow invite requests" %}
 | 
				
			||||||
                </label>
 | 
					                </label>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
								<div class="field">
 | 
				
			||||||
 | 
					                <label class="label" for="id_invite_requests_question">
 | 
				
			||||||
 | 
					                    {{ site_form.invite_request_question }}
 | 
				
			||||||
 | 
					                    {% trans "Set a question for invite requests" %}
 | 
				
			||||||
 | 
					                </label>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
									<div class="field">
 | 
				
			||||||
 | 
										<label class="label" for="id_invite_question_text">
 | 
				
			||||||
 | 
											{% trans "Question:" %}
 | 
				
			||||||
 | 
											{{ site_form.invite_question_text }}
 | 
				
			||||||
 | 
										</label>
 | 
				
			||||||
 | 
									</div>
 | 
				
			||||||
            <div class="field">
 | 
					            <div class="field">
 | 
				
			||||||
                <label class="label mb-0" for="id_require_confirm_email">
 | 
					                <label class="label mb-0" for="id_require_confirm_email">
 | 
				
			||||||
                    {{ site_form.require_confirm_email }}
 | 
					                    {{ site_form.require_confirm_email }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -96,6 +96,7 @@ class ManageInviteRequests(View):
 | 
				
			|||||||
            "created_date",
 | 
					            "created_date",
 | 
				
			||||||
            "invite__times_used",
 | 
					            "invite__times_used",
 | 
				
			||||||
            "invite__invitees__created_date",
 | 
					            "invite__invitees__created_date",
 | 
				
			||||||
 | 
								"answer"
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
        # pylint: disable=consider-using-f-string
 | 
					        # pylint: disable=consider-using-f-string
 | 
				
			||||||
        if not sort in sort_fields + ["-{:s}".format(f) for f in sort_fields]:
 | 
					        if not sort in sort_fields + ["-{:s}".format(f) for f in sort_fields]:
 | 
				
			||||||
@@ -143,6 +144,8 @@ class ManageInviteRequests(View):
 | 
				
			|||||||
        invite_request = get_object_or_404(
 | 
					        invite_request = get_object_or_404(
 | 
				
			||||||
            models.InviteRequest, id=request.POST.get("invite-request")
 | 
					            models.InviteRequest, id=request.POST.get("invite-request")
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							
 | 
				
			||||||
        # only create a new invite if one doesn't exist already (resending)
 | 
					        # only create a new invite if one doesn't exist already (resending)
 | 
				
			||||||
        if not invite_request.invite:
 | 
					        if not invite_request.invite:
 | 
				
			||||||
            invite_request.invite = models.SiteInvite.objects.create(
 | 
					            invite_request.invite = models.SiteInvite.objects.create(
 | 
				
			||||||
@@ -169,10 +172,11 @@ class InviteRequest(View):
 | 
				
			|||||||
        if form.is_valid():
 | 
					        if form.is_valid():
 | 
				
			||||||
            received = True
 | 
					            received = True
 | 
				
			||||||
            form.save()
 | 
					            form.save()
 | 
				
			||||||
 | 
							#answer = 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        data = {
 | 
					        data = {
 | 
				
			||||||
            "request_form": form,
 | 
					            "request_form": form,
 | 
				
			||||||
            "request_received": received,
 | 
					            "request_received": received
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return TemplateResponse(request, "landing/landing.html", data)
 | 
					        return TemplateResponse(request, "landing/landing.html", data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,6 +56,7 @@ class Register(View):
 | 
				
			|||||||
        localname = form.data["localname"].strip()
 | 
					        localname = form.data["localname"].strip()
 | 
				
			||||||
        email = form.data["email"]
 | 
					        email = form.data["email"]
 | 
				
			||||||
        password = form.data["password"]
 | 
					        password = form.data["password"]
 | 
				
			||||||
 | 
					        answer = form.data["answer"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # make sure the email isn't blocked as spam
 | 
					        # make sure the email isn't blocked as spam
 | 
				
			||||||
        email_domain = email.split("@")[-1]
 | 
					        email_domain = email.split("@")[-1]
 | 
				
			||||||
@@ -68,6 +69,7 @@ class Register(View):
 | 
				
			|||||||
            username,
 | 
					            username,
 | 
				
			||||||
            email,
 | 
					            email,
 | 
				
			||||||
            password,
 | 
					            password,
 | 
				
			||||||
 | 
					            answer=answer,
 | 
				
			||||||
            localname=localname,
 | 
					            localname=localname,
 | 
				
			||||||
            local=True,
 | 
					            local=True,
 | 
				
			||||||
            deactivation_reason="pending" if settings.require_confirm_email else None,
 | 
					            deactivation_reason="pending" if settings.require_confirm_email else None,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user