mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-09-05 09:25:03 +00:00
Compare commits
10
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9df6e8c566 | ||
|
|
fb6438db81 | ||
|
|
804a4e2915 | ||
|
|
9daabe46f8 | ||
|
|
4be27e9994 | ||
|
|
9a30866fa9 | ||
|
|
07742d0329 | ||
|
|
305257c6cc | ||
|
|
0209117638 | ||
|
|
b574795a7a |
@@ -76,7 +76,7 @@ class TestApiAppConfig(DirectoriesMixin, APITestCase):
|
|||||||
"remote_ocr_api_key": None,
|
"remote_ocr_api_key": None,
|
||||||
"remote_ocr_endpoint": None,
|
"remote_ocr_endpoint": None,
|
||||||
"remote_ocr_mode": None,
|
"remote_ocr_mode": None,
|
||||||
"ai_enabled": False,
|
"ai_enabled": None,
|
||||||
"llm_embedding_backend": None,
|
"llm_embedding_backend": None,
|
||||||
"llm_embedding_model": None,
|
"llm_embedding_model": None,
|
||||||
"llm_embedding_endpoint": None,
|
"llm_embedding_endpoint": None,
|
||||||
@@ -949,6 +949,26 @@ class TestApiAppConfig(DirectoriesMixin, APITestCase):
|
|||||||
)
|
)
|
||||||
mock_update.assert_called_once()
|
mock_update.assert_called_once()
|
||||||
|
|
||||||
|
@override_settings(AI_ENABLED=True, LLM_EMBEDDING_BACKEND=None)
|
||||||
|
def test_external_ai_setting_triggers_index_update(self) -> None:
|
||||||
|
config = ApplicationConfiguration.objects.first()
|
||||||
|
assert config is not None
|
||||||
|
config.ai_enabled = None
|
||||||
|
config.llm_embedding_backend = None
|
||||||
|
config.save()
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch("documents.tasks.llmindex_index.apply_async") as mock_update,
|
||||||
|
patch("paperless.views.llm_index_exists", return_value=False),
|
||||||
|
):
|
||||||
|
self.client.patch(
|
||||||
|
f"{self.ENDPOINT}1/",
|
||||||
|
json.dumps({"llm_embedding_backend": "openai-like"}),
|
||||||
|
content_type="application/json",
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_update.assert_called_once()
|
||||||
|
|
||||||
def test_update_llm_embedding_chunk_size_triggers_rebuild(self) -> None:
|
def test_update_llm_embedding_chunk_size_triggers_rebuild(self) -> None:
|
||||||
config = ApplicationConfiguration.objects.first()
|
config = ApplicationConfiguration.objects.first()
|
||||||
assert config is not None
|
assert config is not None
|
||||||
|
|||||||
+21
-7
@@ -133,21 +133,27 @@ class BarcodeConfig(BaseConfig):
|
|||||||
app_config = self._get_config_instance()
|
app_config = self._get_config_instance()
|
||||||
|
|
||||||
self.barcodes_enabled = (
|
self.barcodes_enabled = (
|
||||||
app_config.barcodes_enabled or settings.CONSUMER_ENABLE_BARCODES
|
app_config.barcodes_enabled
|
||||||
|
if app_config.barcodes_enabled is not None
|
||||||
|
else settings.CONSUMER_ENABLE_BARCODES
|
||||||
)
|
)
|
||||||
self.barcode_enable_tiff_support = (
|
self.barcode_enable_tiff_support = (
|
||||||
app_config.barcode_enable_tiff_support
|
app_config.barcode_enable_tiff_support
|
||||||
or settings.CONSUMER_BARCODE_TIFF_SUPPORT
|
if app_config.barcode_enable_tiff_support is not None
|
||||||
|
else settings.CONSUMER_BARCODE_TIFF_SUPPORT
|
||||||
)
|
)
|
||||||
self.barcode_string = (
|
self.barcode_string = (
|
||||||
app_config.barcode_string or settings.CONSUMER_BARCODE_STRING
|
app_config.barcode_string or settings.CONSUMER_BARCODE_STRING
|
||||||
)
|
)
|
||||||
self.barcode_retain_split_pages = (
|
self.barcode_retain_split_pages = (
|
||||||
app_config.barcode_retain_split_pages
|
app_config.barcode_retain_split_pages
|
||||||
or settings.CONSUMER_BARCODE_RETAIN_SPLIT_PAGES
|
if app_config.barcode_retain_split_pages is not None
|
||||||
|
else settings.CONSUMER_BARCODE_RETAIN_SPLIT_PAGES
|
||||||
)
|
)
|
||||||
self.barcode_enable_asn = (
|
self.barcode_enable_asn = (
|
||||||
app_config.barcode_enable_asn or settings.CONSUMER_ENABLE_ASN_BARCODE
|
app_config.barcode_enable_asn
|
||||||
|
if app_config.barcode_enable_asn is not None
|
||||||
|
else settings.CONSUMER_ENABLE_ASN_BARCODE
|
||||||
)
|
)
|
||||||
self.barcode_asn_prefix = (
|
self.barcode_asn_prefix = (
|
||||||
app_config.barcode_asn_prefix or settings.CONSUMER_ASN_BARCODE_PREFIX
|
app_config.barcode_asn_prefix or settings.CONSUMER_ASN_BARCODE_PREFIX
|
||||||
@@ -160,13 +166,17 @@ class BarcodeConfig(BaseConfig):
|
|||||||
app_config.barcode_max_pages or settings.CONSUMER_BARCODE_MAX_PAGES
|
app_config.barcode_max_pages or settings.CONSUMER_BARCODE_MAX_PAGES
|
||||||
)
|
)
|
||||||
self.barcode_enable_tag = (
|
self.barcode_enable_tag = (
|
||||||
app_config.barcode_enable_tag or settings.CONSUMER_ENABLE_TAG_BARCODE
|
app_config.barcode_enable_tag
|
||||||
|
if app_config.barcode_enable_tag is not None
|
||||||
|
else settings.CONSUMER_ENABLE_TAG_BARCODE
|
||||||
)
|
)
|
||||||
self.barcode_tag_mapping = (
|
self.barcode_tag_mapping = (
|
||||||
app_config.barcode_tag_mapping or settings.CONSUMER_TAG_BARCODE_MAPPING
|
app_config.barcode_tag_mapping or settings.CONSUMER_TAG_BARCODE_MAPPING
|
||||||
)
|
)
|
||||||
self.barcode_tag_split = (
|
self.barcode_tag_split = (
|
||||||
app_config.barcode_tag_split or settings.CONSUMER_TAG_BARCODE_SPLIT
|
app_config.barcode_tag_split
|
||||||
|
if app_config.barcode_tag_split is not None
|
||||||
|
else settings.CONSUMER_TAG_BARCODE_SPLIT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -248,7 +258,11 @@ class AIConfig(BaseConfig):
|
|||||||
def __post_init__(self) -> None:
|
def __post_init__(self) -> None:
|
||||||
app_config = self._get_config_instance()
|
app_config = self._get_config_instance()
|
||||||
|
|
||||||
self.ai_enabled = app_config.ai_enabled or settings.AI_ENABLED
|
self.ai_enabled = (
|
||||||
|
app_config.ai_enabled
|
||||||
|
if app_config.ai_enabled is not None
|
||||||
|
else settings.AI_ENABLED
|
||||||
|
)
|
||||||
self.llm_embedding_backend = (
|
self.llm_embedding_backend = (
|
||||||
app_config.llm_embedding_backend or settings.LLM_EMBEDDING_BACKEND
|
app_config.llm_embedding_backend or settings.LLM_EMBEDDING_BACKEND
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
from django.db import migrations
|
||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_ai_enabled(apps, schema_editor):
|
||||||
|
application_configuration = apps.get_model(
|
||||||
|
"paperless",
|
||||||
|
"ApplicationConfiguration",
|
||||||
|
)
|
||||||
|
application_configuration.objects.filter(ai_enabled=False).update(ai_enabled=None)
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("paperless", "0015_applicationconfiguration_remote_ocr_mode"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="applicationconfiguration",
|
||||||
|
name="ai_enabled",
|
||||||
|
field=models.BooleanField(
|
||||||
|
null=True,
|
||||||
|
verbose_name="Enables AI features",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.RunPython(normalize_ai_enabled, migrations.RunPython.noop),
|
||||||
|
]
|
||||||
@@ -348,7 +348,6 @@ class ApplicationConfiguration(AbstractSingletonModel):
|
|||||||
ai_enabled = models.BooleanField(
|
ai_enabled = models.BooleanField(
|
||||||
verbose_name=_("Enables AI features"),
|
verbose_name=_("Enables AI features"),
|
||||||
null=True,
|
null=True,
|
||||||
default=False,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
llm_embedding_backend = models.CharField(
|
llm_embedding_backend = models.CharField(
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
from django.test import override_settings
|
||||||
|
|
||||||
|
from paperless.config import AIConfig
|
||||||
|
from paperless.config import BarcodeConfig
|
||||||
|
from paperless.models import ApplicationConfiguration
|
||||||
|
|
||||||
|
|
||||||
|
class TestBooleanConfigPrecedence(TestCase):
|
||||||
|
@override_settings(CONSUMER_ENABLE_BARCODES=True)
|
||||||
|
def test_database_false_overrides_barcode_environment_setting(self) -> None:
|
||||||
|
config, _ = ApplicationConfiguration.objects.get_or_create()
|
||||||
|
config.barcodes_enabled = False
|
||||||
|
config.save()
|
||||||
|
|
||||||
|
self.assertFalse(BarcodeConfig().barcodes_enabled)
|
||||||
|
|
||||||
|
@override_settings(AI_ENABLED=True)
|
||||||
|
def test_database_false_overrides_ai_environment_setting(self) -> None:
|
||||||
|
config, _ = ApplicationConfiguration.objects.get_or_create()
|
||||||
|
config.ai_enabled = False
|
||||||
|
config.save()
|
||||||
|
|
||||||
|
self.assertFalse(AIConfig().ai_enabled)
|
||||||
|
|
||||||
|
@override_settings(AI_ENABLED=True)
|
||||||
|
def test_null_ai_setting_uses_environment_setting(self) -> None:
|
||||||
|
config, _ = ApplicationConfiguration.objects.get_or_create()
|
||||||
|
config.ai_enabled = None
|
||||||
|
config.save()
|
||||||
|
|
||||||
|
self.assertTrue(AIConfig().ai_enabled)
|
||||||
@@ -443,8 +443,13 @@ class ApplicationConfigurationViewSet(ModelViewSet[ApplicationConfiguration]):
|
|||||||
new_llm_embedding_backend = (
|
new_llm_embedding_backend = (
|
||||||
new_instance.llm_embedding_backend or settings.LLM_EMBEDDING_BACKEND
|
new_instance.llm_embedding_backend or settings.LLM_EMBEDDING_BACKEND
|
||||||
)
|
)
|
||||||
|
new_ai_enabled = (
|
||||||
|
new_instance.ai_enabled
|
||||||
|
if new_instance.ai_enabled is not None
|
||||||
|
else settings.AI_ENABLED
|
||||||
|
)
|
||||||
new_ai_index_enabled = bool(
|
new_ai_index_enabled = bool(
|
||||||
new_instance.ai_enabled and new_llm_embedding_backend,
|
new_ai_enabled and new_llm_embedding_backend,
|
||||||
)
|
)
|
||||||
new_llm_embedding_chunk_size = (
|
new_llm_embedding_chunk_size = (
|
||||||
new_instance.llm_embedding_chunk_size or settings.LLM_EMBEDDING_CHUNK_SIZE
|
new_instance.llm_embedding_chunk_size or settings.LLM_EMBEDDING_CHUNK_SIZE
|
||||||
|
|||||||
Reference in New Issue
Block a user