mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-20 02:12:01 +02:00
18.0 vanilla
This commit is contained in:
parent
d72e748793
commit
0a7ae8db93
337 changed files with 399651 additions and 232598 deletions
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue