def __init__(self): QuickSettings.__init__(self) self.routes = ([ '/test1', '/test2', ]) self.var1 = 'foo' self.var2 = 'bar' self.level2.var1 = 'foo' self.level2.var2 = 'bar' self.level3.var1 = 'foo' self.level3.var2 = 'bar' self.level4.var1 = 'foo' self.level4.var2 = 'bar' self.level5.level1.var1 = 'foo' self.level5.level2.var1 = 'bar' self.level5.level2.var2 = 'baz' self.level5.level3.var1 = 'bob' # no more values can be added self.lock()
def __init__(self): QuickSettings.__init__(self) # name of the website/application self.name.full = 'full' self.name.short = 'short' # application modules from our application or supporting applications self.modules.users.enabled = True self.modules.users.var2 = 'not bar' self.modules.users.routes = [] self.modules.users.level2.var2 = 'not bar' self.modules.users.level3 = 'string value to merge' self.modules.users.level4 = (('var2', 'not bar'), ('var3', 'baz')) self.modules.users.level5.level1.var1.notlikely = 'foo' self.modules.users.level5.level2.var1 = 'not_bar' self.modules.apputil.enabled = True self.modules.inactivemod.enabled = False ####################################################################### # ROUTING ####################################################################### # default routes self.routing.routes = [1, 2] # route prefix self.routing.prefix = '' ####################################################################### # DATABASE ####################################################################### self.db.echo = False ####################################################################### # SESSIONS ####################################################################### # beaker session options # http://wiki.pylonshq.com/display/beaker/Configuration+Options self.beaker.type = 'dbm' self.beaker.data_dir = 'session_cache' ####################################################################### # TEMPLATE & VIEW ####################################################################### self.template.default = 'default.html' self.template.admin = 'admin.html' self.trap_view_exceptions = True ####################################################################### # LOGGING & DEBUG ####################################################################### # currently support 'debug' & 'info' self.logging.levels = () # no more values can be added self.lock()
def test_setdefault(self): main = QuickSettings() mylist = [] main.foo.bar.baz = mylist qs = QuickSettings() qs.one = 1 qs.foo.bar.baz = 2 qs.foo.bar.three = 3 main.setdefaults(qs) assert main.foo.bar.baz is mylist assert main.foo.bar.three == 3 assert main.one == 1
def test_update(self): qs = QuickSettings() qs.lock() assert 'foo' not in qs assert 'bar' not in qs assert 'baz' not in qs qs.update({'foo': 1}) assert qs.foo == 1 qs.update(bar=2) assert qs.bar == 2 qs.update([('baz', 3)]) assert qs.baz == 3
def test_email(self): es = QuickSettings() es.email.smtp.server = 'example.com' es.email.smtp.user_name = 'myself' es.email.smtp.password = '******' assert es.email.smtp.server == 'example.com' assert es.email.smtp.user_name == 'myself' assert es.email.smtp.password == 'pass'
def test_copy(self): qs = QuickSettings() mylist = [] qs.foo.bar.baz = mylist qs2 = copy.copy(qs) assert qs2.foo.bar.baz is mylist assert qs.foo.bar.baz is mylist assert qs.foo is not qs2.foo assert qs.foo.bar is not qs2.foo.bar
def test_get_dotted(self): qs = QuickSettings() qs.set_dotted('foo.bar.wow', 'baz') qs.lock() assert qs.get_dotted('foo.bar.wow') == 'baz' assert qs.get_dotted('foo.bar') == qs.foo.bar assert qs.get_dotted('foo') == qs.foo try: qs.get_dotted('foo.none') except AttributeError as e: if 'none' not in str(e): raise qs.unlock() assert isinstance(qs.get_dotted('foo.none'), QuickSettings)
def test_set_dotted(self): qs = QuickSettings() qs.set_dotted('foo.bar.wow', 'baz') qs.lock() assert qs.foo.bar.wow == 'baz' qs = QuickSettings() qs.set_dotted('foo', 'baz') qs.lock() assert qs.foo == 'baz' qs = QuickSettings() qs.set_dotted('', 'baz')
def test_expand_keys(self): qs = QuickSettings() qs.foo.bar.baz = 3 expanded = qs.expandkeys() assert expanded == {'foo.bar.baz': 3}
def __init__(self, app_settings): self.for_me = QuickSettings() self.for_app = QuickSettings() self.for_me.routes = [] self.app_settings = app_settings self.init()
def _set_data_item(self, item, value): if not isinstance(value, QuickSettings): raise TypeError('all values set on ModuleSettings must be a QuickSettings object') QuickSettings._set_data_item(self, item, value)
def __init__(self): QuickSettings.__init__(self) self.init()
def test_level1(self): es = QuickSettings() es.a = 1 assert es.a == 1
def test_pformat(self): qs = QuickSettings() qs.foo.bar.baz = 3 assert qs.pformat == 'foo.bar.baz = 3'
def test_level2(self): es = QuickSettings() es.a.a = 1 assert es.a.a == 1
def init(self): # supporting applications self.supporting_apps = [] # don't want this to be empty self.components = QuickSettings() ####################################################################### # ROUTING ####################################################################### self.routing.routes = [] # where will static files be found? This is prepended to most static # URLs. self.routing.static_prefix = 'static/' # the settings for the Werkzeug routing Map object: self.routing.map.default_subdomain = '' self.routing.map.charset = 'utf-8' self.routing.map.strict_slashes = True self.routing.map.redirect_defaults = True self.routing.map.converters = None ####################################################################### # DIRECTORIES required by PYSVMT ####################################################################### self.dirs.storage = path.abspath(self.get_storage_dir()) self.dirs.writeable = path.join(self.dirs.storage, 'writeable') self.dirs.static = path.join(self.dirs.storage, 'static') self.dirs.data = path.join(self.dirs.writeable, 'data') self.dirs.logs = path.join(self.dirs.writeable, 'logs') self.dirs.tmp = path.join(self.dirs.writeable, 'tmp') ####################################################################### # SESSIONS ####################################################################### # beaker session options # http://beaker.groovie.org/configuration.html self.beaker.enabled = True self.beaker.type = 'dbm' self.beaker.data_dir = path.join(self.dirs.tmp, 'session_cache') self.beaker.lock_dir = path.join(self.dirs.tmp, 'beaker_locks') self.beaker.auto_clear_sessions = True ####################################################################### # TEMPLATES ####################################################################### self.templating.default_engine = 'jinja' self.template.default = 'default.html' # a list of template extensions to escape; set to False to disable # autoescape self.jinja.autoescape = ('html', 'htm', 'xml') self.jinja.extensions = ['jinja2.ext.autoescape', 'jinja2.ext.with_'] ####################################################################### # SYSTEM VIEW ENDPOINTS ####################################################################### self.endpoint.sys_error = '' self.endpoint.sys_auth_error = '' self.endpoint.bad_request_error = '' ####################################################################### # EXCEPTION HANDLING ####################################################################### # an exception will always be logged using python logging # If bool(exception_handling) == False, only logging will occur # If bool(exception_handling) == True, it is expected to be a list # options for handling the exception. Options are: # - handle: will try to use a 500 error document. If that doesn't exist # then a generic 500 respose will be returned # - format: takes precedence over 'handle'. it formats the exception and # displays it as part of the response body. Not usually needed b/c # the debugger is better for development, but the benefit is that # you get more info about the request & environ in the output. # - email: an email will be sent using mail_programmers() whenever # an exception is encountered # example of all: # self.exception_handling = ['handle', 'format', 'email'] # DEV SERVER NOTE: the development server supresses exceptions and # converts them to 500 responses. If you really want the exception to # pass through, you can send --pass-through-errors to the serve # command. self.exception_handling = ['handle', 'email'] # handle HTTP exceptions? Its likely this should only be set to False # when testing to help pinpoint why a certain response code is being # returned self.http_exception_handling = True # These patterns are matched with fnmatch() against POST keys and HTTP cookie keys. If # the keys match, their values are replaced with '<remove>'. self.exception_context_filters = ['*password*', '*secret*', '*session.id*'] ####################################################################### # DEBUGGING ####################################################################### # only matters when exceptions are not handled above. Setting interactive = # to True will give a python command prompt in the stack trace # # ******* SECURITY ALERT ********** # setting interactive = True would allow ANYONE who has http access to the # server to run arbitrary code. ONLY use in an isolated development # environment. self.debugger.enabled = False self.debugger.interactive = False ####################################################################### # EMAIL ADDRESSES ####################################################################### # the 'from' address used by mail_admins() and mail_programmers() # defaults if not set self.emails.from_server = '' # the default 'from' address used if no from address is specified self.emails.from_default = '' # a default reply-to header if one is not specified self.emails.reply_to = '' # recipient defaults. Should be a list of email addresses # ('*****@*****.**', '*****@*****.**') # will always add theses cc's to every email sent self.emails.cc_always = None # default cc, but can be overriden self.emails.cc_defaults = None # will always add theses bcc's to every email sent self.emails.bcc_always = None # default bcc, but can be overriden self.emails.bcc_defaults = None # programmers who would get system level notifications (code # broke, exception notifications, etc.) self.emails.programmers = None # people who would get application level notifications (payment recieved, # action needed, etc.) self.emails.admins = None # a single or list of emails that will be used to override every email sent # by the system. Useful for debugging. Original recipient information # will be added to the body of the email self.emails.override = None ####################################################################### # EMAIL SETTINGS ####################################################################### # used by mail_admins() and mail_programmers() self.email.subject_prefix = '' # Should we actually send email out to a SMTP server? Setting this to # False can be useful when doing testing. self.email.is_live = True ####################################################################### # SMTP SETTINGS ####################################################################### self.smtp.host = 'localhost' self.smtp.port = 25 self.smtp.user = '' self.smtp.password = '' self.smtp.use_tls = False ####################################################################### # OTHER DEFAULTS ####################################################################### self.default.charset = 'utf-8' self.default.file_mode = 0o640 self.default.dir_mode = 0o750 ####################################################################### # ERROR DOCUMENTS ####################################################################### # you can set endpoints here that will be used if an error response # is detected to try and give the user a more consistent experience # self.error_docs[404] = 'errorsmod:NotFound' self.error_docs ####################################################################### # TESTING ####################################################################### # an application can define functions to be called after the app # is initialized but before any test inspection is done or tests # are ran. The import strings given are relative to the application # stack. Some examples: # self.testing.init_callables = ( # 'testing.setup_db', # calls setup_db function in myapp.testing # 'testing:Setup.doit', # calls doit class method of Setup in myapp.testing # ) self.testing.init_callables = None ####################################################################### # Log Files ###################################################################### # a fast cutoff switch, if enabled, you still have to enable errors or # application below. It DOES NOT affect the null_handler setting. self.logs.enabled = True # logs will be logged using RotatingFileHandler # maximum log file size is 50MB self.logs.max_bytes = 1024 * 1024 * 50 # maximum number of log files to keep around self.logs.backup_count = 10 # will log all WARN and above logs to errors.log in the logs directory self.logs.errors.enabled = True # will log all application logs (level 25) to application.log. This will # also setup the logging object so you can use log.application(). The # application log level is 25, which is greater than INFO but less than # WARNING. self.logs.application.enabled = True # will log INFO messages to email.log with information about each email # that gets sent out. self.logs.email.enabled = True # if you don't want application or error logging and don't setup your # own, then you may see error messages on stdout like "No handlers could # be found for logger ...". Enable the null_handler to get rid of # those messages. But, you should *really* enable logging of some kind. self.logs.null_handler.enabled = False # log http requests. You must put HttpRequestLogger middleware # in your WSGI stack, preferrably as the last application so that its # the first middleware in the stack self.logs.http_requests.enabled = False self.logs.http_requests.filters.path_info = None self.logs.http_requests.filters.request_method = None ####################################################################### # Static Files ###################################################################### # should we use Werkzeug's SharedData middleware for serving static # files? Only applies when using middleware.full_wsgi_stack() or # middleware.static_files() self.static_files.enabled = True # should static files be served from the static directory (e.g. after # they are copied there) or from the application and component source # directories? Possible values are: "static" and "source". "source" # is slower and should be used primarily for development environments # when static files are changing often and copying to the static # directory after each change is a hassle. self.static_files.location = 'static' ####################################################################### # Automatic Actions ###################################################################### # when using @asviews, the view modules need to be loaded after the # app is initialized so that the routes get setup properly self.auto_load_views = False # should we copy static files every time an app is loaded? Useful # for dev environments. self.auto_copy_static.enabled = False self.auto_copy_static.delete_existing = True # should we automatically create the writeable directories: data, logs, # tmp self.auto_create_writeable_dirs = True # should we load utils.abort as a builtin? Intended for development # enviornments only. If true, will add abort to Python's builtin # namespace as 'dabort'. The 'd' is for development. self.auto_abort_as_builtin = False