Changeset - 354825a85b56
[Not reviewed]
0 3 2
Ben Sturmfels (bsturmfels) - 17 months ago 2023-04-24 21:49:50
ben@sturm.com.au
Add Security track
5 files changed with 180 insertions and 0 deletions:
0 comments (0 inline, 0 general)
pinaxcon/proposals/forms.py
Show inline comments
 
import copy
 

	
 
from django import forms
 

	
 
from pinaxcon.proposals.fields import HelpTextField
 
from pinaxcon.proposals import models
 

	
 

	
 
DEFAULT_FIELDS =  [
 
    "title",
 
    # "primary_topic",
 
    "target_audience",
 
    "experience_level",
 
    "abstract",
 
    "private_abstract",
 
    # "content_warning",
 
    "technical_requirements",
 
    # "project",
 
    # "project_url",
 
    # "video_url",
 
    "require_approval",
 
    "recording_release",
 
    "materials_release",
 
    "indicate_use_of_proprietary_software",
 
]
 

	
 
TALK_FORMAT_FIELDS = copy.copy(DEFAULT_FIELDS)
 
TALK_FORMAT_FIELDS.insert(2, "talk_format")
 
TALK_FORMAT_FIELDS.append("ticket_acknowledgement")
 

	
 
class ProposalForm(forms.ModelForm):
 

	
 
    required_css_class = 'label-required'
 
    indicate_use_of_proprietary_software = forms.BooleanField(
 
        help_text="Attendees at FOSSY need to be able to assume that any software mentioned is FOSS by default. I understand that I must indicate the use of any proprietary software on slides and any physical materials present.")
 

	
 

	
 
    def clean_description(self):
 
        value = self.cleaned_data["description"]
 
        if len(value) > 400:
 
            raise forms.ValidationError(
 
                u"The description must be less than 400 characters"
 
            )
 
        return value
 

	
 

	
 
class TalkProposalForm(ProposalForm):
 

	
 
    class Meta:
 
        model = models.TalkProposal
 
        fields = copy.copy(DEFAULT_FIELDS)
 

	
 

	
 
class TutorialProposalForm(ProposalForm):
 

	
 
    class Meta:
 
        model = models.TutorialProposal
 
        fields = copy.copy(DEFAULT_FIELDS)
 

	
 

	
 
class MiniconfProposalForm(ProposalForm):
 

	
 
    def __init__(self, *a, **k):
 
        super(MiniconfProposalForm, self).__init__(*a, **k)
 
        self.fields['ticket_acknowledgement'].required = True
 

	
 

	
 
class CopyleftComplianceProposalForm(MiniconfProposalForm):
 

	
 
    class Meta:
 
        model = models.CopyleftComplianceProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class MemberProjectProposalForm(MiniconfProposalForm):
 

	
 
    class Meta:
 
        model = models.MemberProjectProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class ContainerDaysProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.ContainerDaysProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class SustainableOpenSourceBusinessProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.SustainableOpenSourceBusinessProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class SoftwareWorkerCoopsProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.SoftwareWorkerCoopsProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class DiversityEquityInclusionProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.DiversityEquityInclusionProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class FOSSAtPlayProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.FOSSAtPlayProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class OpenSourcAIDataProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.OpenSourcAIDataProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class OpenWorkProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.OpenWorkProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class CommunityProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.CommunityProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class BSDUnixProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.BSDUnixProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class XMPPProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.XMPPProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class ScienceOfCommunityProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.ScienceOfCommunityProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class AArch64ARM64ProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.AArch64ARM64Proposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class FOSSForEducationProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.FOSSForEducationProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class FOSSInDailyLifeProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.FOSSInDailyLifeProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class SecurityProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.SecurityProposal
 
        fields = TALK_FORMAT_FIELDS
 

	
 

	
 
class WildCardProposalForm(MiniconfProposalForm):
 
    class Meta:
 
        model = models.WildCardProposal
 
        fields = TALK_FORMAT_FIELDS
pinaxcon/proposals/migrations/0011_auto_20230424_1449.py
Show inline comments
 
new file 100644
 
# Generated by Django 2.2.28 on 2023-04-24 21:49
 

	
 
from django.db import migrations, models
 
import django.db.models.deletion
 

	
 

	
 
class Migration(migrations.Migration):
 

	
 
    dependencies = [
 
        ('symposion_proposals', '0003_auto_20170702_2250'),
 
        ('proposals', '0010_auto_20230423_1620'),
 
    ]
 

	
 
    operations = [
 
        migrations.CreateModel(
 
            name='SecurityProposal',
 
            fields=[
 
                ('proposalbase_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='symposion_proposals.ProposalBase')),
 
                ('target_audience', models.IntegerField(choices=[(4, 'Developer'), (3, 'Community'), (1, 'End User'), (2, 'Business')], help_text='Who is the target audience for your session?')),
 
                ('recording_release', models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any recordings of presentations covered by this proposal, on YouTube under the standard YouTube licence, and on other platforms under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (<a href='https://creativecommons.org/licenses/by-nc-sa/4.0/'> CC BY-NC-SA 4.0</a>) licence.")),
 
                ('materials_release', models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>")),
 
                ('primary_topic', models.IntegerField(choices=[(1, 'Linux'), (2, 'Software'), (3, 'Hardware'), (4, 'Firmware'), (5, 'System Administration / Operations'), (6, 'Security'), (7, 'Documentation'), (8, 'Community'), (9, 'Science & Data'), (10, 'Galleries, Libraries, Archives & Museums (GLAM)'), (11, 'Multimedia'), (12, 'Aerospace / UAV'), (13, 'Agriculture'), (14, 'Other')], help_text='What is the primary topic area for your session?', null=True)),
 
                ('experience_level', models.IntegerField(choices=[(1, 'Beginner'), (2, 'Intermediate'), (3, 'Advanced')], help_text='What level of experience will your session be pitched at?')),
 
                ('require_approval', models.BooleanField(default=False, help_text='Do you require further approval from your employer or institution before you can confirm your availability to present?')),
 
                ('content_warning', models.TextField(blank=True, help_text='This will be shown on the schedule to give attendees advanced warning of topics covered in the session. ', verbose_name='Content Warning')),
 
                ('content_warning_html', models.TextField(blank=True)),
 
                ('talk_format', models.IntegerField(choices=[(1, 'Lightning Talk (5-10 min)'), (2, 'Short Presentation (20-25 min)'), (3, 'Long Presentation (40-45 min)')], default=3, help_text='Please indicate your preferred talk length in the private abstract field below.')),
 
                ('ticket_acknowledgement', models.BooleanField(default=False, help_text='I understand that I will be required to purchase a conference ticket and arrange my own travel and accommodation.')),
 
            ],
 
            options={
 
                'verbose_name': 'Security',
 
            },
 
            bases=('symposion_proposals.proposalbase',),
 
        ),
 
        migrations.AlterField(
 
            model_name='aarch64arm64proposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='bsdunixproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='communityproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='containerdaysproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='copyleftcomplianceproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='diversityequityinclusionproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='fossatplayproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='fossforeducationproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='fossindailylifeproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='memberprojectproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='opensourcaidataproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='openworkproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='scienceofcommunityproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='softwareworkercoopsproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='sustainableopensourcebusinessproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='talkproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='tutorialproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='wildcardproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
        migrations.AlterField(
 
            model_name='xmppproposal',
 
            name='materials_release',
 
            field=models.BooleanField(default=True, help_text="I allow Software Freedom Conservancy to release any other material (such as slides) from presentations covered by this proposal, under the <a href='https://creativecommons.org/licenses/by-sa/4.0/'> Creative Commons Attribution-ShareAlike 4.0 International</a>"),
 
        ),
 
    ]
pinaxcon/proposals/models.py
Show inline comments
 
from django.db import models
 
from django.utils.translation import ugettext_lazy as _
 

	
 
from symposion.proposals.models import ProposalBase
 
from symposion.text_parser import parse
 

	
 

	
 
class Proposal(ProposalBase):
 

	
 
    TARGET_USER = 1
 
    TARGET_BUSINESS = 2
 
    TARGET_COMMUNITY = 3
 
    TARGET_DEVELOPER = 4
 

	
 
    TARGET_AUDIENCES = [
 
        (TARGET_DEVELOPER, "Developer"),
 
        (TARGET_COMMUNITY, "Community"),
 
        (TARGET_USER, "End User"),
 
        (TARGET_BUSINESS, "Business"),
 
    ]
 

	
 
    TOPIC_LINUX = 1
 
    TOPIC_SOFTWARE = 2
 
    TOPIC_HARDWARE = 3
 
    TOPIC_FIRMWARE = 4
 
    TOPIC_SYSADMIN = 5
 
    TOPIC_SECURITY = 6
 
    TOPIC_DOCUMENTATION = 7
 
    TOPIC_COMMUNITY = 8
 
    TOPIC_SCIENCE = 9
 
    TOPIC_GLAM = 10
 
    TOPIC_MULTIMEDIA = 11
 
    TOPIC_AEROSPACE = 12
 
    TOPIC_AGRICULTURE = 13
 
    TOPIC_OTHER = 14
 

	
 
    PROPOSAL_TOPIC = [
 
        (TOPIC_LINUX, "Linux"),
 
        (TOPIC_SOFTWARE, "Software"),
 
        (TOPIC_HARDWARE, "Hardware"),
 
        (TOPIC_FIRMWARE, "Firmware"),
 
        (TOPIC_SYSADMIN, "System Administration / Operations"),
 
        (TOPIC_SECURITY, "Security"),
 
        (TOPIC_DOCUMENTATION, "Documentation"),
 
        (TOPIC_COMMUNITY, "Community"),
 
        (TOPIC_SCIENCE, "Science & Data"),
 
        (TOPIC_GLAM, "Galleries, Libraries, Archives & Museums (GLAM)"),
 
        (TOPIC_MULTIMEDIA, "Multimedia"),
 
        (TOPIC_AEROSPACE, "Aerospace / UAV"),
 
        (TOPIC_AGRICULTURE, "Agriculture"),
 
        (TOPIC_OTHER, "Other"),
 
    ]
 

	
 
    LEVEL_BEGINNER = 1
 
    LEVEL_INTERMEDIATE = 2
 
    LEVEL_ADVANCED = 3
 

	
 
    EXPERIENCE_LEVEL = [
 
        (LEVEL_BEGINNER, "Beginner"),
 
        (LEVEL_INTERMEDIATE, "Intermediate"),
 
        (LEVEL_ADVANCED, "Advanced"),
 
    ]
 

	
 
    target_audience = models.IntegerField(
 
        choices=TARGET_AUDIENCES,
 
        help_text="Who is the target audience for your session?",
 
    )
 

	
 
    recording_release = models.BooleanField(
 
        default=True,
 
        help_text="I allow Software Freedom Conservancy to release any recordings of "
 
        "presentations covered by this proposal, on YouTube under the "
 
        "standard YouTube licence, and on other platforms under the "
 
        "Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International "
 
        "(<a href='https://creativecommons.org/licenses/by-nc-sa/4.0/'> "
 
        "CC BY-NC-SA 4.0</a>) licence."
 
    )
 

	
 
    materials_release = models.BooleanField(
 
        default=True,
 
        help_text="I allow Software Freedom Conservancy to release any other material "
 
        "(such as slides) from presentations covered by this proposal, under "
 
        "the <a "
 
        "href='https://creativecommons.org/licenses/by-sa/4.0/'> "
 
        "Creative Commons Attribution-ShareAlike 4.0 International</a>"
 
    )
 

	
 
    primary_topic = models.IntegerField(
 
        choices=PROPOSAL_TOPIC,
 
        help_text="What is the primary topic area for your session?",
 
        null=True,
 
    )
 

	
 
    experience_level = models.IntegerField(
 
        choices=EXPERIENCE_LEVEL,
 
        help_text="What level of experience will your session be pitched at?"
 
    )
 

	
 
    require_approval = models.BooleanField(
 
        default=False,
 
        help_text="Do you require further approval from your employer or "
 
        "institution before you can confirm your availability to present?"
 
    )
 

	
 
    content_warning = models.TextField(
 
        "Content Warning",
 
        help_text=_("This will be shown on the schedule to give attendees "
 
                    "advanced warning of topics covered in the session. "),
 
        blank=True,
 
    )
 
    content_warning_html = models.TextField(blank=True)
 

	
 
    class Meta:
 
        abstract = True
 

	
 
    def save(self, *args, **kwargs):
 
        self.content_warning_html = parse(self.content_warning)
 
        return super(Proposal, self).save(*args, **kwargs)
 

	
 

	
 
class TalkProposal(Proposal):
 

	
 
    class Meta:
 
        verbose_name = "talk proposal"
 

	
 

	
 
class TutorialProposal(Proposal):
 

	
 
    class Meta:
 
        verbose_name = "tutorial proposal"
 

	
 

	
 
class MiniconfSessionProposal(Proposal):
 

	
 
    FORMAT_SHORT_PRESENTATION = 1
 
    FORMAT_MEDIUM_PRESENTATION = 2
 
    FORMAT_LONG_PRESENTATION = 3
 
    FORMAT_DEMONSTRATION = 4
 
    FORMAT_OTHER = 5
 

	
 
    TALK_FORMATS = [
 
        (FORMAT_SHORT_PRESENTATION, "Lightning Talk (5-10 min)"),
 
        (FORMAT_MEDIUM_PRESENTATION, "Short Presentation (20-25 min)"),
 
        (FORMAT_LONG_PRESENTATION, "Long Presentation (40-45 min)"),
 
    ]
 

	
 
    talk_format = models.IntegerField(
 
        choices=TALK_FORMATS,
 
        default=FORMAT_LONG_PRESENTATION,
 
        help_text="Please indicate your preferred talk length in the private abstract field below."
 
    )
 

	
 
    ticket_acknowledgement = models.BooleanField(
 
        default=False,
 
        help_text="I understand that I will be required to purchase a conference ticket "
 
        "and arrange my own travel and accommodation."
 
    )
 

	
 
    class Meta:
 
        abstract = True
 

	
 

	
 
class CopyleftComplianceProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "Copyleft and Compliance talk proposal"
 

	
 

	
 
class MemberProjectProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "SFC Member Project talk proposal"
 

	
 

	
 
class ContainerDaysProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "Container Days proposal"
 

	
 

	
 
class SustainableOpenSourceBusinessProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "Sustainable Open Source Business proposal"
 

	
 

	
 
class SoftwareWorkerCoopsProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "Software Worker Co-ops proposal"
 

	
 

	
 
class DiversityEquityInclusionProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "Diversity Equity and Inclusion and FOSS proposal"
 

	
 

	
 
class FOSSAtPlayProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "FOSS at Play: Games, creative development, and open technology proposal"
 

	
 

	
 
class OpenSourcAIDataProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "Open Source AI + Data proposal"
 

	
 

	
 
class OpenWorkProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "Issues in Open Work; Common Challenges and Best Practices in the Open Source Industry, Open Scholarship, and Government proposal"
 

	
 

	
 
class CommunityProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "Community: Open Source in Practice proposal"
 

	
 

	
 
class BSDUnixProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "BSD Unix proposal"
 

	
 

	
 
class XMPPProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "XMPP proposal"
 

	
 

	
 
class ScienceOfCommunityProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "Science of Community proposal"
 

	
 

	
 
class AArch64ARM64Proposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "AArch64/ARM64 Servers and Open Source- The Who, What, Why, and How proposal"
 

	
 

	
 
class FOSSForEducationProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "FOSS For Education proposal"
 

	
 

	
 
class FOSSInDailyLifeProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "FOSS in Daily Life proposal"
 

	
 

	
 
class SecurityProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "Security"
 

	
 

	
 
class WildCardProposal(MiniconfSessionProposal):
 
    class Meta:
 
        verbose_name = "Wild card"
pinaxcon/settings.py
Show inline comments
 
from decimal import Decimal
 
import os
 
import sys
 

	
 
import django
 
import dj_database_url
 
import saml2
 
import saml2.saml
 

	
 
from datetime import date, datetime, timedelta
 
import pytz
 

	
 
from dataclasses import dataclass
 

	
 
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
 
PACKAGE_ROOT = os.path.abspath(os.path.dirname(__file__))
 
DJANGO_ROOT = os.path.abspath(os.path.dirname(django.__file__))
 
BASE_DIR = PACKAGE_ROOT
 

	
 

	
 
### USER SETTINGS
 
DEV_MODE = os.environ.get("SYMPOSION_DEV_MODE", None)
 
DEBUG = os.environ.get('SYMPOSION_APP_DEBUG', '0')
 
if isinstance(DEBUG, str):
 
    try:
 
        i = int(DEBUG)
 
        if not i in [0, 1]:
 
            raise ValueError("not 0 or 1")
 
        DEBUG = bool(i)
 
    except ValueError:
 
        sys.exit('DEBUG env var must be set to string value of a 0 or 1')
 
else:
 
    sys.exit('DEBUG env var is in unexpected format.  Should be a string'
 
             'containing either a 0 or a 1 - Got type %s' % type(DEBUG))
 

	
 
DATABASES = {}
 
DATABASES['default'] = dj_database_url.config(conn_max_age=600)
 
if DATABASES['default']['ENGINE'] == 'django.db.backends.mysql':
 
    DATABASES['default']['OPTIONS'] = {'charset': 'utf8mb4'}
 

	
 
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
 
EMAIL_HOST = os.environ.get('EMAIL_HOST', None)
 
EMAIL_PORT = os.environ.get('EMAIL_PORT', 25)
 
EMAIL_HOST_USER = os.environ.get('EMAIL_HOST_USER', None)
 
EMAIL_HOST_PASSWORD = os.environ.get('EMAIL_HOST_PASSWORD', None)
 
DEFAULT_FROM_EMAIL = os.environ.get('DEFAULT_FROM_EMAIL', 'webmaster@localhost')
 
EMAIL_USE_SSL = False
 
EMAIL_USE_TLS = False
 
_EMAIL_SSL_FLAVOR=os.environ.get('EMAIL_SSL_FLAVOR', None)
 
if _EMAIL_SSL_FLAVOR == "TLS":
 
    EMAIL_USE_TLS = True
 
elif _EMAIL_SSL_FLAVOR == "SSL":
 
    EMAIL_USE_SSL = True
 

	
 
SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY', None)
 

	
 
PINAX_STRIPE_PUBLIC_KEY = os.environ.get('STRIPE_PUBLIC_KEY', None)
 
PINAX_STRIPE_SECRET_KEY = os.environ.get('STRIPE_SECRET_KEY', None)
 
PINAX_STRIPE_SEND_EMAIL_RECEIPTS = False
 

	
 
ANALYTICS_KEY = os.environ.get('ANALYTICS_KEY', None)
 

	
 
saml2_entityid = os.environ.get('SAML2_ENTITYID', None)
 
saml2_sp_name = os.environ.get('SAML2_SP_NAME', None)
 
saml2_sp_assertion_service = os.environ.get('SAML2_SP_ASSERTION_SERVICE', None)
 
saml2_sp_slo_rdir = os.environ.get('SAML2_SP_SLO_RDIR', None)
 
saml2_sp_slo_post = os.environ.get('SAML2_SP_SLO_POST', None)
 

	
 
saml2_idp_metadata = {
 
    'local': [os.environ.get('SAML2_IDP_METADATA_FILE', None)],
 
    }
 
saml2_signing_key = os.environ.get('SAML2_SIGNING_KEY', None)
 
saml2_signing_crt = os.environ.get('SAML2_SIGNING_CRT', None)
 
saml2_encr_key = os.environ.get('SAML2_ENCRYPTION_KEY', None)
 
saml2_encr_crt = os.environ.get('SAML2_ENCRYPTION_CRT', None)
 
saml2_contact = {
 
    'given_name': os.environ.get("META_GIVEN_NAME", 'Bastard'),
 
    'sur_name': os.environ.get('META_FAM_NAME', 'Operator'),
 
    'company': os.environ.get('META_COMPANY', 'Corp1'),
 
    'email_address': os.environ.get('META_EMAIL', 'op@example.com'),
 
    'contact_type': 'technical'},
 

	
 
fail = False
 

	
 
BADGER_DEFAULT_SVG = 'registrasion/badge.svg'
 
BADGER_DEFAULT_FORM = "registrasion/badge_form.html"
 

	
 
if SECRET_KEY is None:
 
    print("FAILURE: You need to supply a DJANGO_SECRET_KEY "
 
          "environment variable")
 
    fail = True
 

	
 
if PINAX_STRIPE_PUBLIC_KEY is None:
 
    print("FAILURE: You need to supply a STRIPE_PUBLIC_KEY "
 
          "environment variable")
 
    fail = True
 

	
 
if PINAX_STRIPE_SECRET_KEY is None:
 
    print("FAILURE: You need to supply a STRIPE_SECRET_KEY "
 
          "environment variable")
 
    fail = True
 

	
 
if fail:
 
    sys.exit('FAILURE: Missing environment variables.')
 

	
 
### Standard settings
 

	
 
ADMIN_USERNAMES = []
 

	
 
if DEV_MODE and DEV_MODE == "LAPTOP":
 
    CACHES = {
 
        'default': {
 
            'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
 
        }
 
    }
 
else:
 
    CACHES = {
 
        'default': {
 
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
 
            'LOCATION': '127.0.0.1:11211',
 
        },
 
    }
 

	
 

	
 
ALLOWED_HOSTS = ['127.0.0.1', 'localhost', '*']
 

	
 
TIME_ZONE = "US/Pacific"
 
DATE_FORMAT = "F j Y"
 
LANGUAGE_CODE = "en-us"
 

	
 
SITE_ID = int(os.environ.get("SITE_ID", 1))
 
USE_I18N = True
 
USE_L10N = True
 
USE_TZ = True
 

	
 
MEDIA_ROOT = os.environ.get("MEDIA_ROOT", os.path.join(PACKAGE_ROOT, "site_media", "media"))
 
MEDIA_URL = "/site_media/media/"
 

	
 
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static', 'build')
 
STATIC_URL = '/static/build/'
 

	
 
STATICFILES_DIRS = [
 
    os.path.join(PROJECT_ROOT, 'static', 'src'),
 
]
 

	
 
STATICFILES_FINDERS = [
 
    "django.contrib.staticfiles.finders.FileSystemFinder",
 
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
 
    "sass_processor.finders.CssFinder",
 
]
 

	
 
TEMPLATES = [
 
    {
 
        "BACKEND": "django.template.backends.django.DjangoTemplates",
 
        "DIRS": [
 
            os.path.join(PACKAGE_ROOT, "templates"),
 
            os.path.join(DJANGO_ROOT, 'forms/templates')
 
        ],
 
        "APP_DIRS": True,
 
        "OPTIONS": {
 
            "debug": DEBUG,
 
            "context_processors": [
 
                "django.contrib.auth.context_processors.auth",
 
                "django.template.context_processors.debug",
 
                "django.template.context_processors.i18n",
 
                "django.template.context_processors.media",
 
                "django.template.context_processors.static",
 
                "django.template.context_processors.tz",
 
                "django.template.context_processors.request",
 
                "django.contrib.messages.context_processors.messages",
 
                "pinax_theme_bootstrap.context_processors.theme",
 
                "account.context_processors.account",
 
                "symposion.reviews.context_processors.reviews",
 
                "django_settings_export.settings_export",
 
            ],
 
        },
 
    },
 
]
 

	
 
MIDDLEWARE = [
 
    "django.middleware.security.SecurityMiddleware",
 
    "whitenoise.middleware.WhiteNoiseMiddleware",
 
    "django.contrib.sessions.middleware.SessionMiddleware",
 
    "django.middleware.common.CommonMiddleware",
 
    "django.middleware.csrf.CsrfViewMiddleware",
 
    "django.contrib.auth.middleware.AuthenticationMiddleware",
 
    "account.middleware.LocaleMiddleware",
 
    "account.middleware.TimezoneMiddleware",
 
    "djangosaml2.middleware.SamlSessionMiddleware",
 
    "django.contrib.messages.middleware.MessageMiddleware",
 
    "debug_toolbar.middleware.DebugToolbarMiddleware",
 
    "reversion.middleware.RevisionMiddleware",
 
    "waffle.middleware.WaffleMiddleware",
 
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
 
    "django.contrib.flatpages.middleware.FlatpageFallbackMiddleware",
 
    'pinaxcon.monkey_patch.MonkeyPatchMiddleware',
 
]
 

	
 
if DEV_MODE and DEV_MODE == "LAPTOP":
 
    ROOT_URLCONF = "pinaxcon.devmode_urls"
 
else:
 
    ROOT_URLCONF = "pinaxcon.urls"
 

	
 
# Python dotted path to the WSGI application used by Django's runserver.
 
WSGI_APPLICATION = "pinaxcon.wsgi.application"
 

	
 
INSTALLED_APPS = [
 
    "whitenoise.runserver_nostatic",
 
    "django.contrib.admin",
 
    "django.contrib.auth",
 
    "django.contrib.contenttypes",
 
    "django.contrib.flatpages",
 
    "django.contrib.messages",
 
    "django.contrib.sessions",
 
    "django.contrib.sites",
 
    "django.contrib.staticfiles",
 
    "django.contrib.humanize",
 
    "debug_toolbar",
 

	
 
    'djangosaml2',
 

	
 
    # theme
 
    "bootstrapform",
 
    "pinax_theme_bootstrap",
 
    "sass_processor",
 
    "capture_tag",
 

	
 
    # external
 
    "easy_thumbnails",
 
    "taggit",
 
    "reversion",
 
    "sitetree",
 
    "django_jsonfield_backport",
 
    "pinax.eventlog",
 
    "timezone_field",
 

	
 
    # symposion
 
    "symposion",
 
    "symposion.conference",
 
    "symposion.proposals",
 
    "symposion.reviews",
 
    "symposion.schedule",
 
    "symposion.speakers",
 
    "symposion.teams",
 

	
 
    # Registrasion
 
    "registrasion",
 

	
 
    # Registrasion-stripe
 
    "pinax.stripe",
 
    "django_countries",
 
    "registripe",
 

	
 
    #registrasion-desk
 
    "regidesk",
 

	
 
    # admin - required by registrasion ??
 
    "nested_admin",
 

	
 
    # project
 
    "pinaxcon",
 
    "pinaxcon.proposals",
 
    "pinaxcon.registrasion",
 
    "pinaxcon.raffle",
 
    "jquery",
 
    "djangoformsetjs",
 

	
 
    # testing and rollout
 
    "django_nose",
 
    "waffle",
 

	
 
    "crispy_forms",
 

	
 
    "account",
 
]
 

	
 
CRISPY_TEMPLATE_PACK = "bootstrap4"
 

	
 
DEBUG_TOOLBAR_PANELS = [
 
    'debug_toolbar.panels.versions.VersionsPanel',
 
    'debug_toolbar.panels.timer.TimerPanel',
 
    'debug_toolbar.panels.settings.SettingsPanel',
 
    'debug_toolbar.panels.headers.HeadersPanel',
 
    'debug_toolbar.panels.request.RequestPanel',
 
    'debug_toolbar.panels.sql.SQLPanel',
 
    'debug_toolbar.panels.staticfiles.StaticFilesPanel',
 
    'debug_toolbar.panels.cache.CachePanel',
 
    'debug_toolbar.panels.signals.SignalsPanel',
 
    'debug_toolbar.panels.logging.LoggingPanel',
 
    'debug_toolbar.panels.templates.TemplatesPanel',
 
    'debug_toolbar.panels.redirects.RedirectsPanel',
 
]
 

	
 
DEBUG_TOOLBAR_CONFIG = {
 
    'INTERCEPT_REDIRECTS': False,
 
}
 

	
 
INTERNAL_IPS = [
 
    '127.0.0.1',
 
]
 

	
 
from debug_toolbar.panels.logging import collector
 
LOGGING = {
 
    'version': 1,
 
    'disable_existing_loggers': False,
 
    'formatters': {
 
        'verbose': {
 
            'format': '%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s'
 
        },
 
        'simple': {
 
            'format': '%(asctime)s %(levelname)s $(module)s %(message)s'
 
        },
 
    },
 
    'filters': {
 
        'require_debug_false': {
 
            '()': 'django.utils.log.RequireDebugFalse'
 
        }
 
    },
 
    'handlers': {
 
        'console': {
 
            'level': 'DEBUG',
 
            'class': 'logging.StreamHandler',
 
            'formatter': 'simple'
 
        },
 
        'mail_admins': {
 
            'level': 'ERROR',
 
            'filters': ['require_debug_false'],
 
            'class': 'django.utils.log.AdminEmailHandler',
 
        },
 
        'djdt_log': {
 
            'level': 'DEBUG',
 
            'class': 'debug_toolbar.panels.logging.ThreadTrackingHandler',
 
            'collector': collector,
 
        },
 
    },
 
    'loggers': {
 
        'django.request': {
 
            'handlers': ['mail_admins'],
 
            'level': 'ERROR',
 
            'propagate': True,
 
        },
 
        'symposion.request': {
 
            'handlers': ['mail_admins'],
 
            'level': 'DEBUG',
 
            'propagate': True,
 
        },
 
    },
 
    'root': {
 
        'handlers': ['console', 'djdt_log'],
 
        'level': 'DEBUG'
 
    },
 
}
 
FIXTURE_DIRS = [
 
    os.path.join(PROJECT_ROOT, "fixtures"),
 
]
 

	
 
AUTHENTICATION_BACKENDS = [
 
    'symposion.teams.backends.TeamPermissionsBackend',
 
    'django.contrib.auth.backends.ModelBackend',
 
    'djangosaml2.backends.Saml2Backend',
 
]
 

	
 
LOGIN_URL = '/account/login/'
 
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
 

	
 
CONFERENCE_ID = 2
 
PROPOSAL_FORMS = {
 
    "copyleft-compliance": "pinaxcon.proposals.forms.CopyleftComplianceProposalForm",
 
    "sfc-member-project": "pinaxcon.proposals.forms.MemberProjectProposalForm",
 
    "container-days": "pinaxcon.proposals.forms.ContainerDaysProposalForm",
 
    "sustainable-open-source-business": "pinaxcon.proposals.forms.SustainableOpenSourceBusinessProposalForm",
 
    "software-worker-coops": "pinaxcon.proposals.forms.SoftwareWorkerCoopsProposalForm",
 
    "diversity-equity-inclusion": "pinaxcon.proposals.forms.DiversityEquityInclusionProposalForm",
 
    "foss-at-play": "pinaxcon.proposals.forms.FOSSAtPlayProposalForm",
 
    "open-source-ai-data": "pinaxcon.proposals.forms.OpenSourcAIDataProposalForm",
 
    "open-work": "pinaxcon.proposals.forms.OpenWorkProposalForm",
 
    "community": "pinaxcon.proposals.forms.CommunityProposalForm",
 
    "bsd-unix": "pinaxcon.proposals.forms.BSDUnixProposalForm",
 
    "xmpp": "pinaxcon.proposals.forms.XMPPProposalForm",
 
    "science-of-community": "pinaxcon.proposals.forms.ScienceOfCommunityProposalForm",
 
    "aarch64-arm64": "pinaxcon.proposals.forms.AArch64ARM64ProposalForm",
 
    "foss-for-education": "pinaxcon.proposals.forms.FOSSForEducationProposalForm",
 
    "foss-in-daily-life": "pinaxcon.proposals.forms.FOSSInDailyLifeProposalForm",
 
    "security": "pinaxcon.proposals.forms.SecurityForm",
 
    "wildcard": "pinaxcon.proposals.forms.WildCardProposalForm",
 
}
 
MAIN_CONFERENCE_PROPOSAL_KINDS = ("Talk",)
 

	
 
# Registrasion bits:
 
ATTENDEE_PROFILE_MODEL = "pinaxcon.registrasion.models.AttendeeProfile"
 
ATTENDEE_PROFILE_FORM = "pinaxcon.registrasion.forms.ProfileForm"
 
INVOICE_CURRENCY = "USD"
 
GST_RATE =  Decimal('0')
 
TICKET_PRODUCT_CATEGORY = 1
 
TERMS_PRODUCT_CATEGORY = 2
 
ATTENDEE_PROFILE_FORM = "pinaxcon.registrasion.forms.ProfileForm"
 

	
 
#REGIDESK
 
REGIDESK_BOARDING_GROUP = "Ready For Boarding"
 

	
 
# CSRF custom error screen
 
CSRF_FAILURE_VIEW = "pinaxcon.csrf_view.csrf_failure"
 

	
 
# Use nose to run all tests
 
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
 

	
 
# Tell nose to measure coverage on the 'foo' and 'bar' apps
 
NOSE_ARGS = [
 
    '--with-coverage',
 
    '--cover-package=registrasion.controllers,registrasion.models',
 
]
 

	
 
SASS_PROCESSOR_INCLUDE_DIRS = [
 
    os.path.join(PROJECT_ROOT, 'static/src/bootstrap/scss'),
 
    os.path.join(PROJECT_ROOT, 'static/src/scss'),
 
]
 

	
 
xmlsec_binary = '/usr/bin/xmlsec1'
 
if not os.path.isfile(xmlsec_binary):
 
        sys.exit('ERROR: xmlsec1 binary missing, EXITING')
 

	
 
SAML_ATTRIBUTE_MAPPING = {
 
    'uid': ('username', ),
 
    'mail': ('email', ),
 
    'givenName': ('first_name', ),
 
    'sn': ('last_name', ),
 
}
 
SAML_CONFIG = {
 
    'xmlsec_binary': xmlsec_binary,
 
    'entityid': saml2_entityid,
 
    'attribute_map_dir': os.path.join(PACKAGE_ROOT, 'saml2/attribute-maps'),
 
    'service': {
 
        'sp': {
 
            'name': saml2_sp_name,
 
            'endpoints': {
 
                'assertion_consumer_service': [
 
                    saml2_sp_assertion_service,
 
                    ],
 
                'single_logout_service': [
 
                    (saml2_sp_slo_rdir, saml2.BINDING_HTTP_REDIRECT),
 
                    (saml2_sp_slo_post, saml2.BINDING_HTTP_POST),
 
                    ],
 
                },
 
            'logout_requests_signed': True,
 
            'required_attributes': ['uid', 'mail', 'givenName', 'sn'],
 
            'allow_unsolicited': True, # Avoid issues with SameSite cookies for now.
 
            },
 
        },
 
    'metadata': saml2_idp_metadata,
 
    'debug': 0,
 
    'key_file': saml2_signing_key,
 
    'cert_file': saml2_signing_crt,
 
    'encryption_keypairs': [{
 
        'key_file': saml2_encr_key,
 
        'cert_file': saml2_encr_crt,
 
    }],
 
    'contact_person': saml2_contact,
 
    'valid_for': 10,
 
}
 

	
 
if 'SAML_CONFIG_LOADER' in os.environ:
 
    SAML_CONFIG_LOADER = os.environ.get('SAML_CONFIG_LOADER')
 

	
 
DEFAULT_FILE_STORAGE = os.environ.get('DEFAULT_FILE_STORAGE', 'gapc_storage.storage.GoogleCloudStorage')
 
GAPC_STORAGE = {
 
    'num_retries': 2,
 
}
 

	
 
SETTINGS_EXPORT = [
 
    'DEBUG',
 
    'ANALYTICS_KEY',
 
    'TIME_ZONE',
 
    'CONF_START',
 
    'CONFERENCE_EMAIL',
 
]
 

	
 
if DEV_MODE and DEV_MODE == "LAPTOP":
 
    print("ENABLING LAPTOP MODE")
 
    from .devmode_settings import *
 

	
 

	
 
class Category(object):
 
    tickets = []
 

	
 
    @classmethod
 
    def order(cls, ticket) -> int:
 
        return (cls.tickets.index(ticket) + 1) * 10
 

	
 

	
 
@dataclass(frozen=True)
 
class Ticket:
 
    name: str
 
    regular_price: Decimal
 
    earlybird_price: Decimal
 

	
 
    def earlybird_discount(self):
 
        return self.regular_price - self.earlybird_price
 

	
 

	
 
@dataclass(frozen=True)
 
class DinnerTicket:
 
    name: str
 
    price: Decimal
 
    description: str
 
    reservation: timedelta
 
    cat: Category
 

	
 
    def order(self):
 
        return self.cat.order(self)
 

	
 

	
 
class PenguinDinnerTicket(DinnerTicket):
 
    pass
 

	
 

	
 
class SpeakersDinnerTicket(DinnerTicket):
 
    pass
 

	
 

	
 
class SpeakersDinnerCat(Category):
 
    @classmethod
 
    def create(cls, name: str, price: Decimal, description: str, reservation: timedelta) -> SpeakersDinnerTicket:
 
        t = SpeakersDinnerTicket(name, price, description, reservation, cls)
 
        cls.tickets.append(t)
 
        return t
 

	
 

	
 
class PenguinDinnerCat(Category):
 
    @classmethod
 
    def create(cls, name: str, price: Decimal, description: str, reservation: timedelta) -> PenguinDinnerTicket:
 
        t = PenguinDinnerTicket(name, price, description, reservation, cls)
 
        cls.tickets.append(t)
 
        return t
 

	
 

	
 
CONFERENCE_NAME = os.environ.get('CONFERENCE_NAME', 'FOSSY')
 
CONFERENCE_NAME_SHORT = os.environ.get('CONFERENCE_NAME_SHORT', 'FOSSY')
 
CONFERENCE_EMAIL = os.environ.get('CONFERENCE_EMAIL', DEFAULT_FROM_EMAIL)
 
CONF_TZINFO = pytz.timezone(TIME_ZONE)
 
CONF_START = CONF_TZINFO.localize(datetime(2023, 7, 13))
 
CONF_END = CONF_TZINFO.localize(datetime(2023, 7, 16))
 
CONF_MINICONF_END = CONF_TZINFO.localize(datetime(2023, 3, 14, 23, 59))
 
EARLY_BIRD_DEADLINE = CONF_TZINFO.localize(datetime(2023, 1, 28))
 
PENGUIN_DINNER_TICKET_DATE = date(2023, 3, 15)
 
SPEAKER_DINNER_TICKET_DATE = date(2023, 3, 14)
 
PDNS_TICKET_DATE = date(2023, 3, 16)
 

	
 
TSHIRT_PRICE = Decimal("25.00")
 

	
 
CONTRIBUTOR = Ticket("Contributor", Decimal("300.00"), Decimal("250.00"))
 
PROFESSIONAL = Ticket("Professional", Decimal("125.00"), Decimal("100.00"))
 
HOBBYIST = Ticket("Hobbyist", Decimal("70.00"), None)
 
STUDENT = Ticket("Student", Decimal("30.00"), None)
 
MINICONF_ONLY = Ticket("Miniconf Only", Decimal("25.00"), None)
 

	
 
MEDIA = Ticket("Media", Decimal("0.0"), None)
 
SPEAKER = Ticket("Speaker", Decimal("0.0"), None)
 
SPONSOR = Ticket("Sponsor", Decimal("0.0"), None)
 

	
 
CONFERENCE_ORG = Ticket("Conference Organiser", Decimal("0.0"), None)
 
CONFERENCE_VOL = Ticket("Conference Volunteer", Decimal("0.0"), None)
 

	
 
PENGUIN_DINNER = PenguinDinnerCat
 
PENGUIN_DINNER_ADULT = PenguinDinnerCat.create(
 
    "Adult", Decimal("95.00"),
 
    "Includes an adult's meal and full beverage service.",
 
    timedelta(hours=1))
 
PENGUIN_DINNER_CHILD = PenguinDinnerCat.create(
 
    "Child", Decimal("50.00"),
 
    "Children 14 and under. "
 
    "Includes a child's meal and soft drink service.",
 
    timedelta(hours=1))
 
PENGUIN_DINNER_INFANT = PenguinDinnerCat.create(
 
    "Infant", Decimal("0.0"),
 
    "Includes no food or beverage service.",
 
    timedelta(hours=1))
 

	
 
SPEAKERS_DINNER = SpeakersDinnerCat
 

	
 
SPEAKERS_DINNER_ADULT = SpeakersDinnerCat.create(
 
    "Adult", Decimal("100.00"),
 
    "Includes an adult's meal and full beverage service.",
 
    timedelta(hours=1))
 

	
 
# SPEAKERS_DINNER_CHILD = SpeakersDinnerCat.create(
 
#     "Child", Decimal("60.00"),
 
#     "Children 14 and under. "
 
#     "Includes a child's meal and soft drink service.",
 
#     timedelta(hours=1))
 

	
 
# SPEAKERS_DINNER_INFANT = SpeakersDinnerCat.create(
 
#     "Infant", Decimal("00.00"),
 
#     "Infant must be seated in an adult's lap. "
 
#     "No food or beverage service.",
 
#     timedelta(hours=1))
 

	
 

	
 
# Venueless integration
 
VENUELESS_URL = os.environ.get('VENUELESS_URL', None)
 
VENUELESS_AUDIENCE = os.environ.get('VENUELESS_AUDIENCE', "venueless")
 
VENUELESS_TOKEN_ISSUER = os.environ.get('VENUELESS_TOKEN_ISSUER', "any")
 
VENUELESS_SECRET = os.environ.get('VENUELESS_SECRET', SECRET_KEY)
 

	
 

	
 
ACCOUNT_SIGNUP_REDIRECT_URL = '/dashboard/'
 
ACCOUNT_LOGIN_REDIRECT_URL = '/dashboard/'
 

	
 
ADMINS = [('', email) for email in os.environ.get('DJANGO_ADMINS', '').split(',') if email]
 
SERVER_EMAIL = DEFAULT_FROM_EMAIL
 

	
 
if not DEBUG:
 
    # Django recommended security settings.
 
    SECURE_CONTENT_TYPE_NOSNIFF = True
 
    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
 
    SECURE_SSL_REDIRECT = True
 
    SECURE_BROWSER_XSS_FILTER = True
 
    SESSION_COOKIE_SECURE = True
 
    CSRF_COOKIE_SECURE = True
 
    CSRF_COOKIE_HTTPONLY = True
 
    X_FRAME_OPTIONS = 'DENY'
 

	
 

	
 
    SILENCED_SYSTEM_CHECKS = [
 
        # HSTS is handled by Nginx.
 
        'security.W004',
 
        # Don't want to preload HSTS at this stage.
 
        'security.W021']
vendor/registrasion/registrasion/migrations/0009_auto_20230424_1449.py
Show inline comments
 
new file 100644
 
# Generated by Django 2.2.28 on 2023-04-24 21:49
 

	
 
from django.db import migrations, models
 

	
 

	
 
class Migration(migrations.Migration):
 

	
 
    dependencies = [
 
        ('registrasion', '0008_auto_20170930_1843'),
 
    ]
 

	
 
    operations = [
 
        migrations.AlterField(
 
            model_name='category',
 
            name='required',
 
            field=models.BooleanField(blank=True, help_text='If enabled, a user must select an item from this category.'),
 
        ),
 
        migrations.AlterField(
 
            model_name='speakerdiscount',
 
            name='is_copresenter',
 
            field=models.BooleanField(blank=True, help_text='This condition is met if the user is a copresenter of a presentation.'),
 
        ),
 
        migrations.AlterField(
 
            model_name='speakerdiscount',
 
            name='is_presenter',
 
            field=models.BooleanField(blank=True, help_text='This condition is met if the user is the primary presenter of a presentation.'),
 
        ),
 
        migrations.AlterField(
 
            model_name='speakerflag',
 
            name='is_copresenter',
 
            field=models.BooleanField(blank=True, help_text='This condition is met if the user is a copresenter of a presentation.'),
 
        ),
 
        migrations.AlterField(
 
            model_name='speakerflag',
 
            name='is_presenter',
 
            field=models.BooleanField(blank=True, help_text='This condition is met if the user is the primary presenter of a presentation.'),
 
        ),
 
    ]
0 comments (0 inline, 0 general)