import logging from collections import deque from importlib import import_module from os import path from lakesuperior.dictionaries.namespaces import ns_collection as nsc RES_CREATED = '_create_' """A resource was created.""" RES_DELETED = '_delete_' """A resource was deleted.""" RES_UPDATED = '_update_' """A resource was updated.""" ROOT_UID = '/' """Root node UID.""" ROOT_RSRC_URI = nsc['fcres'][ROOT_UID] """Internal URI of root resource.""" class AppGlobals: """ Application Globals. This class is instantiated and used as a carrier for all connections and various global variables outside of the Flask app context. The variables are set on initialization by passing a configuration dict. Usually this is done when starting an application. The instance with the loaded variables is then assigned to the :data:`lakesuperior.env` global variable. You can either load the default configuration:: >>>from lakesuperior import env_setup Or set up an environment with a custom configuration:: >>> from lakesuperior import env >>> from lakesuperior.app_globals import AppGlobals >>> my_config = {'name': 'value', '...': '...'} >>> env.app_globals = AppGlobals(my_config) """ def __init__(self, config): """ Generate global variables from configuration. """ from lakesuperior.messaging.messenger import Messenger app_conf = config['application'] # Initialize RDF layout. rdfly_mod_name = app_conf['store']['ldp_rs']['layout'] rdfly_mod = import_module('lakesuperior.store.ldp_rs.{}'.format( rdfly_mod_name)) rdfly_cls = getattr(rdfly_mod, self.camelcase(rdfly_mod_name)) #logger.info('RDF layout: {}'.format(rdfly_mod_name)) # Initialize file layout. nonrdfly_mod_name = app_conf['store']['ldp_nr']['layout'] nonrdfly_mod = import_module('lakesuperior.store.ldp_nr.{}'.format( nonrdfly_mod_name)) nonrdfly_cls = getattr(nonrdfly_mod, self.camelcase(nonrdfly_mod_name)) #logger.info('Non-RDF layout: {}'.format(nonrdfly_mod_name)) ## Initialize metadata store. #from lakesuperior.store.metadata_store import MetadataStore # Set up messaging. self._messenger = Messenger(app_conf['messaging']) # Exposed globals. self._config = config self._rdfly = rdfly_cls(app_conf['store']['ldp_rs']) self._nonrdfly = nonrdfly_cls(app_conf['store']['ldp_nr']) #self._md_store = MetadataStore(path.join( # app_conf['data_dir'], 'metadata'), create=True) self._changelog = deque() @property def config(self): """ Global configuration. This is a collection of all configuration options **except** for the WSGI configuration which is initialized at a different time and is stored under :data:`lakesuperior.env.wsgi_options`. *TODO:* Update class reference when interface will be separated from implementation. """ return self._config @property def rdfly(self): """ Current RDF layout. This is an instance of :class:`~lakesuperior.store.ldp_rs.rsrc_centric_layout.RsrcCentricLayout`. *TODO:* Update class reference when interface will be separated from implementation. """ return self._rdfly @property def rdf_store(self): """ Current RDF low-level store. This is an instance of :class:`~lakesuperior.store.ldp_rs.lmdb_store.LmdbStore`. """ return self._rdfly.store @property def nonrdfly(self): """ Current non-RDF (binary contents) layout. This is an instance of :class:`~lakesuperior.store.ldp_nr.base_non_rdf_layout.BaseNonRdfLayout`. """ return self._nonrdfly #@property #def md_store(self): # """ # Metadata store (LMDB). # This is an instance of # :class:`~lakesuperior.store.metadata_store.MetadataStore`. # """ # return self._md_store @property def messenger(self): """ Current message handler. This is an instance of :class:`~lakesuperior.messaging.messenger.Messenger`. """ return self._messenger @property def changelog(self): return self._changelog def camelcase(self, word): """ Convert a string with underscores to a camel-cased one. Ripped from https://stackoverflow.com/a/6425628 """ return ''.join(x.capitalize() or '_' for x in word.split('_'))