diff --git a/src/crowdprinter/templates/base.html b/src/crowdprinter/templates/base.html
index 06643ac..249dde1 100644
--- a/src/crowdprinter/templates/base.html
+++ b/src/crowdprinter/templates/base.html
@@ -1,5 +1,12 @@
{% include "crowdprinter/head.html" %}
+ {% if messages %}
+
+ {% for message in messages %}
+ - {{ message }}
+ {% endfor %}
+
+ {% endif %}
{% block content %}{% endblock %}
diff --git a/src/crowdprinter/templates/crowdprinter/printjob_create_text.html b/src/crowdprinter/templates/crowdprinter/printjob_create_text.html
new file mode 100644
index 0000000..220954c
--- /dev/null
+++ b/src/crowdprinter/templates/crowdprinter/printjob_create_text.html
@@ -0,0 +1,12 @@
+{% extends 'base.html' %}
+
+{% block content %}
+
+
Add Print Job
+
+
+{% endblock %}
diff --git a/src/crowdprinter/urls.py b/src/crowdprinter/urls.py
index 534b363..2bbbc83 100644
--- a/src/crowdprinter/urls.py
+++ b/src/crowdprinter/urls.py
@@ -25,6 +25,9 @@
path("accounts/", include("allauth.urls")),
path("", views.PrintJobListView.as_view()),
path("myprints", views.MyPrintAttempts.as_view(), name="my_printattempts"),
+ path(
+ "create/text", views.PrintJobCreateView.as_view(), name="printjob_create_text"
+ ),
path(
"printjob/
/",
include(
diff --git a/src/crowdprinter/views.py b/src/crowdprinter/views.py
index 6952441..085ffeb 100644
--- a/src/crowdprinter/views.py
+++ b/src/crowdprinter/views.py
@@ -2,21 +2,38 @@
import math
import os.path
import random
+import tempfile
+from django import forms
from django.conf import settings
from django.contrib.auth.decorators import login_required
+from django.contrib.auth.mixins import LoginRequiredMixin
+from django.contrib.auth.mixins import UserPassesTestMixin
+from django.contrib.messages.views import SuccessMessageMixin
+from django.core.files.base import ContentFile
+from django.db import transaction
from django.http import FileResponse
from django.http import Http404
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.urls import reverse
+from django.urls import reverse_lazy
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_control
+from django.views.generic import CreateView
from django.views.generic import DetailView
from django.views.generic import ListView
from django.views.generic.base import View
import crowdprinter.models as models
+import stl_generator
+
+from .models import PrintJob
+
+
+class SuperUserRequiredMixin(LoginRequiredMixin, UserPassesTestMixin):
+ def test_func(self):
+ return self.request.user.is_superuser
class PrintJobListView(ListView):
@@ -44,6 +61,63 @@ def get_queryset(self):
return super().get_queryset().filter(can_attempt=True).order_by("?")
+class PrintJobForm(forms.ModelForm):
+ text = forms.CharField(
+ required=True,
+ widget=forms.Textarea(attrs={"rows": 4, "cols": 40}),
+ )
+
+ class Meta:
+ model = PrintJob
+ fields = [
+ "slug",
+ "count_needed",
+ "text",
+ ]
+
+ @transaction.atomic
+ def save(self, commit=True):
+ job = super().save(commit=False)
+ slug = self.cleaned_data.get("slug")
+
+ with (
+ tempfile.NamedTemporaryFile(suffix=".stl", delete=False) as f_stl,
+ tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f_png,
+ tempfile.NamedTemporaryFile(suffix=".gcode", delete=False) as f_gcode,
+ ):
+ stl_generator.text_to_stl(self.cleaned_data.get("text"), f_stl)
+ f_stl.seek(0)
+ job.file_stl = ContentFile(f_stl.read(), name=f"{slug}.stl")
+
+ stl_generator.stl_to_png(f_stl.name, f_png)
+ f_png.seek(0)
+ job.file_render = ContentFile(f_png.read(), name=f"{slug}.png")
+
+ job.save()
+
+ for printer in [
+ models.Printer.objects.first()
+ ]: # TODO: support multiple printers w/ presets
+ stl_generator.stl_to_gcode(f_stl.name, f_gcode)
+ f_gcode.seek(0)
+ models.PrintJobFile.objects.create(
+ job=job,
+ printer=printer,
+ file_gcode=ContentFile(f_gcode.read(), name=f"{slug}.gcode"),
+ )
+
+ return job
+
+
+class PrintJobCreateView(SuperUserRequiredMixin, SuccessMessageMixin, CreateView):
+ template_name = "crowdprinter/printjob_create_text.html"
+ model = PrintJob
+ form_class = PrintJobForm
+ template_name = "crowdprinter/printjob_create_text.html"
+ success_url = reverse_lazy("printjob_create_text")
+ success_message = "Job %(slug)s was created successfully"
+
+
class MyPrintAttempts(ListView):
model = models.PrintAttempt
template_name = "crowdprinter/myprintattempts.html"
diff --git a/pipeline/process.py b/src/stl_generator/__init__.py
similarity index 72%
rename from pipeline/process.py
rename to src/stl_generator/__init__.py
index c12a41e..d5cb3eb 100755
--- a/pipeline/process.py
+++ b/src/stl_generator/__init__.py
@@ -4,9 +4,11 @@
import subprocess
import tempfile
+BASE_DIR = pathlib.Path(__file__).parent
+
def text_to_stl(text, f_stl):
- path_lib = pathlib.Path("generate_braille_lib.scad").absolute()
+ path_lib = BASE_DIR / "generate_braille_lib.scad"
with tempfile.NamedTemporaryFile("w", suffix=".scad", delete=False) as f_scad:
f_scad.write(f'BrailleText1="{text.lower()}";')
f_scad.write(f'ProfilText1="{text}";')
@@ -42,7 +44,7 @@ def stl_to_png(path_stl, f_png):
def stl_to_gcode(path_stl, f_gcode):
- path_pp_script = pathlib.Path("insert_m600.py").absolute()
+ path_pp_script = BASE_DIR / "insert_m600.py"
subprocess.check_call(
[
"prusa-slicer",
@@ -54,15 +56,3 @@ def stl_to_gcode(path_stl, f_gcode):
f_gcode.name,
]
)
-
-
-with (
- tempfile.NamedTemporaryFile(suffix=".stl", delete=False) as f_stl,
- tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f_png,
- tempfile.NamedTemporaryFile(suffix=".gcode", delete=False) as f_gcode,
-):
- text_to_stl("Hello World", f_stl)
- stl_to_png(f_stl.name, f_png)
- stl_to_gcode(f_stl.name, f_gcode)
- print(f_png.name)
- print(f_gcode.name)
diff --git a/pipeline/generate_braille_lib.scad b/src/stl_generator/generate_braille_lib.scad
similarity index 100%
rename from pipeline/generate_braille_lib.scad
rename to src/stl_generator/generate_braille_lib.scad
diff --git a/pipeline/insert_m600.py b/src/stl_generator/insert_m600.py
similarity index 100%
rename from pipeline/insert_m600.py
rename to src/stl_generator/insert_m600.py