Add thumbnail support to MediaElements

master
Felix Stupp 3 years ago
parent d41f2d2945
commit 44eb0850f0
Signed by: zocker
GPG Key ID: 93E1BD26F6B02FB7

@ -10,12 +10,34 @@ import math
import logging import logging
from typing import Callable, Dict, Iterable, List, Optional, Set, Tuple, TypeVar, Union from typing import Callable, Dict, Iterable, List, Optional, Set, Tuple, TypeVar, Union
import magic
import requests
from pony import orm from pony import orm
from pony.orm.core import Query from pony.orm.core import Query
db = orm.Database() db = orm.Database()
THUMBNAIL_ALLOWED_TYPES = [
"image/avif",
"image/jpeg",
"image/png",
"image/webp",
]
THUMBNAIL_HEADERS = {
"Accept": ",".join(THUMBNAIL_ALLOWED_TYPES) + ",*/*;q=0.9",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0",
}
THUMBNAIL_TARGET = 16 / 9
def thumbnail_sort_key(width: int, height: int) -> Tuple:
return (
abs((width / height) - THUMBNAIL_TARGET),
width * height,
)
#### ####
## Model Extensions ## Model Extensions
#### ####
@ -367,6 +389,7 @@ class MediaElement(db.Entity, Tagable):
uri: str = orm.Required(str, unique=True) uri: str = orm.Required(str, unique=True)
title: str = orm.Optional(str) title: str = orm.Optional(str)
thumbnail: MediaThumbnail = orm.Optional(lambda: MediaThumbnail)
notes: str = orm.Optional(str) notes: str = orm.Optional(str)
release_date: datetime = orm.Optional(datetime) release_date: datetime = orm.Optional(datetime)
@ -468,6 +491,48 @@ class MediaElement(db.Entity, Tagable):
return f"/media/{self.id}" return f"/media/{self.id}"
class MediaThumbnail(db.Entity):
id: int = orm.PrimaryKey(int, auto=True)
uri: str = orm.Required(str, unique=True)
last_downloaded: datetime = orm.Optional(datetime, default=None, nullable=True)
last_accessed: datetime = orm.Optional(datetime, default=None, nullable=True)
mime_type: str = orm.Optional(str, default="")
data: bytes = orm.Optional(bytes, default=None, nullable=True, lazy=True)
elements: Set[MediaElement] = orm.Set(lambda: MediaElement)
@classmethod
def from_uri(cls, uri: str) -> MediaThumbnail:
return cls.get(uri=uri) or MediaThumbnail(uri=uri)
def access(self):
self.last_accessed = datetime.now()
def download(self) -> bool:
res = requests.get(url=self.uri, headers=THUMBNAIL_HEADERS)
mime = magic.from_buffer(res.content, mime=True)
if mime not in THUMBNAIL_ALLOWED_TYPES:
return False
self.mime_type = mime
self.data = res.content
self.last_downloaded = datetime.now()
return True
def prepare(self) -> bool:
if self.last_downloaded is not None:
return True
return self.download()
def access_data(self):
self.prepare()
self.access()
def receive_data(self) -> bytes:
self.access_data()
return self.data
class MediaUriMapping(db.Entity): class MediaUriMapping(db.Entity):
id: int = orm.PrimaryKey(int, auto=True) id: int = orm.PrimaryKey(int, auto=True)

Loading…
Cancel
Save