Moving the settings to main paperless application
This commit is contained in:
248
src/paperless/migrations/0001_initial.py
Normal file
248
src/paperless/migrations/0001_initial.py
Normal file
@@ -0,0 +1,248 @@
|
||||
# Generated by Django 4.2.7 on 2023-12-14 17:12
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations
|
||||
from django.db import models
|
||||
|
||||
|
||||
def _create_singleton(apps, schema_editor):
|
||||
"""
|
||||
Creates the first and only instance of the settings models
|
||||
"""
|
||||
for model_name in ["CommonSettings", "OcrSettings", "TextSettings", "TikaSettings"]:
|
||||
settings_model = apps.get_model("paperless", model_name)
|
||||
settings_model.objects.create()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
initial = True
|
||||
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="CommonSettings",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"output_type",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("pdf", "pdf"),
|
||||
("pdfa", "pdfa"),
|
||||
("pdfa-1", "pdfa-1"),
|
||||
("pdfa-2", "pdfa-2"),
|
||||
("pdfa-3", "pdfa-3"),
|
||||
],
|
||||
max_length=8,
|
||||
null=True,
|
||||
verbose_name="Sets the output PDF type",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="OcrSettings",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"pages",
|
||||
models.PositiveIntegerField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name="Do OCR from page 1 to this value",
|
||||
),
|
||||
),
|
||||
(
|
||||
"language",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="Do OCR using these languages",
|
||||
),
|
||||
),
|
||||
(
|
||||
"mode",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("skip", "skip"),
|
||||
("skip_noarchive", "skip_noarchive"),
|
||||
("redo", "redo"),
|
||||
("force", "force"),
|
||||
],
|
||||
max_length=8,
|
||||
null=True,
|
||||
verbose_name="Sets the OCR mode",
|
||||
),
|
||||
),
|
||||
(
|
||||
"skip_archive_file",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("never", "never"),
|
||||
("with_text", "with_text"),
|
||||
("always", "always"),
|
||||
],
|
||||
max_length=16,
|
||||
null=True,
|
||||
verbose_name="Controls the generation of an archive file",
|
||||
),
|
||||
),
|
||||
(
|
||||
"image_dpi",
|
||||
models.PositiveIntegerField(
|
||||
null=True,
|
||||
verbose_name="Sets image DPI fallback value",
|
||||
),
|
||||
),
|
||||
(
|
||||
"unpaper_clean",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("clean", "clean"),
|
||||
("clean-final", "clean-final"),
|
||||
("none", "none"),
|
||||
],
|
||||
max_length=16,
|
||||
null=True,
|
||||
verbose_name="Controls the unpaper cleaning",
|
||||
),
|
||||
),
|
||||
(
|
||||
"deskew",
|
||||
models.BooleanField(null=True, verbose_name="Enables deskew"),
|
||||
),
|
||||
(
|
||||
"rotate_pages",
|
||||
models.BooleanField(
|
||||
null=True,
|
||||
verbose_name="Enables page rotation",
|
||||
),
|
||||
),
|
||||
(
|
||||
"rotate_pages_threshold",
|
||||
models.FloatField(
|
||||
null=True,
|
||||
validators=[django.core.validators.MinValueValidator(0.0)],
|
||||
verbose_name="Sets the threshold for rotation of pages",
|
||||
),
|
||||
),
|
||||
(
|
||||
"max_image_pixels",
|
||||
models.FloatField(
|
||||
null=True,
|
||||
validators=[
|
||||
django.core.validators.MinValueValidator(1000000.0),
|
||||
],
|
||||
verbose_name="Sets the maximum image size for decompression",
|
||||
),
|
||||
),
|
||||
(
|
||||
"color_conversion_strategy",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
choices=[
|
||||
("LeaveColorUnchanged", "LeaveColorUnchanged"),
|
||||
("RGB", "RGB"),
|
||||
("UseDeviceIndependentColor", "UseDeviceIndependentColor"),
|
||||
("Gray", "Gray"),
|
||||
("CMYK", "CMYK"),
|
||||
],
|
||||
max_length=32,
|
||||
null=True,
|
||||
verbose_name="Sets the Ghostscript color conversion strategy",
|
||||
),
|
||||
),
|
||||
(
|
||||
"user_args",
|
||||
models.JSONField(
|
||||
null=True,
|
||||
verbose_name="Adds additional user arguments for OCRMyPDF",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "ocr settings",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="TextSettings",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"thumbnail_font_name",
|
||||
models.CharField(
|
||||
blank=True,
|
||||
max_length=64,
|
||||
null=True,
|
||||
verbose_name="Sets the output PDF type",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="TikaSettings",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
(
|
||||
"tika_url",
|
||||
models.URLField(blank=True, null=True, verbose_name="Tika URL"),
|
||||
),
|
||||
(
|
||||
"gotenberg_url",
|
||||
models.URLField(
|
||||
blank=True,
|
||||
null=True,
|
||||
verbose_name="Gotenberg URL",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"abstract": False,
|
||||
},
|
||||
),
|
||||
migrations.RunPython(_create_singleton, migrations.RunPython.noop),
|
||||
]
|
||||
0
src/paperless/migrations/__init__.py
Normal file
0
src/paperless/migrations/__init__.py
Normal file
178
src/paperless/models.py
Normal file
178
src/paperless/models.py
Normal file
@@ -0,0 +1,178 @@
|
||||
from django.core.validators import MinValueValidator
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
DEFAULT_SINGLETON_INSTANCE_ID = 1
|
||||
|
||||
|
||||
class AbstractSingletonModel(models.Model):
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
"""
|
||||
Always save as the first and only model
|
||||
"""
|
||||
self.pk = DEFAULT_SINGLETON_INSTANCE_ID
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
|
||||
class CommonSettings(AbstractSingletonModel):
|
||||
"""
|
||||
Settings which are common across more than 1 parser
|
||||
"""
|
||||
|
||||
class OutputTypeChoices(models.TextChoices):
|
||||
PDF = ("pdf", _("pdf"))
|
||||
PDF_A = ("pdfa", _("pdfa"))
|
||||
PDF_A1 = ("pdfa-1", _("pdfa-1"))
|
||||
PDF_A2 = ("pdfa-2", _("pdfa-2"))
|
||||
PDF_A3 = ("pdfa-3", _("pdfa-3"))
|
||||
|
||||
output_type = models.CharField(
|
||||
verbose_name=_("Sets the output PDF type"),
|
||||
null=True,
|
||||
blank=True,
|
||||
max_length=8,
|
||||
choices=OutputTypeChoices.choices,
|
||||
)
|
||||
|
||||
|
||||
class OcrSettings(AbstractSingletonModel):
|
||||
"""
|
||||
Settings for the Tesseract based OCR parser
|
||||
"""
|
||||
|
||||
class ModeChoices(models.TextChoices):
|
||||
SKIP = ("skip", _("skip"))
|
||||
SKIP_NO_ARCHIVE = ("skip_noarchive", _("skip_noarchive"))
|
||||
REDO = ("redo", _("redo"))
|
||||
FORCE = ("force", _("force"))
|
||||
|
||||
class ArchiveFileChoices(models.TextChoices):
|
||||
NEVER = ("never", _("never"))
|
||||
WITH_TEXT = ("with_text", _("with_text"))
|
||||
ALWAYS = ("always", _("always"))
|
||||
|
||||
class CleanChoices(models.TextChoices):
|
||||
CLEAN = ("clean", _("clean"))
|
||||
FINAL = ("clean-final", _("clean-final"))
|
||||
NONE = ("none", _("none"))
|
||||
|
||||
class ColorConvertChoices(models.TextChoices):
|
||||
UNCHANGED = ("LeaveColorUnchanged", _("LeaveColorUnchanged"))
|
||||
RGB = ("RGB", _("RGB"))
|
||||
INDEPENDENT = ("UseDeviceIndependentColor", _("UseDeviceIndependentColor"))
|
||||
GRAY = ("Gray", _("Gray"))
|
||||
CMYK = ("CMYK", _("CMYK"))
|
||||
|
||||
pages = models.PositiveIntegerField(
|
||||
verbose_name=_("Do OCR from page 1 to this value"),
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
|
||||
language = models.CharField(
|
||||
verbose_name=_("Do OCR using these languages"),
|
||||
null=True,
|
||||
blank=True,
|
||||
max_length=32,
|
||||
)
|
||||
|
||||
mode = models.CharField(
|
||||
verbose_name=_("Sets the OCR mode"),
|
||||
null=True,
|
||||
blank=True,
|
||||
max_length=8,
|
||||
choices=ModeChoices.choices,
|
||||
)
|
||||
|
||||
skip_archive_file = models.CharField(
|
||||
verbose_name=_("Controls the generation of an archive file"),
|
||||
null=True,
|
||||
blank=True,
|
||||
max_length=16,
|
||||
choices=ArchiveFileChoices.choices,
|
||||
)
|
||||
|
||||
image_dpi = models.PositiveIntegerField(
|
||||
verbose_name=_("Sets image DPI fallback value"),
|
||||
null=True,
|
||||
)
|
||||
|
||||
# Can't call it clean, that's a model method
|
||||
unpaper_clean = models.CharField(
|
||||
verbose_name=_("Controls the unpaper cleaning"),
|
||||
null=True,
|
||||
blank=True,
|
||||
max_length=16,
|
||||
choices=CleanChoices.choices,
|
||||
)
|
||||
|
||||
deskew = models.BooleanField(verbose_name=_("Enables deskew"), null=True)
|
||||
|
||||
rotate_pages = models.BooleanField(
|
||||
verbose_name=_("Enables page rotation"),
|
||||
null=True,
|
||||
)
|
||||
|
||||
rotate_pages_threshold = models.FloatField(
|
||||
verbose_name=_("Sets the threshold for rotation of pages"),
|
||||
null=True,
|
||||
validators=[MinValueValidator(0.0)],
|
||||
)
|
||||
|
||||
max_image_pixels = models.FloatField(
|
||||
verbose_name=_("Sets the maximum image size for decompression"),
|
||||
null=True,
|
||||
validators=[MinValueValidator(1_000_000.0)],
|
||||
)
|
||||
|
||||
color_conversion_strategy = models.CharField(
|
||||
verbose_name=_("Sets the Ghostscript color conversion strategy"),
|
||||
blank=True,
|
||||
null=True,
|
||||
max_length=32,
|
||||
choices=ColorConvertChoices.choices,
|
||||
)
|
||||
|
||||
user_args = models.JSONField(
|
||||
verbose_name=_("Adds additional user arguments for OCRMyPDF"),
|
||||
null=True,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("ocr settings")
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "OcrSettings"
|
||||
|
||||
|
||||
class TextSettings(AbstractSingletonModel):
|
||||
"""
|
||||
Settings for the text parser
|
||||
"""
|
||||
|
||||
thumbnail_font_name = models.CharField(
|
||||
verbose_name=_("Sets the output PDF type"),
|
||||
null=True,
|
||||
blank=True,
|
||||
max_length=64,
|
||||
)
|
||||
|
||||
|
||||
class TikaSettings(AbstractSingletonModel):
|
||||
"""
|
||||
Settings for the Tika parser
|
||||
"""
|
||||
|
||||
tika_url = models.URLField(
|
||||
verbose_name=_("Tika URL"),
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
gotenberg_url = models.URLField(
|
||||
verbose_name=_("Gotenberg URL"),
|
||||
null=True,
|
||||
blank=True,
|
||||
)
|
||||
@@ -3,6 +3,8 @@ from django.contrib.auth.models import Permission
|
||||
from django.contrib.auth.models import User
|
||||
from rest_framework import serializers
|
||||
|
||||
from paperless.models import OcrSettings
|
||||
|
||||
|
||||
class ObfuscatedUserPasswordField(serializers.Field):
|
||||
"""
|
||||
@@ -113,3 +115,9 @@ class ProfileSerializer(serializers.ModelSerializer):
|
||||
"last_name",
|
||||
"auth_token",
|
||||
)
|
||||
|
||||
|
||||
class OcrSettingsSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = OcrSettings
|
||||
fields = ["all"]
|
||||
|
||||
@@ -18,7 +18,9 @@ from rest_framework.viewsets import ModelViewSet
|
||||
from documents.permissions import PaperlessObjectPermissions
|
||||
from paperless.filters import GroupFilterSet
|
||||
from paperless.filters import UserFilterSet
|
||||
from paperless.models import OcrSettings
|
||||
from paperless.serialisers import GroupSerializer
|
||||
from paperless.serialisers import OcrSettingsSerializer
|
||||
from paperless.serialisers import ProfileSerializer
|
||||
from paperless.serialisers import UserSerializer
|
||||
|
||||
@@ -160,3 +162,12 @@ class GenerateAuthTokenView(GenericAPIView):
|
||||
return Response(
|
||||
token.key,
|
||||
)
|
||||
|
||||
|
||||
class OcrSettingsViewSet(ModelViewSet):
|
||||
model = OcrSettings
|
||||
|
||||
queryset = OcrSettings.objects
|
||||
|
||||
serializer_class = OcrSettingsSerializer
|
||||
permission_classes = (IsAuthenticated,)
|
||||
|
||||
Reference in New Issue
Block a user