Skip to content

Commit 3fc2244

Browse files
committed
actions: better language management
* Adds decorator to inject language from the current patron session or client. * Sends the language to action handler when if possible. * Bumps dependencies. Co-Authored-by: Lauren-D <laurent.dubois@itld-solutions.be>
1 parent 909c2a2 commit 3fc2244

File tree

4 files changed

+650
-99
lines changed

4 files changed

+650
-99
lines changed

invenio_sip2/actions/actions.py

Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@
2121

2222
from invenio_sip2.actions.base import Action
2323
from invenio_sip2.api import Message
24-
from invenio_sip2.decorators import add_sequence_number, check_selfcheck_authentication
24+
from invenio_sip2.decorators import (
25+
add_sequence_number,
26+
check_selfcheck_authentication,
27+
extract_and_add_language_parameter,
28+
)
2529
from invenio_sip2.errors import SelfcheckCirculationError, SelfcheckError
2630
from invenio_sip2.handlers import (
2731
authorize_patron_handler,
@@ -88,17 +92,22 @@ class AutomatedCirculationSystemStatus(Action):
8892
"""Action to get status from automated circulation system."""
8993

9094
@check_selfcheck_authentication
95+
@extract_and_add_language_parameter
9196
@add_sequence_number
92-
def execute(self, message, client):
97+
def execute(self, message, client, language):
9398
"""Execute automated circulation system status action.
9499
95100
:param message: message receive from the client
96101
:param client: the client
102+
:param language: the client language
97103
:return: message class representing the response of the current action
98104
"""
99105
# TODO : calculate system status from remote app
100106
status = system_status_handler(
101-
client.remote_app, client.terminal, institution_id=client.institution_id
107+
client.remote_app,
108+
client.terminal,
109+
institution_id=client.institution_id,
110+
language=language,
102111
)
103112
current_logger.debug(
104113
f"[AutomatedCirculationSystemStatus]: " f"handler response: {status}"
@@ -163,22 +172,29 @@ class PatronEnable(Action):
163172
"""Action to enable patron on automated circulation system."""
164173

165174
@check_selfcheck_authentication
175+
@extract_and_add_language_parameter
166176
@add_sequence_number
167-
def execute(self, message, client):
177+
def execute(self, message, client, language):
168178
"""Execute enable patron action.
169179
170180
:param message: message receive from the client
171181
:param client: the client
182+
:param language: the client language
172183
:return: message class representing the response of the current action
173184
"""
174185
patron_id = message.get_field_value("patron_id")
175-
176186
is_valid_patron = validate_patron_handler(
177-
client.remote_app, patron_id, institution_id=client.institution_id
187+
client.remote_app,
188+
patron_id,
189+
institution_id=client.institution_id,
190+
language=language,
178191
)
179192

180193
enabled_patron = enable_patron_handler(
181-
client.remote_app, patron_id, institution_id=client.institution_id
194+
client.remote_app,
195+
patron_id,
196+
institution_id=client.institution_id,
197+
language=language,
182198
)
183199
current_logger.debug(f"[PatronEnable]: handler response: {enabled_patron}")
184200
# prepare message based on required fields
@@ -223,17 +239,22 @@ class PatronStatus(Action):
223239
"""Action to get patron status from automated circulation system."""
224240

225241
@check_selfcheck_authentication
242+
@extract_and_add_language_parameter
226243
@add_sequence_number
227-
def execute(self, message, client):
244+
def execute(self, message, client, language):
228245
"""Execute patron status action.
229246
230247
:param message: message receive from the client
231248
:param client: the client
249+
:param language: the client language
232250
:return: message class representing the response of the current action
233251
"""
234252
patron_id = message.get_field_value("patron_id")
235253
patron_status = patron_status_handler(
236-
client.remote_app, patron_id, institution_id=client.institution_id
254+
client.remote_app,
255+
patron_id,
256+
institution_id=client.institution_id,
257+
language=language,
237258
)
238259
current_logger.debug(f"[PatronStatus]: handler response: {patron_status}")
239260
response_message = self.prepare_message_response(
@@ -265,19 +286,23 @@ def execute(self, message, client):
265286
"""
266287
patron_id = message.get_field_value("patron_id")
267288
patron_account = patron_handler(
268-
client.remote_app, patron_id, institution_id=client.institution_id
289+
client.remote_app,
290+
patron_id,
291+
institution_id=client.institution_id,
292+
language=message.i18n_language,
269293
)
270294
current_logger.debug(f"[PatronInformation]: handler response: {patron_account}")
271295
# TODO: better way to begin session
272296
# start patron session
297+
patron_language = patron_account.get("language", message.i18n_language)
273298
client["patron_session"] = {
274299
"patron_id": patron_id,
275-
"language": message.i18n_language,
300+
"language": patron_language,
276301
}
277302
# prepare message based on required fields
278303
response_message = self.prepare_message_response(
279304
patron_status=str(patron_account.get("patron_status")),
280-
language=get_language_code(patron_account.get("language")),
305+
language=get_language_code(patron_language),
281306
transaction_date=acs_system.sip2_current_date,
282307
hold_items_count=str(patron_account.hold_items_count),
283308
overdue_items_count=str(patron_account.overdue_items_count),
@@ -350,19 +375,16 @@ class ItemInformation(Action):
350375
"""Action to get item information from automated circulation system."""
351376

352377
@check_selfcheck_authentication
378+
@extract_and_add_language_parameter
353379
@add_sequence_number
354-
def execute(self, message, client):
380+
def execute(self, message, client, language):
355381
"""Execute item information action.
356382
357383
:param message: message receive from the client
358384
:param client: the client
385+
:param language: the client language
359386
:return: message class representing the response of the current action
360387
"""
361-
patron_session = client.get_current_patron_session()
362-
if patron_session:
363-
language = patron_session.get("language")
364-
else:
365-
language = client.library_language
366388
item_identifier = message.get_field_value("item_id")
367389
item_information = item_handler(
368390
client.remote_app,
@@ -401,12 +423,14 @@ class BlockPatron(Action):
401423
"""Action to block patron."""
402424

403425
@check_selfcheck_authentication
426+
@extract_and_add_language_parameter
404427
@add_sequence_number
405-
def execute(self, message, client, **kwargs):
428+
def execute(self, message, client, language, **kwargs):
406429
"""Execute block patron action.
407430
408431
:param message: message receive from the client
409432
:param client: the client
433+
:param language: the client language
410434
:return: message class representing the response of the current action
411435
"""
412436
# TODO: implements action
@@ -417,21 +441,17 @@ class Checkin(Action):
417441
"""Action to checkin an item."""
418442

419443
@check_selfcheck_authentication
444+
@extract_and_add_language_parameter
420445
@add_sequence_number
421-
def execute(self, message, client, **kwargs):
446+
def execute(self, message, client, language, **kwargs):
422447
"""Execute checkin action.
423448
424449
:param message: message receive from the client
425450
:param client: the client
451+
:param language: the client language
426452
:return: message class representing the response of the current action
427453
"""
428-
patron_session = client.get_current_patron_session()
429-
if patron_session:
430-
language = patron_session.get("language")
431-
else:
432-
language = client.library_language
433454
item_id = message.get_field_value("item_id")
434-
435455
try:
436456
# TODO: give the client to reduce the number of parameters.
437457
checkin = checkin_handler(
@@ -478,19 +498,16 @@ class Checkout(Action):
478498
"""Action to checkout an item."""
479499

480500
@check_selfcheck_authentication
501+
@extract_and_add_language_parameter
481502
@add_sequence_number
482-
def execute(self, message, client, **kwargs):
503+
def execute(self, message, client, language, **kwargs):
483504
"""Execute checkout action.
484505
485506
:param message: message receive from the client
486507
:param client: the client
508+
:param language: the client language
487509
:return: message class representing the response of the current action
488510
"""
489-
patron_session = client.get_current_patron_session()
490-
if patron_session:
491-
language = patron_session.get("language")
492-
else:
493-
language = client.library_language
494511
item_id = message.get_field_value("item_id")
495512
patron_id = message.get_field_value("patron_id")
496513

@@ -537,19 +554,16 @@ class FeePaid(Action):
537554
"""Action to paid fee."""
538555

539556
@check_selfcheck_authentication
557+
@extract_and_add_language_parameter
540558
@add_sequence_number
541-
def execute(self, message, client, **kwargs):
559+
def execute(self, message, client, language, **kwargs):
542560
"""Execute fee paid action.
543561
544562
:param message: message receive from the client
545563
:param client: the client
564+
:param language: the client language
546565
:return: message class representing the response of the current action
547566
"""
548-
patron_session = client.get_current_patron_session()
549-
if patron_session:
550-
language = patron_session.get("language")
551-
else:
552-
language = client.library_language
553567
patron_id = message.get_field_value("patron_id")
554568
try:
555569
fee_paid = fee_paid_handler(
@@ -591,15 +605,16 @@ class Hold(Action):
591605
"""Action to hold an item."""
592606

593607
@check_selfcheck_authentication
608+
@extract_and_add_language_parameter
594609
@add_sequence_number
595-
def execute(self, message, client, **kwargs):
610+
def execute(self, message, client, language, **kwargs):
596611
"""Execute hold action.
597612
598613
:param message: message receive from the client
599614
:param client: the client
615+
:param language: the client language
600616
:return: message class representing the response of the current action
601617
"""
602-
patron_session = client.get_current_patron_session()
603618
item_id = message.get_field_value("item_id")
604619
patron_id = message.get_field_value("patron_id")
605620

@@ -611,7 +626,7 @@ def execute(self, message, client, **kwargs):
611626
patron_id=patron_id,
612627
institution_id=client.institution_id,
613628
terminal=client.terminal,
614-
language=patron_session.get("language"),
629+
language=language,
615630
)
616631
except SelfcheckCirculationError as error:
617632
hold = error.data
@@ -647,15 +662,16 @@ class Renew(Action):
647662
"""Action to renew an item."""
648663

649664
@check_selfcheck_authentication
665+
@extract_and_add_language_parameter
650666
@add_sequence_number
651-
def execute(self, message, client, **kwargs):
667+
def execute(self, message, client, language, **kwargs):
652668
"""Execute renew action.
653669
654670
:param message: message receive from the client
655671
:param client: the client
672+
:param language: the client language
656673
:return: message class representing the response of the current action
657674
"""
658-
patron_session = client.get_current_patron_session()
659675
item_id = message.get_field_value("item_id")
660676
patron_id = message.get_field_value("patron_id")
661677

@@ -667,7 +683,7 @@ def execute(self, message, client, **kwargs):
667683
patron_id=patron_id,
668684
intitution_id=client.institution_id,
669685
terminal=client.terminal,
670-
language=patron_session.get("language"),
686+
language=language,
671687
)
672688
except SelfcheckCirculationError as error:
673689
renew = error.data
@@ -707,12 +723,14 @@ class RenewAll(Action):
707723
"""Action to renew all items."""
708724

709725
@check_selfcheck_authentication
726+
@extract_and_add_language_parameter
710727
@add_sequence_number
711-
def execute(self, message, client, **kwargs):
728+
def execute(self, message, client, language, **kwargs):
712729
"""Execute renew all action.
713730
714731
:param message: message receive from the client
715732
:param client: the client
733+
:param language: the client language
716734
:return: message class representing the response of the current action
717735
"""
718736
# TODO: implements action
@@ -723,12 +741,14 @@ class ItemStatusUpdate(Action):
723741
"""Action to update item status."""
724742

725743
@check_selfcheck_authentication
744+
@extract_and_add_language_parameter
726745
@add_sequence_number
727-
def execute(self, message, client, **kwargs):
746+
def execute(self, message, client, language, **kwargs):
728747
"""Execute item status action.
729748
730749
:param message: message receive from the client
731750
:param client: the client
751+
:param language: the client language
732752
:return: message class representing the response of the current action
733753
"""
734754
# TODO: implements action

invenio_sip2/decorators.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,36 @@ def wrapper(*args, **kwargs):
6767
return result
6868

6969
return wrapper
70+
71+
72+
def extract_and_add_language_parameter(func):
73+
"""Decorator to extract and add language.
74+
75+
Extracts the language from the client and injects it into the wrapped
76+
function as a `language` argument.
77+
"""
78+
79+
@wraps(func)
80+
def wrapper(*args, **kwargs):
81+
# Try to retrieve the `client` argument:
82+
# 1. from keyword arguments
83+
# 2. or from positional arguments by looking for an object
84+
# that has a method named `get_current_patron_session`
85+
client = kwargs.get("client") or next(
86+
(a for a in args if hasattr(a, "get_current_patron_session")), None
87+
)
88+
89+
if client is None:
90+
raise ValueError("Client not found")
91+
92+
# Try to get the language from the patron session first,
93+
# otherwise fall back to the client's `library_language`
94+
patron_session = client.get_current_patron_session()
95+
language = (patron_session or {}).get("language") or client.get(
96+
"library_language"
97+
)
98+
99+
# Call the original function, injecting the language
100+
return func(*args, language=language, **kwargs)
101+
102+
return wrapper

0 commit comments

Comments
 (0)