forked from retoor/devplacepy
chore: consolidate runtime data layout under single data/ root directory
Migrate all runtime artifacts (database, uploads, VAPID keys, locks, bot state, container workspaces, zip staging) from scattered locations (`var/`, `devplacepy/static/uploads/`) into a unified `data/` directory. Update `config.py` as single source of truth with `DATA_PATHS` registry and `ensure_data_dirs()`, add `devplace migrate-data` CLI command with CRC verification and idempotent relocation, adjust `.dockerignore`, `.env.example`, `.gitignore`, `Dockerfile`, `Makefile`, `README.md`, `AGENTS.md`, `CLAUDE.md`, and all import paths in `attachments.py` to reference `config.UPLOADS_DIR`/`ATTACHMENTS_DIR` instead of computing from `STATIC_DIR`.
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
# retoor <retoor@molodetz.nl>
|
||||
|
||||
import random
|
||||
from pathlib import Path
|
||||
|
||||
from devplacepy.config import INTERNAL_GATEWAY_URL, INTERNAL_MODEL
|
||||
from devplacepy.config import INTERNAL_GATEWAY_URL, INTERNAL_MODEL, BOT_DIR
|
||||
|
||||
BASE_URL_DEFAULT = "https://pravda.education"
|
||||
API_URL_DEFAULT = INTERNAL_GATEWAY_URL
|
||||
@@ -15,8 +14,8 @@ OUTPUT_COST_PER_1M_DEFAULT = 1.10
|
||||
COST_WINDOW_SECONDS = 600
|
||||
COST_WARMUP_SECONDS = 120
|
||||
|
||||
STATE_DIR = Path.home() / ".devplace_bots"
|
||||
ARTICLE_REGISTRY_PATH = Path.home() / ".dpbot_article_registry.json"
|
||||
STATE_DIR = BOT_DIR
|
||||
ARTICLE_REGISTRY_PATH = BOT_DIR / "article_registry.json"
|
||||
|
||||
PROJECT_STATUSES = ["In Development", "Released"]
|
||||
|
||||
|
||||
@@ -6,7 +6,12 @@ import os
|
||||
import uuid
|
||||
from dataclasses import dataclass
|
||||
|
||||
from devplacepy.config import INTERNAL_GATEWAY_URL, INTERNAL_MODEL
|
||||
from devplacepy.config import (
|
||||
INTERNAL_GATEWAY_URL,
|
||||
INTERNAL_MODEL,
|
||||
DEVII_TASKS_DB,
|
||||
DEVII_LESSONS_DB,
|
||||
)
|
||||
|
||||
|
||||
DEFAULT_AI_URL = INTERNAL_GATEWAY_URL
|
||||
@@ -100,9 +105,9 @@ def load_settings() -> Settings:
|
||||
),
|
||||
log_level=os.environ.get("DEVII_LOG_LEVEL", "WARNING").upper(),
|
||||
log_path=os.environ.get("DEVII_LOG_PATH", "devii.log"),
|
||||
tasks_db_path=os.environ.get("DEVII_TASKS_DB", "devii_tasks.db"),
|
||||
tasks_db_path=os.environ.get("DEVII_TASKS_DB", str(DEVII_TASKS_DB)),
|
||||
scheduler_tick_seconds=float(os.environ.get("DEVII_SCHEDULER_TICK", "1.0")),
|
||||
lessons_db_path=os.environ.get("DEVII_LESSONS_DB", "devii_lessons.db"),
|
||||
lessons_db_path=os.environ.get("DEVII_LESSONS_DB", str(DEVII_LESSONS_DB)),
|
||||
delegate_max_iterations=int(
|
||||
os.environ.get(
|
||||
"DEVII_DELEGATE_MAX_ITERATIONS", DEFAULT_DELEGATE_MAX_ITERATIONS
|
||||
@@ -172,7 +177,7 @@ FIELD_RSEARCH_ENABLED = "devii_rsearch_enabled"
|
||||
FIELD_RSEARCH_URL = "devii_rsearch_url"
|
||||
FIELD_RSEARCH_TIMEOUT = "devii_rsearch_timeout"
|
||||
|
||||
LESSONS_DB_PATH = os.environ.get("DEVII_LESSONS_DB", "devii_lessons.db")
|
||||
LESSONS_DB_PATH = os.environ.get("DEVII_LESSONS_DB", str(DEVII_LESSONS_DB))
|
||||
|
||||
|
||||
def effective_daily_limit(
|
||||
|
||||
@@ -4,7 +4,7 @@ import asyncio
|
||||
import logging
|
||||
import shutil
|
||||
|
||||
from devplacepy.config import DATA_DIR
|
||||
from devplacepy.config import FORK_STAGING_DIR
|
||||
from devplacepy import project_files
|
||||
from devplacepy.content import create_content_item
|
||||
from devplacepy.database import get_table, record_fork, delete_fork_relations
|
||||
@@ -13,8 +13,6 @@ from devplacepy.utils import XP_PROJECT
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
STAGING_DIR = DATA_DIR / "fork_staging"
|
||||
|
||||
|
||||
class ForkService(JobService):
|
||||
kind = "fork"
|
||||
@@ -115,7 +113,7 @@ class ForkService(JobService):
|
||||
def _copy_files(
|
||||
self, source_uid: str, new_uid: str, user: dict, job_uid: str
|
||||
) -> int:
|
||||
staging = STAGING_DIR / job_uid
|
||||
staging = FORK_STAGING_DIR / job_uid
|
||||
try:
|
||||
project_files.export_to_dir(source_uid, "", staging)
|
||||
return project_files.import_from_dir(
|
||||
@@ -133,4 +131,4 @@ class ForkService(JobService):
|
||||
logger.exception("fork rollback failed for %s", new_uid)
|
||||
|
||||
def cleanup(self, job: dict) -> None:
|
||||
shutil.rmtree(STAGING_DIR / job["uid"], ignore_errors=True)
|
||||
shutil.rmtree(FORK_STAGING_DIR / job["uid"], ignore_errors=True)
|
||||
|
||||
@@ -7,15 +7,13 @@ import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from devplacepy.config import BASE_DIR, DATA_DIR
|
||||
from devplacepy.config import BASE_DIR, ZIPS_DIR, ZIP_STAGING_DIR
|
||||
from devplacepy import project_files
|
||||
from devplacepy.services.jobs.base import JobService
|
||||
from devplacepy.utils import generate_uid, slugify
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
ZIPS_DIR = DATA_DIR / "zips"
|
||||
STAGING_DIR = DATA_DIR / "zip_staging"
|
||||
WORKER_MODULE = "devplacepy.services.jobs.zip_worker"
|
||||
|
||||
|
||||
@@ -40,7 +38,7 @@ class ZipService(JobService):
|
||||
|
||||
source = job["payload"].get("source", {})
|
||||
uid = job["uid"]
|
||||
staging = STAGING_DIR / uid
|
||||
staging = ZIP_STAGING_DIR / uid
|
||||
project_uid = source.get("project_uid", "")
|
||||
fail_meta = {"project_uid": project_uid}
|
||||
try:
|
||||
@@ -131,4 +129,4 @@ class ZipService(JobService):
|
||||
local_path = result.get("local_path")
|
||||
if local_path:
|
||||
Path(local_path).unlink(missing_ok=True)
|
||||
shutil.rmtree(STAGING_DIR / job["uid"], ignore_errors=True)
|
||||
shutil.rmtree(ZIP_STAGING_DIR / job["uid"], ignore_errors=True)
|
||||
|
||||
Reference in New Issue
Block a user