aboutsummaryrefslogtreecommitdiffstats
path: root/tagit/apps
diff options
context:
space:
mode:
Diffstat (limited to 'tagit/apps')
-rw-r--r--tagit/apps/__init__.py44
-rw-r--r--tagit/apps/desktop.py55
-rw-r--r--tagit/apps/port-config.yaml154
-rw-r--r--tagit/apps/port-schema.nt108
-rw-r--r--tagit/apps/port_data.py127
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())
- )
-