From 35e8c0c7e8f5ba9f135eac2ffb10200fb86902cc Mon Sep 17 00:00:00 2001 From: Ben Sturmfels Date: Wed, 1 Apr 2026 20:16:34 +1100 Subject: [PATCH] Add further tracks --- ROLLING OVER.md | 12 +- pinaxcon/proposals/admin.py | 5 + pinaxcon/proposals/forms.py | 34 ++++++ ...inproposal_scienceofcommunityproposal_s.py | 115 ++++++++++++++++++ pinaxcon/proposals/models.py | 25 ++++ pinaxcon/settings.py | 7 +- 6 files changed, 196 insertions(+), 2 deletions(-) create mode 100644 pinaxcon/proposals/migrations/0020_fediverseproposal_fossandresearchcomputingproposal_gnutoolchainproposal_scienceofcommunityproposal_s.py diff --git a/ROLLING OVER.md b/ROLLING OVER.md index b9448428..de37e784 100644 --- a/ROLLING OVER.md +++ b/ROLLING OVER.md @@ -1,4 +1,4 @@ -# Rolling over for a new conference +# Rolling over and setting up for a new conference This website collects a limited amount of personally identifiable information for the purposes of organizing a conference. In the interests of security, we've chosen to reset the site for each conference to limit the amount of information that could potentially ever be exposed in the event of a vulnerability. @@ -111,3 +111,13 @@ Find and update all uses of 2026 and the conference dates in this codebase. Update flatpages such as the "/" home page. Update the Django "site" in the Admin. + + +# Step 6: Update tracks/miniconfs + +These are done in code. See commits from previous years adding/modifying tracks. Essentially you need to modify `pinaxcon/proposals/admin.py`, `.../forms.py`, `.../models.py` and `pinaxcon/settings.py`. Then run `makemigrations` and `migrate`. + + +# Step 7: Update teams + +In the Django Admin, update the teams to match the tracks. These will be used to control who has permission to review which proposals. diff --git a/pinaxcon/proposals/admin.py b/pinaxcon/proposals/admin.py index c28dd034..c6825a8b 100644 --- a/pinaxcon/proposals/admin.py +++ b/pinaxcon/proposals/admin.py @@ -23,10 +23,15 @@ class CategoryAdmin(admin.ModelAdmin): models_to_register = [ models.CampKDEProposal, models.DatabasesProposal, + models.FOSSAndResearchComputingProposal, models.FOSSInDailyLifeProposal, + models.FediverseProposal, + models.GNUToolchainProposal, models.LinuxKernelProposal, models.OpenSourceGovernanceAndCommunitySustainabilityProposal, models.RightToRepairProposal, + models.ScienceOfCommunityProposal, + models.StudentPresentationsProposal, models.WildCardProposal, models.XMPPProposal, ] diff --git a/pinaxcon/proposals/forms.py b/pinaxcon/proposals/forms.py index d73c66c8..d84fe72c 100644 --- a/pinaxcon/proposals/forms.py +++ b/pinaxcon/proposals/forms.py @@ -107,3 +107,37 @@ class XMPPProposalForm(MiniconfProposalForm): class Meta: model = models.XMPPProposal fields = TALK_FORMAT_FIELDS + + +class FediverseProposalForm(MiniconfProposalForm): + class Meta: + model = models.FediverseProposal + fields = TALK_FORMAT_FIELDS + + +class ScienceOfCommunityProposalForm(MiniconfProposalForm): + class Meta: + model = models.ScienceOfCommunityProposal + fields = TALK_FORMAT_FIELDS + + +class FOSSAndResearchComputingProposalForm(MiniconfProposalForm): + class Meta: + model = models.FOSSAndResearchComputingProposal + fields = TALK_FORMAT_FIELDS + + +class StudentPresentationsProposalForm(MiniconfProposalForm): + class Meta: + model = models.StudentPresentationsProposal + fields = TALK_FORMAT_FIELDS +class ProposalForm(MiniconfProposalForm): + class Meta: + model = models.Proposal + fields = TALK_FORMAT_FIELDS + + +class GNUToolchainProposalForm(MiniconfProposalForm): + class Meta: + model = models.GNUToolchainProposal + fields = TALK_FORMAT_FIELDS diff --git a/pinaxcon/proposals/migrations/0020_fediverseproposal_fossandresearchcomputingproposal_gnutoolchainproposal_scienceofcommunityproposal_s.py b/pinaxcon/proposals/migrations/0020_fediverseproposal_fossandresearchcomputingproposal_gnutoolchainproposal_scienceofcommunityproposal_s.py new file mode 100644 index 00000000..d6216f84 --- /dev/null +++ b/pinaxcon/proposals/migrations/0020_fediverseproposal_fossandresearchcomputingproposal_gnutoolchainproposal_scienceofcommunityproposal_s.py @@ -0,0 +1,115 @@ +# Generated by Django 2.2.28 on 2026-04-01 02:03 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('symposion_proposals', '0004_auto_20260319_0640'), + ('proposals', '0019_auto_20260319_0640'), + ] + + operations = [ + migrations.CreateModel( + name='FediverseProposal', + 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 ( CC BY-NC-SA 4.0) 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 Creative Commons Attribution-ShareAlike 4.0 International")), + ('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': 'Fediverse talk proposal', + }, + bases=('symposion_proposals.proposalbase',), + ), + migrations.CreateModel( + name='FOSSAndResearchComputingProposal', + 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 ( CC BY-NC-SA 4.0) 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 Creative Commons Attribution-ShareAlike 4.0 International")), + ('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': 'FOSS and Research Computing talk proposal', + }, + bases=('symposion_proposals.proposalbase',), + ), + migrations.CreateModel( + name='GNUToolchainProposal', + 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 ( CC BY-NC-SA 4.0) 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 Creative Commons Attribution-ShareAlike 4.0 International")), + ('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': 'GNUToolchain and other development tools talk proposal', + }, + bases=('symposion_proposals.proposalbase',), + ), + migrations.CreateModel( + name='ScienceOfCommunityProposal', + 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 ( CC BY-NC-SA 4.0) 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 Creative Commons Attribution-ShareAlike 4.0 International")), + ('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': 'Science of Community talk proposal', + }, + bases=('symposion_proposals.proposalbase',), + ), + migrations.CreateModel( + name='StudentPresentationsProposal', + 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 ( CC BY-NC-SA 4.0) 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 Creative Commons Attribution-ShareAlike 4.0 International")), + ('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': 'Student talks and presentations proposal', + }, + bases=('symposion_proposals.proposalbase',), + ), + ] diff --git a/pinaxcon/proposals/models.py b/pinaxcon/proposals/models.py index 960523d5..90a28098 100644 --- a/pinaxcon/proposals/models.py +++ b/pinaxcon/proposals/models.py @@ -198,3 +198,28 @@ class WildCardProposal(MiniconfSessionProposal): class XMPPProposal(MiniconfSessionProposal): class Meta: verbose_name = "XMPP talk proposal" + + +class FediverseProposal(MiniconfSessionProposal): + class Meta: + verbose_name = "Fediverse talk proposal" + + +class ScienceOfCommunityProposal(MiniconfSessionProposal): + class Meta: + verbose_name = "Science of Community talk proposal" + + +class FOSSAndResearchComputingProposal(MiniconfSessionProposal): + class Meta: + verbose_name = "FOSS and Research Computing talk proposal" + + +class StudentPresentationsProposal(MiniconfSessionProposal): + class Meta: + verbose_name = "Student talks and presentations proposal" + + +class GNUToolchainProposal(MiniconfSessionProposal): + class Meta: + verbose_name = "GNUToolchain and other development tools talk proposal" diff --git a/pinaxcon/settings.py b/pinaxcon/settings.py index bcc13dd2..b8e3b46b 100644 --- a/pinaxcon/settings.py +++ b/pinaxcon/settings.py @@ -401,12 +401,17 @@ CONFERENCE_ID = 5 PROPOSAL_FORMS = { "camp-kde": "pinaxcon.proposals.forms.CampKDEProposalForm", "databases": "pinaxcon.proposals.forms.DatabasesProposalForm", + "fediverse": "pinaxcon.proposals.forms.FediverseProposalForm", + "foss-and-research-computing": "pinaxcon.proposals.forms.FOSSAndResearchComputingProposalForm", "foss-in-daily-life": "pinaxcon.proposals.forms.FOSSInDailyLifeProposalForm", + "gnu-toolchain": "pinaxcon.proposals.forms.GNUToolchainProposalForm", "linux-kernel": "pinaxcon.proposals.forms.LinuxKernelProposalForm", "open-source-governance-and-community-sustainability": "pinaxcon.proposals.forms.OpenSourceGovernanceAndCommunitySustainabilityProposalForm", "right-to-repair": "pinaxcon.proposals.forms.RightToRepairProposalForm", - "xmpp": "pinaxcon.proposals.forms.XMPPProposalForm", + "science-of-community": "pinaxcon.proposals.forms.ScienceOfCommunityProposalForm", + "student-presentations": "pinaxcon.proposals.forms.StudentPresentationsProposalForm", "wild-card": "pinaxcon.proposals.forms.WildCardProposalForm", + "xmpp": "pinaxcon.proposals.forms.XMPPProposalForm", } MAIN_CONFERENCE_PROPOSAL_KINDS = ("Talk",)