-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig.py
182 lines (151 loc) · 6.77 KB
/
config.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
from os import path, environ
import os
from dotenv import load_dotenv
## Init the logging object.
import logging
from datetime import datetime, timedelta
import sys
# Courtesy of: https://stackoverflow.com/questions/13733552/logger-configuration-to-log-to-file-and-print-to-stdout
class LogFormatter(logging.Formatter):
COLOR_CODES = {
logging.CRITICAL: "\033[1;35m", # bright/bold magenta
logging.ERROR: "\033[1;31m", # bright/bold red
logging.WARNING: "\033[1;33m", # bright/bold yellow
logging.INFO: "\033[0;37m", # white / light gray
logging.DEBUG: "\033[1;30m" # bright/bold black / dark gray
}
RESET_CODE = "\033[0m"
def __init__(self, color, *args, **kwargs):
super(LogFormatter, self).__init__(*args, **kwargs)
self.color = color
def format(self, record, *args, **kwargs):
if (self.color is True and record.levelno in self.COLOR_CODES):
record.color_on = self.COLOR_CODES[record.levelno]
record.color_off = self.RESET_CODE
else:
record.color_on = ""
record.color_off = ""
return super(LogFormatter, self).format(record, *args, **kwargs)
# Courtesy of: https://stackoverflow.com/questions/13733552/logger-configuration-to-log-to-file-and-print-to-stdout
def setup_logging(console_log_output, console_log_level, console_log_color, logfile_file, logfile_log_level, logfile_log_color, log_line_template):
# Create logger
# For simplicity, we use the root logger, i.e. call 'logging.getLogger()'
# without name argument. This way we can simply use module methods for
# for logging throughout the script. An alternative would be exporting
# the logger, i.e. 'global logger; logger = logging.getLogger("<name>")'
logger = logging.getLogger()
# Set global log level to 'debug' (required for handler levels to work)
logger.setLevel(logging.DEBUG)
# Create console handler
console_log_output = console_log_output.lower()
if (console_log_output == "stdout"):
console_log_output = sys.stdout
elif (console_log_output == "stderr"):
console_log_output = sys.stderr
else:
print("Failed to set console output: invalid output: '%s'" % console_log_output)
return False
console_handler = logging.StreamHandler(console_log_output)
# Set console log level
try:
console_handler.setLevel(console_log_level.upper()) # only accepts uppercase level names
except:
print("Failed to set console log level: invalid level: '%s'" % console_log_level)
return False
# Create and set formatter, add console handler to logger
console_formatter = LogFormatter(fmt=log_line_template, color=console_log_color)
console_handler.setFormatter(console_formatter)
logger.addHandler(console_handler)
# Create log file handler
try:
# Check ../logs folder.
if not path.isdir('../logs/'):
print('Successfully set up logs folder.')
os.mkdir('../logs/')
logfile_handler = logging.FileHandler(logfile_file)
except Exception as exception:
print("Failed to set up log file: %s" % str(exception))
return False
# Set log file log level
try:
logfile_handler.setLevel(logfile_log_level.upper()) # only accepts uppercase level names
except Exception as e:
print("Failed to set log file log level: invalid level: '%s'" % logfile_log_level, e)
return False
# Create and set formatter, add log file handler to logger
logfile_formatter = LogFormatter(fmt=log_line_template, color=logfile_log_color)
logfile_handler.setFormatter(logfile_formatter)
logger.addHandler(logfile_handler)
# Success
return True
# Courtesy of: https://stackoverflow.com/questions/13733552/logger-configuration-to-log-to-file-and-print-to-stdout
setup_logging(console_log_output="stdout", console_log_level="debug", console_log_color=True,
logfile_file='../logs/{:%Y-%m-%d}.log'.format(datetime.now()), logfile_log_level="debug", logfile_log_color=False,
log_line_template="%(color_on)s[%(asctime)s] [%(threadName)s] [%(levelname)-8s] %(message)s%(color_off)s")
# Load the .env file from this directory.
load_dotenv(path.join(path.dirname(__file__), '.env'))
def load_secret_key(PATH: str) -> str:
'''
Loads the secret key from the path specified.
NOTE: This file should have read-only access.
'''
try:
f = open(PATH, 'rb')
except (OSError, IOError, FileNotFoundError) as e:
raise e
with f:
return f.readline().decode('utf-8')
def load_email_password(PATH: str) -> str:
'''
Loads the email password from the path specified.
NOTE: This file should have read-only access.
'''
try:
f = open(PATH, 'rb')
except (OSError, IOError, FileNotFoundError) as e:
raise e
with f:
return f.readline().decode('utf-8')
class Config():
'''
Base Config object, which sets the secret key and email password.
'''
# Get the secret key, reporting any errors.
try:
SECRET_KEY_PATH = environ.get('SECRET_KEY_PATH')
SECRET_KEY = load_secret_key(SECRET_KEY_PATH)
except (OSError, IOError, FileNotFoundError) as e:
logging.critical(f'Unable to load key file from location: {SECRET_KEY_PATH}')
print('Unable to load key file. Please check the location specified in the .env file and that the file has read access.')
raise SystemExit()
# Get the email password, reporting any errors.
try:
EMAIL_PASS_PATH = environ.get('EMAIL_PASSWORD_PATH')
EMAIL_PASSWORD = load_email_password(EMAIL_PASS_PATH)
except (OSError, IOError, FileNotFoundError) as e:
logging.critical(f'Unable to load email password file from location: {EMAIL_PASS_PATH}')
print('Unable to load email password file. Please check the location specified in the .env file and that the file has read access.')
raise SystemExit()
EMAIL_USERNAME = environ.get('EMAIL_USERNAME')
STATIC_FOLDER = 'static'
TEMPLATES_FOLDER = 'templates'
SESSION_TYPE = 'filesystem'
PERMANENT_SESSION_LIFETIME = timedelta(hours=5)
SESSION_FILE_DIR= '../cookies'
SQLALCHEMY_TRACK_MODIFICATIONS = False
class ProdConfig(Config):
'''
Production config class. Sets the appropriate Debugging and Testing settings.
'''
ENV = 'production'
DEBUG = False
TESTING = False
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + environ.get('PROD_DATABASE_PATH')
class DevConfig(Config):
'''
Development config class. Sets the appropriate Debugging and Testing settings.
'''
ENV = 'development'
DEBUG = True
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + environ.get('DEV_DATABASE_PATH')