224 lines
7.3 KiB
Python
224 lines
7.3 KiB
Python
# Custom
|
|
from model import *
|
|
from appstate import *
|
|
|
|
# External
|
|
from imgui_bundle import (
|
|
imgui,
|
|
imgui_ctx,
|
|
immapp,
|
|
imgui_md,
|
|
im_file_dialog,
|
|
hello_imgui
|
|
)
|
|
|
|
# Built In
|
|
from typing import List
|
|
import shelve
|
|
from pathlib import Path
|
|
from datetime import datetime
|
|
|
|
def file_info(path: Path) -> None:
|
|
stat = path.stat()
|
|
modified = datetime.fromtimestamp(stat.st_atime)
|
|
created = datetime.fromtimestamp(stat.st_ctime)
|
|
format = '%c'
|
|
|
|
data = {
|
|
"File": path.name,
|
|
"Size": f"{stat.st_size/100} KB",
|
|
"Modified": modified.strftime(format),
|
|
"Created": created.strftime(format)
|
|
}
|
|
|
|
if imgui.begin_table("File Info", 2):
|
|
imgui.table_setup_column(" ", 0)
|
|
imgui.table_setup_column(" ")
|
|
|
|
for k, v in data.items():
|
|
imgui.push_id(k)
|
|
imgui.table_next_row()
|
|
imgui.table_next_column()
|
|
imgui.text(k)
|
|
imgui.table_next_column()
|
|
imgui.text(v)
|
|
imgui.pop_id()
|
|
imgui.end_table()
|
|
|
|
@immapp.static(inited=False, res=False)
|
|
def select_file(app_state: AppState):
|
|
statics = select_file
|
|
if not statics.inited:
|
|
statics.res = None
|
|
statics.current = None
|
|
with shelve.open("state") as state:
|
|
statics.current = Path(state["DB"])
|
|
statics.inited = True
|
|
|
|
imgui_md.render("# Database Manager")
|
|
file_info(statics.current)
|
|
|
|
if imgui.button("Open File"):
|
|
im_file_dialog.FileDialog.instance().open("SelectDatabase", "Open Database", "Database File (*.json;*.db){.json,.db}")
|
|
if im_file_dialog.FileDialog.instance().is_done("SelectDatabase"):
|
|
if im_file_dialog.FileDialog.instance().has_result():
|
|
statics.res = im_file_dialog.FileDialog.instance().get_result()
|
|
LOG_INFO(f"Load File {statics.res}")
|
|
im_file_dialog.FileDialog.instance().close()
|
|
|
|
if statics.res:
|
|
filename = statics.res.filename()
|
|
info = Path(statics.res.path())
|
|
|
|
imgui.separator()
|
|
file_info(info)
|
|
|
|
file = None
|
|
if imgui.button("Load"):
|
|
if not db.is_closed():
|
|
db.close()
|
|
|
|
if statics.res.extension() == '.json':
|
|
file = filename.removesuffix('.json')
|
|
file = file + '.db'
|
|
db.init(file)
|
|
db.connect(reuse_if_open=True)
|
|
db.create_tables([Class, Student, Lecture, Submission])
|
|
load_from_json(str(info))
|
|
LOG_INFO(f"Successfully created {file}")
|
|
|
|
if statics.res.extension() == '.db':
|
|
file = str(statics.res.path())
|
|
db.init(file)
|
|
db.connect(reuse_if_open=True)
|
|
db.create_tables([Class, Student, Lecture, Submission])
|
|
LOG_INFO(f"Successfully loaded {filename}")
|
|
|
|
with shelve.open("state") as state:
|
|
state["DB"] = file
|
|
app_state.update()
|
|
statics.res = None
|
|
|
|
@immapp.static(inited=False)
|
|
def table(app_state: AppState) -> None:
|
|
statics = table
|
|
if not statics.inited:
|
|
statics.class_id = None
|
|
statics.lectures = None
|
|
statics.points = list()
|
|
statics.inited = True
|
|
|
|
if statics.class_id != app_state.current_class_id:
|
|
statics.class_id = app_state.current_class_id
|
|
statics.lectures = Lecture.select().where(Lecture.class_id == statics.class_id)
|
|
statics.data = dict()
|
|
for student in Student.select().where(Student.class_id == statics.class_id):
|
|
subs = Submission.select().where(Submission.student_id == student.id)
|
|
points = [sub.points for sub in subs]
|
|
statics.data[f"{student.prename} {student.surname}"] = points
|
|
|
|
if not statics.lectures:
|
|
imgui.text("No Lecture queried")
|
|
return
|
|
|
|
table_flags = (
|
|
imgui.TableFlags_.row_bg.value
|
|
| imgui.TableFlags_.borders.value
|
|
| imgui.TableFlags_.resizable.value
|
|
| imgui.TableFlags_.sizing_stretch_same.value
|
|
)
|
|
|
|
if imgui.begin_table("Overview", len(statics.lectures)+1, table_flags):
|
|
imgui.table_setup_column("Students")
|
|
for n, lecture in enumerate(statics.lectures, start=1):
|
|
imgui.table_setup_column(f"{n}. {lecture.title} ({lecture.points})")
|
|
imgui.table_setup_scroll_freeze(1, 1)
|
|
imgui.table_headers_row()
|
|
|
|
for k, v in statics.data.items():
|
|
imgui.push_id(k)
|
|
imgui.table_next_row()
|
|
imgui.table_next_column()
|
|
imgui.text(k)
|
|
for points in v:
|
|
imgui.table_next_column()
|
|
if points.is_integer():
|
|
points = int(points)
|
|
imgui.text(str(points))
|
|
imgui.pop_id()
|
|
|
|
imgui.end_table()
|
|
|
|
@immapp.static(inited=False)
|
|
def class_editor() -> None:
|
|
statics = class_editor
|
|
if not statics.inited:
|
|
statics.classes = None
|
|
statics.selected = 0
|
|
statics.inited = True
|
|
|
|
statics.classes = Class.select()
|
|
|
|
imgui_md.render("# Edit Classes")
|
|
_, statics.selected = imgui.combo("Classes", statics.selected, [c.name for c in statics.classes])
|
|
imgui.text(statics.classes[statics.selected].name)
|
|
|
|
def database_editor(app_state: AppState) -> None:
|
|
class_editor()
|
|
|
|
def database_docking_splits() -> List[hello_imgui.DockingSplit]:
|
|
split_main_command = hello_imgui.DockingSplit()
|
|
split_main_command.initial_dock = "MainDockSpace"
|
|
split_main_command.new_dock = "CommandSpace"
|
|
split_main_command.direction = imgui.Dir.down
|
|
split_main_command.ratio = 0.3
|
|
|
|
# Log Space
|
|
split_main_command2 = hello_imgui.DockingSplit()
|
|
split_main_command2.initial_dock = "CommandSpace"
|
|
split_main_command2.new_dock = "CommandSpace2"
|
|
split_main_command2.direction = imgui.Dir.right
|
|
split_main_command2.ratio = 0.3
|
|
|
|
split_main_misc = hello_imgui.DockingSplit()
|
|
split_main_misc.initial_dock = "MainDockSpace"
|
|
split_main_misc.new_dock = "MiscSpace"
|
|
split_main_misc.direction = imgui.Dir.left
|
|
split_main_misc.ratio = 0.2
|
|
|
|
splits = [split_main_misc, split_main_command, split_main_command2]
|
|
return splits
|
|
|
|
def set_database_editor_layout(app_state: AppState) -> List[hello_imgui.DockableWindow]:
|
|
|
|
file_dialog = hello_imgui.DockableWindow()
|
|
file_dialog.label = "Database"
|
|
file_dialog.dock_space_name = "MiscSpace"
|
|
file_dialog.gui_function = lambda: select_file(app_state)
|
|
|
|
log = hello_imgui.DockableWindow()
|
|
log.label = "Logs"
|
|
log.dock_space_name = "CommandSpace2"
|
|
log.gui_function = hello_imgui.log_gui
|
|
|
|
table_view = hello_imgui.DockableWindow()
|
|
table_view.label = "Table"
|
|
table_view.dock_space_name = "MainDockSpace"
|
|
table_view.gui_function = lambda: table(app_state)
|
|
|
|
editor = hello_imgui.DockableWindow()
|
|
editor.label = "Editor"
|
|
editor.dock_space_name = "CommandSpace"
|
|
editor.gui_function = lambda: database_editor(app_state)
|
|
|
|
return [
|
|
file_dialog, log, table_view, editor
|
|
]
|
|
|
|
def database_editor_layout(app_state: AppState) -> hello_imgui.DockingParams:
|
|
docking_params = hello_imgui.DockingParams()
|
|
docking_params.layout_name = "Database Editor"
|
|
docking_params.docking_splits = database_docking_splits()
|
|
docking_params.dockable_windows = set_database_editor_layout(app_state)
|
|
return docking_params
|