mirror of
https://github.com/Alexander-D-Karpov/akarpov
synced 2025-02-19 23:40:31 +03:00
added meta for all files, html preview
This commit is contained in:
parent
4c2a00a06a
commit
24ef17bde3
|
@ -34,7 +34,7 @@
|
||||||
},
|
},
|
||||||
"text": {
|
"text": {
|
||||||
"css": text.common.view,
|
"css": text.common.view,
|
||||||
"html": text.common.view,
|
"html": text.html.view,
|
||||||
"javascript": text.common.view,
|
"javascript": text.common.view,
|
||||||
"plain": text.plain.view,
|
"plain": text.plain.view,
|
||||||
"csv": text.csv.view,
|
"csv": text.csv.view,
|
||||||
|
@ -76,6 +76,7 @@
|
||||||
"mpeg": video.mp4.view,
|
"mpeg": video.mp4.view,
|
||||||
"oga": audio.oga.view,
|
"oga": audio.oga.view,
|
||||||
"pdf": application.pdf.view,
|
"pdf": application.pdf.view,
|
||||||
|
"html": text.html.view,
|
||||||
}
|
}
|
||||||
| source_code
|
| source_code
|
||||||
| fonts_ext
|
| fonts_ext
|
||||||
|
@ -88,12 +89,23 @@
|
||||||
"ogg": video.basic.meta,
|
"ogg": video.basic.meta,
|
||||||
"mpeg": video.basic.meta,
|
"mpeg": video.basic.meta,
|
||||||
"quicktime": video.basic.meta,
|
"quicktime": video.basic.meta,
|
||||||
}
|
},
|
||||||
|
"text": {
|
||||||
|
"css": text.common.meta,
|
||||||
|
"html": text.common.meta,
|
||||||
|
"javascript": text.common.meta,
|
||||||
|
"plain": text.common.meta,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
meta_source_code = {}
|
||||||
|
for ext in text.common.language_previews.keys():
|
||||||
|
source_code[ext] = text.common.meta
|
||||||
|
|
||||||
meta_extensions = {
|
meta_extensions = {
|
||||||
"mp4": video.basic.meta,
|
"mp4": video.basic.meta,
|
||||||
"mov": video.basic.meta,
|
"mov": video.basic.meta,
|
||||||
"ogv": video.basic.meta,
|
"ogv": video.basic.meta,
|
||||||
"mpeg": video.basic.meta,
|
"mpeg": video.basic.meta,
|
||||||
}
|
} | meta_source_code
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
from . import common, csv, plain # noqa
|
from . import common, csv, html, plain # noqa
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
"pl": "perl",
|
"pl": "perl",
|
||||||
"PL": "perl",
|
"PL": "perl",
|
||||||
"htm": "html",
|
"htm": "html",
|
||||||
"html": "html",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,20 +70,27 @@ def meta(file: File):
|
||||||
with file.file.open("r") as f:
|
with file.file.open("r") as f:
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
for line in lines:
|
for line in lines:
|
||||||
descr += line + "\n"
|
if i == 0:
|
||||||
|
descr += line + "\n"
|
||||||
|
else:
|
||||||
|
descr += line + " "
|
||||||
i += 1
|
i += 1
|
||||||
if i > 100:
|
if i > 20:
|
||||||
descr += "..."
|
descr += "..."
|
||||||
break
|
break
|
||||||
url = file.get_absolute_url()
|
url = file.get_absolute_url()
|
||||||
|
section = ""
|
||||||
|
if file.file_type:
|
||||||
|
section = file.file_type.split("/")[0]
|
||||||
|
|
||||||
meat_f = f"""
|
meat_f = f"""
|
||||||
<meta property="og:type" content="article">
|
<meta property="og:type" content="article">
|
||||||
<meta property="og:title" content="{file.name}">
|
<meta property="og:title" content="{file.name}">
|
||||||
<meta property="og:url" content="{url}">
|
<meta property="og:url" content="{url}">
|
||||||
<meta property="og:image" content="">
|
<meta property="og:image" content="">
|
||||||
<meta property="og:description" content="{descr}">
|
<meta property="og:description" content="{html.escape(descr)}">
|
||||||
<meta property="article:author" content="{file.user.username}">
|
<meta property="article:author" content="{file.user.username}">
|
||||||
|
<meta property="article:section" content="{section}">
|
||||||
<meta property="article:published_time" content="{file.created}">
|
<meta property="article:published_time" content="{file.created}">
|
||||||
<meta property="article:modified_time" content="{file.modified}">
|
<meta property="article:modified_time" content="{file.modified}">
|
||||||
"""
|
"""
|
||||||
|
|
82
akarpov/files/previews/text/html.py
Normal file
82
akarpov/files/previews/text/html.py
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
import html
|
||||||
|
|
||||||
|
from akarpov.files.models import File
|
||||||
|
|
||||||
|
|
||||||
|
def view(file: File) -> (str, str):
|
||||||
|
static = f"""
|
||||||
|
<meta property="og:title" content="{file.name}" />
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/atom-one-light.min.css">
|
||||||
|
"""
|
||||||
|
content = "<div class='col-auto'><pre>"
|
||||||
|
with file.file.open("r") as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
style = False
|
||||||
|
js = False
|
||||||
|
for line in lines:
|
||||||
|
if "<style" in line and "</style>" not in line:
|
||||||
|
style = True
|
||||||
|
elif "</style>" in line:
|
||||||
|
style = False
|
||||||
|
|
||||||
|
if "<script" in line and "</script>" not in line:
|
||||||
|
js = True
|
||||||
|
elif "</script>" in line:
|
||||||
|
js = False
|
||||||
|
|
||||||
|
if style:
|
||||||
|
content += f"""<div class='code language-css'>{html.escape(line)}</div>"""
|
||||||
|
elif js:
|
||||||
|
content += (
|
||||||
|
f"""<div class='code language-javascript'>{html.escape(line)}</div>"""
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
content += f"""<div class='code language-html'>{html.escape(line)}</div>"""
|
||||||
|
|
||||||
|
content += """</pre></div>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/javascipt.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/html.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/languages/css.min.js"></script>
|
||||||
|
<script>
|
||||||
|
hljs.configure({ ignoreUnescapedHTML: true })
|
||||||
|
document.querySelectorAll('div.code').forEach(el => {
|
||||||
|
hljs.highlightElement(el);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
"""
|
||||||
|
|
||||||
|
return static, content
|
||||||
|
|
||||||
|
|
||||||
|
def meta(file: File):
|
||||||
|
descr = ""
|
||||||
|
i = 0
|
||||||
|
with file.file.open("r") as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
for line in lines:
|
||||||
|
if i == 0:
|
||||||
|
descr += line + "\n"
|
||||||
|
else:
|
||||||
|
descr += line + " "
|
||||||
|
i += 1
|
||||||
|
if i > 20:
|
||||||
|
descr += "..."
|
||||||
|
break
|
||||||
|
url = file.get_absolute_url()
|
||||||
|
section = ""
|
||||||
|
if file.file_type:
|
||||||
|
section = file.file_type.split("/")[0]
|
||||||
|
|
||||||
|
meat_f = f"""
|
||||||
|
<meta property="og:type" content="article">
|
||||||
|
<meta property="og:title" content="{file.name}">
|
||||||
|
<meta property="og:url" content="{url}">
|
||||||
|
<meta property="og:image" content="">
|
||||||
|
<meta property="og:description" content="{html.escape(descr)}">
|
||||||
|
<meta property="article:author" content="{file.user.username}">
|
||||||
|
<meta property="article:section" content="{section}">
|
||||||
|
<meta property="article:published_time" content="{file.created}">
|
||||||
|
<meta property="article:modified_time" content="{file.modified}">
|
||||||
|
"""
|
||||||
|
return meat_f
|
|
@ -4,6 +4,8 @@
|
||||||
from PIL import Image, ImageDraw, ImageFont
|
from PIL import Image, ImageDraw, ImageFont
|
||||||
from preview_generator.manager import PreviewManager
|
from preview_generator.manager import PreviewManager
|
||||||
|
|
||||||
|
from akarpov.files.models import File
|
||||||
|
|
||||||
cache_path = "/tmp/preview_cache"
|
cache_path = "/tmp/preview_cache"
|
||||||
PIL_GRAYSCALE = "L"
|
PIL_GRAYSCALE = "L"
|
||||||
PIL_WIDTH_INDEX = 0
|
PIL_WIDTH_INDEX = 0
|
||||||
|
@ -92,3 +94,26 @@ def get_description(file_path: str) -> str:
|
||||||
if manager.has_text_preview(file_path):
|
if manager.has_text_preview(file_path):
|
||||||
return manager.get_text_preview(file_path)
|
return manager.get_text_preview(file_path)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def get_base_meta(file: File):
|
||||||
|
preview = file.preview.url if file.preview else ""
|
||||||
|
description = file.description if file.description else ""
|
||||||
|
return f"""
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:title" content="{file.name}">
|
||||||
|
<meta property="og:url" content="{file.get_absolute_url()}">
|
||||||
|
<meta property="og:image" content="{preview}">
|
||||||
|
<meta property="og:image:width" content="500" />
|
||||||
|
<meta property="og:image:height" content="500" />
|
||||||
|
<meta property="og:description" content="{description}">
|
||||||
|
|
||||||
|
<meta name="twitter:card" content="summary_large_image">
|
||||||
|
<meta name="twitter:title" content="{file.name}">
|
||||||
|
<meta name="twitter:site" content="{file.get_absolute_url()}">
|
||||||
|
<meta name="twitter:description" content="{description}">
|
||||||
|
<meta name="twitter:image" content="{preview}">
|
||||||
|
<meta property="twitter:image:width" content="500" />
|
||||||
|
<meta property="twitter:image:height" content="500" />
|
||||||
|
<meta name="twitter:image:alt" content="{file.name}">
|
||||||
|
"""
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
from akarpov.files.forms import FileForm
|
from akarpov.files.forms import FileForm
|
||||||
from akarpov.files.models import File, Folder
|
from akarpov.files.models import File, Folder
|
||||||
from akarpov.files.previews import extensions, meta, meta_extensions, previews
|
from akarpov.files.previews import extensions, meta, meta_extensions, previews
|
||||||
|
from akarpov.files.services.preview import get_base_meta
|
||||||
|
|
||||||
logger = structlog.get_logger(__name__)
|
logger = structlog.get_logger(__name__)
|
||||||
|
|
||||||
|
@ -69,38 +70,47 @@ def dispatch(self, request, *args, **kwargs):
|
||||||
return super().dispatch(request, *args, **kwargs)
|
return super().dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
|
||||||
context["has_perm"] = self.object.user == self.request.user
|
|
||||||
static = ""
|
static = ""
|
||||||
content = ""
|
content = ""
|
||||||
meta_s = ""
|
meta_s = ""
|
||||||
extension = self.object.file.path.split(".")[-1]
|
extension = self.object.file.path.split(".")[-1]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
meta_loaded = False
|
||||||
if self.object.file_type:
|
if self.object.file_type:
|
||||||
t1, t2 = self.object.file_type.split("/")
|
t1, t2 = self.object.file_type.split("/")
|
||||||
loaded = False
|
loaded = False
|
||||||
|
|
||||||
|
# get static and content for file view by mimetype
|
||||||
if t1 in previews:
|
if t1 in previews:
|
||||||
if t2 in previews[t1]:
|
if t2 in previews[t1]:
|
||||||
static, content = previews[t1][t2](self.object)
|
static, content = previews[t1][t2](self.object)
|
||||||
loaded = True
|
loaded = True
|
||||||
if not loaded and extension in extensions:
|
if not loaded and extension in extensions:
|
||||||
static, content = extensions[extension](self.object)
|
static, content = extensions[extension](self.object)
|
||||||
elif extension in extensions:
|
|
||||||
static, content = extensions[extension](self.object)
|
|
||||||
|
|
||||||
if self.object.file_type:
|
# get meta tags by mimetype
|
||||||
t1, t2 = self.object.file_type.split("/")
|
|
||||||
loaded = False
|
|
||||||
if t1 in meta:
|
if t1 in meta:
|
||||||
if t2 in meta[t1]:
|
if t2 in meta[t1]:
|
||||||
meta_s = meta[t1][t2](self.object)
|
meta_s = meta[t1][t2](self.object)
|
||||||
loaded = True
|
meta_loaded = True
|
||||||
if not loaded and extension in meta_extensions:
|
if not meta_loaded and extension in meta_extensions:
|
||||||
meta_s = meta_extensions[extension](self.object)
|
meta_s = meta_extensions[extension](self.object)
|
||||||
elif extension in meta_extensions:
|
else:
|
||||||
meta_s = meta_extensions[extension](self.object)
|
# get static and content for file view by file extension
|
||||||
|
if extension in extensions:
|
||||||
|
static, content = extensions[extension](self.object)
|
||||||
|
# get meta tags by file extension
|
||||||
|
if extension in meta_extensions:
|
||||||
|
meta_s = meta_extensions[extension](self.object)
|
||||||
|
meta_loaded = True
|
||||||
|
if not meta_loaded:
|
||||||
|
meta_s = get_base_meta(self.object)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(e)
|
logger.error(e)
|
||||||
|
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["has_perm"] = self.object.user == self.request.user
|
||||||
context["preview_static"] = static
|
context["preview_static"] = static
|
||||||
context["preview_content"] = content
|
context["preview_content"] = content
|
||||||
context["meta"] = meta_s
|
context["meta"] = meta_s
|
||||||
|
|
11
akarpov/users/signals.py
Normal file
11
akarpov/users/signals.py
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
from django.db.models.signals import pre_save
|
||||||
|
from django.dispatch import receiver
|
||||||
|
|
||||||
|
from akarpov.users.models import User
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(pre_save, sender=User)
|
||||||
|
def user_create(sender, instance: User, **kwargs):
|
||||||
|
if instance.id is None:
|
||||||
|
# give user some space on file share on register
|
||||||
|
instance.left_file_upload += 100 * 1024 * 1024
|
Loading…
Reference in New Issue
Block a user