From 616dcd49a15eb74e0e173ea1120e5036d1fc4a5a Mon Sep 17 00:00:00 2001 From: trinkey Date: Sat, 4 Jan 2025 15:41:02 -0500 Subject: [PATCH] fix overflow + editing + post list order --- manage.py | 0 tblog/migrations/0002_tbpost_edited_at.py | 18 +++ tblog/models.py | 1 + tblog/static/css/blog.css | 16 +++ tblog/templates/blog.html | 14 +- tblog/templates/snippets/blog-imports.html | 10 +- tblog/templates/user.html | 10 +- tblog/templates/write.html | 8 +- tblog/urls.py | 3 +- tblog/views/__init__.py | 3 +- tblog/views/static.py | 1 + tblog/views/templates.py | 148 +++++++++++++++------ 12 files changed, 175 insertions(+), 57 deletions(-) mode change 100755 => 100644 manage.py create mode 100644 tblog/migrations/0002_tbpost_edited_at.py create mode 100644 tblog/static/css/blog.css diff --git a/manage.py b/manage.py old mode 100755 new mode 100644 diff --git a/tblog/migrations/0002_tbpost_edited_at.py b/tblog/migrations/0002_tbpost_edited_at.py new file mode 100644 index 0000000..8d05f8a --- /dev/null +++ b/tblog/migrations/0002_tbpost_edited_at.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.4 on 2025-01-04 20:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('tblog', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='tbpost', + name='edited_at', + field=models.IntegerField(null=True), + ), + ] diff --git a/tblog/models.py b/tblog/models.py index 4f781aa..cf00bc7 100644 --- a/tblog/models.py +++ b/tblog/models.py @@ -20,6 +20,7 @@ class tBPost(models.Model): title = models.TextField(max_length=1_000) content = models.TextField(max_length=500_000) timestamp = models.IntegerField() + edited_at = models.IntegerField(null=True) text_format = models.CharField(max_length=10) # plain, mono, markdown, html ... (more to come?) class Meta: diff --git a/tblog/static/css/blog.css b/tblog/static/css/blog.css new file mode 100644 index 0000000..ca990af --- /dev/null +++ b/tblog/static/css/blog.css @@ -0,0 +1,16 @@ +#real-blog-container[data-blog-format="mono"] pre, +#real-blog-container[data-blog-format="plain"] pre { + white-space: pre-wrap; + overflow-x: scroll; +} + +#real-blog-container[data-blog-format="html"], +#real-blog-container[data-blog-format="markdown"] { + width: 100%; + overflow-x: scroll; +} + +#blog-container { + max-width: 1000px; + width: calc(90vw - 40px); +} diff --git a/tblog/templates/blog.html b/tblog/templates/blog.html index c432051..d1783a7 100644 --- a/tblog/templates/blog.html +++ b/tblog/templates/blog.html @@ -8,8 +8,18 @@ {% block body %}

{{ blog.title }}

By {{ blog.u_by.username }}
- + + + + {% if blog.edited_at %} + - Edited + + {% endif %} + + {% if username == blog.u_by.username %} +

Edit post

+
{% csrf_token %}

@@ -20,7 +30,7 @@

{% endif %}
-
Loading...
+
Loading...
{% endif %} + + diff --git a/tblog/urls.py b/tblog/urls.py index f5e39b6..444967c 100644 --- a/tblog/urls.py +++ b/tblog/urls.py @@ -1,7 +1,7 @@ from django.contrib import admin from django.urls import include, path -from .views import auth, index, user, view_blog, write +from .views import auth, edit_blog, index, user, view_blog, write urlpatterns = [ path("", index), @@ -9,6 +9,7 @@ urlpatterns = [ path("create/", write), path("blog//", user), path("blog///", view_blog), + path("blog///edit/", edit_blog), path("static/", include("tblog.views.static")), path("django-admin/", admin.site.urls) ] diff --git a/tblog/views/__init__.py b/tblog/views/__init__.py index 684d3be..326ef4b 100644 --- a/tblog/views/__init__.py +++ b/tblog/views/__init__.py @@ -1 +1,2 @@ -from .templates import auth, index, user, view_blog, write # noqa: F401 +from .templates import (auth, edit_blog, index, user, view_blog, # noqa: F401 + write) diff --git a/tblog/views/static.py b/tblog/views/static.py index c5c4be2..291cfb9 100644 --- a/tblog/views/static.py +++ b/tblog/views/static.py @@ -22,6 +22,7 @@ file_associations = { urlpatterns = [path(i, cache_control(**{"max-age": 60 * 60 * 24 * 30})(get_static_serve(i, file_associations[i.split(".")[-1]]))) for i in [ "css/ace.css", + "css/blog.css", "css/write.css", "js/write.js" ]] diff --git a/tblog/views/templates.py b/tblog/views/templates.py index b0d42cf..77a31ed 100644 --- a/tblog/views/templates.py +++ b/tblog/views/templates.py @@ -38,51 +38,51 @@ def index(request: WSGIRequest) -> HttpResponse: def write(request: WSGIRequest) -> HttpResponse: username = get_username(request) - if username: - repopulate = {} - error = None - - if request.method == "POST": - url = (request.POST.get("url") or "").strip().replace(" ", "-").lower() - title = (request.POST.get("title") or "").strip() - content = (request.POST.get("raw") or "").strip() - fmt = request.POST.get("format") - - repopulate = { - "url": url, - "title": title, - "content": content, - "format": fmt - } - - if not (url and title and content) or fmt not in ["plain", "mono", "markdown", "html"] or len(url) > 250 or len(title) > 1_000 or len(content) > 500_000: - error = "Invalid input(s)" - - else: - try: - tBPost.objects.create( - u_by=get_user_object(username, i_promise_this_user_exists=True), - url=request.POST.get("url"), - title=request.POST.get("title"), - content=request.POST.get("raw"), - timestamp=math.floor(time.time()), - text_format=request.POST.get("format") - ) - except IntegrityError: - error = f"Url '{url}' already in use" - else: - return HttpResponseRedirect(f"/blog/{username}/{escape_url(url)}/") - + if not username: return render_template( - request, "write.html", - title="Writing", - username=username, - error=error, - repopulate=repopulate + request, "noauth/index.html" ) + repopulate = {} + error = None + + if request.method == "POST": + url = (request.POST.get("url") or "").strip().replace(" ", "-").lower() + title = (request.POST.get("title") or "").strip() + content = (request.POST.get("raw") or "").strip() + fmt = request.POST.get("format") + + repopulate = { + "url": url, + "title": title, + "content": content, + "format": fmt + } + + if not (url and title and content) or fmt not in ["plain", "mono", "markdown", "html"] or len(url) > 250 or len(title) > 1_000 or len(content) > 500_000: + error = "Invalid input(s)" + + else: + try: + tBPost.objects.create( + u_by=get_user_object(username, i_promise_this_user_exists=True), + url=url, + title=title, + content=content, + timestamp=math.floor(time.time()), + text_format=fmt + ) + except IntegrityError: + error = f"Url '{url}' already in use" + else: + return HttpResponseRedirect(f"/blog/{username}/{escape_url(url)}/") + return render_template( - request, "noauth/index.html" + request, "write.html", + title="Writing", + username=username, + error=error, + repopulate=repopulate ) def view_blog(request: WSGIRequest, username: str, url: str) -> HttpResponse: @@ -109,6 +109,70 @@ def view_blog(request: WSGIRequest, username: str, url: str) -> HttpResponse: username=self_username ) +def edit_blog(request: WSGIRequest, username: str, url: str) -> HttpResponse: + try: + blog = tBPost.objects.get( + u_by=get_user_object(username), + url=url + ) + except tBPost.DoesNotExist: + return render_template( + request, "404.html" + ) + + self_username = get_username(request) + + if username != self_username: + return render_template( + request, "404.html" + ) + + error = None + repopulate = { + "url": blog.url, + "title": blog.title, + "content": blog.content, + "format": blog.text_format + } + + if request.method == "POST": + url = (request.POST.get("url") or "").strip().replace(" ", "-").lower() or blog.url + title = (request.POST.get("title") or "").strip() or blog.title + content = (request.POST.get("raw") or "").strip() or blog.content + fmt = request.POST.get("format") or blog.text_format + + repopulate = { + "url": url, + "title": title, + "content": content, + "format": fmt + } + + if not (url and title and content) or fmt not in ["plain", "mono", "markdown", "html"] or len(url) > 250 or len(title) > 1_000 or len(content) > 500_000: + error = "Invalid input(s)" + + else: + try: + blog.url = url + blog.title = title + blog.content = content + blog.edited_at = math.floor(time.time()) + blog.text_format = fmt + blog.save() + except IntegrityError: + error = f"Url '{url}' already in use" + else: + return HttpResponseRedirect(f"/blog/{username}/{escape_url(url)}/") + + return render_template( + request, "write.html", + title="Editing", + editing=True, + username=username, + error=error, + repopulate=repopulate + ) + def user(request: WSGIRequest, username: str) -> HttpResponse: user = get_user_object(username) @@ -117,7 +181,7 @@ def user(request: WSGIRequest, username: str) -> HttpResponse: request, "user.html", username=user.username, self_username=get_username(request), - posts=user.posts.all() # type: ignore + posts=user.posts.order_by("-id") # type: ignore ) return render_template(