def rebuild_plugin_static_symlinks(plugin_paths): """Delete and recreate symlinks from the main static/ directory to plugins' static directories. """ # find share/static/plugins here = os.path.dirname(os.path.abspath(__file__)) static_plugins = os.path.abspath( os.path.join(here, '../share/static/plugins')) if not os.path.exists(static_plugins): debug_error( "can't find main static plugins directory (expected at {})".format( static_plugins)) sys.exit(1) debug_detail(' {}'.format(static_plugins)) # remove existing links for rel_fn in os.listdir(static_plugins): abs_fn = os.path.join(static_plugins, rel_fn) if os.path.islink(abs_fn): os.unlink(abs_fn) # add fresh links for plugin_path in plugin_paths: plugin_static = os.path.join(plugin_path, 'static') plugin_name = os.path.basename(plugin_path) if os.path.exists(plugin_static): debug_detail(' {} -> {}'.format(plugin_name, plugin_static)) os.symlink(plugin_static, os.path.join(static_plugins, plugin_name))
def __init__(self, backend, config): try: external_config_string = config.get('webapp', 'external_link_templates') except: external_config_string = '{}' try: self.external_link_templates = json.loads(external_config_string) except: debug_error('WARNING: could not parse JSON in config file for external_link_templates') self.external_link_templates = dict()
def set(self, key, value, timeout=None): ''' Adds a new key/value pair overwriting any existing value for the key. If timeout is given, sets the timeout on the key to be the given timeout, otherwise it does not set one Returns True if the key/value pair was set successfully, False otherwise ''' try: if timeout is None: return uwsgi.cache_set(key, value) else: return uwsgi.cache_set(key, value, timeout) except Exception as e: debug_error(e) return False
def __init__(self, backend, config): try: external_config_string = config.get('webapp', 'external_link_templates') except: external_config_string = '{}' try: self.external_link_templates = json.loads(external_config_string) except: debug_error( 'WARNING: could not parse JSON in config file for external_link_templates' ) self.external_link_templates = dict()
def inc(self, key, delta=1): ''' Increments the value of the given key by delta. If the key does not exist, it is set with delta Returns the new value of the key, or None for any errors ''' try: delta = int(delta) if uwsgi.cache_exists(key): value = self.get(key) + delta else: value = delta self.set(key, value) return value except Exception as err: debug_error(err) return None
def get_plugin_paths(rigor_config): """Processes the paths in rigor_config.plugin_paths and makes them absolute. """ # find the core plugins directory plugin_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../plugins')) if not os.path.exists(plugin_root): plugin_root = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../plugins')) if not os.path.exists(plugin_root): debug_error('ERROR: plugin root not found at {}'.format(plugin_root)) return [] # parse and absolutify the paths in the config file # TODO: allow paths outside the core plugins directory plugin_paths = rigor_config.get('webapp', 'plugin_paths').rstrip(" ,\t") plugin_paths = [path.strip() for path in plugin_paths.split(',')] return [os.path.join(plugin_root, plugin_path) for plugin_path in plugin_paths]
def get_plugin_paths(rigor_config): """Processes the paths in rigor_config.plugin_paths and makes them absolute. """ # find the core plugins directory plugin_root = os.path.abspath( os.path.join(os.path.dirname(__file__), '../../plugins')) if not os.path.exists(plugin_root): plugin_root = os.path.abspath( os.path.join(os.path.dirname(__file__), '../../../../plugins')) if not os.path.exists(plugin_root): debug_error('ERROR: plugin root not found at {}'.format(plugin_root)) return [] # parse and absolutify the paths in the config file # TODO: allow paths outside the core plugins directory plugin_paths = rigor_config.get('webapp', 'plugin_paths').rstrip(" ,\t") plugin_paths = [path.strip() for path in plugin_paths.split(',')] return [ os.path.join(plugin_root, plugin_path) for plugin_path in plugin_paths ]
def rebuild_plugin_static_symlinks(plugin_paths): """Delete and recreate symlinks from the main static/ directory to plugins' static directories. """ # find share/static/plugins here = os.path.dirname(os.path.abspath(__file__)) static_plugins = os.path.abspath(os.path.join(here, '../share/static/plugins')) if not os.path.exists(static_plugins): debug_error("can't find main static plugins directory (expected at {})".format(static_plugins)) sys.exit(1) debug_detail(' {}'.format(static_plugins)) # remove existing links for rel_fn in os.listdir(static_plugins): abs_fn = os.path.join(static_plugins, rel_fn) if os.path.islink(abs_fn): os.unlink(abs_fn) # add fresh links for plugin_path in plugin_paths: plugin_static = os.path.join(plugin_path, 'static') plugin_name = os.path.basename(plugin_path) if os.path.exists(plugin_static): debug_detail(' {} -> {}'.format(plugin_name, plugin_static)) os.symlink(plugin_static, os.path.join(static_plugins, plugin_name))
def get_app(rigor_config): """Builds and returns a Flask app object which gets its configuration from the given config file. rigor_config is an instance of rigor.config.RigorDefaultConfiguration(path_to_config_file) """ #================================================================================ # FLASK HELPERS def check_auth(username, password): """This function is called to check if a username / password combination is valid. """ return username == rigor_config.get('webapp', 'http_auth_user') and password == rigor_config.get('webapp', 'http_auth_password') def authenticate(): """Sends a 401 response that enables basic auth""" return Response( 'Could not verify your access level for that URL.\n' 'You have to login with proper credentials', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'} ) def simulate_slow(fn): @functools.wraps(fn) def decorated(*args, **kwargs): latency = int(rigor_config.get('webapp', 'fake_latency')) if latency > 0: debug_detail('adding {} seconds of fake delay'.format(latency)) time.sleep(latency) return fn(*args, **kwargs) return decorated #================================================================================ # FLASK SETUP share_folder = None share_folder_locations = ['../../share', '../../../../share', '../share'] for path in share_folder_locations: path = os.path.abspath(os.path.join(os.path.dirname(__file__), path)) if os.path.exists(path): share_folder = os.path.abspath(path) break if share_folder is None: debug_error('ERROR: Share folder not found') raise IOError('Share folder not found') else: debug_detail('found share folder at {}'.format(share_folder)) app = Flask( __name__, static_folder=share_folder + '/static', template_folder=share_folder + '/templates', ) app.config['SECRET_KEY'] = rigor_config.get('webapp', 'flask_secret_key') #================================================================================ # PLUGINS debug_detail('loading backend') backend = rigorwebapp.backend.Backend(rigor_config) plugin_instances = rigorwebapp.plugin.load_plugin_instances(rigor_config, backend) debug_detail('loaded plugin classes:') for plugin_instance in plugin_instances: debug_detail(' {}'.format(plugin_instance.__class__.__name__)) #================================================================================ # ROUTING # let plugins add routes debug_detail('adding plugin routes') for plugin_instance in plugin_instances: plugin_instance.add_routes(app, backend, plugin_instances) @app.before_request # see http://stackoverflow.com/a/13451233/856925 for more thoughts on this def require_auth_everywhere(): if rigor_config.getboolean('webapp', 'use_http_auth'): auth = request.authorization if not auth or not check_auth(auth.username, auth.password): return authenticate() @app.route('/') def index_redirect(): initial_db = rigor_config.get('webapp', 'initial_db') initial_db = backend._encode_name_for_db(initial_db) return redirect('/db/{}/perceptsearch'.format(initial_db)) app.config['PROPAGATE_EXCEPTIONS'] = True debug_detail('ready') # set up logging for sqlalchemy from logging import getLogger from logging import StreamHandler getLogger('sqlalchemy').addHandler(StreamHandler()) return app
def get_app(rigor_config): """Builds and returns a Flask app object which gets its configuration from the given config file. rigor_config is an instance of rigor.config.RigorDefaultConfiguration(path_to_config_file) """ #================================================================================ # FLASK HELPERS def check_auth(username, password): """This function is called to check if a username / password combination is valid. """ return username == rigor_config.get( 'webapp', 'http_auth_user') and password == rigor_config.get( 'webapp', 'http_auth_password') def authenticate(): """Sends a 401 response that enables basic auth""" return Response( 'Could not verify your access level for that URL.\n' 'You have to login with proper credentials', 401, {'WWW-Authenticate': 'Basic realm="Login Required"'}) def simulate_slow(fn): @functools.wraps(fn) def decorated(*args, **kwargs): latency = int(rigor_config.get('webapp', 'fake_latency')) if latency > 0: debug_detail('adding {} seconds of fake delay'.format(latency)) time.sleep(latency) return fn(*args, **kwargs) return decorated #================================================================================ # FLASK SETUP share_folder = None share_folder_locations = ['../../share', '../../../../share', '../share'] for path in share_folder_locations: path = os.path.abspath(os.path.join(os.path.dirname(__file__), path)) if os.path.exists(path): share_folder = os.path.abspath(path) break if share_folder is None: debug_error('ERROR: Share folder not found') raise IOError('Share folder not found') else: debug_detail('found share folder at {}'.format(share_folder)) app = Flask( __name__, static_folder=share_folder + '/static', template_folder=share_folder + '/templates', ) app.config['SECRET_KEY'] = rigor_config.get('webapp', 'flask_secret_key') #================================================================================ # PLUGINS debug_detail('loading backend') backend = rigorwebapp.backend.Backend(rigor_config) plugin_instances = rigorwebapp.plugin.load_plugin_instances( rigor_config, backend) debug_detail('loaded plugin classes:') for plugin_instance in plugin_instances: debug_detail(' {}'.format(plugin_instance.__class__.__name__)) #================================================================================ # ROUTING # let plugins add routes debug_detail('adding plugin routes') for plugin_instance in plugin_instances: plugin_instance.add_routes(app, backend, plugin_instances) @app.before_request # see http://stackoverflow.com/a/13451233/856925 for more thoughts on this def require_auth_everywhere(): if rigor_config.getboolean('webapp', 'use_http_auth'): auth = request.authorization if not auth or not check_auth(auth.username, auth.password): return authenticate() @app.route('/') def index_redirect(): initial_db = rigor_config.get('webapp', 'initial_db') initial_db = backend._encode_name_for_db(initial_db) return redirect('/db/{}/perceptsearch'.format(initial_db)) app.config['PROPAGATE_EXCEPTIONS'] = True debug_detail('ready') # set up logging for sqlalchemy from logging import getLogger from logging import StreamHandler getLogger('sqlalchemy').addHandler(StreamHandler()) return app