diff --git a/.hgignore b/.hgignore
index 1b85cd9..913ee1b 100644
--- a/.hgignore
+++ b/.hgignore
@@ -1,3 +1,6 @@
syntax: glob
__pycache__/*
locale/convert_de2en.py
+build/*
+mds_cashbook_media.egg-info/*
+dist/*
diff --git a/README.rst b/README.rst
index ab62e82..c16afe5 100644
--- a/README.rst
+++ b/README.rst
@@ -9,11 +9,11 @@ pip install mds-cashbook-media
Requires
========
-- Tryton 6.0
+- Tryton 7.0
Changes
=======
-*6.0.0 - 14.10.2022*
+*7.0.0 - 01.12.2023*
-- init
+- ported to Tryton 7.0
diff --git a/__init__.py b/__init__.py
index 8681953..4c95efa 100644
--- a/__init__.py
+++ b/__init__.py
@@ -6,6 +6,7 @@
from trytond.pool import Pool
from .line import Line
+
def register():
Pool.register(
Line,
diff --git a/line.py b/line.py
index a7a482d..a0ecf3e 100644
--- a/line.py
+++ b/line.py
@@ -3,13 +3,13 @@
# The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms.
-import mimetypes, magic
+import mimetypes
+import magic
from io import BytesIO
-from PIL import Image
+from PIL import Image, UnidentifiedImageError
from trytond.model import fields
-from trytond.pool import Pool, PoolMeta
+from trytond.pool import PoolMeta
from trytond.config import config
-from trytond.transaction import Transaction
from trytond.exceptions import UserError
from trytond.i18n import gettext
from trytond.pyson import Eval, Bool
@@ -18,30 +18,50 @@ from trytond.modules.cashbook.line import STATES, DEPENDS
store_prefix = config.get('cashbook', 'store_prefix', default='cashbook')
image_limit = config.get('cashbook', 'image_max_pixel', default='2000')
-try :
+try:
image_limit = int(image_limit)
if image_limit < 100:
image_limit = 100
if image_limit > 10000:
image_limit = 10000
-except :
+except Exception:
image_limit = 2000
+STATES2 = {}
+STATES2.update(STATES)
+DEPENDS2 = []
+DEPENDS2.extend(DEPENDS)
+
+
class Line(metaclass=PoolMeta):
__name__ = 'cashbook.line'
- media = fields.Binary(string='Image of PDF', filename='media_name',
- file_id='media_id', store_prefix=store_prefix,
- states=STATES, depends=DEPENDS)
- media_name = fields.Char(string='File name',
+ media = fields.Binary(
+ string='Image of PDF', filename='media_name', file_id='media_id',
+ store_prefix=store_prefix, states=STATES2, depends=DEPENDS2)
+ media_name = fields.Char(
+ string='File name',
states={
'required': Bool(Eval('media')),
- 'readonly': STATES['readonly'],
- }, depends=DEPENDS)
+ 'readonly': STATES2['readonly'],
+ }, depends=DEPENDS2)
media_id = fields.Char(string='File ID', readonly=True)
media_mime = fields.Char(string='MIME', readonly=True)
media_size = fields.Integer(string='File size', readonly=True)
+ media_image = fields.Function(fields.Binary(
+ string='Image', readonly=True,
+ states={
+ 'invisible': ~Eval('media_mime', '').in_([
+ 'image/png', 'image/jpg', 'image/jpeg']),
+ }, depends=['media_mime']), 'on_change_with_media_image')
+
+ @fields.depends('media', 'media_mime')
+ def on_change_with_media_image(self, name=True):
+ """ return binary if its a image
+ """
+ if (self.media_mime or '-').startswith('image/'):
+ return self.media
@classmethod
def _identify_file(cls, data, mime=True):
@@ -65,14 +85,17 @@ class Line(metaclass=PoolMeta):
"""
image_data2 = None
with BytesIO(image_data) as fhdl:
- image = Image.open(fhdl, 'r')
+ try:
+ image = Image.open(fhdl, 'r')
+ except UnidentifiedImageError:
+ raise UserError(gettext('cashbook_media.msg_file_unknown_type'))
(width, height) = image.size
if (width > image_limit) or (height > image_limit):
if width > height:
new_size = (image_limit, int(height * image_limit / width))
- else :
+ else:
new_size = (int(width * image_limit / height), image_limit)
# resize - fit in (image_limit x image_limit)
@@ -95,15 +118,17 @@ class Line(metaclass=PoolMeta):
values['media_mime'] = None
values['media_size'] = None
values['media_name'] = None
- else :
+ else:
values['media_mime'] = cls._identify_file(values['media'][:1024])
- # if its a image, resize it to fit in (image_limit x image_limit) pixel
+ # if its a image, resize it to fit
+ # in (image_limit x image_limit) pixel
if values['media_mime'].startswith('image'):
new_image = cls.resize_image_file(values['media'])
if new_image is not None:
values['media'] = new_image
- values['media_mime'] = cls._identify_file(values['media'][:1024])
+ values['media_mime'] = cls._identify_file(
+ values['media'][:1024])
values['media_size'] = len(values['media'])
file_ext = mimetypes.guess_extension(values['media_mime'])
@@ -126,15 +151,14 @@ class Line(metaclass=PoolMeta):
if line.media_size > 1024*1024*5:
raise UserError(gettext(
'cashbook_media.msg_file_too_big',
- recname = line.rec_name,
- ))
- if not line.media_mime in ['application/pdf',
- 'image/png', 'image/jpg', 'image/jpeg']:
+ recname=line.rec_name))
+ if line.media_mime not in [
+ 'application/pdf',
+ 'image/png', 'image/jpg', 'image/jpeg']:
raise UserError(gettext(
'cashbook_media.msg_file_invalid_mime',
- recname = line.rec_name,
- fmime = line.media_mime,
- ))
+ recname=line.rec_name,
+ fmime=line.media_mime))
@classmethod
def create(cls, vlist):
diff --git a/locale/de.po b/locale/de.po
index 69df498..7618e5c 100644
--- a/locale/de.po
+++ b/locale/de.po
@@ -14,6 +14,10 @@ msgctxt "model:ir.message,text:msg_file_invalid_mime"
msgid "The file type '%(fmime)s' of the record '%(recname)s' is not allowed. (allowed: PNG, JPG, PDF)"
msgstr "Der Dateityp '%(fmime)s' des Datensatzes '%(recname)s' ist nicht zugelassen. (erlaubt: PNG, JPG, PDF)"
+msgctxt "model:ir.message,text:msg_file_unknown_type"
+msgid "cannot identify image file"
+msgstr "Bilddatei kann nicht identifiziert werden"
+
#################
# cashbook.line #
@@ -42,3 +46,6 @@ msgctxt "field:cashbook.line,media_size:"
msgid "File size"
msgstr "Dateigröße"
+msgctxt "field:cashbook.line,media_image:"
+msgid "Image"
+msgstr "Bild"
diff --git a/locale/en.po b/locale/en.po
index 956e614..5ff9df6 100644
--- a/locale/en.po
+++ b/locale/en.po
@@ -10,6 +10,10 @@ msgctxt "model:ir.message,text:msg_file_invalid_mime"
msgid "The file type '%(fmime)s' of the record '%(recname)s' is not allowed. (allowed: PNG, JPG, PDF)"
msgstr "The file type '%(fmime)s' of the record '%(recname)s' is not allowed. (allowed: PNG, JPG, PDF)"
+msgctxt "model:ir.message,text:msg_file_unknown_type"
+msgid "cannot identify image file"
+msgstr "cannot identify image file"
+
msgctxt "view:cashbook.line:"
msgid "Image/PDF"
msgstr "Image/PDF"
diff --git a/message.xml b/message.xml
index d88ff9a..3582d1e 100644
--- a/message.xml
+++ b/message.xml
@@ -11,6 +11,9 @@ full copyright notices and license terms. -->
The file type '%(fmime)s' of the record '%(recname)s' is not allowed. (allowed: PNG, JPG, PDF)
+
+ cannot identify image file
+
diff --git a/setup.py b/setup.py
index aa97035..c3531db 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@
"""
# Always prefer setuptools over distutils
-from setuptools import setup, find_packages
+from setuptools import setup
# To use a consistent encoding
from codecs import open
from os import path
@@ -36,10 +36,10 @@ with open(path.join(here, 'versiondep.txt'), encoding='utf-8') as f:
l2 = i.strip().split(';')
if len(l2) < 4:
continue
- modversion[l2[0]] = {'min':l2[1], 'max':l2[2], 'prefix':l2[3]}
+ modversion[l2[0]] = {'min': l2[1], 'max': l2[2], 'prefix': l2[3]}
# tryton-version
-major_version = 6
+major_version = 7
minor_version = 0
requires = ['python-magic>=0.4.24', 'Pillow']
@@ -51,42 +51,52 @@ for dep in info.get('depends', []):
prefix = modversion[dep]['prefix']
if len(modversion[dep]['max']) > 0:
- requires.append('%s_%s >= %s, <= %s' %
- (prefix, dep, modversion[dep]['min'], modversion[dep]['max']))
- else :
- requires.append('%s_%s >= %s' %
+ requires.append(
+ '%s_%s >= %s, <= %s' %
+ (prefix, dep,
+ modversion[dep]['min'],
+ modversion[dep]['max']))
+ else:
+ requires.append(
+ '%s_%s >= %s' %
(prefix, dep, modversion[dep]['min']))
- else :
- requires.append('%s_%s >= %s.%s, < %s.%s' %
- ('trytond', dep, major_version, minor_version,
- major_version, minor_version + 1))
-requires.append('trytond >= %s.%s, < %s.%s' %
- (major_version, minor_version, major_version, minor_version + 1))
+ else:
+ requires.append(
+ '%s_%s >= %s.%s, < %s.%s' % (
+ 'trytond', dep, major_version, minor_version,
+ major_version, minor_version + 1))
+requires.append(
+ 'trytond >= %s.%s, < %s.%s' % (
+ major_version, minor_version, major_version, minor_version + 1))
-setup(name='%s_%s' % (PREFIX, MODULE),
+setup(
+ name='%s_%s' % (PREFIX, MODULE),
version=info.get('version', '0.0.1'),
description='Tryton module to add a file-field to cashbook.',
long_description=long_description,
+ long_description_content_type='text/x-rst',
url='https://www.m-ds.de/',
+ download_url='https://scmdev.m-ds.de/Tryton/Extra/cashbook_media',
author='martin-data services',
author_email='service@m-ds.de',
license='GPL-3',
classifiers=[
- 'Development Status :: 5 - Production/Stable',
- 'Environment :: Plugins',
- 'Framework :: Tryton',
- 'Intended Audience :: Developers',
- 'Intended Audience :: Customer Service',
- 'Intended Audience :: Information Technology',
- 'Intended Audience :: Financial and Insurance Industry',
- 'Topic :: Office/Business',
- 'Topic :: Office/Business :: Financial :: Accounting',
- 'Natural Language :: German',
- 'Natural Language :: English',
- 'Operating System :: OS Independent',
- 'License :: OSI Approved :: GNU General Public License (GPL)',
- 'Programming Language :: Python :: 3.7',
- 'Programming Language :: Python :: 3.8',
+ 'Development Status :: 5 - Production/Stable',
+ 'Environment :: Plugins',
+ 'Framework :: Tryton',
+ 'Intended Audience :: Developers',
+ 'Intended Audience :: Customer Service',
+ 'Intended Audience :: Information Technology',
+ 'Intended Audience :: Financial and Insurance Industry',
+ 'Topic :: Office/Business',
+ 'Topic :: Office/Business :: Financial :: Accounting',
+ 'Natural Language :: German',
+ 'Natural Language :: English',
+ 'Operating System :: OS Independent',
+ 'License :: OSI Approved :: GNU General Public License (GPL)',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
],
keywords='tryton cashbook pdf png image file',
@@ -95,7 +105,8 @@ setup(name='%s_%s' % (PREFIX, MODULE),
'trytond.modules.%s' % MODULE,
],
package_data={
- 'trytond.modules.%s' % MODULE: (info.get('xml', [])
+ 'trytond.modules.%s' % MODULE: (
+ info.get('xml', [])
+ ['tryton.cfg', 'locale/*.po', 'tests/*.py',
'view/*.xml', 'versiondep.txt', 'README.rst']),
},
diff --git a/tests/__init__.py b/tests/__init__.py
index fa351bf..4effdfa 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -1,24 +1,2 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
-
-import trytond.tests.test_tryton
-import unittest
-
-from trytond.modules.cashbook_media.tests.test_line import LineTestCase
-
-
-__all__ = ['suite']
-
-
-class CashbookTestCase(\
- LineTestCase,
- ):
- 'Test cashbook module'
- module = 'cashbook_media'
-
-# end CashbookTestCase
-
-def suite():
- suite = trytond.tests.test_tryton.suite()
- suite.addTests(unittest.TestLoader().loadTestsFromTestCase(CashbookTestCase))
- return suite
diff --git a/tests/test_line.py b/tests/test_line.py
index 28fadd9..a6fbe1d 100644
--- a/tests/test_line.py
+++ b/tests/test_line.py
@@ -5,11 +5,10 @@
from io import BytesIO
from PIL import Image
-from trytond.tests.test_tryton import ModuleTestCase, with_transaction
+from trytond.tests.test_tryton import with_transaction
from trytond.pool import Pool
-from trytond.transaction import Transaction
from trytond.exceptions import UserError
-from trytond.modules.cashbook.tests import CashbookTestCase
+from trytond.modules.cashbook.tests.test_module import CashbookTestCase
from datetime import date
from decimal import Decimal
from .img_data import img_data_png, dok_data_pdf, text_data
@@ -126,8 +125,11 @@ class LineTestCase(CashbookTestCase):
self.assertEqual(book.state, 'open')
# add invalid file
- self.assertRaisesRegex(UserError,
- "The file type 'text/plain' of the record '05/02/2022|Rev|1.00 usd|Text 2 [Cat1]' is not allowed. (allowed: PNG, JPG, PDF)",
+ self.assertRaisesRegex(
+ UserError,
+ "The file type 'text/plain' of the record " +
+ "'05/02/2022|Rev|1.00 usd|Text 2 [Cat1]' is not allowed. " +
+ "(allowed: PNG, JPG, PDF)",
Book.write,
*[
[book],
@@ -146,8 +148,11 @@ class LineTestCase(CashbookTestCase):
])
# replace image at line-1 by invalid file
- self.assertRaisesRegex(UserError,
- "The file type 'text/plain' of the record '05/02/2022|Rev|1.00 usd|Text 2 [Cat1]' is not allowed. (allowed: PNG, JPG, PDF)",
+ self.assertRaisesRegex(
+ UserError,
+ "The file type 'text/plain' of the record " +
+ "'05/02/2022|Rev|1.00 usd|Text 2 [Cat1]' is not allowed. " +
+ "(allowed: PNG, JPG, PDF)",
Lines.write,
*[
[book.lines[0]],
@@ -163,7 +168,6 @@ class LineTestCase(CashbookTestCase):
"""
pool = Pool()
Book = pool.get('cashbook.book')
- Lines = pool.get('cashbook.line')
types = self.prep_type()
category = self.prep_category(cattype='in')
@@ -226,3 +230,6 @@ class LineTestCase(CashbookTestCase):
self.assertEqual(img2.size, (2000, 837))
# end LineTestCase
+
+
+del CashbookTestCase
diff --git a/tryton.cfg b/tryton.cfg
index f603792..e0bd666 100644
--- a/tryton.cfg
+++ b/tryton.cfg
@@ -1,5 +1,5 @@
[tryton]
-version=6.0.0
+version=7.0.0
depends:
cashbook
xml:
diff --git a/versiondep.txt b/versiondep.txt
index 7a98af6..bae9199 100644
--- a/versiondep.txt
+++ b/versiondep.txt
@@ -1 +1 @@
-cashbook;6.0.18;6.0.999;mds
+cashbook;7.0.31;7.0.999;mds
diff --git a/view/line_form.xml b/view/line_form.xml
index 6785333..0d80ebc 100644
--- a/view/line_form.xml
+++ b/view/line_form.xml
@@ -13,10 +13,10 @@ full copyright notices and license terms. -->
-
+