Commit Graph
4370 Commits
Author SHA1 Message Date
shamoon ac59404389 Sure, cover ollama too 2026-09-20 21:09:20 -07:00
shamoon 285e3fec39 Enhancement: support passthrough extra params for LLMs 2026-09-20 21:09:20 -07:00
Trenton H 7575d60782 Bump version to 3.2.1 2026-09-20 14:29:37 -07:00
github-actions[bot]andCrowdin Bot 8b02a23b86 New Crowdin translations by GitHub Action (#14179)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-09-20 21:24:50 +00:00
Trenton H 506afb4200 Fix: replace stale mail-fetch overlap check with a self-expiring lock (#14189) 2026-09-19 20:02:10 -07:00
Trenton H d5425a893d Fix: rebuild the search index automatically when it is corrupted, instead of hard-failing (#14180) 2026-09-19 12:53:36 -07:00
shamoon 961f018d3e Bump version to 3.2.0 2026-09-18 19:13:02 -07:00
shamoon 405ab39b40 Chore: drop classifier match default threshold to 0.3 2026-09-18 19:10:13 -07:00
github-actions[bot]andCrowdin Bot 36c10b72b9 New Crowdin translations by GitHub Action (#13968)
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2026-09-18 19:07:47 +00:00
Boris Rybalkin 4c4ef5617c Fix: don't redirect to signup on first install when regular login is disabled (#14165) 2026-09-18 01:14:03 -07:00
GitHub Actions cf2f913a06 Auto translate strings 2026-09-18 01:30:10 +00:00
shamoon f4ff87e69b Enhancement (QoL): support deselecting single items from "select all" (#14117) 2026-09-18 01:28:55 +00:00
Trenton H fdd32b73bb Chore: Move the search tests onto the shared indexing fixtures (#14159) 2026-09-17 14:55:13 -07:00
Trenton H 20d309a413 Enhancement: Match fuzzy terms in place inside the parsed query (#14157)
* Feature: match fuzzy terms in place inside the parsed query

Fuzzy matching was a separate clause OR'd in above the query: a flat bag
of the query's words, re-parsed through tantivy's own parser, blended
beside the exact clause. Nothing around a term reached it, so a fielded
term fuzzed across every default field, a filter did not constrain it, and
an exclusion had to be hoisted back over the whole blend to stop the
clause re-admitting what the query had just excluded.

Widen each leaf where it sits instead, through emit()'s rewrite_leaf hook,
so fielding, negation, AND, REQUIRE and positive filters constrain the
fuzzy match exactly as they constrain the exact one. Each of a leaf's
words becomes a Fuzzy leaf on the leaf's own field, boosted to 0.1, beside
the leaf and any CJK alternative it already had.

* Hello?
2026-09-17 14:55:13 -07:00
Trenton H 762e8cf4d1 Feature: match CJK terms through their bigram fields in place (#14156)
QUERY-mode searches blended a separate bigram clause in at the top of the
query, built from the parsed AST's free-text tokens. Because it sat beside
the exact clause rather than inside the query, nothing around a CJK term
constrained its bigram match: an exclusion that was one OR branch's own
condition could never reach it, so "(東京 AND NOT secret) OR bill" still
returned the secret document.

Widen each CJK leaf where it sits instead, through emit()'s rewrite_leaf
hook, so every AND, NOT, REQUIRE, boost and field restriction around the
leaf applies to its bigram match too. Negated leaves are widened on
purpose, so "NOT X" excludes exactly what "X" matches.
2026-09-17 14:55:13 -07:00
GitHub Actions 0d14d80995 Auto translate strings 2026-09-16 15:47:19 +00:00
shamoon c97c6923ea Enhancement: centralized management of share links + bundles (#14115) 2026-09-16 15:45:49 +00:00
GitHub Actions cd53d1b2c8 Auto translate strings 2026-09-16 14:36:53 +00:00
Trenton H 530059c5c0 Performance: Preprocess classifier text with Tantivy instead of NLTK (#14127)
* Preprocesses classifier content with Tantivy instead of NLTK

Tokenizing and stemming now happen in one Rust call instead of NLTK's
Python tokenizer and per word stemming, which also removes the Redis
backed stem cache from every preprocessing call. The output matches the
NLTK pipeline closely; tokens containing digits are now stemmed, and the
English stop words follow Snowball's list.

Stemming and stop word removal apply whenever the OCR language is one of
the supported classifier languages, so PAPERLESS_ENABLE_NLTK and
PAPERLESS_NLTK_DIR are removed.

* Copies packages instead of hardlinking them in backend CI, some NLTK thing

* Adds a normalization to NFC to better fit what Tantivy expects
2026-09-16 07:35:26 -07:00
Trenton H 7e698360ff Performance: Drops fields from the MLPClassifier that are training only before pickling (#14114) 2026-09-15 20:40:49 -07:00
shamoon e8b7a98d3e Fix: better catch email workflow placeholder parsing errors (#14129) 2026-09-15 16:44:12 -07:00
Trenton H f919c981e1 Peformance: Improves the memory efficency of classifier training (#14124) 2026-09-15 13:35:44 -07:00
Trenton H ec4e45ecf4 Performance: Streams the classifier pickle file during save to file (#14121) 2026-09-15 19:35:18 +00:00
GitHub Actions 27927fab4d Auto translate strings 2026-09-15 19:24:55 +00:00
Trenton H 683f2ac250 Fix: validate legacy bulk_edit owner/rotate/split parameters (#14120)
BulkEditSerializer's hand-parsed validators only caught the exceptions
their happy paths raised, so wrong-typed input produced a 500 or was
passed through to the task:

- owner: a nonexistent or wrong-typed id raised an uncaught error, and a
  boolean was accepted (Django coerces True to pk 1). It is now validated
  with PrimaryKeyRelatedField and the validated pk is passed on.
- rotate: null raised TypeError, while true, "90" and 45 were accepted and
  failed later in QPDF. Degrees are now an IntegerField plus a
  multiple-of-90 check, passing an int on. The dedicated rotate endpoint
  and edit_pdf operations share the same multiple-of-90 check.
- split: null raised AttributeError, "0" silently became the last page,
  "3-1" gave an empty group that crashed the task, and a range like
  "1-5000000" was expanded into a list during the request with no upper
  bound. Each range is now checked against 1 <= start <= end <= page_count
  before it is built.
2026-09-15 19:23:37 +00:00
GitHub Actions 73de6b17bf Auto translate strings 2026-09-15 18:47:52 +00:00
Trenton H ef26bc1570 Fix: enforce set_permissions shape via a nested DRF serializer (#14119)
SetPermissionsSerializer was a bare DictField, and the legacy bulk_edit
set_permissions parameter bypassed even that by hand-calling
validate_set_permissions() on an unchecked dict. A bool or a non-list in
place of users/groups crashed with a raw TypeError instead of a 400.

It is now a nested serializer (view/change, each with users/groups as
lists of integers), used for owned-object create/update, the legacy
bulk_edit set_permissions parameter, and bulk_edit_objects permissions.
Unknown action keys are rejected: previously a typo like "veiw" was
silently dropped, leaving an empty permission set that could clear
existing grants. An explicit set_permissions null (an owner-only change)
remains a no-op, and an empty bulk_edit_objects permissions dict is still
rejected.
2026-09-15 18:46:32 +00:00
Trenton H ff1e61b162 Fix: Use prefetching to reduce query counts during classifier training (#14122) 2026-09-15 11:12:08 -07:00
Trenton H 1f374cd656 Fix: reject non-dict user_args/barcode_tag_mapping in config API (#14118)
JSONField(binary=True) accepts any JSON value, so a truthy non-dict
(bool/int/list/string) silently passed validation.

Additionally, require string substitutes in barcode_tag_mapping, a non-string
substitute value made the barcode tag substitution fail inside
get_tag_ids, and the tag was silently skipped. barcode_tag_mapping values
must now be strings (empty still means "use the raw barcode").
2026-09-15 16:14:01 +00:00
GitHub Actions 7354427229 Auto translate strings 2026-09-15 15:45:22 +00:00
Trenton H 970eb55a70 Fix: type edit_pdf operations via a nested serializer (#14116)
operations was a ListField with no child, so both EditPdfDocumentsSerializer
and BulkEditSerializer._validate_parameters_edit_pdf hand-checked each entry
with isinstance(). That accepted booleans (isinstance(True, int) is true) and
passed through any extra keys.

Adds PdfEditOperationSerializer (page >= 1, doc >= 0, rotate a multiple of
90) and uses it as the ListField child on both paths, dropping the manual
type checks and the now-redundant negative/page < 1 bounds checks. Rotations
that are not a multiple of 90 previously passed validation and then failed
inside the task when QPDF refused them.
2026-09-15 15:43:21 +00:00
Trenton H d2170f1267 Performance: Loads the classifier through a memory view to reduce memory usage (#14113) 2026-09-15 15:23:41 +00:00
GitHub Actions 2ac5a1c2e2 Auto translate strings 2026-09-15 14:28:16 +00:00
Trenton H a4e69aac9d Documentation: document the query grammar paperless actually supports (#14074)
* docs(search): document the query grammar paperless actually supports

* docs(search): cover ?/bracket wildcards and the no-stemmer fallback

* Shorten things up, use tables and less wordy stuff.  Fixes some test doc strings that referred to the documentation

* Silly sonarr
2026-09-15 07:26:42 -07:00
Trenton H 1e62f5e811 Fix: cap the advanced search query length (#14073)
* fix(search): cap the advanced search query length

* Adds a couple of spies, just to prove it further
2026-09-15 07:26:42 -07:00
Trenton H 1f8b6c95b1 Feature: parse advanced search with whoosh-compat and delete the handwritten translation (#14072)
* Feature: parse advanced search with whoosh-compat and delete the hand-written translator

* Don't cover these, they exist for defensive, but there's no other current diagnostic

* A mix of more no cover and tests

* Route SCHEMA_FIELD_MISSING into an error, not an HTTP 400
2026-09-15 07:26:41 -07:00
Trenton H e78521c912 Chore: Search field registry (#14071)
* feat(search): add whoosh-compat, the shared field table and the field registry

* Sonar being useful actually

* Adds the given/when/then commenting

* Trims tests I don't think cover our logic or code or are redundant

* Coverage

* test(search): add pattern normalizer stem-alternates unit tests

* build: bump whoosh-compat to 0.2.0
2026-09-15 07:26:41 -07:00
shamoon 9cea08118e Fix: ensure django setup is run for management comments under 3.14 (#14100) 2026-09-14 07:20:20 -07:00
GitHub Actions cb2506900e Auto translate strings 2026-09-13 22:13:45 +00:00
shamoon 5293194551 Fix: validate PDF output doc indexes in bulk edit (#14083) 2026-09-13 22:12:10 +00:00
GitHub Actions 1b86488e2e Auto translate strings 2026-09-13 21:59:18 +00:00
shamoon c9a5607902 Enhancement: allow regex timeout configuration (#14085) 2026-09-13 21:57:24 +00:00
Trenton H 05b7697c35 Fix: avoid IntegrityError when a retried task republishes with the same task_id (#14096) 2026-09-13 21:05:54 +00:00
GitHub Actions 72ea38ab12 Auto translate strings 2026-09-12 23:19:06 +00:00
shamoon 4421d4fe58 Fix: update some api global perms inconsistencies (#14086) 2026-09-12 16:17:48 -07:00
GitHub Actions 4d64632f70 Auto translate strings 2026-09-12 23:15:32 +00:00
shamoon 26094bc863 Fix: ignore nested action IDs on WF create (#14084) 2026-09-12 16:14:17 -07:00
shamoon 9dbad4de09 Chore: read-only deleted_at 2026-09-12 16:13:58 -07:00
GitHub Actions 4a54935b3d Auto translate strings 2026-09-11 15:48:00 +00:00
shamoon d53c9070ba Fix: correct text/stream compression workaround (#14064) 2026-09-11 15:46:08 +00:00