Skip to content

Commit 9deafe9

Browse files
committed
Integrate pyformat with localize()
By integrating string formattig with the localize() function call we can make both the translations easier to comprehend, as well as the code more transparant/readable. And by using SafeDict() it is also more reliable if arguments do not add up. When a key is not found the 'template' remains in the string.
1 parent 4becfc0 commit 9deafe9

File tree

10 files changed

+86
-37
lines changed

10 files changed

+86
-37
lines changed

resources/language/resource.language.en_gb/strings.po

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -634,11 +634,11 @@ msgid "Please increase the maximum bandwidth. Maximum bandwidth is set to {max}
634634
msgstr ""
635635

636636
msgctxt "#30958"
637-
msgid "There is a problem with this VRT NU %s stream. Try again with %s %s %s or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/"
637+
msgid "There is a problem with this VRT NU {protocol} stream. Try again with {component} {state} or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/"
638638
msgstr ""
639639

640640
msgctxt "#30959"
641-
msgid "and Widevine DRM"
641+
msgid "InputStream Adaptive and Widevine DRM"
642642
msgstr ""
643643

644644
msgctxt "#30960"
@@ -650,7 +650,7 @@ msgid "enabled"
650650
msgstr ""
651651

652652
msgctxt "#30962"
653-
msgid "There is a problem with this VRT NU %s stream and Kodi %s does not support the alternative stream. Please upgrade to a newer Kodi version or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/"
653+
msgid "There is a problem with this VRT NU {protocol} stream and Kodi {version} does not support the alternative stream. Please upgrade to a newer Kodi version or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/"
654654
msgstr ""
655655

656656
msgctxt "#30965"
@@ -678,7 +678,7 @@ msgid "Failed to get favorites token from VRT NU"
678678
msgstr ""
679679

680680
msgctxt "#30976"
681-
msgid "Failed to (un)follow program '%s' at VRT NU"
681+
msgid "Failed to (un)follow program '{program}' at VRT NU"
682682
msgstr ""
683683

684684
msgctxt "#30978"
@@ -714,7 +714,7 @@ msgid "Successfully cleared VRT tokens."
714714
msgstr ""
715715

716716
msgctxt "#30986"
717-
msgid "No on demand stream available for %s."
717+
msgid "No on demand stream available for {title}."
718718
msgstr ""
719719

720720
msgctxt "#30990"

resources/language/resource.language.nl_nl/strings.po

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -526,12 +526,12 @@ msgid "Please increase the maximum bandwidth. Maximum bandwidth is set to {max}
526526
msgstr "Verhoog de maximale bandbreedte alstublieft. De maximale bandbreedte is ingesteld op {max} kbps, maar deze stream heeft minimum {min} kbps nodig."
527527

528528
msgctxt "#30958"
529-
msgid "There is a problem with this VRT NU %s stream. Try again with %s %s %s or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/"
530-
msgstr "Er is een probleem met deze VRT NU %s-stream. Probeer het opnieuw met %s %s %s of probeer dit programma af te spelen vanaf de VRT NU-website. Meld dit probleem op https://www.vrt.be/vrtnu/help/"
529+
msgid "There is a problem with this VRT NU {protocol} stream. Try again with {component} {state} or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/"
530+
msgstr "Er is een probleem met deze VRT NU {protocol}-stream. Probeer het opnieuw met {component} {state} of probeer dit programma af te spelen vanaf de VRT NU-website. Meld dit probleem op https://www.vrt.be/vrtnu/help/"
531531

532532
msgctxt "#30959"
533-
msgid "and Widevine DRM"
534-
msgstr "en Widevine DRM"
533+
msgid "InputStream Adaptive and Widevine DRM"
534+
msgstr "InputStream Adaptive en Widevine DRM"
535535

536536
msgctxt "#30960"
537537
msgid "disabled"
@@ -542,8 +542,8 @@ msgid "enabled"
542542
msgstr "ingeschakeld"
543543

544544
msgctxt "#30962"
545-
msgid "There is a problem with this VRT NU %s stream and Kodi %s does not support the alternative stream. Please upgrade to a newer Kodi version or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/"
546-
msgstr "Er is een probleem met deze VRT NU %s-stream en Kodi %s ondersteunt de alternatieve stream niet. Schakel over op een nieuwere versie van Kodi of probeer dit programma af te spelen vanaf de VRT NU-website. Meld dit probleem op https://www.vrt.be/vrtnu/help/"
545+
msgid "There is a problem with this VRT NU {protocol} stream and Kodi {version} does not support the alternative stream. Please upgrade to a newer Kodi version or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/"
546+
msgstr "Er is een probleem met deze VRT NU {protocol}-stream en Kodi {version} ondersteunt de alternatieve stream niet. Schakel over op een nieuwere versie van Kodi of probeer dit programma af te spelen vanaf de VRT NU-website. Meld dit probleem op https://www.vrt.be/vrtnu/help/"
547547

548548
msgctxt "#30965"
549549
msgid "Using a SOCKS proxy requires the PySocks library (script.module.pysocks) installed."
@@ -570,8 +570,8 @@ msgid "Failed to get favorites token from VRT NU"
570570
msgstr "Ophalen van het favorieten token van VRT NU is mislukt"
571571

572572
msgctxt "#30976"
573-
msgid "Failed to (un)follow program '%s' at VRT NU"
574-
msgstr "Het programma '%s' op VRT NU volgen of vergeten is mislukt"
573+
msgid "Failed to (un)follow program '{program}' at VRT NU"
574+
msgstr "Het programma '{program}' op VRT NU volgen of vergeten is mislukt"
575575

576576
msgctxt "#30978"
577577
msgid "Welcome to VRT NU add-on v2.0.0"
@@ -606,8 +606,8 @@ msgid "Successfully cleared VRT tokens."
606606
msgstr "VRT tokens werden verwijderd."
607607

608608
msgctxt "#30986"
609-
msgid "No on demand stream available for %s."
610-
msgstr "Geen on demand stream beschikbaar voor %s"
609+
msgid "No on demand stream available for {title}."
610+
msgstr "Geen on demand stream beschikbaar voor {title}"
611611

612612
msgctxt "#30990"
613613
msgid "This program cannot be played. To view this program outside of Belgium, you first have to validate a Belgian mobile phone number on the VRT NU website."

resources/lib/favorites.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ def set_favorite(self, program, title, value=True):
6565

6666
xvrttoken = self._tokenresolver.get_xvrttoken(token_variant='user')
6767
if xvrttoken is None:
68-
self._kodi.show_notification(message=self._kodi.localize(30975))
6968
self._kodi.log_error('Failed to get favorites token from VRT NU')
69+
self._kodi.show_notification(message=self._kodi.localize(30975))
7070
return False
7171

7272
headers = {
@@ -81,8 +81,8 @@ def set_favorite(self, program, title, value=True):
8181
req = Request('https://video-user-data.vrt.be/favorites/%s' % self.uuid(program), data=data, headers=headers)
8282
result = urlopen(req)
8383
if result.getcode() != 200:
84-
self._kodi.show_notification(message=self._kodi.localize(30976) % program)
85-
self._kodi.log_error("Failed to (un)follow program '%s' at VRT NU" % program)
84+
self._kodi.log_error("Failed to (un)follow program '{program}' at VRT NU".format(program=program))
85+
self._kodi.show_notification(message=self._kodi.localize(30976, program=program))
8686
return False
8787
# NOTE: Updates to favorites take a longer time to take effect, so we keep our own cache and use it
8888
self._favorites[self.uuid(program)] = dict(value=payload)

resources/lib/kodiwrapper.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ def has_socks():
100100
return has_socks.installed
101101

102102

103+
class SafeDict(dict):
104+
''' A safe dictionary implementation that does not break down on missing keys '''
105+
def __missing__(self, key):
106+
''' Replace missing keys with the original placeholder '''
107+
return '{' + key + '}'
108+
109+
103110
class KodiWrapper:
104111
''' A wrapper around all Kodi functionality '''
105112

@@ -291,8 +298,12 @@ def set_locale(self):
291298
self.log_notice("Your system does not support locale '%s': %s" % (locale_lang, e), 'Debug')
292299
return False
293300

294-
def localize(self, string_id):
295-
''' Return the translated string from the .po language files '''
301+
def localize(self, string_id, **kwargs):
302+
''' Return the translated string from the .po language files, optionally translating variables '''
303+
if kwargs:
304+
import string
305+
return string.Formatter().vformat(self._addon.getLocalizedString(string_id), (), SafeDict(**kwargs))
306+
296307
return self._addon.getLocalizedString(string_id)
297308

298309
def localize_date(self, date, strftime):

resources/lib/search.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def search(self, keywords=None, page=None):
7474
self.add(keywords)
7575
search_items, sort, ascending, content = self._apihelper.get_search_items(keywords, page=page)
7676
if not search_items:
77-
self._kodi.show_ok_dialog(heading=self._kodi.localize(30098), message=self._kodi.localize(30099).format(keywords=keywords))
77+
self._kodi.show_ok_dialog(heading=self._kodi.localize(30098), message=self._kodi.localize(30099, keywords=keywords))
7878
self._kodi.end_of_directory()
7979
return
8080

resources/lib/streamservice.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,15 +291,15 @@ def _handle_bad_stream_error(self, protocol):
291291
'''
292292
# HLS AES DRM failed
293293
if protocol == 'hls_aes' and not self._kodi.supports_drm():
294-
message = self._kodi.localize(30962) % (protocol.upper(), self._kodi.kodi_version())
294+
message = self._kodi.localize(30962, protocol=protocol.upper(), version=self._kodi.kodi_version())
295295
elif protocol == 'hls_aes' and not self._kodi.has_inputstream_adaptive() and self._kodi.get_setting('usedrm', 'true') == 'false':
296-
message = self._kodi.localize(30958) % (protocol.upper(), 'InputStream Adaptive', self._kodi.localize(30959), self._kodi.localize(30961))
296+
message = self._kodi.localize(30958, protocol=protocol.upper(), component=self._kodi.localize(30959), state=self._kodi.localize(30961))
297297
elif protocol == 'hls_aes' and self._kodi.has_inputstream_adaptive():
298-
message = self._kodi.localize(30958) % (protocol.upper(), 'Widevine DRM', '', self._kodi.localize(30961))
298+
message = self._kodi.localize(30958, protocol=protocol.upper(), component='Widevine DRM', state=self._kodi.localize(30961))
299299
elif protocol == 'hls_aes' and self._kodi.get_setting('usedrm', 'true') == 'true':
300-
message = self._kodi.localize(30958) % (protocol.upper(), 'InputStream Adaptive', '', self._kodi.localize(30961))
300+
message = self._kodi.localize(30958, protocol=protocol.upper(), component='InputStream Adaptive', state=self._kodi.localize(30961))
301301
else:
302-
message = self._kodi.localize(30958) % (protocol.upper(), 'InputStream Adaptive', '', self._kodi.localize(30960))
302+
message = self._kodi.localize(30958, protocol=protocol.upper(), component='InputStream Adaptive', state=self._kodi.localize(30960))
303303
self._kodi.show_ok_dialog(message=message)
304304
self._kodi.end_of_directory()
305305

@@ -338,7 +338,7 @@ def _select_hls_substreams(self, master_hls_url, protocol):
338338
break
339339

340340
if stream_bandwidth > max_bandwidth and not hls_variant_url:
341-
message = self._kodi.localize(30057).format(max=max_bandwidth, min=stream_bandwidth)
341+
message = self._kodi.localize(30057, max=max_bandwidth, min=stream_bandwidth)
342342
self._kodi.show_ok_dialog(message=message)
343343
self._kodi.open_settings()
344344

resources/lib/tvguide.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def show_channel_menu(self, date):
110110

111111
fanart = 'resource://resource.images.studios.coloured/%(studio)s.png' % channel
112112
thumb = 'resource://resource.images.studios.white/%(studio)s.png' % channel
113-
plot = '%s\n%s' % (self._kodi.localize(30301).format(**channel), datelong)
113+
plot = '%s\n%s' % (self._kodi.localize(30301, **channel), datelong)
114114
channel_items.append(TitleItem(
115115
title=channel.get('label'),
116116
path=self._kodi.url_for('tvguide', date=date, channel=channel.get('name')),

resources/lib/vrtapihelper.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -400,12 +400,12 @@ def episode_to_listitem(self, episode, program, cache_file, titletype):
400400
# Only display when a video disappears if it is within the next 3 months
401401
if metadata.offtime is not None and (metadata.offtime - now).days < 93:
402402
# Show date when episode is removed
403-
plot_meta += self._kodi.localize(30202).format(date=self._kodi.localize_dateshort(metadata.offtime))
403+
plot_meta += self._kodi.localize(30202, date=self._kodi.localize_dateshort(metadata.offtime))
404404
# Show the remaining days/hours the episode is still available
405405
if (metadata.offtime - now).days > 0:
406-
plot_meta += self._kodi.localize(30203).format(days=(metadata.offtime - now).days)
406+
plot_meta += self._kodi.localize(30203, days=(metadata.offtime - now).days)
407407
else:
408-
plot_meta += self._kodi.localize(30204).format(hours=int((metadata.offtime - now).seconds / 3600))
408+
plot_meta += self._kodi.localize(30204, hours=int((metadata.offtime - now).seconds / 3600))
409409

410410
if plot_meta:
411411
metadata.plot = '%s\n%s' % (plot_meta, metadata.plot)
@@ -638,17 +638,17 @@ def get_channel_items(self, channels=None, live=True):
638638
path = self._kodi.url_for('play_id', video_id=channel.get('live_stream_id'))
639639
elif channel.get('live_stream'):
640640
path = self._kodi.url_for('play_url', video_url=channel.get('live_stream'))
641-
label = self._kodi.localize(30101).format(**channel)
641+
label = self._kodi.localize(30101, **channel)
642642
# A single Live channel means it is the entry for channel's TV Show listing, so make it stand out
643643
if channels and len(channels) == 1:
644644
label = '[B]%s[/B]' % label
645645
is_playable = True
646646
if channel.get('name') in ['een', 'canvas', 'ketnet']:
647647
if self._showfanart:
648648
fanart = self.get_live_screenshot(channel.get('name', fanart))
649-
plot = '%s\n\n%s' % (self._kodi.localize(30102).format(**channel), _tvguide.live_description(channel.get('name')))
649+
plot = '%s\n\n%s' % (self._kodi.localize(30102, **channel), _tvguide.live_description(channel.get('name')))
650650
else:
651-
plot = self._kodi.localize(30102).format(**channel)
651+
plot = self._kodi.localize(30102, **channel)
652652
# NOTE: Playcount is required to not have live streams as "Watched"
653653
info_dict = dict(title=label, plot=plot, studio=channel.get('studio'), mediatype='video', playcount=0, duration=0)
654654
stream_dict = dict(duration=0)
@@ -686,11 +686,11 @@ def get_youtube_items(self, channels=None, live=True):
686686

687687
if channel.get('youtube'):
688688
path = channel.get('youtube')
689-
label = self._kodi.localize(30103).format(**channel)
689+
label = self._kodi.localize(30103, **channel)
690690
# A single Live channel means it is the entry for channel's TV Show listing, so make it stand out
691691
if channels and len(channels) == 1:
692692
label = '[B]%s[/B]' % label
693-
plot = self._kodi.localize(30104).format(**channel)
693+
plot = self._kodi.localize(30104, **channel)
694694
# NOTE: Playcount is required to not have live streams as "Watched"
695695
info_dict = dict(title=label, plot=plot, studio=channel.get('studio'), mediatype='video', playcount=0)
696696
context_menu = [(self._kodi.localize(30413), 'RunPlugin(%s)' % self._kodi.url_for('delete_cache', cache_file='channel.%s.json' % channel))]

resources/lib/vrtplayer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ def play_episode_by_air_date(self, channel, start_date, end_date):
238238
''' Play an episode of a program given the channel and the air date in iso format (2019-07-06T19:35:00) '''
239239
video = self._apihelper.get_episode_by_air_date(channel, start_date, end_date)
240240
if video and video.get('video_title'):
241-
self._kodi.show_ok_dialog(message=self._kodi.localize(30986) % video.get('video_title'))
241+
self._kodi.show_ok_dialog(message=self._kodi.localize(30986, title=video.get('video_title')))
242242
self._kodi.end_of_directory()
243243
return
244244
if not video:

test/test_kodi.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# GNU General Public License v3.0 (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
4+
5+
# pylint: disable=missing-docstring
6+
7+
from __future__ import absolute_import, division, print_function, unicode_literals
8+
import unittest
9+
10+
from resources.lib import kodiwrapper
11+
12+
xbmc = __import__('xbmc')
13+
xbmcaddon = __import__('xbmcaddon')
14+
xbmcgui = __import__('xbmcgui')
15+
xbmcplugin = __import__('xbmcplugin')
16+
xbmcvfs = __import__('xbmcvfs')
17+
18+
19+
class KodiTests(unittest.TestCase):
20+
21+
_kodi = kodiwrapper.KodiWrapper(None)
22+
23+
def test_localize(self):
24+
msg = self._kodi.localize(30958)
25+
self.assertEqual(msg, "There is a problem with this VRT NU {protocol} stream. Try again with {component} {state} or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/") # noqa
26+
print(msg)
27+
28+
msg = self._kodi.localize(30958, component='Widevine DRM', state='enabled')
29+
self.assertEqual(msg, "There is a problem with this VRT NU {protocol} stream. Try again with Widevine DRM enabled or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/") # noqa
30+
print(msg)
31+
32+
msg = self._kodi.localize(30958, protocol='MPEG-DASH', component='Widevine DRM', state='enabled')
33+
self.assertEqual(msg, "There is a problem with this VRT NU MPEG-DASH stream. Try again with Widevine DRM enabled or try to play this program from the VRT NU website. Please report this problem at https://www.vrt.be/vrtnu/help/") # noqa
34+
print(msg)
35+
36+
37+
if __name__ == '__main__':
38+
unittest.main()

0 commit comments

Comments
 (0)