import os import yaml from collections import OrderedDict from flask import Flask, jsonify, send_from_directory, request, redirect, url_for, session, render_template from werkzeug.security import check_password_hash import database # Imports the database.py you created earlier # --- Path Configurations --- BASE_DIR = os.path.dirname(os.path.abspath(__file__)) FRONTEND_DIR = os.path.join(BASE_DIR, '..', 'frontend') YML_PATH = os.path.join(BASE_DIR, '..\\mxpic\\PDKs\\Silterra\\directories.yaml') COMPS_ROOT = os.path.join(BASE_DIR, '..\\mxpic\\PDKs\\Silterra') # --- YAML & PDK Parsing Helper Functions (Unchanged) --- def countSpaces(line): """Count leading spaces (tab=4).""" expanded = line.expandtabs(4) return len(expanded) - len(expanded.lstrip(' ')) def buildTree(filepath): """Build nested tree from indented yaml.""" if not os.path.exists(filepath): return OrderedDict() with open(filepath, 'r', encoding='utf-8') as f: lines = f.readlines() rootIdx = None for i, line in enumerate(lines): if line.strip().startswith('root') and ':' in line.strip(): rootIdx = i break if rootIdx is None: return OrderedDict() entries = [] for line in lines[rootIdx + 1:]: stripped = line.strip() if not stripped or stripped.startswith('#'): continue if stripped.startswith('- '): spaceNum = countSpaces(line) name = stripped[2:].strip() if name.strip(): entries.append((spaceNum, name)) if not entries: return OrderedDict() minIndent = min(indent for indent, _ in entries) nest = OrderedDict() levelStack = [(minIndent - 1, nest)] for spaceNum, name in entries: while levelStack and levelStack[-1][0] >= spaceNum: levelStack.pop() parent = levelStack[-1][1] child = OrderedDict() parent[name] = child levelStack.append((spaceNum, child)) return nest def findComps(baseDir): """Scan component folders, return map of paths -> component info.""" compMap = {} refDir = os.path.dirname(baseDir) for root, dirs, files in os.walk(baseDir): ymlFiles = [f for f in files if f.endswith('.yml')] if ymlFiles: parentDir = os.path.dirname(root) relPath = os.path.relpath(parentDir, refDir) parts = () if relPath == '.' else tuple(relPath.split(os.sep)) compName = os.path.basename(root) compMap[parts] = { 'folder': compName, 'yml': ymlFiles[0] } dirs.clear() return compMap def addCompsToTree(tree, compMap): """Insert component nodes into the tree.""" for pathSeg, compItem in compMap.items(): compName = compItem['folder'] curNode = tree try: for seg in pathSeg: curNode = curNode[seg] except KeyError: continue curNode[compName] = OrderedDict({ "__type__": "component", "__name__": compName, "__yml__": compItem['yml'] }) return tree def readCompYaml(compName): """Load YAML from component folder.""" for root, dirs, files in os.walk(COMPS_ROOT): if os.path.basename(root) == compName: dirs.clear() ymlFiles = [f for f in files if f.endswith('.yml')] if ymlFiles: ymlPath = os.path.join(root, ymlFiles[0]) with open(ymlPath, 'r', encoding='utf-8') as f: return yaml.safe_load(f) return None