<commit_before># -*- coding: utf-8 -*-
"""
Settings module for atxcf bot to keep state and cache market data.
"""

import os
import os.path
import json
import filelock
import time
import threading
import copy

from utils import (
    append_csv_row
)

class SettingsError(RuntimeError):
    pass


_js_settings = {}
_js_settings_ts = time.time()
_js_settings_lock = threading.RLock()
_prevent_write = False

def _get_settings_filename():
    varname = "ATXCF_SETTINGS"
    if varname in os.environ:
        return os.environ[varname]
    else:
        return "atxcf.json"


def _get_settings_lockfile_name():
    return _get_settings_filename() + ".lock"

    
_js_filelock = filelock.FileLock(_get_settings_lockfile_name())


def get_default_options():
    """
    Default atxcf bot runtime options.
    """
    return {
        # try to keep the settings file synced every 5 minutes
        "settings_update_interval": 60*5
    }


_settings_log = None
def init_settings():
    """
    Initializes settings dict with default values.
    """
    global _js_settings
    global _js_settings_ts
    global _js_settings_lock
    with _js_settings_lock:
        _js_settings = {
            "program_url": "https://github.com/transfix/atxcf",
            "version": "0.1",
            "last_updated": time.time(),
            "options": get_default_options(),
            "credentials": {}
        }
        _js_settings_ts = time.time()


def _check_options_section(settings):
    """
    Raises an exception if the options section is missing.
    """
    if not "options" in settings:
        raise SettingsError("Missing options section in %s" % _get_settings_filename())
    

def _get_settings():
    """
    Returns the current settings dict. If there isn't one, then 
    it loads it from disk.
    """
    global _js_settings
    global _js_settings_lock
    global _js_filelock
    ret_settings = None
    doInit = False
    with _js_settings_lock:
        if not _js_settings:
            fn = _get_settings_filename()
            # if a settings file doesn't exist, just init with defaults
            if not os.path.isfile(fn):
                doInit = True
            else:
                with _js_filelock:
                    try:
                        _js_settings = json.load(open(fn))
                    except IOError as e:
                        raise SettingsError("Error loading %s: %s" % (fn, e.message))
    if doInit:
        init_settings()
    return _js_settings


def get_settings():
    """
    Deprecated
    """
    return _get_settings()


def get_setting(*args, **kwargs):
    """
    Use this to get settings in a thread safe way.
    Use the keyword argument "default" to assign a default value
    if a setting with the specified name isn't present.
    """
    global _js_settings_lock
    default = None
    if "default" in kwargs:
        default = kwargs["default"]
    with _js_settings_lock:
        sett = _get_settings()
        for arg in args[:-1]:
            if not arg in sett:
                sett[arg] = {}
            next_sett = sett[arg]
            sett = next_sett
        if not args[-1] in sett:
            if not default:
                raise SettingsError("Missing setting value and no default specified")
            sett[args[-1]] = default
            _js_settings_ts = time.time()
            append_csv_row(get_settings_log(), [_js_settings_ts] + list(args) + [default])
        return copy.deepcopy(sett[args[-1]])
    

def get_settings_log():<commit_msg>Checking if default is properly equivalent to None<commit_after># -*- coding: utf-8 -*-
"""
Settings module for atxcf bot to keep state and cache market data.
"""

import os
import os.path
import json
import filelock
import time
import threading
import copy

from utils import (
    append_csv_row
)

class SettingsError(RuntimeError):
    pass


_js_settings = {}
_js_settings_ts = time.time()
_js_settings_lock = threading.RLock()
_prevent_write = False

def _get_settings_filename():
    varname = "ATXCF_SETTINGS"
    if varname in os.environ:
        return os.environ[varname]
    else:
        return "atxcf.json"


def _get_settings_lockfile_name():
    return _get_settings_filename() + ".lock"

    
_js_filelock = filelock.FileLock(_get_settings_lockfile_name())


def get_default_options():
    """
    Default atxcf bot runtime options.
    """
    return {
        # try to keep the settings file synced every 5 minutes
        "settings_update_interval": 60*5
    }


_settings_log = None
def init_settings():
    """
    Initializes settings dict with default values.
    """
    global _js_settings
    global _js_settings_ts
    global _js_settings_lock
    with _js_settings_lock:
        _js_settings = {
            "program_url": "https://github.com/transfix/atxcf",
            "version": "0.1",
            "last_updated": time.time(),
            "options": get_default_options(),
            "credentials": {}
        }
        _js_settings_ts = time.time()


def _check_options_section(settings):
    """
    Raises an exception if the options section is missing.
    """
    if not "options" in settings:
        raise SettingsError("Missing options section in %s" % _get_settings_filename())
    

def _get_settings():
    """
    Returns the current settings dict. If there isn't one, then 
    it loads it from disk.
    """
    global _js_settings
    global _js_settings_lock
    global _js_filelock
    ret_settings = None
    doInit = False
    with _js_settings_lock:
        if not _js_settings:
            fn = _get_settings_filename()
            # if a settings file doesn't exist, just init with defaults
            if not os.path.isfile(fn):
                doInit = True
            else:
                with _js_filelock:
                    try:
                        _js_settings = json.load(open(fn))
                    except IOError as e:
                        raise SettingsError("Error loading %s: %s" % (fn, e.message))
    if doInit:
        init_settings()
    return _js_settings


def get_settings():
    """
    Deprecated
    """
    return _get_settings()


def get_setting(*args, **kwargs):
    """
    Use this to get settings in a thread safe way.
    Use the keyword argument "default" to assign a default value
    if a setting with the specified name isn't present.
    """
    global _js_settings_lock
    default = None
    if "default" in kwargs:
        default = kwargs["default"]
    with _js_settings_lock:
        sett = _get_settings()
        for arg in args[:-1]:
            if not arg in sett:
                sett[arg] = {}
            next_sett = sett[arg]
            sett = next_sett
        if not args[-1] in sett:
            if default == None:
                raise SettingsError("Missing setting value and no default specified")
            sett[args[-1]] = default
            _js_settings_ts = time.time()
            append_csv_row(get_settings_log(), [_js_settings_ts] + list(args) + [default])
        return copy.deepcopy(sett[args[-1]])
    

def get_settings_log():
{'fraction_non_alphanumeric': 0.08905171199098211, 'fraction_numerical': 0.0030999013667746935, 'mean_word_length': 2.269461077844311, 'pattern_counts': {'":': 12, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, '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': '4579179', 'n_tokens_mistral': 2090, 'n_tokens_neox': 2047, 'n_words': 606}