forked from QiCuiHub/discord-audio-pipe
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig.py
201 lines (172 loc) · 5.3 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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
import configparser
import asyncio
from os.path import exists
import zoneinfo
import datetime
import logging
# configparser.ConfigParser config
config = None
# asyncio.Task save_task
save_task = None
# str file_name
file_name = ""
# set[str] valid_time_zones
valid_time_zones = None
# params: str cfg_file_name
# return boolean
def setup_config(cfg_file_name):
global valid_time_zones
valid_time_zones = zoneinfo.available_timezones()
global file_name
file_name = cfg_file_name
# str use_file_name
use_file_name = file_name
# declare config for use within the function (Python, scope is a thing, bruh)
global config
config = configparser.ConfigParser()
# if our config file doesn't already exist, load the default
# bool use_default
use_default = not exists(cfg_file_name)
if use_default:
use_file_name = cfg_file_name + ".default"
config.read(use_file_name)
if config.sections == []:
logging.error("{} is empty! Cannot load!".format(use_file_name))
return False
else:
logging.info("{} successfully loaded".format(use_file_name))
return True
if use_default:
# write the defaults out to the regular cfg file
try_save()
# params: str section, str key
# return str
def get_config(section, key):
if config is not None:
return config[section][key]
else:
raise Exception()
# alias for readability's sake
get_config_string = get_config
# params: str section, str key
# return float
def get_config_float(section, key):
return float(get_config(section, key))
# params: str section, str key
# return int
def get_config_int(section, key):
return int(get_config(section, key))
# params: str section, str key
# return boolean
def get_config_bool(section, key):
return config.getboolean(section, key)
# params: str section, str key
# return List[str]
def get_config_list(section, key):
# str raw_str
raw_str = get_config(section, key)
return raw_str.split(',')
# alias for readability's sake
get_config_str_list = get_config_list
# params: str section, str key
# return List[int]
def get_config_int_list(section, key):
return list(map(int, get_config_list(section, key)))
# params: str section, str key
# return List[float]
def get_config_float_list(section, key):
return list(map(float, get_config_list(section, key)))
# params: str section, str key
# return List[boolean]
def get_config_bool_list(section, key):
return list(map(convert_to_bool, get_config_list(section, key)))
# params: str section, str key, ??? value
# return boolean
def config_list_add(section, key, value):
# str value_str
value_str = str(value)
# str list_str
list_str = get_config(section, key)
if len(list_str) == 0:
# nothing's in there, so we can just set the list to be the one new element
set_config(section, key, value_str)
return True
else:
if list_str.find(value_str) == -1:
list_str = list_str + ',' + value_str
set_config(section, key, value_str)
return True
else:
logging.warning("Attention: Value \"{}\" is already in [{}] {}.".format(value_str, section, key))
return False
# params: str section, str key, ??? value
# return boolean
def config_list_remove(section, key, value):
# str value_str
value_str = str(value)
# str list_str
list_str = get_config(section, key)
if len(list_str) == 0:
logging.warning("Attention: Cannot remove value \"{}\" from empty list [{}] {}.".format(value_str, section, key))
return False
elif list_str == value_str:
list_str = ""
set_config(section, key, list_str)
return True
else:
# int substr_idx
substr_idx = list_str.find(value_str)
if substr_idx != -1:
if substr_idx + len(value_str) == len(list_str) - 1:
list_str = list_str.replace(value_str, "")
else:
list_str = list_str.replace(value_str + ',', "")
set_config(section, key, list_str)
return True
else:
logging.warning("Attention: Cannot remove value \"{}\" from [{}] {} because the list doesn't contain it.".format(value_str, section, key))
return False
# params: str value
# return boolean
# copy of ConfigParser._convert_to_boolean()
def convert_to_bool(value):
if value.lower() not in config.BOOLEAN_STATES:
raise ValueError('Not a boolean: %s' % value)
return config.BOOLEAN_STATES[value.lower()]
# params: str section, str key, ??? value
def set_config(section, key, value):
# stupid Python global nonsense...
global config
config[section][key] = str(value)
try_save()
def try_save():
# allow multiple config sets to be bundled into one save
global save_task
if save_task is None:
save_task = asyncio.ensure_future(save_config())
async def save_config():
# clear task
global save_task
save_task = None
global file_name
# File config_file
config_file = open(file_name, "w")
if config_file is not None:
config.write(config_file)
logging.info("{} successfully saved".format(file_name))
else:
logging.error("{} is missing! Cannot save!".format(file_name))
# params: str date, str time
# return datetime.DateTime
def parse_datetime(date: str, time: str):
concat_dt = date + " " + time
valid_formats = get_config_str_list("Time", "datetime_formats")
for dt_format in valid_formats:
try:
test_dt = datetime.datetime.strptime(concat_dt, dt_format)
return test_dt
except ValueError:
# strftime() throws this if the input string doesn't fit the format
# we're okay with this because we're testing multiple formats
continue
raise ValueError("Invalid date format!")