Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Changelog

- Do not let `Recreate session` when it is `sent` or `signed`.
[gbastien]
- Formalised the sent filename generation in `ISignable.get_filename` (PARAF-550).
[chris-adam]

1.0.2 (2026-08-24)
------------------
Expand Down
15 changes: 15 additions & 0 deletions src/imio/esign/adapters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from imio.esign.utils import get_session_annotation
from imio.esign.utils import get_session_info
from imio.helpers.transmogrifier import get_correct_id
from os import path
from plone.memoize import ram
from zope.interface import Interface

Expand Down Expand Up @@ -80,6 +82,10 @@ def get_discriminators(self):
def get_create_session_custom_data(self):
return {}

def get_filename(self, annex, existing_files=()):
filename, ext = path.splitext(annex.file.filename or u"no_filename.pdf")
return get_correct_id(existing_files, filename) + ext


class ISignable(Interface):
def get_signers(self):
Expand Down Expand Up @@ -118,3 +124,12 @@ def get_create_session_custom_data(self):
in the annotation.
"""
return {}

def get_filename(self, annex, existing_files=()):
"""
Return the filename to use for that element in the session.

`existing_files` holds the names (without extension) already used in the
session, to keep them unique.
"""
return u""
5 changes: 5 additions & 0 deletions src/imio/esign/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
<include package=".browser" />
<include package=".services" />

<adapter
factory=".adapters.SignableAdapter"
provides=".adapters.ISignable"
for="*" />

<adapter
factory=".adapters.DefaultContextUidProvider"
provides=".interfaces.IContextUidProvider"
Expand Down
13 changes: 8 additions & 5 deletions src/imio/esign/events.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-

from Acquisition import aq_parent
from imio.esign.adapters import ISignable
from imio.esign.utils import get_file_info
from imio.esign.utils import get_session_annotation
from imio.esign.utils import get_sessions_for
from imio.esign.utils import remove_files_from_session
from imio.helpers.transmogrifier import get_correct_id
from os import path


Expand Down Expand Up @@ -57,10 +58,12 @@ def on_categorized_annex_updated(annex, event):
file_data["scan_id"] = annex.scan_id
# filename changed, need to make sure new filename is unique
if annex.file.filename != file_data["filename"]:
existing_files = [path.splitext(f["filename"])[0] for f in session["files"]]
filename, ext = path.splitext(annex.file.filename)
new_filename = get_correct_id(existing_files, filename)
file_data["filename"] = new_filename + ext
existing_files = [

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ici le if f["uid"] != annex_uid peut être utile si le nom précédent correspond au nouveau nom généré par get_correct_id, donc bien vu, mais on pourrait même ajouter un test :-)

path.splitext(f["filename"])[0] for f in session["files"] if f["uid"] != annex_uid
]
file_data["filename"] = ISignable(aq_parent(annex)).get_filename(
annex, existing_files=existing_files
)
# file_uid is only there one time per session
break

Expand Down
5 changes: 0 additions & 5 deletions src/imio/esign/testing.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,4 @@

<include file="configure.zcml" />

<adapter
for="*"
factory="imio.esign.adapters.SignableAdapter"
provides="imio.esign.adapters.ISignable"/>

</configure>
24 changes: 24 additions & 0 deletions src/imio/esign/tests/test_adapters.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-

from imio.esign.adapters import DefaultContextUidProvider
from imio.esign.adapters import ISignable
from imio.esign.adapters import SignableAdapter
from imio.esign.interfaces import IContextUidProvider
from imio.esign.interfaces import IItemOrderProvider
from imio.esign.tests.base import BaseEsignTest
Expand Down Expand Up @@ -35,3 +37,25 @@ def test_get_item_order(self):
empty = api.content.create(container=self.portal, type="Folder", id="empty-folder")
provider = getAdapter(empty, IItemOrderProvider)
self.assertEqual(provider.get_item_order(), {})


class TestSignableAdapter(BaseEsignTest):

def test_get_filename(self):
annex = self.portal["folder0"]["annex0"]
adapter = getAdapter(annex.aq_parent, ISignable)
self.assertIsInstance(adapter, SignableAdapter)
self.assertEqual(adapter.get_filename(annex), u"annex0.pdf")
# a name already used in the session gets a numbered suffix
self.assertEqual(adapter.get_filename(annex, existing_files=["annex0"]), u"annex0-1.pdf")
self.assertEqual(adapter.get_filename(annex, existing_files=["annex0", "annex0-1"]), u"annex0-2.pdf")
# a __<uid> suffix is kept: imio.zamqp parses it back

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ce fonctionnement est propre à dmsmail mais çà pourrait devenir le fonctionnement de base (pas inutile d'avoir l'uid dans le nom du fichier en cas de debug ou autre) mais le problème actuellement c'est que çà apparaît sans doute dans l'interface de Cosi (à vérifier), si il y a la notion de "friendly pdf name" dans Cosi avec possibilité d'afficher un titre qui n'est pas l'id du fichier pdf, çà pourrait rentrer dans le comportement par défaut...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oui, ça s'affiche dans l'interface COSI. Samuel me dit qu'il va chercher comment faire pour avoir ce "friendly pdf name"
image

annex.file.filename = u"Rapport__{}.pdf".format(annex.UID())
self.assertEqual(adapter.get_filename(annex), u"Rapport__{}.pdf".format(annex.UID()))
# and it survives deduplication, the suffix landing after the uid
self.assertEqual(
adapter.get_filename(annex, existing_files=["Rapport__{}".format(annex.UID())]),
u"Rapport__{}-1.pdf".format(annex.UID()),
)
annex.file.filename = None
self.assertEqual(adapter.get_filename(annex), u"no_filename.pdf")
25 changes: 25 additions & 0 deletions src/imio/esign/tests/test_events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-
"""events tests for this package."""
from imio.esign.tests.base import BaseEsignTest
from imio.esign.utils import add_files_to_session
from zope.event import notify
from zope.lifecycleevent import ObjectModifiedEvent


class TestEvents(BaseEsignTest):
def test_on_categorized_annex_updated(self):
"""Renaming an annex keeps its session filename unique, without conflicting with itself."""
signers = [("user1", "user1@sign.com", "User 1", "Position 1")]
annex0 = self.portal["folder0"]["annex0"]
annex2 = self.portal["folder0"]["annex2"]
sid, session = add_files_to_session(signers, (annex0.UID(), annex2.UID()))[-1]
self.assertEqual([f["filename"] for f in session["files"]], [u"annex0.pdf", u"annex2.pdf"])
# renamed to a name already used in the session: deduplicated
annex2.file.filename = u"annex0.pdf"
notify(ObjectModifiedEvent(annex2))
self.assertEqual([f["filename"] for f in session["files"]], [u"annex0.pdf", u"annex0-1.pdf"])
# updated again: the generated name is the one it already has, it must not drift to annex0-2.pdf
annex2.setTitle("New Annex 2")
notify(ObjectModifiedEvent(annex2))
self.assertEqual([f["filename"] for f in session["files"]], [u"annex0.pdf", u"annex0-1.pdf"])
self.assertEqual(session["files"][1]["title"], "New Annex 2")
9 changes: 4 additions & 5 deletions src/imio/esign/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-

from Acquisition import aq_parent
from collections import OrderedDict
from copy import deepcopy
from datetime import datetime
Expand All @@ -19,7 +20,6 @@
from imio.esign.interfaces import IContextUidProvider
from imio.esign.interfaces import IItemOrderProvider
from imio.helpers.content import uuidToObject
from imio.helpers.transmogrifier import get_correct_id
from imio.helpers.ws import get_auth_token
# from imio.pyutils.system import post_request
from imio.pyutils.utils import shortuid_encode_id
Expand Down Expand Up @@ -101,6 +101,7 @@ def add_files_to_session( # noqa C901
session = annot["sessions"][session_id]
dispatch = session_id is None
sessions_used = []
from imio.esign.adapters import ISignable # avoid circular import

for uid in files_uids:
file_size = get_filesize(uid)
Expand Down Expand Up @@ -135,13 +136,11 @@ def add_files_to_session( # noqa C901
logger.info("File with UID %s is already in session_id %s and data were updated!", uid, session_id)
remove_files_from_session([uid], remove_empty_session=False)

existing_files = [path.splitext(f["filename"])[0] for f in session["files"]]
filename, ext = path.splitext(annex.file.filename or "no_filename.pdf")
new_filename = get_correct_id(existing_files, filename)
existing_files = [path.splitext(f["filename"])[0] for f in session["files"] if f["uid"] != uid]
file_dict = PersistentMapping(
{
"scan_id": annex.scan_id,
"filename": new_filename + ext,
"filename": ISignable(aq_parent(annex)).get_filename(annex, existing_files=existing_files),
"title": annex.title or "no_title",
"uid": uid,
"context_uid": context_uid,
Expand Down
Loading