diff --git a/appinfo/info.xml b/appinfo/info.xml
index 6bb2c1d..67c6c7d 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -37,6 +37,14 @@ Setup background job workers as described here: https://docs.nextcloud.com/serve
nextcloud/context_chat_backend
4.3.0
+
+
+ downloadLogs
+ GET
+ ADMIN
+ []
+
+
EXTERNAL_DB
diff --git a/context_chat_backend/controller.py b/context_chat_backend/controller.py
index a976e79..b84daab 100644
--- a/context_chat_backend/controller.py
+++ b/context_chat_backend/controller.py
@@ -12,7 +12,9 @@
import logging
import multiprocessing as mp
import os
+import tempfile
import threading
+import zipfile
from collections.abc import Callable
from contextlib import asynccontextmanager
from functools import wraps
@@ -25,6 +27,7 @@
from nc_py_api import AsyncNextcloudApp, NextcloudApp
from nc_py_api.ex_app import persistent_storage, set_handlers
from pydantic import BaseModel, ValidationInfo, field_validator
+from starlette.responses import FileResponse
from .chain.context import do_doc_search
from .chain.ingest.injest import embed_sources
@@ -492,3 +495,15 @@ def _(query: Query) -> list[SearchResult]:
query.scopeType,
query.scopeList,
))
+
+
+@app.get('/downloadLogs')
+def download_logs() -> FileResponse:
+ with tempfile.NamedTemporaryFile('wb', delete=False) as tmp:
+ with zipfile.ZipFile(tmp, mode='w', compression=zipfile.ZIP_DEFLATED) as zip_file:
+ files = os.listdir(os.path.join(persistent_storage(), 'logs'))
+ for file in files:
+ file_path = os.path.join(persistent_storage(), 'logs', file)
+ if os.path.isfile(file_path): # Might be a folder (just skip it then)
+ zip_file.write(file_path)
+ return FileResponse(tmp.name, media_type='application/zip', filename='docker_logs.zip')