File size: 3,435 Bytes
8c3e275
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
from __future__ import annotations

import hashlib
from pathlib import Path


class Settings:
    def __init__(self) -> None:
        self._models_dir: Path | None = None
        self._grammars_dir: Path | None = None
        self._db_path: Path | None = None
        self._samples_dir: Path | None = None
        self._webhook_url: str | None = None
        self._webhook_secret: str | None = None

    @property
    def models_dir(self) -> Path:
        if self._models_dir is not None:
            return self._models_dir
        p = Path(__file__).resolve().parent.parent.parent / "models"
        if not p.exists():
            p = Path.cwd() / "models"
        return p

    @models_dir.setter
    def models_dir(self, value: Path) -> None:
        self._models_dir = value

    @property
    def grammars_dir(self) -> Path:
        if self._grammars_dir is not None:
            return self._grammars_dir
        p = Path(__file__).resolve().parent.parent.parent / "grammars"
        if not p.exists():
            p = Path.cwd() / "grammars"
        return p

    @grammars_dir.setter
    def grammars_dir(self, value: Path) -> None:
        self._grammars_dir = value

    @property
    def db_path(self) -> Path:
        if self._db_path is not None:
            return self._db_path
        return Path.cwd() / "pageparse.db"

    @db_path.setter
    def db_path(self, value: Path) -> None:
        self._db_path = value

    @property
    def samples_dir(self) -> Path:
        if self._samples_dir is not None:
            return self._samples_dir
        p = Path(__file__).resolve().parent.parent.parent / "samples"
        if not p.exists():
            p = Path.cwd() / "samples"
        return p

    @samples_dir.setter
    def samples_dir(self, value: Path) -> None:
        self._samples_dir = value

    @property
    def webhook_url(self) -> str | None:
        return self._webhook_url

    @webhook_url.setter
    def webhook_url(self, value: str) -> None:
        self._webhook_url = value

    @property
    def webhook_secret(self) -> str | None:
        return self._webhook_secret

    @webhook_secret.setter
    def webhook_secret(self, value: str) -> None:
        self._webhook_secret = value

    airgap: bool = False
    confidence_threshold: float = 0.5
    ollama_url: str = "http://localhost:11434"
    slm_model: str = "llama3.2:1b"
    vision_model: str = "moondream"
    ocr_model: str = "tr_ocr_base_handwritten.onnx"
    embedding_model: str = "all-MiniLM-L6-v2.onnx"
    whisper_model: str = "ggml-tiny.en-q5_0.bin"
    tts_enabled: bool = False
    auto_schema: bool = True
    diff_sync_enabled: bool = False
    max_workers: int = 4
    prometheus_enabled: bool = True
    tracing_enabled: bool = True

    def model_path(self, name: str) -> Path:
        return self.models_dir / name

    def grammar_path(self, name: str = "task.gbnf") -> Path:
        return self.grammars_dir / name

    def content_hash(self, content: bytes) -> str:
        return hashlib.sha256(content).hexdigest()

    def should_reprocess(self, source_id: int, content_hash: str) -> bool:
        if not self.diff_sync_enabled:
            return True
        from pageparse.store import Store
        store = Store()
        sources = store.list_sources()
        for s in sources:
            if s.get("content_hash") == content_hash:
                return False
        return True


settings = Settings()