updated previews, fixed short links, added og tags, download delete

This commit is contained in:
Alexander Karpov 2023-04-13 00:54:44 +03:00
parent e7d78d59ec
commit d4f68935a1
14 changed files with 141 additions and 31 deletions

View File

@ -9,7 +9,7 @@
"wav": audio.basic.view,
"webm": audio.basic.view,
},
"video": {"mp4": video.mp4.view},
"video": {"mp4": video.mp4.view, "quicktime": video.basic.view},
"image": {
"jpeg": image.basic.view,
"png": image.basic.view,
@ -17,4 +17,9 @@
},
}
extensions = {"mp4": video.mp4.view, "mp3": audio.basic.view, "avif": image.basic.view}
extensions = {
"mp4": video.mp4.view,
"mp3": audio.basic.view,
"avif": image.basic.view,
"mov": video.basic.view,
}

View File

@ -2,7 +2,8 @@
def view(file: File) -> (str, str):
static = """
static = f"""
<meta property="og:title" content="{file.name}" />
"""
content = (
"""

View File

@ -2,7 +2,11 @@
def view(file: File) -> (str, str):
static = """
static = (
f"""
<meta property="og:title" content="{file.name}" />
"""
+ """
<style>
#canvas {
position: absolute;
@ -13,6 +17,7 @@ def view(file: File) -> (str, str):
}
</style>
"""
)
content = (
"""
<div id="container">

View File

@ -2,8 +2,9 @@
def view(file: File) -> (str, str):
static = """
static = f"""
<link href="https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.3/viewer.min.css" rel="stylesheet">
<meta property="og:title" content="{file.name}" />
"""
content = (
f"""

View File

@ -1 +1 @@
from . import mp4 # noqa
from . import basic, mp4 # noqa

View File

@ -0,0 +1,26 @@
from akarpov.files.models import File
def view(file: File) -> (str, str):
static = f"""
<meta property="og:title" content="{file.name}" />
<meta property="og:type" content="video.movie" />
<meta property="og:video" content="dev2.akarpov.ru/{file.file.url}" />
<meta property="og:video:type" content="{file.file_type}" />
<meta property="og:video:width" content="720" />
<meta property="og:video:height" content="480" />
<link href="https://vjs.zencdn.net/8.0.4/video-js.css" rel="stylesheet" />
"""
data = """"playbackRates": [0.5, 1, 1.5, 2], "responsive": true }"""
content = f"""
<video id="my_video_1" class="video-js vjs-default-skin" height="500px"
controls poster='{file.preview.url if file.preview else ''}'
data-setup='{data}'>
<source src="{file.file.url}" type='{file.file_type}' />
</video>
<script src="https://vjs.zencdn.net/8.0.4/video.min.js"></script>
"""
return static, content

View File

@ -2,7 +2,13 @@
def view(file: File) -> (str, str):
static = """
static = f"""
<meta property="og:title" content="{file.name}" />
<meta property="og:type" content="video.movie" />
<meta property="og:video" content="{file.file.url}" />
<meta property="og:video:type" content="{file.file_type}" />
<meta property="og:video:width" content="720" />
<meta property="og:video:height" content="480" />
<link href="https://vjs.zencdn.net/8.0.4/video-js.css" rel="stylesheet" />
"""
data = """"playbackRates": [0.5, 1, 1.5, 2], "responsive": true }"""
@ -11,7 +17,7 @@ def view(file: File) -> (str, str):
<video id="my_video_1" class="video-js vjs-default-skin" height="500px"
controls poster='{file.preview.url if file.preview else ''}'
data-setup='{data}'>
<source src="{file.file.url}" type='video/mp4' />
<source src="{file.file.url}" type='{file.file_type}' />
</video>
<script src="https://vjs.zencdn.net/8.0.4/video.min.js"></script>

View File

@ -5,11 +5,7 @@
from django.core.files import File
from akarpov.files.models import File as FileModel
from akarpov.files.services.preview import (
create_preview,
get_description,
get_file_mimetype,
)
from akarpov.files.services.preview import create_preview, get_file_mimetype
logger = structlog.get_logger(__name__)
@ -32,18 +28,7 @@ def process_file(pk: int):
except Exception as e:
logger.error(e)
file.file_type = get_file_mimetype(file.file.path)
descr = None
try:
descr = get_description(file.file.path)
if descr:
with open(descr, encoding="utf-8") as f:
data = f.read()
file.description = data
except Exception as e:
logger.error(e)
file.save(update_fields=["preview", "name", "file_type", "description"])
file.save(update_fields=["preview", "name", "file_type"])
if pth and os.path.isfile(pth):
os.remove(pth)
if descr and os.path.isfile(descr):
os.remove(descr)
return pk

View File

@ -5,6 +5,7 @@
MyChunkedUploadCompleteView,
MyChunkedUploadView,
TopFolderView,
delete_file_view,
files_view,
folder_view,
)
@ -22,5 +23,6 @@
"api/chunked_upload/", MyChunkedUploadView.as_view(), name="api_chunked_upload"
),
path("<str:slug>", files_view, name="view"),
path("<str:slug>/delete", delete_file_view, name="delete"),
path("f/<str:slug>", folder_view, name="folder"),
]

View File

@ -1,7 +1,9 @@
import os
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import DetailView, ListView
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.views.generic import DetailView, ListView, RedirectView
from django.views.generic.base import TemplateView
from akarpov.contrib.chunked_upload.exceptions import ChunkedUploadError
@ -58,6 +60,17 @@ def get_context_data(self, **kwargs):
files_view = FileView.as_view()
class DeleteFileView(LoginRequiredMixin, RedirectView):
def get_redirect_url(self, *args, **kwargs):
file = get_object_or_404(File, slug=kwargs["slug"])
if file.user == self.request.user:
file.delete()
return reverse("files:main")
delete_file_view = DeleteFileView.as_view()
class FileFolderView(DetailView):
template_name = "files/folder.html"
model = Folder

View File

@ -85,7 +85,7 @@
{% if ACCOUNT_ALLOW_REGISTRATION %}
<li>
<a href="{% url 'account_signup' %}" class="text-muted nav-link px-sm-0 px-2 {% active_link 'account_signup' %}">
<i class="fs-5 bi-person"></i><span class="ms-1 d-none d-sm-inline">Sign up</span> </a>
<i class="fs-5 bi-person"></i><span class="ms-1 d-none d-sm-inline">Register</span> </a>
</li>
{% endif %}
<li>

View File

@ -8,8 +8,8 @@
{% block content %}
<div class="row m-2">
<div class="col-md-4 col-sm-6">
<h1 class="fs-1">{{ file.name }}</h1>
<h1 class="fs-1 text-break mb-4">{{ file.name }}</h1>
<div class="col-md-4 col-sm-6 col-xs-auto">
{% if not has_perm %}
<p>Uploaded by: <a href="{% url 'users:detail' file.user.username %}">
{% if file.user.image_cropped %}<img class="rounded" width="20" src="{{ file.user.image_cropped.url }}" alt=""> {% endif %}
@ -23,11 +23,30 @@
{% if file.description %}
<p>{{ file.description }}</p>
{% endif %}
{% if file.private %}
<p>File is private</p>
{% else %}
<p>File is public{% if file.short_link %},
<a href="{{ file.short_link.get_absolute_url }}">short link</a><button class="btn" data-clipboard-text="{{ request.get_host }}{{ file.short_link.get_absolute_url }}">
<i style="font-size: 0.8em" class="bi bi-clipboard ml-2"></i>
</button>
{% endif %}</p>
{% endif %}
<div class="mt-4 text-center justify-content-sm-evenly justify-content-md-start gap-3 align-items-md-start align-items-sm-center d-flex">
<a class="btn btn-success fs-6" href="{{ file.file.url }}" download><i class="bi bi-download"></i> Download</a>
{% if has_perm %}
<a class="btn btn-danger fs-6" href="{% url 'files:delete' slug=file.slug %}"><i class="bi bi-trash"></i> Delete</a>
{% endif %}
</div>
</div>
<div class="col-md-8 col-sm-10">
<div class="col-md-8 col-sm-10 col-xs-auto">
{% autoescape off %}
{{ preview_content }}
{% endautoescape %}
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.10/clipboard.min.js"></script>
<script>
new ClipboardJS('.btn');
</script>
{% endblock %}

View File

@ -48,12 +48,57 @@ def create_model_link(sender, instance, created, **kwargs):
return
if hasattr(instance, "creator"):
link.creator = instance.creator
elif hasattr(instance, "user"):
link.creator = instance.user
elif hasattr(instance, "owner"):
link.creator = instance.owner
link.save()
instance.short_link = link
instance.save()
def update_model_link(sender, instance, **kwargs):
model = sender
if instance.id:
previous = model.objects.get(id=instance.id)
prev_private = False
cur_private = False
if hasattr(instance, "private"):
if instance.private:
cur_private = True
if hasattr(instance, "public"):
if not instance.public:
cur_private = True
if hasattr(previous, "private"):
if previous.private:
prev_private = True
if hasattr(previous, "public"):
if not previous.public:
prev_private = True
if prev_private != cur_private:
if prev_private:
# instance was private, public now, need to create short link
if hasattr(instance, "short_link"):
if not instance.short_link:
link = Link(source=instance.get_absolute_url())
if hasattr(instance, "creator"):
link.creator = instance.creator
elif hasattr(instance, "user"):
link.creator = instance.user
elif hasattr(instance, "owner"):
link.creator = instance.owner
link.save()
instance.short_link = link
else:
# instance was public, private now, need to delete short link
if hasattr(previous, "short_link"):
if previous.short_link:
previous.short_link.delete()
instance.short_link = None
class ShortLink(SlugModel):
short_link: Link | None = models.ForeignKey(
"shortener.Link", blank=True, null=True, on_delete=models.SET_NULL
@ -63,6 +108,7 @@ class ShortLink(SlugModel):
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
models.signals.post_save.connect(create_model_link, sender=cls)
models.signals.pre_save.connect(update_model_link, sender=cls)
@abstractmethod
def get_absolute_url(self):

View File

@ -11,7 +11,8 @@
default="Lm4alUqtub6qQT4MnV4NmtXQP02RCBtmGj1bJhyDho07Bkjk9WFZxGtwpnLNQGJQ",
)
# https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
ALLOWED_HOSTS = ["localhost", "0.0.0.0", "127.0.0.1"]
ALLOWED_HOSTS = ["*"]
CSRF_TRUSTED_ORIGINS = ["http://127.0.0.1", "https://*.akarpov.ru"]
# CACHES
# ------------------------------------------------------------------------------