diff --git a/pinaxcon/proposals/admin.py b/pinaxcon/proposals/admin.py
index 4d3414d5..c28dd034 100644
--- a/pinaxcon/proposals/admin.py
+++ b/pinaxcon/proposals/admin.py
@@ -21,17 +21,12 @@ class CategoryAdmin(admin.ModelAdmin):
models_to_register = [
+ models.CampKDEProposal,
models.DatabasesProposal,
- models.DistrosProposal,
models.FOSSInDailyLifeProposal,
- models.FOSSInEducationProposal,
- models.LegalIssuesProposal,
- models.LibreGraphicsProposal,
- models.LinuxKernalProposal,
- models.MobileDevicesProposal,
- models.P2PLocalFirstProposal,
- models.ScienceOfCommunityProposal,
- models.SupportingUserGroupsProposal,
+ models.LinuxKernelProposal,
+ models.OpenSourceGovernanceAndCommunitySustainabilityProposal,
+ models.RightToRepairProposal,
models.WildCardProposal,
models.XMPPProposal,
]
diff --git a/pinaxcon/proposals/forms.py b/pinaxcon/proposals/forms.py
index 37a4a413..d73c66c8 100644
--- a/pinaxcon/proposals/forms.py
+++ b/pinaxcon/proposals/forms.py
@@ -61,15 +61,15 @@ class MiniconfProposalForm(ProposalForm):
pass
-class DatabasesProposalForm(MiniconfProposalForm):
+class CampKDEProposalForm(MiniconfProposalForm):
class Meta:
- model = models.DatabasesProposal
+ model = models.CampKDEProposal
fields = TALK_FORMAT_FIELDS
-class DistrosProposalForm(MiniconfProposalForm):
+class DatabasesProposalForm(MiniconfProposalForm):
class Meta:
- model = models.DistrosProposal
+ model = models.DatabasesProposal
fields = TALK_FORMAT_FIELDS
@@ -79,57 +79,21 @@ class FOSSInDailyLifeProposalForm(MiniconfProposalForm):
fields = TALK_FORMAT_FIELDS
-class FOSSInEducationProposalForm(MiniconfProposalForm):
- class Meta:
- model = models.FOSSInEducationProposal
- fields = TALK_FORMAT_FIELDS
-
-
-class LegalIssuesProposalForm(MiniconfProposalForm):
- class Meta:
- model = models.LegalIssuesProposal
- fields = TALK_FORMAT_FIELDS
-
-
-class LibreGraphicsProposalForm(MiniconfProposalForm):
- class Meta:
- model = models.LibreGraphicsProposal
- fields = TALK_FORMAT_FIELDS
-
-
class LinuxKernelProposalForm(MiniconfProposalForm):
class Meta:
- model = models.LinuxKernalProposal
+ model = models.LinuxKernelProposal
fields = TALK_FORMAT_FIELDS
-class MobileDevicesProposalForm(MiniconfProposalForm):
+class OpenSourceGovernanceAndCommunitySustainabilityProposalForm(MiniconfProposalForm):
class Meta:
- model = models.MobileDevicesProposal
+ model = models.OpenSourceGovernanceAndCommunitySustainabilityProposal
fields = TALK_FORMAT_FIELDS
-class P2PLocalFirstProposalForm(MiniconfProposalForm):
+class RightToRepairProposalForm(MiniconfProposalForm):
class Meta:
- model = models.P2PLocalFirstProposal
- fields = TALK_FORMAT_FIELDS
-
-
-class ScienceOfCommunityProposalForm(MiniconfProposalForm):
- class Meta:
- model = models.ScienceOfCommunityProposal
- fields = TALK_FORMAT_FIELDS
-
-
-class SupportingUserGroupsProposalForm(MiniconfProposalForm):
- class Meta:
- model = models.SupportingUserGroupsProposal
- fields = TALK_FORMAT_FIELDS
-
-
-class XMPPProposalForm(MiniconfProposalForm):
- class Meta:
- model = models.XMPPProposal
+ model = models.RightToRepairProposal
fields = TALK_FORMAT_FIELDS
@@ -137,3 +101,9 @@ class WildCardProposalForm(MiniconfProposalForm):
class Meta:
model = models.WildCardProposal
fields = TALK_FORMAT_FIELDS
+
+
+class XMPPProposalForm(MiniconfProposalForm):
+ class Meta:
+ model = models.XMPPProposal
+ fields = TALK_FORMAT_FIELDS
diff --git a/pinaxcon/proposals/migrations/0019_auto_20260319_0640.py b/pinaxcon/proposals/migrations/0019_auto_20260319_0640.py
new file mode 100644
index 00000000..709089ce
--- /dev/null
+++ b/pinaxcon/proposals/migrations/0019_auto_20260319_0640.py
@@ -0,0 +1,138 @@
+# Generated by Django 2.2.28 on 2026-03-19 06:40
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('symposion_schedule', '0009_presentation_videos'),
+ ('symposion_speakers', '0014_auto_20260319_0640'),
+ ('symposion_proposals', '0004_auto_20260319_0640'),
+ ('symposion_reviews', '0001_initial'),
+ ('proposals', '0018_mobiledevicesproposal'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='CampKDEProposal',
+ 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': 'Camp KDE talk proposal',
+ },
+ bases=('symposion_proposals.proposalbase',),
+ ),
+ migrations.CreateModel(
+ name='OpenSourceGovernanceAndCommunitySustainabilityProposal',
+ 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': 'Open Source Governance and Community Sustainability talk proposal',
+ },
+ bases=('symposion_proposals.proposalbase',),
+ ),
+ migrations.CreateModel(
+ name='RightToRepairProposal',
+ 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': 'Right to Repair talk proposal',
+ },
+ bases=('symposion_proposals.proposalbase',),
+ ),
+ migrations.RenameModel(
+ old_name='LinuxKernalProposal',
+ new_name='LinuxKernelProposal',
+ ),
+ migrations.RemoveField(
+ model_name='fossineducationproposal',
+ name='proposalbase_ptr',
+ ),
+ migrations.RemoveField(
+ model_name='legalissuesproposal',
+ name='proposalbase_ptr',
+ ),
+ migrations.RemoveField(
+ model_name='libregraphicsproposal',
+ name='proposalbase_ptr',
+ ),
+ migrations.RemoveField(
+ model_name='mobiledevicesproposal',
+ name='proposalbase_ptr',
+ ),
+ migrations.RemoveField(
+ model_name='p2plocalfirstproposal',
+ name='proposalbase_ptr',
+ ),
+ migrations.RemoveField(
+ model_name='scienceofcommunityproposal',
+ name='proposalbase_ptr',
+ ),
+ migrations.RemoveField(
+ model_name='supportingusergroupsproposal',
+ name='proposalbase_ptr',
+ ),
+ migrations.AlterModelOptions(
+ name='linuxkernelproposal',
+ options={'verbose_name': 'Linux Kernel talk proposal'},
+ ),
+ migrations.DeleteModel(
+ name='DistrosProposal',
+ ),
+ migrations.DeleteModel(
+ name='FOSSInEducationProposal',
+ ),
+ migrations.DeleteModel(
+ name='LegalIssuesProposal',
+ ),
+ migrations.DeleteModel(
+ name='LibreGraphicsProposal',
+ ),
+ migrations.DeleteModel(
+ name='MobileDevicesProposal',
+ ),
+ migrations.DeleteModel(
+ name='P2PLocalFirstProposal',
+ ),
+ migrations.DeleteModel(
+ name='ScienceOfCommunityProposal',
+ ),
+ migrations.DeleteModel(
+ name='SupportingUserGroupsProposal',
+ ),
+ ]
diff --git a/pinaxcon/proposals/models.py b/pinaxcon/proposals/models.py
index 88f8c18b..960523d5 100644
--- a/pinaxcon/proposals/models.py
+++ b/pinaxcon/proposals/models.py
@@ -160,66 +160,41 @@ class MiniconfSessionProposal(Proposal):
abstract = True
+class CampKDEProposal(MiniconfSessionProposal):
+ class Meta:
+ verbose_name = "Camp KDE talk proposal"
+
+
class DatabasesProposal(MiniconfSessionProposal):
class Meta:
verbose_name = "Databases talk proposal"
-class DistrosProposal(MiniconfSessionProposal):
- class Meta:
- verbose_name = "Distros talk proposal"
-
-
class FOSSInDailyLifeProposal(MiniconfSessionProposal):
class Meta:
verbose_name = "FOSS in Daily Life talk proposal"
-class FOSSInEducationProposal(MiniconfSessionProposal):
+class LinuxKernelProposal(MiniconfSessionProposal):
class Meta:
- verbose_name = "FOSS in Education talk proposal"
+ verbose_name = "Linux Kernel talk proposal"
-class LegalIssuesProposal(MiniconfSessionProposal):
+class OpenSourceGovernanceAndCommunitySustainabilityProposal(MiniconfSessionProposal):
class Meta:
- verbose_name = "Legal Issues talk proposal"
+ verbose_name = "Open Source Governance and Community Sustainability talk proposal"
-class LibreGraphicsProposal(MiniconfSessionProposal):
+class RightToRepairProposal(MiniconfSessionProposal):
class Meta:
- verbose_name = "Libre Graphics talk proposal"
-
-
-class LinuxKernalProposal(MiniconfSessionProposal):
- class Meta:
- verbose_name = "Linux Kernal talk proposal"
-
-
-class MobileDevicesProposal(MiniconfSessionProposal):
- class Meta:
- verbose_name = "Mobile Devices talk proposal"
-
-
-class P2PLocalFirstProposal(MiniconfSessionProposal):
- class Meta:
- verbose_name = "Peer-to-Peer and Local First talk proposal"
-
-
-class ScienceOfCommunityProposal(MiniconfSessionProposal):
- class Meta:
- verbose_name = "Science of Community talk proposal"
-
-
-class SupportingUserGroupsProposal(MiniconfSessionProposal):
- class Meta:
- verbose_name = "Supporting User Groups talk proposal"
-
-
-class XMPPProposal(MiniconfSessionProposal):
- class Meta:
- verbose_name = "XMPP talk proposal"
+ verbose_name = "Right to Repair talk proposal"
class WildCardProposal(MiniconfSessionProposal):
class Meta:
verbose_name = "Wild card talk proposal"
+
+
+class XMPPProposal(MiniconfSessionProposal):
+ class Meta:
+ verbose_name = "XMPP talk proposal"
diff --git a/pinaxcon/settings.py b/pinaxcon/settings.py
index 7c8ce0b3..bcc13dd2 100644
--- a/pinaxcon/settings.py
+++ b/pinaxcon/settings.py
@@ -399,17 +399,12 @@ MARKDOWNIFY = {
CONFERENCE_ID = 5
PROPOSAL_FORMS = {
+ "camp-kde": "pinaxcon.proposals.forms.CampKDEProposalForm",
"databases": "pinaxcon.proposals.forms.DatabasesProposalForm",
- "distros": "pinaxcon.proposals.forms.DistrosProposalForm",
"foss-in-daily-life": "pinaxcon.proposals.forms.FOSSInDailyLifeProposalForm",
- "foss-in-education": "pinaxcon.proposals.forms.FOSSInEducationProposalForm",
- "legal-issues": "pinaxcon.proposals.forms.LegalIssuesProposalForm",
- "libre-graphics": "pinaxcon.proposals.forms.LibreGraphicsProposalForm",
"linux-kernel": "pinaxcon.proposals.forms.LinuxKernelProposalForm",
- "mobile-devices": "pinaxcon.proposals.forms.MobileDevicesProposalForm",
- "peer-to-peer-local-first": "pinaxcon.proposals.forms.P2PLocalFirstProposalForm",
- "science-of-community": "pinaxcon.proposals.forms.ScienceOfCommunityProposalForm",
- "supporting-user-groups": "pinaxcon.proposals.forms.SupportingUserGroupsProposalForm",
+ "open-source-governance-and-community-sustainability": "pinaxcon.proposals.forms.OpenSourceGovernanceAndCommunitySustainabilityProposalForm",
+ "right-to-repair": "pinaxcon.proposals.forms.RightToRepairProposalForm",
"xmpp": "pinaxcon.proposals.forms.XMPPProposalForm",
"wild-card": "pinaxcon.proposals.forms.WildCardProposalForm",
}