|
|
#1 | |
|
Addict
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 295
Karma: 2534928
Join Date: Nov 2022
Location: Canada
Device: Kobo Aura 2
|
Issue with collections template in KoboTouch config
I have a saved template function, transform_awards(). However, the following template code gives an error when trying to set it for the Collections template in the Collections, covers & uploads tab:
Code:
program: transform_awards() Quote:
![]() The code for my template function: Code:
def evaluate(self, formatter, kwargs, metadata, _locals):
awards = metadata.get('#awards')
if not awards:
return ''
transformed_awards = []
for award in awards:
# Split the award record into its components
components = award.split('.')
# Extract the name of the award and the category
award_name = components[0]
award_name = award_name.removesuffix(' Award').removesuffix(' Awards')
category_name = components[1]
category_name = category_name.removeprefix('Best ')
# Extract the year from the record and determine the decade it falls in
year = int(components[2])
decade = str(year // 10 * 10) + "s"
# Extract the rank from the record and determine whether or not it is a winner
rank = components[3]
if rank == "winner":
rank_message = "winners"
else:
rank_message = "nominees, etc."
# Combine the components into the desired format
transformed_awards.append(f"Awards: {award_name}, {category_name} ({rank_message})")
return ':@:'.join(transformed_awards)
Thank you!
Last edited by isarl; 08-12-2025 at 09:02 PM. |
|
|
|
|
|
|
#2 |
|
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,525
Karma: 8065948
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
The template check works on fake metadata, not real books. This means that the contents of #awards is a single word, "#awards". Your template fails in this case because it expects any value to be a triplet. Change the template to handle "malformed" awards, ones that don't have the "correct" number of periods, by checking the length of components after the split().
|
|
|
|
| Advert | |
|
|
|
|
#3 |
|
Addict
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 295
Karma: 2534928
Join Date: Nov 2022
Location: Canada
Device: Kobo Aura 2
|
Ah, I need to validate the result of the split has the expected number of components. So obvious now that you point it out – thank you very much!
|
|
|
|
|
|
#4 |
|
Addict
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 295
Karma: 2534928
Join Date: Nov 2022
Location: Canada
Device: Kobo Aura 2
|
Just in case anybody else finds it helpful, my updated, now functional, template:
Code:
def evaluate(self, formatter, kwargs, metadata, _locals):
awards = metadata.get('#awards')
if not awards:
return ''
transformed_awards = []
for award in awards:
# Split the award record into its components
components = award.split('.')
if len(components) < 4:
return 'error with award: ' + award
# Extract the name of the award and the category
award_name = components[0]
award_name = award_name.removesuffix(' Award').removesuffix(' Awards')
category_name = components[1]
category_name = category_name.removeprefix('Best ')
# Extract the year from the record and determine the decade it falls in
year = int(components[2])
decade = str(year // 10 * 10) + "s"
# Extract the rank from the record and determine whether or not it is a winner
rank = components[3]
if rank == "winner":
rank_message = "winners"
else:
rank_message = "nominees, etc."
# Combine the components into the desired format
transformed_awards.append(f"Awards: {award_name}, {category_name} ({rank_message})")
return ':@:'.join(transformed_awards)
|
|
|
|
|
|
#5 |
|
Grand Sorcerer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 12,525
Karma: 8065948
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
|
Looking at the rest of the template, don't you want to either limit the split to the first 3 commas (maxsplit=3) or (preferred by me) check that the len(components) == 4? And to be complete, you should check that int(components[2]) doesn't throw a ValueError exception.
|
|
|
|
| Advert | |
|
|
|
|
#6 |
|
Addict
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 295
Karma: 2534928
Join Date: Nov 2022
Location: Canada
Device: Kobo Aura 2
|
Good points, thank you!
Yes, it's probably better to check that len(components) is exactly 4, as more than 4 would also be a problem. (I initially posted the fixed code checking against 3, then noticed my error and edited my above post.)In fact I could probably be doing a lot more validation here, like adding a whitelist for known awards or to make sure that the rank field looks right (i.e., is a known word or a positive integer). Since this template is for transforming metadata on the fly while loading books onto my device, I will probably repurpose that added validation elsewhere as well, e.g. to show me a warning icon in my library view for books which fail. Thanks again for the debugging help! <3 Last edited by isarl; 08-14-2025 at 04:40 AM. Reason: oops, no markdown here! |
|
|
|
![]() |
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| URGENT: Calibre Config Lost + Template Functions Fail (Formatter Expected 'then' in P | howens | Library Management | 5 | 05-25-2025 12:18 PM |
| [GUI Plugin] KoboTouch Config Button | Comfy.n | Plugins | 0 | 04-20-2025 04:22 PM |
| Kobo Libra2: template collections not created | chaley | Devices | 3 | 06-08-2022 01:33 AM |
| [Kobo] Collections: using a template | chaley | Devices | 9 | 05-03-2022 11:36 AM |
| save template and collections/folders | 2nise | Library Management | 4 | 10-09-2019 11:01 AM |