Skip to content

Commit

Permalink
Merge branch 'development' into Issue18
Browse files Browse the repository at this point in the history
  • Loading branch information
mariobehling authored Mar 23, 2024
2 parents 42ff963 + 4d4212b commit 79bef2c
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 35 deletions.
40 changes: 17 additions & 23 deletions src/pretalx/cfp/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@
from django.utils.translation import gettext
from django.utils.translation import gettext_lazy as _
from django.views.generic.base import TemplateResponseMixin

from django_context_decorator import context

from i18nfield.strings import LazyI18nString
from i18nfield.utils import I18nJSONEncoder

from pretalx.cfp.signals import cfp_steps
from pretalx.common.exceptions import SendMailException
from pretalx.common.phrases import phrases
from pretalx.common.utils import language
from pretalx.common.views import is_form_bound
from pretalx.person.forms import SpeakerProfileForm, UserForm
from pretalx.person.models import User
from pretalx.submission.forms import InfoForm, QuestionsForm
Expand Down Expand Up @@ -407,29 +411,7 @@ def _text(self):
)

def is_applicable(self, request):
self.request = request
info_data = self.cfp_session.get("data", {}).get("info", {})
track = info_data.get("track")
if track:
questions = self.event.questions.exclude(
Q(target=QuestionTarget.SUBMISSION)
& (
(~Q(tracks__in=[info_data.get("track")]) & Q(tracks__isnull=False))
| (
~Q(submission_types__in=[info_data.get("submission_type")])
& Q(submission_types__isnull=False)
)
)
)
else:
questions = self.event.questions.exclude(
Q(target=QuestionTarget.SUBMISSION)
& (
~Q(submission_types__in=[info_data.get("submission_type")])
& Q(submission_types__isnull=False)
)
)
return questions.exists()
return False

def get_form_kwargs(self):
result = super().get_form_kwargs()
Expand Down Expand Up @@ -537,6 +519,18 @@ def get_context_data(self, **kwargs):
result["gravatar_parameter"] = User(email=email).gravatar_parameter
return result

@context
@cached_property
def questions_form(self):
bind = is_form_bound(self.request, "questions")
return QuestionsForm(
data=self.request.POST if bind else None,
files=self.request.FILES if bind else None,
speaker=self.request.user,
event=self.request.event,
target="speaker",
)

def done(self, request, draft=False):
form = self.get_form(from_storage=True)
form.is_valid()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ <h2>{{ title }}</h2>

{% bootstrap_field form.name layout='event' %}
{% if form.biography %}{% bootstrap_field form.biography layout='event' %}{% endif %}
{% if questions_form %}{% bootstrap_form questions_form layout='event' %}{% endif %}
{% if form.availabilities %}
{% compress js %}
<script defer src="{% static "vendored/moment-with-locales.js" %}"></script>
Expand Down
2 changes: 1 addition & 1 deletion src/pretalx/orga/forms/cfp.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def __init__(self, *args, obj, **kwargs):
self.fields[
"mail_on_new_submission"
].help_text += f' (<a href="mailto:{obj.email}">{obj.email}</a>)'
self.length_fields = ["title", "abstract", "description", "biography"]
self.length_fields = ["title", "abstract", "description", "biography", "avatar_source", "avatar_license"]
self.request_require_fields = [
"abstract",
"description",
Expand Down
8 changes: 4 additions & 4 deletions src/pretalx/orga/templates/orga/cfp/text.html
Original file line number Diff line number Diff line change
Expand Up @@ -169,14 +169,14 @@
<tr>
<th>{% translate "Profile picture source" %}</th>
<td class="hide-label">{% bootstrap_field sform.cfp_ask_avatar_source layout='event-inline' %}</td>
<td></td>
<td></td>
<td>{% bootstrap_field sform.cfp_avatar_source_min_length use_label=False layout='inline' %}</td>
<td>{% bootstrap_field sform.cfp_avatar_source_max_length use_label=False layout='inline' %}</td>
</tr>
<tr>
<th>{% translate "Profile picture license" %}</th>
<td class="hide-label">{% bootstrap_field sform.cfp_ask_avatar_license layout='event-inline' %}</td>
<td></td>
<td></td>
<td>{% bootstrap_field sform.cfp_avatar_license_min_length use_label=False layout='inline' %}</td>
<td>{% bootstrap_field sform.cfp_avatar_license_max_length use_label=False layout='inline' %}</td>
</tr>
<tr>
<th>{% translate "Biography" %}</th>
Expand Down
4 changes: 4 additions & 0 deletions src/pretalx/person/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ def __init__(self, *args, name=None, **kwargs):
self.fields[field] = field_class(
initial=initial.get(field), disabled=read_only
)
if self.Meta.widgets.get(field):
self.fields[field].widget = self.Meta.widgets.get(field)()
self._update_cfp_texts(field)

if not self.event.cfp.request_avatar:
Expand Down Expand Up @@ -276,6 +278,8 @@ class Meta:
}
widgets = {
"biography": MarkdownWidget,
"avatar_source": MarkdownWidget,
"avatar_license": MarkdownWidget,
}
request_require = {"biography", "availabilities"}

Expand Down
18 changes: 18 additions & 0 deletions src/pretalx/person/migrations/0031_alter_user_avatar_license.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.11 on 2024-03-16 15:15

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("person", "0030_user_avatar_source_alter_user_avatar_license"),
]

operations = [
migrations.AlterField(
model_name="user",
name="avatar_license",
field=models.TextField(null=True),
),
]
18 changes: 18 additions & 0 deletions src/pretalx/person/migrations/0032_alter_user_avatar_source.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.2.11 on 2024-03-16 22:03

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("person", "0031_alter_user_avatar_license"),
]

operations = [
migrations.AlterField(
model_name="user",
name="avatar_source",
field=models.TextField(null=True),
),
]
6 changes: 2 additions & 4 deletions src/pretalx/person/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,19 +128,17 @@ class User(PermissionsMixin, GenerateCode, FileCleanupMixin, AbstractBaseUser):
"If you have registered with an email address that has a gravatar account, we can retrieve your profile picture from there."
),
)
avatar_source = models.CharField(
avatar_source = models.TextField(
null=True,
blank=True,
max_length=999,
verbose_name=_("Profile Picture Source"),
help_text=_(
"Please enter the name of the author or source of image and a link if applicable."
),
)
avatar_license = models.CharField(
avatar_license = models.TextField(
null=True,
blank=True,
max_length=999,
verbose_name=_("Profile Picture License"),
help_text=_(
"Please enter the name of the license of the photo and link to it if applicable."
Expand Down
71 changes: 68 additions & 3 deletions src/pretalx/submission/forms/submission.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
from django import forms
from django.db.models import Count, Exists, OuterRef, Q
from django.utils.functional import cached_property
from django.utils.timezone import now
from django.utils.translation import gettext_lazy as _
from django_scopes.forms import SafeModelChoiceField

from pretalx.cfp.forms.cfp import CfPFormMixin
from pretalx.common.forms.fields import ImageField
from pretalx.common.forms.widgets import MarkdownWidget
from pretalx.common.mixins.forms import PublicContent, RequestRequire
from pretalx.common.mixins.forms import PublicContent, RequestRequire, QuestionFieldsMixin
from pretalx.common.mixins.views import Filterable
from pretalx.submission.forms.track_select_widget import TrackSelectWidget
from pretalx.submission.models import Answer, Question, Submission, SubmissionStates
from pretalx.submission.models import Answer, Question, Submission, SubmissionStates, QuestionTarget, QuestionVariant


class InfoForm(CfPFormMixin, RequestRequire, PublicContent, forms.ModelForm):
class InfoForm(CfPFormMixin, RequestRequire, PublicContent, QuestionFieldsMixin, forms.ModelForm):
additional_speaker = forms.EmailField(
label=_("Additional Speaker"),
help_text=_(
Expand All @@ -30,6 +31,13 @@ class InfoForm(CfPFormMixin, RequestRequire, PublicContent, forms.ModelForm):

def __init__(self, event, **kwargs):
self.event = event
self.submission = kwargs.pop("submission", None)
self.track = kwargs.pop("track", None) or getattr(
self.submission, "track", None
)
self.submission_type = kwargs.pop("submission_type", None) or getattr(
self.submission, "submission_type", None
)
self.readonly = kwargs.pop("readonly", False)
self.access_code = kwargs.pop("access_code", None)
self.default_values = {}
Expand Down Expand Up @@ -60,6 +68,55 @@ def __init__(self, event, **kwargs):
for f in self.fields.values():
f.disabled = True

self.target_type = kwargs.pop("target", QuestionTarget.SUBMISSION)
self.for_reviewers = kwargs.pop("for_reviewers", False)
if self.target_type == QuestionTarget.SUBMISSION:
target_object = self.submission
elif self.target_type == QuestionTarget.SPEAKER:
target_object = self.speaker

self.queryset = Question.all_objects.filter(event=self.event, active=True)
if self.target_type:
self.queryset = self.queryset.filter(target=self.target_type)
else:
self.queryset = self.queryset.exclude(target=QuestionTarget.REVIEWER)
if self.track:
self.queryset = self.queryset.filter(
Q(tracks__in=[self.track]) | Q(tracks__isnull=True)
)
if self.submission_type:
self.queryset = self.queryset.filter(
Q(submission_types__in=[self.submission_type])
| Q(submission_types__isnull=True)
)

for question in self.queryset.prefetch_related("options"):
initial_object = None
initial = question.default_answer
if target_object:
answers = [
a
for a in target_object.answers.all()
if a.question_id == question.id
]
if answers:
initial_object = answers[0]
initial = (
answers[0].answer_file
if question.variant == QuestionVariant.FILE
else answers[0].answer
)

field = self.get_field(
question=question,
initial=initial,
initial_object=initial_object,
readonly=self.readonly,
)
field.question = question
field.answer = initial_object
self.fields[f"question_{question.pk}"] = field

def _set_track(self, instance=None):
if "track" in self.fields:
if (
Expand Down Expand Up @@ -160,6 +217,14 @@ def _set_slot_count(self, instance=None):
)
)

@cached_property
def submission_fields(self):
return [
forms.BoundField(self, field, name)
for name, field in self.fields.items()
if hasattr(field, "question") and field.question.target == QuestionTarget.SUBMISSION
]

def save(self, *args, **kwargs):
for key, value in self.default_values.items():
setattr(self.instance, key, value)
Expand Down

0 comments on commit 79bef2c

Please sign in to comment.