diff options
Diffstat (limited to 'tagit/apps')
-rw-r--r-- | tagit/apps/__init__.py | 44 | ||||
-rw-r--r-- | tagit/apps/desktop.py | 55 | ||||
-rw-r--r-- | tagit/apps/port-config.yaml | 154 | ||||
-rw-r--r-- | tagit/apps/port-schema.nt | 108 | ||||
-rw-r--r-- | tagit/apps/port_data.py | 127 |
5 files changed, 75 insertions, 413 deletions
diff --git a/tagit/apps/__init__.py b/tagit/apps/__init__.py index 4c64128..84d0bf1 100644 --- a/tagit/apps/__init__.py +++ b/tagit/apps/__init__.py @@ -1,10 +1,52 @@ -""" +#!/usr/bin/env python3 +"""The tagit applications. Part of the tagit module. A copy of the license is provided with the project. Author: Matthias Baumgartner, 2022 """ +# standard imports +import argparse +import typing + +# tagit imports +import tagit + # inner-module imports from .desktop import main as desktop +# exports +__all__: typing.Sequence[str] = ( + 'desktop', + 'main', + ) + +# config +apps = { + 'desktop' : desktop, + } + + +## code ## + +def main(argv=None): + """The BSFS browser, focused on image tagging.""" + parser = argparse.ArgumentParser(description=main.__doc__, prog='tagit') + # version + parser.add_argument('--version', action='version', + version='%(prog)s {}.{}.{}'.format(*tuple(tagit.version_info))) # pylint: disable=C0209 + # application selection + parser.add_argument('app', choices=apps.keys(), nargs='?', default='desktop', + help='Select the application to run.') + # dangling args + parser.add_argument('rest', nargs=argparse.REMAINDER) + # parse + args = parser.parse_args() + # run application + apps[args.app](args.rest) + +if __name__ == '__main__': + import sys + main(sys.argv[1:]) + ## EOF ## diff --git a/tagit/apps/desktop.py b/tagit/apps/desktop.py index 7b21336..149bf30 100644 --- a/tagit/apps/desktop.py +++ b/tagit/apps/desktop.py @@ -10,6 +10,7 @@ import typing # kivy imports from kivy.app import App +from kivy.resources import resource_find from kivy.uix.settings import SettingsWithSidebar # tagit imports @@ -26,6 +27,26 @@ __all__: typing.Sequence[str] = ( ## code ## +def load_data_hook(cfg, store): + """Data loading hook to circumvent non-persistent storage.""" + import pickle + import os + # fetch data_hook config flags + schema_path = os.path.expanduser(cfg('session', 'data_hook', 'schema')) + triples_path = os.path.expanduser(cfg('session', 'data_hook', 'triples')) + # load data if present + if os.path.exists(schema_path) and os.path.exists(triples_path): + with open(schema_path, 'rb') as ifile: + store._backend._schema = pickle.load(ifile) + with open(triples_path, 'rb') as ifile: + for triple in pickle.load(ifile): + store._backend._graph.add(triple) + return store + +config.declare(('session', 'data_hook', 'schema'), config.String(), '') +config.declare(('session', 'data_hook', 'triples'), config.String(), '') + + class TagitApp(App): """The tagit main application.""" @@ -34,41 +55,29 @@ class TagitApp(App): self.settings_cls = SettingsWithSidebar # set title - self.title = 'tagit v2.0' + self.title = 'tagit v0.23.03' - # FIXME: mb/port - # load essentials + # load config + from tagit.config.loader import load_settings, TAGITRC + cfg = load_settings(TAGITRC, 0) - #from tagit.config.loader import load_settings, TAGITRC - #cfg = load_settings(TAGITRC, 0) - cfg = config.Settings.Open(os.path.join(os.path.dirname(__file__), 'port-config.yaml')) - - # FIXME: mb/port/bsfs # open BSFS storage - store = bsfs.Open(cfg('session', 'bsfs')) + store = load_data_hook(cfg, bsfs.Open(cfg('session', 'bsfs'))) # FIXME: mb/port: data hook # check storage schema - # FIXME: Move somewhere else?! - with open(os.path.join(os.path.dirname(__file__), 'port-schema.nt'), 'rt') as ifile: + with open(resource_find('required_schema.nt'), 'rt') as ifile: required_schema = bsfs.schema.from_string(ifile.read()) - # FIXME: Since the store isn't persistent, we migrate to the required one here. - #if not required_schema <= store.schema: - # raise Exception('') - store.migrate(required_schema) - - # FIXME: debug: add some data to the storage - from . import port_data - port_data.add_port_data(store) + if not required_schema.consistent_with(store.schema): + raise Exception("The storage's schema is incompatible with tagit's requirements") + if not required_schema <= store.schema: + store.migrate(required_schema | store.schema) # create widget - return desktop.MainWindow(cfg, store, None) # FIXME: expects cfg, stor, log arguments + return desktop.MainWindow(cfg, store, None) # FIXME: mb/port: expects log arguments def on_start(self): # trigger startup operations self.root.on_startup() - # FIXME: mb/port - #def on_stop(self): - # self.root.session.storage.close() def main(argv): """Start the tagit GUI. Opens a window to browse images.""" diff --git a/tagit/apps/port-config.yaml b/tagit/apps/port-config.yaml deleted file mode 100644 index a9907b7..0000000 --- a/tagit/apps/port-config.yaml +++ /dev/null @@ -1,154 +0,0 @@ -session: - first_start: false - paths: - searchlog: ~/.tagit.log - bsfs: # FIXME: mb/port: rename to storage, but that space is currently polluted - Graph: - backend: - SparqlStore: {} - user: 'http://example.com/me' - script: - #- ShowBrowsing - - [AddToken, 'hello'] -storage: - index: - preview_size: - - 50 - - 200 - - 400 -ui: - standalone: - plane: browsing - keytriggers: - - CreateGroup - - DissolveGroup - - AddToGroup - - MoveCursorUp - - MoveCursorDown - - MoveCursorLeft - - MoveCursorRight - - MoveCursorLast - - MoveCursorFirst - - NextPage - - PreviousPage - - ScrollDown - - ScrollUp - - ZoomIn - - ZoomOut - - Select - - SelectAll - - SelectNone - - SelectMulti - - SelectRange - - AddToken - - GoBack - - GoForth - - SearchByAddressOnce - - SearchmodeSwitch - - AddTag - - EditTag - - OpenGroup - #- RepresentGroup - - Search - - ShowSelected - - RemoveSelected - - OpenExternal - - ShowHelp - browser: - maxcols: 8 - maxrows: 8 - buttondocks: - sidebar_left: - - Menu - - ShowDashboard - - AddToken - - AddTag - - EditTag - - CreateGroup - - DissolveGroup - - SelectAll - - SelectNone - - SelectInvert - - SelectAdditive - - SelectSubtractive - - SelectSingle - - SelectMulti - - SelectRange - - ShellDrop - filter: - - AddToken - - EditToken - context: - app: - - ShowSettings - - ShowHelp - - ShowConsole - - ShowBrowsing - browser: - - ZoomIn - - ZoomOut - # clipboard: - # - ClipboardCopy - # - ClipboardPaste - grouping: - - CreateGroup - - DissolveGroup - - AddToGroup - # - RepresentGroup - # - RemoveFromGroup - root: - - LoadSession - # search: - # - ShowSelected - # - RemoveSelected - select: - - SelectAll - - SelectNone - - SelectInvert - - SelectSingle - - SelectMulti - - SelectRange - - SelectAdditive - - SelectSubtractive - tagging: - - AddTag - - EditTag - # - SetRank1 - # - SetRank3 - # - SetRank5 - search: - sort_blacklist: - - entity - - flash - - latitude - - longitude - - mime - - author - - camera - - attributes - tiledocks: - dashboard: {} - #Buttons: - # buttons: - # - ShowBrowsing - # - CreateSession - # - CreateTempSession - # - LoadSession - # - ReloadSession - # - ImportObjects - # - ItemExport - # - UpdateSelectedObjects - # - ShowHelp - # - ShowSettings - #Hints: {} - #LibSummary: {} - #Searchtree: {} - #TagHistogram: {} - #Tagcloud: {} - sidebar_right: - Info: {} - CursorTags: {} - BrowserTags: {} - #SelectionTags: {} - #Geo: {} - window_size: 1024x768 diff --git a/tagit/apps/port-schema.nt b/tagit/apps/port-schema.nt deleted file mode 100644 index 7569052..0000000 --- a/tagit/apps/port-schema.nt +++ /dev/null @@ -1,108 +0,0 @@ -# common external prefixes -prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> -prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> -prefix xsd: <http://www.w3.org/2001/XMLSchema#> -prefix schema: <http://schema.org/> - -# common bsfs prefixes -prefix bsfs: <http://bsfs.ai/schema/> -prefix bse: <http://bsfs.ai/schema/Entity#> -prefix bst: <http://bsfs.ai/schema/Tag#> -prefix bsg: <http://bsfs.ai/schema/Group#> -prefix bsp: <http://bsfs.ai/schema/Preview#> - -# essential nodes -bsfs:Entity rdfs:subClassOf bsfs:Node . -bsfs:Preview rdfs:subClassOf bsfs:Node . -bsfs:File rdfs:subClassOf bsfs:Entity . -bsfs:Tag rdfs:subClassOf bsfs:Node . -bsfs:Group rdfs:subClassOf bsfs:Node . - -# common definitions -bsfs:BinaryBlob rdfs:subClassOf bsfs:Literal . -bsfs:URI rdfs:subClassOf bsfs:Literal . -bsfs:Number rdfs:subClassOf bsfs:Literal . -bsfs:Time rdfs:subClassOf bsfs:Literal . -bsfs:JPEG rdfs:subClassOf bsfs:BinaryBlob . -xsd:string rdfs:subClassOf bsfs:Literal . -xsd:integer rdfs:subClassOf bsfs:Number . - -bse:filename rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:File ; - rdfs:range xsd:string ; - rdfs:label "File name"^^xsd:string ; - schema:description "Filename of entity in some filesystem."^^xsd:string ; - bsfs:unique "true"^^xsd:boolean . - -bse:filesize rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:File ; - rdfs:range xsd:integer ; - rdfs:label "File size"^^xsd:string ; - schema:description "File size of entity in some filesystem."^^xsd:string ; - bsfs:unique "true"^^xsd:boolean . - -bse:mime rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:File ; - rdfs:range xsd:string ; - bsfs:unique "true"^^xsd:boolean . - -bse:preview rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range bsfs:Preview . - -bse:tag rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:File ; - rdfs:range bsfs:Tag . - -bst:label rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Tag ; - rdfs:range xsd:string ; - bsfs:unique "true"^^xsd:boolean . - -bse:comment rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Node ; - rdfs:range xsd:string . - -bse:group rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Entity ; - rdfs:range bsfs:Group . - -bsg:represented_by rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:Group ; - rdfs:range bsfs:File ; - bsfs:unique "true"^^xsd:boolean . - -bse:longitude rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:File ; - rdfs:range xsd:integer ; - bsfs:unique "true"^^xsd:boolean . - -bse:latitude rdfs:subClassOf bsfs:Predicate ; - rdfs:domain bsfs:File ; - rdfs:range xsd:integer ; - bsfs:unique "true"^^xsd:boolean . - - -## preview nodes - -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:orientation 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 . - - diff --git a/tagit/apps/port_data.py b/tagit/apps/port_data.py deleted file mode 100644 index cda2d63..0000000 --- a/tagit/apps/port_data.py +++ /dev/null @@ -1,127 +0,0 @@ -import os -from tagit.utils import ns -from tagit.utils.bsfs import URI - -def add_port_data(store): - # tags - t_hello = store.node(ns.bsfs.Tag, URI('http://example.com/me/tag#hello')) \ - .set(ns.bst.label, 'hello') - t_world = store.node(ns.bsfs.Tag, URI('http://example.com/me/tag#world')) \ - .set(ns.bst.label, 'world') - t_foobar = store.node(ns.bsfs.Tag, URI('http://example.com/me/tag#foobar')) \ - .set(ns.bst.label, 'foobar') - - # entities - n0 = store.node(ns.bsfs.File, URI('http://example.com/me/entity#01')) \ - .set(ns.bse.filename, 'textfile.t') \ - .set(ns.bse.filesize, 100) \ - .set(ns.bse.tag, t_hello) \ - .set(ns.bse.tag, t_foobar) \ - .set(ns.bse.latitude, 47.374444) \ - .set(ns.bse.longitude, 8.541111) - n1 = store.node(ns.bsfs.File, URI('http://example.com/me/entity#02')) \ - .set(ns.bse.filename, 'document.pdf') \ - .set(ns.bse.filesize, 200) \ - .set(ns.bse.tag, t_world) \ - .set(ns.bse.tag, t_foobar) - n2 = store.node(ns.bsfs.File, URI('http://example.com/me/entity#03')) \ - .set(ns.bse.filename, 'document.odt') \ - .set(ns.bse.filesize, 300) \ - .set(ns.bse.tag, t_world) - n3 = store.node(ns.bsfs.File, URI('http://example.com/me/entity#04')) \ - .set(ns.bse.filename, 'image.jpg') \ - .set(ns.bse.comment, 'some image') \ - .set(ns.bse.tag, t_hello) \ - .set(ns.bse.tag, t_foobar) - n4 = store.node(ns.bsfs.File, URI('http://example.com/me/entity#05')) \ - .set(ns.bse.filename, 'image.png') \ - .set(ns.bse.comment, 'another image') \ - .set(ns.bse.tag, t_hello) - - # groups - grp = store.node(ns.bsfs.Group, URI('http://example.com/me/group#1234')) - grp.set(ns.bsg.represented_by, n0) - n0.set(ns.bse.group, grp) - n1.set(ns.bse.group, grp) - n3.set(ns.bse.group, grp) - - # previews - base = os.path.join(os.path.dirname(__file__), 'port-data') - n0.set(ns.bse.preview, - store.node(ns.bsfs.Preview, URI('http://example.com/me/preview#ent01_w100_h100')) \ - .set(ns.bsp.width, 100) \ - .set(ns.bsp.height, 100) \ - .set(ns.bsp.orientation, 1) \ - .set(ns.bsp.asset, open(os.path.join(base, 'ent01_w100_h100.jpg'), 'rb').read()) - ) - n0.set(ns.bse.preview, - store.node(ns.bsfs.Preview, str('http://example.com/me/preview#ent01_w400_h200')) \ - .set(ns.bsp.width, 200) \ - .set(ns.bsp.height, 400) \ - .set(ns.bsp.orientation, 1) \ - .set(ns.bsp.asset, open(os.path.join(base, 'ent01_w400_h200.jpg'), 'rb').read()) - ) - n0.set(ns.bse.preview, - store.node(ns.bsfs.Preview, URI('http://example.com/me/preview#ent01_w400_h400')) \ - .set(ns.bsp.width, 400) \ - .set(ns.bsp.height, 400) \ - .set(ns.bsp.orientation, 1) \ - .set(ns.bsp.asset, open(os.path.join(base, 'ent01_w400_h400.jpg'), 'rb').read()) - ) - n1.set(ns.bse.preview, - store.node(ns.bsfs.Preview, URI('http://example.com/me/preview#ent02_w100_h100')) \ - .set(ns.bsp.width, 100) \ - .set(ns.bsp.height, 100) \ - .set(ns.bsp.orientation, 1) \ - .set(ns.bsp.asset, open(os.path.join(base, 'ent02_w100_h100.jpg'), 'rb').read()) - ) - n1.set(ns.bse.preview, - store.node(ns.bsfs.Preview, URI('http://example.com/me/preview#ent02_w400_h200')) \ - .set(ns.bsp.width, 200) \ - .set(ns.bsp.height, 400) \ - .set(ns.bsp.orientation, 1) \ - .set(ns.bsp.asset, open(os.path.join(base, 'ent02_w400_h200.jpg'), 'rb').read()) - ) - n2.set(ns.bse.preview, - store.node(ns.bsfs.Preview, URI('http://example.com/me/preview#ent03_w100_h100')) \ - .set(ns.bsp.width, 100) \ - .set(ns.bsp.height, 100) \ - .set(ns.bsp.orientation, 1) \ - .set(ns.bsp.asset, open(os.path.join(base, 'ent03_w100_h100.jpg'), 'rb').read()) - ) - n2.set(ns.bse.preview, - store.node(ns.bsfs.Preview, URI('http://example.com/me/preview#ent03_w400_h200')) \ - .set(ns.bsp.width, 200) \ - .set(ns.bsp.height, 400) \ - .set(ns.bsp.orientation, 1) \ - .set(ns.bsp.asset, open(os.path.join(base, 'ent03_w400_h200.jpg'), 'rb').read()) - ) - n3.set(ns.bse.preview, - store.node(ns.bsfs.Preview, URI('http://example.com/me/preview#ent04_w100_h100')) \ - .set(ns.bsp.width, 100) \ - .set(ns.bsp.height, 100) \ - .set(ns.bsp.orientation, 1) \ - .set(ns.bsp.asset, open(os.path.join(base, 'ent04_w100_h100.png'), 'rb').read()) - ) - n3.set(ns.bse.preview, - store.node(ns.bsfs.Preview, URI('http://example.com/me/preview#ent04_w400_h200')) \ - .set(ns.bsp.width, 200) \ - .set(ns.bsp.height, 400) \ - .set(ns.bsp.orientation, 1) \ - .set(ns.bsp.asset, open(os.path.join(base, 'ent04_w400_h200.png'), 'rb').read()) - ) - n4.set(ns.bse.preview, - store.node(ns.bsfs.Preview, URI('http://example.com/me/preview#ent05_w100_h100')) \ - .set(ns.bsp.width, 100) \ - .set(ns.bsp.height, 100) \ - .set(ns.bsp.orientation, 1) \ - .set(ns.bsp.asset, open(os.path.join(base, 'ent05_w100_h100.jpg'), 'rb').read()) - ) - n4.set(ns.bse.preview, - store.node(ns.bsfs.Preview, URI('http://example.com/me/preview#ent05_w400_h200')) \ - .set(ns.bsp.width, 200) \ - .set(ns.bsp.height, 400) \ - .set(ns.bsp.orientation, 1) \ - .set(ns.bsp.asset, open(os.path.join(base, 'ent05_w400_h200.jpg'), 'rb').read()) - ) - |