DashMachine/dashmachine/main/read_config.py
Ross Mountjoy ff6b2372b3 - reduced the size of app cards, moving description to a pop-open
- broke up config readme into 3 tabs, and 3 .md files
- changed 'app templates' to 'card templates'
- added 'collection' cards
- added 'custom' cards
- added options for setting tag icons and sort position
- removed list view to focus on different card types on /home
- added ability to collapse/expand tags on /home
- added setting for having tags default to collapsed state
- added settings for the default state of the sidebar
- created a public user view with no sidebar
- added sidebar default overrides for users
2020-03-27 08:58:11 -04:00

255 lines
9.4 KiB
Python

import os
import json
from configparser import ConfigParser
from dashmachine.main.models import Apps, Groups, DataSources, DataSourcesArgs, Tags
from dashmachine.user_system.models import User
from dashmachine.user_system.utils import (
hash_and_cache_password,
get_cached_password,
clean_auth_cache,
)
from dashmachine.settings_system.models import Settings
from dashmachine.paths import user_data_folder
from dashmachine import db
def row2dict(row):
d = {}
for column in row.__table__.columns:
d[column.name] = str(getattr(row, column.name))
return d
def read_config():
config = ConfigParser()
try:
config.read(os.path.join(user_data_folder, "config.ini"))
except Exception as e:
return {"msg": f"Invalid Config: {e}."}
ds_list = DataSources.query.all()
for ds in ds_list:
ds.apps.clear()
DataSources.query.delete()
DataSourcesArgs.query.delete()
Apps.query.delete()
Settings.query.delete()
Groups.query.delete()
Tags.query.delete()
User.query.delete()
for section in config.sections():
# Settings creation
if section == "Settings":
settings = Settings()
settings.theme = config["Settings"].get("theme", "light")
settings.accent = config["Settings"].get("accent", "orange")
settings.background = config["Settings"].get("background", "None")
if "roles" in config["Settings"]:
settings.roles = config["Settings"]["roles"]
if "admin" not in settings.roles:
settings.roles += ",admin"
if "user" not in settings.roles:
settings.roles += ",user"
if "public_user" not in settings.roles:
settings.roles += ",public_user"
else:
settings.roles = "admin,user,public_user"
settings.home_access_groups = config["Settings"].get(
"home_access_groups", "admin_only"
)
settings.settings_access_groups = config["Settings"].get(
"settings_access_groups", "admin_only"
)
settings.custom_app_title = config["Settings"].get(
"custom_app_title", "DashMachine"
)
settings.sidebar_default = config["Settings"].get("sidebar_default", "open")
settings.tags_expanded = config["Settings"].get("tags_expanded", "True")
db.session.add(settings)
db.session.commit()
# User creation
elif "role" in config[section]:
user = User()
user.username = section
user.role = config[section]["role"]
user.sidebar_default = config[section].get("sidebar_default", None)
user.theme = config[section].get("theme", None)
user.accent = config[section].get("accent", None)
user.tags_expanded = config[section].get("tags_expanded", None)
user.password = ""
if not User.query.filter_by(role="admin").first() and user.role != "admin":
print(
f"Invalid Config: admin user not specified, or not specified first. {user.username} role set to admin"
)
user.role = "admin"
config.set(section, "role", "admin")
config.write(open(os.path.join(user_data_folder, "config.ini"), "w"))
db.session.add(user)
db.session.commit()
new_password = config[section].get("password", None)
if new_password:
if new_password == config[section].get("confirm_password", None):
password = hash_and_cache_password(new_password, user.id)
user.password = password
db.session.merge(user)
db.session.commit()
else:
password = get_cached_password(user.id)
if password == "error":
print(
f"Invalid Config: Password for {user.username} must be specified. Using 'admin' by default"
)
user.password = password
db.session.merge(user)
db.session.commit()
config.set(section, "password", "")
config.set(section, "confirm_password", "")
config.write(open(os.path.join(user_data_folder, "config.ini"), "w"))
# Groups creation
elif "roles" in config[section]:
group = Groups()
group.name = section
group.roles = config[section]["roles"]
db.session.add(group)
db.session.commit()
# Data source creation
elif "platform" in config[section]:
data_source = DataSources()
data_source.name = section
data_source.platform = config[section]["platform"]
db.session.add(data_source)
db.session.commit()
for key, value in config[section].items():
if key not in ["name", "platform"]:
arg = DataSourcesArgs()
arg.key = key
arg.value = value
arg.data_source = data_source
db.session.add(arg)
db.session.commit()
else:
# App creation
app = Apps()
app.name = section
app.type = config[section].get("type", "app")
app.prefix = config[section].get("prefix", None)
if app.type == "app" and not app.prefix:
return {"msg": f"Invalid Config: {section} does not contain prefix."}
app.url = config[section].get("url", None)
if app.type == "app" and not app.url:
return {"msg": f"Invalid Config: {section} does not contain url."}
app.icon = config[section].get("icon", None)
app.sidebar_icon = config[section].get("sidebar_icon", None)
app.description = config[section].get("description", None)
app.open_in = config[section].get("open_in", "this_tab")
app.urls = config[section].get("urls", None)
if "groups" in config[section]:
for group_name in config[section]["groups"].split(","):
if not Groups.query.filter_by(name=group_name.strip()).first():
return {
"msg": f"Invalid Config: {section} contains at group that is not defined."
}
app.groups = config[section]["groups"]
else:
app.groups = None
# Tags creation
if "tags" in config[section]:
app.tags = config[section]["tags"]
for tag in app.tags.split(","):
tag = tag.strip()
if not Tags.query.filter_by(name=tag).first():
tag_db = Tags(name=tag)
db.session.add(tag_db)
db.session.commit()
tag_db.sort_pos = tag_db.id
db.session.merge(tag_db)
db.session.commit()
else:
if Tags.query.first():
app.tags = "Untagged"
if not Tags.query.filter_by(name="Untagged").first():
tag_db = Tags(name="Untagged")
db.session.add(tag_db)
db.session.commit()
else:
app.tags = None
db.session.add(app)
db.session.commit()
if "data_sources" in config[section]:
for config_ds in config[section]["data_sources"].split(","):
db_ds = DataSources.query.filter_by(name=config_ds.strip()).first()
if db_ds:
app.data_sources.append(db_ds)
db.session.merge(app)
db.session.commit()
else:
return {
"msg": f"Invalid Config: {section} has a data_source variable that doesn't exist."
}
group = Groups.query.filter_by(name="admin_only").first()
if not group:
group = Groups()
group.name = "admin_only"
group.roles = "admin"
db.session.add(group)
db.session.commit()
tags_settings = config["Settings"].get("tags", None)
if tags_settings:
tags_settings = tags_settings.replace("},{", "}%,%{").split("%,%")
for tag_setting in tags_settings:
tag_json = json.loads(tag_setting)
tag = Tags.query.filter_by(name=tag_json.get("name", None)).first()
if tag:
icon = tag_json.get("icon", None)
if icon:
tag.icon = icon
sort_pos = tag_json.get("sort_pos", None)
if icon:
tag.sort_pos = sort_pos
db.session.merge(tag)
db.session.commit()
clean_auth_cache()
if not User.query.first():
user = User()
user.username = "admin"
user.role = "admin"
user.password = ""
db.session.add(user)
db.session.commit()
user.password = hash_and_cache_password("admin", user.id)
db.session.merge(user)
db.session.commit()
return {"msg": "success", "settings": row2dict(settings)}