Hi,
Find attached a first patch that add internationalization support in
Freevo. It's main purpose is to enclose strings between '_(...)' for all
the strings displayed on screen.
For example, the string:
return 'Directory on disc [%s]' % self.media.label
is replaced by:
return _('Directory on disc [%s]') % self.media.labelTo notice the changes at runtime, you have to set LANG variable to a supported language (For example, export LANG=fr). To support internationalization, we have to add a directory 'locale' in freevo (cf. attached file freevo_locale.tgz). This directory contains the .mo files that translate english strings in the supported language. For the moment, only French has a (very) limited support (only directory.py, main.py, menu.py, osd.py, record_server.py, tv/tv.py, and tv/tvguide.py were internationalized). I plan to update the other files in the next days. If you want to add a new language, you must provide translations for all the strings in freevo.pot file. Please note that, for the moment, all the strings read from the XML files are not translated... I try to find a solution that would prevent us to have as many version of an xml file as we have different supported languages. Regards, David
freevo_locale.tgz
Description: application/compressed-tar
diff -Naur freevo/src/directory.py freevo_new/src/directory.py
--- freevo/src/directory.py 2003-08-21 00:45:11.000000000 -0400
+++ freevo_new/src/directory.py 2003-08-21 00:59:08.000000000 -0400
@@ -265,8 +265,8 @@
"""
if attr == 'type':
if self.media:
- return 'Directory on disc [%s]' % self.media.label
- return 'Directory'
+ return _('Directory on disc [%s]') % self.media.label
+ return _('Directory')
return Item.getattr(self, attr)
@@ -274,20 +274,20 @@
"""
return a list of actions for this item
"""
- items = [ ( self.cwd, 'Browse directory' ) ]
+ items = [ ( self.cwd, _('Browse directory') ) ]
# this doen't work right now because we have no playlist
# at this point :-(
# if self.playlist and len(self.playlist) > 1:
# items += [ (RandomPlaylist(self.playlist, self),
- # 'Random play all items' ) ]
+ # _('Random play all items') ) ]
if ((not self.display_type or self.display_type == 'audio') and
config.AUDIO_RANDOM_PLAYLIST == 1):
items += [ (RandomPlaylist((self.dir, config.SUFFIX_AUDIO_FILES),
self),
- 'Recursive random play all items') ]
+ _('Recursive random play all items')) ]
return items
@@ -310,7 +310,7 @@
if os.path.isfile(self.dir + '/.password'):
print 'password protected dir'
- pb = PasswordInputBox(text='Enter Password', handler=self.pass_cmp_cb)
+ pb = PasswordInputBox(text=_('Enter Password'), handler=self.pass_cmp_cb)
pb.show()
# save these so the InputBox callback can pass them to do_cwd
self.arg = arg
@@ -335,7 +335,7 @@
if word == password:
self.do_cwd(self.arg, self.menuw)
else:
- pb = AlertBox(text='Password incorrect')
+ pb = AlertBox(text=_('Password incorrect'))
pb.show()
return
@@ -375,9 +375,9 @@
pop = None
if (num_changes > 10) or (num_changes and self.media):
if self.media:
- pop = PopupBox(text='Scanning disc, be patient...')
+ pop = PopupBox(text=_('Scanning disc, be patient...'))
else:
- pop = PopupBox(text='Scanning directory, be patient...')
+ pop = PopupBox(text=_('Scanning directory, be patient...'))
pop.show()
if num_changes > 0:
diff -Naur freevo/src/main.py freevo_new/src/main.py
--- freevo/src/main.py 2003-08-21 00:45:12.000000000 -0400
+++ freevo_new/src/main.py 2003-08-21 00:59:10.000000000 -0400
@@ -149,6 +149,21 @@
from item import Item
import event as em
+# For Internationalization purpose
+# an exception is raised with Python 2.1 if LANG is unavailable.
+import gettext
+if gettext.find('freevo'): # Test if installed in '/usr/share/locale'
+ try:
+ gettext.install('freevo')
+ except:
+ import __builtin__
+ __builtin__.__dict__['_']= lambda m: m
+else:
+ try:
+ gettext.install('freevo', './locale')
+ except: # unavailable, define '_' for all modules
+ import __builtin__
+ __builtin__.__dict__['_']= lambda m: m
skin = skin.get_singleton()
@@ -175,7 +190,7 @@
import plugin
osd.clearscreen(color=osd.COL_BLACK)
- osd.drawstring('shutting down...', osd.width/2 - 90, osd.height/2 - 10,
+ osd.drawstring(_('shutting down...'), osd.width/2 - 90, osd.height/2 - 10,
fgcolor=osd.COL_ORANGE, bgcolor=osd.COL_BLACK)
osd.update()
@@ -273,7 +288,7 @@
items = get_main_menu(self)
- mainmenu = menu.Menu('FREEVO MAIN MENU', items, item_types='main', umount_all = 1)
+ mainmenu = menu.Menu(_('FREEVO MAIN MENU'), items, item_types='main', umount_all = 1)
menuwidget.pushmenu(mainmenu)
osd.add_app(menuwidget)
diff -Naur freevo/src/menu.py freevo_new/src/menu.py
--- freevo/src/menu.py 2003-08-21 00:45:12.000000000 -0400
+++ freevo_new/src/menu.py 2003-08-21 00:59:10.000000000 -0400
@@ -527,7 +527,7 @@
if action == None:
print 'No action.. '
- AlertBox(text='No action defined for this choice!').show()
+ AlertBox(text=_('No action defined for this choice!')).show()
else:
action( arg=arg, menuw=self )
return
diff -Naur freevo/src/osd.py freevo_new/src/osd.py
--- freevo/src/osd.py 2003-08-21 00:45:12.000000000 -0400
+++ freevo_new/src/osd.py 2003-08-21 00:59:11.000000000 -0400
@@ -383,11 +383,11 @@
if config.CONF.display == 'x11' and config.START_FULLSCREEN_X == 1:
self.toggle_fullscreen()
- help = ['z = Toggle Fullscreen']
- help += ['Arrow Keys = Move']
- help += ['Spacebar = Select']
- help += ['Escape = Stop/Prev. Menu']
- help += ['h = Help']
+ help = [_('z = Toggle Fullscreen')]
+ help += [_('Arrow Keys = Move')]
+ help += [_('Spacebar = Select')]
+ help += [_('Escape = Stop/Prev. Menu')]
+ help += [_('h = Help')]
help_str = ' '.join(help)
pygame.display.set_caption('Freevo' + ' '*7 + help_str)
icon = pygame.image.load(os.path.join(config.ICON_DIR,
diff -Naur freevo/src/record_server.py freevo_new/src/record_server.py
--- freevo/src/record_server.py 2003-08-21 00:45:14.000000000 -0400
+++ freevo_new/src/record_server.py 2003-08-21 00:59:12.000000000 -0400
@@ -177,10 +177,10 @@
global guide
if not prog:
- return (FALSE, 'no prog')
+ return (FALSE, _('no prog'))
if prog.stop < time.time():
- return (FALSE, 'cannot record it if it is over')
+ return (FALSE, _('cannot record it if it is over'))
self.updateGuide()
@@ -193,33 +193,33 @@
scheduledRecordings.addProgram(prog, tv_util.getKey(prog))
self.saveScheduledRecordings(scheduledRecordings)
- return (TRUE, 'recording scheduled')
+ return (TRUE, _('recording scheduled'))
def removeScheduledRecording(self, prog=None):
if not prog:
- return (FALSE, 'no prog')
+ return (FALSE, _('no prog'))
scheduledRecordings = self.getScheduledRecordings()
scheduledRecordings.removeProgram(prog, tv_util.getKey(prog))
self.saveScheduledRecordings(scheduledRecordings)
- return (TRUE, 'recording removed')
+ return (TRUE, _('recording removed'))
def isProgScheduled(self, prog, schedule=None):
if schedule == {}:
- return (FALSE, 'prog not scheduled')
+ return (FALSE, _('prog not scheduled'))
if not schedule:
schedule = self.getScheduledRecordings().getProgramList()
for me in schedule.values():
if me.start == prog.start and me.channel_id == prog.channel_id:
- return (TRUE, 'prog is scheduled')
+ return (TRUE, _('prog is scheduled'))
- return (FALSE, 'prog not scheduled')
+ return (FALSE, _('prog not scheduled'))
def findProg(self, chan=None, start=None):
@@ -228,7 +228,7 @@
log.debug('findProg: %s, %s' % (chan, start))
if not chan or not start:
- return (FALSE, 'no chan or no start')
+ return (FALSE, _('no chan or no start'))
self.updateGuide()
@@ -240,7 +240,7 @@
log.debug('PROGRAM MATCH')
return (TRUE, prog)
- return (FALSE, 'prog not found')
+ return (FALSE, _('prog not found'))
def findMatches(self, find=None):
@@ -271,7 +271,7 @@
if matches:
return (TRUE, matches)
else:
- return (FALSE, 'no matches')
+ return (FALSE, _('no matches'))
def updateGuide(self):
@@ -334,7 +334,7 @@
def addFavorite(self, name, prog, exactchan=FALSE, exactdow=FALSE, exacttod=FALSE):
if not name:
- return (FALSE, 'no name')
+ return (FALSE, '_(no name'))
(status, favs) = self.getFavorites()
priority = len(favs) + 1
@@ -345,7 +345,7 @@
self.saveScheduledRecordings(scheduledRecordings)
self.addFavoriteToSchedule(fav)
- return (TRUE, 'favorite added')
+ return (TRUE, _('favorite added'))
def addEditedFavorite(self, name, title, chan, dow, mod, priority):
@@ -363,12 +363,12 @@
self.saveScheduledRecordings(scheduledRecordings)
self.addFavoriteToSchedule(fav)
- return (TRUE, 'favorite added')
+ return (TRUE, _('favorite added'))
def removeFavorite(self, name=None):
if not name:
- return (FALSE, 'no name')
+ return (FALSE, _('no name'))
(status, fav) = self.getFavorite(name)
self.removeFavoriteFromSchedule(fav)
@@ -376,7 +376,7 @@
scheduledRecordings.removeFavorite(name)
self.saveScheduledRecordings(scheduledRecordings)
- return (TRUE, 'favorite removed')
+ return (TRUE, _('favorite removed'))
def clearFavorites(self):
@@ -384,7 +384,7 @@
scheduledRecordings.clearFavorites()
self.saveScheduledRecordings(scheduledRecordings)
- return (TRUE, 'favorites cleared')
+ return (TRUE, _('favorites cleared'))
def getFavorites(self):
@@ -398,7 +398,7 @@
fav = favs[name]
return (TRUE, fav)
else:
- return (FALSE, 'not a favorite')
+ return (FALSE, _('not a favorite'))
def adjustPriority(self, favname, mod=0):
@@ -440,7 +440,7 @@
sr.setFavoritesList(favs)
self.saveScheduledRecordings(sr)
- return (TRUE, 'priorities adjusted')
+ return (TRUE, _('priorities adjusted'))
def isProgAFavorite(self, prog, favs=None):
@@ -465,7 +465,7 @@
return (TRUE, fav.name)
# if we get this far prog is not a favorite
- return (FALSE, 'not a favorite')
+ return (FALSE, _('not a favorite'))
def removeFavoriteFromSchedule(self, fav):
@@ -482,7 +482,7 @@
if isFav:
self.removeScheduledRecording(prog)
- return (TRUE, 'favorite unscheduled')
+ return (TRUE, _('favorite unscheduled'))
def addFavoriteToSchedule(self, fav):
@@ -499,7 +499,7 @@
prog.isFavorite = favorite
self.scheduleRecording(prog)
- return (TRUE, 'favorite scheduled')
+ return (TRUE, _('favorite scheduled'))
def updateFavoritesSchedule(self):
@@ -521,7 +521,7 @@
(status, favs) = self.getFavorites()
if not len(favs):
- return (FALSE, 'there are no favorites to update')
+ return (FALSE, _('there are no favorites to update'))
# Then remove all scheduled favorites in that timeframe to
@@ -546,7 +546,7 @@
prog.isFavorite = favorite
self.scheduleRecording(prog)
- return (TRUE, 'favorites schedule updated')
+ return (TRUE, _('favorites schedule updated'))
#################################################################
diff -Naur freevo/src/tv/tv.py freevo_new/src/tv/tv.py
--- freevo/src/tv/tv.py 2003-08-21 00:45:28.000000000 -0400
+++ freevo_new/src/tv/tv.py 2003-08-21 00:59:13.000000000 -0400
@@ -115,14 +115,14 @@
if tv_channel_id == channel_id:
return tv_tuner_id
- AlertBox(text='Could not find TV channel %s' % channel_id).show()
+ AlertBox(text=_('Could not find TV channel')+' %s' % channel_id).show()
return None
def get_friendly_channel(channel_id):
channel_name = tv_util.get_chan_displayname(channel_id)
if not channel_name:
- AlertBox(text='Could not find TV channel %s' % channel_id).show()
+ AlertBox(text=_('Could not find TV channel')+' %s' % channel_id).show()
return channel_name
@@ -145,11 +145,11 @@
def main_menu(self, arg, menuw):
- items = [ menu.MenuItem('TV Guide', action=self.start_tvguide),
- DirItem(config.DIR_RECORD, None, name = 'Recorded Shows',
+ items = [ menu.MenuItem(_('TV Guide'), action=self.start_tvguide),
+ DirItem(config.DIR_RECORD, None, name = _('Recorded Shows'),
display_type='tv'),
- menu.MenuItem('Scheduled Recordings',action=self.view_schedule) ]
- menuw.pushmenu(menu.Menu('TV MAIN MENU', items, item_types = 'tv'))
+ menu.MenuItem(_('Scheduled Recordings'),action=self.view_schedule) ]
+ menuw.pushmenu(menu.Menu(_('TV MAIN MENU'), items, item_types = 'tv'))
def get_start_time(self):
@@ -173,8 +173,8 @@
# Check that the TV channel list is not None
if not config.TV_CHANNELS:
- msg = 'The list of TV channels is invalid!\n'
- msg += 'Please check the config file.'
+ msg = _('The list of TV channels is invalid!')+'\n'
+ msg += _('Please check the config file.')
AlertBox(text=msg).show()
return
@@ -182,7 +182,7 @@
start_tv(None, ('record', None))
return
- guide = epg.get_guide(PopupBox(text='Preparing the program guide'))
+ guide = epg.get_guide(PopupBox(text=_('Preparing the program guide')))
start_time = self.get_start_time()
stop_time = self.get_start_time() + config.TVGUIDE_HOURS_PER_PAGE * 60 * 60
@@ -190,7 +190,7 @@
channels = guide.GetPrograms(start=start_time+1, stop=stop_time-1)
if not channels:
- AlertBox(text='TV Guide is corrupt!').show()
+ AlertBox(text=_('TV Guide is corrupt!')).show()
return
prg = None
diff -Naur freevo/src/tv/tvguide.py freevo_new/src/tv/tvguide.py
--- freevo/src/tv/tvguide.py 2003-08-21 00:45:28.000000000 -0400
+++ freevo_new/src/tv/tvguide.py 2003-08-21 00:59:14.000000000 -0400
@@ -71,12 +71,11 @@
skin = skin.get_singleton() # Create the Skin object
-
TRUE = 1
FALSE = 0
-CHAN_NO_DATA = 'This channel has no data loaded'
+CHAN_NO_DATA = _('This channel has no data loaded')
class TVGuide(gui.GUIObject):
@@ -432,9 +431,9 @@
prg.channel_id = channel.id
prg.start = 0
prg.stop = 2147483647 # Year 2038
- prg.title = 'This channel has no data loaded'
+ prg.title = _('This channel has no data loaded')
prg.desc = ''
- to_info = 'This channel has no data loaded'
+ to_info = _('This channel has no data loaded')
self.rebuild(start_time, stop_time, start_channel, prg)
