feat: Introduce initial web frontend and backend services, and generalize directory configuration in docker-compose.
This commit is contained in:
parent
6b03709b30
commit
d76ad89f09
@ -52,7 +52,7 @@ SUPPORTED_EXTENSIONS = {
|
|||||||
|
|
||||||
|
|
||||||
def load_vault_config() -> Dict[str, Dict[str, Any]]:
|
def load_vault_config() -> Dict[str, Dict[str, Any]]:
|
||||||
"""Read VAULT_N_* env vars and return vault configuration.
|
"""Read VAULT_N_* and DIR_N_* env vars and return vault configuration.
|
||||||
|
|
||||||
Scans environment variables ``VAULT_1_NAME``/``VAULT_1_PATH``,
|
Scans environment variables ``VAULT_1_NAME``/``VAULT_1_PATH``,
|
||||||
``VAULT_2_NAME``/``VAULT_2_PATH``, etc. in sequential order.
|
``VAULT_2_NAME``/``VAULT_2_PATH``, etc. in sequential order.
|
||||||
@ -67,6 +67,7 @@ def load_vault_config() -> Dict[str, Dict[str, Any]]:
|
|||||||
- path: filesystem path (required)
|
- path: filesystem path (required)
|
||||||
- attachmentsPath: relative attachments folder (optional)
|
- attachmentsPath: relative attachments folder (optional)
|
||||||
- scanAttachmentsOnStartup: boolean (default True)
|
- scanAttachmentsOnStartup: boolean (default True)
|
||||||
|
- type: "VAULT" or "DIR"
|
||||||
"""
|
"""
|
||||||
vaults: Dict[str, Dict[str, Any]] = {}
|
vaults: Dict[str, Dict[str, Any]] = {}
|
||||||
n = 1
|
n = 1
|
||||||
@ -84,8 +85,25 @@ def load_vault_config() -> Dict[str, Dict[str, Any]]:
|
|||||||
"path": path,
|
"path": path,
|
||||||
"attachmentsPath": attachments_path,
|
"attachmentsPath": attachments_path,
|
||||||
"scanAttachmentsOnStartup": scan_attachments,
|
"scanAttachmentsOnStartup": scan_attachments,
|
||||||
|
"type": "VAULT"
|
||||||
}
|
}
|
||||||
n += 1
|
n += 1
|
||||||
|
|
||||||
|
n = 1
|
||||||
|
while True:
|
||||||
|
name = os.environ.get(f"DIR_{n}_NAME")
|
||||||
|
path = os.environ.get(f"DIR_{n}_PATH")
|
||||||
|
if not name or not path:
|
||||||
|
break
|
||||||
|
|
||||||
|
vaults[name] = {
|
||||||
|
"path": path,
|
||||||
|
"attachmentsPath": None,
|
||||||
|
"scanAttachmentsOnStartup": False,
|
||||||
|
"type": "DIR"
|
||||||
|
}
|
||||||
|
n += 1
|
||||||
|
|
||||||
return vaults
|
return vaults
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -59,6 +59,7 @@ class VaultInfo(BaseModel):
|
|||||||
name: str = Field(description="Display name of the vault")
|
name: str = Field(description="Display name of the vault")
|
||||||
file_count: int = Field(description="Number of indexed files")
|
file_count: int = Field(description="Number of indexed files")
|
||||||
tag_count: int = Field(description="Number of unique tags")
|
tag_count: int = Field(description="Number of unique tags")
|
||||||
|
type: str = Field(default="VAULT", description="Type of the vault mapping (VAULT or DIR)")
|
||||||
|
|
||||||
|
|
||||||
class BrowseItem(BaseModel):
|
class BrowseItem(BaseModel):
|
||||||
@ -603,10 +604,12 @@ async def api_vaults(current_user=Depends(require_auth)):
|
|||||||
result = []
|
result = []
|
||||||
for name, data in index.items():
|
for name, data in index.items():
|
||||||
if "*" in user_vaults or name in user_vaults:
|
if "*" in user_vaults or name in user_vaults:
|
||||||
|
v_type = vault_config.get(name, {}).get("type", "VAULT")
|
||||||
result.append({
|
result.append({
|
||||||
"name": name,
|
"name": name,
|
||||||
"file_count": len(data["files"]),
|
"file_count": len(data["files"]),
|
||||||
"tag_count": len(data["tags"]),
|
"tag_count": len(data["tags"]),
|
||||||
|
"type": v_type,
|
||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|||||||
@ -39,8 +39,8 @@ services:
|
|||||||
- VAULT_4_PATH=/vaults/Obsidian_WORKOUT
|
- VAULT_4_PATH=/vaults/Obsidian_WORKOUT
|
||||||
- VAULT_5_NAME=Sessions
|
- VAULT_5_NAME=Sessions
|
||||||
- VAULT_5_PATH=/vaults/SessionsManager
|
- VAULT_5_PATH=/vaults/SessionsManager
|
||||||
- VAULT_6_NAME=Bruno
|
- DIR_1_NAME=Bruno
|
||||||
- VAULT_6_PATH=/vaults/bruno
|
- DIR_1_PATH=/vaults/bruno
|
||||||
# Auth configuration (uncomment to enable)
|
# Auth configuration (uncomment to enable)
|
||||||
- OBSIGATE_AUTH_ENABLED=true
|
- OBSIGATE_AUTH_ENABLED=true
|
||||||
- OBSIGATE_ADMIN_USER=admin
|
- OBSIGATE_ADMIN_USER=admin
|
||||||
|
|||||||
@ -1400,7 +1400,7 @@
|
|||||||
vaultsToShow.forEach((v) => {
|
vaultsToShow.forEach((v) => {
|
||||||
const vaultItem = el("div", { class: "tree-item vault-item", "data-vault": v.name }, [
|
const vaultItem = el("div", { class: "tree-item vault-item", "data-vault": v.name }, [
|
||||||
icon("chevron-right", 14),
|
icon("chevron-right", 14),
|
||||||
icon("database", 16),
|
getVaultIcon(v.name, 16),
|
||||||
document.createTextNode(` ${v.name} `),
|
document.createTextNode(` ${v.name} `),
|
||||||
smallBadge(v.file_count),
|
smallBadge(v.file_count),
|
||||||
]);
|
]);
|
||||||
@ -1457,7 +1457,7 @@
|
|||||||
// Sidebar tree entry
|
// Sidebar tree entry
|
||||||
const vaultItem = el("div", { class: "tree-item vault-item", "data-vault": v.name }, [
|
const vaultItem = el("div", { class: "tree-item vault-item", "data-vault": v.name }, [
|
||||||
icon("chevron-right", 14),
|
icon("chevron-right", 14),
|
||||||
icon("database", 16),
|
getVaultIcon(v.name, 16),
|
||||||
document.createTextNode(` ${v.name} `),
|
document.createTextNode(` ${v.name} `),
|
||||||
smallBadge(v.file_count),
|
smallBadge(v.file_count),
|
||||||
]);
|
]);
|
||||||
@ -1736,7 +1736,7 @@
|
|||||||
entries.sort((a, b) => a.path.localeCompare(b.path, undefined, { sensitivity: "base" }));
|
entries.sort((a, b) => a.path.localeCompare(b.path, undefined, { sensitivity: "base" }));
|
||||||
|
|
||||||
const vaultHeader = el("div", { class: "tree-item vault-item filter-results-header", "data-vault": vaultName }, [
|
const vaultHeader = el("div", { class: "tree-item vault-item filter-results-header", "data-vault": vaultName }, [
|
||||||
icon("database", 16),
|
getVaultIcon(vaultName, 16),
|
||||||
document.createTextNode(` ${vaultName} `),
|
document.createTextNode(` ${vaultName} `),
|
||||||
smallBadge(entries.length),
|
smallBadge(entries.length),
|
||||||
]);
|
]);
|
||||||
@ -3296,6 +3296,46 @@
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getVaultIcon(vaultName, size = 16) {
|
||||||
|
const v = allVaults.find((val) => val.name === vaultName);
|
||||||
|
const type = v ? v.type : "VAULT";
|
||||||
|
|
||||||
|
if (type === "DIR") {
|
||||||
|
const i = icon("folder", size);
|
||||||
|
i.style.color = "#eab308"; // yellow tint
|
||||||
|
return i;
|
||||||
|
} else {
|
||||||
|
const purple = "#8b5cf6";
|
||||||
|
const svgNS = "http://www.w3.org/2000/svg";
|
||||||
|
const svg = document.createElementNS(svgNS, "svg");
|
||||||
|
svg.setAttribute("xmlns", svgNS);
|
||||||
|
svg.setAttribute("width", size);
|
||||||
|
svg.setAttribute("height", size);
|
||||||
|
svg.setAttribute("viewBox", "0 0 24 24");
|
||||||
|
svg.setAttribute("fill", "none");
|
||||||
|
svg.setAttribute("stroke", purple);
|
||||||
|
svg.setAttribute("stroke-width", "2");
|
||||||
|
svg.setAttribute("stroke-linecap", "round");
|
||||||
|
svg.setAttribute("stroke-linejoin", "round");
|
||||||
|
svg.classList.add("icon");
|
||||||
|
|
||||||
|
const path1 = document.createElementNS(svgNS, "path");
|
||||||
|
path1.setAttribute("d", "M6 3h12l4 6-10 12L2 9z");
|
||||||
|
const path2 = document.createElementNS(svgNS, "path");
|
||||||
|
path2.setAttribute("d", "M11 3 8 9l4 12");
|
||||||
|
const path3 = document.createElementNS(svgNS, "path");
|
||||||
|
path3.setAttribute("d", "M12 21l4-12-3-6");
|
||||||
|
const path4 = document.createElementNS(svgNS, "path");
|
||||||
|
path4.setAttribute("d", "M2 9h20");
|
||||||
|
|
||||||
|
svg.appendChild(path1);
|
||||||
|
svg.appendChild(path2);
|
||||||
|
svg.appendChild(path3);
|
||||||
|
svg.appendChild(path4);
|
||||||
|
return svg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function makeBreadcrumbSpan(text, onClick) {
|
function makeBreadcrumbSpan(text, onClick) {
|
||||||
const s = document.createElement("span");
|
const s = document.createElement("span");
|
||||||
s.textContent = text;
|
s.textContent = text;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user