Compare commits

...

10 Commits

9 changed files with 131 additions and 23 deletions

View File

@ -1,6 +1,7 @@
FROM alpine FROM alpine
RUN apk --no-cache add python3 inkscape bash imagemagick ttf-opensans RUN apk --no-cache add python3 inkscape bash imagemagick ttf-opensans
RUN apk --no-cache add py3-pip && pip3 install django tzdata gunicorn
ADD backend /root/zetikettes ADD backend /root/zetikettes
@ -8,6 +9,7 @@ RUN mkdir -p /usr/share/fonts/TTF \
&& cp /root/zetikettes/fonts/*.ttf /usr/share/fonts/TTF/ \ && cp /root/zetikettes/fonts/*.ttf /usr/share/fonts/TTF/ \
&& fc-cache -fv && fc-cache -fv
# the script will look for templates in /data # the script will look for templates in /data
WORKDIR /root/zetikettes WORKDIR /root/zetikettes/zetikettes
CMD /usr/bin/python3 web.py CMD /usr/bin/gunicorn zetikettes.wsgi -b 0.0.0.0:8000 --timeout 600

View File

@ -21,7 +21,7 @@ Test
---- ----
``` ```
docker run --rm -it -v $PWD/templates:/data zetikettes /bin/bash /root/zetikettes/mkjam.sh docker run --rm -it -v $PWD/templates:/data zetikettes /bin/bash /root/zetikettes/old/mkjam.sh
``` ```
This should produce a .pdf in `templates/`. Open it to check that This should produce a .pdf in `templates/`. Open it to check that
@ -34,10 +34,28 @@ Run
docker run -d --rm -p 127.0.0.1:8000:8000 -v /var/lib/zetikettes/templates:/data zetikettes docker run -d --rm -p 127.0.0.1:8000:8000 -v /var/lib/zetikettes/templates:/data zetikettes
``` ```
Notes for deploying
-------------------
.h3 Initialize empty database
```
python manage.py migrate
```
.h3 Prepare static files
```
python manage.py collectstatic
```
The files will be in `www_static/` and need to be moved to `/var/lib/zetikettes/www_static`
.h3 Change host settings
If not deploying on `aerith.ponteilla.net`, you'll need to edit `backend/zetikettes/zetikettes/settings.py` to change a couple things in there.
Change available templates Change available templates
-------------------------- --------------------------
1. go to /zetikettes/newtikette.html or konami code from main app 1. go to /zetikettes/admin
1. add the newtikette 1. add the newtikette
1. still no need to restart the container (magic!) 1. still no need to restart the container (magic!)
2. profit. 2. profit.

View File

@ -0,0 +1,51 @@
# Generated by Django 4.2.2 on 2023-07-03 14:37
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Tikategory',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('landscape', models.BooleanField()),
],
options={
'verbose_name_plural': 'tikategoriez',
},
),
migrations.CreateModel(
name='Tisub',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50)),
('descritpion', models.TextField()),
('default', models.TextField()),
],
options={
'verbose_name_plural': 'tisubz',
},
),
migrations.CreateModel(
name='Tikette',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=100)),
('svg', models.FileField(upload_to='')),
('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='tikette.tikategory')),
('subs', models.ManyToManyField(to='tikette.tisub')),
],
options={
'verbose_name_plural': 'tikettz',
},
),
]

View File

@ -1,16 +1,5 @@
from django.db import models from django.db import models
class Tikategory(models.Model):
name = models.CharField(max_length=50)
landscape = models.BooleanField()
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "tikategoriez"
class Tisub(models.Model): class Tisub(models.Model):
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
descritpion = models.TextField() descritpion = models.TextField()
@ -23,11 +12,22 @@ class Tisub(models.Model):
verbose_name_plural = "tisubz" verbose_name_plural = "tisubz"
class Tikategory(models.Model):
name = models.CharField(max_length=50)
landscape = models.BooleanField()
subs = models.ManyToManyField(Tisub)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "tikategoriez"
class Tikette(models.Model): class Tikette(models.Model):
title = models.CharField(max_length=100) title = models.CharField(max_length=100)
category = models.ForeignKey(Tikategory, on_delete=models.CASCADE) category = models.ForeignKey(Tikategory, on_delete=models.CASCADE)
svg = models.FileField() svg = models.FileField()
subs = models.ManyToManyField(Tisub)
def __str__(self): def __str__(self):
return self.title return self.title

View File

@ -16,7 +16,7 @@ def index(request):
'category': x.category.name, 'category': x.category.name,
'sticker': x.svg.name, 'sticker': x.svg.name,
'landscape': x.category.landscape, 'landscape': x.category.landscape,
'subs': {x.name: x.default for x in x.subs.all()}, 'subs': {x.name: x.default for x in x.category.subs.all()},
} for x in Tikette.objects.all()] } for x in Tikette.objects.all()]
return JsonResponse({'status': 'ok', 'tikettes': tikettes}, headers=CORS) return JsonResponse({'status': 'ok', 'tikettes': tikettes}, headers=CORS)

View File

@ -18,7 +18,7 @@ BASE_DIR = Path(__file__).resolve().parent.parent
#TIKETTE_OUT_DIR = BASE_DIR / 'data' #TIKETTE_OUT_DIR = BASE_DIR / 'data'
TIKETTE_OUT_DIR = Path('/data') TIKETTE_OUT_DIR = Path('/data')
MEDIA_ROOT = TIKETTE_OUT_DIR MEDIA_ROOT = TIKETTE_OUT_DIR
MEDIA_URL = 'data/' MEDIA_URL = '/data/'
# Quick-start development settings - unsuitable for production # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
@ -29,7 +29,8 @@ SECRET_KEY = 'django-insecure-64qxpe55#9wy=5@#dl0)3w7ywxh48m!f&!slp9e7v4lh@hjdct
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
ALLOWED_HOSTS = [] ALLOWED_HOSTS = ['*']
CSRF_TRUSTED_ORIGINS = ['https://*.ponteilla.net']
# Application definition # Application definition
@ -81,7 +82,7 @@ WSGI_APPLICATION = 'zetikettes.wsgi.application'
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3', 'NAME': TIKETTE_OUT_DIR / 'db.sqlite3',
} }
} }
@ -122,6 +123,8 @@ USE_TZ = True
STATIC_URL = 'static/' STATIC_URL = 'static/'
STATIC_ROOT = 'www_static'
# Default primary key field type # Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field # https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

View File

@ -35,7 +35,7 @@ function loadAll(zetikettes) {
$.post(backend_api, JSON.stringify(req)) $.post(backend_api, JSON.stringify(req))
.then(data => { .then(data => {
console.log(data); console.log(data);
const pdfbtn = $(`<a class="btn" href="${backend_api}/data/${data.file}" target="_blank">open pdf</a>`); const pdfbtn = $(`<a class="btn" href="${backend_api}data/${data.file}" target="_blank">open pdf</a>`);
action.append(pdfbtn); action.append(pdfbtn);
}) })
.catch(err => { .catch(err => {
@ -67,7 +67,7 @@ function konami() {
$(document).keydown(function (e) { $(document).keydown(function (e) {
if (e.keyCode === k[n++]) { if (e.keyCode === k[n++]) {
if (n === k.length) { if (n === k.length) {
document.location.href = 'newtikette.html'; document.location.href = backend_api + 'admin';
} }
} }
else { else {
@ -82,7 +82,7 @@ $(document).ready(async () => {
url: backend_api + 'list', url: backend_api + 'list',
timeout: 1000, timeout: 1000,
}); });
loadAll(resp.tikettes); loadAll(resp.tikettes.sort((a, b) => (a.title < b.title) ? -1 : 1));
} catch(e) { } catch(e) {
const appbody = $("#appbody"); const appbody = $("#appbody");
appbody.append(`<li>Could not reach backend server`); appbody.append(`<li>Could not reach backend server`);

18
nginx_locations Normal file
View File

@ -0,0 +1,18 @@
# prod site
location /zetikettes {
alias /var/lib/zetikettes/frontend;
}
location /zetikettes/srv/static {
alias /var/lib/zetikettes/www_static;
}
location ^~ /zetikettes/srv {
proxy_pass http://127.0.0.1:8000;
proxy_set_header SCRIPT_NAME /zetikettes/srv;
proxy_set_header Host $http_host;
# generating stuff takes time
proxy_read_timeout 10m;
client_max_body_size 10M;
}

16
zetikettes.service Normal file
View File

@ -0,0 +1,16 @@
[Unit]
Description=Zetikettes backend service
After=docker.service
Requires=docker.service
[Service]
ExecStart=/usr/bin/docker run --rm --name %n \
-p 127.0.0.1:8000:8000 \
-v /var/lib/zetikettes/data:/data \
zetikettes
Restart=on-failure
ExecStartPre=-/usr/bin/docker exec %n stop
ExecStartPre=-/usr/bin/docker rm %n
[Install]
WantedBy=multi-user.target