Repository: paperless-ngx/paperless-ngx

Issue:
[BUG] Consumption fails on too long filenames
### Description

Currently, Paperless throws an exception when trying to consume documents with "too long" filenames, e.g. 
`Zertifikat Es-geht-nicht-darum-Faesser-zu-fuellen-sondern-Flammen-zu-entzuenden.-Ausbilderkills-um-das-Thema-Erste-Hilfe-be-greifbar-zu-machen-.pdf`

### Steps to reproduce

(Tested via e-mail import)
1. Set up consumption via email
2. Send document with too long filename as attachment
3. see Error in logs

### Webserver logs

```bash
[2024-02-28 08:41:09,507] [ERROR] [paperless.consumer] The following error occurred while storing document Zertifikat Es-geht-nicht-darum-Faesser-zu-fuellen-sondern-Flammen-zu-entzuenden.-Ausbilderkills-um-das-Thema-Erste-Hilfe-be-greifbar-zu-machen-.pdf after parsing: value too long for type character varying(128)

Traceback (most recent call last):

  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 89, in _execute

    return self.cursor.execute(sql, params)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

psycopg2.errors.StringDataRightTruncation: value too long for type character varying(128)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

  File "/usr/local/lib/python3.11/site-packages/asgiref/sync.py", line 349, in main_wrap

    raise exc_info[1]

  File "/usr/src/paperless/src/documents/consumer.py", line 579, in try_consume_file

    document = self._store(text=text, date=date, mime_type=mime_type)

               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/src/paperless/src/documents/consumer.py", line 744, in _store

    document = Document.objects.create(

               ^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method

    return getattr(self.get_queryset(), name)(*args, **kwargs)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/django/db/models/query.py", line 658, in create

    obj.save(force_insert=True, using=self.db)

  File "/usr/local/lib/python3.11/site-packages/django/db/models/base.py", line 814, in save

    self.save_base(

  File "/usr/local/lib/python3.11/site-packages/django/db/models/base.py", line 877, in save_base

    updated = self._save_table(

              ^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/django/db/models/base.py", line 1020, in _save_table

    results = self._do_insert(

              ^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/django/db/models/base.py", line 1061, in _do_insert

    return manager._insert(

           ^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/django/db/models/manager.py", line 87, in manager_method

    return getattr(self.get_queryset(), name)(*args, **kwargs)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/django/db/models/query.py", line 1805, in _insert

    return query.get_compiler(using=using).execute_sql(returning_fields)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1822, in execute_sql

    cursor.execute(sql, params)

  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 67, in execute

    return self._execute_with_wrappers(

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers

    return executor(sql, params, many, context)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 84, in _execute

    with self.db.wrap_database_errors:

  File "/usr/local/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__

    raise dj_exc_value.with_traceback(traceback) from exc_value

  File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 89, in _execute

    return self.cursor.execute(sql, params)

           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

django.db.utils.DataError: value too long for type character varying(128)

[2024-02-28 08:41:09,516] [DEBUG] [paperless.parsing.tesseract] Deleting directory /tmp/paperless/paperless-awlhyv2b
```


### Browser logs

_No response_

### Paperless-ngx version

2.5.4

### Host OS

Ubuntu 22.04.3 LTS (GNU/Linux 6.5.11-8-pve x86_64)

### Installation method

Docker - official image

### Browser

Chrome

### Configuration changes

_No response_

### Other

_No response_

### Please confirm the following

- [X] I believe this issue is a bug that affects all users of Paperless-ngx, not something specific to my installation.
- [X] I have already searched for relevant existing issues and discussions before opening this report.
- [X] I have updated the title field above with a concise description.


Discussion:
The field for file name has a max length of 1024, Im guessing this is actually the title field. Does your rule use "Assign title from": "Use attachment filename as title"?


Resolving patch:
diff --git a/src/documents/consumer.py b/src/documents/consumer.py
--- a/src/documents/consumer.py
+++ b/src/documents/consumer.py
@@ -732,7 +732,7 @@ def _store(
 
         storage_type = Document.STORAGE_TYPE_UNENCRYPTED
 
-        title = file_info.title[:127]
+        title = file_info.title
         if self.override_title is not None:
             try:
                 title = self._parse_title_placeholders(self.override_title)
@@ -742,7 +742,7 @@ def _store(
                 )
 
         document = Document.objects.create(
-            title=title,
+            title=title[:127],
             content=text,
             mime_type=mime_type,
             checksum=hashlib.md5(self.working_copy.read_bytes()).hexdigest(),


Test patch: