diff --git a/conservancy/usethesource/forms.py b/conservancy/usethesource/forms.py
index 497c66f440157847382f16da2389af7e3c530a17..e7618c6de57ddf9cc41bfb2989f9b75b47e2c089 100644
--- a/conservancy/usethesource/forms.py
+++ b/conservancy/usethesource/forms.py
@@ -1,6 +1,6 @@
from django import forms
-from .models import Comment
+from .models import Comment, SourceOffer
class CommentForm(forms.ModelForm):
@@ -17,3 +17,14 @@ class CommentForm(forms.ModelForm):
class DownloadForm(forms.Form):
agree = forms.BooleanField(label="I understand that the goal of this process is to determine compliance with FOSS licenses, and that in downloading the source code candidate and/or firmware image, I am assisting SFC as a volunteer to investigate that question. I, therefore, promise and represent that I will not copy, distribute, modify, or otherwise use this source code candidate and/or firmware image for any purpose other than to help SFC evaluate the source code candidate for compliance with the terms of FOSS licenses, including but not limited to any version of the GNU General Public License. Naturally, if I determine in good faith that portions of the source code candidate and/or firmware image are subject to a FOSS license and are compliant with it, I may copy, distribute, modify, or otherwise use those portions in accordance with the FOSS license, and I take full responsibility for that determination and subsequent use.")
+
+
+class SourceOfferForm(forms.ModelForm):
+ class Meta:
+ model = SourceOffer
+ fields = ['vendor', 'device', 'photo']
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self.fields['photo'].widget.attrs['capture'] = 'camera'
+ self.fields['photo'].widget.attrs['accept'] = 'image/*'
diff --git a/conservancy/usethesource/migrations/0009_sourceoffer.py b/conservancy/usethesource/migrations/0009_sourceoffer.py
new file mode 100644
index 0000000000000000000000000000000000000000..5eb1094d4c29625e13b2d63036f9fdcee027bc5e
--- /dev/null
+++ b/conservancy/usethesource/migrations/0009_sourceoffer.py
@@ -0,0 +1,30 @@
+# Generated by Django 4.2.11 on 2024-07-22 08:59
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('usethesource', '0008_comment_attribute_to'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='SourceOffer',
+ fields=[
+ (
+ 'id',
+ models.AutoField(
+ auto_created=True,
+ primary_key=True,
+ serialize=False,
+ verbose_name='ID',
+ ),
+ ),
+ ('vendor', models.CharField(max_length=50, verbose_name='Vendor name')),
+ ('device', models.CharField(max_length=50, verbose_name='Device name')),
+ ('photo', models.ImageField(upload_to='usethesource/offers')),
+ ],
+ ),
+ ]
diff --git a/conservancy/usethesource/models.py b/conservancy/usethesource/models.py
index 6b070e5443674e96c11d27e581ac69f51a4affc3..64e817f5a6d5d048761d27019160667f5d21512d 100644
--- a/conservancy/usethesource/models.py
+++ b/conservancy/usethesource/models.py
@@ -67,3 +67,9 @@ class Comment(models.Model):
class Meta:
ordering = ['id']
+
+
+class SourceOffer(models.Model):
+ vendor = models.CharField('Vendor name', max_length=50)
+ device = models.CharField('Device name', max_length=50)
+ photo = models.ImageField(upload_to='usethesource/offers')
diff --git a/conservancy/usethesource/templates/usethesource/upload_offer.html b/conservancy/usethesource/templates/usethesource/upload_offer.html
new file mode 100644
index 0000000000000000000000000000000000000000..6c93a6a70a7d6c60aef37692b4f03272a07e8238
--- /dev/null
+++ b/conservancy/usethesource/templates/usethesource/upload_offer.html
@@ -0,0 +1,49 @@
+{% extends "usethesource/base.html" %}
+
+{% block title %}Upload an offer for source - Software Freedom Conservancy{% endblock %}
+
+{% block head %}
+ {{ block.super }}
+
+{% endblock %}
+
+{% block content %}
+ {{ block.super }}
+
+ Upload an offer for source
+