Store background images in DB, persist SQLite via volume
This commit is contained in:
parent
5c8c57f04f
commit
978b6fa24b
7 changed files with 22 additions and 36 deletions
|
|
@ -11,7 +11,7 @@ RUN pip install --no-cache-dir -r requirements.txt gunicorn
|
|||
|
||||
COPY . .
|
||||
|
||||
RUN python manage.py collectstatic --noinput
|
||||
RUN python manage.py collectstatic --noinput && mkdir -p /app/data
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
# Generated by Django 4.2.29 on 2026-03-15 21:37
|
||||
|
||||
import accounts.models
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
|
|
@ -13,7 +10,7 @@ class Migration(migrations.Migration):
|
|||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='userprofile',
|
||||
name='background_image',
|
||||
field=models.FileField(blank=True, null=True, upload_to=accounts.models._bg_upload_path),
|
||||
name='background_image_data',
|
||||
field=models.TextField(blank=True),
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -4,17 +4,12 @@ from django.db.models.signals import post_save
|
|||
from django.dispatch import receiver
|
||||
|
||||
|
||||
def _bg_upload_path(instance, filename):
|
||||
ext = filename.rsplit('.', 1)[-1].lower()
|
||||
return f'backgrounds/bg_{instance.user_id}.{ext}'
|
||||
|
||||
|
||||
class UserProfile(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
|
||||
lastfm_session_key = models.CharField(max_length=100, blank=True)
|
||||
lastfm_username = models.CharField(max_length=100, blank=True)
|
||||
lastfm_scrobble = models.BooleanField(default=True)
|
||||
background_image = models.FileField(upload_to=_bg_upload_path, null=True, blank=True)
|
||||
background_image_data = models.TextField(blank=True) # base64 data URL
|
||||
|
||||
def has_lastfm(self) -> bool:
|
||||
return bool(self.lastfm_session_key)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import os
|
||||
import base64
|
||||
from django.conf import settings
|
||||
from django.contrib.auth import authenticate, login, get_user_model
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
|
@ -123,35 +123,29 @@ def upload_background(request):
|
|||
return JsonResponse({'error': 'no file'}, status=400)
|
||||
|
||||
ext = f.name.rsplit('.', 1)[-1].lower() if '.' in f.name else ''
|
||||
if ext not in ('jpg', 'jpeg', 'png', 'webp'):
|
||||
mime_map = {'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'png': 'image/png', 'webp': 'image/webp'}
|
||||
if ext not in mime_map:
|
||||
return JsonResponse({'error': 'only jpg, png, or webp allowed'}, status=400)
|
||||
|
||||
if f.size > settings.BG_MAX_BYTES:
|
||||
return JsonResponse({'error': 'file too large (max 5 MB)'}, status=400)
|
||||
|
||||
profile = request.user.profile
|
||||
# Delete old file from disk before replacing
|
||||
if profile.background_image:
|
||||
old_path = profile.background_image.path
|
||||
if os.path.exists(old_path):
|
||||
os.remove(old_path)
|
||||
data = base64.b64encode(f.read()).decode('ascii')
|
||||
data_url = f"data:{mime_map[ext]};base64,{data}"
|
||||
|
||||
profile.background_image = f
|
||||
profile.save(update_fields=['background_image'])
|
||||
return JsonResponse({'ok': True, 'url': profile.background_image.url})
|
||||
profile = request.user.profile
|
||||
profile.background_image_data = data_url
|
||||
profile.save(update_fields=['background_image_data'])
|
||||
return JsonResponse({'ok': True, 'url': data_url})
|
||||
|
||||
|
||||
@login_required
|
||||
@require_http_methods(['POST'])
|
||||
def delete_background(request):
|
||||
profile = request.user.profile
|
||||
if profile.background_image:
|
||||
path = profile.background_image.path
|
||||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
profile.background_image = None
|
||||
profile.save(update_fields=['background_image'])
|
||||
return JsonResponse({'ok': True})
|
||||
profile.background_image_data = ''
|
||||
profile.save(update_fields=['background_image_data'])
|
||||
return redirect('settings')
|
||||
|
||||
|
||||
@login_required
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ WSGI_APPLICATION = 'diora.wsgi.application'
|
|||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': BASE_DIR / 'db.sqlite3',
|
||||
'NAME': BASE_DIR / 'data' / 'db.sqlite3',
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@
|
|||
<!-- Background section -->
|
||||
<section class="settings-section">
|
||||
<h2>Background</h2>
|
||||
{% if request.user.profile.background_image %}
|
||||
{% if request.user.profile.background_image_data %}
|
||||
<p>
|
||||
<img src="{{ request.user.profile.background_image.url }}" class="bg-preview" alt="Your background">
|
||||
<img src="{{ request.user.profile.background_image_data }}" class="bg-preview" alt="Your background">
|
||||
</p>
|
||||
<form method="post" action="{% url 'delete_background' %}" class="inline-form">
|
||||
{% csrf_token %}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,10 @@
|
|||
<link rel="apple-touch-icon" href="/static/icon-192.png">
|
||||
<link rel="stylesheet" href="/static/css/app.css">
|
||||
<title>{% block title %}diora{% endblock %}</title>
|
||||
{% if user.is_authenticated and user.profile.background_image %}
|
||||
{% if user.is_authenticated and user.profile.background_image_data %}
|
||||
<style>
|
||||
body {
|
||||
background-image: url('{{ user.profile.background_image.url }}');
|
||||
background-image: url('{{ user.profile.background_image_data }}');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-attachment: fixed;
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
</style>
|
||||
{% endif %}
|
||||
</head>
|
||||
<body{% if user.is_authenticated and user.profile.background_image %} data-bg="{{ user.profile.background_image.url }}"{% endif %}>
|
||||
<body{% if user.is_authenticated and user.profile.background_image_data %} data-bg="1"{% endif %}>
|
||||
<nav class="navbar">
|
||||
<a href="/" class="navbar-brand">diora</a>
|
||||
<div class="navbar-links">
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue