<commit_before>#!/usr/bin/python

import argparse
from flask import Flask
from flask import redirect
from flask import request
from flask import session
from functools import wraps
import logging
import os
import re
import signal

import db_controller as dbc
import rz_api
import rz_api_rest
import rz_feedback
from rz_kernel import RZ_Kernel
from rz_mesh import init_ws_interface
from rz_req_handling import make_response__http__empty
import rz_server_ctrl
import rz_user
import rz_blob
from rz_user_db import User_DB


class Config(object):
    """
    rhizi-server configuration

    TODO: config option documentation
    
        listen_address
        listen_port
        log_level: upper/lower case log level as specified by the logging module
        neo4j_url
        root_path: root path from which the server will server content
        user_db_path: absolute path to a Berkeley DB file used to store user accounts & password hash values
    """

    @staticmethod
    def init_from_file(file_path):

        if False == os.path.exists(file_path):
            raise Exception('config file not found: ' + file_path)

        # apply defaults
        cfg = {}
        cfg['access_control'] = True
        cfg['config_dir'] = os.path.abspath(os.path.dirname(file_path))  # bypass prop restriction
        cfg['development_mode'] = False
        cfg['listen_address'] = '127.0.0.1'
        cfg['listen_port'] = 8080
        cfg['log_level'] = 'INFO'
        cfg['root_path'] = os.getcwd()
        cfg['static_url_path'] = '/static'
        cfg['user_db_path'] = os.path.join(cfg['config_dir'], 'user_db.db')

        # client configuration
        cfg['optimized_main'] = False

        # Mail settings
        cfg['mail_hostname'] = 'localhost'
        cfg['mail_port'] = 25

        # User feedback settings
        cfg['feedback_recipient'] = '<EMAIL>@localhost'

        # Flask keys
        cfg['SECRET_KEY'] = ''

        # Rhizi
        cfg['rzdoc__welcome_doc__name'] = 'Welcome Rhizi'
        cfg['rzdoc__name__max_length'] = 256

        with open(file_path, 'r') as f:
            for line in f:
                if re.match('(^#)|(\s+$)', line):
                    continue

                kv_arr = line.split('=')
                if 2 != len(kv_arr):
                    raise Exception('failed to parse config line: ' + line)

                k, v = map(str.strip, kv_arr)

                if None != cfg.get(k):
                    # apply type conversion based on default value type
                    type_f = type(cfg[k])
                    if bool == type_f:
                        v = v in ("True", "true")  # workaround bool('false') = True
                    else:
                        v = type_f(v)

                # [!] we can't use k.lower() as we are loading Flask configuration
                # keys which are expected to be capitalized
                cfg[k] = v

        ret = Config()
        ret.__dict__ = cfg  # allows setting of @property attributes

        # validate config
        if False == os.path.isabs(ret.root_path):
            ret.root_path = os.path.abspath(ret.root_path)

        # authentication keys - see issue #419<commit_msg>rz_server: config: allow None values<commit_after>#!/usr/bin/python

import argparse
from flask import Flask
from flask import redirect
from flask import request
from flask import session
from functools import wraps
import logging
import os
import re
import signal

import db_controller as dbc
import rz_api
import rz_api_rest
import rz_feedback
from rz_kernel import RZ_Kernel
from rz_mesh import init_ws_interface
from rz_req_handling import make_response__http__empty
import rz_server_ctrl
import rz_user
import rz_blob
from rz_user_db import User_DB


class Config(object):
    """
    rhizi-server configuration

    TODO: config option documentation
    
        listen_address
        listen_port
        log_level: upper/lower case log level as specified by the logging module
        neo4j_url
        root_path: root path from which the server will server content
        user_db_path: absolute path to a Berkeley DB file used to store user accounts & password hash values
    """

    @staticmethod
    def init_from_file(file_path):

        if False == os.path.exists(file_path):
            raise Exception('config file not found: ' + file_path)

        # apply defaults
        cfg = {}
        cfg['access_control'] = True
        cfg['config_dir'] = os.path.abspath(os.path.dirname(file_path))  # bypass prop restriction
        cfg['development_mode'] = False
        cfg['listen_address'] = '127.0.0.1'
        cfg['listen_port'] = 8080
        cfg['log_level'] = 'INFO'
        cfg['root_path'] = os.getcwd()
        cfg['static_url_path'] = '/static'
        cfg['user_db_path'] = os.path.join(cfg['config_dir'], 'user_db.db')

        # client configuration
        cfg['optimized_main'] = False

        # Mail settings
        cfg['mail_hostname'] = 'localhost'
        cfg['mail_port'] = 25

        # User feedback settings
        cfg['feedback_recipient'] = 'feedback@localhost'

        # Flask keys
        cfg['SECRET_KEY'] = ''

        # Rhizi
        cfg['rzdoc__welcome_doc__name'] = 'Welcome Rhizi'
        cfg['rzdoc__name__max_length'] = 256

        with open(file_path, 'r') as f:
            for line in f:
                if re.match('(^#)|(\s+$)', line):
                    continue

                kv_arr = line.split('=')
                if len(kv_arr) != 2:
                    raise Exception('failed to parse config line: ' + line)

                k, v = map(str.strip, kv_arr)
                if '' == v: v = None

                if None != cfg.get(k):
                    # apply type conversion based on default value type
                    type_f = type(cfg[k])
                    if bool == type_f:
                        v = v in ("True", "true")  # workaround bool('false') = True
                    else:
                        v = type_f(v)

                # [!] we can't use k.lower() as we are loading Flask configuration
                # keys which are expected to be capitalized
                cfg[k] = v

        ret = Config()
        ret.__dict__ = cfg  # allows setting of @property attributes

        # validate config
        if False == os.path.isabs(ret.root_path):
            ret.root_path = os.path.abspath(ret.root_path)

        # authentication keys - see issue #419
{'fraction_non_alphanumeric': 0.09207874748101069, 'fraction_numerical': 0.0062005890559603165, 'mean_word_length': 2.0870813397129186, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2324513', 'n_tokens_mistral': 1925, 'n_tokens_neox': 1801, 'n_words': 543}