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",)