Compare commits

..

No commits in common. "f4413e0a08ce1878a6099fce6db78ff3d6619f14" and "955ff32dcd677dd57bfabdd04a99af29d94bd216" have entirely different histories.

19 changed files with 127 additions and 209 deletions

View File

@ -89,50 +89,3 @@ updates:
- "major"
- "minor"
- "patch"
# Update Dockerfile in root directory
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
reviewers:
- "paperless-ngx/ci-cd"
labels:
- "ci-cd"
- "dependencies"
commit-message:
prefix: "docker"
include: "scope"
# Update Docker Compose files in docker/compose directory
- package-ecosystem: "docker-compose"
directory: "/docker/compose/"
schedule:
interval: "weekly"
open-pull-requests-limit: 5
reviewers:
- "paperless-ngx/ci-cd"
labels:
- "ci-cd"
- "dependencies"
commit-message:
prefix: "docker-compose"
include: "scope"
groups:
# Individual groups for each image
gotenberg:
patterns:
- "docker.io/gotenberg/gotenberg*"
tika:
patterns:
- "docker.io/apache/tika*"
redis:
patterns:
- "docker.io/library/redis*"
mariadb:
patterns:
- "docker.io/library/mariadb*"
postgres:
patterns:
- "docker.io/library/postgres*"

View File

@ -30,7 +30,7 @@ RUN set -eux \
# Purpose: Installs s6-overlay and rootfs
# Comments:
# - Don't leave anything extra in here either
FROM ghcr.io/astral-sh/uv:0.6.5-python3.12-bookworm-slim AS s6-overlay-base
FROM ghcr.io/astral-sh/uv:0.6.3-python3.12-bookworm-slim AS s6-overlay-base
WORKDIR /usr/src/s6

View File

@ -38,7 +38,7 @@ services:
- redisdata:/data
db:
image: docker.io/library/postgres:17
image: docker.io/library/postgres:16
restart: unless-stopped
volumes:
- pgdata:/var/lib/postgresql/data

View File

@ -38,7 +38,7 @@ services:
- redisdata:/data
db:
image: docker.io/library/postgres:17
image: docker.io/library/postgres:16
restart: unless-stopped
volumes:
- pgdata:/var/lib/postgresql/data

View File

@ -34,7 +34,7 @@ services:
- redisdata:/data
db:
image: docker.io/library/postgres:17
image: docker.io/library/postgres:16
restart: unless-stopped
volumes:
- pgdata:/var/lib/postgresql/data

View File

@ -37,7 +37,7 @@ dependencies = [
"djangorestframework~=3.15",
"djangorestframework-guardian~=0.3.0",
"drf-spectacular~=0.28",
"drf-spectacular-sidecar~=2025.3.1",
"drf-spectacular-sidecar~=2025.2.1",
"drf-writable-nested~=0.7.1",
"filelock~=3.17.0",
"flower~=2.0.1",
@ -48,7 +48,7 @@ dependencies = [
"jinja2~=3.1.5",
"langdetect~=1.0.9",
"nltk~=3.9.1",
"ocrmypdf~=16.10.0",
"ocrmypdf~=16.9.0",
"pathvalidate~=3.2.3",
"pdf2image~=1.17.0",
"python-dateutil~=2.9.0",
@ -73,9 +73,9 @@ optional-dependencies.mariadb = [
"mysqlclient~=2.2.7",
]
optional-dependencies.postgres = [
"psycopg[c]==3.2.5",
"psycopg[c]==3.2.4",
# Direct dependency for proper resolution of the pre-built wheels
"psycopg-c==3.2.5",
"psycopg-c==3.2.4",
]
optional-dependencies.webserver = [
"granian~=1.7.6",
@ -343,8 +343,8 @@ environments = [
[tool.uv.sources]
# Markers are chosen to select these almost exclusively when building the Docker image
psycopg-c = [
{ url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_x86_64.whl", marker = "sys_platform == 'linux' and platform_machine == 'x86_64' and python_version == '3.12'" },
{ url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_aarch64.whl", marker = "sys_platform == 'linux' and platform_machine == 'aarch64' and python_version == '3.12'" },
{ url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_x86_64.whl", marker = "sys_platform == 'linux' and platform_machine == 'x86_64' and python_version == '3.12'" },
{ url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_aarch64.whl", marker = "sys_platform == 'linux' and platform_machine == 'aarch64' and python_version == '3.12'" },
]
zxing-cpp = [
{ url = "https://github.com/paperless-ngx/builder/releases/download/zxing-2.3.0/zxing_cpp-2.3.0-cp312-cp312-linux_x86_64.whl", marker = "sys_platform == 'linux' and platform_machine == 'x86_64' and python_version == '3.12'" },

View File

@ -6185,39 +6185,32 @@
<context context-type="linenumber">43</context>
</context-group>
</trans-unit>
<trans-unit id="4524189418954028091" datatype="html">
<source>Hint: saved views can be created from the <x id="START_LINK" ctype="x-a" equiv-text="&lt;a routerLink=&quot;/documents&quot;&gt;"/>documents list<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/dashboard.component.html</context>
<context context-type="linenumber">42</context>
</context-group>
</trans-unit>
<trans-unit id="6581372518205328477" datatype="html">
<source>Hello <x id="PH" equiv-text="this.settingsService.displayName"/>, welcome to <x id="PH_1" equiv-text="environment.appTitle"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/dashboard.component.ts</context>
<context context-type="linenumber">61</context>
<context context-type="linenumber">57</context>
</context-group>
</trans-unit>
<trans-unit id="2901300640157872718" datatype="html">
<source>Welcome to <x id="PH" equiv-text="environment.appTitle"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/dashboard.component.ts</context>
<context context-type="linenumber">63</context>
<context context-type="linenumber">59</context>
</context-group>
</trans-unit>
<trans-unit id="1325877348738783391" datatype="html">
<source>Dashboard updated</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/dashboard.component.ts</context>
<context context-type="linenumber">94</context>
<context context-type="linenumber">90</context>
</context-group>
</trans-unit>
<trans-unit id="3214475953924351473" datatype="html">
<source>Error updating dashboard</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/dashboard/dashboard.component.ts</context>
<context context-type="linenumber">97</context>
<context context-type="linenumber">93</context>
</context-group>
</trans-unit>
<trans-unit id="2946624699882754313" datatype="html">

View File

@ -34,17 +34,6 @@
}
<ng-container *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.SavedView }">
@if (!settingsService.offerTour() && savedViewService.allViews.length === 0) {
<div class="col">
<div class="card shadow-sm bg-light opacity-50">
<div class="card-body">
<div class="text-center">
<p class="mb-0 fst-italic"><i-bs name="info-circle" class="me-2"></i-bs><ng-container i18n>Hint: saved views can be created from the <a routerLink="/documents">documents list</a></ng-container></p>
</div>
</div>
</div>
</div>
}
@for (v of dashboardViews; track v.id) {
<div class="col">
<pngx-saved-view-widget

View File

@ -105,7 +105,6 @@ describe('DashboardComponent', () => {
results: saved_views,
}),
dashboardViews: saved_views.filter((v) => v.show_on_dashboard),
allViews: saved_views,
},
},
provideHttpClient(withInterceptorsFromDi()),

View File

@ -6,8 +6,6 @@ import {
moveItemInArray,
} from '@angular/cdk/drag-drop'
import { Component } from '@angular/core'
import { RouterModule } from '@angular/router'
import { NgxBootstrapIconsModule } from 'ngx-bootstrap-icons'
import { TourNgBootstrapModule, TourService } from 'ngx-ui-tour-ng-bootstrap'
import { SavedView } from 'src/app/data/saved-view'
import { IfPermissionsDirective } from 'src/app/directives/if-permissions.directive'
@ -37,8 +35,6 @@ import { WelcomeWidgetComponent } from './widgets/welcome-widget/welcome-widget.
IfPermissionsDirective,
DragDropModule,
TourNgBootstrapModule,
NgxBootstrapIconsModule,
RouterModule,
],
})
export class DashboardComponent extends ComponentWithPermissions {

View File

@ -45,8 +45,7 @@ describe('CustomDatePipe', () => {
if (now.getMonth() === 0) {
notNow.setFullYear(now.getFullYear() - 1)
}
// weird options are for february...
expect(['Last month', '4 weeks ago', '3 weeks ago']).toContain(
expect(['Last month', '4 weeks ago']).toContain(
datePipe.transform(notNow, 'relative')
)
expect(datePipe.transform(now, 'relative')).toEqual('Just now')

View File

@ -294,9 +294,9 @@ class Command(BaseCommand):
inotify = INotify()
inotify_flags = flags.CLOSE_WRITE | flags.MOVED_TO | flags.MODIFY
if recursive:
inotify.add_watch_recursive(directory, inotify_flags)
descriptor = inotify.add_watch_recursive(directory, inotify_flags)
else:
inotify.add_watch(directory, inotify_flags)
descriptor = inotify.add_watch(directory, inotify_flags)
inotify_debounce_secs: Final[float] = settings.CONSUMER_INOTIFY_DELAY
inotify_debounce_ms: Final[int] = inotify_debounce_secs * 1000
@ -305,55 +305,55 @@ class Command(BaseCommand):
notified_files = {}
try:
while not finished:
try:
for event in inotify.read(timeout=timeout_ms):
path = inotify.get_path(event.wd) if recursive else directory
filepath = os.path.join(path, event.name)
if flags.MODIFY in flags.from_mask(event.mask):
notified_files.pop(filepath, None)
else:
notified_files[filepath] = monotonic()
# Check the files against the timeout
still_waiting = {}
# last_event_time is time of the last inotify event for this file
for filepath, last_event_time in notified_files.items():
# Current time - last time over the configured timeout
waited_long_enough = (
monotonic() - last_event_time
) > inotify_debounce_secs
# Also make sure the file exists still, some scanners might write a
# temporary file first
file_still_exists = os.path.exists(filepath) and os.path.isfile(
filepath,
)
if waited_long_enough and file_still_exists:
_consume(filepath)
elif file_still_exists:
still_waiting[filepath] = last_event_time
# These files are still waiting to hit the timeout
notified_files = still_waiting
# If files are waiting, need to exit read() to check them
# Otherwise, go back to infinite sleep time, but only if not testing
if len(notified_files) > 0:
timeout_ms = inotify_debounce_ms
elif is_testing:
timeout_ms = self.testing_timeout_ms
while not finished:
try:
for event in inotify.read(timeout=timeout_ms):
path = inotify.get_path(event.wd) if recursive else directory
filepath = os.path.join(path, event.name)
if flags.MODIFY in flags.from_mask(event.mask):
notified_files.pop(filepath, None)
else:
timeout_ms = None
notified_files[filepath] = monotonic()
if self.stop_flag.is_set():
logger.debug("Finishing because event is set")
finished = True
# Check the files against the timeout
still_waiting = {}
# last_event_time is time of the last inotify event for this file
for filepath, last_event_time in notified_files.items():
# Current time - last time over the configured timeout
waited_long_enough = (
monotonic() - last_event_time
) > inotify_debounce_secs
except KeyboardInterrupt:
logger.info("Received SIGINT, stopping inotify")
# Also make sure the file exists still, some scanners might write a
# temporary file first
file_still_exists = os.path.exists(filepath) and os.path.isfile(
filepath,
)
if waited_long_enough and file_still_exists:
_consume(filepath)
elif file_still_exists:
still_waiting[filepath] = last_event_time
# These files are still waiting to hit the timeout
notified_files = still_waiting
# If files are waiting, need to exit read() to check them
# Otherwise, go back to infinite sleep time, but only if not testing
if len(notified_files) > 0:
timeout_ms = inotify_debounce_ms
elif is_testing:
timeout_ms = self.testing_timeout_ms
else:
timeout_ms = None
if self.stop_flag.is_set():
logger.debug("Finishing because event is set")
finished = True
finally:
inotify.close()
except KeyboardInterrupt:
logger.info("Received SIGINT, stopping inotify")
finished = True
inotify.rm_watch(descriptor)
inotify.close()

View File

@ -43,7 +43,6 @@ from documents.models import CustomFieldInstance
from documents.models import Document
from documents.models import DocumentType
from documents.models import MatchingModel
from documents.models import Note
from documents.models import PaperlessTask
from documents.models import SavedView
from documents.models import SavedViewFilterRule
@ -862,22 +861,6 @@ class CustomFieldInstanceSerializer(serializers.ModelSerializer):
]
class BasicUserSerializer(serializers.ModelSerializer):
# Different than paperless.serializers.UserSerializer
class Meta:
model = User
fields = ["id", "username", "first_name", "last_name"]
class NotesSerializer(serializers.ModelSerializer):
user = BasicUserSerializer()
class Meta:
model = Note
fields = ["id", "note", "created", "user"]
ordering = ["-created"]
class DocumentSerializer(
OwnedObjectSerializer,
NestedUpdateMixin,
@ -893,8 +876,6 @@ class DocumentSerializer(
created_date = serializers.DateField(required=False)
page_count = SerializerMethodField()
notes = NotesSerializer(many=True, required=False)
custom_fields = CustomFieldInstanceSerializer(
many=True,
allow_null=False,

View File

@ -6,7 +6,7 @@
{% endblock head_title %}
{% block form_top_content %}
<h4>{% translate "Account inactive." %}</h4>
<h4>{% translate "Account inactve." %}</h4>
{% endblock form_top_content %}
{% block form_content %}

View File

@ -2170,10 +2170,8 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
GIVEN:
- A document with a single note
WHEN:
- API request for document
- API request for document notes is made
THEN:
- Note is included in the document response
- The associated note is returned
"""
doc = Document.objects.create(
@ -2187,18 +2185,6 @@ class TestDocumentApi(DirectoriesMixin, DocumentConsumeDelayMixin, APITestCase):
user=self.user,
)
response = self.client.get(
f"/api/documents/{doc.pk}/",
format="json",
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
resp_data = response.json()
self.assertEqual(len(resp_data["notes"]), 1)
self.assertEqual(resp_data["notes"][0]["note"], note.note)
self.assertEqual(resp_data["notes"][0]["user"]["username"], self.user.username)
response = self.client.get(
f"/api/documents/{doc.pk}/notes/",
format="json",

View File

@ -4,7 +4,6 @@ from pathlib import Path
from django.conf import settings
from documents.tests.utils import DirectoriesMixin
from documents.tests.utils import TestMigrations
@ -15,7 +14,7 @@ def source_path_before(self):
return os.path.join(settings.ORIGINALS_DIR, fname)
class TestMigrateDocumentPageCount(DirectoriesMixin, TestMigrations):
class TestMigrateDocumentPageCount(TestMigrations):
migrate_from = "1052_document_transaction_id"
migrate_to = "1053_document_page_count"

View File

@ -803,6 +803,33 @@ class DocumentViewSet(
except (FileNotFoundError, Document.DoesNotExist):
raise Http404
def getNotes(self, doc):
return [
{
"id": c.pk,
"note": c.note,
"created": c.created,
"user": {
"id": c.user.id,
"username": c.user.username,
"first_name": c.user.first_name,
"last_name": c.user.last_name,
},
}
for c in Note.objects.select_related("user")
.only(
"pk",
"note",
"created",
"user__id",
"user__username",
"user__first_name",
"user__last_name",
)
.filter(document=doc)
.order_by("-created")
]
@action(
methods=["get", "post", "delete"],
detail=True,
@ -827,11 +854,9 @@ class DocumentViewSet(
except Document.DoesNotExist:
raise Http404
serializer = self.get_serializer(doc)
if request.method == "GET":
try:
notes = serializer.to_representation(doc).get("notes")
notes = self.getNotes(doc)
return Response(notes)
except Exception as e:
logger.warning(f"An error occurred retrieving notes: {e!s}")
@ -872,7 +897,7 @@ class DocumentViewSet(
index.add_or_update_document(doc)
notes = serializer.to_representation(doc).get("notes")
notes = self.getNotes(doc)
return Response(notes)
except Exception as e:
@ -909,9 +934,7 @@ class DocumentViewSet(
index.add_or_update_document(doc)
notes = serializer.to_representation(doc).get("notes")
return Response(notes)
return Response(self.getNotes(doc))
return Response(
{

View File

@ -1199,7 +1199,7 @@ msgid "Paperless-ngx account inactive"
msgstr ""
#: documents/templates/account/account_inactive.html:9
msgid "Account inactive."
msgid "Account inactve."
msgstr ""
#: documents/templates/account/account_inactive.html:14

58
uv.lock generated
View File

@ -880,14 +880,14 @@ wheels = [
[[package]]
name = "drf-spectacular-sidecar"
version = "2025.3.1"
version = "2025.2.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "django", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/80/5c/85671ba50957e0ab45e2828ca713cd7b5d0d237c398936c1b45bd0286b72/drf_spectacular_sidecar-2025.3.1.tar.gz", hash = "sha256:7425940a409fb68a46c9b024eb504098fab5b4d73d12573efcaef048445d678f", size = 2401986 }
sdist = { url = "https://files.pythonhosted.org/packages/7e/4c/6c945509d578f04d19eee2ffeb25bc37e6aeb9713688a87fc4f3b02bc32b/drf_spectacular_sidecar-2025.2.1.tar.gz", hash = "sha256:ca9507c5fe708680d6b8eda96928f3cf3ffc07e8d67678778bcd2e80f9f2baae", size = 2390256 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5e/09/7382eb93a09f33fac72a8af1fc986f43681d15dd5fda750b238a8aace0e8/drf_spectacular_sidecar-2025.3.1-py3-none-any.whl", hash = "sha256:6b9c96204c8e45a06c39928dad704b18536d3253b61591c478540b63db6bdcea", size = 2422301 },
{ url = "https://files.pythonhosted.org/packages/eb/8a/b66f58e92c5752bbc241bb04ce76d2bf92c676af4cb8b94edac3a0e0c701/drf_spectacular_sidecar-2025.2.1-py3-none-any.whl", hash = "sha256:674e1336810c7cf117442300b5c213c4fee1e984ba48689502c947a6ecd25d0c", size = 2409274 },
]
[[package]]
@ -1803,7 +1803,7 @@ wheels = [
[[package]]
name = "ocrmypdf"
version = "16.10.0"
version = "16.9.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "deprecation", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
@ -1816,9 +1816,9 @@ dependencies = [
{ name = "pluggy", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "rich", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/07/cf/d207aea8442a8e5a63b16faae89af2b9e3474d8d5925a5ea8c4f10f73fa9/ocrmypdf-16.10.0.tar.gz", hash = "sha256:d5b907a7b92951f1f3617f0f5ca002d866143d94fd168546a70e51756bf6412e", size = 6809110 }
sdist = { url = "https://files.pythonhosted.org/packages/a8/07/d8810415b98718a39b1161720acd925b6ef15743227012809f6da9d3b7bc/ocrmypdf-16.9.0.tar.gz", hash = "sha256:d000a2294cd1478d4bbfe15df5172327f77f4139bb5307404bc53be9bd81f039", size = 6804849 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/33/47/10058f54f593f5e618a6796fc3e8dc3e19536128f832e2d3d6e4943e9834/ocrmypdf-16.10.0-py3-none-any.whl", hash = "sha256:5093b9b058e7278b17c0b0978eb5175063b7a5511e3b9068257ece063d91ce8f", size = 162336 },
{ url = "https://files.pythonhosted.org/packages/12/69/e40431c5410eaf0c55588d0d256e27ee32af7622cb7116ac99a2e868bd2f/ocrmypdf-16.9.0-py3-none-any.whl", hash = "sha256:33fec95450727b0d9482ee3851e45dd0219ff8d52a14fd45a8d3d0c71875584e", size = 161863 },
]
[[package]]
@ -1904,9 +1904,9 @@ mariadb = [
]
postgres = [
{ name = "psycopg", extra = ["c"], marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
{ name = "psycopg-c", version = "3.2.5", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version != '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux') or (python_full_version != '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'linux') or sys_platform == 'darwin'" },
{ name = "psycopg-c", version = "3.2.5", source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_aarch64.whl" }, marker = "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'" },
{ name = "psycopg-c", version = "3.2.5", source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_x86_64.whl" }, marker = "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "psycopg-c", version = "3.2.4", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version != '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux') or (python_full_version != '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'linux') or sys_platform == 'darwin'" },
{ name = "psycopg-c", version = "3.2.4", source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_aarch64.whl" }, marker = "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'" },
{ name = "psycopg-c", version = "3.2.4", source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_x86_64.whl" }, marker = "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux'" },
]
webserver = [
{ name = "granian", marker = "sys_platform == 'darwin' or sys_platform == 'linux'" },
@ -1994,7 +1994,7 @@ requires-dist = [
{ name = "djangorestframework", specifier = "~=3.15" },
{ name = "djangorestframework-guardian", specifier = "~=0.3.0" },
{ name = "drf-spectacular", specifier = "~=0.28" },
{ name = "drf-spectacular-sidecar", specifier = "~=2025.3.1" },
{ name = "drf-spectacular-sidecar", specifier = "~=2025.2.1" },
{ name = "drf-writable-nested", specifier = "~=0.7.1" },
{ name = "filelock", specifier = "~=3.17.0" },
{ name = "flower", specifier = "~=2.0.1" },
@ -2007,13 +2007,13 @@ requires-dist = [
{ name = "langdetect", specifier = "~=1.0.9" },
{ name = "mysqlclient", marker = "extra == 'mariadb'", specifier = "~=2.2.7" },
{ name = "nltk", specifier = "~=3.9.1" },
{ name = "ocrmypdf", specifier = "~=16.10.0" },
{ name = "ocrmypdf", specifier = "~=16.9.0" },
{ name = "pathvalidate", specifier = "~=3.2.3" },
{ name = "pdf2image", specifier = "~=1.17.0" },
{ name = "psycopg", extras = ["c"], marker = "extra == 'postgres'", specifier = "==3.2.5" },
{ name = "psycopg-c", marker = "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'postgres'", url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_aarch64.whl" },
{ name = "psycopg-c", marker = "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'postgres'", url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_x86_64.whl" },
{ name = "psycopg-c", marker = "(python_full_version != '3.12.*' and platform_machine == 'aarch64' and extra == 'postgres') or (python_full_version != '3.12.*' and platform_machine == 'x86_64' and extra == 'postgres') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'postgres') or (sys_platform != 'linux' and extra == 'postgres')", specifier = "==3.2.5" },
{ name = "psycopg", extras = ["c"], marker = "extra == 'postgres'", specifier = "==3.2.4" },
{ name = "psycopg-c", marker = "python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux' and extra == 'postgres'", url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_aarch64.whl" },
{ name = "psycopg-c", marker = "python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux' and extra == 'postgres'", url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_x86_64.whl" },
{ name = "psycopg-c", marker = "(python_full_version != '3.12.*' and platform_machine == 'aarch64' and extra == 'postgres') or (python_full_version != '3.12.*' and platform_machine == 'x86_64' and extra == 'postgres') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and extra == 'postgres') or (sys_platform != 'linux' and extra == 'postgres')", specifier = "==3.2.4" },
{ name = "python-dateutil", specifier = "~=2.9.0" },
{ name = "python-dotenv", specifier = "~=1.0.1" },
{ name = "python-gnupg", specifier = "~=0.5.4" },
@ -2348,53 +2348,53 @@ wheels = [
[[package]]
name = "psycopg"
version = "3.2.5"
version = "3.2.4"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "typing-extensions", marker = "(python_full_version < '3.13' and sys_platform == 'darwin') or (python_full_version < '3.13' and sys_platform == 'linux')" },
]
sdist = { url = "https://files.pythonhosted.org/packages/0e/cf/dc1a4d45e3c6222fe272a245c5cea9a969a7157639da606ac7f2ab5de3a1/psycopg-3.2.5.tar.gz", hash = "sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8", size = 156158 }
sdist = { url = "https://files.pythonhosted.org/packages/e0/f2/954b1467b3e2ca5945b83b5e320268be1f4df486c3e8ffc90f4e4b707979/psycopg-3.2.4.tar.gz", hash = "sha256:f26f1346d6bf1ef5f5ef1714dd405c67fb365cfd1c6cea07de1792747b167b92", size = 156109 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/18/f3/14a1370b1449ca875d5e353ef02cb9db6b70bd46ec361c236176837c0be1/psycopg-3.2.5-py3-none-any.whl", hash = "sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879", size = 198749 },
{ url = "https://files.pythonhosted.org/packages/40/49/15114d5f7ee68983f4e1a24d47e75334568960352a07c6f0e796e912685d/psycopg-3.2.4-py3-none-any.whl", hash = "sha256:43665368ccd48180744cab26b74332f46b63b7e06e8ce0775547a3533883d381", size = 198716 },
]
[package.optional-dependencies]
c = [
{ name = "psycopg-c", version = "3.2.5", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version != '3.12.*' and implementation_name != 'pypy' and platform_machine == 'aarch64' and sys_platform == 'linux') or (python_full_version != '3.12.*' and implementation_name != 'pypy' and platform_machine == 'x86_64' and sys_platform == 'linux') or (implementation_name != 'pypy' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'linux') or (implementation_name != 'pypy' and sys_platform == 'darwin')" },
{ name = "psycopg-c", version = "3.2.5", source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_aarch64.whl" }, marker = "python_full_version == '3.12.*' and implementation_name != 'pypy' and platform_machine == 'aarch64' and sys_platform == 'linux'" },
{ name = "psycopg-c", version = "3.2.5", source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_x86_64.whl" }, marker = "python_full_version == '3.12.*' and implementation_name != 'pypy' and platform_machine == 'x86_64' and sys_platform == 'linux'" },
{ name = "psycopg-c", version = "3.2.4", source = { registry = "https://pypi.org/simple" }, marker = "(python_full_version != '3.12.*' and implementation_name != 'pypy' and platform_machine == 'aarch64' and sys_platform == 'linux') or (python_full_version != '3.12.*' and implementation_name != 'pypy' and platform_machine == 'x86_64' and sys_platform == 'linux') or (implementation_name != 'pypy' and platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'linux') or (implementation_name != 'pypy' and sys_platform == 'darwin')" },
{ name = "psycopg-c", version = "3.2.4", source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_aarch64.whl" }, marker = "python_full_version == '3.12.*' and implementation_name != 'pypy' and platform_machine == 'aarch64' and sys_platform == 'linux'" },
{ name = "psycopg-c", version = "3.2.4", source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_x86_64.whl" }, marker = "python_full_version == '3.12.*' and implementation_name != 'pypy' and platform_machine == 'x86_64' and sys_platform == 'linux'" },
]
[[package]]
name = "psycopg-c"
version = "3.2.5"
version = "3.2.4"
source = { registry = "https://pypi.org/simple" }
resolution-markers = [
"sys_platform == 'darwin'",
"(python_full_version != '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux') or (python_full_version != '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux') or (platform_machine != 'aarch64' and platform_machine != 'x86_64' and sys_platform == 'linux')",
]
sdist = { url = "https://files.pythonhosted.org/packages/cf/cb/468dcca82f08b47af59af4681ef39473cf5c0ef2e09775c701ccdf7284d6/psycopg_c-3.2.5.tar.gz", hash = "sha256:57ad4cfd28de278c424aaceb1f2ad5c7910466e315dfe84e403f3c7a0a2ce81b", size = 609318 }
sdist = { url = "https://files.pythonhosted.org/packages/17/76/dbdadd9b93b8ad38cff31402c73a6bb9a23c88a4466fa09655d3c6db4d11/psycopg_c-3.2.4.tar.gz", hash = "sha256:22097a04263efb2efd2cc8b00a51fa90e23f9cd4a2e09903fe4d9c6923dac17a", size = 601853 }
[[package]]
name = "psycopg-c"
version = "3.2.5"
source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_aarch64.whl" }
version = "3.2.4"
source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_aarch64.whl" }
resolution-markers = [
"python_full_version == '3.12.*' and platform_machine == 'aarch64' and sys_platform == 'linux'",
]
wheels = [
{ url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_aarch64.whl", hash = "sha256:39012b8df2ef34e172d43ab5976017d054f2c2fc549854927a62e73f5253eacc" },
{ url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_aarch64.whl", hash = "sha256:7a3b1152b676afe4a9113f784257221cf85147812116de86970272553a846f40" },
]
[[package]]
name = "psycopg-c"
version = "3.2.5"
source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_x86_64.whl" }
version = "3.2.4"
source = { url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_x86_64.whl" }
resolution-markers = [
"python_full_version == '3.12.*' and platform_machine == 'x86_64' and sys_platform == 'linux'",
]
wheels = [
{ url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.5/psycopg_c-3.2.5-cp312-cp312-linux_x86_64.whl", hash = "sha256:a0667a62595e355c2d3b6ac05336403c998fbfb31cf6922d73e19018016df1bc" },
{ url = "https://github.com/paperless-ngx/builder/releases/download/psycopg-3.2.4/psycopg_c-3.2.4-cp312-cp312-linux_x86_64.whl", hash = "sha256:d0c0c87699846bd7f8c9259db0d17f0c9d062f3281d07b32be00ca28cdcbd5f3" },
]
[[package]]