18.0 vanilla

This commit is contained in:
Ernad Husremovic 2025-10-03 18:06:50 +02:00
parent d72e748793
commit 0a7ae8db93
337 changed files with 399651 additions and 232598 deletions

View file

@ -2,6 +2,7 @@
import importlib
import io
import re
import unicodedata
import sys
from datetime import datetime
from hashlib import md5
@ -14,6 +15,7 @@ from reportlab.lib.units import cm
from reportlab.lib.utils import ImageReader
from reportlab.pdfgen import canvas
from odoo.tools.arabic_reshaper import reshape
from odoo.tools.parse_version import parse_version
from odoo.tools.misc import file_open
@ -23,6 +25,24 @@ try:
except ImportError:
TTFont = None
# ----------------------------------------------------------
# PyPDF2 hack
# ensure that zlib does not throw error -5 when decompressing
# because some pdf won't fit into allocated memory
# https://docs.python.org/3/library/zlib.html#zlib.decompressobj
# ----------------------------------------------------------
try:
import zlib
def _decompress(data):
zobj = zlib.decompressobj()
return zobj.decompress(data)
import PyPDF2.filters # needed after PyPDF2 2.0.0 and before 2.11.0
PyPDF2.filters.decompress = _decompress
except ImportError:
pass # no fix required
# might be a good case for exception groups
error = None
@ -177,16 +197,6 @@ def fill_form_fields_pdf(writer, form_fields):
_logger.info("Fields couldn't be filled in this page.")
continue
for raw_annot in page.get('/Annots', []):
annot = raw_annot.getObject()
for field in form_fields:
# Modifying the form flags to force all text fields read-only
if annot.get('/T') == field:
form_flags = annot.get('/Ff', 0)
readonly_flag = 1 # 1st bit sets readonly
new_flags = form_flags | readonly_flag
annot.update({NameObject("/Ff"): NumberObject(new_flags)})
def rotate_pdf(pdf):
''' Rotate clockwise PDF (90°) into a new PDF.
@ -280,6 +290,38 @@ def add_banner(pdf_stream, text=None, logo=False, thickness=2 * cm):
return output
def reshape_text(text):
"""
Display the text based on his first character unicode name to choose Right-to-left or Left-to-right
This is just a hotfix to make things work
In the future the clean way be to use arabic-reshaper and python3-bidi libraries
Here we want to check the text is in a right-to-left language and if then, flip before returning it.
Depending on the language, the type should be Left-to-Right, Right-to-Left, or Right-to-Left Arabic
(Refer to this https://www.unicode.org/reports/tr9/#Bidirectional_Character_Types)
The base module ```unicodedata``` with his function ```bidirectional(str)``` helps us by taking a character in
argument and returns his type:
- 'L' for Left-to-Right character
- 'R' or 'AL' for Right-to-Left character
So we have to check if the first character of the text is of type 'R' or 'AL', and check that there is no
character in the rest of the text that is of type 'L'. Based on that we can confirm we have a fully Right-to-Left language,
then we can flip the text before returning it.
"""
if not text:
return ''
maybe_rtl_letter = text.lstrip()[:1] or ' '
maybe_ltr_text = text[1:]
first_letter_is_rtl = unicodedata.bidirectional(maybe_rtl_letter) in ('AL', 'R')
no_letter_is_ltr = not any(unicodedata.bidirectional(letter) == 'L' for letter in maybe_ltr_text)
if first_letter_is_rtl and no_letter_is_ltr:
text = reshape(text)
text = text[::-1]
return text
class OdooPdfFileReader(PdfFileReader):
# OVERRIDE of PdfFileReader to add the management of multiple embedded files.

View file

@ -42,6 +42,9 @@ class PdfReader(_Reader):
def getDocumentInfo(self):
return self.metadata
def getFormTextFields(self):
return self.get_form_text_fields()
class PdfWriter(_Writer):
def add_metadata(self, infos: Dict[str, Any]) -> None:

View file

@ -17,6 +17,12 @@ class PdfReader(PdfFileReader):
def __init__(self, stream, strict=True, warndest=None, overwriteWarnings=True):
super().__init__(stream, strict=strict, warndest=warndest, overwriteWarnings=False)
def getFormTextFields(self):
if self.getFields() is None:
# Prevent this version of PyPDF2 from trying to iterate over `None`
return None
return super().getFormTextFields()
class PdfWriter(PdfFileWriter):
def get_fields(self, *args, **kwargs):