Add media upload

- Create requirements file
This commit is contained in:
MatthiasSaihttam 2021-04-25 13:09:30 -04:00
parent c2bd957d9b
commit 118614eeff
7 changed files with 64 additions and 3 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
/.idea
/db.sqlite3
/static
/media
/log
stale_outputs_checked
__pycache__

View File

@ -0,0 +1,18 @@
# Generated by Django 3.1.7 on 2021-04-20 16:19
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0003_thought_uuid'),
]
operations = [
migrations.AddField(
model_name='thought',
name='media',
field=models.FileField(blank=True, upload_to=''),
),
]

View File

@ -9,3 +9,4 @@ class Thought(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, editable=False)
posted = models.DateTimeField(auto_now_add=True)
timezone_offset = models.IntegerField() # The number of minutes behind UTC we were when this was posted
media = models.FileField(upload_to="", blank=True) # A single image, video, or sound clip per post

View File

@ -19,6 +19,7 @@
<textarea name="text" id="text" class="thought" rows="1" placeholder="What are you thinking?"></textarea>
<textarea name="extended_text" id="extended_text" class="thought" rows="2" placeholder="Anything else?"></textarea>
<input type="hidden" name="timezone_offset" id="timezone_offset">
<input type="file" name="media" id="media"><br>
<input type="submit" id="post-button" value="Submit">
</form>
@ -86,7 +87,7 @@
//And we have to set it this first time
//This also effectively doubles the padding value we set in CSS
box.style.height = box.scrollHeight + "px";
box.addEventListener("input", e => {
box.addEventListener("input", evt => {
box.style.height = "auto";
box.style.height = box.scrollHeight + "px";
});

View File

@ -1,11 +1,23 @@
import uuid
import magic
from django.http import HttpResponse
from django.shortcuts import render
from django.utils import timezone
from .models import Thought
# A dict mapping allowed mime types to file extensions
ALLOWED_MEDIA_TYPES = {
"image/png": "png",
"image/jpeg": "jpeg",
"audio/x-m4a": "mp4",
"audio/mp4": "mp4",
"audio/mp3": "mp3",
"video/mp4": "mp4",
"video/quicktime": "mov",
}
def index(request):
authenticated = False
@ -52,11 +64,30 @@ def post(request):
if len(request.POST["text"]) > 140:
return HttpResponse("Content too long", status=400)
Thought(
thought = Thought(
text=request.POST["text"],
extended_text=request.POST["extended_text"],
timezone_offset=request.POST["timezone_offset"]
).save()
)
if "media" in request.FILES:
f = request.FILES["media"]
# 16 MB file size limit.
if f.size > 2**24:
return HttpResponse("Content too long", status=400)
chunk = next(f.chunks(chunk_size=2048))
media_type = magic.from_buffer(chunk, mime="True")
if media_type not in ALLOWED_MEDIA_TYPES:
return HttpResponse("Invalid media type", status=400)
f.name = f"{thought.uuid}.{ALLOWED_MEDIA_TYPES[media_type]}"
thought.media = request.FILES["media"]
thought.save()
return render(request, "whispermaphone/post.html", {})

5
requirements.txt Normal file
View File

@ -0,0 +1,5 @@
Django~=3.2
python-magic~=0.4.22
bleach~=3.3.0
Pygments~=2.8.1
Markdown~=3.3.4

View File

@ -74,6 +74,7 @@ DATABASES = {
}
}
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/
@ -95,3 +96,6 @@ USE_TZ = True
STATIC_URL = '/static/'
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
STATIC_ROOT = BASE_DIR / "static/"
MEDIA_ROOT = BASE_DIR / "media/"
MEDIA_URL = "/media/"