aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--blog_admin/views.py19
-rw-r--r--ignis/admin.py6
-rw-r--r--ignis/migrations/0008_postimage_repositoryimages_repositorytitles_and_more.py50
-rw-r--r--ignis/migrations/0009_rename_repositorytitles_repositorytitle_and_more.py20
-rw-r--r--ignis/migrations/0010_alter_postimage_post.py20
-rw-r--r--ignis/migrations/0011_postimage_name.py18
-rw-r--r--ignis/models.py31
-rw-r--r--ignis/objectstorage.py36
-rw-r--r--ignis/urls.py3
-rw-r--r--ignis/views.py142
-rw-r--r--templates/blog_admin/edit_post.html12
-rw-r--r--templates/blog_admin/new_post.html12
13 files changed, 243 insertions, 128 deletions
diff --git a/.gitignore b/.gitignore
index 75debe7a..4257b4e4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -131,5 +131,5 @@ dmypy.json
# .DS_Store for macOS
.DS_Store
-genimages
+images
.DS_Store
diff --git a/blog_admin/views.py b/blog_admin/views.py
index 75b58507..35ab6489 100644
--- a/blog_admin/views.py
+++ b/blog_admin/views.py
@@ -4,7 +4,10 @@ from users.models import UserProfile
from django.contrib.auth.models import User
from django.contrib import messages
from blog.models import Post, Category, Tag
+from ignis.models import PostImage
import re
+import random
+import string
# Create your views here.
@@ -52,6 +55,7 @@ def new_post(request):
tags = request.POST.get('tags')
slug = request.POST.get('slug')
post_image = request.FILES['post_image'] if 'post_image' in request.FILES else None
+ random_post_identifier = request.POST.get('random_post_identifier')
if title and body and category and tags and slug and post_image:
try:
category = Category.objects.get(slug = category)
@@ -65,16 +69,25 @@ def new_post(request):
post_image = base64.b64encode(post_image)
post.post_image = "data:image/png;base64," + post_image.decode('utf-8')
post.save()
+ PostImage.objects.filter(temp_post_id = random_post_identifier).update(post = post)
+ PostImage.objects.filter(temp_post_id = random_post_identifier).update(temp_post_id = None)
+ # replace all random_post_identifier with post.id in post.body
+ post.body = post.body.replace(random_post_identifier, str(post.id))
+ post.save()
messages.success(request, 'Post created successfully!')
return redirect('blog-admin:posts')
except Exception as e:
messages.error(request, 'Error: {}'.format(e), extra_tags='new_post_create_error')
- return render(request, 'blog_admin/new_post.html', { 'title': 'New Post', 'categories': categories, 'blog_title': title, 'blog_body': body, 'blog_category': category, 'blog_tags': tags, 'blog_slug': slug })
+ return render(request, 'blog_admin/new_post.html', { 'title': 'New Post', 'categories': categories, 'blog_title': title, 'blog_body': body, 'blog_category': category, 'blog_tags': tags, 'blog_slug': slug, 'random_post_identifier': random_post_identifier })
else:
messages.error(request, 'Error: All fields are required!', extra_tags='new_post_create_error')
- return render(request, 'blog_admin/new_post.html', { 'title': 'New Post', 'categories': categories, 'blog_title': title, 'blog_body': body, 'blog_category': category, 'blog_tags': tags, 'blog_slug': slug })
+ return render(request, 'blog_admin/new_post.html', { 'title': 'New Post', 'categories': categories, 'blog_title': title, 'blog_body': body, 'blog_category': category, 'blog_tags': tags, 'blog_slug': slug, 'random_post_identifier': random_post_identifier })
else:
- return render(request, 'blog_admin/new_post.html', { 'title': 'New Post', 'categories': categories })
+ # new random temorary post identifier - 8 digit alphanumeric string
+
+ random_post_identifier = ''.join(random.choices(string.ascii_uppercase + string.digits, k=8))
+ random_post_identifier = 'rpi_' + random_post_identifier
+ return render(request, 'blog_admin/new_post.html', { 'title': 'New Post', 'categories': categories, 'random_post_identifier': random_post_identifier })
else:
return redirect('blog:home')
diff --git a/ignis/admin.py b/ignis/admin.py
index 0e97a0e9..eb188185 100644
--- a/ignis/admin.py
+++ b/ignis/admin.py
@@ -1,7 +1,7 @@
from django.contrib import admin
# Register your models here.
-from .models import Object, ObjectDirectory
+from .models import PostImage, RepositoryTitle
-admin.site.register(Object)
-admin.site.register(ObjectDirectory) \ No newline at end of file
+admin.site.register(PostImage)
+admin.site.register(RepositoryTitle)
diff --git a/ignis/migrations/0008_postimage_repositoryimages_repositorytitles_and_more.py b/ignis/migrations/0008_postimage_repositoryimages_repositorytitles_and_more.py
new file mode 100644
index 00000000..8cd1b668
--- /dev/null
+++ b/ignis/migrations/0008_postimage_repositoryimages_repositorytitles_and_more.py
@@ -0,0 +1,50 @@
+# Generated by Django 4.0.6 on 2022-11-22 15:13
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('blog', '0004_alter_post_post_image'),
+ ('ignis', '0007_alter_object_location'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='PostImage',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('image', models.ImageField(upload_to='images//post_images')),
+ ('temp_post_id', models.CharField(default=None, max_length=12, null=True)),
+ ('post', models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='blog.post')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='RepositoryImages',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('image', models.ImageField(upload_to='images//repository_images')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='RepositoryTitles',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('repository', models.CharField(max_length=100)),
+ ('image', models.ImageField(upload_to='images//repository_titles')),
+ ],
+ ),
+ migrations.DeleteModel(
+ name='Object',
+ ),
+ migrations.DeleteModel(
+ name='ObjectDirectory',
+ ),
+ migrations.AddField(
+ model_name='repositoryimages',
+ name='repository',
+ field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='ignis.repositorytitles'),
+ ),
+ ]
diff --git a/ignis/migrations/0009_rename_repositorytitles_repositorytitle_and_more.py b/ignis/migrations/0009_rename_repositorytitles_repositorytitle_and_more.py
new file mode 100644
index 00000000..81087071
--- /dev/null
+++ b/ignis/migrations/0009_rename_repositorytitles_repositorytitle_and_more.py
@@ -0,0 +1,20 @@
+# Generated by Django 4.0.6 on 2022-11-22 15:17
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ignis', '0008_postimage_repositoryimages_repositorytitles_and_more'),
+ ]
+
+ operations = [
+ migrations.RenameModel(
+ old_name='RepositoryTitles',
+ new_name='RepositoryTitle',
+ ),
+ migrations.DeleteModel(
+ name='RepositoryImages',
+ ),
+ ]
diff --git a/ignis/migrations/0010_alter_postimage_post.py b/ignis/migrations/0010_alter_postimage_post.py
new file mode 100644
index 00000000..3fda7708
--- /dev/null
+++ b/ignis/migrations/0010_alter_postimage_post.py
@@ -0,0 +1,20 @@
+# Generated by Django 4.0.6 on 2022-11-22 15:30
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('blog', '0004_alter_post_post_image'),
+ ('ignis', '0009_rename_repositorytitles_repositorytitle_and_more'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='postimage',
+ name='post',
+ field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='blog.post'),
+ ),
+ ]
diff --git a/ignis/migrations/0011_postimage_name.py b/ignis/migrations/0011_postimage_name.py
new file mode 100644
index 00000000..43be1a41
--- /dev/null
+++ b/ignis/migrations/0011_postimage_name.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.0.6 on 2022-11-22 15:34
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('ignis', '0010_alter_postimage_post'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='postimage',
+ name='name',
+ field=models.CharField(default=None, max_length=100, null=True),
+ ),
+ ]
diff --git a/ignis/models.py b/ignis/models.py
index ac6d64d2..91809204 100644
--- a/ignis/models.py
+++ b/ignis/models.py
@@ -1,19 +1,26 @@
from django.db import models
+from blog.models import Post
+from dotenv import load_dotenv
+import os
-# Create your models here.
-class Object(models.Model):
- md5 = models.CharField(max_length=32)
- metadata = models.CharField(max_length=255)
- data = models.TextField()
- created = models.DateTimeField(auto_now_add=True)
-
- location = models.ForeignKey('ObjectDirectory', on_delete=models.CASCADE)
+load_dotenv()
+UPLOAD_ROOT = 'images/' if os.getenv('ENVIRONMENT') == 'development' else '/home/ubuntu/database/images/'
- def __str__(self):
- return self.md5
+# Only For Storing Images
-class ObjectDirectory(models.Model):
- name = models.CharField(max_length=255, null=True)
+class PostImage(models.Model):
+ post = models.ForeignKey(Post, default=None, on_delete=models.CASCADE, null=True)
+ image = models.ImageField(upload_to="{}/post_images".format(UPLOAD_ROOT))
+ temp_post_id = models.CharField(max_length=12, default=None, null=True)
+ name = models.CharField(max_length=100, default=None, null=True)
def __str__(self):
return self.name
+
+class RepositoryTitle(models.Model):
+ repository = models.CharField(max_length=100)
+ image = models.ImageField(upload_to="{}/repository_titles".format(UPLOAD_ROOT))
+
+ def __str__(self):
+ return self.repository
+
diff --git a/ignis/objectstorage.py b/ignis/objectstorage.py
deleted file mode 100644
index 7e437750..00000000
--- a/ignis/objectstorage.py
+++ /dev/null
@@ -1,36 +0,0 @@
-from .models import Object, ObjectDirectory
-
-class ObjectStorage:
- def create_directory(self, name):
- if not ObjectDirectory.objects.filter(name=name).exists():
- ObjectDirectory.objects.create(name=name)
-
- def rename_directory(self, old_name, new_name):
- if not ObjectDirectory.objects.filter(name=old_name).exists():
- ObjectDirectory.objects.create(name=old_name)
- ObjectDirectory.objects.filter(name=old_name).update(name=new_name)
-
- def delete_directory(self, name):
- Object.objects.filter(location=ObjectDirectory.objects.get(name=name)).delete()
- ObjectDirectory.objects.filter(name=name).delete()
-
- def create_object(self, md5, metadata, data, name):
- if not ObjectDirectory.objects.filter(name=name).exists():
- ObjectDirectory.objects.create(name=name)
- if not Object.objects.filter(md5=md5).exists():
- Object.objects.create(md5=md5, metadata=metadata, data=data, location=ObjectDirectory.objects.get(name=name))
-
- def delete_object(self, slug, md5):
- Object.objects.filter(location=ObjectDirectory.objects.get(name=slug), md5=md5).delete()
-
- def get_object(self, slug, md5):
- return Object.objects.get(location=ObjectDirectory.objects.get(name=slug), md5=md5)
-
- def object_exists(self, slug, md5):
- return Object.objects.filter(location=ObjectDirectory.objects.get(name=slug), md5=md5).exists()
-
- def get_directory_contents(self, name):
- return Object.objects.filter(location=ObjectDirectory.objects.get(name=name))
-
- def get_directories(self):
- return ObjectDirectory.objects.all()
diff --git a/ignis/urls.py b/ignis/urls.py
index de4ff05b..ea0e3b66 100644
--- a/ignis/urls.py
+++ b/ignis/urls.py
@@ -6,7 +6,6 @@ urlpatterns = [
path('/tex', views.tex, name='tex'),
path('/post_image/<int:post_id>/', views.post_image, name='post_image'),
path('/upload', views.upload_image, name='upload_image'),
- path('/image/<str:slug>/<str:md5>', views.get_image, name='get_image'),
+ path('/image/<post_id>/<image_name>', views.get_image, name='get_image'),
path('/cover/<str:repository>', views.cover_image, name='cover_image'),
- path('/su/mvdir', views.mvdir, name='mvdir'),
]
diff --git a/ignis/views.py b/ignis/views.py
index 9f539d05..ba0e5f81 100644
--- a/ignis/views.py
+++ b/ignis/views.py
@@ -4,11 +4,11 @@ from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
import base64
from blog.models import Post
-from .objectstorage import ObjectStorage
import base64
-import _md5
+from .models import PostImage, RepositoryTitle
import json
import requests
+from django.core.files.base import ContentFile
# from .github import get_cover
# Create your views here.
@@ -44,36 +44,64 @@ def post_image(request, post_id):
return HttpResponse(image, content_type='image/png')
@csrf_exempt
-def get_image(request, slug, md5):
- object_storage = ObjectStorage()
- image = object_storage.get_object(slug, md5)
- return HttpResponse(base64.b64decode(image.data), content_type=image.metadata)
+def get_image(request, post_id, image_name):
+ if 'rpi_' in post_id:
+ # post has random post identifier => means it's a new post and not saved yet
+ # get image from temp_post_id
+ pi = PostImage.objects.filter(temp_post_id=post_id, name=image_name)
+ else:
+ # post has id => means it's an existing post
+ # get image from post_id
+ pi = PostImage.objects.filter(post=Post.objects.get(id=post_id), name=image_name)
+ if not pi:
+ return HttpResponse('No image found!', status=404)
+
+ # open image and return
+ image = pi[0].image
+ with open(image.path, 'rb') as f:
+ return HttpResponse(f.read(), content_type='image/{}'.format(image.name.split('.')[-1]))
@csrf_exempt
def cover_image(request, repository):
- url = 'https://socialify.git.ci/luciferreeves/{}/png?font=KoHo&language=1&name=1&pattern=Solid&theme=Dark'.format(repository)
-
- image = requests.get(url).content
-
- # reduce image size to 320x160
- image = Image.open(BytesIO(image))
- image = image.resize((320, 160), Image.ANTIALIAS)
-
- # remove black background
- image = image.convert('RGBA').getdata()
- new_data = []
- for item in image:
- if item[0] == 0 and item[1] == 0 and item[2] == 0:
- new_data.append((255, 255, 255, 0))
- else:
- new_data.append(item)
-
- # Convert back to png and return
- output = BytesIO()
- image = Image.new('RGBA', (320, 160))
- image.putdata(new_data)
- image.save(output, format='GIF')
- return HttpResponse(output.getvalue(), content_type='image/gif')
+ force_reload = request.GET.get('force_reload')
+ # check if the image is in RepositoryTitles
+ try:
+ if force_reload:
+ raise Exception('Force reload')
+ repository_title = RepositoryTitle.objects.get(repository=repository)
+ image = repository_title.image
+ except:
+ # image is not in RepositoryTitles
+ # get image
+ url = 'https://socialify.git.ci/luciferreeves/{}/png?font=KoHo&language=1&name=1&pattern=Solid&theme=Dark'.format(repository)
+ image = requests.get(url).content
+
+ # reduce image size to 320x160
+ image = Image.open(BytesIO(image))
+ image = image.resize((320, 160), Image.ANTIALIAS)
+
+ # remove black background
+ image = image.convert('RGBA').getdata()
+ new_data = []
+ for item in image:
+ if item[0] == 0 and item[1] == 0 and item[2] == 0:
+ new_data.append((255, 255, 255, 0))
+ else:
+ new_data.append(item)
+
+ # Convert back to png and return
+ output = BytesIO()
+ image = Image.new('RGBA', (320, 160))
+ image.putdata(new_data)
+ image.save(output, format='GIF')
+ image = output.getvalue()
+
+ # save image to RepositoryTitles
+ image = ContentFile(image, name='{}.png'.format(repository))
+ repository_title = RepositoryTitle(repository=repository, image=image)
+ repository_title.save()
+
+ return HttpResponse(image, content_type='image/gif')
def upload_image(request):
@@ -82,48 +110,24 @@ def upload_image(request):
return HttpResponse('Unauthorized', status=401)
if not request.FILES.get('image'):
return HttpResponse('No image provided!', status=400)
- if not request.POST.get('slug'):
- return HttpResponse('No slug provided!', status=400)
+ if not request.POST.get('id'):
+ return HttpResponse('No id provided!', status=400)
- # upload image to object storage
+ # upload image to PostImage model
image = request.FILES['image']
- slug = request.POST.get('slug')
- object_storage = ObjectStorage()
- object_storage.create_directory(slug)
-
-
- image_data = image.read()
- metadata = image.content_type
-
- image_hash = _md5.md5(image_data).hexdigest()
- data = base64.b64encode(image_data).decode('utf-8')
-
- if not object_storage.object_exists(slug, image_hash):
- object_storage.create_object(md5=image_hash, metadata=metadata, data=data, name=slug)
-
- # return json response
+ post_id = request.POST['id']
+ if 'rpi_' in post_id:
+ # post has random post identifier => means it's a new post and not saved yet
+ # save image to temp_post_id
+ pi = PostImage(image=image, temp_post_id=post_id, post=None, name=image.name)
+ else:
+ # post has id => means it's an existing post
+ # save image to post_id
+ pi = PostImage(image=image, post=Post.objects.get(id=post_id), name=image.name)
+ pi.save()
response = {
- 'url': "/ignis/image/{}/{}".format(slug, image_hash)
+ 'url': '/ignis/image/{}/{}'.format(post_id, pi.name)
}
-
- return HttpResponse(json.dumps(response), content_type='application/json', status=200)
-
-
-def mvdir(request):
- if not request.user.is_authenticated and not request.user.is_staff:
- return HttpResponse('Unauthorized', status=401)
- object_storage = ObjectStorage()
-
- # get from query params
- old_name = request.GET.get('old')
- new_name = request.GET.get('new')
-
- if not old_name or not new_name:
- return HttpResponse('No name provided!', status=400)
+ return HttpResponse(json.dumps(response), content_type='application/json')
+ return HttpResponse('Method not allowed', status=405)
- if old_name == "":
- object_storage.create_directory(new_name)
- return HttpResponse(json.dumps({'status': 'success'}), content_type='application/json', status=200)
- else:
- object_storage.rename_directory(old_name, new_name)
- return HttpResponse(json.dumps({'status': 'success'}), content_type='application/json', status=200)
diff --git a/templates/blog_admin/edit_post.html b/templates/blog_admin/edit_post.html
index b50848e3..5d113d9f 100644
--- a/templates/blog_admin/edit_post.html
+++ b/templates/blog_admin/edit_post.html
@@ -45,6 +45,16 @@
value="{{ blog_slug }}"
/>
</div>
+ <div class="form-group">
+ <input
+ style="display: inline-block"
+ type="hidden"
+ class="form-control"
+ id="post_id"
+ name="post_id"
+ value="{{ post.id }}"
+ />
+ </div>
<br>
<div class="form-group">
<label for="content">Post Image</label>
@@ -245,7 +255,7 @@
const url = "/ignis/upload";
const formData = new FormData();
formData.append("image", fileInput.files[0]);
- formData.append("slug", document.getElementById("slug").value);
+ formData.append("id", document.getElementById("post_id").value);
// append csrf token in header
const headers = new Headers();
headers.append("X-CSRFToken", "{{ csrf_token }}");
diff --git a/templates/blog_admin/new_post.html b/templates/blog_admin/new_post.html
index 7972cc87..ce4b9485 100644
--- a/templates/blog_admin/new_post.html
+++ b/templates/blog_admin/new_post.html
@@ -39,6 +39,16 @@
value="{{ blog_slug }}"
/>
</div>
+ <div class="form-group">
+ <input
+ style="display: inline-block"
+ type="hidden"
+ class="form-control"
+ id="random_post_identifier"
+ name="random_post_identifier"
+ value="{{ random_post_identifier }}"
+ />
+ </div>
<br>
<div class="form-group">
<label for="content">Post Image</label>
@@ -238,7 +248,7 @@
const url = "/ignis/upload";
const formData = new FormData();
formData.append("image", fileInput.files[0]);
- formData.append("slug", document.getElementById("slug").value);
+ formData.append("id", document.getElementById("random_post_identifier").value);
// append csrf token in header
const headers = new Headers();
headers.append("X-CSRFToken", "{{ csrf_token }}");