aboutsummaryrefslogtreecommitdiffstats
path: root/tagit/apps/desktop.py
blob: 149bf301681e267c8051e2e1dbb844fca84f10fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
"""

Part of the tagit module.
A copy of the license is provided with the project.
Author: Matthias Baumgartner, 2022
"""
# standard imports
import os
import typing

# kivy imports
from kivy.app import App
from kivy.resources import resource_find
from kivy.uix.settings import SettingsWithSidebar

# tagit imports
from tagit import config
from tagit.utils import bsfs, ns
from tagit.utils.bsfs import URI
from tagit.windows import desktop

# exports
__all__: typing.Sequence[str] = (
    'main',
    )


## 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."""

    def build(self):
        # set settings panel style
        self.settings_cls = SettingsWithSidebar

        # set title
        self.title = 'tagit v0.23.03'

        # load config
        from tagit.config.loader import load_settings, TAGITRC
        cfg = load_settings(TAGITRC, 0)

        # open BSFS storage
        store = load_data_hook(cfg, bsfs.Open(cfg('session', 'bsfs'))) # FIXME: mb/port: data hook
        # check storage schema
        with open(resource_find('required_schema.nt'), 'rt') as ifile:
            required_schema = bsfs.schema.from_string(ifile.read())
        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: mb/port: expects log arguments

    def on_start(self):
        # trigger startup operations
        self.root.on_startup()


def main(argv):
    """Start the tagit GUI. Opens a window to browse images."""
    # Run the GUI
    app = TagitApp()
    app.run()

## config

config.declare(('session', 'bsfs'), config.Any(), {},
    __name__, 'bsfs config', 'Configuration to connect to a BSFS storage.')

## main ##

if __name__ == '__main__':
    main()

## EOF ##