aboutsummaryrefslogtreecommitdiffstats
path: root/bsie/extractor/preview.py
diff options
context:
space:
mode:
Diffstat (limited to 'bsie/extractor/preview.py')
-rw-r--r--bsie/extractor/preview.py99
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 ##