diff --git a/.gitignore b/.gitignore
index 5d381cc..01ef23f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -160,3 +160,7 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
+
+
+thumbnails/
+uploads/
\ No newline at end of file
diff --git a/penparse/webui/migrations/0003_imagememo_image_mimetype_alter_imagememo_image.py b/penparse/webui/migrations/0003_imagememo_image_mimetype_alter_imagememo_image.py
new file mode 100644
index 0000000..f99503e
--- /dev/null
+++ b/penparse/webui/migrations/0003_imagememo_image_mimetype_alter_imagememo_image.py
@@ -0,0 +1,24 @@
+# Generated by Django 4.2.16 on 2024-12-08 15:28
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('webui', '0002_imagememo'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='imagememo',
+ name='image_mimetype',
+ field=models.CharField(default='image/jpeg', max_length=256),
+ preserve_default=False,
+ ),
+ migrations.AlterField(
+ model_name='imagememo',
+ name='image',
+ field=models.ImageField(upload_to='uploads/%Y/%m/%d'),
+ ),
+ ]
diff --git a/penparse/webui/models.py b/penparse/webui/models.py
index f28afc8..0b5f4b2 100644
--- a/penparse/webui/models.py
+++ b/penparse/webui/models.py
@@ -42,6 +42,9 @@ class UserManager(BaseUserManager):
class ImageMemo(models.Model):
"""Model definition for ImageMemo."""
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
+
+ image_mimetype = models.CharField(max_length=256)
+
image = models.ImageField(upload_to='uploads/%Y/%m/%d')
content = models.TextField()
diff --git a/penparse/webui/templates/dashboard.html b/penparse/webui/templates/dashboard.html
index 3194160..0b81e3e 100644
--- a/penparse/webui/templates/dashboard.html
+++ b/penparse/webui/templates/dashboard.html
@@ -13,9 +13,8 @@
{% for document in documents %}
-
+
+
{{ document.title }}
Analyzed on: {{ document.analysis_date }}
@@ -40,13 +39,19 @@
{% endfor %}
-
Upload a New Document
- Upload Document
+
{% endblock %}
diff --git a/penparse/webui/urls.py b/penparse/webui/urls.py
index 6204aff..29d02a7 100644
--- a/penparse/webui/urls.py
+++ b/penparse/webui/urls.py
@@ -5,7 +5,14 @@ from . import views
urlpatterns = [
path("", views.index, name="index"),
path("dashboard", views.dashboard, name="dashboard"),
- path("settings", views.settings, name='settings'),
+ path("settings", views.settings, name="settings"),
path("documents/upload", views.upload_document, name="upload_document"),
+ path("documents/
", views.view_document, name="view_document"),
+ path(
+ "documents//thumbnail", views.document_thumbnail, name="document_thumbnail"
+ ),
+ path(
+ "documents//download", views.download_document, name="download_document"
+ ),
path("auth/register", views.register, name="register"),
]
diff --git a/penparse/webui/views.py b/penparse/webui/views.py
deleted file mode 100644
index 49a381c..0000000
--- a/penparse/webui/views.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import logging
-
-
-from django.contrib import messages
-from django.shortcuts import redirect, render
-from django.http import HttpRequest, HttpResponse
-
-from django import conf, forms
-
-
-from .models import User
-from .forms import RegisterForm
-
-
-logger = logging.getLogger(__name__)
-
-
-def index(request):
- # return HttpResponse("Hello, world. You're at the polls index.")
- return render(request, 'index.html')
-
-
-def dashboard(request):
- return render(request, 'dashboard.html')
-
-
-def settings(request):
- return render(request, 'settings.html')
-
-
-def upload_document(request):
- return render(request, 'upload.html')
-
-
-def register(request: HttpRequest):
-
- # if the form is not submitted yet, return the form
- if request.method == 'POST':
- form = RegisterForm(request.POST)
- if form.is_valid():
- form.save()
- messages.success(request, 'Registration successful!')
- return redirect('login')
- else:
- form = RegisterForm()
-
- return render(request, 'register.html', {'form': form})
diff --git a/penparse/webui/views/__init__.py b/penparse/webui/views/__init__.py
new file mode 100644
index 0000000..2f2572d
--- /dev/null
+++ b/penparse/webui/views/__init__.py
@@ -0,0 +1,82 @@
+import logging
+import os
+
+from django.contrib import messages
+from django.shortcuts import redirect, render
+from django.http import HttpRequest
+from django.core.files.storage import default_storage
+from django.core.files.base import ContentFile
+from ..models import ImageMemo
+
+from django.contrib.auth.decorators import login_required
+
+
+
+logger = logging.getLogger(__name__)
+
+from .thumbnail import document_thumbnail
+from .register import register
+
+
+def index(request):
+ # return HttpResponse("Hello, world. You're at the polls index.")
+ return render(request, "index.html")
+
+
+__all__ = ["index", "document_thumbnail", "register", "dashboard", "settings", "view_document", "download_document", "upload_document"]
+
+
+@login_required
+def dashboard(request: HttpRequest):
+
+ documents = ImageMemo.objects.filter(author__id=request.user.id).order_by(
+ "-updated_at"
+ )
+ context = {"documents": documents}
+
+ return render(request, "dashboard.html", context)
+
+
+@login_required
+def settings(request):
+ return render(request, "settings.html")
+
+
+@login_required
+def view_document(request):
+ return render(request, "document.html")
+
+
+@login_required
+def download_document(request):
+ return render(request, "document.html")
+
+
+@login_required
+def upload_document(request):
+ if request.method == "POST" and request.FILES.get("document"):
+ uploaded_file = request.FILES["document"]
+
+ # Check if the file is an image
+ if not uploaded_file.content_type.startswith("image/"):
+ messages.error(request, "Please upload an image file.")
+ return redirect("dashboard")
+
+ # Save the image
+ file_name = default_storage.save(
+ f"uploads/{uploaded_file.name}", ContentFile(uploaded_file.read())
+ )
+
+ # Create an ImageMemo instance
+ image_memo = ImageMemo(
+ image=file_name,
+ content="", # You can add initial content here if needed
+ author=request.user, # Assuming the user is authenticated
+ )
+ image_memo.save()
+
+ messages.success(request, "Image uploaded successfully!")
+
+ return redirect("dashboard") # Redirect to dashboard or appropriate page
+
+
diff --git a/penparse/webui/views/register.py b/penparse/webui/views/register.py
new file mode 100644
index 0000000..d3e00cf
--- /dev/null
+++ b/penparse/webui/views/register.py
@@ -0,0 +1,27 @@
+import logging
+import os
+
+from django.contrib import messages
+from django.shortcuts import redirect, render
+from django.http import HttpRequest
+
+from ..forms import RegisterForm
+
+
+logger = logging.getLogger(__name__)
+
+
+
+def register(request: HttpRequest):
+
+ # if the form is not submitted yet, return the form
+ if request.method == "POST":
+ form = RegisterForm(request.POST)
+ if form.is_valid():
+ form.save()
+ messages.success(request, "Registration successful!")
+ return redirect("login")
+ else:
+ form = RegisterForm()
+
+ return render(request, "register.html", {"form": form})
diff --git a/penparse/webui/views/thumbnail.py b/penparse/webui/views/thumbnail.py
new file mode 100644
index 0000000..e293968
--- /dev/null
+++ b/penparse/webui/views/thumbnail.py
@@ -0,0 +1,60 @@
+import os
+
+from PIL import Image
+from io import BytesIO
+from django.core.files.storage import default_storage
+
+from django import conf
+from django.http import HttpRequest, HttpResponse
+from django.contrib.auth.decorators import login_required
+
+from ..models import ImageMemo
+
+@login_required
+def document_thumbnail(request: HttpRequest, pk: str):
+ """Given a document uuid, look it up, ensure that it belongs to the current user and respond with a thumbnail"""
+
+ # find document with given ID (pk path param) and current user id
+ document = ImageMemo.objects.filter(id=pk, author__id=request.user.id).first()
+
+ if not document:
+ return HttpResponse("Document not found", status_code=404)
+
+ # look up the file on disk
+
+ # get thumb directory from django setting
+ thumbnail_dir = getattr(conf.settings, "THUMBNAIL_DIR", "thumbnails")
+
+ thumb_max_width = getattr(conf.settings, "THUMBNAIL_MAX_WIDTH", 420)
+
+ thumb_path = os.path.join(thumbnail_dir, str(document.id) + ".jpg")
+
+ if not os.path.exists(thumb_path):
+
+ if not os.path.exists(thumbnail_dir):
+ os.makedirs(thumbnail_dir)
+
+ # Open the image using PIL
+ image = Image.open(default_storage.open(document.image.name))
+
+ # get the image width and height
+ width = int(image.size[0])
+ height = int(image.size[1])
+
+ # find the ratio of the width to height
+ ratio = round(width / float(height), 3)
+
+ # max width of thumbnail is 240, calculate height based on ratio
+ thumb_height = int(thumb_max_width * ratio)
+
+ # Create a thumbnail
+ image.thumbnail((thumb_max_width, thumb_height)) # Adjust size as needed
+
+ # Save the thumbnail to a BytesIO object
+ thumb_io = BytesIO()
+ image.save(thumb_path, format="JPEG")
+ thumb_io.seek(0)
+
+ # Return the thumbnail as an HTTP response
+ with open(thumb_path, "rb") as f:
+ return HttpResponse(f.read(), content_type="image/jpeg")