From df7029d2c246bd7f7793aca4d6fce50c7805b8a0 Mon Sep 17 00:00:00 2001 From: zzz Date: Wed, 9 Dec 2009 20:54:10 +0000 Subject: [PATCH] translation support and initial tagging --- apps/i2psnark/java/bmsg.sh | 17 ++ apps/i2psnark/java/build.xml | 34 +++- apps/i2psnark/java/bundle-messages.bat | 26 +++ apps/i2psnark/java/bundle-messages.sh | 85 ++++++++ .../src/org/klomp/snark/I2PSnarkUtil.java | 24 +++ .../org/klomp/snark/web/I2PSnarkServlet.java | 172 ++++++++++------ apps/i2psnark/locale/messages_de.po | 186 ++++++++++++++++++ build.xml | 1 + 8 files changed, 487 insertions(+), 58 deletions(-) create mode 100644 apps/i2psnark/java/bmsg.sh create mode 100644 apps/i2psnark/java/bundle-messages.bat create mode 100755 apps/i2psnark/java/bundle-messages.sh create mode 100644 apps/i2psnark/locale/messages_de.po diff --git a/apps/i2psnark/java/bmsg.sh b/apps/i2psnark/java/bmsg.sh new file mode 100644 index 0000000000..b9d294b323 --- /dev/null +++ b/apps/i2psnark/java/bmsg.sh @@ -0,0 +1,17 @@ +# +# Update messages_xx.po and messages_xx.class files, +# from both java and jsp sources. +# Requires installed programs xgettext, msgfmt, msgmerge, and find. +# zzz - public domain +# + +## launching sh.exe with -login parameter will open a shell with the current path always pointing to \bin\ +## need to cd into our orignal path - where we call sh.exe from. + +cd $CALLFROM +## echo $PWD + +## except this everything is the same with bundle-message.sh +## walking - public domain :-D + +source bundle-messages.sh $PARAS \ No newline at end of file diff --git a/apps/i2psnark/java/build.xml b/apps/i2psnark/java/build.xml index 59f0421e70..bcafb362e8 100644 --- a/apps/i2psnark/java/build.xml +++ b/apps/i2psnark/java/build.xml @@ -36,7 +36,7 @@ - + @@ -57,6 +57,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/i2psnark/java/bundle-messages.bat b/apps/i2psnark/java/bundle-messages.bat new file mode 100644 index 0000000000..90feca972a --- /dev/null +++ b/apps/i2psnark/java/bundle-messages.bat @@ -0,0 +1,26 @@ +@echo off +set Callfrom=%cd% +set Paras=%1 + +rem before calling make sure you have msys and mingw 's "bin" path +rem in your current searching path +rem type "set path" to check +if not exist ..\locale\*.only goto updateALL + +rem put a messages_xx.only(eg messages_zh.only) into locale folder +rem this script will only touch the po file(eg zh) you specified, leaving other po files untact. + +for %%i in (..\locale\*.only) do set PO=%%~ni +echo [Notice] Yu choose to Ony update the choosen file: %PO%.po +for %%i in (..\locale\*.po) do if not %%~ni==%PO% ren %%i %%~ni.po- + +call sh --login %cd%\bmsg.sh + +for %%i in (..\locale\*.po-) do if not %%~ni==%PO% ren %%i %%~ni.po +goto end + +:updateALL +call sh --login %cd%\bmsg.sh + +:end +echo End of Message Bundling \ No newline at end of file diff --git a/apps/i2psnark/java/bundle-messages.sh b/apps/i2psnark/java/bundle-messages.sh new file mode 100755 index 0000000000..bd62ea9ee3 --- /dev/null +++ b/apps/i2psnark/java/bundle-messages.sh @@ -0,0 +1,85 @@ +# +# Update messages_xx.po and messages_xx.class files, +# from both java and jsp sources. +# Requires installed programs xgettext, msgfmt, msgmerge, and find. +# +# usage: +# bundle-messages.sh (generates the resource bundle from the .po file) +# bundle-messages.sh -p (updates the .po file from the source tags, then generates the resource bundle) +# +# zzz - public domain +# +CLASS=org.klomp.snark.messages +TMPFILE=build/javafiles.txt +export TZ=UTC + +if [ "$1" = "-p" ] +then + POUPDATE=1 +fi + +# add ../java/ so the refs will work in the po file +JPATHS="../java/src" +for i in ../locale/messages_*.po +do + # get language + LG=${i#../locale/messages_} + LG=${LG%.po} + + if [ "$POUPDATE" = "1" ] + then + # make list of java files newer than the .po file + find $JPATHS -name *.java -newer $i > $TMPFILE + fi + + if [ -s build/obj/org/klomp/snark/messages_$LG.class -a \ + build/obj/org/klomp/snark/messages_$LG.class -nt $i -a \ + ! -s $TMPFILE ] + then + continue + fi + + if [ "$POUPDATE" = "1" ] + then + echo "Updating the $i file from the tags..." + # extract strings from java and jsp files, and update messages.po files + # translate calls must be one of the forms: + # _("foo") + # _x("foo") + # To start a new translation, copy the header from an old translation to the new .po file, + # then ant distclean poupdate. + find $JPATHS -name *.java > $TMPFILE + xgettext -f $TMPFILE -F -L java --from-code=UTF-8 \ + --keyword=_ --keyword=_x \ + -o ${i}t + if [ $? -ne 0 ] + then + echo 'Warning - xgettext failed, not updating translations' + rm -f ${i}t + break + fi + msgmerge -U --backup=none $i ${i}t + if [ $? -ne 0 ] + then + echo 'Warning - msgmerge failed, not updating translations' + rm -f ${i}t + break + fi + rm -f ${i}t + # so we don't do this again + touch $i + fi + + echo "Generating ${CLASS}_$LG ResourceBundle..." + + # convert to class files in build/obj + msgfmt --java -r $CLASS -l $LG -d build/obj $i + if [ $? -ne 0 ] + then + echo 'Warning - msgfmt failed, not updating translations' + break + fi +done +rm -f $TMPFILE +# todo: return failure +exit 0 diff --git a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java index cbb1d17147..b40233fbb6 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java +++ b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java @@ -28,6 +28,7 @@ import net.i2p.util.FileUtil; import net.i2p.util.Log; import net.i2p.util.SimpleScheduler; import net.i2p.util.SimpleTimer; +import net.i2p.util.Translate; /** * I2P specific helpers for I2PSnark @@ -402,4 +403,27 @@ public class I2PSnarkUtil { break; } } + + private static final String BUNDLE_NAME = "org.klomp.snark.messages"; + + /** lang in routerconsole.lang property, else current locale */ + public String getString(String key) { + return Translate.getString(key, _context, BUNDLE_NAME); + } + + /** + * translate a string with a parameter + * This is a lot more expensive than getString(s, ctx), so use sparingly. + * + * @param s string to be translated containing {0} + * The {0} will be replaced by the parameter. + * Single quotes must be doubled, i.e. ' -> '' in the string. + * @param o parameter, not translated. + * To tranlslate parameter also, use _("foo {0} bar", _("baz")) + * Do not double the single quotes in the parameter. + * Use autoboxing to call with ints, longs, floats, etc. + */ + public String getString(String s, Object o) { + return Translate.getString(s, o, _context, BUNDLE_NAME); + } } diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java index 5beb0ae447..3198ca4b78 100644 --- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java +++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java @@ -80,13 +80,23 @@ public class I2PSnarkServlet extends HttpServlet { } PrintWriter out = resp.getWriter(); - out.write(HEADER_BEGIN); + out.write("\n" + + "\n" + + ""); + out.write(_("I2PSnark - Anonymous BitTorrent Client")); + out.write("\n"); + // we want it to go to the base URI so we don't refresh with some funky action= value out.write("\n"); out.write(HEADER); out.write(""); out.write("
"); - out.write("
I2PSnark Forum\n"); + out.write("
"); + out.write(_("I2PSnark")); + out.write(" Forum\n"); + Map trackers = _manager.getTrackers(); for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) { Map.Entry entry = (Map.Entry)iter.next(); @@ -110,22 +120,50 @@ public class I2PSnarkServlet extends HttpServlet { List snarks = getSortedSnarks(req); String uri = req.getRequestURI(); out.write(TABLE_HEADER); + out.write(_("Status")); + out.write("\n"); if (_manager.util().connected() && snarks.size() > 0) { + out.write("("); if (peerParam != null) - out.write("(Hide Peers)
\n"); + out.write(_("Hide Peers")); else - out.write("(Show Peers)
\n"); + out.write(_("Show Peers")); + out.write(")
\n"); } - out.write(TABLE_HEADER2); + out.write(""); + out.write(_("Torrent")); + out.write("\n"); + out.write(_("ETA")); + out.write("\n"); + out.write(_("Downloaded")); + out.write("\n"); + out.write(_("Uploaded")); + out.write("\n"); + out.write(_("Down Rate")); + out.write("\n"); + out.write(_("Up Rate")); + out.write("\n"); + out.write(""); - if (_manager.util().connected()) + if (_manager.util().connected()) { out.write("Stop All"); - else if (snarks.size() > 0) + "\" title=\""); + out.write(_("Stop all torrents and the I2P tunnel")); + out.write("\">"); + out.write(_("Stop All")); + out.write(""); + } else if (snarks.size() > 0) { out.write("Start All"); - else + "\" title=\""); + out.write(_("Start all torrents and the I2P tunnel")); + out.write("\">"); + out.write(_("Start All")); + out.write(""); + } else { out.write(" "); + } out.write("\n"); for (int i = 0; i < snarks.size(); i++) { Snark snark = (Snark)snarks.get(i); @@ -133,8 +171,13 @@ public class I2PSnarkServlet extends HttpServlet { boolean showPeers = showDebug || "1".equals(peerParam) || Base64.encode(snark.meta.getInfoHash()).equals(peerParam); displaySnark(out, snark, uri, i, stats, showPeers, showDebug); } + if (snarks.size() <= 0) { - out.write(TABLE_EMPTY); + out.write("" + + ""); + out.write(_("No torrents loaded.")); + out.write("\n"); } else if (snarks.size() > 1) { out.write("\n" + " Totals (" + @@ -464,30 +507,30 @@ public class I2PSnarkServlet extends HttpServlet { } } else if (remaining <= 0) { if (isRunning && curPeers > 0 && !showPeers) - statusString = "Seeding (" + - curPeers + "/" + knownPeers + - " peers)"; + statusString = _("Seeding") + " (" + + curPeers + '/' + knownPeers + + " " + _("peers") + ")"; else if (isRunning) - statusString = "Seeding (" + curPeers + "/" + knownPeers + " peers)"; + statusString = _("Seeding") + " (" + curPeers + "/" + knownPeers + ' ' + ("peers") + ')'; else - statusString = "Complete"; + statusString = _("Complete"); } else { if (isRunning && curPeers > 0 && downBps > 0 && !showPeers) - statusString = "OK (" + + statusString = _("OK") + " (" + curPeers + "/" + knownPeers + - " peers)"; + " " + _("peers") + ")"; else if (isRunning && curPeers > 0 && downBps > 0) - statusString = "OK (" + curPeers + "/" + knownPeers + " peers)"; + statusString = _("OK") + " (" + curPeers + "/" + knownPeers + ' ' + _("peers") + ')'; else if (isRunning && curPeers > 0 && !showPeers) - statusString = "Stalled (" + - curPeers + "/" + knownPeers + - " peers)"; + statusString = _("Stalled") + " (" + + curPeers + '/' + knownPeers + + " " + _("peers") + ")"; else if (isRunning && curPeers > 0) - statusString = "Stalled (" + curPeers + "/" + knownPeers + " peers)"; + statusString = _("Stalled") + " (" + curPeers + '/' + knownPeers + ' ' + _("peers") + ')'; else if (isRunning) - statusString = "No Peers (0/" + knownPeers + ")"; + statusString = _("No Peers") + " (0/" + knownPeers + ')'; else - statusString = "Stopped"; + statusString = _("Stopped"); } String rowClass = (row % 2 == 0 ? "snarkTorrentEven" : "snarkTorrentOdd"); @@ -500,9 +543,10 @@ public class I2PSnarkServlet extends HttpServlet { out.write(""); + out.write(_("View files")); else - out.write("Open file\">"); + out.write(_("Open file")); + out.write("\">"); } out.write(filename); if (remaining == 0) @@ -525,7 +569,9 @@ public class I2PSnarkServlet extends HttpServlet { baseURL = baseURL.substring(e + 1); out.write("   [Details]"); + out.write("\" title=\"" + name + " Tracker\">"); + out.write(_("Details")); + out.write("]"); break; } } @@ -557,17 +603,35 @@ public class I2PSnarkServlet extends HttpServlet { parameters = parameters + "&p=1"; if (isRunning) { out.write("Stop"); + + "\" title=\""); + out.write(_("Stop the torrent")); + out.write("\">"); + out.write(_("Stop")); + out.write(""); } else { - if (isValid) + if (isValid) { out.write("Start "); + + "\" title=\""); + out.write(_("Start the torrent")); + out.write("\">"); + out.write(_("Start")); + out.write("\n"); + } out.write("Remove
"); + + "\" title=\""); + out.write(_("Remove the torrent from the active list, deleting the .torrent file")); + out.write("\">"); + out.write(_("Remove")); + out.write("
"); out.write("Delete "); + + "\" title=\""); + out.write(_("Delete the .torrent file and the associated data file(s)")); + out.write("\">"); + out.write(_("Delete")); + out.write(""); } out.write("\n\n"); + if(showPeers && isRunning && curPeers > 0) { List peers = snark.coordinator.peerList(); Iterator it = peers.iterator(); @@ -578,11 +642,11 @@ public class I2PSnarkServlet extends HttpServlet { out.write(""); out.write(""); out.write("\n\t"); - out.write(""); + out.write(""); String ch = peer.toString().substring(0, 4); String client; if ("AwMD".equals(ch)) - client = "I2PSnark"; + client = _("I2PSnark"); else if ("BFJT".equals(ch)) client = "I2PRufus"; else if ("TTMt".equals(ch)) @@ -606,7 +670,7 @@ public class I2PSnarkServlet extends HttpServlet { out.write(""); float pct = (float) (100.0 * (float) peer.completed() / snark.meta.getPieces()); if (pct == 100.0) - out.write("Seed"); + out.write(_("Seed")); else { String ps = String.valueOf(pct); if (ps.length() > 5) @@ -624,9 +688,10 @@ public class I2PSnarkServlet extends HttpServlet { } else { out.write(""); + out.write(_("Uninteresting")); else - out.write("Choked\">"); + out.write(_("Choked")); + out.write("\">"); out.write(formatSize(peer.getDownloadRate()) + "ps"); } } @@ -639,9 +704,10 @@ public class I2PSnarkServlet extends HttpServlet { } else { out.write(""); + out.write(_("Uninterested")); else - out.write("Choking\">"); + out.write(_("Choking")); + out.write("\">"); out.write(formatSize(peer.getUploadRate()) + "ps"); } } @@ -779,6 +845,14 @@ public class I2PSnarkServlet extends HttpServlet { out.write("
"); } + private String _(String s) { + return _manager.util().getString(s); + } + + private String _(String s, Object o) { + return _manager.util().getString(s, o); + } + // rounding makes us look faster :) private String formatSize(long bytes) { if (bytes < 5*1024) @@ -791,28 +865,12 @@ public class I2PSnarkServlet extends HttpServlet { return ((bytes + 512*1024*1024)/(1024*1024*1024)) + "GB"; } - private static final String HEADER_BEGIN = "\n" + - "\n" + - "I2PSnark - Anonymous BitTorrent Client\n"; - private static final String HEADER = ""; private static final String TABLE_HEADER = "\n" + "\n" + - "\n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n" + - " \n"; - - private static final String TABLE_EMPTY = "" + - "\n"; + "
Status \n"; - - private static final String TABLE_HEADER2 = "TorrentETADownloadedUploadedDown RateUp Rate
No torrents loaded.
"; private static final String TABLE_FOOTER = "
\n"; diff --git a/apps/i2psnark/locale/messages_de.po b/apps/i2psnark/locale/messages_de.po new file mode 100644 index 0000000000..fd52fbb81c --- /dev/null +++ b/apps/i2psnark/locale/messages_de.po @@ -0,0 +1,186 @@ +# I2P +# Copyright (C) 2009 The I2P Project +# This file is distributed under the same license as the i2psnark package. +# To contribute translations, see http://www.i2p2.de/newdevelopers +# foo , 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: I2P i2psnark\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2009-12-09 20:35+0000\n" +"PO-Revision-Date: 2009-10-19 12:50+0000\n" +"Last-Translator: foo \n" +"Language-Team: foo \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: German\n" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:86 +msgid "I2PSnark - Anonymous BitTorrent Client" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:95 +msgid "Refresh page" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:97 +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:649 +msgid "I2PSnark" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:123 +msgid "Status" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:130 +msgid "Hide Peers" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:132 +msgid "Show Peers" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:136 +msgid "Torrent" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:138 +msgid "ETA" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:140 +msgid "Downloaded" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:142 +msgid "Uploaded" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:144 +msgid "Down Rate" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:146 +msgid "Up Rate" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:153 +msgid "Stop all torrents and the I2P tunnel" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:155 +msgid "Stop All" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:160 +msgid "Start all torrents and the I2P tunnel" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:162 +msgid "Start All" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:179 +msgid "No torrents loaded." +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:510 +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:514 +msgid "Seeding" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:512 +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:521 +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:523 +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:527 +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:529 +msgid "peers" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:516 +msgid "Complete" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:519 +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:523 +msgid "OK" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:525 +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:529 +msgid "Stalled" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:531 +msgid "No Peers" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:533 +msgid "Stopped" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:546 +msgid "View files" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:548 +msgid "Open file" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:573 +msgid "Details" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:607 +msgid "Stop the torrent" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:609 +msgid "Stop" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:615 +msgid "Start the torrent" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:617 +msgid "Start" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:622 +msgid "Remove the torrent from the active list, deleting the .torrent file" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:624 +msgid "Remove" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:628 +msgid "Delete the .torrent file and the associated data file(s)" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:630 +msgid "Delete" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:673 +msgid "Seed" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:691 +msgid "Uninteresting" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:693 +msgid "Choked" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:707 +msgid "Uninterested" +msgstr "" + +#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:709 +msgid "Choking" +msgstr "" diff --git a/build.xml b/build.xml index 1b54d2fb2e..961fe3dea4 100644 --- a/build.xml +++ b/build.xml @@ -141,6 +141,7 @@ +