added meta for all files, html preview

This commit is contained in:
Alexander Karpov 2023-04-21 21:30:32 +03:00
parent 4c2a00a06a
commit 24ef17bde3
7 changed files with 165 additions and 19 deletions

View File

@ -34,7 +34,7 @@
},
"text": {
"css": text.common.view,
"html": text.common.view,
"html": text.html.view,
"javascript": text.common.view,
"plain": text.plain.view,
"csv": text.csv.view,
@ -76,6 +76,7 @@
"mpeg": video.mp4.view,
"oga": audio.oga.view,
"pdf": application.pdf.view,
"html": text.html.view,
}
| source_code
| fonts_ext
@ -88,12 +89,23 @@
"ogg": video.basic.meta,
"mpeg": 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 = {
"mp4": video.basic.meta,
"mov": video.basic.meta,
"ogv": video.basic.meta,
"mpeg": video.basic.meta,
}
} | meta_source_code

View File

@ -1 +1 @@
from . import common, csv, plain # noqa
from . import common, csv, html, plain # noqa

View File

@ -26,7 +26,6 @@
"pl": "perl",
"PL": "perl",
"htm": "html",
"html": "html",
}
@ -71,20 +70,27 @@ def meta(file: File):
with file.file.open("r") as f:
lines = f.readlines()
for line in lines:
descr += line + "\n"
if i == 0:
descr += line + "\n"
else:
descr += line + " "
i += 1
if i > 100:
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="{descr}">
<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}">
"""

View 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

View File

@ -4,6 +4,8 @@
from PIL import Image, ImageDraw, ImageFont
from preview_generator.manager import PreviewManager
from akarpov.files.models import File
cache_path = "/tmp/preview_cache"
PIL_GRAYSCALE = "L"
PIL_WIDTH_INDEX = 0
@ -92,3 +94,26 @@ def get_description(file_path: str) -> str:
if manager.has_text_preview(file_path):
return manager.get_text_preview(file_path)
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}">
"""

View File

@ -18,6 +18,7 @@
from akarpov.files.forms import FileForm
from akarpov.files.models import File, Folder
from akarpov.files.previews import extensions, meta, meta_extensions, previews
from akarpov.files.services.preview import get_base_meta
logger = structlog.get_logger(__name__)
@ -69,38 +70,47 @@ def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["has_perm"] = self.object.user == self.request.user
static = ""
content = ""
meta_s = ""
extension = self.object.file.path.split(".")[-1]
try:
meta_loaded = False
if self.object.file_type:
t1, t2 = self.object.file_type.split("/")
loaded = False
# get static and content for file view by mimetype
if t1 in previews:
if t2 in previews[t1]:
static, content = previews[t1][t2](self.object)
loaded = True
if not loaded and extension in extensions:
static, content = extensions[extension](self.object)
elif extension in extensions:
static, content = extensions[extension](self.object)
if self.object.file_type:
t1, t2 = self.object.file_type.split("/")
loaded = False
# get meta tags by mimetype
if t1 in meta:
if t2 in meta[t1]:
meta_s = meta[t1][t2](self.object)
loaded = True
if not loaded and extension in meta_extensions:
meta_loaded = True
if not meta_loaded and extension in meta_extensions:
meta_s = meta_extensions[extension](self.object)
elif extension in meta_extensions:
meta_s = meta_extensions[extension](self.object)
else:
# 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:
logger.error(e)
context = super().get_context_data(**kwargs)
context["has_perm"] = self.object.user == self.request.user
context["preview_static"] = static
context["preview_content"] = content
context["meta"] = meta_s

11
akarpov/users/signals.py Normal file
View 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