mirror of
https://github.com/Alexander-D-Karpov/akarpov
synced 2024-11-25 18:43:47 +03:00
added file previews, file page
This commit is contained in:
parent
a30f402f18
commit
8a995a8ca5
3
akarpov/files/previews/__init__.py
Normal file
3
akarpov/files/previews/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from . import image, video
|
||||
|
||||
previews = {"video": {"mp4": video.mp4.view}, "image": {"jpeg": image.jpeg.view}}
|
1
akarpov/files/previews/image/__init__.py
Normal file
1
akarpov/files/previews/image/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from . import jpeg # noqa
|
35
akarpov/files/previews/image/jpeg.py
Normal file
35
akarpov/files/previews/image/jpeg.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
from akarpov.files.models import File
|
||||
|
||||
|
||||
def view(file: File) -> (str, str):
|
||||
static = """
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.3/viewer.min.css" rel="stylesheet">
|
||||
"""
|
||||
content = (
|
||||
f"""
|
||||
<div>
|
||||
<img id="image" class="img-fluid" src="{file.file.url}" alt="Picture">
|
||||
</div>
|
||||
<script src="/static/js/jquery.js"></script>
|
||||
"""
|
||||
+ """
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.3/viewer.min.js">
|
||||
var $image = $('#image');
|
||||
|
||||
$image.viewer({
|
||||
inline: true,
|
||||
viewed: function() {
|
||||
$image.viewer('zoomTo', 1);
|
||||
}
|
||||
});
|
||||
|
||||
// Get the Viewer.js instance after initialized
|
||||
var viewer = $image.data('viewer');
|
||||
|
||||
// View a list of images
|
||||
$('#images').viewer();
|
||||
</script>
|
||||
"""
|
||||
)
|
||||
|
||||
return static, content
|
1
akarpov/files/previews/video/__init__.py
Normal file
1
akarpov/files/previews/video/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from . import mp4 # noqa
|
20
akarpov/files/previews/video/mp4.py
Normal file
20
akarpov/files/previews/video/mp4.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
from akarpov.files.models import File
|
||||
|
||||
|
||||
def view(file: File) -> (str, str):
|
||||
static = """
|
||||
<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}'
|
||||
data-setup='{data}'>
|
||||
<source src="{file.file.url}" type='video/mp4' />
|
||||
</video>
|
||||
|
||||
<script src="https://vjs.zencdn.net/8.0.4/video.min.js"></script>
|
||||
"""
|
||||
|
||||
return static, content
|
|
@ -84,7 +84,8 @@ def create_preview(file_path: str) -> str:
|
|||
|
||||
|
||||
def get_file_mimetype(file_path: str) -> str:
|
||||
return magic.from_file(file_path)
|
||||
mime = magic.Magic(mime=True)
|
||||
return mime.from_file(file_path)
|
||||
|
||||
|
||||
def get_description(file_path: str) -> str:
|
||||
|
|
|
@ -31,7 +31,7 @@ def process_file(pk: int):
|
|||
)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
file.type = get_file_mimetype(file.file.path)
|
||||
file.file_type = get_file_mimetype(file.file.path)
|
||||
descr = None
|
||||
try:
|
||||
descr = get_description(file.file.path)
|
||||
|
|
|
@ -11,10 +11,12 @@
|
|||
ChunkedUploadView,
|
||||
)
|
||||
from akarpov.files.models import File, Folder
|
||||
from akarpov.files.previews import previews
|
||||
|
||||
|
||||
class TopFolderView(LoginRequiredMixin, ListView):
|
||||
template_name = "files/list.html"
|
||||
paginate_by = 20
|
||||
model = File
|
||||
|
||||
def get_queryset(self):
|
||||
|
@ -33,6 +35,20 @@ class FileView(DetailView):
|
|||
model = File
|
||||
slug_field = "slug"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super().get_context_data(**kwargs)
|
||||
context["has_perm"] = self.object.user == self.request.user
|
||||
static = ""
|
||||
content = ""
|
||||
if self.object.file_type:
|
||||
t1, t2 = self.object.file_type.split("/")
|
||||
if t1 in previews:
|
||||
if t2 in previews[t1]:
|
||||
static, content = previews[t1][t2](self.object)
|
||||
context["preview_static"] = static
|
||||
context["preview_content"] = content
|
||||
return context
|
||||
|
||||
|
||||
files_view = FileView.as_view()
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
</li>
|
||||
{% if request.user.is_authenticated %}
|
||||
<li>
|
||||
<a href="{% url 'files:main' %}" class="{% active_link 'files' %} text-muted nav-link px-sm-0 px-2">
|
||||
<a href="{% url 'files:main' %}" class="{% active_link 'files:main' %} text-muted nav-link px-sm-0 px-2">
|
||||
<i class="fs-5 bi-folder-fill"></i><span class="ms-1 d-none d-sm-inline">Files</span></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
|
|
@ -57,8 +57,8 @@
|
|||
</symbol>
|
||||
</defs>
|
||||
</svg>
|
||||
<p class="text-break" id="progress-message"></p>
|
||||
<div id="progress" class="progress w-100" style="display: none" role="progressbar" aria-label="Warning example" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
||||
<h1 id="progress-message"></h1>
|
||||
<div id="progress-bar" class="progress-bar text-bg-warning" style="width: 0%">0%</div>
|
||||
</div>
|
||||
<div id="messages"></div>
|
||||
|
@ -72,11 +72,36 @@
|
|||
<div class="align-self-stretch align-items-center justify-content-center d-flex flex-column fill-height controlsdiv">
|
||||
<img src="{{ file.file_image_url }}" class="img-fluid" alt="">
|
||||
</div>
|
||||
|
||||
<a href="{% url 'files:view' file.slug %}" class="stretched-link"></a>
|
||||
<p class="card-text mb-4 mt-2 ms-3"><small class="text-muted">{{ file.modified | naturaltime }}</small></p>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% if page_obj.has_other_pages %}
|
||||
<div class="btn-group" role="group" aria-label="Item pagination">
|
||||
{% if page_obj.has_previous %}
|
||||
<a href="?page={{ page_obj.previous_page_number }}" class="btn btn-outline-warning">«</a>
|
||||
{% endif %}
|
||||
|
||||
{% for page_number in page_obj.paginator.page_range %}
|
||||
{% if page_obj.number == page_number %}
|
||||
<button class="btn btn-outline-warning active">
|
||||
<span>{{ page_number }} <span class="sr-only">(current)</span></span>
|
||||
</button>
|
||||
{% else %}
|
||||
<a href="?page={{ page_number }}" class="btn btn-outline-warning">
|
||||
{{ page_number }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if page_obj.has_next %}
|
||||
<a href="?page={{ page_obj.next_page_number }}" class="btn btn-outline-warning">»</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block inline_javascript %}
|
||||
|
@ -157,15 +182,14 @@
|
|||
add: function(e, data) { // Called before starting upload
|
||||
if (cur !== true){
|
||||
cur = true
|
||||
console.log("add", data.files[0])
|
||||
form_data.splice(1);
|
||||
calculate_md5(data.files[0], 1000000);
|
||||
data.submit();
|
||||
$("#progress").css("display", "flex");
|
||||
$("#progress-message").text("loading file: " + data.files[0].name);
|
||||
}
|
||||
},
|
||||
chunkdone: function (e, data) { // Called after uploading each chunk
|
||||
console.log("chunkdone", data.files[0])
|
||||
if (form_data.length < 2) {
|
||||
form_data.push(
|
||||
{"name": "upload_id", "value": data.result.upload_id}
|
||||
|
@ -177,7 +201,10 @@
|
|||
sel.text(progress + "%");
|
||||
},
|
||||
done: function (e, data) { // Called when the file has completely uploaded
|
||||
console.log("done", data.files[0])
|
||||
var progress = 100;
|
||||
let sel = $("#progress-bar");
|
||||
sel.css("width", progress + "%");
|
||||
sel.text(progress + "%");
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "{% url 'files:api_chunked_upload_complete' %}",
|
||||
|
|
33
akarpov/templates/files/view.html
Normal file
33
akarpov/templates/files/view.html
Normal file
|
@ -0,0 +1,33 @@
|
|||
{% extends 'base.html' %}
|
||||
|
||||
{% block javascript %}
|
||||
{% autoescape off %}
|
||||
{{ preview_static }}
|
||||
{% endautoescape %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="row m-2">
|
||||
<div class="col-auto">
|
||||
<h1 class="fs-1">{{ file.name }}</h1>
|
||||
{% 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 %}
|
||||
{{ file.user.username }}</a></p>
|
||||
{% endif %}
|
||||
<p class="mt-2">Last updated: {{ file.modified|date:"d.m.Y" }} {{ file.modified|time:"H:i" }}</p>
|
||||
<p>File size: {{ file.file_size | filesizeformat }}</p>
|
||||
{% if file.file_type %}
|
||||
<p>File type: {{ file.file_type }}</p>
|
||||
{% endif %}
|
||||
{% if file.description %}
|
||||
<p>{{ file.description }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
{% autoescape off %}
|
||||
{{ preview_content }}
|
||||
{% endautoescape %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user