mirror of
https://github.com/daniviga/django-ram.git
synced 2025-08-04 13:17:50 +02:00
Replace ckeditor with tinymce due to deprecation
This commit is contained in:
19
ram/bookshelf/migrations/0012_alter_book_notes.py
Normal file
19
ram/bookshelf/migrations/0012_alter_book_notes.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 5.0.2 on 2024-02-17 12:19
|
||||||
|
|
||||||
|
import tinymce.models
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("bookshelf", "0011_alter_book_language"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="book",
|
||||||
|
name="notes",
|
||||||
|
field=tinymce.models.HTMLField(blank=True),
|
||||||
|
),
|
||||||
|
]
|
@@ -6,7 +6,7 @@ from django.conf import settings
|
|||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_countries.fields import CountryField
|
from django_countries.fields import CountryField
|
||||||
|
|
||||||
from ckeditor_uploader.fields import RichTextUploadingField
|
from tinymce import models as tinymce
|
||||||
|
|
||||||
from metadata.models import Tag
|
from metadata.models import Tag
|
||||||
from ram.utils import DeduplicatedStorage
|
from ram.utils import DeduplicatedStorage
|
||||||
@@ -56,7 +56,7 @@ class Book(models.Model):
|
|||||||
tags = models.ManyToManyField(
|
tags = models.ManyToManyField(
|
||||||
Tag, related_name="bookshelf", blank=True
|
Tag, related_name="bookshelf", blank=True
|
||||||
)
|
)
|
||||||
notes = RichTextUploadingField(blank=True)
|
notes = tinymce.HTMLField(blank=True)
|
||||||
creation_time = models.DateTimeField(auto_now_add=True)
|
creation_time = models.DateTimeField(auto_now_add=True)
|
||||||
updated_time = models.DateTimeField(auto_now=True)
|
updated_time = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
19
ram/consist/migrations/0010_alter_consist_notes.py
Normal file
19
ram/consist/migrations/0010_alter_consist_notes.py
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Generated by Django 5.0.2 on 2024-02-17 12:19
|
||||||
|
|
||||||
|
import tinymce.models
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("consist", "0009_alter_consist_image"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="consist",
|
||||||
|
name="notes",
|
||||||
|
field=tinymce.models.HTMLField(blank=True),
|
||||||
|
),
|
||||||
|
]
|
@@ -4,7 +4,7 @@ from uuid import uuid4
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
|
|
||||||
from ckeditor_uploader.fields import RichTextUploadingField
|
from tinymce import models as tinymce
|
||||||
|
|
||||||
from ram.utils import DeduplicatedStorage
|
from ram.utils import DeduplicatedStorage
|
||||||
from metadata.models import Company, Tag
|
from metadata.models import Company, Tag
|
||||||
@@ -26,7 +26,7 @@ class Consist(models.Model):
|
|||||||
null=True,
|
null=True,
|
||||||
blank=True,
|
blank=True,
|
||||||
)
|
)
|
||||||
notes = RichTextUploadingField(blank=True)
|
notes = tinymce.HTMLField(blank=True)
|
||||||
creation_time = models.DateTimeField(auto_now_add=True)
|
creation_time = models.DateTimeField(auto_now_add=True)
|
||||||
updated_time = models.DateTimeField(auto_now=True)
|
updated_time = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
@@ -0,0 +1,34 @@
|
|||||||
|
# Generated by Django 5.0.2 on 2024-02-17 12:19
|
||||||
|
|
||||||
|
import tinymce.models
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("portal", "0016_remove_siteconfiguration_site_name"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="flatpage",
|
||||||
|
name="content",
|
||||||
|
field=tinymce.models.HTMLField(),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="siteconfiguration",
|
||||||
|
name="about",
|
||||||
|
field=tinymce.models.HTMLField(blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="siteconfiguration",
|
||||||
|
name="footer",
|
||||||
|
field=tinymce.models.HTMLField(blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="siteconfiguration",
|
||||||
|
name="footer_extended",
|
||||||
|
field=tinymce.models.HTMLField(blank=True),
|
||||||
|
),
|
||||||
|
]
|
@@ -6,8 +6,7 @@ from django.dispatch.dispatcher import receiver
|
|||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from solo.models import SingletonModel
|
from solo.models import SingletonModel
|
||||||
|
|
||||||
from ckeditor.fields import RichTextField
|
from tinymce import models as tinymce
|
||||||
from ckeditor_uploader.fields import RichTextUploadingField
|
|
||||||
|
|
||||||
from ram import __version__ as app_version
|
from ram import __version__ as app_version
|
||||||
from ram.utils import slugify
|
from ram.utils import slugify
|
||||||
@@ -15,7 +14,7 @@ from ram.utils import slugify
|
|||||||
|
|
||||||
class SiteConfiguration(SingletonModel):
|
class SiteConfiguration(SingletonModel):
|
||||||
site_author = models.CharField(max_length=256, blank=True)
|
site_author = models.CharField(max_length=256, blank=True)
|
||||||
about = RichTextField(blank=True)
|
about = tinymce.HTMLField(blank=True)
|
||||||
items_per_page = models.CharField(
|
items_per_page = models.CharField(
|
||||||
max_length=2,
|
max_length=2,
|
||||||
choices=[(str(x * 3), str(x * 3)) for x in range(2, 11)],
|
choices=[(str(x * 3), str(x * 3)) for x in range(2, 11)],
|
||||||
@@ -30,8 +29,8 @@ class SiteConfiguration(SingletonModel):
|
|||||||
],
|
],
|
||||||
default="type",
|
default="type",
|
||||||
)
|
)
|
||||||
footer = RichTextField(blank=True)
|
footer = tinymce.HTMLField(blank=True)
|
||||||
footer_extended = RichTextField(blank=True)
|
footer_extended = tinymce.HTMLField(blank=True)
|
||||||
show_version = models.BooleanField(default=True)
|
show_version = models.BooleanField(default=True)
|
||||||
use_cdn = models.BooleanField(default=True)
|
use_cdn = models.BooleanField(default=True)
|
||||||
extra_head = models.TextField(blank=True)
|
extra_head = models.TextField(blank=True)
|
||||||
@@ -56,7 +55,7 @@ class Flatpage(models.Model):
|
|||||||
name = models.CharField(max_length=256, unique=True)
|
name = models.CharField(max_length=256, unique=True)
|
||||||
path = models.CharField(max_length=256, unique=True)
|
path = models.CharField(max_length=256, unique=True)
|
||||||
published = models.BooleanField(default=False)
|
published = models.BooleanField(default=False)
|
||||||
content = RichTextUploadingField()
|
content = tinymce.HTMLField()
|
||||||
creation_time = models.DateTimeField(auto_now_add=True)
|
creation_time = models.DateTimeField(auto_now_add=True)
|
||||||
updated_time = models.DateTimeField(auto_now=True)
|
updated_time = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
from ram.utils import git_suffix
|
from ram.utils import git_suffix
|
||||||
|
|
||||||
__version__ = "0.9.6"
|
__version__ = "0.10.0"
|
||||||
__version__ += git_suffix(__file__)
|
__version__ += git_suffix(__file__)
|
||||||
|
@@ -44,8 +44,7 @@ INSTALLED_APPS = [
|
|||||||
"adminsortable2",
|
"adminsortable2",
|
||||||
"django_countries",
|
"django_countries",
|
||||||
"solo",
|
"solo",
|
||||||
"ckeditor",
|
"tinymce",
|
||||||
"ckeditor_uploader",
|
|
||||||
"rest_framework",
|
"rest_framework",
|
||||||
"ram",
|
"ram",
|
||||||
"portal",
|
"portal",
|
||||||
@@ -60,7 +59,7 @@ MIDDLEWARE = [
|
|||||||
"django.middleware.security.SecurityMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
||||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||||
"django.middleware.common.CommonMiddleware",
|
"django.middleware.common.CommonMiddleware",
|
||||||
'django.middleware.csrf.CsrfViewMiddleware',
|
"django.middleware.csrf.CsrfViewMiddleware",
|
||||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||||
"django.contrib.messages.middleware.MessageMiddleware",
|
"django.contrib.messages.middleware.MessageMiddleware",
|
||||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||||
@@ -142,7 +141,23 @@ DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
|||||||
|
|
||||||
MEDIA_URL = "media/"
|
MEDIA_URL = "media/"
|
||||||
MEDIA_ROOT = STORAGE_DIR / "media"
|
MEDIA_ROOT = STORAGE_DIR / "media"
|
||||||
CKEDITOR_UPLOAD_PATH = "uploads/"
|
|
||||||
|
TINYMCE_DEFAULT_CONFIG = {
|
||||||
|
"height": "500px",
|
||||||
|
"menubar": False,
|
||||||
|
"plugins": "autolink lists link image charmap preview anchor "
|
||||||
|
"searchreplace visualblocks code fullscreen insertdatetime media "
|
||||||
|
"table paste code",
|
||||||
|
"toolbar": "undo redo | "
|
||||||
|
"bold italic underline strikethrough removeformat | "
|
||||||
|
"fontsizeselect formatselect | "
|
||||||
|
"alignleft aligncenter alignright alignjustify | "
|
||||||
|
"outdent indent numlist bullist | "
|
||||||
|
"insertfile image media pageembed template link anchor codesample | "
|
||||||
|
"charmap | "
|
||||||
|
"fullscreen preview code",
|
||||||
|
"images_upload_url": "/tinymce/upload_image",
|
||||||
|
}
|
||||||
|
|
||||||
COUNTRIES_OVERRIDE = {
|
COUNTRIES_OVERRIDE = {
|
||||||
"EU": "Europe",
|
"EU": "Europe",
|
||||||
|
@@ -20,9 +20,16 @@ from django.conf.urls.static import static
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
|
|
||||||
|
from ram.views import UploadImage
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("", lambda r: redirect("portal/")),
|
path("", lambda r: redirect("portal/")),
|
||||||
path("ckeditor/", include("ckeditor_uploader.urls")),
|
path('tinymce/', include('tinymce.urls')),
|
||||||
|
path(
|
||||||
|
"tinymce/upload_image",
|
||||||
|
UploadImage.as_view(),
|
||||||
|
name="upload_image"
|
||||||
|
),
|
||||||
path("portal/", include("portal.urls")),
|
path("portal/", include("portal.urls")),
|
||||||
path("admin/", admin.site.urls),
|
path("admin/", admin.site.urls),
|
||||||
path("api/v1/consist/", include("consist.urls")),
|
path("api/v1/consist/", include("consist.urls")),
|
||||||
|
59
ram/ram/views.py
Normal file
59
ram/ram/views.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import os
|
||||||
|
import datetime
|
||||||
|
import posixpath
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
from PIL import Image, UnidentifiedImageError
|
||||||
|
|
||||||
|
from django.views import View
|
||||||
|
from django.conf import settings
|
||||||
|
from django.http import (
|
||||||
|
JsonResponse, HttpResponseForbidden, HttpResponse
|
||||||
|
)
|
||||||
|
from django.utils.text import slugify as slugify
|
||||||
|
from django.utils.decorators import method_decorator
|
||||||
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
|
|
||||||
|
@method_decorator(csrf_exempt, name='dispatch')
|
||||||
|
class UploadImage(View):
|
||||||
|
def post(self, request, application=None, model=None):
|
||||||
|
if not request.user.is_authenticated:
|
||||||
|
raise HttpResponseForbidden()
|
||||||
|
|
||||||
|
file_obj = request.FILES['file']
|
||||||
|
file_name, file_extension = os.path.splitext(file_obj.name)
|
||||||
|
file_name = slugify(file_name) + file_extension
|
||||||
|
|
||||||
|
try:
|
||||||
|
Image.open(file_obj)
|
||||||
|
except UnidentifiedImageError:
|
||||||
|
response = HttpResponse("Invalid extension") # FIXME
|
||||||
|
response.status_code = 400
|
||||||
|
return response
|
||||||
|
|
||||||
|
today = datetime.date.today()
|
||||||
|
container = (
|
||||||
|
"uploads",
|
||||||
|
today.strftime("%Y"),
|
||||||
|
today.strftime("%m"),
|
||||||
|
today.strftime("%d"),
|
||||||
|
)
|
||||||
|
|
||||||
|
file_path = os.path.join(
|
||||||
|
settings.MEDIA_ROOT,
|
||||||
|
*(p for p in container)
|
||||||
|
)
|
||||||
|
Path(file_path).mkdir(parents=True, exist_ok=True)
|
||||||
|
with open(os.path.join(file_path, file_name), 'wb+') as f:
|
||||||
|
for chunk in file_obj.chunks():
|
||||||
|
f.write(chunk)
|
||||||
|
|
||||||
|
return JsonResponse({
|
||||||
|
'message': 'Image uploaded successfully',
|
||||||
|
'location': posixpath.join(
|
||||||
|
settings.MEDIA_URL,
|
||||||
|
*(p for p in container),
|
||||||
|
file_name
|
||||||
|
)
|
||||||
|
})
|
@@ -0,0 +1,24 @@
|
|||||||
|
# Generated by Django 5.0.2 on 2024-02-17 12:19
|
||||||
|
|
||||||
|
import tinymce.models
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("roster", "0021_alter_rollingstockdocument_file_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="rollingstock",
|
||||||
|
name="notes",
|
||||||
|
field=tinymce.models.HTMLField(blank=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="rollingstockjournal",
|
||||||
|
name="log",
|
||||||
|
field=tinymce.models.HTMLField(),
|
||||||
|
),
|
||||||
|
]
|
@@ -7,7 +7,7 @@ from django.urls import reverse
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
|
|
||||||
from ckeditor_uploader.fields import RichTextUploadingField
|
from tinymce import models as tinymce
|
||||||
|
|
||||||
from ram.models import Document, Image, PropertyInstance
|
from ram.models import Document, Image, PropertyInstance
|
||||||
from ram.utils import DeduplicatedStorage
|
from ram.utils import DeduplicatedStorage
|
||||||
@@ -85,7 +85,7 @@ class RollingStock(models.Model):
|
|||||||
era = models.CharField(max_length=32, blank=True)
|
era = models.CharField(max_length=32, blank=True)
|
||||||
production_year = models.SmallIntegerField(null=True, blank=True)
|
production_year = models.SmallIntegerField(null=True, blank=True)
|
||||||
purchase_date = models.DateField(null=True, blank=True)
|
purchase_date = models.DateField(null=True, blank=True)
|
||||||
notes = RichTextUploadingField(blank=True)
|
notes = tinymce.HTMLField(blank=True)
|
||||||
tags = models.ManyToManyField(
|
tags = models.ManyToManyField(
|
||||||
Tag, related_name="rolling_stock", blank=True
|
Tag, related_name="rolling_stock", blank=True
|
||||||
)
|
)
|
||||||
@@ -175,7 +175,7 @@ class RollingStockJournal(models.Model):
|
|||||||
blank=False,
|
blank=False,
|
||||||
)
|
)
|
||||||
date = models.DateField()
|
date = models.DateField()
|
||||||
log = RichTextUploadingField()
|
log = tinymce.HTMLField()
|
||||||
private = models.BooleanField(default=False)
|
private = models.BooleanField(default=False)
|
||||||
creation_time = models.DateTimeField(auto_now_add=True)
|
creation_time = models.DateTimeField(auto_now_add=True)
|
||||||
updated_time = models.DateTimeField(auto_now=True)
|
updated_time = models.DateTimeField(auto_now=True)
|
||||||
|
@@ -7,7 +7,7 @@ django-solo
|
|||||||
django-countries
|
django-countries
|
||||||
django-health-check
|
django-health-check
|
||||||
django-admin-sortable2
|
django-admin-sortable2
|
||||||
django-ckeditor
|
django-tinymce
|
||||||
# Optional: # psycopg2-binary
|
# Optional: # psycopg2-binary
|
||||||
# Optional: # pySerial
|
# Optional: # pySerial
|
||||||
# Required by django-countries and not always installed
|
# Required by django-countries and not always installed
|
||||||
|
Reference in New Issue
Block a user