diff options
author | Matthias Baumgartner <dev@igsor.net> | 2023-02-08 19:23:46 +0100 |
---|---|---|
committer | Matthias Baumgartner <dev@igsor.net> | 2023-02-08 19:23:46 +0100 |
commit | a281d6b3a75a7d4a97e673c285ee430a327482ed (patch) | |
tree | cbdecc56c7fca6a7a4cd03a1b974d5c60ee3cd7b /bsie/extractor/preview.py | |
parent | 482235a8229261fa905f73ce167982bca57ab3e6 (diff) | |
download | bsie-a281d6b3a75a7d4a97e673c285ee430a327482ed.tar.gz bsie-a281d6b3a75a7d4a97e673c285ee430a327482ed.tar.bz2 bsie-a281d6b3a75a7d4a97e673c285ee430a327482ed.zip |
preview extractor
Diffstat (limited to 'bsie/extractor/preview.py')
-rw-r--r-- | bsie/extractor/preview.py | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/bsie/extractor/preview.py b/bsie/extractor/preview.py new file mode 100644 index 0000000..1531d62 --- /dev/null +++ b/bsie/extractor/preview.py @@ -0,0 +1,99 @@ +""" + +Part of the bsie module. +A copy of the license is provided with the project. +Author: Matthias Baumgartner, 2022 +""" +# imports +import io +import typing + +# external imports +import PIL.Image + +# bsie imports +from bsie.utils import bsfs, node, ns + +# inner-module imports +from . import base + +# exports +__all__: typing.Sequence[str] = ( + 'Preview', + ) + + +## code ## + +class Preview(base.Extractor): + """Extract previews.""" + + CONTENT_READER = 'bsie.reader.preview.Preview' + + def __init__(self, max_sides: typing.Iterable[int]): + super().__init__(bsfs.schema.from_string(base.SCHEMA_PREAMBLE + ''' + + bsfs:Preview rdfs:subClassOf bsfs:Node . + bsfs:BinaryBlob rdfs:subClassOf bsfs:Literal . + bsfs:JPEG rdfs:subClassOf bsfs:BinaryBlob . + + bse:preview rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:File ; + rdfs:range bsfs:Preview ; + bsfs:unique "false"^^xsd:boolean . + + bsp:width rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Preview ; + rdfs:range xsd:integer ; + bsfs:unique "true"^^xsd:boolean . + + bsp:height rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Preview ; + rdfs:range xsd:integer ; + bsfs:unique "true"^^xsd:boolean . + + bsp:asset rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Preview ; + rdfs:range bsfs:JPEG ; + bsfs:unique "true"^^xsd:boolean . + + ''')) + # initialize extra args + self.max_sides = set(max_sides) + + def __eq__(self, other: typing.Any) -> bool: + return super().__eq__(other) \ + and self.max_sides == other.max_sides + + def __hash__(self) -> int: + return hash((super().__hash__(), tuple(sorted(self.max_sides)))) + + def extract( + self, + subject: node.Node, + content: typing.Callable[[int], PIL.Image.Image], + principals: typing.Iterable[bsfs.schema.Predicate], + ) -> typing.Iterator[typing.Tuple[node.Node, bsfs.schema.Predicate, typing.Any]]: + # check principals + if self.schema.predicate(ns.bse.preview) not in principals: + return + + for max_side in self.max_sides: + # get the preview in the right resolution + img = content(max_side) + # convert the preview to jpeg + buffer = io.BytesIO() + img.save(buffer, format='jpeg') + # create a preview node + preview = node.Node(ns.bsfs.Preview, + ucid=bsfs.uuid.UCID.from_bytes(buffer.getvalue()), + size=max_side, + source=subject, + ) + # yield triples + yield subject, self.schema.predicate(ns.bse.preview), preview + yield preview, self.schema.predicate(ns.bsp.width), img.width + yield preview, self.schema.predicate(ns.bsp.height), img.height + yield preview, self.schema.predicate(ns.bsp.asset), buffer.getvalue() + +## EOF ## |