Applied i18n patch from Marcos.

This commit is contained in:
Andrew Resch 2007-09-16 01:24:08 +00:00
parent 9bb65d1ab4
commit 7f5a0d8ab7
8 changed files with 1055 additions and 21 deletions

3
deluge/i18n/POTFILES.in Normal file
View File

@ -0,0 +1,3 @@
deluge/ui/gtkui/glade/main_window.glade
deluge/ui/gtkui/glade/preferences_dialog.glade
deluge/plugins/queue/queue/gtkui.py

521
deluge/i18n/deluge.pot Normal file
View File

@ -0,0 +1,521 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2007-09-15 18:22-0700\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: deluge/ui/gtkui/glade/main_window.glade:20
msgid "_File"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:27
msgid "_Add Torrent"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:42
msgid "Add _URL"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:49
msgid "_Clear Completed"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:69
msgid "Quit & Shutdown Daemon"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:101
msgid "_Edit"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:122
msgid "_Torrent"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:129
msgid "_View"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:137
msgid "_Toolbar"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:145
msgid "_Details"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:153
msgid "Columns"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:164
msgid "_Help"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:192
msgid "Add torrent"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:193
msgid "Add Torrent"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:205
msgid "Remove the selected torrents"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:206
msgid "Remove Torrent"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:218
msgid "Remove the finished torrents"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:219
msgid "Clear Finished"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:240
msgid "Pause the selected torrents"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:241
msgid "Pause"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:254
msgid "Resume the selected torrents"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:255
msgid "Resume"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:275
#: deluge/ui/gtkui/glade/main_window.glade:276
msgid "Preferences"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:420
msgid "<b>Name:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:439
msgid "<b>Next Announce:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:465
msgid "<b>Tracker Status:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:493
msgid "<b>Tracker:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:516
msgid "<b>Total Size:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:576
msgid "<b># of files:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:595
msgid "<b>Torrent Info</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:666
msgid "<b>Availability:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:702
msgid "<b>Pieces:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:719
msgid "<b>ETA:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:740
msgid "<b>Peers:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:761
#: deluge/ui/gtkui/glade/main_window.glade:782
msgid "<b>Speed:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:800
msgid "<b>Share Ratio:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:818
msgid "<b>Seeders:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:836
msgid "<b>Uploaded:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:854
msgid "<b>Downloaded:</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:966
msgid "<b>Statistics</b>"
msgstr ""
#: deluge/ui/gtkui/glade/main_window.glade:991
msgid "Details"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:8
msgid "Deluge Preferences"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:74
msgid "<b><i><big>Downloads</big></i></b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:108
msgid "Ask where to save each download"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:124
#: deluge/ui/gtkui/glade/preferences_dialog.glade:125
msgid "Store all downloads in:"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:142
msgid "Select A Folder"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:161
msgid "<b>Download Location</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:197
msgid ""
"Full allocation preallocates all of the space that is needed for the torrent "
"and prevents disk fragmentation"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:198
msgid "Use Full Allocation"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:213
msgid "Compact allocation only allocates space as needed"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:214
msgid "Use Compact Allocation"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:232
msgid "<b>Allocation</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:266
#: deluge/ui/gtkui/glade/preferences_dialog.glade:267
msgid "Enable selecting files for torrents before loading"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:280
#: deluge/ui/gtkui/glade/preferences_dialog.glade:281
msgid "Prioritize first and last pieces of files in torrent"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:297
msgid "<b>Torrents</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:350
msgid "<b><i><big>Network</big></i></b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:387
msgid "From:"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:414
msgid "To:"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:445
msgid "Test Active Port"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:469
msgid "Deluge will automatically choose a different port to use every time."
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:470
msgid "Use Random Ports"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:488
msgid "Active Port:"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:500
msgid "0000"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:530
msgid "<b>Ports</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:562
msgid "Distributed hash table may improve the amount of active connections."
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:563
msgid "Enable Mainline DHT"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:576
msgid "<b>DHT</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:609
msgid "Universal Plug and Play"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:610
msgid "UPnP"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:625
msgid "NAT Port Mapping Protocol"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:626
msgid "NAT-PMP"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:642
msgid "µTorrent Peer-Exchange"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:643
msgid "µTorrent-PeX"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:662
msgid "<b>Network Extras</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:698
msgid "Inbound:"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:707
#: deluge/ui/gtkui/glade/preferences_dialog.glade:731
msgid ""
"Disabled\n"
"Enabled\n"
"Forced"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:721
msgid "Outbound:"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:750
msgid "Level:"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:759
msgid ""
"Handshake\n"
"Either\n"
"Full Stream"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:778
msgid "Prefer to encrypt the entire stream"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:795
msgid "<b>Encryption</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:849
msgid "<b><i><big>Bandwidth</big></i></b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:887
#: deluge/ui/gtkui/glade/preferences_dialog.glade:911
#: deluge/ui/gtkui/glade/preferences_dialog.glade:977
msgid "The maximum upload speed for all torrents. Set -1 for unlimited."
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:889
msgid "Maximum Upload Speed (KiB/s):"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:900
#: deluge/ui/gtkui/glade/preferences_dialog.glade:925
msgid "The maximum number of connections allowed. Set -1 for unlimited."
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:902
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1071
msgid "Maximum Connections:"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:913
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1058
msgid "Maximum Upload Slots:"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:943
#: deluge/ui/gtkui/glade/preferences_dialog.glade:958
msgid "The maximum download speed for all torrents. Set -1 for unlimited."
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:945
msgid "Maximum Download Speed (KiB/s):"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:996
msgid "The maximum upload slots for all torrents. Set -1 for unlimited."
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1018
msgid "<b>Global Bandwidth Usage</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1081
msgid "The maximum number of connections per torrent. Set -1 for unlimited."
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1097
msgid "The maximum upload slots per torrent. Set -1 for unlimited."
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1120
msgid "<b>Per Torrent Bandwidth Usage</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1174
msgid "<i><b><big>Other</big></b></i>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1208
msgid "Enable system tray icon"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1223
msgid "Minimize to tray on close"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1242
msgid "Start in tray"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1263
msgid "Password protect system tray"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1288
msgid "Password:"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1322
msgid "<b>System Tray</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1372
msgid ""
"Auto-detect (xdg-open)\n"
"Konqueror\n"
"Nautilus\n"
"Thunar"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1396
msgid "Custom:"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1413
msgid "Open folder with:"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1430
msgid "<b>Desktop File Manager</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1465
msgid ""
"Deluge will check our servers and will tell you if a newer version has been "
"released"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1466
msgid "Be alerted about new releases"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1483
msgid "<b>Updates</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1519
msgid ""
"Help us improve Deluge by sending us your Python version, PyGTK version, OS "
"and processor types. Absolutely no other information is sent."
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1538
msgid "Yes, please send anonymous statistics"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1557
msgid "<b>System Information</b>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1611
msgid "<i><b><big>Plugins</big></b></i>"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1703
msgid "gtk-cancel"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1715
msgid "gtk-apply"
msgstr ""
#: deluge/ui/gtkui/glade/preferences_dialog.glade:1730
msgid "gtk-ok"
msgstr ""
#: deluge/plugins/queue/queue/gtkui.py:100
msgid "Queue Up"
msgstr ""
#: deluge/plugins/queue/queue/gtkui.py:101
msgid "Queue selected torrents up"
msgstr ""
#: deluge/plugins/queue/queue/gtkui.py:105
msgid "Queue Down"
msgstr ""
#: deluge/plugins/queue/queue/gtkui.py:106
msgid "Queue selected torrents down"
msgstr ""

View File

@ -37,11 +37,25 @@ DBusGMainLoop(set_as_default=True)
import pkg_resources
import gtk.glade
import gettext
import locale
from deluge.log import LOG as log
class GtkUI:
def __init__(self, plugin_manager):
# Initialize gettext
locale.setlocale(locale.LC_MESSAGES, '')
locale.bindtextdomain("deluge",
pkg_resources.resource_filename(
"deluge", "i18n"))
locale.textdomain("deluge")
gettext.bindtextdomain("deluge",
pkg_resources.resource_filename(
"deluge", "i18n"))
gettext.textdomain("deluge")
gettext.install("deluge",
pkg_resources.resource_filename(
"deluge", "i18n"))
log.debug("Queue GtkUI plugin initalized..")
self.plugin = plugin_manager
# Get a reference to the core portion of the plugin
@ -83,13 +97,13 @@ class GtkUI:
# Add a toolbar buttons
self.plugin.get_toolbar().add_separator()
self.plugin.get_toolbar().add_toolbutton(stock="gtk-go-up",
label="Queue Up",
tooltip="Queue selected torrents up",
label=_("Queue Up"),
tooltip=_("Queue selected torrents up"),
callback=self.on_toolbutton_queueup_clicked)
self.plugin.get_toolbar().add_toolbutton(stock="gtk-go-down",
label="Queue Down",
tooltip="Queue selected torrents down",
label=_("Queue Down"),
tooltip=_("Queue selected torrents down"),
callback=self.on_toolbutton_queuedown_clicked)
# Add the queue menu to the torrent menu

View File

@ -190,7 +190,7 @@
<widget class="GtkToolButton" id="toolbutton_add">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Add torrent</property>
<property name="label">Add Torrent</property>
<property name="label" translatable="yes">Add Torrent</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-add</property>
<signal name="clicked" handler="on_toolbutton_add_clicked"/>
@ -203,7 +203,7 @@
<widget class="GtkToolButton" id="toolbutton_remove">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Remove the selected torrents</property>
<property name="label">Remove Torrent</property>
<property name="label" translatable="yes">Remove Torrent</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-remove</property>
<signal name="clicked" handler="on_toolbutton_remove_clicked"/>
@ -216,7 +216,7 @@
<widget class="GtkToolButton" id="toolbutton_clear">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Remove the finished torrents</property>
<property name="label">Clear Finished</property>
<property name="label" translatable="yes">Clear Finished</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-clear</property>
<signal name="clicked" handler="on_toolbutton_clear_clicked"/>
@ -238,7 +238,7 @@
<widget class="GtkToolButton" id="toolbutton_pause">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Pause the selected torrents</property>
<property name="label">Pause</property>
<property name="label" translatable="yes">Pause</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-media-pause</property>
<signal name="clicked" handler="on_toolbutton_pause_clicked"/>
@ -252,7 +252,7 @@
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip" translatable="yes">Resume the selected torrents</property>
<property name="label">Resume</property>
<property name="label" translatable="yes">Resume</property>
<property name="stock_id">gtk-media-play</property>
<signal name="clicked" handler="on_toolbutton_resume_clicked"/>
</widget>
@ -273,7 +273,7 @@
<widget class="GtkToolButton" id="toolbutton_preferences">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Preferences</property>
<property name="label">Preferences</property>
<property name="label" translatable="yes">Preferences</property>
<property name="use_underline">True</property>
<property name="stock_id">gtk-preferences</property>
<signal name="clicked" handler="on_toolbutton_preferences_clicked"/>

View File

@ -35,6 +35,7 @@ import pygtk
pygtk.require('2.0')
import gtk, gtk.glade
import gettext
import locale
import pkg_resources
from mainwindow import MainWindow
@ -46,15 +47,18 @@ from deluge.log import LOG as log
class GtkUI:
def __init__(self):
# Initialize gettext
locale.setlocale(locale.LC_MESSAGES, '')
locale.bindtextdomain("deluge",
pkg_resources.resource_filename(
"deluge", "i18n"))
locale.textdomain("deluge")
gettext.bindtextdomain("deluge",
pkg_resources.resource_filename(
"deluge.ui.gtkui",
"po"))
"deluge", "i18n"))
gettext.textdomain("deluge")
gettext.install("deluge",
pkg_resources.resource_filename(
"deluge.ui.gtkui",
"po"))
"deluge", "i18n"))
# Initialize the main window
self.mainwindow = MainWindow()

2
gettextize.sh Normal file
View File

@ -0,0 +1,2 @@
#!/bin/sh
xgettext -f deluge/i18n/POTFILES.in -o deluge/i18n/deluge.pot

438
msgfmt.py Normal file
View File

@ -0,0 +1,438 @@
# -*- coding: iso-8859-1 -*-
# Written by Martin v. Lwis <loewis@informatik.hu-berlin.de>
# Plural forms support added by alexander smishlajev <alex@tycobka.lv>
"""
Generate binary message catalog from textual translation description.
This program converts a textual Uniforum-style message catalog (.po file) into
a binary GNU catalog (.mo file). This is essentially the same function as the
GNU msgfmt program, however, it is a simpler implementation.
Usage: msgfmt.py [OPTIONS] filename.po
Options:
-o file
--output-file=file
Specify the output file to write to. If omitted, output will go to a
file named filename.mo (based off the input file name).
-h
--help
Print this message and exit.
-V
--version
Display version information and exit.
"""
import sys
import os
import getopt
import struct
import array
__version__ = "1.1"
MESSAGES = {}
def usage (ecode, msg=''):
"""
Print usage and msg and exit with given code.
"""
print >> sys.stderr, __doc__
if msg:
print >> sys.stderr, msg
sys.exit(ecode)
def add (msgid, transtr, fuzzy):
"""
Add a non-fuzzy translation to the dictionary.
"""
global MESSAGES
if not fuzzy and transtr and not transtr.startswith('\0'):
MESSAGES[msgid] = transtr
def generate ():
"""
Return the generated output.
"""
global MESSAGES
keys = MESSAGES.keys()
# the keys are sorted in the .mo file
keys.sort()
offsets = []
ids = strs = ''
for _id in keys:
# For each string, we need size and file offset. Each string is NUL
# terminated; the NUL does not count into the size.
offsets.append((len(ids), len(_id), len(strs), len(MESSAGES[_id])))
ids += _id + '\0'
strs += MESSAGES[_id] + '\0'
output = ''
# The header is 7 32-bit unsigned integers. We don't use hash tables, so
# the keys start right after the index tables.
# translated string.
keystart = 7*4+16*len(keys)
# and the values start after the keys
valuestart = keystart + len(ids)
koffsets = []
voffsets = []
# The string table first has the list of keys, then the list of values.
# Each entry has first the size of the string, then the file offset.
for o1, l1, o2, l2 in offsets:
koffsets += [l1, o1+keystart]
voffsets += [l2, o2+valuestart]
offsets = koffsets + voffsets
output = struct.pack("Iiiiiii",
0x950412deL, # Magic
0, # Version
len(keys), # # of entries
7*4, # start of key index
7*4+len(keys)*8, # start of value index
0, 0) # size and offset of hash table
output += array.array("i", offsets).tostring()
output += ids
output += strs
return output
def make (filename, outfile):
ID = 1
STR = 2
global MESSAGES
MESSAGES = {}
# Compute .mo name from .po name and arguments
if filename.endswith('.po'):
infile = filename
else:
infile = filename + '.po'
if outfile is None:
outfile = os.path.splitext(infile)[0] + '.mo'
try:
lines = open(infile).readlines()
except IOError, msg:
print >> sys.stderr, msg
sys.exit(1)
section = None
fuzzy = 0
# Parse the catalog
msgid = msgstr = ''
lno = 0
for l in lines:
lno += 1
# If we get a comment line after a msgstr, this is a new entry
if l[0] == '#' and section == STR:
add(msgid, msgstr, fuzzy)
section = None
fuzzy = 0
# Record a fuzzy mark
if l[:2] == '#,' and (l.find('fuzzy') >= 0):
fuzzy = 1
# Skip comments
if l[0] == '#':
continue
# Start of msgid_plural section, separate from singular form with \0
if l.startswith('msgid_plural'):
msgid += '\0'
l = l[12:]
# Now we are in a msgid section, output previous section
elif l.startswith('msgid'):
if section == STR:
add(msgid, msgstr, fuzzy)
section = ID
l = l[5:]
msgid = msgstr = ''
# Now we are in a msgstr section
elif l.startswith('msgstr'):
section = STR
l = l[6:]
# Check for plural forms
if l.startswith('['):
# Separate plural forms with \0
if not l.startswith('[0]'):
msgstr += '\0'
# Ignore the index - must come in sequence
l = l[l.index(']') + 1:]
# Skip empty lines
l = l.strip()
if not l:
continue
# XXX: Does this always follow Python escape semantics?
l = eval(l)
if section == ID:
msgid += l
elif section == STR:
msgstr += l
else:
print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \
'before:'
print >> sys.stderr, l
sys.exit(1)
# Add last entry
if section == STR:
add(msgid, msgstr, fuzzy)
# Compute output
output = generate()
try:
open(outfile,"wb").write(output)
except IOError,msg:
print >> sys.stderr, msg
def main ():
try:
opts, args = getopt.getopt(sys.argv[1:], 'hVo:',
['help', 'version', 'output-file='])
except getopt.error, msg:
usage(1, msg)
outfile = None
# parse options
for opt, arg in opts:
if opt in ('-h', '--help'):
usage(0)
elif opt in ('-V', '--version'):
print >> sys.stderr, "msgfmt.py", __version__
sys.exit(0)
elif opt in ('-o', '--output-file'):
outfile = arg
# do it
if not args:
print >> sys.stderr, 'No input file given'
print >> sys.stderr, "Try `msgfmt --help' for more information."
return
for filename in args:
make(filename, outfile)
if __name__ == '__main__':
main()
# -*- coding: iso-8859-1 -*-
# Written by Martin v. Lwis <loewis@informatik.hu-berlin.de>
# Plural forms support added by alexander smishlajev <alex@tycobka.lv>
"""
Generate binary message catalog from textual translation description.
This program converts a textual Uniforum-style message catalog (.po file) into
a binary GNU catalog (.mo file). This is essentially the same function as the
GNU msgfmt program, however, it is a simpler implementation.
Usage: msgfmt.py [OPTIONS] filename.po
Options:
-o file
--output-file=file
Specify the output file to write to. If omitted, output will go to a
file named filename.mo (based off the input file name).
-h
--help
Print this message and exit.
-V
--version
Display version information and exit.
"""
import sys
import os
import getopt
import struct
import array
__version__ = "1.1"
MESSAGES = {}
def usage (ecode, msg=''):
"""
Print usage and msg and exit with given code.
"""
print >> sys.stderr, __doc__
if msg:
print >> sys.stderr, msg
sys.exit(ecode)
def add (msgid, transtr, fuzzy):
"""
Add a non-fuzzy translation to the dictionary.
"""
global MESSAGES
if not fuzzy and transtr and not transtr.startswith('\0'):
MESSAGES[msgid] = transtr
def generate ():
"""
Return the generated output.
"""
global MESSAGES
keys = MESSAGES.keys()
# the keys are sorted in the .mo file
keys.sort()
offsets = []
ids = strs = ''
for _id in keys:
# For each string, we need size and file offset. Each string is NUL
# terminated; the NUL does not count into the size.
offsets.append((len(ids), len(_id), len(strs), len(MESSAGES[_id])))
ids += _id + '\0'
strs += MESSAGES[_id] + '\0'
output = ''
# The header is 7 32-bit unsigned integers. We don't use hash tables, so
# the keys start right after the index tables.
# translated string.
keystart = 7*4+16*len(keys)
# and the values start after the keys
valuestart = keystart + len(ids)
koffsets = []
voffsets = []
# The string table first has the list of keys, then the list of values.
# Each entry has first the size of the string, then the file offset.
for o1, l1, o2, l2 in offsets:
koffsets += [l1, o1+keystart]
voffsets += [l2, o2+valuestart]
offsets = koffsets + voffsets
output = struct.pack("Iiiiiii",
0x950412deL, # Magic
0, # Version
len(keys), # # of entries
7*4, # start of key index
7*4+len(keys)*8, # start of value index
0, 0) # size and offset of hash table
output += array.array("i", offsets).tostring()
output += ids
output += strs
return output
def make (filename, outfile):
ID = 1
STR = 2
global MESSAGES
MESSAGES = {}
# Compute .mo name from .po name and arguments
if filename.endswith('.po'):
infile = filename
else:
infile = filename + '.po'
if outfile is None:
outfile = os.path.splitext(infile)[0] + '.mo'
try:
lines = open(infile).readlines()
except IOError, msg:
print >> sys.stderr, msg
sys.exit(1)
section = None
fuzzy = 0
# Parse the catalog
msgid = msgstr = ''
lno = 0
for l in lines:
lno += 1
# If we get a comment line after a msgstr, this is a new entry
if l[0] == '#' and section == STR:
add(msgid, msgstr, fuzzy)
section = None
fuzzy = 0
# Record a fuzzy mark
if l[:2] == '#,' and (l.find('fuzzy') >= 0):
fuzzy = 1
# Skip comments
if l[0] == '#':
continue
# Start of msgid_plural section, separate from singular form with \0
if l.startswith('msgid_plural'):
msgid += '\0'
l = l[12:]
# Now we are in a msgid section, output previous section
elif l.startswith('msgid'):
if section == STR:
add(msgid, msgstr, fuzzy)
section = ID
l = l[5:]
msgid = msgstr = ''
# Now we are in a msgstr section
elif l.startswith('msgstr'):
section = STR
l = l[6:]
# Check for plural forms
if l.startswith('['):
# Separate plural forms with \0
if not l.startswith('[0]'):
msgstr += '\0'
# Ignore the index - must come in sequence
l = l[l.index(']') + 1:]
# Skip empty lines
l = l.strip()
if not l:
continue
# XXX: Does this always follow Python escape semantics?
l = eval(l)
if section == ID:
msgid += l
elif section == STR:
msgstr += l
else:
print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \
'before:'
print >> sys.stderr, l
sys.exit(1)
# Add last entry
if section == STR:
add(msgid, msgstr, fuzzy)
# Compute output
output = generate()
try:
open(outfile,"wb").write(output)
except IOError,msg:
print >> sys.stderr, msg
def main ():
try:
opts, args = getopt.getopt(sys.argv[1:], 'hVo:',
['help', 'version', 'output-file='])
except getopt.error, msg:
usage(1, msg)
outfile = None
# parse options
for opt, arg in opts:
if opt in ('-h', '--help'):
usage(0)
elif opt in ('-V', '--version'):
print >> sys.stderr, "msgfmt.py", __version__
sys.exit(0)
elif opt in ('-o', '--output-file'):
outfile = arg
# do it
if not args:
print >> sys.stderr, 'No input file given'
print >> sys.stderr, "Try `msgfmt --help' for more information."
return
for filename in args:
make(filename, outfile)
if __name__ == '__main__':
main()

View File

@ -32,6 +32,12 @@ import ez_setup
ez_setup.use_setuptools()
from setuptools import setup, find_packages, Extension
from distutils import cmd
from distutils.command.build import build as _build
from distutils.command.install import install as _install
from distutils.command.install_data import install_data as _install_data
import msgfmt
import platform
import glob
import os
@ -84,6 +90,52 @@ libtorrent = Extension(
sources = _sources
)
class build_trans(cmd.Command):
description = 'Compile .po files into .mo files'
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
po_dir = os.path.join(os.path.dirname(__file__), 'deluge/i18n/')
for path, names, filenames in os.walk(po_dir):
for f in filenames:
if f.endswith('.po'):
lang = f[:len(f) - 3]
src = os.path.join(path, f)
dest_path = os.path.join('deluge', 'i18n', lang, \
'LC_MESSAGES')
dest = os.path.join(dest_path, 'deluge.mo')
if not os.path.exists(dest_path):
os.makedirs(dest_path)
if not os.path.exists(dest):
print 'Compiling %s' % src
msgfmt.make(src, dest)
else:
src_mtime = os.stat(src)[8]
dest_mtime = os.stat(dest)[8]
if src_mtime > dest_mtime:
print 'Compiling %s' % src
msgfmt.make(src, dest)
class build(_build):
sub_commands = _build.sub_commands + [('build_trans', None)]
def run(self):
_build.run(self)
class install_data(_install_data):
def run(self):
_install_data.run(self)
cmdclass = {
'build': build,
'build_trans': build_trans,
'install_data': install_data
}
# Build the plugin eggs
for path in glob.glob('deluge/plugins/*'):
print path + "/setup.py"
@ -95,23 +147,23 @@ setup(
name = "deluge",
fullname = "Deluge Bittorent Client",
version = "0.6.0.0",
author = "Andrew Resch",
author_email = "andrewresch@gmail.com",
author = "Andrew Resch, Marcos Pinto",
author_email = "andrewresch@gmail.com, markybob@dipconsultants.com",
description = "GTK+ bittorrent client",
url = "http://deluge-torrent.org",
license = "GPLv2",
include_package_data = True,
package_data = {"deluge": ["ui/gtkui/glade/*.glade",
"data/pixmaps/*.png",
"ui/gtkui/po/*.po?",
"plugins/*.egg",
"i18n/*.pot",
"i18n/*/LC_MESSAGES/*.mo"
]},
ext_package = "deluge",
ext_modules = [libtorrent],
packages = find_packages(exclude=["plugins"]),
cmdclass=cmdclass,
entry_points = """
[console_scripts]
deluge = deluge.main:main
"""
)
""")