コード例 #1
0
ファイル: __init__.py プロジェクト: gramener/gramex
 def test_overlay(self):
     # +ChainConfig updates configs successively
     conf = ChainConfig()
     conf.a = AttrDict()
     conf.b = AttrDict()
     conf.a.x = 1
     conf.a.y = 2
     conf.b.x = 2
     eq_(+conf, {'x': 2, 'y': 2})
     conf.b.x = None
     eq_(+conf, {'y': 2})
コード例 #2
0
ファイル: __init__.py プロジェクト: venkataravi7/gramex
 def test_merge(self):
     # Config files are loaded and merged
     unlink(self.temp)
     conf = ChainConfig([
         ('a', PathConfig(self.a)),
         ('b', PathConfig(self.b))])
     eq_(+conf, PathConfig(self.final))
コード例 #3
0
ファイル: __init__.py プロジェクト: gramener/gramex
 def test_attrdict(self):
     # ChainConfig is an AttrDict
     conf = ChainConfig(a=AttrDict(), b=AttrDict())
     conf.a.x = 1
     conf.a.y = 2
     eq_(conf, {'a': {'x': 1, 'y': 2}, 'b': {}})
     conf.b.x = 3
     conf.b.y = 4
     eq_(conf, {'a': {'x': 1, 'y': 2}, 'b': {'x': 3, 'y': 4}})
コード例 #4
0
ファイル: __init__.py プロジェクト: gramener/gramex
    def test_chain_update(self):
        # Chained config files are changed on update
        # Set up a configuration with 2 files -- conf1.test and conf2.test.
        with self.conf1.open(mode='w', encoding='utf-8') as handle:
            yaml.dump({'url': {}}, handle)
        with self.conf2.open(mode='w', encoding='utf-8') as handle:
            yaml.dump({'url': {'a': 1}}, handle)

        conf = ChainConfig()
        conf.conf1 = PathConfig(self.conf1)
        conf.conf2 = PathConfig(self.conf2)
        eq_(+conf, {'url': {'a': 1}})

        # Change conf2.test and ensure that its original contents are replaced,
        # not just merged with previous value
        with self.conf2.open(mode='w', encoding='utf-8') as handle:
            yaml.dump({'url': {'b': 10}}, handle)
        eq_(+conf, {'url': {'b': 10}})
コード例 #5
0
ファイル: __init__.py プロジェクト: gramener/gramex
 def test_default(self):
     # Missing, empty or malformed config files return an empty AttrDict
     conf = ChainConfig([
         ('missing', PathConfig(self.missing)),
         ('error', PathConfig(self.error)),
         ('empty', PathConfig(self.empty)),
         ('string', PathConfig(self.string)),
     ])
     eq_(+conf, AttrDict())
コード例 #6
0
ファイル: __init__.py プロジェクト: gramener/gramex
    def test_import(self):
        # Check if config files are imported
        conf_imp = ChainConfig(conf=PathConfig(self.imp))
        conf_b = ChainConfig(conf=PathConfig(self.b))

        # When temp is missing, config matches b
        unlink(self.temp)
        eq_(+conf_imp, +conf_b)

        # Once temp file is created, it is automatically imported
        data = AttrDict(a=1, b=2)
        with self.temp.open('w') as out:
            yaml.dump(dict(data), out)
        result = +conf_b
        result.update(data)
        eq_(+conf_imp, result)

        # Once removed, it no longer used
        unlink(self.temp)
        eq_(+conf_imp, +conf_b)
コード例 #7
0
ファイル: __init__.py プロジェクト: gramener/gramex
    def test_update(self):
        # Config files are updated on change
        conf = ChainConfig(temp=PathConfig(self.temp))

        # When the file is missing, config is empty
        unlink(self.temp)
        eq_(+conf, {})

        # When the file is blank, config is empty
        with self.temp.open('w') as out:
            out.write('')
        eq_(+conf, {})

        # Once created, it is automatically reloaded
        data = AttrDict(a=1, b=2)
        with self.temp.open('w') as out:
            yaml.dump(dict(data), out)
        eq_(+conf, data)

        # Deleted file is detected
        self.temp.unlink()
        eq_(+conf, {})
コード例 #8
0
            exe_path = which(exe)
            if exe_path is not None:
                cmd = cmd.format(FILE=setup_file, EXE=exe_path)
                app_log.info('Running %s', cmd)
                _run_console(cmd, cwd=target)
                break
        else:
            app_log.warning('Skipping %s. No %s found', setup_file, exe)


app_dir = Path(variables.get('GRAMEXDATA')) / 'apps'
if not app_dir.exists():
    app_dir.mkdir(parents=True)

# Get app configuration by chaining apps.yaml in gramex + app_dir + command line
apps_config = ChainConfig()
apps_config['base'] = PathConfig(gramex.paths['source'] / 'apps.yaml')
user_conf_file = app_dir / 'apps.yaml'
apps_config['user'] = PathConfig(
    user_conf_file) if user_conf_file.exists() else AttrDict()

app_keys = {
    'url': 'URL / filename of a ZIP file to install',
    'cmd': 'Command used to install file',
    'dir': 'Sub-directory under "url" to run from (optional)',
    'contentdir':
    'Strip root directory with a single child (optional, default=True)',
    'target': 'Local directory where the app is installed',
    'installed': 'Additional installation information about the app',
    'run': 'Runtime keyword arguments for the app',
}
コード例 #9
0
import os
import sys
import json
import yaml
import logging
import logging.config
import tornado.ioloop
from pathlib import Path
from orderedattrdict import AttrDict
from gramex.config import ChainConfig, PathConfig, app_log, variables, setup_variables
from gramex.config import ioloop_running, prune_keys, setup_secrets

paths = AttrDict()  # Paths where configurations are stored
conf = AttrDict()  # Final merged configurations
config_layers = ChainConfig()  # Loads all configurations. init() updates it
appconfig = AttrDict()  # Final app configuration

paths['source'] = Path(
    __file__).absolute().parent  # Where gramex source code is
paths['base'] = Path('.')  # Where gramex is run from

callbacks = {}  # Services callbacks

# Populate __version__ from release.json
with (paths['source'] / 'release.json').open() as _release_file:
    release = json.load(_release_file, object_pairs_hook=AttrDict)
    __version__ = release.info.version

_sys_path = list(sys.path)  # Preserve original sys.path
コード例 #10
0
ファイル: __init__.py プロジェクト: gramener/gramex
    def test_variables(self):
        # Templates interpolate string variables
        # Create configuration with 2 layers and a subdirectory import
        conf = +ChainConfig(
            base=PathConfig(self.chain.base),
            child=PathConfig(self.chain.child),
        )
        # Custom variables are deleted after use
        ok_('variables' not in conf)
        for key in ['base', 'child', 'subdir']:
            # {.} maps to YAML file's directory
            eq_(conf['%s_DOT' % key], str(self.chain[key].parent))
            # $YAMLPATH maps to YAML file's directory
            eq_(conf['%s_YAMLPATH' % key], str(self.chain[key].parent))
            # $YAMLURL is the relative path to YAML file's directory
            eq_(conf['%s_YAMLURL' % key], conf['%s_YAMLURL_EXPECTED' % key])
            # Environment variables are present by default
            eq_(conf['%s_HOME' % key], os.environ.get('HOME', ''))
            # Non-existent variables map to ''
            eq_(conf['%s_NONEXISTENT' % key],
                os.environ.get('NONEXISTENT', ''))
            # Custom variables are applied
            eq_(conf['%s_THIS' % key], key)
            # Custom variables are inherited. Defaults do not override
            eq_(conf['%s_ROOT' % key], conf.base_ROOT)
            # Default variables are set
            eq_(conf['%s_DEFAULT' % key], key)
            # Functions run and override values
            eq_(conf['%s_FUNCTION' % key], key)
            # Default functions "underride" values
            eq_(conf['%s_DEFAULT_FUNCTION' % key], 'base')
            # Functions can use variables using gramex.config.variables
            eq_(conf['%s_FUNCTION_VAR' % key], conf.base_ROOT + key)
            # Derived variables
            eq_(conf['%s_DERIVED' % key], '%s/derived' % key)
            # $URLROOT is the frozen to base $YAMLURL
            eq_(conf['%s_YAMLURL_VAR' % key],
                conf['%s_YAMLURL_VAR_EXPECTED' % key])
            # $GRAMEXPATH is the gramex path
            gramex_path = os.path.dirname(inspect.getfile(gramex))
            eq_(conf['%s_GRAMEXPATH' % key], gramex_path)
            # $GRAMEXAPPS is the gramex apps path
            eq_(conf['%s_GRAMEXAPPS' % key], os.path.join(gramex_path, 'apps'))
            # $GRAMEXHOST is the socket.gethostname
            eq_(conf['%s_GRAMEXHOST' % key], socket.gethostname())
        # Imports do not override, but do setdefault
        eq_(conf['path'], str(self.chain['base'].parent))
        eq_(conf['subpath'], str(self.chain['subdir'].parent))

        # Check if variable types are preserved
        eq_(conf['numeric'], 1)
        eq_(conf['boolean'], True)
        eq_(conf['object'], {'x': 1})
        eq_(conf['list'], [1, 2])

        # Check if variables of different types are string substituted
        eq_(conf['numeric_subst'], '/1')
        eq_(conf['boolean_subst'], '/True')
        # Actually, conf['object_subst'] is "/AttrDict([('x', 1)])". Let's not test that.
        # eq_(conf['object_subst'], "/{'x': 1}")
        eq_(conf['list_subst'], '/[1, 2]')

        # Check condition variables
        for key, val in conf['conditions'].items():
            eq_('is-' + key, val)
コード例 #11
0
ファイル: gramextest.py プロジェクト: naveengattu/gramex
import os
import pytest
import re
import requests
import time
import gramex.cache
from fnmatch import fnmatch
from lxml.html import document_fromstring
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from six import string_types
from tornado.web import create_signed_value
from gramex.config import ChainConfig, PathConfig, objectpath, variables

# Get Gramex conf from current directory
gramex_conf = ChainConfig()
gramex_conf['source'] = PathConfig(os.path.join(variables['GRAMEXPATH'], 'gramex.yaml'))
gramex_conf['base'] = PathConfig('gramex.yaml')
secret = objectpath(+gramex_conf, 'app.settings.cookie_secret')
drivers = {}
default = object()


class ChromeConf(dict):
    def __init__(self, **conf):
        self['goog:chromeOptions'] = {'args': ['--no-sandbox']}
        for key, val in conf.items():
            getattr(self, key)(val)

    def headless(self, val):
        if val: