From 4d0ce7fb62eaad3a1f705ec3c77744e3ebc96a9e Mon Sep 17 00:00:00 2001 From: Matthias Baumgartner Date: Sun, 29 Jan 2023 11:31:16 +0100 Subject: session actions port --- .gitignore | 1 + tagit/actions/__init__.py | 8 +- tagit/actions/session.kv | 7 ++ tagit/actions/session.py | 56 +++++++++ tagit/apps/port-config.yaml | 4 +- tagit/assets/icons/scalable/session/open.svg | 180 +++++++++++++++++++++++++++ tagit/dialogues/__init__.py | 8 +- tagit/dialogues/file_picker.py | 39 ++++++ tagit/dialogues/path_picker.kv | 27 ++++ tagit/dialogues/path_picker.py | 41 ++++++ tagit/widgets/session.py | 21 +++- 11 files changed, 374 insertions(+), 18 deletions(-) create mode 100644 tagit/actions/session.kv create mode 100644 tagit/actions/session.py create mode 100644 tagit/assets/icons/scalable/session/open.svg create mode 100644 tagit/dialogues/file_picker.py create mode 100644 tagit/dialogues/path_picker.kv create mode 100644 tagit/dialogues/path_picker.py diff --git a/.gitignore b/.gitignore index 084e82d..ba73cdf 100644 --- a/.gitignore +++ b/.gitignore @@ -38,6 +38,7 @@ tagit/assets/icons/kivy/grouping* tagit/assets/icons/kivy/misc* tagit/assets/icons/kivy/planes* tagit/assets/icons/kivy/search* +tagit/assets/icons/kivy/session* tagit/assets/icons/kivy/tagging* ## EOF ## diff --git a/tagit/actions/__init__.py b/tagit/actions/__init__.py index 7144e44..fa2bed0 100644 --- a/tagit/actions/__init__.py +++ b/tagit/actions/__init__.py @@ -18,7 +18,7 @@ from . import misc #from . import objects from . import planes from . import search -#from . import session +from . import session from . import tagging # exports @@ -104,11 +104,7 @@ class ActionBuilder(BuilderBase): #'SortKey': search.SortKey, 'SortOrder': search.SortOrder, ## session - #'LoadSession': session.LoadSession, - #'CreateSession': session.CreateSession, - #'CreateTempSession': session.CreateTempSession, - #'ReloadSession': session.ReloadSession, - #'CloseSessionAndExit': session.CloseSessionAndExit, + 'LoadSession': session.LoadSession, } ## EOF ## diff --git a/tagit/actions/session.kv b/tagit/actions/session.kv new file mode 100644 index 0000000..21807b2 --- /dev/null +++ b/tagit/actions/session.kv @@ -0,0 +1,7 @@ +#:import resource_find kivy.resources.resource_find + +: + source: resource_find('atlas://session/open') + tooltip: 'Load a session' + +## EOF ## diff --git a/tagit/actions/session.py b/tagit/actions/session.py new file mode 100644 index 0000000..3c5ad39 --- /dev/null +++ b/tagit/actions/session.py @@ -0,0 +1,56 @@ +""" + +Part of the tagit module. +A copy of the license is provided with the project. +Author: Matthias Baumgartner, 2022 +""" +# standard imports +import os + +# kivy imports +from kivy.lang import Builder +import kivy.properties as kp + +# tagit imports +from tagit import config, dialogues +from tagit.config.loader import load_settings + +# inner-module imports +from .action import Action + +# exports +__all__ = [] + + +## code ## + +# load kv +Builder.load_file(os.path.join(os.path.dirname(__file__), 'session.kv')) + +# classes +class LoadSession(Action): + """Load a session from a project file.""" + text = kp.StringProperty('Load') + + def apply(self): + """Open a file load dialogue to select a session file.""" + dlg = dialogues.FilePicker(title='Select a session file to load') + dlg.bind(on_ok=self.load_from_path) + dlg.open() + + def load_from_path(self, wx): + """Load a session from *path*.""" + with self.root.session as session: + try: + if not os.path.exists(wx.path) or not os.path.isfile(wx.path): + raise FileNotFoundError(wx.path) + + # load config from path + cfg = load_settings(wx.path, verbose=self.cfg('session', 'verbose')) + session.load(cfg) + + except Exception as e: + dialogues.Error(text=f'The file cannot be loaded ({e})').open() + + +## EOF ## diff --git a/tagit/apps/port-config.yaml b/tagit/apps/port-config.yaml index 6b0b06d..c4d47dd 100644 --- a/tagit/apps/port-config.yaml +++ b/tagit/apps/port-config.yaml @@ -87,8 +87,8 @@ ui: - AddToGroup # - RepresentGroup # - RemoveFromGroup - # root: - # - CloseSessionAndExit + root: + - LoadSession # search: # - ShowSelected # - RemoveSelected diff --git a/tagit/assets/icons/scalable/session/open.svg b/tagit/assets/icons/scalable/session/open.svg new file mode 100644 index 0000000..0b2d29c --- /dev/null +++ b/tagit/assets/icons/scalable/session/open.svg @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tagit/dialogues/__init__.py b/tagit/dialogues/__init__.py index a467699..3647bf0 100644 --- a/tagit/dialogues/__init__.py +++ b/tagit/dialogues/__init__.py @@ -23,11 +23,11 @@ from .console import Console #from .dir_picker import DirPicker from .error import Error #from .file_creator import FileCreator -#from .file_picker import FilePicker +from .file_picker import FilePicker from .message import Message from .numeric_input import NumericInput #from .path_creator import PathCreator -#from .path_picker import PathPicker +from .path_picker import PathPicker #from .project import Project from .simple_input import SimpleInput from .stoken import TokenEdit @@ -40,11 +40,11 @@ __all__: typing.Sequence[str] = ( #'DirPicker', 'Error', #'FileCreator', - #'FilePicker', + 'FilePicker', 'Message', 'NumericInput', #'PathCreator', - #'PathPicker', + 'PathPicker', #'Project', 'SimpleInput', 'TokenEdit', diff --git a/tagit/dialogues/file_picker.py b/tagit/dialogues/file_picker.py new file mode 100644 index 0000000..283adb6 --- /dev/null +++ b/tagit/dialogues/file_picker.py @@ -0,0 +1,39 @@ +"""Dialogue to pick a file. + +Part of the tagit module. +A copy of the license is provided with the project. +Author: Matthias Baumgartner, 2022 +""" +# standard imports +import os + +# kivy imports +from kivy.lang import Builder + +# inner-module imports +from .path_picker import PathPicker +from .error import Error + +# exports +__all__ = ('FilePicker', ) + + +## code ## + +# load kv +Builder.load_string(''' +: + dirselect: False + title: 'Please select a file' +''') + +# classes +class FilePicker(PathPicker): + """Dialogue with a file browser to select a file.""" + def ok(self): + if not os.path.exists(self.path) or not os.path.isfile(self.path): + Error(text='Please select a file').open() + else: + super(FilePicker, self).ok() + +## EOF ## diff --git a/tagit/dialogues/path_picker.kv b/tagit/dialogues/path_picker.kv new file mode 100644 index 0000000..1837b80 --- /dev/null +++ b/tagit/dialogues/path_picker.kv @@ -0,0 +1,27 @@ +#:import join os.path.join +#:import pwd os.path.curdir + +: + path: '' + title: 'Please select a file or directory' + filters: [] + dirselect: True + + DialogueContentTitle: + title: root.title + size_hint_y: 0.8 + + FileChooserListView: + text_size: self.width - dp(16), None + halign: 'center' + dirselect: root.dirselect + path: pwd + filters: root.filters + + on_selection: root.path = join(self.path, self.selection[0]); buttons.ok_enabled = True + + DialogueButtons_Two: + id: buttons + ok_enabled: False + +## EOF ## diff --git a/tagit/dialogues/path_picker.py b/tagit/dialogues/path_picker.py new file mode 100644 index 0000000..25bbf32 --- /dev/null +++ b/tagit/dialogues/path_picker.py @@ -0,0 +1,41 @@ +"""Dialogue to pick a file or directory. + +Part of the tagit module. +A copy of the license is provided with the project. +Author: Matthias Baumgartner, 2022 +""" +# standard imports +import os + +# kivy imports +from kivy.lang import Builder +import kivy.properties as kp + +# inner-module imports +from .dialogue import Dialogue +from .error import Error + +# exports +__all__ = ('PathPicker', ) + + +## code ## + +# load kv +Builder.load_file(os.path.join(os.path.dirname(__file__), 'path_picker.kv')) + +# classes +class PathPicker(Dialogue): + """Dialogue with a file browser to select a file or directory.""" + + title = kp.StringProperty('') + path = kp.StringProperty('') + filters = kp.ListProperty() + + def ok(self): + if not os.path.exists(self.path): + Error(text='Please select a file or directory').open() + else: + super(PathPicker, self).ok() + +## EOF ## diff --git a/tagit/widgets/session.py b/tagit/widgets/session.py index f45ab35..e97a688 100644 --- a/tagit/widgets/session.py +++ b/tagit/widgets/session.py @@ -5,7 +5,7 @@ A copy of the license is provided with the project. Author: Matthias Baumgartner, 2022 """ # standard imports -from threading import current_thread +import os import typing # kivy imports @@ -16,8 +16,7 @@ import kivy.properties as kp # tagit imports from tagit import parsing from tagit.config.loader import load_settings -#from tagit.storage.broker import Broker # FIXME: mb/port -#from tagit.storage.loader import load_broker, load_log # FIXME: mb/port +from tagit.utils import bsfs # exports __all__: typing.Sequence[str] = ( @@ -63,10 +62,20 @@ class Session(Widget): def load(self, cfg): """Load the session from configuration *cfg*.""" - self.cfg = cfg + #self.log = load_log(cfg) # FIXME: mb/port # initialize storages from config - self.log = load_log(cfg) - self.storage = load_broker(cfg) + # open BSFS storage + store = bsfs.Open(cfg('session', 'bsfs')) + # check storage schema + # FIXME: how to properly load the required schema? + with open(os.path.join(os.path.dirname(__file__), '..', 'apps', 'port-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) + # replace current with new storage + self.storage = store def update_settings_key(self, key, value): # change setting -- cgit v1.2.3