mirror of
https://github.com/krateng/maloja.git
synced 2025-07-09 03:04:07 -04:00
Updated doreah toolkit
This commit is contained in:
parent
b8e4158336
commit
5cd6752510
29
doreah/_internal.py
Normal file
29
doreah/_internal.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
## decorator to set default arguments that are only evaluated at runtime
|
||||||
|
def defaultarguments(defaultdict,**defaultargs):
|
||||||
|
def decorator(func): #actual decorator function
|
||||||
|
def newfunc(*args,**kwargs):
|
||||||
|
realargs = {}
|
||||||
|
|
||||||
|
# evaluate default values at runtime
|
||||||
|
for k in defaultargs:
|
||||||
|
realargs[k] = defaultdict[defaultargs[k]]
|
||||||
|
|
||||||
|
# overwrite given arguments of function
|
||||||
|
realargs.update(kwargs)
|
||||||
|
|
||||||
|
# execute function with correct arguments
|
||||||
|
return func(*args,**realargs)
|
||||||
|
|
||||||
|
return newfunc
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
## opens file, creates it if necessary (including all folders)
|
||||||
|
def gopen(filepath,mode):
|
||||||
|
directory = os.path.dirname(filepath)
|
||||||
|
os.makedirs(directory, exist_ok=True)
|
||||||
|
|
||||||
|
return open(filepath,mode)
|
@ -1,6 +1,11 @@
|
|||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
|
from ._internal import defaultarguments
|
||||||
|
|
||||||
|
|
||||||
|
_config = {}
|
||||||
|
|
||||||
# set configuration
|
# set configuration
|
||||||
# defaultextension unused
|
# defaultextension unused
|
||||||
# files list of all files that will be used for configuration. high indicies overwrite low indicies
|
# files list of all files that will be used for configuration. high indicies overwrite low indicies
|
||||||
@ -9,186 +14,173 @@ import shutil
|
|||||||
# onlytext interpret everything as a string. if False, strings can be put into quotes to avoid confusion
|
# onlytext interpret everything as a string. if False, strings can be put into quotes to avoid confusion
|
||||||
def config(defaultextension=".ini",files=["settings.ini","settings.conf","configuration.ini","configuration.conf"],
|
def config(defaultextension=".ini",files=["settings.ini","settings.conf","configuration.ini","configuration.conf"],
|
||||||
comment=["#","//"],category=("[","]"),onlytext=False):
|
comment=["#","//"],category=("[","]"),onlytext=False):
|
||||||
global _defaultextension, _files, _comment, _category, _onlytext
|
|
||||||
_defaultextension = defaultextension
|
|
||||||
_files = files
|
|
||||||
_comment = comment
|
|
||||||
_category = category
|
|
||||||
_onlytext = onlytext
|
|
||||||
|
|
||||||
|
global _config
|
||||||
|
_config["defaultextension"] = defaultextension
|
||||||
|
_config["files"] = files
|
||||||
|
_config["comment"] = comment
|
||||||
|
_config["category"] = category
|
||||||
|
_config["onlytext"] = onlytext
|
||||||
|
|
||||||
global Settings, get_settings, update_settings, update
|
# initial config on import, set everything to default
|
||||||
|
config()
|
||||||
|
|
||||||
# manager object so we can read settings once and retain them
|
|
||||||
class Settings:
|
|
||||||
def __init__(self,**kwargs):
|
|
||||||
self.settings = get_settings(**kwargs)
|
|
||||||
|
|
||||||
def get(self,*keys):
|
|
||||||
result = (self.settings.get(k) for k in keys)
|
|
||||||
if len(result) == 1: result = result[0]
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _interpret(text):
|
def _interpret(text):
|
||||||
if _onlytext: return text
|
if _config["onlytext"]: return text
|
||||||
|
|
||||||
if text.lower() in ["true","yes"]: return True
|
if text.lower() in ["true","yes"]: return True
|
||||||
if text.lower() in ["false","no"]: return False
|
if text.lower() in ["false","no"]: return False
|
||||||
if text.lower() in ["none","nan","n/a",""]: return None
|
if text.lower() in ["none","nan","n/a",""]: return None
|
||||||
if text.startswith("'") and text.endswith("'"): return text[1:-1]
|
if text.startswith("'") and text.endswith("'"): return text[1:-1]
|
||||||
if text.startswith('"') and text.endswith('"'): return text[1:-1]
|
if text.startswith('"') and text.endswith('"'): return text[1:-1]
|
||||||
try:
|
try:
|
||||||
return int(text)
|
return int(text)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
return float(text)
|
return float(text)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
# get settings
|
# get settings
|
||||||
# keys list of requested keys. if present, will return list of according values, if not, will return dict of key-value pairs
|
# keys list of requested keys. if present, will return list of according values, if not, will return dict of key-value pairs
|
||||||
# files which files to parse. later files (higher indicies) will overload earlier ones
|
# files which files to parse. later files (higher indicies) will overload earlier ones
|
||||||
# prefix only request keys with a certain prefix. key filter will still be applied if present
|
# prefix only request keys with a certain prefix. key filter will still be applied if present
|
||||||
# cut_prefix return keys without the prefix
|
# cut_prefix return keys without the prefix
|
||||||
# category return only keys of specific category
|
# category return only keys of specific category
|
||||||
# raw do not interpret data type, only return strings
|
# raw do not interpret data type, only return strings
|
||||||
def get_settings(*keys,files=_files,prefix="",cut_prefix=False,category=None,raw=False):
|
@defaultarguments(_config,files="files")
|
||||||
|
def get_settings(*keys,files,prefix="",cut_prefix=False,category=None,raw=False):
|
||||||
|
|
||||||
allsettings = {}
|
allsettings = {}
|
||||||
|
|
||||||
for f in files:
|
for f in files:
|
||||||
if not os.path.exists(f): continue
|
if not os.path.exists(f): continue
|
||||||
|
|
||||||
# if category is specified, ignore all entries by default and switch when we encounter the right heading
|
# if category is specified, ignore all entries by default and switch when we encounter the right heading
|
||||||
ignore = False if category is None else True
|
ignore = False if category is None else True
|
||||||
|
|
||||||
with open(f) as file:
|
with open(f) as file:
|
||||||
lines = file.readlines()
|
lines = file.readlines()
|
||||||
|
|
||||||
|
|
||||||
for l in lines:
|
for l in lines:
|
||||||
# clean up line
|
|
||||||
l = l.replace("\n","")
|
|
||||||
for symbol in _comment:
|
|
||||||
l = l.split(symbol)[0]
|
|
||||||
l = l.strip()
|
|
||||||
|
|
||||||
# check if valid settings entry
|
|
||||||
if l == "": continue
|
|
||||||
if l.startswith(_category[0]):
|
|
||||||
# ignore category headers if we don't care
|
|
||||||
if category is None: continue
|
|
||||||
# otherwise, find out if this is the category we want
|
|
||||||
else:
|
|
||||||
if l.endswith(_category[1]):
|
|
||||||
cat = l[len(_category[0]):-len(_category[1])]
|
|
||||||
ignore = not (cat == category) #if this is the right heading, set ignore to false
|
|
||||||
continue
|
|
||||||
|
|
||||||
if ignore: continue
|
|
||||||
|
|
||||||
if "=" not in l: continue
|
|
||||||
|
|
||||||
# read
|
|
||||||
(key,val) = l.split("=")
|
|
||||||
key = key.strip()
|
|
||||||
val = val.strip() if raw else _interpret(val.strip())
|
|
||||||
|
|
||||||
if key.startswith(prefix):
|
|
||||||
# return keys without the common prefix
|
|
||||||
if cut_prefix:
|
|
||||||
allsettings[key[len(prefix):]] = val
|
|
||||||
|
|
||||||
# return full keys
|
|
||||||
else:
|
|
||||||
allsettings[key] = val
|
|
||||||
|
|
||||||
# no arguments means all settings
|
|
||||||
if len(keys) == 0:
|
|
||||||
return allsettings
|
|
||||||
|
|
||||||
# specific keys requested
|
|
||||||
else:
|
|
||||||
if len(keys) == 1: return allsettings.get(keys[0])
|
|
||||||
else: return [allsettings.get(k) for k in keys]
|
|
||||||
|
|
||||||
|
|
||||||
def update_settings(file,settings,create_new=False):
|
|
||||||
|
|
||||||
if not os.path.exists(file): open(file,"w").close()
|
|
||||||
|
|
||||||
with open(file,"r") as origfile:
|
|
||||||
lines = origfile.readlines()
|
|
||||||
|
|
||||||
newlines = []
|
|
||||||
|
|
||||||
for origline in lines:
|
|
||||||
l = origline
|
|
||||||
# clean up line
|
# clean up line
|
||||||
l = l.replace("\n","")
|
l = l.replace("\n","")
|
||||||
for symbol in _comment:
|
for symbol in _config["comment"]:
|
||||||
l = l.split(symbol)[0]
|
l = l.split(symbol)[0]
|
||||||
l = l.strip()
|
l = l.strip()
|
||||||
|
|
||||||
# check if valid settings entry
|
# check if valid settings entry
|
||||||
if l == "":
|
if l == "": continue
|
||||||
newlines.append(origline)
|
if l.startswith(_config["category"][0]):
|
||||||
continue
|
# ignore category headers if we don't care
|
||||||
if l.startswith(_category[0]):
|
if category is None: continue
|
||||||
newlines.append(origline)
|
# otherwise, find out if this is the category we want
|
||||||
continue
|
else:
|
||||||
if "=" not in l:
|
if l.endswith(_config["category"][1]):
|
||||||
newlines.append(origline)
|
cat = l[len(_config["category"][0]):-len(_config["category"][1])]
|
||||||
continue
|
ignore = not (cat == category) #if this is the right heading, set ignore to false
|
||||||
|
continue
|
||||||
|
|
||||||
|
if ignore: continue
|
||||||
|
|
||||||
|
if "=" not in l: continue
|
||||||
|
|
||||||
# read
|
# read
|
||||||
(key,val) = l.split("=")
|
(key,val) = l.split("=")
|
||||||
key = key.strip()
|
key = key.strip()
|
||||||
val = val.strip()
|
val = val.strip() if raw else _interpret(val.strip())
|
||||||
|
|
||||||
|
if key.startswith(prefix):
|
||||||
|
# return keys without the common prefix
|
||||||
|
if cut_prefix:
|
||||||
|
allsettings[key[len(prefix):]] = val
|
||||||
|
|
||||||
|
# return full keys
|
||||||
|
else:
|
||||||
|
allsettings[key] = val
|
||||||
|
|
||||||
|
# no arguments means all settings
|
||||||
|
if len(keys) == 0:
|
||||||
|
return allsettings
|
||||||
|
|
||||||
|
# specific keys requested
|
||||||
|
else:
|
||||||
|
if len(keys) == 1: return allsettings.get(keys[0])
|
||||||
|
else: return [allsettings.get(k) for k in keys]
|
||||||
|
|
||||||
|
|
||||||
if key not in settings:
|
def update_settings(file,settings,create_new=False):
|
||||||
newlines.append(origline)
|
|
||||||
continue
|
|
||||||
|
|
||||||
else:
|
if not os.path.exists(file): open(file,"w").close()
|
||||||
#print("Found key")
|
|
||||||
newline = origline.split("=",1)
|
|
||||||
#print({"linepart":newline[1],"keytoreplace":val,"new":settings[key]})
|
|
||||||
newline[1] = newline[1].replace(val,str(settings[key]),1)
|
|
||||||
newline = "=".join(newline)
|
|
||||||
newlines.append(newline)
|
|
||||||
|
|
||||||
del settings[key]
|
with open(file,"r") as origfile:
|
||||||
|
lines = origfile.readlines()
|
||||||
|
|
||||||
if create_new:
|
newlines = []
|
||||||
# settings that were not present in the file
|
|
||||||
for key in settings:
|
|
||||||
newlines.append(key + " = " + settings[key] + "\n")
|
|
||||||
|
|
||||||
with open(file,"w") as newfile:
|
for origline in lines:
|
||||||
newfile.write("".join(newlines))
|
l = origline
|
||||||
|
# clean up line
|
||||||
|
l = l.replace("\n","")
|
||||||
|
for symbol in _config["comment"]:
|
||||||
|
l = l.split(symbol)[0]
|
||||||
|
l = l.strip()
|
||||||
|
|
||||||
|
# check if valid settings entry
|
||||||
|
if l == "":
|
||||||
|
newlines.append(origline)
|
||||||
|
continue
|
||||||
|
if l.startswith(_config["category"][0]):
|
||||||
|
newlines.append(origline)
|
||||||
|
continue
|
||||||
|
if "=" not in l:
|
||||||
|
newlines.append(origline)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# read
|
||||||
|
(key,val) = l.split("=")
|
||||||
|
key = key.strip()
|
||||||
|
val = val.strip()
|
||||||
|
|
||||||
|
|
||||||
|
if key not in settings:
|
||||||
|
newlines.append(origline)
|
||||||
|
continue
|
||||||
|
|
||||||
|
|
||||||
# updates a user settings file to a newer format from a default file without overwriting user's settings
|
|
||||||
def update(source="default_settings.ini",target="settings.ini"):
|
|
||||||
|
|
||||||
if not os.path.exists(target):
|
|
||||||
shutil.copyfile(source,target)
|
|
||||||
else:
|
else:
|
||||||
usersettings = get_settings(files=[target],raw=True)
|
#print("Found key")
|
||||||
shutil.copyfile(source,target)
|
newline = origline.split("=",1)
|
||||||
update_settings(target,usersettings)
|
#print({"linepart":newline[1],"keytoreplace":val,"new":settings[key]})
|
||||||
|
newline[1] = newline[1].replace(val,str(settings[key]),1)
|
||||||
|
newline = "=".join(newline)
|
||||||
|
newlines.append(newline)
|
||||||
|
|
||||||
|
del settings[key]
|
||||||
|
|
||||||
|
if create_new:
|
||||||
|
# settings that were not present in the file
|
||||||
|
for key in settings:
|
||||||
|
newlines.append(key + " = " + settings[key] + "\n")
|
||||||
|
|
||||||
|
with open(file,"w") as newfile:
|
||||||
|
newfile.write("".join(newlines))
|
||||||
|
|
||||||
|
|
||||||
# initial config on import, set everything to default
|
|
||||||
config()
|
|
||||||
|
# updates a user settings file to a newer format from a default file without overwriting user's settings
|
||||||
|
def update(source="default_settings.ini",target="settings.ini"):
|
||||||
|
|
||||||
|
if not os.path.exists(target):
|
||||||
|
shutil.copyfile(source,target)
|
||||||
|
else:
|
||||||
|
usersettings = get_settings(files=[target],raw=True)
|
||||||
|
shutil.copyfile(source,target)
|
||||||
|
update_settings(target,usersettings)
|
||||||
|
@ -10,4 +10,4 @@ LASTFM_API_KEY = "ASK" # "ASK" signifies that the user has not yet indicated to
|
|||||||
[Cache]
|
[Cache]
|
||||||
|
|
||||||
CACHE_EXPIRE_NEGATIVE = 30 # after how many days negative results should be tried again
|
CACHE_EXPIRE_NEGATIVE = 30 # after how many days negative results should be tried again
|
||||||
CACHE_EXPIRE_POSITIVE = none # after how many days positive results should be refreshed
|
CACHE_EXPIRE_POSITIVE = 300 # after how many days positive results should be refreshed
|
||||||
|
Loading…
x
Reference in New Issue
Block a user