Use properties in config for pass-through compat vars
Strings are immutable, so when one variable changes the other will not, as such there is variance on config load between variables that should be the the value of another variable. To solve that I've moved the config into a class and made those values read-only properties to the loaded values. Closes: #137 #138
This commit is contained in:
parent
9fd2661405
commit
695dba98f9
|
@ -164,7 +164,7 @@ def error_handler(e):
|
||||||
|
|
||||||
def create_app(config=None):
|
def create_app(config=None):
|
||||||
app = Application(__name__)
|
app = Application(__name__)
|
||||||
app.config.from_object('realms.config')
|
app.config.from_object('realms.config.conf')
|
||||||
app.url_map.converters['regex'] = RegexConverter
|
app.url_map.converters['regex'] = RegexConverter
|
||||||
app.url_map.strict_slashes = False
|
app.url_map.strict_slashes = False
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ import pip
|
||||||
import time
|
import time
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
config = config.conf
|
||||||
|
|
||||||
# called to discover commands in modules
|
# called to discover commands in modules
|
||||||
app = create_app()
|
app = create_app()
|
||||||
|
|
||||||
|
|
|
@ -1,208 +1,218 @@
|
||||||
import os
|
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
from urlparse import urlparse
|
from urlparse import urlparse
|
||||||
|
|
||||||
from realms.lib.util import in_vagrant
|
from realms.lib.util import in_vagrant
|
||||||
|
|
||||||
|
|
||||||
def update(data):
|
class Config(object):
|
||||||
conf = read()
|
|
||||||
conf.update(data)
|
|
||||||
return save(data)
|
|
||||||
|
|
||||||
|
urlparse = urlparse
|
||||||
|
|
||||||
def read():
|
APP_PATH = os.path.abspath(os.path.dirname(__file__) + "/../..")
|
||||||
conf = dict()
|
USER_HOME = os.path.abspath(os.path.expanduser("~"))
|
||||||
|
|
||||||
for k, v in os.environ.items():
|
# Best to change to /var/run
|
||||||
if k.startswith('REALMS_'):
|
PIDFILE = "/tmp/realms-wiki.pid"
|
||||||
conf[k[7:]] = v
|
|
||||||
|
|
||||||
loc = get_path()
|
ENV = 'DEV'
|
||||||
|
|
||||||
if loc:
|
HOST = "0.0.0.0"
|
||||||
with open(loc) as f:
|
PORT = 5000
|
||||||
conf.update(json.load(f))
|
BASE_URL = 'http://localhost'
|
||||||
|
SITE_TITLE = "Realms"
|
||||||
|
|
||||||
for k in ['APP_PATH', 'USER_HOME']:
|
# https://pythonhosted.org/Flask-SQLAlchemy/config.html#connection-uri-format
|
||||||
if k in conf:
|
DB_URI = 'sqlite:////tmp/wiki.db'
|
||||||
del conf[k]
|
# DB_URI = 'mysql://scott:tiger@localhost/mydatabase'
|
||||||
|
# DB_URI = 'postgresql://scott:tiger@localhost/mydatabase'
|
||||||
|
# DB_URI = 'oracle://scott:tiger@127.0.0.1:1521/sidname'
|
||||||
|
# DB_URI = 'crate://'
|
||||||
|
|
||||||
return conf
|
# LDAP = {
|
||||||
|
# 'URI': '',
|
||||||
|
#
|
||||||
|
# # This BIND_DN/BIND_PASSWORD default to '', this is shown here for demonstrative purposes
|
||||||
|
# # The values '' perform an anonymous bind so we may use search/bind method
|
||||||
|
# 'BIND_DN': '',
|
||||||
|
# 'BIND_AUTH': '',
|
||||||
|
#
|
||||||
|
# # Adding the USER_SEARCH field tells the flask-ldap-login that we are using
|
||||||
|
# # the search/bind method
|
||||||
|
# 'USER_SEARCH': {'base': 'dc=example,dc=com', 'filter': 'uid=%(username)s'},
|
||||||
|
#
|
||||||
|
# # Map ldap keys into application specific keys
|
||||||
|
# 'KEY_MAP': {
|
||||||
|
# 'name': 'cn',
|
||||||
|
# 'company': 'o',
|
||||||
|
# 'location': 'l',
|
||||||
|
# 'email': 'mail',
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
|
# OAUTH = {
|
||||||
|
# 'twitter': {
|
||||||
|
# 'key': '',
|
||||||
|
# 'secret': ''
|
||||||
|
# },
|
||||||
|
# 'github': {
|
||||||
|
# 'key': '',
|
||||||
|
# 'secret': ''
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
def save(conf):
|
# Valid options: simple, redis, memcached
|
||||||
loc = get_path(check_write=True)
|
CACHE_TYPE = 'simple'
|
||||||
with open(loc, 'w') as f:
|
|
||||||
f.write(json.dumps(conf, sort_keys=True, indent=4, separators=(',', ': ')).strip() + '\n')
|
|
||||||
return loc
|
|
||||||
|
|
||||||
|
CACHE_REDIS_HOST = '127.0.0.1'
|
||||||
|
CACHE_REDIS_PORT = 6379
|
||||||
|
CACHE_REDIS_DB = '0'
|
||||||
|
|
||||||
def get_path(check_write=False):
|
CACHE_MEMCACHED_SERVERS = ['127.0.0.1:11211']
|
||||||
"""Find config path
|
|
||||||
"""
|
|
||||||
for loc in os.curdir, os.path.expanduser("~"), "/etc/realms-wiki":
|
|
||||||
if not loc:
|
|
||||||
continue
|
|
||||||
path = os.path.join(loc, "realms-wiki.json")
|
|
||||||
if os.path.isfile(path):
|
|
||||||
# file exists
|
|
||||||
if not check_write:
|
|
||||||
# Don't care if I can write
|
|
||||||
return path
|
|
||||||
|
|
||||||
if os.access(path, os.W_OK):
|
# Valid options: simple, elasticsearch, woosh
|
||||||
# Has write access, ok!
|
SEARCH_TYPE = 'simple'
|
||||||
return path
|
|
||||||
elif os.path.isdir(loc) and check_write:
|
|
||||||
# dir exists file doesn't
|
|
||||||
if os.access(loc, os.W_OK):
|
|
||||||
# can write file
|
|
||||||
return path
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
ELASTICSEARCH_URL = 'http://127.0.0.1:9200'
|
||||||
|
ELASTICSEARCH_FIELDS = ["name"]
|
||||||
|
|
||||||
APP_PATH = os.path.abspath(os.path.dirname(__file__) + "/../..")
|
WHOOSH_INDEX = '/tmp/whoosh'
|
||||||
USER_HOME = os.path.abspath(os.path.expanduser("~"))
|
WHOOSH_LANGUAGE = 'en'
|
||||||
|
|
||||||
# Best to change to /var/run
|
# Get ReCaptcha Keys for your domain here:
|
||||||
PIDFILE = "/tmp/realms-wiki.pid"
|
# https://www.google.com/recaptcha/admin#whyrecaptcha
|
||||||
|
RECAPTCHA_ENABLE = False
|
||||||
|
RECAPTCHA_USE_SSL = False
|
||||||
|
RECAPTCHA_PUBLIC_KEY = "6LfYbPkSAAAAAB4a2lG2Y_Yjik7MG9l4TDzyKUao"
|
||||||
|
RECAPTCHA_PRIVATE_KEY = "6LfYbPkSAAAAAG-KlkwjZ8JLWgwc9T0ytkN7lWRE"
|
||||||
|
RECAPTCHA_OPTIONS = {}
|
||||||
|
|
||||||
ENV = 'DEV'
|
SECRET_KEY = 'CHANGE_ME'
|
||||||
|
|
||||||
DEBUG = True
|
# Path on file system where wiki data will reside
|
||||||
ASSETS_DEBUG = True
|
WIKI_PATH = '/tmp/wiki'
|
||||||
SQLALCHEMY_ECHO = False
|
|
||||||
|
|
||||||
HOST = "0.0.0.0"
|
# Name of page that will act as home
|
||||||
PORT = 5000
|
WIKI_HOME = 'home'
|
||||||
BASE_URL = 'http://localhost'
|
|
||||||
SITE_TITLE = "Realms"
|
|
||||||
|
|
||||||
# https://pythonhosted.org/Flask-SQLAlchemy/config.html#connection-uri-format
|
AUTH_LOCAL_ENABLE = True
|
||||||
DB_URI = 'sqlite:////tmp/wiki.db'
|
ALLOW_ANON = True
|
||||||
# DB_URI = 'mysql://scott:tiger@localhost/mydatabase'
|
REGISTRATION_ENABLED = True
|
||||||
# DB_URI = 'postgresql://scott:tiger@localhost/mydatabase'
|
PRIVATE_WIKI = False
|
||||||
# DB_URI = 'oracle://scott:tiger@127.0.0.1:1521/sidname'
|
|
||||||
# DB_URI = 'crate://'
|
|
||||||
|
|
||||||
# LDAP = {
|
# None, firepad, and/or togetherjs
|
||||||
# 'URI': '',
|
COLLABORATION = 'togetherjs'
|
||||||
#
|
|
||||||
# # This BIND_DN/BIND_PASSWORD default to '', this is shown here for demonstrative purposes
|
|
||||||
# # The values '' perform an anonymous bind so we may use search/bind method
|
|
||||||
# 'BIND_DN': '',
|
|
||||||
# 'BIND_AUTH': '',
|
|
||||||
#
|
|
||||||
# # Adding the USER_SEARCH field tells the flask-ldap-login that we are using
|
|
||||||
# # the search/bind method
|
|
||||||
# 'USER_SEARCH': {'base': 'dc=example,dc=com', 'filter': 'uid=%(username)s'},
|
|
||||||
#
|
|
||||||
# # Map ldap keys into application specific keys
|
|
||||||
# 'KEY_MAP': {
|
|
||||||
# 'name': 'cn',
|
|
||||||
# 'company': 'o',
|
|
||||||
# 'location': 'l',
|
|
||||||
# 'email': 'mail',
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
|
|
||||||
# OAUTH = {
|
# Required for firepad
|
||||||
# 'twitter': {
|
FIREBASE_HOSTNAME = None
|
||||||
# 'key': '',
|
|
||||||
# 'secret': ''
|
|
||||||
# },
|
|
||||||
# 'github': {
|
|
||||||
# 'key': '',
|
|
||||||
# 'secret': ''
|
|
||||||
# }
|
|
||||||
# }
|
|
||||||
|
|
||||||
CACHE_TYPE = 'simple'
|
# Page names that can't be modified
|
||||||
|
WIKI_LOCKED_PAGES = []
|
||||||
|
|
||||||
# Redis
|
ROOT_ENDPOINT = 'wiki.page'
|
||||||
# CACHE_TYPE = 'redis'
|
|
||||||
CACHE_REDIS_HOST = '127.0.0.1'
|
|
||||||
CACHE_REDIS_PORT = 6379
|
|
||||||
CACHE_REDIS_DB = '0'
|
|
||||||
|
|
||||||
# Memcached
|
# Used by Flask-Login
|
||||||
# CACHE_TYPE = 'memcached'
|
@property
|
||||||
CACHE_MEMCACHED_SERVERS = ['127.0.0.1:11211']
|
def LOGIN_DISABLED(self):
|
||||||
|
return self.ALLOW_ANON
|
||||||
|
|
||||||
SEARCH_TYPE = 'simple' # simple is not good for large wikis
|
# Depreciated variable name
|
||||||
|
@property
|
||||||
|
def LOCKED(self):
|
||||||
|
return self.WIKI_LOCKED_PAGES[:]
|
||||||
|
|
||||||
# SEARCH_TYPE = 'elasticsearch'
|
@property
|
||||||
ELASTICSEARCH_URL = 'http://127.0.0.1:9200'
|
def SQLALCHEMY_DATABASE_URI(self):
|
||||||
ELASTICSEARCH_FIELDS = ["name"]
|
return self.DB_URI
|
||||||
|
|
||||||
# SEARCH_TYPE = 'whoosh'
|
@property
|
||||||
WHOOSH_INDEX = '/tmp/whoosh'
|
def _url(self):
|
||||||
WHOOSH_LANGUAGE = 'en'
|
return urlparse(self.BASE_URL)
|
||||||
|
|
||||||
# Get ReCaptcha Keys for your domain here:
|
@property
|
||||||
# https://www.google.com/recaptcha/admin#whyrecaptcha
|
def RELATIVE_PATH(self):
|
||||||
RECAPTCHA_ENABLE = False
|
return self._url.path
|
||||||
RECAPTCHA_USE_SSL = False
|
|
||||||
RECAPTCHA_PUBLIC_KEY = "6LfYbPkSAAAAAB4a2lG2Y_Yjik7MG9l4TDzyKUao"
|
|
||||||
RECAPTCHA_PRIVATE_KEY = "6LfYbPkSAAAAAG-KlkwjZ8JLWgwc9T0ytkN7lWRE"
|
|
||||||
RECAPTCHA_OPTIONS = {}
|
|
||||||
|
|
||||||
SECRET_KEY = 'CHANGE_ME'
|
|
||||||
|
|
||||||
# Path on file system where wiki data will reside
|
|
||||||
WIKI_PATH = '/tmp/wiki'
|
|
||||||
|
|
||||||
# Name of page that will act as home
|
|
||||||
WIKI_HOME = 'home'
|
|
||||||
|
|
||||||
AUTH_LOCAL_ENABLE = True
|
|
||||||
ALLOW_ANON = True
|
|
||||||
REGISTRATION_ENABLED = True
|
|
||||||
PRIVATE_WIKI = False
|
|
||||||
|
|
||||||
# None, firepad, and/or togetherjs
|
|
||||||
COLLABORATION = 'togetherjs'
|
|
||||||
|
|
||||||
# Required for firepad
|
|
||||||
FIREBASE_HOSTNAME = None
|
|
||||||
|
|
||||||
# Page names that can't be modified
|
|
||||||
WIKI_LOCKED_PAGES = []
|
|
||||||
|
|
||||||
ROOT_ENDPOINT = 'wiki.page'
|
|
||||||
|
|
||||||
# Used by Flask-Login
|
|
||||||
LOGIN_DISABLED = ALLOW_ANON
|
|
||||||
|
|
||||||
# Depreciated variable name
|
|
||||||
LOCKED = WIKI_LOCKED_PAGES[:]
|
|
||||||
|
|
||||||
if BASE_URL.endswith('/'):
|
|
||||||
BASE_URL = BASE_URL[:-1]
|
|
||||||
|
|
||||||
SQLALCHEMY_DATABASE_URI = DB_URI
|
|
||||||
|
|
||||||
_url = urlparse(BASE_URL)
|
|
||||||
RELATIVE_PATH = _url.path
|
|
||||||
|
|
||||||
if in_vagrant():
|
|
||||||
# sendfile doesn't work well with Virtualbox shared folders
|
|
||||||
USE_X_SENDFILE = False
|
USE_X_SENDFILE = False
|
||||||
|
|
||||||
if ENV != "DEV":
|
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
ASSETS_DEBUG = False
|
ASSETS_DEBUG = False
|
||||||
SQLALCHEMY_ECHO = False
|
SQLALCHEMY_ECHO = False
|
||||||
|
|
||||||
MODULES = ['wiki', 'search', 'auth']
|
MODULES = ['wiki', 'search', 'auth']
|
||||||
|
|
||||||
globals().update(read())
|
def __init__(self):
|
||||||
|
for k, v in self.read().iteritems():
|
||||||
|
setattr(self, k, v)
|
||||||
|
if hasattr(self, 'AUTH_LOCAL_ENABLE'):
|
||||||
|
self.MODULES.append('auth.local')
|
||||||
|
if hasattr(self, 'OAUTH'):
|
||||||
|
self.MODULES.append('auth.oauth')
|
||||||
|
if hasattr(self, 'LDAP'):
|
||||||
|
self.MODULES.append('auth.ldap')
|
||||||
|
if in_vagrant():
|
||||||
|
self.USE_X_SENDFILE = False
|
||||||
|
if self.ENV == "DEV":
|
||||||
|
self.DEBUG = True
|
||||||
|
self.ASSETS_DEBUG = True
|
||||||
|
self.SQLALCHEMY_ECHO = True
|
||||||
|
self.USE_X_SENDFILE = False
|
||||||
|
|
||||||
if globals().get('AUTH_LOCAL_ENABLE'):
|
def update(self, data):
|
||||||
MODULES.append('auth.local')
|
conf = self.read()
|
||||||
|
conf.update(data)
|
||||||
|
return self.save(data)
|
||||||
|
|
||||||
if globals().get('OAUTH'):
|
def read(self):
|
||||||
MODULES.append('auth.oauth')
|
conf = dict()
|
||||||
|
|
||||||
if globals().get('LDAP'):
|
for k, v in os.environ.items():
|
||||||
MODULES.append('auth.ldap')
|
if k.startswith('REALMS_'):
|
||||||
|
conf[k[7:]] = v
|
||||||
|
|
||||||
|
loc = self.get_path()
|
||||||
|
|
||||||
|
if loc:
|
||||||
|
with open(loc) as f:
|
||||||
|
conf.update(json.load(f))
|
||||||
|
|
||||||
|
if 'BASE_URL' in conf and conf['BASE_URL'].endswith('/'):
|
||||||
|
conf['BASE_URL'] = conf['BASE_URL'][:-1]
|
||||||
|
|
||||||
|
for k in ['APP_PATH', 'USER_HOME']:
|
||||||
|
if k in conf:
|
||||||
|
del conf[k]
|
||||||
|
|
||||||
|
return conf
|
||||||
|
|
||||||
|
def save(self, conf):
|
||||||
|
loc = self.get_path(check_write=True)
|
||||||
|
with open(loc, 'w') as f:
|
||||||
|
f.write(json.dumps(conf, sort_keys=True, indent=4, separators=(',', ': ')).strip() + '\n')
|
||||||
|
return loc
|
||||||
|
|
||||||
|
def get_path(self, check_write=False):
|
||||||
|
"""Find config path
|
||||||
|
"""
|
||||||
|
for loc in os.curdir, os.path.expanduser("~"), "/etc/realms-wiki":
|
||||||
|
if not loc:
|
||||||
|
continue
|
||||||
|
path = os.path.join(loc, "realms-wiki.json")
|
||||||
|
if os.path.isfile(path):
|
||||||
|
# file exists
|
||||||
|
if not check_write:
|
||||||
|
# Don't care if I can write
|
||||||
|
return path
|
||||||
|
|
||||||
|
if os.access(path, os.W_OK):
|
||||||
|
# Has write access, ok!
|
||||||
|
return path
|
||||||
|
elif os.path.isdir(loc) and check_write:
|
||||||
|
# dir exists file doesn't
|
||||||
|
if os.access(loc, os.W_OK):
|
||||||
|
# can write file
|
||||||
|
return path
|
||||||
|
return None
|
||||||
|
|
||||||
|
conf = Config()
|
||||||
|
|
|
@ -5,6 +5,8 @@ from flask_oauthlib.client import OAuth
|
||||||
from realms import config
|
from realms import config
|
||||||
from ..models import BaseUser
|
from ..models import BaseUser
|
||||||
|
|
||||||
|
config = config.conf
|
||||||
|
|
||||||
oauth = OAuth()
|
oauth = OAuth()
|
||||||
|
|
||||||
users = {}
|
users = {}
|
||||||
|
|
Loading…
Reference in a new issue