forked from I2P_Developers/i2p.i2p
propagate from branch 'i2p.i2p' (head d32b82100cf6076e8f3de30b6a0edfbb034caac7)
to branch 'i2p.i2p.zzz.pcap' (head 551957edb05526df88ff3a2b3c717faed4aac906)
This commit is contained in:
10
INSTALL.txt
10
INSTALL.txt
@ -1,10 +1,17 @@
|
||||
I2P source installation instructions
|
||||
|
||||
Prerequisites to build from source:
|
||||
Java SDK (preferably Sun) 1.5.0 or higher (1.6 recommended)
|
||||
Apache Ant 1.7.0 or higher
|
||||
Optional, For multilanguage support: The xgettext, msgfmt, and msgmerge tools installed
|
||||
from the GNU gettext package http://www.gnu.org/software/gettext/
|
||||
|
||||
To build and install I2P from source, you must first build
|
||||
and package up the appropriate installer by running:
|
||||
|
||||
ant pkg
|
||||
|
||||
|
||||
This will produce a few key files:
|
||||
* install.jar: the GUI and console installer
|
||||
* i2pinstall.exe: the GUI and console installer wrapped for cross-platform execution
|
||||
@ -18,9 +25,6 @@ Or run the GUI installer:
|
||||
|
||||
Or move the update file into an existing installation directory and restart.
|
||||
|
||||
You will need to have ant installed from http://ant.apache.org/
|
||||
(1.7.0 or newer)
|
||||
|
||||
Supported JVMs:
|
||||
Windows: Latest available from http://java.sun.com/ (1.5+ supported)
|
||||
Linux: Latest available from http://java.sun.com/ (1.5+ supported)
|
||||
|
@ -1,11 +1,13 @@
|
||||
Prerequisites to build from source:
|
||||
Java SDK (preferably Sun) 1.5.0 or higher (1.6 recommended)
|
||||
Apache Ant 1.7.0 or higher
|
||||
Optional, For multilanguage support: The xgettext, msgfmt, and msgmerge tools installed
|
||||
from the GNU gettext package http://www.gnu.org/software/gettext/
|
||||
|
||||
To build:
|
||||
ant pkg
|
||||
Run 'ant' with no arguments to see other build options.
|
||||
See http://www.i2p2.de/download.html for installation instructions.
|
||||
See INSTALL.txt or http://www.i2p2.de/download.html for installation instructions.
|
||||
|
||||
Documentation:
|
||||
http://www.i2p2.de/
|
||||
|
@ -2,6 +2,6 @@
|
||||
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
||||
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
|
||||
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/1">
|
||||
<file>file:/usblv/NetBeansProjects/wi2p.i2p/apps/BOB/src/net/i2p/BOB/BOB.java</file>
|
||||
<file>file:/usblv/NetBeansProjects/i2p.i2p/apps/BOB/src/net/i2p/BOB/TCPio.java</file>
|
||||
</open-files>
|
||||
</project-private>
|
||||
|
@ -50,7 +50,7 @@ public class DoCMDS implements Runnable {
|
||||
|
||||
// FIX ME
|
||||
// I need a better way to do versioning, but this will do for now.
|
||||
public static final String BMAJ = "00", BMIN = "00", BREV = "08", BEXT = "";
|
||||
public static final String BMAJ = "00", BMIN = "00", BREV = "0A", BEXT = "";
|
||||
public static final String BOBversion = BMAJ + "." + BMIN + "." + BREV + BEXT;
|
||||
private Socket server;
|
||||
private Properties props;
|
||||
|
@ -60,20 +60,9 @@ public class I2Plistener implements Runnable {
|
||||
this._log = _log;
|
||||
this.socketManager = S;
|
||||
this.serverSocket = SS;
|
||||
// tgwatch = 1;
|
||||
this.lives = lives;
|
||||
}
|
||||
|
||||
private void rlock() throws Exception {
|
||||
database.getReadLock();
|
||||
info.getReadLock();
|
||||
}
|
||||
|
||||
private void runlock() throws Exception {
|
||||
database.releaseReadLock();
|
||||
info.releaseReadLock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply listen on I2P port, and thread connections
|
||||
*
|
||||
@ -83,34 +72,31 @@ public class I2Plistener implements Runnable {
|
||||
I2PSocket sessSocket = null;
|
||||
int conn = 0;
|
||||
try {
|
||||
die:
|
||||
{
|
||||
try {
|
||||
serverSocket.setSoTimeout(50);
|
||||
|
||||
while (lives.get()) {
|
||||
try {
|
||||
sessSocket = serverSocket.accept();
|
||||
g = true;
|
||||
} catch (ConnectException ce) {
|
||||
g = false;
|
||||
} catch (SocketTimeoutException ste) {
|
||||
g = false;
|
||||
}
|
||||
if (g) {
|
||||
g = false;
|
||||
conn++;
|
||||
// toss the connection to a new thread.
|
||||
I2PtoTCP conn_c = new I2PtoTCP(sessSocket, info, database, lives);
|
||||
Thread t = new Thread(conn_c, Thread.currentThread().getName() + " I2PtoTCP " + conn);
|
||||
t.start();
|
||||
}
|
||||
try {
|
||||
serverSocket.setSoTimeout(50);
|
||||
|
||||
while (lives.get()) {
|
||||
try {
|
||||
sessSocket = serverSocket.accept();
|
||||
g = true;
|
||||
} catch (ConnectException ce) {
|
||||
g = false;
|
||||
} catch (SocketTimeoutException ste) {
|
||||
g = false;
|
||||
}
|
||||
} catch (I2PException e) {
|
||||
// bad shit
|
||||
System.out.println("Exception " + e);
|
||||
if (g) {
|
||||
g = false;
|
||||
conn++;
|
||||
// toss the connection to a new thread.
|
||||
I2PtoTCP conn_c = new I2PtoTCP(sessSocket, info, database, lives);
|
||||
Thread t = new Thread(conn_c, Thread.currentThread().getName() + " I2PtoTCP " + conn);
|
||||
t.start();
|
||||
}
|
||||
|
||||
}
|
||||
} catch (I2PException e) {
|
||||
// bad shit
|
||||
System.out.println("Exception " + e);
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
|
@ -104,10 +104,10 @@ public class MUXlisten implements Runnable {
|
||||
this.database.releaseReadLock();
|
||||
this.info.releaseReadLock();
|
||||
|
||||
socketManager = I2PSocketManagerFactory.createManager(prikey, Q);
|
||||
if (this.come_in) {
|
||||
this.listener = new ServerSocket(port, backlog, host);
|
||||
}
|
||||
socketManager = I2PSocketManagerFactory.createManager(prikey, Q);
|
||||
// I2PException, IOException, RuntimeException
|
||||
// To bad we can't just catch and enumerate....
|
||||
// } catch (I2PException e) {
|
||||
@ -141,8 +141,6 @@ public class MUXlisten implements Runnable {
|
||||
this.info.add("STARTING", new Boolean(false));
|
||||
this.info.releaseWriteLock();
|
||||
this.database.releaseWriteLock();
|
||||
// throw new Exception(e);
|
||||
// Debugging, I guess.
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -78,16 +78,20 @@ public class TCPio implements Runnable {
|
||||
* --Sponge
|
||||
*
|
||||
* Tested with 128 bytes, and there was no performance gain.
|
||||
* 8192 bytes did lower load average across many connections.
|
||||
* Should I raise it higer? The correct thing to do would be to
|
||||
* override... perhaps use NTCP, but I2P's streaming lib lacks
|
||||
* anything NTCP compatable.
|
||||
*
|
||||
* --Sponge
|
||||
*/
|
||||
|
||||
int b;
|
||||
byte a[] = new byte[1];
|
||||
byte a[] = new byte[8192];
|
||||
try {
|
||||
try {
|
||||
while (lives.get()) {
|
||||
b = Ain.read(a, 0, 1);
|
||||
b = Ain.read(a, 0, 8192);
|
||||
if (b > 0) {
|
||||
Aout.write(a, 0, b);
|
||||
} else if (b == 0) {
|
||||
|
@ -64,16 +64,6 @@ public class TCPlistener implements Runnable {
|
||||
this.lives = lives;
|
||||
}
|
||||
|
||||
private void rlock() throws Exception {
|
||||
database.getReadLock();
|
||||
info.getReadLock();
|
||||
}
|
||||
|
||||
private void runlock() throws Exception {
|
||||
database.releaseReadLock();
|
||||
info.releaseReadLock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply listen on TCP port, and thread connections
|
||||
*
|
||||
@ -81,30 +71,27 @@ public class TCPlistener implements Runnable {
|
||||
public void run() {
|
||||
boolean g = false;
|
||||
int conn = 0;
|
||||
Socket server = null;
|
||||
try {
|
||||
die:
|
||||
{
|
||||
try {
|
||||
Socket server = new Socket();
|
||||
listener.setSoTimeout(50); // We don't block, we cycle and check.
|
||||
while (lives.get()) {
|
||||
try {
|
||||
server = listener.accept();
|
||||
g = true;
|
||||
} catch (SocketTimeoutException ste) {
|
||||
g = false;
|
||||
}
|
||||
if (g) {
|
||||
conn++;
|
||||
// toss the connection to a new thread.
|
||||
TCPtoI2P conn_c = new TCPtoI2P(socketManager, server, info, database, lives);
|
||||
Thread t = new Thread(conn_c, Thread.currentThread().getName() + " TCPtoI2P " + conn);
|
||||
t.start();
|
||||
g = false;
|
||||
}
|
||||
try {
|
||||
listener.setSoTimeout(50); // We don't block, we cycle and check.
|
||||
while (lives.get()) {
|
||||
try {
|
||||
server = listener.accept();
|
||||
g = true;
|
||||
} catch (SocketTimeoutException ste) {
|
||||
g = false;
|
||||
}
|
||||
if (g) {
|
||||
conn++;
|
||||
// toss the connection to a new thread.
|
||||
TCPtoI2P conn_c = new TCPtoI2P(socketManager, server, info, database, lives);
|
||||
Thread t = new Thread(conn_c, Thread.currentThread().getName() + " TCPtoI2P " + conn);
|
||||
t.start();
|
||||
g = false;
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
|
@ -21,24 +21,48 @@
|
||||
|
||||
package net.i2p.addressbook;
|
||||
|
||||
import javax.servlet.GenericServlet;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* A wrapper for addressbook to allow it to be started as a web application.
|
||||
*
|
||||
* This was a GenericServlet, we make it an HttpServlet solely to provide a hook
|
||||
* for SusiDNS to wake us up when the subscription list changes.
|
||||
*
|
||||
* @author Ragnarok
|
||||
*
|
||||
*/
|
||||
public class Servlet extends GenericServlet {
|
||||
public class Servlet extends HttpServlet {
|
||||
private Thread thread;
|
||||
private String nonce;
|
||||
private static final String PROP_NONCE = "addressbook.nonce";
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
|
||||
/**
|
||||
* Hack to allow susidns to kick the daemon when the subscription list changes.
|
||||
* URL must be /addressbook/ with wakeup param set, and nonce param set from system property.
|
||||
*
|
||||
* (non-Javadoc)
|
||||
* see javax.servlet.Servlet#service(javax.servlet.ServletRequest, javax.servlet.ServletResponse)
|
||||
*/
|
||||
public void service(ServletRequest request, ServletResponse response) {
|
||||
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||
//System.err.println("Got request nonce = " + request.getParameter("nonce"));
|
||||
if (this.thread != null && request.getParameter("wakeup") != null &&
|
||||
this.nonce != null && this.nonce.equals(request.getParameter("nonce"))) {
|
||||
//System.err.println("Sending interrupt");
|
||||
this.thread.interrupt();
|
||||
// no output
|
||||
} else {
|
||||
PrintWriter out = response.getWriter();
|
||||
out.write("I2P addressbook OK");
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
@ -49,15 +73,19 @@ public class Servlet extends GenericServlet {
|
||||
try {
|
||||
super.init(config);
|
||||
} catch (ServletException exp) {
|
||||
System.err.println("Addressbook init exception: " + exp);
|
||||
}
|
||||
this.nonce = "" + Math.abs((new Random()).nextLong());
|
||||
// put the nonce where susidns can get it
|
||||
System.setProperty(PROP_NONCE, this.nonce);
|
||||
String[] args = new String[1];
|
||||
args[0] = config.getInitParameter("home");
|
||||
DaemonThread thread = new DaemonThread(args);
|
||||
thread.setDaemon(true);
|
||||
thread.setName("Addressbook");
|
||||
thread.start();
|
||||
this.thread = new DaemonThread(args);
|
||||
this.thread.setDaemon(true);
|
||||
this.thread.setName("Addressbook");
|
||||
this.thread.start();
|
||||
System.out.println("INFO: Starting Addressbook " + Daemon.VERSION);
|
||||
System.out.println("INFO: config root under " + args[0]);
|
||||
//System.out.println("INFO: config root under " + args[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,4 +13,10 @@
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>addressbook</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
</web-app>
|
||||
|
17
apps/i2psnark/java/bmsg.sh
Normal file
17
apps/i2psnark/java/bmsg.sh
Normal file
@ -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
|
@ -37,7 +37,7 @@
|
||||
</javac>
|
||||
</target>
|
||||
<target name="jar" depends="builddep, compile">
|
||||
<jar destfile="./build/i2psnark.jar" basedir="./build/obj" includes="**/*.class" excludes="**/I2PSnarkServlet*.class">
|
||||
<jar destfile="./build/i2psnark.jar" basedir="./build/obj" includes="**/*.class" excludes="**/I2PSnarkServlet*.class **/messages_*.class">
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="org.klomp.snark.Snark" />
|
||||
<attribute name="Class-Path" value="i2p.jar mstreaming.jar streaming.jar" />
|
||||
@ -51,12 +51,44 @@
|
||||
- So we must continue to duplicate everything in the war.
|
||||
<classes dir="./build/obj" includes="**/I2PSnarkServlet*.class" />
|
||||
-->
|
||||
<target name="war" depends="jar">
|
||||
<target name="war" depends="jar, bundle">
|
||||
<war destfile="../i2psnark.war" webxml="../web.xml">
|
||||
<classes dir="./build/obj" includes="**/*.class" excludes="**/RunStandalone.class" />
|
||||
</war>
|
||||
</target>
|
||||
|
||||
<target name="bundle" depends="compile">
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="false" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="false" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="cmd" osfamily="windows" failifexecutionfails="false" >
|
||||
<arg value="/c" />
|
||||
<arg value="bundle-messages.bat" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="poupdate" depends="compile">
|
||||
<!-- Update the messages_*.po files. -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
<arg value="-p" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
<arg value="-p" />
|
||||
</exec>
|
||||
<exec executable="cmd" osfamily="windows" failifexecutionfails="true" >
|
||||
<arg value="/c" />
|
||||
<arg value="bundle-messages.bat" />
|
||||
<arg value="-p" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="standalone" depends="standalone_prep">
|
||||
<zip destfile="i2psnark-standalone.zip">
|
||||
<zipfileset dir="./dist/" prefix="i2psnark/" />
|
||||
@ -95,9 +127,7 @@
|
||||
<delete dir="./dist" />
|
||||
</target>
|
||||
<target name="cleandep" depends="clean">
|
||||
<ant dir="../../ministreaming/java/" target="distclean" />
|
||||
</target>
|
||||
<target name="distclean" depends="clean">
|
||||
<ant dir="../../ministreaming/java/" target="distclean" />
|
||||
</target>
|
||||
</project>
|
||||
|
26
apps/i2psnark/java/bundle-messages.bat
Normal file
26
apps/i2psnark/java/bundle-messages.bat
Normal file
@ -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
|
85
apps/i2psnark/java/bundle-messages.sh
Executable file
85
apps/i2psnark/java/bundle-messages.sh
Executable file
@ -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.web.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/web/messages_$LG.class -a \
|
||||
build/obj/org/klomp/snark/web/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 --statistics -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
|
@ -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,32 @@ public class I2PSnarkUtil {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static final String BUNDLE_NAME = "org.klomp.snark.web.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);
|
||||
}
|
||||
|
||||
/** {0} and {1} */
|
||||
public String getString(String s, Object o, Object o2) {
|
||||
return Translate.getString(s, o, o2, _context, BUNDLE_NAME);
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.OrderedProperties;
|
||||
|
||||
/**
|
||||
* Manage multiple snarks
|
||||
@ -80,7 +81,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
_peerCoordinatorSet = new PeerCoordinatorSet();
|
||||
_connectionAcceptor = new ConnectionAcceptor(_util);
|
||||
int minutes = getStartupDelayMinutes();
|
||||
_messages.add("Adding torrents in " + minutes + (minutes == 1 ? " minute" : " minutes"));
|
||||
_messages.add(_("Adding torrents in {0} minutes", minutes));
|
||||
I2PAppThread monitor = new I2PAppThread(new DirMonitor(), "Snark DirMonitor");
|
||||
monitor.setDaemon(true);
|
||||
monitor.start();
|
||||
@ -126,7 +127,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
/** null to set initial defaults */
|
||||
public void loadConfig(String filename) {
|
||||
if (_config == null)
|
||||
_config = new Properties();
|
||||
_config = new OrderedProperties();
|
||||
if (filename != null) {
|
||||
File cfg = new File(filename);
|
||||
if (!cfg.isAbsolute())
|
||||
@ -216,6 +217,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
String upLimit, String upBW, boolean useOpenTrackers, String openTrackers) {
|
||||
boolean changed = false;
|
||||
if (eepHost != null) {
|
||||
// unused, we use socket eepget
|
||||
int port = _util.getEepProxyPort();
|
||||
try { port = Integer.parseInt(eepPort); } catch (NumberFormatException nfe) {}
|
||||
String host = _util.getEepProxyHost();
|
||||
@ -236,9 +238,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
_util.setMaxUploaders(limit);
|
||||
changed = true;
|
||||
_config.setProperty(PROP_UPLOADERS_TOTAL, "" + limit);
|
||||
addMessage("Total uploaders limit changed to " + limit);
|
||||
addMessage(_("Total uploaders limit changed to {0}", limit));
|
||||
} else {
|
||||
addMessage("Minimum total uploaders limit is " + Snark.MIN_TOTAL_UPLOADERS);
|
||||
addMessage(_("Minimum total uploaders limit is {0}", Snark.MIN_TOTAL_UPLOADERS));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -250,9 +252,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
_util.setMaxUpBW(limit);
|
||||
changed = true;
|
||||
_config.setProperty(PROP_UPBW_MAX, "" + limit);
|
||||
addMessage("Up BW limit changed to " + limit + "KBps");
|
||||
addMessage(_("Up BW limit changed to {0}KBps", limit));
|
||||
} else {
|
||||
addMessage("Minimum Up BW limit is " + MIN_UP_BW + "KBps");
|
||||
addMessage(_("Minimum up bandwidth limit is {0}KBps", MIN_UP_BW));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -296,27 +298,27 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
}
|
||||
}
|
||||
if (snarksActive) {
|
||||
addMessage("Cannot change the I2CP settings while torrents are active");
|
||||
addMessage(_("Cannot change the I2CP settings while torrents are active"));
|
||||
_log.debug("i2cp host [" + i2cpHost + "] i2cp port " + port + " opts [" + opts
|
||||
+ "] oldOpts [" + oldOpts + "]");
|
||||
} else {
|
||||
if (_util.connected()) {
|
||||
_util.disconnect();
|
||||
addMessage("Disconnecting old I2CP destination");
|
||||
addMessage(_("Disconnecting old I2CP destination"));
|
||||
}
|
||||
Properties p = new Properties();
|
||||
p.putAll(opts);
|
||||
addMessage("I2CP settings changed to " + i2cpHost + ":" + port + " (" + i2cpOpts.trim() + ")");
|
||||
addMessage(_("I2CP settings changed to {0}", i2cpHost + ":" + port + " (" + i2cpOpts.trim() + ")"));
|
||||
_util.setI2CPConfig(i2cpHost, port, p);
|
||||
boolean ok = _util.connect();
|
||||
if (!ok) {
|
||||
addMessage("Unable to connect with the new settings, reverting to the old I2CP settings");
|
||||
addMessage(_("Unable to connect with the new settings, reverting to the old I2CP settings"));
|
||||
_util.setI2CPConfig(oldI2CPHost, oldI2CPPort, oldOpts);
|
||||
ok = _util.connect();
|
||||
if (!ok)
|
||||
addMessage("Unable to reconnect with the old settings!");
|
||||
addMessage(_("Unable to reconnect with the old settings!"));
|
||||
} else {
|
||||
addMessage("Reconnected on the new I2CP destination");
|
||||
addMessage(_("Reconnected on the new I2CP destination"));
|
||||
_config.setProperty(PROP_I2CP_HOST, i2cpHost.trim());
|
||||
_config.setProperty(PROP_I2CP_PORT, "" + port);
|
||||
_config.setProperty(PROP_I2CP_OPTS, i2cpOpts.trim());
|
||||
@ -327,7 +329,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
Snark snark = getTorrent(name);
|
||||
if ( (snark != null) && (snark.acceptor != null) ) {
|
||||
snark.acceptor.restart();
|
||||
addMessage("I2CP listener restarted for " + snark.meta.getName());
|
||||
addMessage(_("I2CP listener restarted for \"{0}\"", snark.meta.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -337,26 +339,32 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
}
|
||||
if (shouldAutoStart() != autoStart) {
|
||||
_config.setProperty(PROP_AUTO_START, autoStart + "");
|
||||
addMessage("Adjusted autostart to " + autoStart);
|
||||
if (autoStart)
|
||||
addMessage(_("Enabled autostart"));
|
||||
else
|
||||
addMessage(_("Disabled autostart"));
|
||||
changed = true;
|
||||
}
|
||||
if (_util.shouldUseOpenTrackers() != useOpenTrackers) {
|
||||
_config.setProperty(I2PSnarkUtil.PROP_USE_OPENTRACKERS, useOpenTrackers + "");
|
||||
addMessage((useOpenTrackers ? "En" : "Dis") + "abled open trackers - torrent restart required to take effect.");
|
||||
if (useOpenTrackers)
|
||||
addMessage(_("Enabled open trackers - torrent restart required to take effect."));
|
||||
else
|
||||
addMessage(_("Disabled open trackers - torrent restart required to take effect."));
|
||||
changed = true;
|
||||
}
|
||||
if (openTrackers != null) {
|
||||
if (openTrackers.trim().length() > 0 && !openTrackers.trim().equals(_util.getOpenTrackerString())) {
|
||||
_config.setProperty(I2PSnarkUtil.PROP_OPENTRACKERS, openTrackers.trim());
|
||||
_util.setOpenTrackerString(openTrackers);
|
||||
addMessage("Open Tracker list changed - torrent restart required to take effect.");
|
||||
addMessage(_("Open Tracker list changed - torrent restart required to take effect."));
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
saveConfig();
|
||||
} else {
|
||||
addMessage("Configuration unchanged.");
|
||||
addMessage(_("Configuration unchanged."));
|
||||
}
|
||||
}
|
||||
|
||||
@ -366,7 +374,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
DataHelper.storeProps(_config, _configFile);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
addMessage("Unable to save the config to '" + _configFile.getAbsolutePath() + "'.");
|
||||
addMessage(_("Unable to save the config to {0}", _configFile.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -384,10 +392,10 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
public void addTorrent(String filename) { addTorrent(filename, false); }
|
||||
public void addTorrent(String filename, boolean dontAutoStart) {
|
||||
if ((!dontAutoStart) && !_util.connected()) {
|
||||
addMessage("Connecting to I2P");
|
||||
addMessage(_("Connecting to I2P"));
|
||||
boolean ok = _util.connect();
|
||||
if (!ok) {
|
||||
addMessage("Error connecting to I2P - check your I2CP settings!");
|
||||
addMessage(_("Error connecting to I2P - check your I2CP settings!"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -396,7 +404,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
filename = sfile.getCanonicalPath();
|
||||
} catch (IOException ioe) {
|
||||
_log.error("Unable to add the torrent " + filename, ioe);
|
||||
addMessage("ERR: Could not add the torrent '" + filename + "': " + ioe.getMessage());
|
||||
addMessage(_("Error: Could not add the torrent {0}", filename) + ": " + ioe.getMessage());
|
||||
return;
|
||||
}
|
||||
File dataDir = getDataDir();
|
||||
@ -435,7 +443,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
addMessage("Torrent in " + sfile.getName() + " is invalid: " + ioe.getMessage());
|
||||
addMessage(_("Torrent in \"{0}\" is invalid", sfile.getName()) + ": " + ioe.getMessage());
|
||||
if (sfile.exists())
|
||||
sfile.delete();
|
||||
return;
|
||||
@ -450,9 +458,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
File f = new File(filename);
|
||||
if (!dontAutoStart && shouldAutoStart()) {
|
||||
torrent.startTorrent();
|
||||
addMessage("Torrent added and started: '" + f.getName() + "'.");
|
||||
addMessage(_("Torrent added and started: \"{0}\"", f.getName()));
|
||||
} else {
|
||||
addMessage("Torrent added: '" + f.getName() + "'.");
|
||||
addMessage(_("Torrent added: \"{0}\"", f.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -548,19 +556,19 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
// basic validation of url
|
||||
if ((!announce.startsWith("http://")) ||
|
||||
(announce.indexOf(".i2p/") < 0)) // need to do better than this
|
||||
return "Non-i2p tracker in " + info.getName() + ", deleting it from our list of trackers!";
|
||||
return _("Non-i2p tracker in \"{0}\", deleting it from our list of trackers!", info.getName());
|
||||
List files = info.getFiles();
|
||||
if ( (files != null) && (files.size() > MAX_FILES_PER_TORRENT) ) {
|
||||
return "Too many files in " + info.getName() + " (" + files.size() + "), deleting it!";
|
||||
return _("Too many files in \"{0}\" ({1}), deleting it!", info.getName(), files.size());
|
||||
} else if ( (files == null) && (info.getName().endsWith(".torrent")) ) {
|
||||
return "Torrent file " + info.getName() + " cannot end in '.torrent', deleting it!";
|
||||
return _("Torrent file \"{0}\" cannot end in '.torrent', deleting it!", info.getName());
|
||||
} else if (info.getPieces() <= 0) {
|
||||
return "No pieces in " + info.getName() + "? deleting it!";
|
||||
return _("No pieces in \"{0}\", deleting it!", info.getName());
|
||||
} else if (info.getPieces() > Storage.MAX_PIECES) {
|
||||
return "Too many pieces in " + info.getName() + ", limit is " + Storage.MAX_PIECES + ", deleting it!";
|
||||
return _("Too many pieces in \"{0}\", limit is {1}, deleting it!", info.getName(), Storage.MAX_PIECES);
|
||||
} else if (info.getPieceLength(0) > Storage.MAX_PIECE_SIZE) {
|
||||
return "Pieces are too large in " + info.getName() + " (" + DataHelper.formatSize(info.getPieceLength(0)) +
|
||||
"B, limit is " + DataHelper.formatSize(Storage.MAX_PIECE_SIZE) + "B), deleting it.";
|
||||
return _("Pieces are too large in \"{0}\" ({1}B), deleting it.", info.getName(), DataHelper.formatSize(info.getPieceLength(0))) + ' ' +
|
||||
_("Limit is {0}B", DataHelper.formatSize(Storage.MAX_PIECE_SIZE));
|
||||
} else if (info.getTotalLength() > Storage.MAX_TOTAL_SIZE) {
|
||||
System.out.println("torrent info: " + info.toString());
|
||||
List lengths = info.getLengths();
|
||||
@ -568,8 +576,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
for (int i = 0; i < lengths.size(); i++)
|
||||
System.out.println("File " + i + " is " + lengths.get(i) + " long.");
|
||||
|
||||
return "Torrents larger than " + DataHelper.formatSize(Storage.MAX_TOTAL_SIZE) +
|
||||
"B are not supported yet (because we're paranoid): " + info.getName() + ", deleting it!";
|
||||
return _("Torrents larger than {0}B are not supported yet, deleting \"{1}\"", Storage.MAX_TOTAL_SIZE, info.getName());
|
||||
} else {
|
||||
// ok
|
||||
return null;
|
||||
@ -585,7 +592,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
filename = sfile.getCanonicalPath();
|
||||
} catch (IOException ioe) {
|
||||
_log.error("Unable to remove the torrent " + filename, ioe);
|
||||
addMessage("ERR: Could not remove the torrent '" + filename + "': " + ioe.getMessage());
|
||||
addMessage(_("Error: Could not remove the torrent {0}", filename) + ": " + ioe.getMessage());
|
||||
return null;
|
||||
}
|
||||
int remaining = 0;
|
||||
@ -606,7 +613,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
////_util.
|
||||
}
|
||||
if (!wasStopped)
|
||||
addMessage("Torrent stopped: '" + sfile.getName() + "'.");
|
||||
addMessage(_("Torrent stopped: \"{0}\"", sfile.getName()));
|
||||
}
|
||||
return torrent;
|
||||
}
|
||||
@ -621,7 +628,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
torrentFile.delete();
|
||||
if (torrent.storage != null)
|
||||
removeTorrentStatus(torrent.storage.getMetaInfo());
|
||||
addMessage("Torrent removed: '" + torrentFile.getName() + "'.");
|
||||
addMessage(_("Torrent removed: \"{0}\"", torrentFile.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -654,7 +661,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
public void torrentComplete(Snark snark) {
|
||||
File f = new File(snark.torrent);
|
||||
long len = snark.meta.getTotalLength();
|
||||
addMessage("Download finished: " + f.getName() + " (size: " + DataHelper.formatSize(len) + "B)");
|
||||
addMessage(_("Download finished: \"{0}\"", f.getName()) + " (" + _("size: {0}B", DataHelper.formatSize(len)) + ')');
|
||||
updateStatus(snark);
|
||||
}
|
||||
|
||||
@ -682,7 +689,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
// already known. noop
|
||||
} else {
|
||||
if (shouldAutoStart() && !_util.connect())
|
||||
addMessage("Unable to connect to I2P!");
|
||||
addMessage(_("Unable to connect to I2P!"));
|
||||
addTorrent((String)foundNames.get(i), !shouldAutoStart());
|
||||
}
|
||||
}
|
||||
@ -698,6 +705,21 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
}
|
||||
}
|
||||
|
||||
/** translate */
|
||||
private String _(String s) {
|
||||
return _util.getString(s);
|
||||
}
|
||||
|
||||
/** translate */
|
||||
private String _(String s, Object o) {
|
||||
return _util.getString(s, o);
|
||||
}
|
||||
|
||||
/** translate */
|
||||
private String _(String s, Object o, Object o2) {
|
||||
return _util.getString(s, o, o2);
|
||||
}
|
||||
|
||||
/**
|
||||
* "name", "announceURL=websiteURL" pairs
|
||||
*/
|
||||
|
@ -80,13 +80,25 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
}
|
||||
|
||||
PrintWriter out = resp.getWriter();
|
||||
out.write(HEADER_BEGIN);
|
||||
out.write("<html>\n" +
|
||||
"<head>\n" +
|
||||
"<title>");
|
||||
out.write(_("I2PSnark - Anonymous BitTorrent Client"));
|
||||
out.write("</title>\n");
|
||||
|
||||
// we want it to go to the base URI so we don't refresh with some funky action= value
|
||||
out.write("<meta http-equiv=\"refresh\" content=\"60;" + req.getRequestURI() + peerString + "\">\n");
|
||||
out.write(HEADER);
|
||||
out.write("</head><body>");
|
||||
out.write("<center>");
|
||||
out.write("<div class=\"snarknavbar\"><a href=\"" + req.getRequestURI() + peerString + "\" title=\"Refresh page\" class=\"snarkRefresh\">I2PSnark</a> <a href=\"http://forum.i2p/viewforum.php?f=21\" class=\"snarkRefresh\" target=\"_blank\">Forum</a>\n");
|
||||
out.write("<div class=\"snarknavbar\"><a href=\"" + req.getRequestURI() + peerString + "\" title=\"");
|
||||
out.write(_("Refresh page"));
|
||||
out.write("\" class=\"snarkRefresh\">");
|
||||
out.write(_("I2PSnark"));
|
||||
out.write("</a> <a href=\"http://forum.i2p/viewforum.php?f=21\" class=\"snarkRefresh\" target=\"_blank\">");
|
||||
out.write(_("Forum"));
|
||||
out.write("</a>\n");
|
||||
|
||||
Map trackers = _manager.getTrackers();
|
||||
for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) {
|
||||
Map.Entry entry = (Map.Entry)iter.next();
|
||||
@ -110,22 +122,51 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
List snarks = getSortedSnarks(req);
|
||||
String uri = req.getRequestURI();
|
||||
out.write(TABLE_HEADER);
|
||||
out.write(_("Status"));
|
||||
if (_manager.util().connected() && snarks.size() > 0) {
|
||||
if (peerParam != null)
|
||||
out.write("(<a href=\"" + req.getRequestURI() + "\">Hide Peers</a>)<br>\n");
|
||||
else
|
||||
out.write("(<a href=\"" + req.getRequestURI() + "?p=1" + "\">Show Peers</a>)<br>\n");
|
||||
out.write(" (<a href=\"");
|
||||
out.write(req.getRequestURI());
|
||||
if (peerParam != null) {
|
||||
out.write("\">");
|
||||
out.write(_("Hide Peers"));
|
||||
} else {
|
||||
out.write("?p=1\">");
|
||||
out.write(_("Show Peers"));
|
||||
}
|
||||
out.write("</a>)<br>\n");
|
||||
}
|
||||
out.write(TABLE_HEADER2);
|
||||
out.write("</th>\n<th align=\"left\">");
|
||||
out.write(_("Torrent"));
|
||||
out.write("</th>\n<th align=\"center\">");
|
||||
out.write(_("ETA"));
|
||||
out.write("</th>\n<th align=\"right\">");
|
||||
out.write(_("Downloaded"));
|
||||
out.write("</th>\n<th align=\"right\">");
|
||||
out.write(_("Uploaded"));
|
||||
out.write("</th>\n<th align=\"right\">");
|
||||
out.write(_("Down Rate"));
|
||||
out.write("</th>\n<th align=\"right\">");
|
||||
out.write(_("Up Rate"));
|
||||
out.write("</th>\n");
|
||||
|
||||
out.write("<th align=\"center\">");
|
||||
if (_manager.util().connected())
|
||||
if (_manager.util().connected()) {
|
||||
out.write("<a href=\"" + uri + "?action=StopAll&nonce=" + _nonce +
|
||||
"\" title=\"Stop all torrents and the I2P tunnel\">Stop All</a>");
|
||||
else if (snarks.size() > 0)
|
||||
"\" title=\"");
|
||||
out.write(_("Stop all torrents and the I2P tunnel"));
|
||||
out.write("\">");
|
||||
out.write(_("Stop All"));
|
||||
out.write("</a>");
|
||||
} else if (snarks.size() > 0) {
|
||||
out.write("<a href=\"" + uri + "?action=StartAll&nonce=" + _nonce +
|
||||
"\" title=\"Start all torrents and the I2P tunnel\">Start All</a>");
|
||||
else
|
||||
"\" title=\"");
|
||||
out.write(_("Start all torrents and the I2P tunnel"));
|
||||
out.write("\">");
|
||||
out.write(_("Start All"));
|
||||
out.write("</a>");
|
||||
} else {
|
||||
out.write(" ");
|
||||
}
|
||||
out.write("</th></tr></thead>\n");
|
||||
for (int i = 0; i < snarks.size(); i++) {
|
||||
Snark snark = (Snark)snarks.get(i);
|
||||
@ -133,14 +174,23 @@ 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("<tr class=\"snarkTorrentEven\">" +
|
||||
"<td class=\"snarkTorrentEven\" align=\"center\"" +
|
||||
" colspan=\"8\"><i>");
|
||||
out.write(_("No torrents loaded."));
|
||||
out.write("</i></td></tr>\n");
|
||||
} else if (snarks.size() > 1) {
|
||||
out.write("<tfoot><tr>\n" +
|
||||
" <th align=\"left\" colspan=\"2\">Totals (" +
|
||||
snarks.size() + " torrents, " +
|
||||
DataHelper.formatSize(stats[5]) + "B, " +
|
||||
stats[4] + " connected peers)</th>\n" +
|
||||
" <th align=\"left\" colspan=\"2\">");
|
||||
out.write(_("Totals"));
|
||||
out.write(" (");
|
||||
out.write(_("{0} torrents", snarks.size()));
|
||||
out.write(", ");
|
||||
out.write(DataHelper.formatSize(stats[5]) + "B, ");
|
||||
out.write(_("{0} connected peers", stats[4]));
|
||||
out.write(")</th>\n" +
|
||||
" <th> </th>\n" +
|
||||
" <th align=\"right\">" + formatSize(stats[0]) + "</th>\n" +
|
||||
" <th align=\"right\">" + formatSize(stats[1]) + "</th>\n" +
|
||||
@ -166,7 +216,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
String action = req.getParameter("action");
|
||||
if (action == null) {
|
||||
// noop
|
||||
} else if ("Add torrent".equals(action)) {
|
||||
} else if ("Add".equals(action)) {
|
||||
String newFile = req.getParameter("newFile");
|
||||
String newURL = req.getParameter("newURL");
|
||||
// NOTE - newFile currently disabled in HTML form - see below
|
||||
@ -174,7 +224,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
if ( (newFile != null) && (newFile.trim().length() > 0) )
|
||||
f = new File(newFile.trim());
|
||||
if ( (f != null) && (!f.exists()) ) {
|
||||
_manager.addMessage("Torrent file " + newFile +" does not exist");
|
||||
_manager.addMessage(_("Torrent file {0} does not exist", newFile));
|
||||
}
|
||||
if ( (f != null) && (f.exists()) ) {
|
||||
File local = new File(_manager.getDataDir(), f.getName());
|
||||
@ -184,16 +234,16 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
|
||||
if (local.exists()) {
|
||||
if (_manager.getTorrent(canonical) != null)
|
||||
_manager.addMessage("Torrent already running: " + newFile);
|
||||
_manager.addMessage(_("Torrent already running: {0}", newFile));
|
||||
else
|
||||
_manager.addMessage("Torrent already in the queue: " + newFile);
|
||||
_manager.addMessage(_("Torrent already in the queue: {0}", newFile));
|
||||
} else {
|
||||
boolean ok = FileUtil.copy(f.getAbsolutePath(), local.getAbsolutePath(), true);
|
||||
if (ok) {
|
||||
_manager.addMessage("Copying torrent to " + local.getAbsolutePath());
|
||||
_manager.addMessage(_("Copying torrent to {0}", local.getAbsolutePath()));
|
||||
_manager.addTorrent(canonical);
|
||||
} else {
|
||||
_manager.addMessage("Unable to copy the torrent to " + local.getAbsolutePath() + " from " + f.getAbsolutePath());
|
||||
_manager.addMessage(_("Unable to copy the torrent to {0}", local.getAbsolutePath()) + ' ' + _("from {0}", f.getAbsolutePath()));
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
@ -201,11 +251,11 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
}
|
||||
} else if (newURL != null) {
|
||||
if (newURL.startsWith("http://")) {
|
||||
_manager.addMessage("Fetching " + newURL);
|
||||
_manager.addMessage(_("Fetching {0}", newURL));
|
||||
I2PAppThread fetch = new I2PAppThread(new FetchAndAdd(_manager, newURL), "Fetch and add");
|
||||
fetch.start();
|
||||
} else {
|
||||
_manager.addMessage("Invalid URL - must start with http://");
|
||||
_manager.addMessage(_("Invalid URL - must start with http://"));
|
||||
}
|
||||
} else {
|
||||
// no file or URL specified
|
||||
@ -235,7 +285,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
Snark snark = _manager.getTorrent(name);
|
||||
if ( (snark != null) && (DataHelper.eq(infoHash, snark.meta.getInfoHash())) ) {
|
||||
snark.startTorrent();
|
||||
_manager.addMessage("Starting up torrent " + name);
|
||||
_manager.addMessage(_("Starting up torrent {0}", name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -255,7 +305,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
// yeah, need to, otherwise it'll get autoadded again (at the moment
|
||||
File f = new File(name);
|
||||
f.delete();
|
||||
_manager.addMessage("Torrent file deleted: " + f.getAbsolutePath());
|
||||
_manager.addMessage(_("Torrent file deleted: {0}", f.getAbsolutePath()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -273,15 +323,15 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
_manager.stopTorrent(name, true);
|
||||
File f = new File(name);
|
||||
f.delete();
|
||||
_manager.addMessage("Torrent file deleted: " + f.getAbsolutePath());
|
||||
_manager.addMessage(_("Torrent file deleted: {0}", f.getAbsolutePath()));
|
||||
List files = snark.meta.getFiles();
|
||||
String dataFile = snark.meta.getName();
|
||||
f = new File(_manager.getDataDir(), dataFile);
|
||||
if (files == null) { // single file torrent
|
||||
if (f.delete())
|
||||
_manager.addMessage("Data file deleted: " + f.getAbsolutePath());
|
||||
_manager.addMessage(_("Data file deleted: {0}", f.getAbsolutePath()));
|
||||
else
|
||||
_manager.addMessage("Data file could not be deleted: " + f.getAbsolutePath());
|
||||
_manager.addMessage(_("Data file could not be deleted: {0}", f.getAbsolutePath()));
|
||||
break;
|
||||
}
|
||||
for (int i = 0; i < files.size(); i++) { // pass 1 delete files
|
||||
@ -289,9 +339,9 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
// each of those lists just contain a single file afaict...
|
||||
File df = Storage.getFileFromNames(f, (List) files.get(i));
|
||||
if (df.delete())
|
||||
_manager.addMessage("Data file deleted: " + df.getAbsolutePath());
|
||||
_manager.addMessage(_("Data file deleted: {0}", df.getAbsolutePath()));
|
||||
else
|
||||
_manager.addMessage("Data file could not be deleted: " + df.getAbsolutePath());
|
||||
_manager.addMessage(_("Data file could not be deleted: {0}", df.getAbsolutePath()));
|
||||
}
|
||||
for (int i = files.size() - 1; i >= 0; i--) { // pass 2 delete dirs - not foolproof,
|
||||
// we could sort and do a strict bottom-up
|
||||
@ -300,14 +350,14 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
if (df == null || !df.exists())
|
||||
continue;
|
||||
if(df.delete())
|
||||
_manager.addMessage("Data dir deleted: " + df.getAbsolutePath());
|
||||
_manager.addMessage(_("Data dir deleted: {0}", df.getAbsolutePath()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ("Save configuration".equals(action)) {
|
||||
} else if ("Save".equals(action)) {
|
||||
String dataDir = req.getParameter("dataDir");
|
||||
boolean autoStart = req.getParameter("autoStart") != null;
|
||||
String seedPct = req.getParameter("seedPct");
|
||||
@ -321,7 +371,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
boolean useOpenTrackers = req.getParameter("useOpenTrackers") != null;
|
||||
String openTrackers = req.getParameter("openTrackers");
|
||||
_manager.updateConfig(dataDir, autoStart, seedPct, eepHost, eepPort, i2cpHost, i2cpPort, i2cpOpts, upLimit, upBW, useOpenTrackers, openTrackers);
|
||||
} else if ("Create torrent".equals(action)) {
|
||||
} else if ("Create".equals(action)) {
|
||||
String baseData = req.getParameter("baseFile");
|
||||
if (baseData != null && baseData.trim().length() > 0) {
|
||||
File baseFile = new File(_manager.getDataDir(), baseData);
|
||||
@ -331,7 +381,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
announceURL = announceURLOther;
|
||||
|
||||
if (announceURL == null || announceURL.length() <= 0)
|
||||
_manager.addMessage("Error creating torrent - you must select a tracker");
|
||||
_manager.addMessage(_("Error creating torrent - you must select a tracker"));
|
||||
else if (baseFile.exists()) {
|
||||
try {
|
||||
Storage s = new Storage(_manager.util(), baseFile, announceURL, null);
|
||||
@ -346,21 +396,21 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
FileOutputStream out = new FileOutputStream(torrentFile);
|
||||
out.write(info.getTorrentData());
|
||||
out.close();
|
||||
_manager.addMessage("Torrent created for " + baseFile.getName() + ": " + torrentFile.getAbsolutePath());
|
||||
_manager.addMessage(_("Torrent created for \"{0}\"", baseFile.getName()) + ": " + torrentFile.getAbsolutePath());
|
||||
// now fire it up, but don't automatically seed it
|
||||
_manager.addTorrent(torrentFile.getCanonicalPath(), true);
|
||||
_manager.addMessage("Many I2P trackers require you to register new torrents before seeding - please do so before starting " + baseFile.getName());
|
||||
_manager.addMessage(_("Many I2P trackers require you to register new torrents before seeding - please do so before starting \"{0}\"", baseFile.getName()));
|
||||
} catch (IOException ioe) {
|
||||
_manager.addMessage("Error creating a torrent for " + baseFile.getAbsolutePath() + ": " + ioe.getMessage());
|
||||
_manager.addMessage(_("Error creating a torrent for \"{0}\"", baseFile.getAbsolutePath()) + ": " + ioe.getMessage());
|
||||
}
|
||||
} else {
|
||||
_manager.addMessage("Cannot create a torrent for the nonexistent data: " + baseFile.getAbsolutePath());
|
||||
_manager.addMessage(_("Cannot create a torrent for the nonexistent data: {0}", baseFile.getAbsolutePath()));
|
||||
}
|
||||
} else {
|
||||
_manager.addMessage("Error creating torrent - you must enter a file or directory");
|
||||
_manager.addMessage(_("Error creating torrent - you must enter a file or directory"));
|
||||
}
|
||||
} else if ("StopAll".equals(action)) {
|
||||
_manager.addMessage("Stopping all torrents and closing the I2P tunnel.");
|
||||
_manager.addMessage(_("Stopping all torrents and closing the I2P tunnel."));
|
||||
List snarks = getSortedSnarks(req);
|
||||
for (int i = 0; i < snarks.size(); i++) {
|
||||
Snark snark = (Snark)snarks.get(i);
|
||||
@ -369,10 +419,10 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
}
|
||||
if (_manager.util().connected()) {
|
||||
_manager.util().disconnect();
|
||||
_manager.addMessage("I2P tunnel closed.");
|
||||
_manager.addMessage(_("I2P tunnel closed."));
|
||||
}
|
||||
} else if ("StartAll".equals(action)) {
|
||||
_manager.addMessage("Opening the I2P tunnel and starting all torrents.");
|
||||
_manager.addMessage(_("Opening the I2P tunnel and starting all torrents."));
|
||||
List snarks = getSortedSnarks(req);
|
||||
for (int i = 0; i < snarks.size(); i++) {
|
||||
Snark snark = (Snark)snarks.get(i);
|
||||
@ -449,45 +499,45 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
knownPeers = snark.coordinator.trackerSeenPeers;
|
||||
}
|
||||
|
||||
String statusString = "Unknown";
|
||||
String statusString = _("Unknown");
|
||||
if (err != null) {
|
||||
if (isRunning && curPeers > 0 && !showPeers)
|
||||
statusString = "<a title=\"" + err + "\">TrackerErr</a> (" +
|
||||
statusString = "<a title=\"" + err + "\">" + _("TrackerErr") + "</a> (" +
|
||||
curPeers + "/" + knownPeers +
|
||||
" <a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">peers</a>)";
|
||||
" <a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">" + _("peers") + "</a>)";
|
||||
else if (isRunning)
|
||||
statusString = "<a title=\"" + err + "\">TrackerErr (" + curPeers + "/" + knownPeers + " peers)";
|
||||
statusString = "<a title=\"" + err + "\">" + _("TrackerErr") + " (" + curPeers + '/' + knownPeers + ' ' + _("peers") + ')';
|
||||
else {
|
||||
if (err.length() > MAX_DISPLAYED_ERROR_LENGTH)
|
||||
err = err.substring(0, MAX_DISPLAYED_ERROR_LENGTH) + "…";
|
||||
statusString = "TrackerErr<br>(" + err + ")";
|
||||
statusString = _("TrackerErr") + "<br>(" + err + ")";
|
||||
}
|
||||
} else if (remaining <= 0) {
|
||||
if (isRunning && curPeers > 0 && !showPeers)
|
||||
statusString = "Seeding (" +
|
||||
curPeers + "/" + knownPeers +
|
||||
" <a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">peers</a>)";
|
||||
statusString = _("Seeding") + " (" +
|
||||
curPeers + '/' + knownPeers +
|
||||
" <a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">" + _("peers") + "</a>)";
|
||||
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 +
|
||||
" <a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">peers</a>)";
|
||||
" <a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">" + _("peers") + "</a>)";
|
||||
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 +
|
||||
" <a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">peers</a>)";
|
||||
statusString = _("Stalled") + " (" +
|
||||
curPeers + '/' + knownPeers +
|
||||
" <a href=\"" + uri + "?p=" + Base64.encode(snark.meta.getInfoHash()) + "\">" + _("peers") + "</a>)";
|
||||
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");
|
||||
@ -496,9 +546,15 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
out.write(statusString + "</td>\n\t");
|
||||
out.write("<td align=\"left\" class=\"snarkTorrentName " + rowClass + "\">");
|
||||
|
||||
if (remaining == 0)
|
||||
if (remaining == 0) {
|
||||
out.write("<a href=\"" + _manager.linkPrefix() + snark.meta.getName()
|
||||
+ "\" title=\"View file\">");
|
||||
+ "\" title=\"");
|
||||
if (snark.meta.getFiles() != null)
|
||||
out.write(_("View files"));
|
||||
else
|
||||
out.write(_("Open file"));
|
||||
out.write("\">");
|
||||
}
|
||||
out.write(filename);
|
||||
if (remaining == 0)
|
||||
out.write("</a>");
|
||||
@ -520,7 +576,9 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
baseURL = baseURL.substring(e + 1);
|
||||
out.write(" [<a href=\"" + baseURL + "details.php?dllist=1&filelist=1&info_hash=");
|
||||
out.write(TrackerClient.urlencode(snark.meta.getInfoHash()));
|
||||
out.write("\" title=\"" + name + " Tracker\">Details</a>]");
|
||||
out.write("\" title=\"" + name + ' ' + _("Tracker") + "\">");
|
||||
out.write(_("Details"));
|
||||
out.write("</a>]");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -552,17 +610,35 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
parameters = parameters + "&p=1";
|
||||
if (isRunning) {
|
||||
out.write("<a href=\"" + uri + "?action=Stop" + parameters
|
||||
+ "\" title=\"Stop the torrent\">Stop</a>");
|
||||
+ "\" title=\"");
|
||||
out.write(_("Stop the torrent"));
|
||||
out.write("\">");
|
||||
out.write(_("Stop"));
|
||||
out.write("</a>");
|
||||
} else {
|
||||
if (isValid)
|
||||
if (isValid) {
|
||||
out.write("<a href=\"" + uri + "?action=Start" + parameters
|
||||
+ "\" title=\"Start the torrent\">Start</a> ");
|
||||
+ "\" title=\"");
|
||||
out.write(_("Start the torrent"));
|
||||
out.write("\">");
|
||||
out.write(_("Start"));
|
||||
out.write("</a>\n");
|
||||
}
|
||||
out.write("<a href=\"" + uri + "?action=Remove" + parameters
|
||||
+ "\" title=\"Remove the torrent from the active list, deleting the .torrent file\">Remove</a><br>");
|
||||
+ "\" title=\"");
|
||||
out.write(_("Remove the torrent from the active list, deleting the .torrent file"));
|
||||
out.write("\">");
|
||||
out.write(_("Remove"));
|
||||
out.write("</a><br>");
|
||||
out.write("<a href=\"" + uri + "?action=Delete" + parameters
|
||||
+ "\" title=\"Delete the .torrent file and the associated data file(s)\">Delete</a> ");
|
||||
+ "\" title=\"");
|
||||
out.write(_("Delete the .torrent file and the associated data file(s)"));
|
||||
out.write("\">");
|
||||
out.write(_("Delete"));
|
||||
out.write("</a>");
|
||||
}
|
||||
out.write("</td>\n</tr>\n");
|
||||
|
||||
if(showPeers && isRunning && curPeers > 0) {
|
||||
List peers = snark.coordinator.peerList();
|
||||
Iterator it = peers.iterator();
|
||||
@ -573,11 +649,11 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
out.write("<tr class=\"" + rowClass + "\">");
|
||||
out.write("<td align=\"center\" class=\"snarkTorrentStatus " + rowClass + "\">");
|
||||
out.write("</td>\n\t");
|
||||
out.write("<td align=\"left\" class=\"snarkTorrentStatus " + rowClass + "\">");
|
||||
out.write("<td align=\"right\" class=\"snarkTorrentStatus " + rowClass + "\">");
|
||||
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))
|
||||
@ -591,7 +667,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
else if ("VUZP".equals(ch))
|
||||
client = "Robert";
|
||||
else
|
||||
client = "Unknown (" + ch + ')';
|
||||
client = _("Unknown") + " (" + ch + ')';
|
||||
out.write(client + " " + peer.toString().substring(5, 9));
|
||||
if (showDebug)
|
||||
out.write(" inactive " + (peer.getInactiveTime() / 1000) + "s");
|
||||
@ -601,7 +677,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
out.write("<td align=\"right\" class=\"snarkTorrentStatus " + rowClass + "\">");
|
||||
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)
|
||||
@ -619,9 +695,10 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
} else {
|
||||
out.write("<font color=#a00000><a title=\"");
|
||||
if (!peer.isInteresting())
|
||||
out.write("Uninteresting\">");
|
||||
out.write(_("Uninteresting (The peer has no pieces we need)"));
|
||||
else
|
||||
out.write("Choked\">");
|
||||
out.write(_("Choked (The peer is not allowing us to request pieces)"));
|
||||
out.write("\">");
|
||||
out.write(formatSize(peer.getDownloadRate()) + "ps</a></font>");
|
||||
}
|
||||
}
|
||||
@ -634,9 +711,10 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
} else {
|
||||
out.write("<font color=#a00000><a title=\"");
|
||||
if (!peer.isInterested())
|
||||
out.write("Uninterested\">");
|
||||
out.write(_("Uninterested (We have no pieces the peer needs)"));
|
||||
else
|
||||
out.write("Choking\">");
|
||||
out.write(_("Choking (We are not allowing the peer to request pieces)"));
|
||||
out.write("\">");
|
||||
out.write(formatSize(peer.getUploadRate()) + "ps</a></font>");
|
||||
}
|
||||
}
|
||||
@ -659,14 +737,23 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
out.write("<span class=\"snarkNewTorrent\">\n");
|
||||
// *not* enctype="multipart/form-data", so that the input type=file sends the filename, not the file
|
||||
out.write("<form action=\"" + uri + "\" method=\"POST\">\n");
|
||||
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" />\n");
|
||||
out.write("<div class=\"addtorrentsection\"><span class=\"snarkConfigTitle\">Add Torrent:</span><br>\n");
|
||||
out.write("From URL : <input type=\"text\" name=\"newURL\" size=\"80\" value=\"" + newURL + "\" /> \n");
|
||||
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n");
|
||||
out.write("<input type=\"hidden\" name=\"action\" value=\"Add\" >\n");
|
||||
out.write("<div class=\"addtorrentsection\"><span class=\"snarkConfigTitle\">");
|
||||
out.write(_("Add Torrent"));
|
||||
out.write("</span><br>\n<table border=\"0\"><tr><td>");
|
||||
out.write(_("From URL"));
|
||||
out.write(":<td><input type=\"text\" name=\"newURL\" size=\"80\" value=\"" + newURL + "\" > \n");
|
||||
// not supporting from file at the moment, since the file name passed isn't always absolute (so it may not resolve)
|
||||
//out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>\n");
|
||||
out.write("<input type=\"submit\" value=\"Add torrent\" name=\"action\" /><br>\n");
|
||||
out.write("<span class=\"snarkAddInfo\">Alternately, you can copy .torrent files to " + _manager.getDataDir().getAbsolutePath() + "<br>\n");
|
||||
out.write("Removing that .torrent file will cause the torrent to stop.<br></span>\n");
|
||||
out.write("<tr><td> <td><input type=\"submit\" value=\"");
|
||||
out.write(_("Add torrent"));
|
||||
out.write("\" name=\"foo\" ><br>\n");
|
||||
out.write("<tr><td> <td><span class=\"snarkAddInfo\">");
|
||||
out.write(_("Alternately, you can copy .torrent files to the directory {0}.", _manager.getDataDir().getAbsolutePath()));
|
||||
out.write("\n");
|
||||
out.write(_("Removing a .torrent file will cause the torrent to stop."));
|
||||
out.write("<br></span></table>\n");
|
||||
out.write("</form>\n</span></div>");
|
||||
}
|
||||
|
||||
@ -679,13 +766,22 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
out.write("<div class=\"newtorrentsection\"><span class=\"snarkNewTorrent\">\n");
|
||||
// *not* enctype="multipart/form-data", so that the input type=file sends the filename, not the file
|
||||
out.write("<form action=\"" + uri + "\" method=\"POST\">\n");
|
||||
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" />\n");
|
||||
out.write("<span class=\"snarkConfigTitle\">Create Torrent:</span><br>\n");
|
||||
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n");
|
||||
out.write("<input type=\"hidden\" name=\"action\" value=\"Create\" >\n");
|
||||
out.write("<span class=\"snarkConfigTitle\">");
|
||||
out.write(_("Create Torrent"));
|
||||
out.write("</span><br>\n<table border=\"0\"><tr><td>");
|
||||
//out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>\n");
|
||||
out.write("Data to seed: " + _manager.getDataDir().getAbsolutePath() + File.separatorChar
|
||||
out.write(_("Data to seed"));
|
||||
out.write(":<td>" + _manager.getDataDir().getAbsolutePath() + File.separatorChar
|
||||
+ "<input type=\"text\" name=\"baseFile\" size=\"20\" value=\"" + baseFile
|
||||
+ "\" title=\"File to seed (must be within the specified path)\" /><br>\n");
|
||||
out.write("Tracker: <select name=\"announceURL\"><option value=\"\">Select a tracker</option>\n");
|
||||
+ "\" title=\"");
|
||||
out.write(_("File or directory to seed (must be within the specified path)"));
|
||||
out.write("\" ><tr><td>\n");
|
||||
out.write(_("Tracker"));
|
||||
out.write(":<td><select name=\"announceURL\"><option value=\"\">");
|
||||
out.write(_("Select a tracker"));
|
||||
out.write("</option>\n");
|
||||
Map trackers = _manager.getTrackers();
|
||||
for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) {
|
||||
Map.Entry entry = (Map.Entry)iter.next();
|
||||
@ -697,9 +793,14 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
out.write("\t<option value=\"" + announceURL + "\">" + name + "</option>\n");
|
||||
}
|
||||
out.write("</select>\n");
|
||||
out.write("or <input type=\"text\" name=\"announceURLOther\" size=\"50\" value=\"http://\" " +
|
||||
"title=\"Custom tracker URL\" /> ");
|
||||
out.write("<input type=\"submit\" value=\"Create torrent\" name=\"action\" />\n");
|
||||
out.write(_("or"));
|
||||
out.write("<tr><td> <td><input type=\"text\" name=\"announceURLOther\" size=\"50\" value=\"http://\" " +
|
||||
"title=\"");
|
||||
out.write(_("Specify custom tracker announce URL"));
|
||||
out.write("\" > ");
|
||||
out.write("<tr><td> <td><input type=\"submit\" value=\"");
|
||||
out.write(_("Create torrent"));
|
||||
out.write("\" name=\"foo\" ></table>\n");
|
||||
out.write("</form>\n</span></div>");
|
||||
}
|
||||
|
||||
@ -713,13 +814,28 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
|
||||
out.write("<form action=\"" + uri + "\" method=\"POST\">\n");
|
||||
out.write("<div class=\"configsection\"><span class=\"snarkConfig\">\n");
|
||||
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" />\n");
|
||||
out.write("<span class=\"snarkConfigTitle\">Configuration:</span><br>\n");
|
||||
out.write("Data directory: <input type=\"text\" size=\"40\" name=\"dataDir\" value=\"" + dataDir + "\" ");
|
||||
out.write("title=\"Directory to store torrents and data\" disabled=\"true\" /> <i>(Edit i2psnark.config and restart to change)</i><br>\n");
|
||||
out.write("Auto start: <input type=\"checkbox\" class=\"optbox\" name=\"autoStart\" value=\"true\" "
|
||||
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n");
|
||||
out.write("<input type=\"hidden\" name=\"action\" value=\"Save\" >\n");
|
||||
out.write("<span class=\"snarkConfigTitle\">");
|
||||
out.write(_("Configuration"));
|
||||
out.write("</span><br>\n");
|
||||
out.write("<table border=\"0\"><tr><td>");
|
||||
out.write(_("Data directory"));
|
||||
out.write(": <td><input type=\"text\" size=\"50\" name=\"dataDir\" value=\"" + dataDir + "\" ");
|
||||
out.write("title=\"");
|
||||
out.write(_("Directory to store torrents and data"));
|
||||
out.write("\" disabled=\"true\" ><br><i>(");
|
||||
out.write(_("Edit i2psnark.config and restart to change"));
|
||||
out.write(")</i><br>\n");
|
||||
|
||||
out.write("<tr><td>");
|
||||
out.write(_("Auto start"));
|
||||
out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"autoStart\" value=\"true\" "
|
||||
+ (autoStart ? "checked " : "")
|
||||
+ "title=\"If true, automatically start torrents that are added\" />");
|
||||
+ "title=\"");
|
||||
out.write(_("If checked, automatically start torrents that are added"));
|
||||
out.write("\" >");
|
||||
|
||||
//Auto add: <input type="checkbox" name="autoAdd" value="true" title="If true, automatically add torrents that are found in the data directory" />
|
||||
//Auto stop: <input type="checkbox" name="autoStop" value="true" title="If true, automatically stop torrents that are removed from the data directory" />
|
||||
//out.write("<br>\n");
|
||||
@ -739,26 +855,51 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
out.write("<option value=\"150\">150%</option>\n\t");
|
||||
out.write("</select><br>\n");
|
||||
*/
|
||||
out.write("Total uploader limit: <input type=\"text\" name=\"upLimit\" value=\""
|
||||
+ _manager.util().getMaxUploaders() + "\" size=\"3\" maxlength=\"3\" /> peers<br>\n");
|
||||
out.write("Up bandwidth limit: <input type=\"text\" name=\"upBW\" value=\""
|
||||
+ _manager.util().getMaxUpBW() + "\" size=\"3\" maxlength=\"3\" /> KBps <i>(Half <a href=\"/config.jsp\" target=\"blank\">available bandwidth</a> recommended.)</i><br>\n");
|
||||
out.write("<tr><td>");
|
||||
out.write(_("Total uploader limit"));
|
||||
out.write(": <td><input type=\"text\" name=\"upLimit\" value=\""
|
||||
+ _manager.util().getMaxUploaders() + "\" size=\"3\" maxlength=\"3\" > ");
|
||||
out.write(_("peers"));
|
||||
out.write("<br>\n");
|
||||
|
||||
out.write("<tr><td>");
|
||||
out.write(_("Up bandwidth limit"));
|
||||
out.write(": <td><input type=\"text\" name=\"upBW\" value=\""
|
||||
+ _manager.util().getMaxUpBW() + "\" size=\"3\" maxlength=\"3\" > KBps <i>(");
|
||||
out.write(_("Half available bandwidth recommended."));
|
||||
out.write(" <a href=\"/config.jsp\" target=\"blank\">");
|
||||
out.write(_("View or change router bandwidth"));
|
||||
out.write("</a>)</i><br>\n");
|
||||
|
||||
out.write("Use open trackers also: <input type=\"checkbox\" class=\"optbox\" name=\"useOpenTrackers\" value=\"true\" "
|
||||
out.write("<tr><td>");
|
||||
out.write(_("Use open trackers also"));
|
||||
out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"useOpenTrackers\" value=\"true\" "
|
||||
+ (useOpenTrackers ? "checked " : "")
|
||||
+ "title=\"If true, uses open trackers in addition\" /> ");
|
||||
out.write("Announce URLs: <input type=\"text\" name=\"openTrackers\" value=\""
|
||||
+ openTrackers + "\" size=\"50\" /><br>\n");
|
||||
+ "title=\"");
|
||||
out.write(_("If checked, announce torrents to open trackers as well as the tracker listed in the torrent file"));
|
||||
out.write("\" > ");
|
||||
|
||||
out.write("<tr><td>");
|
||||
out.write(_("Open tracker announce URLs"));
|
||||
out.write(": <td><input type=\"text\" name=\"openTrackers\" value=\""
|
||||
+ openTrackers + "\" size=\"50\" ><br>\n");
|
||||
|
||||
//out.write("\n");
|
||||
//out.write("EepProxy host: <input type=\"text\" name=\"eepHost\" value=\""
|
||||
// + _manager.util().getEepProxyHost() + "\" size=\"15\" /> ");
|
||||
//out.write("port: <input type=\"text\" name=\"eepPort\" value=\""
|
||||
// + _manager.util().getEepProxyPort() + "\" size=\"5\" maxlength=\"5\" /><br>\n");
|
||||
out.write("I2CP host: <input type=\"text\" name=\"i2cpHost\" value=\""
|
||||
+ _manager.util().getI2CPHost() + "\" size=\"15\" /> ");
|
||||
out.write("port: <input type=\"text\" name=\"i2cpPort\" value=\"" +
|
||||
+ _manager.util().getI2CPPort() + "\" size=\"5\" maxlength=\"5\" /> <br>\n");
|
||||
|
||||
out.write("<tr><td>");
|
||||
out.write(_("I2CP host"));
|
||||
out.write(": <td><input type=\"text\" name=\"i2cpHost\" value=\""
|
||||
+ _manager.util().getI2CPHost() + "\" size=\"15\" > ");
|
||||
|
||||
out.write("<tr><td>");
|
||||
out.write(_("I2CP port"));
|
||||
out.write(": <td><input type=\"text\" name=\"i2cpPort\" value=\"" +
|
||||
+ _manager.util().getI2CPPort() + "\" size=\"5\" maxlength=\"5\" > <br>\n");
|
||||
|
||||
StringBuilder opts = new StringBuilder(64);
|
||||
Map options = new TreeMap(_manager.util().getI2CPOptions());
|
||||
for (Iterator iter = options.entrySet().iterator(); iter.hasNext(); ) {
|
||||
@ -767,13 +908,28 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
String val = (String)entry.getValue();
|
||||
opts.append(key).append('=').append(val).append(' ');
|
||||
}
|
||||
out.write("I2CP opts: <input type=\"text\" name=\"i2cpOpts\" size=\"80\" value=\""
|
||||
+ opts.toString() + "\" /><br>\n");
|
||||
out.write("<input type=\"submit\" value=\"Save configuration\" name=\"action\" />\n");
|
||||
out.write("</span>\n");
|
||||
out.write("<tr><td>");
|
||||
out.write(_("I2CP options"));
|
||||
out.write(": <td><textarea name=\"i2cpOpts\" cols=\"60\" rows=\"1\" wrap=\"off\" >"
|
||||
+ opts.toString() + "</textarea><br>\n");
|
||||
|
||||
out.write("<tr><td> <td><input type=\"submit\" value=\"");
|
||||
out.write(_("Save configuration"));
|
||||
out.write("\" name=\"foo\" >\n");
|
||||
out.write("</table></span>\n");
|
||||
out.write("</form></div>");
|
||||
}
|
||||
|
||||
/** translate */
|
||||
private String _(String s) {
|
||||
return _manager.util().getString(s);
|
||||
}
|
||||
|
||||
/** translate */
|
||||
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)
|
||||
@ -786,28 +942,12 @@ public class I2PSnarkServlet extends HttpServlet {
|
||||
return ((bytes + 512*1024*1024)/(1024*1024*1024)) + "GB";
|
||||
}
|
||||
|
||||
private static final String HEADER_BEGIN = "<html>\n" +
|
||||
"<head>\n" +
|
||||
"<title>I2PSnark - Anonymous BitTorrent Client</title>\n";
|
||||
|
||||
private static final String HEADER = "<link href=\"../themes/console/snark.css\" rel=\"stylesheet\" type=\"text/css\" />";
|
||||
private static final String HEADER = "<link href=\"../themes/console/snark.css\" rel=\"stylesheet\" type=\"text/css\" >";
|
||||
|
||||
|
||||
private static final String TABLE_HEADER = "<table border=\"0\" class=\"snarkTorrents\" width=\"100%\" cellpadding=\"0 10px\">\n" +
|
||||
"<thead>\n" +
|
||||
"<tr><th align=\"center\">Status \n";
|
||||
|
||||
private static final String TABLE_HEADER2 = "</th>\n" +
|
||||
" <th align=\"left\">Torrent</th>\n" +
|
||||
" <th align=\"center\">ETA</th>\n" +
|
||||
" <th align=\"right\">Downloaded</th>\n" +
|
||||
" <th align=\"right\">Uploaded</th>\n" +
|
||||
" <th align=\"right\">Down Rate</th>\n" +
|
||||
" <th align=\"right\">Up Rate</th>\n";
|
||||
|
||||
private static final String TABLE_EMPTY = "<tr class=\"snarkTorrentEven\">" +
|
||||
"<td class=\"snarkTorrentEven\" align=\"center\"" +
|
||||
" colspan=\"8\"><i>No torrents loaded.</i></td></tr>\n";
|
||||
"<tr><th align=\"center\">";
|
||||
|
||||
private static final String TABLE_FOOTER = "</table></div>\n";
|
||||
|
||||
@ -827,12 +967,13 @@ private static class FetchAndAdd implements Runnable {
|
||||
File file = _manager.util().get(_url, false, 3);
|
||||
try {
|
||||
if ( (file != null) && (file.exists()) && (file.length() > 0) ) {
|
||||
_manager.addMessage("Torrent fetched from " + _url);
|
||||
_manager.addMessage(_("Torrent fetched from {0}", _url));
|
||||
FileInputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(file);
|
||||
MetaInfo info = new MetaInfo(in);
|
||||
String name = info.getName();
|
||||
name = DataHelper.stripHTML(name); // XSS
|
||||
name = name.replace('/', '_');
|
||||
name = name.replace('\\', '_');
|
||||
name = name.replace('&', '+');
|
||||
@ -846,25 +987,30 @@ private static class FetchAndAdd implements Runnable {
|
||||
|
||||
if (torrentFile.exists()) {
|
||||
if (_manager.getTorrent(canonical) != null)
|
||||
_manager.addMessage("Torrent already running: " + name);
|
||||
_manager.addMessage(_("Torrent already running: {0}", name));
|
||||
else
|
||||
_manager.addMessage("Torrent already in the queue: " + name);
|
||||
_manager.addMessage(_("Torrent already in the queue: {0}", name));
|
||||
} else {
|
||||
FileUtil.copy(file.getAbsolutePath(), canonical, true);
|
||||
_manager.addTorrent(canonical);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
_manager.addMessage("Torrent at " + _url + " was not valid: " + ioe.getMessage());
|
||||
_manager.addMessage(_("Torrent at {0} was not valid", _url) + ": " + ioe.getMessage());
|
||||
} finally {
|
||||
try { in.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
} else {
|
||||
_manager.addMessage("Torrent was not retrieved from " + _url);
|
||||
_manager.addMessage(_("Torrent was not retrieved from {0}", _url));
|
||||
}
|
||||
} finally {
|
||||
if (file != null) file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private String _(String s, String o) {
|
||||
return _manager.util().getString(s, o);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
655
apps/i2psnark/locale/messages_de.po
Normal file
655
apps/i2psnark/locale/messages_de.po
Normal file
@ -0,0 +1,655 @@
|
||||
# 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 <foo@bar>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P i2psnark\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-12-10 17:41+0000\n"
|
||||
"PO-Revision-Date: 2009-10-19 12:50+0000\n"
|
||||
"Last-Translator: foo <foo@bar>\n"
|
||||
"Language-Team: foo <foo@bar>\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/SnarkManager.java:84
|
||||
#, java-format
|
||||
msgid "Adding torrents in {0} minutes"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:241
|
||||
#, java-format
|
||||
msgid "Total uploaders limit changed to {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:243
|
||||
#, java-format
|
||||
msgid "Minimum total uploaders limit is {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:255
|
||||
#, java-format
|
||||
msgid "Up BW limit changed to {0}KBps"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:257
|
||||
#, java-format
|
||||
msgid "Minimum up bandwidth limit is {0}KBps"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:301
|
||||
msgid "Cannot change the I2CP settings while torrents are active"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:307
|
||||
msgid "Disconnecting old I2CP destination"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:311
|
||||
#, java-format
|
||||
msgid "I2CP settings changed to {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:315
|
||||
msgid ""
|
||||
"Unable to connect with the new settings, reverting to the old I2CP settings"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:319
|
||||
msgid "Unable to reconnect with the old settings!"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:321
|
||||
msgid "Reconnected on the new I2CP destination"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:332
|
||||
#, java-format
|
||||
msgid "I2CP listener restarted for \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:343
|
||||
msgid "Enabled autostart"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:345
|
||||
msgid "Disabled autostart"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:351
|
||||
msgid "Enabled open trackers - torrent restart required to take effect."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:353
|
||||
msgid "Disabled open trackers - torrent restart required to take effect."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:360
|
||||
msgid "Open Tracker list changed - torrent restart required to take effect."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:367
|
||||
msgid "Configuration unchanged."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:377
|
||||
#, java-format
|
||||
msgid "Unable to save the config to {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:395
|
||||
msgid "Connecting to I2P"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:398
|
||||
msgid "Error connecting to I2P - check your I2CP settings!"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:407
|
||||
#, java-format
|
||||
msgid "Error: Could not add the torrent {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:446
|
||||
#, java-format
|
||||
msgid "Torrent in \"{0}\" is invalid"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:461
|
||||
#, java-format
|
||||
msgid "Torrent added and started: \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:463
|
||||
#, java-format
|
||||
msgid "Torrent added: \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:559
|
||||
#, java-format
|
||||
msgid "Non-i2p tracker in \"{0}\", deleting it from our list of trackers!"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:562
|
||||
#, java-format
|
||||
msgid "Too many files in \"{0}\" ({1}), deleting it!"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:564
|
||||
#, java-format
|
||||
msgid "Torrent file \"{0}\" cannot end in '.torrent', deleting it!"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:566
|
||||
#, java-format
|
||||
msgid "No pieces in \"{0}\", deleting it!"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:568
|
||||
#, java-format
|
||||
msgid "Too many pieces in \"{0}\", limit is {1}, deleting it!"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:570
|
||||
#, java-format
|
||||
msgid "Pieces are too large in \"{0}\" ({1}B), deleting it."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:571
|
||||
#, java-format
|
||||
msgid "Limit is {0}B"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:579
|
||||
#, java-format
|
||||
msgid "Torrents larger than {0}B are not supported yet, deleting \"{1}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:595
|
||||
#, java-format
|
||||
msgid "Error: Could not remove the torrent {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:616
|
||||
#, java-format
|
||||
msgid "Torrent stopped: \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:631
|
||||
#, java-format
|
||||
msgid "Torrent removed: \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:664
|
||||
#, java-format
|
||||
msgid "Download finished: \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:664
|
||||
#, java-format
|
||||
msgid "size: {0}B"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:692
|
||||
msgid "Unable to connect to I2P!"
|
||||
msgstr ""
|
||||
|
||||
#: ../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:655
|
||||
msgid "I2PSnark"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:99
|
||||
msgid "Forum"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:125
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:132
|
||||
msgid "Hide Peers"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:134
|
||||
msgid "Show Peers"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:138
|
||||
msgid "Torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:140
|
||||
msgid "ETA"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:142
|
||||
msgid "Downloaded"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:144
|
||||
msgid "Uploaded"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:146
|
||||
msgid "Down Rate"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:148
|
||||
msgid "Up Rate"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:155
|
||||
msgid "Stop all torrents and the I2P tunnel"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:157
|
||||
msgid "Stop All"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:162
|
||||
msgid "Start all torrents and the I2P tunnel"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:164
|
||||
msgid "Start All"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:181
|
||||
msgid "No torrents loaded."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:186
|
||||
msgid "Totals"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:188
|
||||
#, java-format
|
||||
msgid "{0} torrents"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:191
|
||||
#, java-format
|
||||
msgid "{0} connected peers"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:218
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:748
|
||||
msgid "Add torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:226
|
||||
#, java-format
|
||||
msgid "Torrent file {0} does not exist"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:236
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:985
|
||||
#, java-format
|
||||
msgid "Torrent already running: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:238
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:987
|
||||
#, java-format
|
||||
msgid "Torrent already in the queue: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:242
|
||||
#, java-format
|
||||
msgid "Copying torrent to {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:245
|
||||
#, java-format
|
||||
msgid "Unable to copy the torrent to {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:245
|
||||
#, java-format
|
||||
msgid "from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:253
|
||||
#, java-format
|
||||
msgid "Fetching {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:257
|
||||
msgid "Invalid URL - must start with http://"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:262
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:615
|
||||
msgid "Stop"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:277
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:623
|
||||
msgid "Start"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:287
|
||||
#, java-format
|
||||
msgid "Starting up torrent {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:307
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:325
|
||||
#, java-format
|
||||
msgid "Torrent file deleted: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:331
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:341
|
||||
#, java-format
|
||||
msgid "Data file deleted: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:333
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:343
|
||||
#, java-format
|
||||
msgid "Data file could not be deleted: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:352
|
||||
#, java-format
|
||||
msgid "Data dir deleted: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:359
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:913
|
||||
msgid "Save configuration"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:373
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:799
|
||||
msgid "Create torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:383
|
||||
msgid "Error creating torrent - you must select a tracker"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:398
|
||||
#, java-format
|
||||
msgid "Torrent created for \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:401
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Many I2P trackers require you to register new torrents before seeding - "
|
||||
"please do so before starting \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:403
|
||||
#, java-format
|
||||
msgid "Error creating a torrent for \"{0}\""
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:406
|
||||
#, java-format
|
||||
msgid "Cannot create a torrent for the nonexistent data: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:409
|
||||
msgid "Error creating torrent - you must enter a file or directory"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:412
|
||||
msgid "Stopping all torrents and closing the I2P tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:421
|
||||
msgid "I2P tunnel closed."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:424
|
||||
msgid "Opening the I2P tunnel and starting all torrents."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:501
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:669
|
||||
msgid "Unknown"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:504
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:508
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:512
|
||||
msgid "TrackerErr"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:506
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:508
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:518
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:527
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:529
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:533
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:535
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:858
|
||||
msgid "peers"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:516
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:520
|
||||
msgid "Seeding"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:522
|
||||
msgid "Complete"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:525
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:529
|
||||
msgid "OK"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:531
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:535
|
||||
msgid "Stalled"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:537
|
||||
msgid "No Peers"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:539
|
||||
msgid "Stopped"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:552
|
||||
msgid "View files"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:554
|
||||
msgid "Open file"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:578
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:778
|
||||
msgid "Tracker"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:579
|
||||
msgid "Details"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:613
|
||||
msgid "Stop the torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:621
|
||||
msgid "Start the torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:628
|
||||
msgid "Remove the torrent from the active list, deleting the .torrent file"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:630
|
||||
msgid "Remove"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:634
|
||||
msgid "Delete the .torrent file and the associated data file(s)"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:636
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:679
|
||||
msgid "Seed"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:697
|
||||
msgid "Uninteresting"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:699
|
||||
msgid "Choked"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:713
|
||||
msgid "Uninterested"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:715
|
||||
msgid "Choking"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:741
|
||||
msgid "Add Torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:743
|
||||
msgid "From URL"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:751
|
||||
#, java-format
|
||||
msgid "Alternately, you can copy .torrent files to {0} ."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:753
|
||||
msgid "Removing a .torrent file will cause the torrent to stop."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:769
|
||||
msgid "Create Torrent"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:772
|
||||
msgid "Data to seed"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:776
|
||||
msgid "File to seed (must be within the specified path)"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:780
|
||||
msgid "Select a tracker"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:793
|
||||
msgid "or"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:796
|
||||
msgid "Custom tracker URL"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:816
|
||||
msgid "Configuration"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:819
|
||||
msgid "Data directory"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:822
|
||||
msgid "Directory to store torrents and data"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:824
|
||||
msgid "Edit i2psnark.config and restart to change"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:828
|
||||
msgid "Auto start"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:832
|
||||
msgid "If checked, automatically start torrents that are added"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:855
|
||||
msgid "Total uploader limit"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:862
|
||||
msgid "Up bandwidth limit"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:865
|
||||
msgid "Half available bandwidth< recommended."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:867
|
||||
msgid "Configure"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:871
|
||||
msgid "Use open trackers also"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:875
|
||||
msgid ""
|
||||
"If checked, announce torrents to open trackers as well as the tracker listed "
|
||||
"in the torrent file"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:879
|
||||
msgid "Open tracker announce URLs"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:890
|
||||
msgid "I2CP host"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:895
|
||||
msgid "I2CP port"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:908
|
||||
msgid "I2CP options"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:966
|
||||
#, java-format
|
||||
msgid "Torrent fetched from {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:993
|
||||
#, java-format
|
||||
msgid "Torrent at {0} was not valid"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:998
|
||||
#, java-format
|
||||
msgid "Torrent was not retrieved from {0}"
|
||||
msgstr ""
|
648
apps/i2psnark/locale/messages_ru.po
Normal file
648
apps/i2psnark/locale/messages_ru.po
Normal file
@ -0,0 +1,648 @@
|
||||
# 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 <foo@bar>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P i2psnark\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-12-14 03:19+0000\n"
|
||||
"PO-Revision-Date: 2009-12-20 07:03+0000\n"
|
||||
"Last-Translator: 4get <forget@mail.i2p>\n"
|
||||
"Language-Team: foo <foo@bar>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Russian\n"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:84
|
||||
#, java-format
|
||||
msgid "Adding torrents in {0} minutes"
|
||||
msgstr "Торренты будут подгружены через {0} минут(ы)"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:241
|
||||
#, java-format
|
||||
msgid "Total uploaders limit changed to {0}"
|
||||
msgstr "Новое значение лимита количества слотов отдачи: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:243
|
||||
#, java-format
|
||||
msgid "Minimum total uploaders limit is {0}"
|
||||
msgstr "Минимально допустимое значение для количества слотов: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:255
|
||||
#, java-format
|
||||
msgid "Up BW limit changed to {0}KBps"
|
||||
msgstr "Новое значение лимита скорости отдачи: {0} KBps"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:257
|
||||
#, java-format
|
||||
msgid "Minimum up bandwidth limit is {0}KBps"
|
||||
msgstr "Минимально допустимое значение для лимита скорости отдачи: {0} KBps"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:301
|
||||
msgid "Cannot change the I2CP settings while torrents are active"
|
||||
msgstr "Невозможно изменить настройки I2CP пока есть активные торренты"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:307
|
||||
msgid "Disconnecting old I2CP destination"
|
||||
msgstr "Рассоединяемся по старому адресу I2CP"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:311
|
||||
#, java-format
|
||||
msgid "I2CP settings changed to {0}"
|
||||
msgstr "Новые параметры I2CP: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:315
|
||||
msgid "Unable to connect with the new settings, reverting to the old I2CP settings"
|
||||
msgstr "Не удалось соединиться с использованием новых настроек I2CP, возвращаемся к старым настройкам"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:319
|
||||
msgid "Unable to reconnect with the old settings!"
|
||||
msgstr "Не удалось пересоединиться с использованием старых настроек I2CP!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:321
|
||||
msgid "Reconnected on the new I2CP destination"
|
||||
msgstr "Пересоединились по новому адресу I2CP"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:332
|
||||
#, java-format
|
||||
msgid "I2CP listener restarted for \"{0}\""
|
||||
msgstr "I2CP-приёмник перезапущен для \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:343
|
||||
msgid "Enabled autostart"
|
||||
msgstr "Автостарт включен"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:345
|
||||
msgid "Disabled autostart"
|
||||
msgstr "Автостарт выключен"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:351
|
||||
msgid "Enabled open trackers - torrent restart required to take effect."
|
||||
msgstr "Включено использование открытых трекеров. Требуется перезапуск торрента, чтобы изменения вступили в силу."
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:353
|
||||
msgid "Disabled open trackers - torrent restart required to take effect."
|
||||
msgstr "Отключено использование открытых трекеров. Требуется перезапуск торрента, чтобы изменения вступили в силу."
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:360
|
||||
msgid "Open Tracker list changed - torrent restart required to take effect."
|
||||
msgstr "Изменен список открытых трекеров. Требуется перезапуск торрента, чтобы изменения вступили в силу."
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:367
|
||||
msgid "Configuration unchanged."
|
||||
msgstr "Настройки не изменились."
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:377
|
||||
#, java-format
|
||||
msgid "Unable to save the config to {0}"
|
||||
msgstr "Не удалось сохранить настройки в {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:395
|
||||
msgid "Connecting to I2P"
|
||||
msgstr "Устанавливается соединение с I2P"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:398
|
||||
msgid "Error connecting to I2P - check your I2CP settings!"
|
||||
msgstr "Ошибка соединения с I2P, проверьте настройки I2CP!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:407
|
||||
#, java-format
|
||||
msgid "Error: Could not add the torrent {0}"
|
||||
msgstr "Ошибка: Не удалось добавить торрент {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:446
|
||||
#, java-format
|
||||
msgid "Torrent in \"{0}\" is invalid"
|
||||
msgstr "Торрент в \"{0}\" некорректен"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:461
|
||||
#, java-format
|
||||
msgid "Torrent added and started: \"{0}\""
|
||||
msgstr "Торрент добавлен и запущен: \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:463
|
||||
#, java-format
|
||||
msgid "Torrent added: \"{0}\""
|
||||
msgstr "Торрент добавлен: \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:559
|
||||
#, java-format
|
||||
msgid "Non-i2p tracker in \"{0}\", deleting it from our list of trackers!"
|
||||
msgstr "Обнаружен не-I2P трекер в торренте \"{0}\", удаляем его из нашего списка трекеров!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:562
|
||||
#, java-format
|
||||
msgid "Too many files in \"{0}\" ({1}), deleting it!"
|
||||
msgstr "Слишком много файлов в торренте \"{0}\" ({1}), удаляем его!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:564
|
||||
#, java-format
|
||||
msgid "Torrent file \"{0}\" cannot end in '.torrent', deleting it!"
|
||||
msgstr "Торрент \"{0}\" содержит единственный файл заканчивающийся на '.torrent', удаляем его!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:566
|
||||
#, java-format
|
||||
msgid "No pieces in \"{0}\", deleting it!"
|
||||
msgstr "В торренте \"{0}\" не оказалось ни одной части, удаляем его!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:568
|
||||
#, java-format
|
||||
msgid "Too many pieces in \"{0}\", limit is {1}, deleting it!"
|
||||
msgstr "Слишком много частей в торренте \"{0}\" (наш предел {1}), удаляем его!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:570
|
||||
#, java-format
|
||||
msgid "Pieces are too large in \"{0}\" ({1}B), deleting it."
|
||||
msgstr "Слишком крупные части в торренте \"{0}\" ({1}B), удаляем его."
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:571
|
||||
#, java-format
|
||||
msgid "Limit is {0}B"
|
||||
msgstr "Наш предел {0}B"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:579
|
||||
#, java-format
|
||||
msgid "Torrents larger than {0}B are not supported yet, deleting \"{1}\""
|
||||
msgstr "Торренты крупнее чем {0}B пока не поддерживается, удаляем \"{1}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:595
|
||||
#, java-format
|
||||
msgid "Error: Could not remove the torrent {0}"
|
||||
msgstr "Ошибка: Невозможно удалить торрент {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:616
|
||||
#, java-format
|
||||
msgid "Torrent stopped: \"{0}\""
|
||||
msgstr "Торрент остановлен: \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:631
|
||||
#, java-format
|
||||
msgid "Torrent removed: \"{0}\""
|
||||
msgstr "Торрент удален: \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:664
|
||||
#, java-format
|
||||
msgid "Download finished: \"{0}\""
|
||||
msgstr "Завершена загрузка: \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:664
|
||||
#, java-format
|
||||
msgid "size: {0}B"
|
||||
msgstr "размер: {0}B"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:692
|
||||
msgid "Unable to connect to I2P!"
|
||||
msgstr "Не удалось установить соединение с I2P!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:86
|
||||
msgid "I2PSnark - Anonymous BitTorrent Client"
|
||||
msgstr "I2PSnark — Анонимный BitTorrent Клиент"
|
||||
|
||||
#: ../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:656
|
||||
msgid "I2PSnark"
|
||||
msgstr "I2PSnark"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:99
|
||||
msgid "Forum"
|
||||
msgstr "Форум"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:125
|
||||
msgid "Status"
|
||||
msgstr "Статус"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:131
|
||||
msgid "Hide Peers"
|
||||
msgstr "спрятать список пиров"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:134
|
||||
msgid "Show Peers"
|
||||
msgstr "показать список пиров"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:139
|
||||
msgid "Torrent"
|
||||
msgstr "Торрент"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:141
|
||||
msgid "ETA"
|
||||
msgstr "Осталось"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:143
|
||||
msgid "Downloaded"
|
||||
msgstr "Получено"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:145
|
||||
msgid "Uploaded"
|
||||
msgstr "Отдано"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:147
|
||||
msgid "Down Rate"
|
||||
msgstr "Скорость загрузки"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:149
|
||||
msgid "Up Rate"
|
||||
msgstr "Скорость отдачи"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:156
|
||||
msgid "Stop all torrents and the I2P tunnel"
|
||||
msgstr "Остановить все торренты и закрыть соединение с I2P"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:158
|
||||
msgid "Stop All"
|
||||
msgstr "Остановить все"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:163
|
||||
msgid "Start all torrents and the I2P tunnel"
|
||||
msgstr "Запустить все торренты и открыть соединение с I2P"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:165
|
||||
msgid "Start All"
|
||||
msgstr "Запустить все"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:182
|
||||
msgid "No torrents loaded."
|
||||
msgstr "Нет загруженных торрентов."
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:187
|
||||
msgid "Totals"
|
||||
msgstr "Всего"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:189
|
||||
#, java-format
|
||||
msgid "{0} torrents"
|
||||
msgstr "{0} торрентов"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:192
|
||||
#, java-format
|
||||
msgid "{0} connected peers"
|
||||
msgstr "{0} подсоединенных пиров"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:227
|
||||
#, java-format
|
||||
msgid "Torrent file {0} does not exist"
|
||||
msgstr "Торрент {0} не существует"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:237
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:986
|
||||
#, java-format
|
||||
msgid "Torrent already running: {0}"
|
||||
msgstr "Торрент уже запущен: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:239
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:988
|
||||
#, java-format
|
||||
msgid "Torrent already in the queue: {0}"
|
||||
msgstr "Торрент уже в очереди: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:243
|
||||
#, java-format
|
||||
msgid "Copying torrent to {0}"
|
||||
msgstr "Копируем торрент в: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:246
|
||||
#, java-format
|
||||
msgid "Unable to copy the torrent to {0}"
|
||||
msgstr "Не удалось скопировать торрент в: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:246
|
||||
#, java-format
|
||||
msgid "from {0}"
|
||||
msgstr "из: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:254
|
||||
#, java-format
|
||||
msgid "Fetching {0}"
|
||||
msgstr "Получение торрента: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:258
|
||||
msgid "Invalid URL - must start with http://"
|
||||
msgstr "Некорректный URL, должен начинаться с http://"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:288
|
||||
#, java-format
|
||||
msgid "Starting up torrent {0}"
|
||||
msgstr "Запускаем торрент: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:308
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:326
|
||||
#, java-format
|
||||
msgid "Torrent file deleted: {0}"
|
||||
msgstr "Удален торрент: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:332
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:342
|
||||
#, java-format
|
||||
msgid "Data file deleted: {0}"
|
||||
msgstr "Файл удален: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:334
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:344
|
||||
#, java-format
|
||||
msgid "Data file could not be deleted: {0}"
|
||||
msgstr "Не удалось удалить файл: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:353
|
||||
#, java-format
|
||||
msgid "Data dir deleted: {0}"
|
||||
msgstr "Директория удалена: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:384
|
||||
msgid "Error creating torrent - you must select a tracker"
|
||||
msgstr "Торрент не создан — вы должны указать трекер"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:399
|
||||
#, java-format
|
||||
msgid "Torrent created for \"{0}\""
|
||||
msgstr "Создан торрент для \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:402
|
||||
#, java-format
|
||||
msgid "Many I2P trackers require you to register new torrents before seeding - please do so before starting \"{0}\""
|
||||
msgstr "Многие I2P трекеры требуют зарегистрировать на них торрент перед началом раздачи — пожалуйста проверьте требуется ли это перед запуском \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:404
|
||||
#, java-format
|
||||
msgid "Error creating a torrent for \"{0}\""
|
||||
msgstr "Ошибка при создании торрента для: \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:407
|
||||
#, java-format
|
||||
msgid "Cannot create a torrent for the nonexistent data: {0}"
|
||||
msgstr "Невозможно создать торрент для несуществующего файла или директории: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:410
|
||||
msgid "Error creating torrent - you must enter a file or directory"
|
||||
msgstr "Торрент не создан — вы должны указать файл или директорию"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:413
|
||||
msgid "Stopping all torrents and closing the I2P tunnel."
|
||||
msgstr "Останавливаем все торренты и закрываем соединение с I2P"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:422
|
||||
msgid "I2P tunnel closed."
|
||||
msgstr "Соединение с I2P закрыто."
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:425
|
||||
msgid "Opening the I2P tunnel and starting all torrents."
|
||||
msgstr "Соединяемся с I2P и запускаем все торренты."
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:502
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:670
|
||||
msgid "Unknown"
|
||||
msgstr "Неизвестный"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:505
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:509
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:513
|
||||
msgid "TrackerErr"
|
||||
msgstr "ОшибкаТрекера"
|
||||
|
||||
# TODO should replace "uploader limit NN peers" with "global number of upload slots: NN"
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:507
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:509
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:519
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:521
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:528
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:530
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:534
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:536
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:859
|
||||
msgid "peers"
|
||||
msgstr "пир."
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:517
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:521
|
||||
msgid "Seeding"
|
||||
msgstr "Раздается"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:523
|
||||
msgid "Complete"
|
||||
msgstr "Завершен"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:526
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:530
|
||||
msgid "OK"
|
||||
msgstr "Загружается"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:532
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:536
|
||||
msgid "Stalled"
|
||||
msgstr "Простаивает"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:538
|
||||
msgid "No Peers"
|
||||
msgstr "Нет Пиров"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:540
|
||||
msgid "Stopped"
|
||||
msgstr "Остановлен"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:553
|
||||
msgid "View files"
|
||||
msgstr "Открыть директорию"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:555
|
||||
msgid "Open file"
|
||||
msgstr "Открыть файл"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:579
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:779
|
||||
msgid "Tracker"
|
||||
msgstr "Трекер"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:580
|
||||
msgid "Details"
|
||||
msgstr "Подробнее"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:614
|
||||
msgid "Stop the torrent"
|
||||
msgstr "Остановить торрент"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:616
|
||||
msgid "Stop"
|
||||
msgstr "Остановить"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:622
|
||||
msgid "Start the torrent"
|
||||
msgstr "Запустить торрент"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:624
|
||||
msgid "Start"
|
||||
msgstr "Запустить"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:629
|
||||
msgid "Remove the torrent from the active list, deleting the .torrent file"
|
||||
msgstr "Удалить торрент из списка и с диска"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:631
|
||||
msgid "Remove"
|
||||
msgstr "Удалить"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:635
|
||||
msgid "Delete the .torrent file and the associated data file(s)"
|
||||
msgstr "Удалить торрент и стереть загруженные файлы"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:637
|
||||
msgid "Delete"
|
||||
msgstr "Стереть"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:680
|
||||
msgid "Seed"
|
||||
msgstr "Сид"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:698
|
||||
msgid "Uninteresting (The peer has no pieces we need)"
|
||||
msgstr "Uninteresting (У пира нет нужных нам частей торрента)"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:700
|
||||
msgid "Choked (The peer is not allowing us to request pieces)"
|
||||
msgstr "Choked (Этот пир не позволяет нам запрашивать части торрента)"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:714
|
||||
msgid "Uninterested (We have no pieces the peer needs)"
|
||||
msgstr "Uninterested (У нас нужных этому пиру частей торрента)"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:716
|
||||
msgid "Choking (We are not allowing the peer to request pieces)"
|
||||
msgstr "Choking (Мы не позволяем этому пиру запрашивать у нас части торрента)"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:742
|
||||
msgid "Add Torrent"
|
||||
msgstr "Добавить Торрент"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:744
|
||||
msgid "From URL"
|
||||
msgstr "Из URL"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:749
|
||||
msgid "Add torrent"
|
||||
msgstr "Добавить торрент"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:752
|
||||
#, java-format
|
||||
msgid "Alternately, you can copy .torrent files to the directory {0}."
|
||||
msgstr "Ну или вы можете скопировать .torrent-файлы в директорию {0}."
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:754
|
||||
msgid "Removing a .torrent file will cause the torrent to stop."
|
||||
msgstr "Удаление .torrent-файла приведет к остановке торрента."
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:770
|
||||
msgid "Create Torrent"
|
||||
msgstr "Создать Торрент"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:773
|
||||
msgid "Data to seed"
|
||||
msgstr "Файлы для раздачи"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:777
|
||||
msgid "File or directory to seed (must be within the specified path)"
|
||||
msgstr "Файл или директория для раздачи (вводите только название файла или директории, указание абсолютных путей не поддерживается)"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:781
|
||||
msgid "Select a tracker"
|
||||
msgstr "Выбрать трекер"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:794
|
||||
msgid "or"
|
||||
msgstr "или"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:797
|
||||
msgid "Specify custom tracker announce URL"
|
||||
msgstr "Задать URL анонсера вручную"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:800
|
||||
msgid "Create torrent"
|
||||
msgstr "Создать торрент"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:817
|
||||
msgid "Configuration"
|
||||
msgstr "Настройки"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:820
|
||||
msgid "Data directory"
|
||||
msgstr "Директория для файлов"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:823
|
||||
msgid "Directory to store torrents and data"
|
||||
msgstr "Директория, где будут храниться торренты и загружаемые файлы"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:825
|
||||
msgid "Edit i2psnark.config and restart to change"
|
||||
msgstr "Для изменения отредактируйте файл i2psnark.config и перезагрузите I2PSnark"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:829
|
||||
msgid "Auto start"
|
||||
msgstr "Автозапуск"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:833
|
||||
msgid "If checked, automatically start torrents that are added"
|
||||
msgstr "Автоматически запускать торренты после добавления"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:856
|
||||
msgid "Total uploader limit"
|
||||
msgstr "Ограничение количества слотов отдачи"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:863
|
||||
msgid "Up bandwidth limit"
|
||||
msgstr "Ограничение скорости отдачи"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:866
|
||||
msgid "Half available bandwidth recommended."
|
||||
msgstr "Рекомендуется использовать половину от доступной пропускной способности."
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:868
|
||||
msgid "View or change router bandwidth"
|
||||
msgstr "Посмотреть/настроить ограничения скорости в маршрутизаторе I2P"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:872
|
||||
msgid "Use open trackers also"
|
||||
msgstr "Дополнительно использовать открытые трекеры"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:876
|
||||
msgid "If checked, announce torrents to open trackers as well as the tracker listed in the torrent file"
|
||||
msgstr "Анонсировать торренты на открытых трекерах, дополнительно к тем, что указаны внутри торрента"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:880
|
||||
msgid "Open tracker announce URLs"
|
||||
msgstr "URL открытых трекеров"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:891
|
||||
msgid "I2CP host"
|
||||
msgstr "Адрес I2CP"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:896
|
||||
msgid "I2CP port"
|
||||
msgstr "Порт I2CP"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:909
|
||||
msgid "I2CP options"
|
||||
msgstr "Параметры I2CP"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:914
|
||||
msgid "Save configuration"
|
||||
msgstr "Сохранить настройки"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:967
|
||||
#, java-format
|
||||
msgid "Torrent fetched from {0}"
|
||||
msgstr "Получен торрент из: {0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:994
|
||||
#, java-format
|
||||
msgid "Torrent at {0} was not valid"
|
||||
msgstr "Торрент полученный из {0} некорректен"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:999
|
||||
#, java-format
|
||||
msgid "Torrent was not retrieved from {0}"
|
||||
msgstr "Не удалось получить торрент из: {0}"
|
||||
|
652
apps/i2psnark/locale/messages_zh.po
Normal file
652
apps/i2psnark/locale/messages_zh.po
Normal file
@ -0,0 +1,652 @@
|
||||
# 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 <foo@bar>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P i2psnark\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-12-18 06:45+0000\n"
|
||||
"PO-Revision-Date: 2009-12-18 15:57+0800\n"
|
||||
"Last-Translator: walking <zhazhenzhong@gmail.com>\n"
|
||||
"Language-Team: foo <foo@bar>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Chinese\n"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:84
|
||||
#, java-format
|
||||
msgid "Adding torrents in {0} minutes"
|
||||
msgstr "{0}分钟内完成添加"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:241
|
||||
#, java-format
|
||||
msgid "Total uploaders limit changed to {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:243
|
||||
#, java-format
|
||||
msgid "Minimum total uploaders limit is {0}"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:255
|
||||
#, java-format
|
||||
msgid "Up BW limit changed to {0}KBps"
|
||||
msgstr "上传带宽限制改为 {0} KBps"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:257
|
||||
#, java-format
|
||||
msgid "Minimum up bandwidth limit is {0}KBps"
|
||||
msgstr "最小上传带宽限制为 {0} KBps"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:301
|
||||
msgid "Cannot change the I2CP settings while torrents are active"
|
||||
msgstr "正在下载/上传,无法更改I2CP设置"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:307
|
||||
msgid "Disconnecting old I2CP destination"
|
||||
msgstr "正在断开旧的I2CP目标"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:311
|
||||
#, java-format
|
||||
msgid "I2CP settings changed to {0}"
|
||||
msgstr "I2CP设置改为{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:315
|
||||
msgid "Unable to connect with the new settings, reverting to the old I2CP settings"
|
||||
msgstr "无法通过新设置连接,恢复I2CP的旧设置"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:319
|
||||
msgid "Unable to reconnect with the old settings!"
|
||||
msgstr "旧设置也无法连接!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:321
|
||||
msgid "Reconnected on the new I2CP destination"
|
||||
msgstr "重新连接新I2CP目标"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:332
|
||||
#, java-format
|
||||
msgid "I2CP listener restarted for \"{0}\""
|
||||
msgstr "\"{0}\"的I2CP监听端口已启动"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:343
|
||||
msgid "Enabled autostart"
|
||||
msgstr "启用自动启动"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:345
|
||||
msgid "Disabled autostart"
|
||||
msgstr "禁用自动启动"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:351
|
||||
msgid "Enabled open trackers - torrent restart required to take effect."
|
||||
msgstr "启用OpenTracker-重新启动种子后生效"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:353
|
||||
msgid "Disabled open trackers - torrent restart required to take effect."
|
||||
msgstr "禁用OpenTracker - 重新启动种子后生效"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:360
|
||||
msgid "Open Tracker list changed - torrent restart required to take effect."
|
||||
msgstr "OpenTracker列表已改变 - 重新启动种子后生效"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:367
|
||||
msgid "Configuration unchanged."
|
||||
msgstr "设置未改变"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:377
|
||||
#, java-format
|
||||
msgid "Unable to save the config to {0}"
|
||||
msgstr "无法保存设置到{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:395
|
||||
msgid "Connecting to I2P"
|
||||
msgstr "正在连接到I2P"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:398
|
||||
msgid "Error connecting to I2P - check your I2CP settings!"
|
||||
msgstr "连接I2P时发生错误 - 请检查I2CP设置!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:407
|
||||
#, java-format
|
||||
msgid "Error: Could not add the torrent {0}"
|
||||
msgstr "错误:无法添加种子{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:446
|
||||
#, java-format
|
||||
msgid "Torrent in \"{0}\" is invalid"
|
||||
msgstr "无效种子 \"{0}\" "
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:461
|
||||
#, java-format
|
||||
msgid "Torrent added and started: \"{0}\""
|
||||
msgstr "已添加并启动种子:\"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:463
|
||||
#, java-format
|
||||
msgid "Torrent added: \"{0}\""
|
||||
msgstr "已添加种子:\"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:559
|
||||
#, java-format
|
||||
msgid "Non-i2p tracker in \"{0}\", deleting it from our list of trackers!"
|
||||
msgstr "【匿名性警告】\"{0}\" 中含有非I2P Tracker,程序将从Tracker列表中将其删除。"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:562
|
||||
#, java-format
|
||||
msgid "Too many files in \"{0}\" ({1}), deleting it!"
|
||||
msgstr "\"{0}\" ({1}) 含有太多文件,删除之!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:564
|
||||
#, java-format
|
||||
msgid "Torrent file \"{0}\" cannot end in '.torrent', deleting it!"
|
||||
msgstr "种子文件 \"{0}\" 不以 \".torrent\"结尾,删除之!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:566
|
||||
#, java-format
|
||||
msgid "No pieces in \"{0}\", deleting it!"
|
||||
msgstr "\"{0}\" 中没有数据片,删除之!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:568
|
||||
#, java-format
|
||||
msgid "Too many pieces in \"{0}\", limit is {1}, deleting it!"
|
||||
msgstr "\"{0}\" 中文件分片太多,限额为{1},删除之!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:570
|
||||
#, java-format
|
||||
msgid "Pieces are too large in \"{0}\" ({1}B), deleting it."
|
||||
msgstr "\"{0}\" ({1}B) 中文件分片过大,删除之。"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:571
|
||||
#, java-format
|
||||
msgid "Limit is {0}B"
|
||||
msgstr "限额为 {0}B"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:579
|
||||
#, java-format
|
||||
msgid "Torrents larger than {0}B are not supported yet, deleting \"{1}\""
|
||||
msgstr "目前不支持大于{0}B 的种子,正在删除\"{1}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:595
|
||||
#, java-format
|
||||
msgid "Error: Could not remove the torrent {0}"
|
||||
msgstr "错误:无法删除种子{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:616
|
||||
#, java-format
|
||||
msgid "Torrent stopped: \"{0}\""
|
||||
msgstr "种子已停止:\"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:631
|
||||
#, java-format
|
||||
msgid "Torrent removed: \"{0}\""
|
||||
msgstr "种子已删除:\"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:664
|
||||
#, java-format
|
||||
msgid "Download finished: \"{0}\""
|
||||
msgstr "下载已完成:\"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:664
|
||||
#, java-format
|
||||
msgid "size: {0}B"
|
||||
msgstr "大小:{0}B"
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:692
|
||||
msgid "Unable to connect to I2P!"
|
||||
msgstr "无法连接至I2P!"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:86
|
||||
msgid "I2PSnark - Anonymous BitTorrent Client"
|
||||
msgstr "I2PSnark - 匿名BitTorrent客户端"
|
||||
|
||||
#: ../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:656
|
||||
msgid "I2PSnark"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:99
|
||||
msgid "Forum"
|
||||
msgstr "论坛"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:125
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:131
|
||||
msgid "Hide Peers"
|
||||
msgstr "隐藏用户"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:134
|
||||
msgid "Show Peers"
|
||||
msgstr "显示用户"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:139
|
||||
msgid "Torrent"
|
||||
msgstr "种子"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:141
|
||||
msgid "ETA"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:143
|
||||
msgid "Downloaded"
|
||||
msgstr "已下载"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:145
|
||||
msgid "Uploaded"
|
||||
msgstr "已上传"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:147
|
||||
msgid "Down Rate"
|
||||
msgstr "下载速度"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:149
|
||||
msgid "Up Rate"
|
||||
msgstr "上传速度"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:156
|
||||
msgid "Stop all torrents and the I2P tunnel"
|
||||
msgstr "停止全部种子及I2P隧道"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:158
|
||||
msgid "Stop All"
|
||||
msgstr "停止全部"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:163
|
||||
msgid "Start all torrents and the I2P tunnel"
|
||||
msgstr "启动全部种子及I2P隧道"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:165
|
||||
msgid "Start All"
|
||||
msgstr "启动全部"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:182
|
||||
msgid "No torrents loaded."
|
||||
msgstr "未载入任何种子"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:187
|
||||
msgid "Totals"
|
||||
msgstr "总计"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:189
|
||||
#, java-format
|
||||
msgid "{0} torrents"
|
||||
msgstr "{0} 个种子"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:192
|
||||
#, java-format
|
||||
msgid "{0} connected peers"
|
||||
msgstr "{0} 已连接用户"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:227
|
||||
#, java-format
|
||||
msgid "Torrent file {0} does not exist"
|
||||
msgstr "种子文件{0}不存在"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:237
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:990
|
||||
#, java-format
|
||||
msgid "Torrent already running: {0}"
|
||||
msgstr "种子已启动:{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:239
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:992
|
||||
#, java-format
|
||||
msgid "Torrent already in the queue: {0}"
|
||||
msgstr "种子排队中:{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:243
|
||||
#, java-format
|
||||
msgid "Copying torrent to {0}"
|
||||
msgstr "正在复制种子到{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:246
|
||||
#, java-format
|
||||
msgid "Unable to copy the torrent to {0}"
|
||||
msgstr "无法复制种子文件到{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:246
|
||||
#, java-format
|
||||
msgid "from {0}"
|
||||
msgstr "来源{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:254
|
||||
#, java-format
|
||||
msgid "Fetching {0}"
|
||||
msgstr "正在获取{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:258
|
||||
msgid "Invalid URL - must start with http://"
|
||||
msgstr "无效链接 - 必须以http:// 开头"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:288
|
||||
#, java-format
|
||||
msgid "Starting up torrent {0}"
|
||||
msgstr "正在启动种子{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:308
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:326
|
||||
#, java-format
|
||||
msgid "Torrent file deleted: {0}"
|
||||
msgstr "种子文件已删除:{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:332
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:342
|
||||
#, java-format
|
||||
msgid "Data file deleted: {0}"
|
||||
msgstr "数据文件已删除:{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:334
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:344
|
||||
#, java-format
|
||||
msgid "Data file could not be deleted: {0}"
|
||||
msgstr "无法删除数据文件:{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:353
|
||||
#, java-format
|
||||
msgid "Data dir deleted: {0}"
|
||||
msgstr "数据文件夹已删除:{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:384
|
||||
msgid "Error creating torrent - you must select a tracker"
|
||||
msgstr "创建种子时发生错误 - 您必须选择一个Tracker"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:399
|
||||
#, java-format
|
||||
msgid "Torrent created for \"{0}\""
|
||||
msgstr "种子创建成功\"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:402
|
||||
#, java-format
|
||||
msgid "Many I2P trackers require you to register new torrents before seeding - please do so before starting \"{0}\""
|
||||
msgstr "多数I2PTracker需要用户在做种前注册新种子 - 请在启动 \"{0}\"前到所使用的Tracker进行注册。"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:404
|
||||
#, java-format
|
||||
msgid "Error creating a torrent for \"{0}\""
|
||||
msgstr "创建种子时发生错误 \"{0}\""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:407
|
||||
#, java-format
|
||||
msgid "Cannot create a torrent for the nonexistent data: {0}"
|
||||
msgstr "无法为不存在的数据文件创建种子:{0}"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:410
|
||||
msgid "Error creating torrent - you must enter a file or directory"
|
||||
msgstr "创建种子时发生错误 - 必须指定文件或文件夹"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:413
|
||||
msgid "Stopping all torrents and closing the I2P tunnel."
|
||||
msgstr "正在停用所有种子并关闭I2P隧道。"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:422
|
||||
msgid "I2P tunnel closed."
|
||||
msgstr "I2P隧道已关闭"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:425
|
||||
msgid "Opening the I2P tunnel and starting all torrents."
|
||||
msgstr "正在打开I2P隧道并启动所有种子"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:502
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:670
|
||||
msgid "Unknown"
|
||||
msgstr "未知"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:505
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:509
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:513
|
||||
msgid "TrackerErr"
|
||||
msgstr "Tracker错误"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:507
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:509
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:519
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:521
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:528
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:530
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:534
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:536
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:862
|
||||
msgid "peers"
|
||||
msgstr "用户"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:517
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:521
|
||||
msgid "Seeding"
|
||||
msgstr "正做种"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:523
|
||||
msgid "Complete"
|
||||
msgstr "完成"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:526
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:530
|
||||
msgid "OK"
|
||||
msgstr "确定"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:532
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:536
|
||||
msgid "Stalled"
|
||||
msgstr "等待"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:538
|
||||
msgid "No Peers"
|
||||
msgstr "没有用户"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:540
|
||||
msgid "Stopped"
|
||||
msgstr "已停用"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:553
|
||||
msgid "View files"
|
||||
msgstr "浏览文件"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:555
|
||||
msgid "Open file"
|
||||
msgstr "打开文件"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:579
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:781
|
||||
msgid "Tracker"
|
||||
msgstr "Tracker服务器"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:580
|
||||
msgid "Details"
|
||||
msgstr "详情"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:614
|
||||
msgid "Stop the torrent"
|
||||
msgstr "停止种子"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:616
|
||||
msgid "Stop"
|
||||
msgstr "停止"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:622
|
||||
msgid "Start the torrent"
|
||||
msgstr "启动种子"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:624
|
||||
msgid "Start"
|
||||
msgstr "启动"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:629
|
||||
msgid "Remove the torrent from the active list, deleting the .torrent file"
|
||||
msgstr "取消下载任务并删除对应种子文件。"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:631
|
||||
msgid "Remove"
|
||||
msgstr "移除"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:635
|
||||
msgid "Delete the .torrent file and the associated data file(s)"
|
||||
msgstr "删除种子及所下载的文件"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:637
|
||||
msgid "Delete"
|
||||
msgstr "删除"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:680
|
||||
msgid "Seed"
|
||||
msgstr "种子"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:698
|
||||
msgid "Uninteresting (The peer has no pieces we need)"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:700
|
||||
msgid "Choked (The peer is not allowing us to request pieces)"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:714
|
||||
msgid "Uninterested (We have no pieces the peer needs)"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:716
|
||||
msgid "Choking (We are not allowing the peer to request pieces)"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:743
|
||||
msgid "Add Torrent"
|
||||
msgstr "添加种子"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:745
|
||||
msgid "From URL"
|
||||
msgstr "从URL"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:750
|
||||
msgid "Add torrent"
|
||||
msgstr "添加种子"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:753
|
||||
#, java-format
|
||||
msgid "Alternately, you can copy .torrent files to the directory {0}."
|
||||
msgstr "或者您可以将.torrent文件复制到以下目录{0}."
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:755
|
||||
msgid "Removing a .torrent file will cause the torrent to stop."
|
||||
msgstr "删除种子文件将导致中止该下载任务。"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:772
|
||||
msgid "Create Torrent"
|
||||
msgstr "创建种子"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:775
|
||||
msgid "Data to seed"
|
||||
msgstr "做种数据"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:779
|
||||
msgid "File or directory to seed (must be within the specified path)"
|
||||
msgstr "做种文件或文件夹(必须下面为Snark指定的文件夹中)"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:783
|
||||
msgid "Select a tracker"
|
||||
msgstr "选择一个Tracker"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:796
|
||||
msgid "or"
|
||||
msgstr "或"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:799
|
||||
msgid "Specify custom tracker announce URL"
|
||||
msgstr "指定Open Tracker发布链接"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:802
|
||||
msgid "Create torrent"
|
||||
msgstr "创建种子"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:820
|
||||
msgid "Configuration"
|
||||
msgstr "设置"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:823
|
||||
msgid "Data directory"
|
||||
msgstr "数据文件夹"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:826
|
||||
msgid "Directory to store torrents and data"
|
||||
msgstr "种子及被做种文件的保存位置。"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:828
|
||||
msgid "Edit i2psnark.config and restart to change"
|
||||
msgstr "编辑 i2psnark.config 并重启Snark后生效"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:832
|
||||
msgid "Auto start"
|
||||
msgstr "自动启动"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:836
|
||||
msgid "If checked, automatically start torrents that are added"
|
||||
msgstr "选中后Snark将自动启动已添加的所有种子。"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:859
|
||||
msgid "Total uploader limit"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:866
|
||||
msgid "Up bandwidth limit"
|
||||
msgstr "上传带宽限制"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:869
|
||||
msgid "Half available bandwidth recommended."
|
||||
msgstr "推荐设置为可用带宽的一半。"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:871
|
||||
msgid "View or change router bandwidth"
|
||||
msgstr "浏览或修改路由器带宽"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:875
|
||||
msgid "Use open trackers also"
|
||||
msgstr "同时使用OpenTracker"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:879
|
||||
msgid "If checked, announce torrents to open trackers as well as the tracker listed in the torrent file"
|
||||
msgstr "选择后在OpenTracker及种子文件中的Tracker上同时发布。"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:883
|
||||
msgid "Open tracker announce URLs"
|
||||
msgstr "Open Tracker发布链接"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:894
|
||||
msgid "I2CP host"
|
||||
msgstr "I2CP主机"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:899
|
||||
msgid "I2CP port"
|
||||
msgstr "I2CP端口"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:912
|
||||
msgid "I2CP options"
|
||||
msgstr "I2CP选项"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:917
|
||||
msgid "Save configuration"
|
||||
msgstr "保存设置"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:970
|
||||
#, java-format
|
||||
msgid "Torrent fetched from {0}"
|
||||
msgstr "从{0}获取种子成功"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:998
|
||||
#, java-format
|
||||
msgid "Torrent at {0} was not valid"
|
||||
msgstr "{0}的种子中有错误"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1003
|
||||
#, java-format
|
||||
msgid "Torrent was not retrieved from {0}"
|
||||
msgstr "从{0}获得种子失败"
|
||||
|
||||
#~ msgid "Custom tracker URL"
|
||||
#~ msgstr "自定义TrackerURL"
|
||||
#~ msgid "Configure"
|
||||
#~ msgstr "设置"
|
||||
|
17
apps/i2ptunnel/java/bmsg.sh
Normal file
17
apps/i2ptunnel/java/bmsg.sh
Normal file
@ -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
|
@ -41,13 +41,48 @@
|
||||
<attribute name="Class-Path" value="i2p.jar mstreaming.jar" />
|
||||
</manifest>
|
||||
</jar>
|
||||
<ant target="bundle" />
|
||||
<ant target="war" />
|
||||
</target>
|
||||
|
||||
<target name="bundle" depends="compile, precompilejsp">
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="false" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="false" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="cmd" osfamily="windows" failifexecutionfails="false" >
|
||||
<arg value="/c" />
|
||||
<arg value="bundle-messages.bat" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="poupdate" depends="compile, precompilejsp">
|
||||
<!-- Update the messages_*.po files. -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
<arg value="-p" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
<arg value="-p" />
|
||||
</exec>
|
||||
<exec executable="cmd" osfamily="windows" failifexecutionfails="true" >
|
||||
<arg value="/c" />
|
||||
<arg value="bundle-messages.bat" />
|
||||
<arg value="-p" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="war" depends="precompilejsp">
|
||||
<war destfile="build/i2ptunnel.war" webxml="../jsp/web-out.xml"
|
||||
basedir="../jsp/" excludes="web.xml, **/*.java, *.jsp">
|
||||
</war>
|
||||
</target>
|
||||
|
||||
<target name="precompilejsp" unless="precompilejsp.uptodate">
|
||||
<delete dir="../jsp/WEB-INF/" />
|
||||
<delete file="../jsp/web-fragment.xml" />
|
||||
@ -113,11 +148,7 @@
|
||||
<delete file="../jsp/web-out.xml" />
|
||||
</target>
|
||||
<target name="cleandep" depends="clean">
|
||||
<!-- ministreaming will clean core -->
|
||||
<ant dir="../../ministreaming/java/" target="distclean" />
|
||||
</target>
|
||||
<target name="distclean" depends="clean">
|
||||
<!-- ministreaming will clean core -->
|
||||
<ant dir="../../ministreaming/java/" target="distclean" />
|
||||
</target>
|
||||
</project>
|
||||
|
26
apps/i2ptunnel/java/bundle-messages.bat
Normal file
26
apps/i2ptunnel/java/bundle-messages.bat
Normal file
@ -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
|
87
apps/i2ptunnel/java/bundle-messages.sh
Executable file
87
apps/i2ptunnel/java/bundle-messages.sh
Executable file
@ -0,0 +1,87 @@
|
||||
#
|
||||
# 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=net.i2p.i2ptunnel.web.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 ../jsp/WEB-INF"
|
||||
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 ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/web/messages_$LG.class -a \
|
||||
../jsp/WEB-INF/classes/net/i2p/i2ptunnel/web/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")
|
||||
# intl._("foo")
|
||||
# intl.title("foo")
|
||||
# In a jsp, you must use a helper or handler that has the context set.
|
||||
# To start a new translation, copy the header from an old translation to the new .po file,
|
||||
# then ant distclean updater.
|
||||
find $JPATHS -name *.java > $TMPFILE
|
||||
xgettext -f $TMPFILE -F -L java --from-code=UTF-8 \
|
||||
--keyword=_ --keyword=_x --keyword=intl._ --keyword=intl.title \
|
||||
-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 --statistics -r $CLASS -l $LG -d ../jsp/WEB-INF/classes $i
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo 'Warning - msgfmt failed, not updating translations'
|
||||
break
|
||||
fi
|
||||
done
|
||||
rm -f $TMPFILE
|
||||
# todo: return failure
|
||||
exit 0
|
@ -20,7 +20,7 @@ import java.util.zip.GZIPInputStream;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.util.ByteCache;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -219,7 +219,7 @@ class HTTPResponseOutputStream extends FilterOutputStream {
|
||||
//out.flush();
|
||||
PipedInputStream pi = new PipedInputStream();
|
||||
PipedOutputStream po = new PipedOutputStream(pi);
|
||||
new I2PThread(new Pusher(pi, out), "HTTP decompresser").start();
|
||||
new I2PAppThread(new Pusher(pi, out), "HTTP decompresser").start();
|
||||
out = po;
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ import net.i2p.client.streaming.I2PSocketManagerFactory;
|
||||
import net.i2p.client.streaming.I2PSocketOptions;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.EventDispatcher;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SimpleScheduler;
|
||||
import net.i2p.util.SimpleTimer;
|
||||
@ -153,7 +153,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
|
||||
} // else delay creating session until createI2PSocket() is called
|
||||
|
||||
Thread t = new I2PThread(this);
|
||||
Thread t = new I2PAppThread(this);
|
||||
t.setName("Client " + _clientId);
|
||||
listenerReady = false;
|
||||
t.start();
|
||||
@ -207,7 +207,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
|
||||
for (int i = 0; i < _numConnectionBuilders; i++) {
|
||||
String name = "ClientBuilder" + _clientId + '.' + i;
|
||||
I2PThread b = new I2PThread(new TunnelConnectionBuilder(), name);
|
||||
I2PAppThread b = new I2PAppThread(new TunnelConnectionBuilder(), name);
|
||||
b.setDaemon(true);
|
||||
b.start();
|
||||
}
|
||||
@ -350,7 +350,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
* called by derived classes after initialization.
|
||||
*
|
||||
*/
|
||||
public final void startRunning() {
|
||||
public void startRunning() {
|
||||
synchronized (startLock) {
|
||||
startRunning = true;
|
||||
startLock.notify();
|
||||
@ -490,7 +490,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
||||
protected void manageConnection(Socket s) {
|
||||
if (s == null) return;
|
||||
if (_numConnectionBuilders <= 0) {
|
||||
new I2PThread(new BlockingRunner(s), "Clinet run").start();
|
||||
new I2PAppThread(new BlockingRunner(s), "Clinet run").start();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -233,11 +233,35 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
return opts;
|
||||
}
|
||||
|
||||
private InternalSocketRunner isr;
|
||||
|
||||
/**
|
||||
* Actually start working on incoming connections.
|
||||
* Overridden to start an internal socket too.
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void startRunning() {
|
||||
super.startRunning();
|
||||
this.isr = new InternalSocketRunner(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overridden to close internal socket too.
|
||||
*/
|
||||
public boolean close(boolean forced) {
|
||||
boolean rv = super.close(forced);
|
||||
if (this.isr != null)
|
||||
this.isr.stopRunning();
|
||||
return rv;
|
||||
}
|
||||
|
||||
private static final boolean DEFAULT_GZIP = true;
|
||||
// all default to false
|
||||
public static final String PROP_REFERER = "i2ptunnel.httpclient.sendReferer";
|
||||
public static final String PROP_USER_AGENT = "i2ptunnel.httpclient.sendUserAgent";
|
||||
public static final String PROP_VIA = "i2ptunnel.httpclient.sendVia";
|
||||
public static final String PROP_JUMP_SERVERS = "i2ptunnel.httpclient.jumpServers";
|
||||
|
||||
private static long __requestId = 0;
|
||||
protected void clientConnectionRun(Socket s) {
|
||||
@ -245,6 +269,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
OutputStream out = null;
|
||||
String targetRequest = null;
|
||||
boolean usingWWWProxy = false;
|
||||
boolean usingInternalServer = false;
|
||||
String currentProxy = null;
|
||||
long requestId = ++__requestId;
|
||||
try {
|
||||
@ -271,6 +296,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
int pos = line.indexOf(" ");
|
||||
if (pos == -1) break;
|
||||
method = line.substring(0, pos);
|
||||
// TODO use Java URL class to make all this simpler and more robust
|
||||
String request = line.substring(pos + 1);
|
||||
if (request.startsWith("/") && getTunnel().getClientOptions().getProperty("i2ptunnel.noproxy") != null) {
|
||||
request = "http://i2p" + request;
|
||||
@ -316,8 +342,11 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
}
|
||||
}
|
||||
|
||||
// Quick hack for foo.bar.i2p
|
||||
if (host.toLowerCase().endsWith(".i2p")) {
|
||||
if (host.toLowerCase().equals("proxy.i2p")) {
|
||||
// so we don't do any naming service lookups
|
||||
destination = "proxy.i2p";
|
||||
usingInternalServer = true;
|
||||
} else if (host.toLowerCase().endsWith(".i2p")) {
|
||||
// Destination gets the host name
|
||||
destination = host;
|
||||
// Host becomes the destination key
|
||||
@ -454,15 +483,15 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
}
|
||||
destination = request.substring(0, pos);
|
||||
line = method + " " + request.substring(pos);
|
||||
}
|
||||
} // end host name processing
|
||||
|
||||
boolean isValid = usingWWWProxy || isSupportedAddress(host, protocol);
|
||||
boolean isValid = usingWWWProxy || usingInternalServer || isSupportedAddress(host, protocol);
|
||||
if (!isValid) {
|
||||
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "notValid(" + host + ")");
|
||||
method = null;
|
||||
destination = null;
|
||||
break;
|
||||
} else if (!usingWWWProxy) {
|
||||
} else if ((!usingWWWProxy) && (!usingInternalServer)) {
|
||||
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "host=getHostName(" + destination + ")");
|
||||
host = getHostName(destination); // hide original host
|
||||
}
|
||||
@ -473,7 +502,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
_log.debug(getPrefix(requestId) + "HOST :" + host + ":");
|
||||
_log.debug(getPrefix(requestId) + "DEST :" + destination + ":");
|
||||
}
|
||||
|
||||
|
||||
// end first line processing
|
||||
|
||||
} else {
|
||||
if (lowercaseLine.startsWith("host: ") && !usingWWWProxy) {
|
||||
line = "Host: " + host;
|
||||
@ -505,14 +536,14 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
continue; // completely strip the line
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (line.length() == 0) {
|
||||
|
||||
String ok = getTunnel().getClientOptions().getProperty("i2ptunnel.gzip");
|
||||
boolean gzip = DEFAULT_GZIP;
|
||||
if (ok != null)
|
||||
gzip = Boolean.valueOf(ok).booleanValue();
|
||||
if (gzip) {
|
||||
if (gzip && !usingInternalServer) {
|
||||
// according to rfc2616 s14.3, this *should* force identity, even if
|
||||
// an explicit q=0 for gzip doesn't. tested against orion.i2p, and it
|
||||
// seems to work.
|
||||
@ -526,7 +557,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
} else {
|
||||
newRequest.append(line).append("\r\n"); // HTTP spec
|
||||
}
|
||||
}
|
||||
} // end header processing
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug(getPrefix(requestId) + "NewRequest header: [" + newRequest.toString() + "]");
|
||||
|
||||
@ -548,7 +580,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
|
||||
// Serve local proxy files (images, css linked from error pages)
|
||||
// Ignore all the headers
|
||||
if (destination.equals("proxy.i2p")) {
|
||||
if (usingInternalServer) {
|
||||
serveLocalFile(out, method, targetRequest);
|
||||
s.close();
|
||||
return;
|
||||
@ -560,7 +592,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Unable to resolve " + destination + " (proxy? " + usingWWWProxy + ", request: " + targetRequest);
|
||||
byte[] header;
|
||||
boolean showAddrHelper = false;
|
||||
String jumpServers = null;
|
||||
if (usingWWWProxy)
|
||||
header = getErrorPage("dnfp", ERR_DESTINATION_UNKNOWN);
|
||||
else if(ahelper != 0)
|
||||
@ -569,9 +601,11 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
header = getErrorPage("dnf", ERR_DESTINATION_UNKNOWN);
|
||||
else {
|
||||
header = getErrorPage("dnfh", ERR_DESTINATION_UNKNOWN);
|
||||
showAddrHelper = true;
|
||||
jumpServers = getTunnel().getClientOptions().getProperty(PROP_JUMP_SERVERS);
|
||||
if (jumpServers == null)
|
||||
jumpServers = DEFAULT_JUMP_SERVERS;
|
||||
}
|
||||
writeErrorMessage(header, out, targetRequest, usingWWWProxy, destination, showAddrHelper);
|
||||
writeErrorMessage(header, out, targetRequest, usingWWWProxy, destination, jumpServers);
|
||||
s.close();
|
||||
return;
|
||||
}
|
||||
@ -726,15 +760,16 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
}
|
||||
}
|
||||
|
||||
private static String jumpServers[] = {
|
||||
"http://i2host.i2p/cgi-bin/i2hostjump?",
|
||||
// "http://orion.i2p/jump/",
|
||||
"http://stats.i2p/cgi-bin/jump.cgi?a=",
|
||||
// "http://trevorreznik.i2p/cgi-bin/jump.php?hostname=",
|
||||
"http://i2jump.i2p/"
|
||||
};
|
||||
private static String DEFAULT_JUMP_SERVERS =
|
||||
"http://i2host.i2p/cgi-bin/i2hostjump?," +
|
||||
"http://stats.i2p/cgi-bin/jump.cgi?a=," +
|
||||
"http://i2jump.i2p/";
|
||||
|
||||
/**
|
||||
* @param jumpServers comma- or space-separated list, or null
|
||||
*/
|
||||
private static void writeErrorMessage(byte[] errMessage, OutputStream out, String targetRequest,
|
||||
boolean usingWWWProxy, String wwwProxy, boolean showAddrHelper) throws IOException {
|
||||
boolean usingWWWProxy, String wwwProxy, String jumpServers) throws IOException {
|
||||
if (out != null) {
|
||||
out.write(errMessage);
|
||||
if (targetRequest != null) {
|
||||
@ -750,12 +785,17 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
out.write(uri.getBytes());
|
||||
out.write("</a>".getBytes());
|
||||
if (usingWWWProxy) out.write(("<br>WWW proxy: " + wwwProxy).getBytes());
|
||||
if (showAddrHelper) {
|
||||
if (jumpServers != null && jumpServers.length() > 0) {
|
||||
// Fixme untranslated
|
||||
out.write("<br><br>Click a link below to look for an address helper by using a \"jump\" service:<br>".getBytes());
|
||||
for (int i = 0; i < jumpServers.length; i++) {
|
||||
|
||||
StringTokenizer tok = new StringTokenizer(jumpServers, ", ");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String jurl = tok.nextToken();
|
||||
if (!jurl.startsWith("http://"))
|
||||
continue;
|
||||
// Skip jump servers we don't know
|
||||
String jumphost = jumpServers[i].substring(7); // "http://"
|
||||
String jumphost = jurl.substring(7); // "http://"
|
||||
jumphost = jumphost.substring(0, jumphost.indexOf('/'));
|
||||
try {
|
||||
Destination dest = I2PTunnel.destFromName(jumphost);
|
||||
@ -765,10 +805,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
}
|
||||
|
||||
out.write("<br><a href=\"".getBytes());
|
||||
out.write(jumpServers[i].getBytes());
|
||||
out.write(jurl.getBytes());
|
||||
out.write(uri.getBytes());
|
||||
out.write("\">".getBytes());
|
||||
out.write(jumpServers[i].getBytes());
|
||||
out.write(jurl.getBytes());
|
||||
out.write(uri.getBytes());
|
||||
out.write("</a>".getBytes());
|
||||
}
|
||||
@ -792,7 +832,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
||||
header = getErrorPage(I2PAppContext.getGlobalContext(), "dnfp", ERR_DESTINATION_UNKNOWN);
|
||||
else
|
||||
header = getErrorPage(I2PAppContext.getGlobalContext(), "dnf", ERR_DESTINATION_UNKNOWN);
|
||||
writeErrorMessage(header, out, targetRequest, usingWWWProxy, wwwProxy, false);
|
||||
writeErrorMessage(header, out, targetRequest, usingWWWProxy, wwwProxy, null);
|
||||
} catch (IOException ioe) {
|
||||
// static
|
||||
//_log.warn(getPrefix(requestId) + "Error writing out the 'destination was unknown' " + "message", ioe);
|
||||
|
@ -17,7 +17,7 @@ import java.util.zip.GZIPOutputStream;
|
||||
import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.EventDispatcher;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.data.Base32;
|
||||
|
||||
@ -118,7 +118,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
|
||||
useGZIP = true;
|
||||
|
||||
if (allowGZIP && useGZIP) {
|
||||
I2PThread req = new I2PThread(new CompressedRequestor(s, socket, modifiedHeader), Thread.currentThread().getName()+".hc");
|
||||
I2PAppThread req = new I2PAppThread(new CompressedRequestor(s, socket, modifiedHeader), Thread.currentThread().getName()+".hc");
|
||||
req.start();
|
||||
} else {
|
||||
new I2PTunnelRunner(s, socket, slock, null, modifiedHeader.getBytes(), null);
|
||||
@ -174,7 +174,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
|
||||
_log.info("request headers: " + _headers);
|
||||
serverout.write(_headers.getBytes());
|
||||
browserin = _browser.getInputStream();
|
||||
I2PThread sender = new I2PThread(new Sender(serverout, browserin, "server: browser to server"), Thread.currentThread().getName() + "hcs");
|
||||
I2PAppThread sender = new I2PAppThread(new Sender(serverout, browserin, "server: browser to server"), Thread.currentThread().getName() + "hcs");
|
||||
sender.start();
|
||||
|
||||
browserout = _browser.getOutputStream();
|
||||
|
@ -14,7 +14,7 @@ import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.EventDispatcher;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable {
|
||||
@ -83,9 +83,9 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
||||
i2ps = createI2PSocket(clientDest);
|
||||
i2ps.setReadTimeout(readTimeout);
|
||||
StringBuilder expectedPong = new StringBuilder();
|
||||
Thread in = new I2PThread(new IrcInboundFilter(s,i2ps, expectedPong), "IRC Client " + __clientId + " in");
|
||||
Thread in = new I2PAppThread(new IrcInboundFilter(s,i2ps, expectedPong), "IRC Client " + __clientId + " in");
|
||||
in.start();
|
||||
Thread out = new I2PThread(new IrcOutboundFilter(s,i2ps, expectedPong), "IRC Client " + __clientId + " out");
|
||||
Thread out = new I2PAppThread(new IrcOutboundFilter(s,i2ps, expectedPong), "IRC Client " + __clientId + " out");
|
||||
out.start();
|
||||
} catch (Exception ex) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
|
@ -16,10 +16,10 @@ import net.i2p.client.streaming.I2PSocket;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.util.ByteCache;
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorListener {
|
||||
public class I2PTunnelRunner extends I2PAppThread implements I2PSocket.SocketErrorListener {
|
||||
private final static Log _log = new Log(I2PTunnelRunner.class);
|
||||
|
||||
private static volatile long __runnerId;
|
||||
@ -222,7 +222,7 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
|
||||
}
|
||||
}
|
||||
|
||||
private class StreamForwarder extends I2PThread {
|
||||
private class StreamForwarder extends I2PAppThread {
|
||||
|
||||
InputStream in;
|
||||
OutputStream out;
|
||||
|
@ -24,7 +24,7 @@ import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.util.EventDispatcher;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
@ -132,7 +132,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
*
|
||||
*/
|
||||
public void startRunning() {
|
||||
Thread t = new I2PThread(this);
|
||||
Thread t = new I2PAppThread(this);
|
||||
t.setName("Server " + (++__serverId));
|
||||
t.start();
|
||||
}
|
||||
@ -204,7 +204,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
I2PServerSocket i2pS_S = sockMgr.getServerSocket();
|
||||
int handlers = getHandlerCount();
|
||||
for (int i = 0; i < handlers; i++) {
|
||||
I2PThread handler = new I2PThread(new Handler(i2pS_S), "Handle Server " + i);
|
||||
I2PAppThread handler = new I2PAppThread(new Handler(i2pS_S), "Handle Server " + i);
|
||||
handler.start();
|
||||
}
|
||||
} else {
|
||||
@ -213,7 +213,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||
try {
|
||||
final I2PSocket i2ps = i2pS_S.accept();
|
||||
if (i2ps == null) throw new I2PException("I2PServerSocket closed");
|
||||
new I2PThread(new Runnable() { public void run() { blockingHandle(i2ps); } }).start();
|
||||
new I2PAppThread(new Runnable() { public void run() { blockingHandle(i2ps); } }).start();
|
||||
} catch (I2PException ipe) {
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Error accepting - KILLING THE TUNNEL SERVER", ipe);
|
||||
|
@ -14,7 +14,7 @@ import net.i2p.I2PException;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.EventDispatcher;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
public class I2Ping extends I2PTunnelTask implements Runnable {
|
||||
@ -59,7 +59,7 @@ public class I2Ping extends I2PTunnelTask implements Runnable {
|
||||
sockMgr = I2PTunnelClient.getSocketManager(tunnel);
|
||||
}
|
||||
}
|
||||
Thread t = new I2PThread(this);
|
||||
Thread t = new I2PAppThread(this);
|
||||
t.setName("Client");
|
||||
t.start();
|
||||
open = true;
|
||||
@ -188,7 +188,7 @@ public class I2Ping extends I2PTunnelTask implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
public class PingHandler extends I2PThread {
|
||||
public class PingHandler extends I2PAppThread {
|
||||
private String destination;
|
||||
|
||||
public PingHandler(String dest) {
|
||||
|
@ -0,0 +1,55 @@
|
||||
package net.i2p.i2ptunnel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.InternalServerSocket;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Listen for in-JVM connections on the internal "socket"
|
||||
*
|
||||
* @author zzz
|
||||
*/
|
||||
class InternalSocketRunner implements Runnable {
|
||||
private I2PTunnelClientBase client;
|
||||
private int port;
|
||||
private ServerSocket ss;
|
||||
private boolean open;
|
||||
private static final Log _log = new Log(InternalSocketRunner.class);
|
||||
|
||||
/** starts the runner */
|
||||
InternalSocketRunner(I2PTunnelClientBase client) {
|
||||
this.client = client;
|
||||
this.port = client.getLocalPort();
|
||||
Thread t = new I2PAppThread(this, "Internal socket port " + this.port, true);
|
||||
t.start();
|
||||
}
|
||||
|
||||
public final void run() {
|
||||
try {
|
||||
this.ss = new InternalServerSocket(this.port);
|
||||
this.open = true;
|
||||
while (true) {
|
||||
Socket s = this.ss.accept();
|
||||
this.client.manageConnection(s);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
if (this.open) {
|
||||
_log.error("Error listening for internal connections on " + this.port, ex);
|
||||
}
|
||||
this.open = false;
|
||||
}
|
||||
}
|
||||
|
||||
void stopRunning() {
|
||||
if (this.open) {
|
||||
try {
|
||||
this.ss.close();
|
||||
} catch (IOException ex) {}
|
||||
this.open = false;
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ import net.i2p.client.I2PClientFactory;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.data.Base32;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -106,7 +106,7 @@ public class TunnelController implements Logging {
|
||||
public void startTunnelBackground() {
|
||||
if (_running) return;
|
||||
_starting = true;
|
||||
new I2PThread(new Runnable() { public void run() { startTunnel(); } }).start();
|
||||
new I2PAppThread(new Runnable() { public void run() { startTunnel(); } }).start();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,7 @@ import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -94,7 +94,7 @@ public class TunnelControllerGroup {
|
||||
_controllers.add(controller);
|
||||
i++;
|
||||
}
|
||||
I2PThread startupThread = new I2PThread(new StartControllers(), "Startup tunnels");
|
||||
I2PAppThread startupThread = new I2PAppThread(new StartControllers(), "Startup tunnels");
|
||||
startupThread.start();
|
||||
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
|
@ -55,7 +55,7 @@ public class I2PSOCKSTunnel extends I2PTunnelClientBase {
|
||||
I2PSocket destSock = serv.getDestinationI2PSocket(this);
|
||||
new I2PTunnelRunner(clientSock, destSock, sockLock, null, mySockets);
|
||||
} catch (SOCKSException e) {
|
||||
_log.error("Error from SOCKS connection: " + e.getMessage());
|
||||
_log.error("Error from SOCKS connection", e);
|
||||
closeSocket(s);
|
||||
}
|
||||
}
|
||||
|
37
apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/Messages.java
Normal file
37
apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/Messages.java
Normal file
@ -0,0 +1,37 @@
|
||||
package net.i2p.i2ptunnel.web;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.Translate;
|
||||
|
||||
/**
|
||||
* Translate strings for this package.
|
||||
*/
|
||||
public class Messages {
|
||||
private static final String BUNDLE_NAME = "net.i2p.i2ptunnel.web.messages";
|
||||
private final I2PAppContext _context;
|
||||
|
||||
public Messages() {
|
||||
_context = I2PAppContext.getGlobalContext();
|
||||
}
|
||||
|
||||
/** lang in routerconsole.lang property, else current locale */
|
||||
public String _(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 _(String s, Object o) {
|
||||
return Translate.getString(s, o, _context, BUNDLE_NAME);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.EditBean" id="editBean" scope="request" />
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />
|
||||
<% String tun = request.getParameter("tunnel");
|
||||
int curTunnel = -1;
|
||||
if (tun != null) {
|
||||
@ -13,7 +14,7 @@
|
||||
%>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>I2P Tunnel Manager - Edit</title>
|
||||
<title><%=intl._("I2P Tunnel Manager - Edit Client Tunnel")%></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
|
||||
|
||||
@ -205,9 +206,9 @@
|
||||
</div>
|
||||
<div id="depthField" class="rowItem">
|
||||
<label for="tunnelDepth" accesskey="t">
|
||||
Dep<span class="accessKey">t</span>h:
|
||||
Leng<span class="accessKey">t</span>h:
|
||||
</label>
|
||||
<select id="tunnelDepth" name="tunnelDepth" title="Depth of each Tunnel" class="selectbox">
|
||||
<select id="tunnelDepth" name="tunnelDepth" title="Length of each Tunnel" class="selectbox">
|
||||
<% int tunnelDepth = editBean.getTunnelDepth(curTunnel, 2);
|
||||
%><option value="0"<%=(tunnelDepth == 0 ? " selected=\"selected\"" : "") %>>0 hop tunnel (low anonymity, low latency)</option>
|
||||
<option value="1"<%=(tunnelDepth == 1 ? " selected=\"selected\"" : "") %>>1 hop tunnel (medium anonymity, medium latency)</option>
|
||||
@ -222,7 +223,7 @@
|
||||
<label for="tunnelVariance" accesskey="v">
|
||||
<span class="accessKey">V</span>ariance:
|
||||
</label>
|
||||
<select id="tunnelVariance" name="tunnelVariance" title="Level of Randomization for Tunnel Depth" class="selectbox">
|
||||
<select id="tunnelVariance" name="tunnelVariance" title="Level of Randomization for Tunnel Length" class="selectbox">
|
||||
<% int tunnelVariance = editBean.getTunnelVariance(curTunnel, 0);
|
||||
%><option value="0"<%=(tunnelVariance == 0 ? " selected=\"selected\"" : "") %>>0 hop variance (no randomisation, consistant performance)</option>
|
||||
<option value="1"<%=(tunnelVariance == 1 ? " selected=\"selected\"" : "") %>>+ 0-1 hop variance (medium additive randomisation, subtractive performance)</option>
|
||||
|
@ -1,6 +1,7 @@
|
||||
<%@page contentType="text/html" import="net.i2p.i2ptunnel.web.EditBean"%><?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.EditBean" id="editBean" scope="request" />
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />
|
||||
<% String tun = request.getParameter("tunnel");
|
||||
int curTunnel = -1;
|
||||
if (tun != null) {
|
||||
@ -13,7 +14,7 @@
|
||||
%>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>I2P Tunnel Manager - Edit</title>
|
||||
<title><%=intl._("I2P Tunnel Manager - Edit Server Tunnel")%></title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
|
||||
|
||||
@ -172,9 +173,9 @@
|
||||
</div>
|
||||
<div id="depthField" class="rowItem">
|
||||
<label for="tunnelDepth" accesskey="t">
|
||||
Dep<span class="accessKey">t</span>h:
|
||||
Leng<span class="accessKey">t</span>h:
|
||||
</label>
|
||||
<select id="tunnelDepth" name="tunnelDepth" title="Depth of each Tunnel" class="selectbox">
|
||||
<select id="tunnelDepth" name="tunnelDepth" title="Length of each Tunnel" class="selectbox">
|
||||
<% int tunnelDepth = editBean.getTunnelDepth(curTunnel, 2);
|
||||
%><option value="0"<%=(tunnelDepth == 0 ? " selected=\"selected\"" : "") %>>0 hop tunnel (low anonymity, low latency)</option>
|
||||
<option value="1"<%=(tunnelDepth == 1 ? " selected=\"selected\"" : "") %>>1 hop tunnel (medium anonymity, medium latency)</option>
|
||||
|
@ -8,9 +8,10 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.IndexBean" id="indexBean" scope="request" />
|
||||
<jsp:setProperty name="indexBean" property="*" />
|
||||
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>I2P Tunnel Manager - List</title>
|
||||
<title><%=intl._("I2P Tunnel Manager - List")%></title>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
|
||||
|
30
apps/i2ptunnel/locale/messages_de.po
Normal file
30
apps/i2ptunnel/locale/messages_de.po
Normal file
@ -0,0 +1,30 @@
|
||||
# I2P
|
||||
# Copyright (C) 2009 The I2P Project
|
||||
# This file is distributed under the same license as the i2ptunnel package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
# foo <foo@bar>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P i2ptunnel\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-12-10 00:50+0000\n"
|
||||
"PO-Revision-Date: 2009-10-19 12:50+0000\n"
|
||||
"Last-Translator: foo <foo@bar>\n"
|
||||
"Language-Team: foo <foo@bar>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: German\n"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:73
|
||||
msgid "I2P Tunnel Manager - Edit Client Tunnel"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:73
|
||||
msgid "I2P Tunnel Manager - Edit Server Tunnel"
|
||||
msgstr ""
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:71
|
||||
msgid "I2P Tunnel Manager - List"
|
||||
msgstr ""
|
31
apps/i2ptunnel/locale/messages_ru.po
Normal file
31
apps/i2ptunnel/locale/messages_ru.po
Normal file
@ -0,0 +1,31 @@
|
||||
# I2P
|
||||
# Copyright (C) 2009 The I2P Project
|
||||
# This file is distributed under the same license as the i2ptunnel package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
# foo <foo@bar>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P i2ptunnel\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-12-10 00:50+0000\n"
|
||||
"PO-Revision-Date: 2009-12-14 11:51+0000\n"
|
||||
"Last-Translator: 4get <forget@mail.i2p>\n"
|
||||
"Language-Team: foo <foo@bar>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Russian\n"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:73
|
||||
msgid "I2P Tunnel Manager - Edit Client Tunnel"
|
||||
msgstr "Менеджер Туннелей I2P — Редактирование Клиентского Туннеля"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:73
|
||||
msgid "I2P Tunnel Manager - Edit Server Tunnel"
|
||||
msgstr "Менеджер Туннелей I2P — Редактирование Серверного Туннеля"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:71
|
||||
msgid "I2P Tunnel Manager - List"
|
||||
msgstr "Менеджер Туннелей I2P — Список"
|
||||
|
@ -89,7 +89,7 @@
|
||||
<!-- jar again to get the latest messages_*.class files -->
|
||||
<jar destfile="./build/routerconsole.jar" basedir="./build/obj" includes="**/*.class" update="true" />
|
||||
</target>
|
||||
<target name="poupdate" depends="compile">
|
||||
<target name="poupdate" depends="build">
|
||||
<ant target="war" />
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
|
@ -104,7 +104,7 @@ do
|
||||
echo "Generating ${CLASS}_$LG ResourceBundle..."
|
||||
|
||||
# convert to class files in build/obj
|
||||
msgfmt --java -r $CLASS -l $LG -d build/obj $i
|
||||
msgfmt --java --statistics -r $CLASS -l $LG -d build/obj $i
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo 'Warning - msgfmt failed, not updating translations'
|
||||
|
@ -232,7 +232,7 @@ public class ConfigNetHandler extends FormHandler {
|
||||
|
||||
if (_requireIntroductions) {
|
||||
_context.router().setConfigSetting(UDPTransport.PROP_FORCE_INTRODUCERS, "true");
|
||||
addFormNotice(_("Requiring SSU introduers"));
|
||||
addFormNotice(_("Requiring SSU introducers"));
|
||||
} else {
|
||||
_context.router().removeConfigSetting(UDPTransport.PROP_FORCE_INTRODUCERS);
|
||||
}
|
||||
@ -256,24 +256,26 @@ public class ConfigNetHandler extends FormHandler {
|
||||
if (switchRequired) {
|
||||
hiddenSwitch();
|
||||
} else if (restartRequired) {
|
||||
// Wow this dumps all conns immediately and really isn't nice
|
||||
//addFormNotice("Performing a soft restart");
|
||||
//_context.router().restart();
|
||||
//addFormNotice("Soft restart complete");
|
||||
if (System.getProperty("wrapper.version") == null) {
|
||||
// Wow this dumps all conns immediately and really isn't nice
|
||||
addFormNotice("Performing a soft restart");
|
||||
_context.router().restart();
|
||||
addFormNotice("Soft restart complete");
|
||||
|
||||
// Most of the time we aren't changing addresses, just enabling or disabling
|
||||
// things, so let's try just a new routerInfo and see how that works.
|
||||
// Maybe we should restart if we change addresses though?
|
||||
// No, this doesn't work well, really need to call SSU Transport externalAddressReceived(),
|
||||
// but that's hard to get to, and doesn't handle port changes, etc.
|
||||
// So don't do this...
|
||||
//_context.router().rebuildRouterInfo();
|
||||
//addFormNotice("Router Info rebuilt");
|
||||
|
||||
// There's a few changes that don't really require restart (e.g. enabling inbound TCP)
|
||||
// But it would be hard to get right, so just do a restart.
|
||||
addFormError(_("Gracefully restarting I2P to change published router address"));
|
||||
_context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
|
||||
// Most of the time we aren't changing addresses, just enabling or disabling
|
||||
// things, so let's try just a new routerInfo and see how that works.
|
||||
// Maybe we should restart if we change addresses though?
|
||||
// No, this doesn't work well, really need to call SSU Transport externalAddressReceived(),
|
||||
// but that's hard to get to, and doesn't handle port changes, etc.
|
||||
// So don't do this...
|
||||
//_context.router().rebuildRouterInfo();
|
||||
//addFormNotice("Router Info rebuilt");
|
||||
} else {
|
||||
// There's a few changes that don't really require restart (e.g. enabling inbound TCP)
|
||||
// But it would be hard to get right, so just do a restart.
|
||||
addFormError(_("Gracefully restarting I2P to change published router address"));
|
||||
_context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,12 @@ public class ConfigRestartBean {
|
||||
long timeRemaining = ctx.router().getShutdownTimeRemaining();
|
||||
StringBuilder buf = new StringBuilder(128);
|
||||
if ((shuttingDown || restarting) && timeRemaining <= 0) {
|
||||
buf.append("<center><b>").append(_("Shutdown imminent", ctx)).append("</b></center>");
|
||||
buf.append("<center><b>");
|
||||
if (restarting)
|
||||
buf.append(_("Restart imminent", ctx));
|
||||
else
|
||||
buf.append(_("Shutdown imminent", ctx));
|
||||
buf.append("</b></center>");
|
||||
} else if (shuttingDown) {
|
||||
buf.append("<center><b>");
|
||||
buf.append(_("Shutdown in {0}", DataHelper.formatDuration(timeRemaining), ctx));
|
||||
|
@ -84,7 +84,7 @@ public class ConfigTunnelsHelper extends HelperBase {
|
||||
// buf.append("<tr><th></th><th>Inbound</th><th>Outbound</th></tr>\n");
|
||||
|
||||
// tunnel depth
|
||||
buf.append("<tr><td align=\"right\" class=\"mediumtags\">" + _("Depth") + ":</td>\n");
|
||||
buf.append("<tr><td align=\"right\" class=\"mediumtags\">" + _("Length") + ":</td>\n");
|
||||
buf.append("<td align=\"center\"><select name=\"").append(index).append(".depthInbound\">\n");
|
||||
int now = in.getLength();
|
||||
renderOptions(buf, 0, MAX_LENGTH, now, "", HOP);
|
||||
|
@ -36,10 +36,10 @@ public class ConfigUIHelper extends HelperBase {
|
||||
return rv;
|
||||
}
|
||||
|
||||
private static final String langs[] = {"de", "en", "fr", "nl", "se", "zh"};
|
||||
private static final String flags[] = {"de", "us", "fr", "nl", "se", "cn"};
|
||||
private static final String langs[] = {"de", "en", "fr", "nl", "ru", "sv", "zh"};
|
||||
private static final String flags[] = {"de", "us", "fr", "nl", "ru", "se", "cn"};
|
||||
private static final String xlangs[] = {_x("German"), _x("English"), _x("French"),
|
||||
_x("Dutch"), _x("Swedish"), _x("Chinese")};
|
||||
_x("Dutch"), _x("Russian"), _x("Swedish"), _x("Chinese")};
|
||||
|
||||
/** todo sort by translated string */
|
||||
public String getLangSettings() {
|
||||
|
@ -34,7 +34,7 @@ public class LogsHelper extends HelperBase {
|
||||
return "";
|
||||
else {
|
||||
str = str.replaceAll("<", "<").replaceAll(">", ">");
|
||||
return "Location:<b><code> " + f.getAbsolutePath() + "</code></b> <pre>" + str + "</pre>";
|
||||
return _("File location") + ":<b><code> " + f.getAbsolutePath() + "</code></b> <pre>" + str + "</pre>";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,65 +1,17 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.MissingResourceException;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.ConcurrentHashSet;
|
||||
import net.i2p.util.Translate;
|
||||
|
||||
/**
|
||||
* Translate strings efficiently.
|
||||
* We don't include an English or default ResourceBundle, we simply check
|
||||
* for "en" and return the original string.
|
||||
* Support real-time language changing with the routerconsole.lang property.
|
||||
*
|
||||
* @author zzz, from a base generated by eclipse.
|
||||
* Translate strings for this package.
|
||||
*/
|
||||
public class Messages {
|
||||
public static final String PROP_LANG = "routerconsole.lang";
|
||||
public class Messages extends Translate {
|
||||
private static final String BUNDLE_NAME = "net.i2p.router.web.messages";
|
||||
private static final String _localeLang = Locale.getDefault().getLanguage();
|
||||
private static final Map<String, ResourceBundle> _bundles = new ConcurrentHashMap(2);
|
||||
private static final Set<String> _missing = new ConcurrentHashSet(2);
|
||||
/** use to look for untagged strings */
|
||||
private static final String TEST_LANG = "xx";
|
||||
private static final String TEST_STRING = "XXXX";
|
||||
|
||||
/** current locale **/
|
||||
/* unused
|
||||
public static String getString(String key) {
|
||||
if (_localeLang.equals("en"))
|
||||
return key;
|
||||
ResourceBundle bundle = findBundle(_localeLang);
|
||||
if (bundle == null)
|
||||
return key;
|
||||
try {
|
||||
return bundle.getString(key);
|
||||
} catch (MissingResourceException e) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/** lang in routerconsole.lang property, else current locale */
|
||||
public static String getString(String key, I2PAppContext ctx) {
|
||||
String lang = getLanguage(ctx);
|
||||
if (lang.equals("en"))
|
||||
return key;
|
||||
else if (lang.equals(TEST_LANG))
|
||||
return TEST_STRING;
|
||||
ResourceBundle bundle = findBundle(lang);
|
||||
if (bundle == null)
|
||||
return key;
|
||||
try {
|
||||
return bundle.getString(key);
|
||||
} catch (MissingResourceException e) {
|
||||
return key;
|
||||
}
|
||||
return Translate.getString(key, ctx, BUNDLE_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,45 +27,6 @@ public class Messages {
|
||||
* Use autoboxing to call with ints, longs, floats, etc.
|
||||
*/
|
||||
public static String getString(String s, Object o, I2PAppContext ctx) {
|
||||
String lang = getLanguage(ctx);
|
||||
if (lang.equals(TEST_LANG))
|
||||
return TEST_STRING + '(' + o + ')' + TEST_STRING;
|
||||
String x = getString(s, ctx);
|
||||
Object[] oArray = new Object[1];
|
||||
oArray[0] = o;
|
||||
try {
|
||||
MessageFormat fmt = new MessageFormat(x, new Locale(lang));
|
||||
return fmt.format(oArray, new StringBuffer(), null).toString();
|
||||
} catch (IllegalArgumentException iae) {
|
||||
System.err.println("Bad format: orig: \"" + s +
|
||||
"\" trans: \"" + x +
|
||||
"\" param: \"" + o +
|
||||
"\" lang: " + lang);
|
||||
return "FIXME: " + x + ' ' + o;
|
||||
}
|
||||
}
|
||||
|
||||
public static String getLanguage(I2PAppContext ctx) {
|
||||
String lang = ctx.getProperty(PROP_LANG);
|
||||
if (lang == null || lang.length() <= 0)
|
||||
lang = _localeLang;
|
||||
return lang;
|
||||
}
|
||||
|
||||
/** cache both found and not found for speed */
|
||||
private static ResourceBundle findBundle(String lang) {
|
||||
ResourceBundle rv = _bundles.get(lang);
|
||||
if (rv == null && !_missing.contains(lang)) {
|
||||
try {
|
||||
// Would it be faster to specify a class loader?
|
||||
// No matter we only do this once per lang.
|
||||
rv = ResourceBundle.getBundle(BUNDLE_NAME, new Locale(lang));
|
||||
if (rv != null)
|
||||
_bundles.put(lang, rv);
|
||||
} catch (MissingResourceException e) {
|
||||
_missing.add(lang);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
return Translate.getString(s, o, ctx, BUNDLE_NAME);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
|
||||
public class NetDbHelper extends HelperBase {
|
||||
private String _routerPrefix;
|
||||
@ -12,7 +13,11 @@ public class NetDbHelper extends HelperBase {
|
||||
|
||||
public NetDbHelper() {}
|
||||
|
||||
public void setRouter(String r) { _routerPrefix = r; }
|
||||
public void setRouter(String r) {
|
||||
if (r != null)
|
||||
_routerPrefix = DataHelper.stripHTML(r); // XSS
|
||||
}
|
||||
|
||||
public void setFull(String f) {
|
||||
try {
|
||||
_full = Integer.parseInt(f);
|
||||
|
@ -179,7 +179,7 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
if (get.fetch()) {
|
||||
String lastmod = get.getLastModified();
|
||||
if (lastmod != null) {
|
||||
if (!(_context instanceof RouterContext)) return;
|
||||
if (!(_context.isRouterContext())) return;
|
||||
long modtime = parse822Date(lastmod);
|
||||
if (modtime <= 0) return;
|
||||
String lastUpdate = _context.getProperty(UpdateHandler.PROP_LAST_UPDATE_TIME);
|
||||
@ -310,7 +310,7 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Policy requests update, so we update");
|
||||
UpdateHandler handler = null;
|
||||
if (_context instanceof RouterContext) {
|
||||
if (_context.isRouterContext()) {
|
||||
handler = new UpdateHandler((RouterContext)_context);
|
||||
} else {
|
||||
List contexts = RouterContext.listContexts();
|
||||
|
@ -32,7 +32,7 @@ class ProfileOrganizerRenderer {
|
||||
_organizer = organizer;
|
||||
_comparator = new ProfileComparator();
|
||||
}
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
public void renderStatusHTML(Writer out, boolean full) throws IOException {
|
||||
Set peers = _organizer.selectAllPeers();
|
||||
|
||||
long now = _context.clock().now();
|
||||
@ -40,18 +40,27 @@ class ProfileOrganizerRenderer {
|
||||
|
||||
TreeSet order = new TreeSet(_comparator);
|
||||
TreeSet integratedPeers = new TreeSet(_comparator);
|
||||
int older = 0;
|
||||
int standard = 0;
|
||||
for (Iterator iter = peers.iterator(); iter.hasNext();) {
|
||||
Hash peer = (Hash)iter.next();
|
||||
if (_organizer.getUs().equals(peer)) continue;
|
||||
PeerProfile prof = _organizer.getProfile(peer);
|
||||
if (_organizer.isWellIntegrated(peer)) {
|
||||
integratedPeers.add(prof);
|
||||
} else {
|
||||
//if (_organizer.isWellIntegrated(peer)) {
|
||||
// integratedPeers.add(prof);
|
||||
//} else {
|
||||
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
|
||||
if (info != null && info.getCapabilities().indexOf("f") >= 0)
|
||||
integratedPeers.add(prof);
|
||||
//}
|
||||
if (prof.getLastSendSuccessful() <= hideBefore) {
|
||||
older++;
|
||||
continue;
|
||||
}
|
||||
if ((!full) && !_organizer.isHighCapacity(peer)) {
|
||||
standard++;
|
||||
continue;
|
||||
}
|
||||
if (prof.getLastSendSuccessful() <= hideBefore) continue;
|
||||
order.add(prof);
|
||||
}
|
||||
|
||||
@ -62,7 +71,10 @@ class ProfileOrganizerRenderer {
|
||||
StringBuilder buf = new StringBuilder(16*1024);
|
||||
buf.append("<h2>").append(_("Peer Profiles")).append("</h2>\n<p>");
|
||||
buf.append(_("Showing {0} recent profiles.", order.size())).append('\n');
|
||||
buf.append(_("Hiding {0} older profiles.", peers.size()-order.size()));
|
||||
if (older > 0)
|
||||
buf.append(_("Hiding {0} older profiles.", older)).append('\n');
|
||||
if (standard > 0)
|
||||
buf.append("<a href=\"/profiles.jsp?f=1\">").append(_("Hiding {0} standard profiles.", standard)).append("</a>\n");
|
||||
buf.append("</p>");
|
||||
buf.append("<table>");
|
||||
buf.append("<tr>");
|
||||
@ -169,7 +181,7 @@ class ProfileOrganizerRenderer {
|
||||
}
|
||||
buf.append("</table>");
|
||||
|
||||
buf.append("<h2>").append(_("Floodfill and Integrated Peers")).append("</h2>\n");
|
||||
buf.append("<h2><a name=\"flood\"></a>").append(_("Floodfill and Integrated Peers")).append("</h2>\n");
|
||||
buf.append("<table>");
|
||||
buf.append("<tr>");
|
||||
buf.append("<th class=\"smallhead\">").append(_("Peer")).append("</th>");
|
||||
@ -231,6 +243,7 @@ class ProfileOrganizerRenderer {
|
||||
for (int i = 0; i < 6; i++)
|
||||
buf.append("<td align=\"right\">").append(_(NA));
|
||||
}
|
||||
buf.append("</tr>\n");
|
||||
}
|
||||
buf.append("</table>");
|
||||
|
||||
@ -324,12 +337,15 @@ class ProfileOrganizerRenderer {
|
||||
private String davg (DBHistory dbh, long rate) {
|
||||
RateStat rs = dbh.getFailedLookupRate();
|
||||
if (rs == null)
|
||||
return _(NA);
|
||||
return "0%";
|
||||
Rate r = rs.getRate(rate);
|
||||
if (r == null)
|
||||
return _(NA);
|
||||
return "0%";
|
||||
long c = r.getCurrentEventCount() + r.getLastEventCount();
|
||||
return "" + c;
|
||||
if (c <= 0)
|
||||
return "0%";
|
||||
double avg = 0.5 + 100 * (r.getCurrentTotalValue() + r.getLastTotalValue()) / c;
|
||||
return ((int) avg) + "%";
|
||||
}
|
||||
|
||||
/** translate a string */
|
||||
|
@ -4,13 +4,19 @@ import java.io.IOException;
|
||||
|
||||
|
||||
public class ProfilesHelper extends HelperBase {
|
||||
private boolean _full;
|
||||
|
||||
public ProfilesHelper() {}
|
||||
|
||||
public void setFull(String f) {
|
||||
_full = f != null;
|
||||
}
|
||||
|
||||
/** @return empty string, writes directly to _out */
|
||||
public String getProfileSummary() {
|
||||
try {
|
||||
ProfileOrganizerRenderer rend = new ProfileOrganizerRenderer(_context.profileOrganizer(), _context);
|
||||
rend.renderStatusHTML(_out);
|
||||
rend.renderStatusHTML(_out, _full);
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
@ -20,6 +21,7 @@ import org.mortbay.http.SecurityConstraint;
|
||||
import org.mortbay.http.handler.SecurityHandler;
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.servlet.WebApplicationContext;
|
||||
import org.mortbay.jetty.servlet.WebApplicationHandler;
|
||||
|
||||
public class RouterConsoleRunner {
|
||||
private Server _server;
|
||||
@ -87,6 +89,8 @@ public class RouterConsoleRunner {
|
||||
if (!_webAppsDir.endsWith("/"))
|
||||
_webAppsDir += '/';
|
||||
|
||||
List<String> notStarted = new ArrayList();
|
||||
WebApplicationHandler baseHandler = null;
|
||||
try {
|
||||
StringTokenizer tok = new StringTokenizer(_listenHost, " ,");
|
||||
int boundAddresses = 0;
|
||||
@ -111,7 +115,8 @@ public class RouterConsoleRunner {
|
||||
File tmpdir = new File(workDir, ROUTERCONSOLE + "-" + _listenPort);
|
||||
tmpdir.mkdir();
|
||||
wac.setTempDirectory(tmpdir);
|
||||
wac.addHandler(0, new LocaleWebAppHandler(I2PAppContext.getGlobalContext()));
|
||||
baseHandler = new LocaleWebAppHandler(I2PAppContext.getGlobalContext());
|
||||
wac.addHandler(0, baseHandler);
|
||||
initialize(wac);
|
||||
File dir = new File(_webAppsDir);
|
||||
String fileNames[] = dir.list(WarFilenameFilter.instance());
|
||||
@ -132,6 +137,8 @@ public class RouterConsoleRunner {
|
||||
props.setProperty(PREFIX + appName + ENABLED, "true");
|
||||
rewrite = true;
|
||||
}
|
||||
} else {
|
||||
notStarted.add(appName);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
System.err.println("Error resolving '" + fileNames[i] + "' in '" + dir);
|
||||
@ -154,6 +161,19 @@ public class RouterConsoleRunner {
|
||||
"\"::1,\" in the \"clientApp.0.args\" line of the clients.config file.\n" +
|
||||
"Exception: " + me);
|
||||
}
|
||||
|
||||
if (baseHandler != null) {
|
||||
// map each not-started webapp to the error page
|
||||
for (int i = 0; i < notStarted.size(); i++) {
|
||||
try {
|
||||
baseHandler.mapPathToServlet('/' + notStarted.get(i) + "/*",
|
||||
"net.i2p.router.web.jsp.nowebapp_jsp");
|
||||
} catch (Throwable me) {
|
||||
System.err.println(me);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
SysTray tray = SysTray.getInstance();
|
||||
} catch (Throwable t) {
|
||||
|
@ -40,7 +40,7 @@ public class StatsGenerator {
|
||||
String group = (String)entry.getKey();
|
||||
Set stats = (Set)entry.getValue();
|
||||
buf.append("<option value=\"/stats.jsp#").append(group).append("\">");
|
||||
buf.append(group).append("</option>\n");
|
||||
buf.append(_(group)).append("</option>\n");
|
||||
for (Iterator statIter = stats.iterator(); statIter.hasNext(); ) {
|
||||
String stat = (String)statIter.next();
|
||||
buf.append("<option value=\"/stats.jsp#");
|
||||
@ -52,7 +52,7 @@ public class StatsGenerator {
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
}
|
||||
buf.append("</select> <input type=\"submit\" value=\"GO\" />");
|
||||
buf.append("</select> <input type=\"submit\" value=\"").append(_("GO")).append("\" />");
|
||||
buf.append("</form>");
|
||||
|
||||
buf.append(_("Statistics gathered during this router's uptime")).append(" (");
|
||||
@ -69,7 +69,7 @@ public class StatsGenerator {
|
||||
buf.append("<h3><a name=\"");
|
||||
buf.append(group);
|
||||
buf.append("\">");
|
||||
buf.append(group);
|
||||
buf.append(_(group));
|
||||
buf.append("</a></h3>");
|
||||
buf.append("<ul>");
|
||||
out.write(buf.toString());
|
||||
@ -88,7 +88,7 @@ public class StatsGenerator {
|
||||
out.write(buf.toString());
|
||||
buf.setLength(0);
|
||||
}
|
||||
out.write("</ul><br>");
|
||||
out.write("</ul><br>\n");
|
||||
}
|
||||
out.flush();
|
||||
}
|
||||
@ -104,7 +104,7 @@ public class StatsGenerator {
|
||||
for (int i = 0; i < periods.length; i++) {
|
||||
if (periods[i] > uptime)
|
||||
break;
|
||||
renderPeriod(buf, periods[i], "frequency");
|
||||
renderPeriod(buf, periods[i], _("frequency"));
|
||||
Frequency curFreq = freq.getFrequency(periods[i]);
|
||||
buf.append(" <i>avg per period:</i> (");
|
||||
buf.append(num(curFreq.getAverageEventsPerPeriod()));
|
||||
@ -124,9 +124,9 @@ public class StatsGenerator {
|
||||
buf.append(" using the lifetime of ");
|
||||
buf.append(curFreq.getEventCount());
|
||||
buf.append(" events)");
|
||||
buf.append("<br>");
|
||||
buf.append("<br>\n");
|
||||
}
|
||||
buf.append("<br>");
|
||||
buf.append("<br>\n");
|
||||
}
|
||||
|
||||
private void renderRate(String name, StringBuilder buf) {
|
||||
@ -138,7 +138,7 @@ public class StatsGenerator {
|
||||
buf.append("</i><br>");
|
||||
}
|
||||
if (rate.getLifetimeEventCount() <= 0) {
|
||||
buf.append("No lifetime events<br>");
|
||||
buf.append(_("No lifetime events")).append("<br>\n");
|
||||
return;
|
||||
}
|
||||
long now = _context.clock().now();
|
||||
@ -150,9 +150,9 @@ public class StatsGenerator {
|
||||
if (curRate.getLastCoalesceDate() <= curRate.getCreationDate())
|
||||
break;
|
||||
buf.append("<li>");
|
||||
renderPeriod(buf, periods[i], "rate");
|
||||
renderPeriod(buf, periods[i], _("rate"));
|
||||
if (curRate.getLastEventCount() > 0) {
|
||||
buf.append( "<i>avg value:</i> (");
|
||||
buf.append( "<i>").append(_("avg value")).append(":</i> (");
|
||||
buf.append(num(curRate.getAverageValue()));
|
||||
buf.append(" peak ");
|
||||
buf.append(num(curRate.getExtremeAverageValue()));
|
||||
@ -181,21 +181,21 @@ public class StatsGenerator {
|
||||
buf.append(num(curRate.getExtremeSaturationLimit()));
|
||||
buf.append(")");
|
||||
}
|
||||
buf.append(" <i>events:</i> ");
|
||||
buf.append(" <i>").append(_("events")).append(":</i> ");
|
||||
buf.append(curRate.getLastEventCount());
|
||||
buf.append(" <i>in this period which ended:</i> ");
|
||||
buf.append(DataHelper.formatDuration(now - curRate.getLastCoalesceDate()));
|
||||
buf.append(" ago ");
|
||||
} else {
|
||||
buf.append(" <i>No events</i> ");
|
||||
buf.append(" <i>").append(_("No events")).append("</i> ");
|
||||
}
|
||||
long numPeriods = curRate.getLifetimePeriods();
|
||||
if (numPeriods > 0) {
|
||||
double avgFrequency = curRate.getLifetimeEventCount() / (double)numPeriods;
|
||||
double peakFrequency = curRate.getExtremeEventCount();
|
||||
buf.append(" (lifetime average: ");
|
||||
buf.append(" (").append(_("lifetime average")).append(": ");
|
||||
buf.append(num(avgFrequency));
|
||||
buf.append(", peak average: ");
|
||||
buf.append(", ").append(_("peak average")).append(": ");
|
||||
buf.append(curRate.getExtremeEventCount());
|
||||
buf.append(")");
|
||||
}
|
||||
@ -210,16 +210,16 @@ public class StatsGenerator {
|
||||
buf.append("&format=xml\" title=\"Dump stat history as XML\">XML</a>");
|
||||
buf.append(" in a format <a href=\"http://people.ee.ethz.ch/~oetiker/webtools/rrdtool\">RRDTool</a> understands)");
|
||||
}
|
||||
buf.append("</li>");
|
||||
buf.append("</li>\n");
|
||||
}
|
||||
// Display the strict average
|
||||
buf.append("<li><b>lifetime average value:</b> ");
|
||||
buf.append("<li><b>").append(_("lifetime average value")).append(":</b> ");
|
||||
buf.append(num(rate.getLifetimeAverageValue()));
|
||||
buf.append(" over ");
|
||||
buf.append(rate.getLifetimeEventCount());
|
||||
buf.append(" events<br></li>");
|
||||
buf.append("</ul>");
|
||||
buf.append("<br>");
|
||||
buf.append("<br>\n");
|
||||
}
|
||||
|
||||
private static void renderPeriod(StringBuilder buf, long period, String name) {
|
||||
@ -240,4 +240,9 @@ public class StatsGenerator {
|
||||
private String _(String s) {
|
||||
return Messages.getString(s, _context);
|
||||
}
|
||||
|
||||
/** translate a string */
|
||||
private String _(String s, Object o) {
|
||||
return Messages.getString(s, o, _context);
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,14 @@ public class SummaryBarRenderer {
|
||||
_helper = helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note - ensure all links in here are absolute, as the summary bar may be displayed
|
||||
* on lower-level directory errors.
|
||||
*/
|
||||
public void renderSummaryHTML(Writer out) throws IOException {
|
||||
StringBuilder buf = new StringBuilder(8*1024);
|
||||
|
||||
buf.append("<a href=\"index.jsp\" target=\"_top\"><img src=\"/themes/console/images/i2plogo.png\" alt=\"")
|
||||
buf.append("<a href=\"/index.jsp\" target=\"_top\"><img src=\"/themes/console/images/i2plogo.png\" alt=\"")
|
||||
.append(_("I2P Router Console"))
|
||||
.append("\" title=\"")
|
||||
.append(_("I2P Router Console"))
|
||||
@ -44,19 +48,19 @@ public class SummaryBarRenderer {
|
||||
|
||||
"<hr><table>" +
|
||||
|
||||
"<tr><td><a href=\"susidns/index.jsp\" target=\"_blank\" title=\"")
|
||||
"<tr><td><a href=\"/susidns/index.jsp\" target=\"_blank\" title=\"")
|
||||
.append(_("Manage your I2P hosts file here (I2P domain name resolution)"))
|
||||
.append("\">")
|
||||
.append(_("Addressbook"))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"i2psnark/\" target=\"_blank\" title=\"")
|
||||
"<a href=\"/i2psnark/\" target=\"_blank\" title=\"")
|
||||
.append(_("Built-in anonymous BitTorrent Client"))
|
||||
.append("\">")
|
||||
.append(_("Torrents"))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"susimail/susimail\" target=\"blank\" title=\"")
|
||||
"<a href=\"/susimail/susimail\" target=\"blank\" title=\"")
|
||||
.append(_("Anonymous webmail client"))
|
||||
.append("\">")
|
||||
.append(_("Webmail"))
|
||||
@ -68,7 +72,7 @@ public class SummaryBarRenderer {
|
||||
.append(_("Webserver"))
|
||||
.append("</a></td></tr></table>\n" +
|
||||
|
||||
"<hr><h3><a href=\"config.jsp\" target=\"_top\" title=\"")
|
||||
"<hr><h3><a href=\"/config.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("Configure I2P Router"))
|
||||
.append("\">")
|
||||
.append(_("I2P Internals"))
|
||||
@ -76,49 +80,49 @@ public class SummaryBarRenderer {
|
||||
|
||||
"<table><tr><td>\n" +
|
||||
|
||||
"<a href=\"tunnels.jsp\" target=\"_top\" title=\"")
|
||||
"<a href=\"/tunnels.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("View existing tunnels and tunnel build status"))
|
||||
.append("\">")
|
||||
.append(_("Tunnels"))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"peers.jsp\" target=\"_top\" title=\"")
|
||||
"<a href=\"/peers.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("Show all current peer connections"))
|
||||
.append("\">")
|
||||
.append(_("Peers"))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"profiles.jsp\" target=\"_top\" title=\"")
|
||||
"<a href=\"/profiles.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("Show recent peer performance profiles"))
|
||||
.append("\">")
|
||||
.append(_("Profiles"))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"netdb.jsp\" target=\"_top\" title=\"")
|
||||
"<a href=\"/netdb.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("Show list of all known I2P routers"))
|
||||
.append("\">")
|
||||
.append(_("NetDB"))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"logs.jsp\" target=\"_top\" title=\"")
|
||||
"<a href=\"/logs.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("Health Report"))
|
||||
.append("\">")
|
||||
.append(_("Logs"))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"jobs.jsp\" target=\"_top\" title=\"")
|
||||
"<a href=\"/jobs.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("Show the router's workload, and how it's performing"))
|
||||
.append("\">")
|
||||
.append(_("Jobs"))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"graphs.jsp\" target=\"_top\" title=\"")
|
||||
"<a href=\"/graphs.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("Graph router performance"))
|
||||
.append("\">")
|
||||
.append(_("Graphs"))
|
||||
.append("</a>\n" +
|
||||
|
||||
"<a href=\"stats.jsp\" target=\"_top\" title=\"")
|
||||
"<a href=\"/stats.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("Textual router performance statistics"))
|
||||
.append("\">")
|
||||
.append(_("Stats"))
|
||||
@ -130,7 +134,7 @@ public class SummaryBarRenderer {
|
||||
|
||||
|
||||
|
||||
buf.append("<hr><h3><a href=\"help.jsp\" target=\"_top\" title=\"")
|
||||
buf.append("<hr><h3><a href=\"/help.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("I2P Router Help"))
|
||||
.append("\">")
|
||||
.append(_("General"))
|
||||
@ -141,7 +145,7 @@ public class SummaryBarRenderer {
|
||||
.append(_helper.getIdent())
|
||||
.append(", ")
|
||||
.append(_("never reveal it to anyone"))
|
||||
.append("\" href=\"netdb.jsp?r=.\" target=\"_top\">")
|
||||
.append("\" href=\"/netdb.jsp?r=.\" target=\"_top\">")
|
||||
.append(_("Local Identity"))
|
||||
.append("</a></h4><hr>\n" +
|
||||
|
||||
@ -163,7 +167,7 @@ public class SummaryBarRenderer {
|
||||
.append(_helper.getUptime())
|
||||
.append("</td></tr></table>\n" +
|
||||
|
||||
"<hr><h4><a href=\"config.jsp#help\" target=\"_top\" title=\"")
|
||||
"<hr><h4><a href=\"/config.jsp#help\" target=\"_top\" title=\"")
|
||||
.append(_("Help with configuring your firewall and router for optimal I2P performance"))
|
||||
.append("\">")
|
||||
.append(_helper.getReachability())
|
||||
@ -172,7 +176,7 @@ public class SummaryBarRenderer {
|
||||
|
||||
if (_helper.updateAvailable() || _helper.unsignedUpdateAvailable()) {
|
||||
// display all the time so we display the final failure message
|
||||
buf.append("<br>").append(UpdateHandler.getStatus());
|
||||
buf.append(UpdateHandler.getStatus());
|
||||
if ("true".equals(System.getProperty("net.i2p.router.web.UpdateHandler.updateInProgress"))) {
|
||||
// nothing
|
||||
} else if(
|
||||
@ -187,7 +191,7 @@ public class SummaryBarRenderer {
|
||||
System.setProperty("net.i2p.router.web.UpdateHandler.noncePrev", prev);
|
||||
System.setProperty("net.i2p.router.web.UpdateHandler.nonce", nonce+"");
|
||||
String uri = _helper.getRequestURI();
|
||||
buf.append("<form action=\"").append(uri).append("\" method=\"GET\">\n");
|
||||
buf.append("<p><form action=\"").append(uri).append("\" method=\"GET\">\n");
|
||||
buf.append("<input type=\"hidden\" name=\"updateNonce\" value=\"").append(nonce).append("\" >\n");
|
||||
if (_helper.updateAvailable()) {
|
||||
buf.append("<button type=\"submit\" name=\"updateAction\" value=\"signed\" >")
|
||||
@ -217,7 +221,7 @@ public class SummaryBarRenderer {
|
||||
buf.append("<p>")
|
||||
.append(ConfigRestartBean.renderStatus(_helper.getRequestURI(), _helper.getAction(), _helper.getConsoleNonce()))
|
||||
|
||||
.append("</p><hr><h3><a href=\"peers.jsp\" target=\"_top\" title=\"")
|
||||
.append("</p><hr><h3><a href=\"/peers.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("Show all current peer connections"))
|
||||
.append("\">")
|
||||
.append(_("Peers"))
|
||||
@ -266,7 +270,7 @@ public class SummaryBarRenderer {
|
||||
|
||||
boolean anotherLine = false;
|
||||
if (_helper.showFirewallWarning()) {
|
||||
buf.append("<h4><a href=\"config.jsp\" target=\"_top\" title=\"")
|
||||
buf.append("<h4><a href=\"/config.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("Help with firewall configuration"))
|
||||
.append("\">")
|
||||
.append(_("Check NAT/firewall"))
|
||||
@ -305,7 +309,7 @@ public class SummaryBarRenderer {
|
||||
buf.append("<hr>");
|
||||
|
||||
|
||||
buf.append("<h3><a href=\"config.jsp\" title=\"")
|
||||
buf.append("<h3><a href=\"/config.jsp\" title=\"")
|
||||
.append(_("Configure router bandwidth allocation"))
|
||||
.append("\" target=\"_top\">")
|
||||
.append(_("Bandwidth in/out"))
|
||||
@ -340,7 +344,7 @@ public class SummaryBarRenderer {
|
||||
.append(_helper.getOutboundTransferred())
|
||||
.append("</td></tr></table>\n" +
|
||||
|
||||
"<hr><h3><a href=\"tunnels.jsp\" target=\"_top\" title=\"")
|
||||
"<hr><h3><a href=\"/tunnels.jsp\" target=\"_top\" title=\"")
|
||||
.append(_("View existing tunnels and tunnel build status"))
|
||||
.append("\">")
|
||||
.append(_("Tunnels in/out"))
|
||||
|
@ -62,6 +62,9 @@ public class SummaryHelper extends HelperBase {
|
||||
return DataHelper.formatDuration(router.getUptime());
|
||||
}
|
||||
|
||||
/**
|
||||
this displayed offset, not skew - now handled in reachability()
|
||||
|
||||
private String timeSkew() {
|
||||
if (_context == null) return "";
|
||||
//if (!_context.clock().getUpdatedSuccessfully())
|
||||
@ -72,6 +75,7 @@ public class SummaryHelper extends HelperBase {
|
||||
return "";
|
||||
return " (" + DataHelper.formatDuration(diff) + " " + _("skew") + ")";
|
||||
}
|
||||
**/
|
||||
|
||||
public boolean allowReseed() {
|
||||
return _context.netDb().isInitialized() &&
|
||||
@ -83,15 +87,20 @@ public class SummaryHelper extends HelperBase {
|
||||
public int getAllPeers() { return Math.max(_context.netDb().getKnownRouters() - 1, 0); }
|
||||
|
||||
public String getReachability() {
|
||||
return reachability() + timeSkew();
|
||||
return reachability(); // + timeSkew();
|
||||
}
|
||||
|
||||
private String reachability() {
|
||||
if (_context.router().getUptime() > 60*1000 && (!_context.router().gracefulShutdownInProgress()) &&
|
||||
!_context.clientManager().isAlive())
|
||||
return _("ERR-Client Manager I2CP Error - check logs"); // not a router problem but the user should know
|
||||
if (!_context.clock().getUpdatedSuccessfully())
|
||||
return _("ERR-ClockSkew");
|
||||
// Warn based on actual skew from peers, not update status, so if we successfully offset
|
||||
// the clock, we don't complain.
|
||||
//if (!_context.clock().getUpdatedSuccessfully())
|
||||
Long skew = _context.commSystem().getFramedAveragePeerClockSkew(33);
|
||||
// Display the actual skew, not the offset
|
||||
if (skew != null && Math.abs(skew.longValue()) > 45)
|
||||
return _("ERR-Clock Skew of {0}", DataHelper.formatDuration(Math.abs(skew.longValue()) * 1000));
|
||||
if (_context.router().isHidden())
|
||||
return _("Hidden");
|
||||
|
||||
@ -118,7 +127,9 @@ public class SummaryHelper extends HelperBase {
|
||||
default:
|
||||
ra = _context.router().getRouterInfo().getTargetAddress("SSU");
|
||||
if (ra == null && _context.router().getUptime() > 5*60*1000) {
|
||||
if (_context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME) == null ||
|
||||
if (getActivePeers() <= 0)
|
||||
return _("ERR-No Active Peers, Check Network Connection and Firewall");
|
||||
else if (_context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME) == null ||
|
||||
_context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_PORT) == null)
|
||||
return _("ERR-UDP Disabled and Inbound TCP host/port not set");
|
||||
else
|
||||
|
@ -23,6 +23,7 @@ import net.i2p.router.TunnelInfo;
|
||||
import net.i2p.router.TunnelPoolSettings;
|
||||
import net.i2p.router.tunnel.HopConfig;
|
||||
import net.i2p.router.tunnel.pool.TunnelPool;
|
||||
import net.i2p.router.CommSystemFacade;
|
||||
import net.i2p.stat.RateStat;
|
||||
import net.i2p.util.ObjectCounter;
|
||||
|
||||
@ -229,10 +230,10 @@ public class TunnelRenderer {
|
||||
Set<Hash> peers = new HashSet(lc.objects());
|
||||
peers.addAll(pc.objects());
|
||||
List<Hash> peerList = new ArrayList(peers);
|
||||
Collections.sort(peerList, new HashComparator());
|
||||
Collections.sort(peerList, new CountryComparator(this._context.commSystem()));
|
||||
|
||||
out.write("<h2><a name=\"peers\"></a>" + _("Tunnel Counts By Peer") + "</h2>\n");
|
||||
out.write("<table><tr><th>" + _("Peer") + "</th><th>" + _("Expl. + Client") + "</th><th>" + _("% of total") + "</th><th>" + _("Part. from + to") + "</th><th>" + _("% of total") + "</th></tr>\n");
|
||||
out.write("<table><tr><th>" + _("Peer") + "</th><th>" + _("Our Tunnels") + "</th><th>" + _("% of total") + "</th><th>" + _("Participating Tunnels") + "</th><th>" + _("% of total") + "</th></tr>\n");
|
||||
for (Hash h : peerList) {
|
||||
out.write("<tr> <td class=\"cells\" align=\"center\">");
|
||||
out.write(netDbLink(h));
|
||||
@ -250,7 +251,7 @@ public class TunnelRenderer {
|
||||
out.write('0');
|
||||
out.write('\n');
|
||||
}
|
||||
out.write("<tr class=\"tablefooter\"> <td align=\"center\"><b>" + _("Tunnels") + "</b> <td align=\"center\"><b>" + tunnelCount);
|
||||
out.write("<tr class=\"tablefooter\"> <td align=\"center\"><b>" + _("Totals") + "</b> <td align=\"center\"><b>" + tunnelCount);
|
||||
out.write("</b> <td> </td> <td align=\"center\"><b>" + partCount);
|
||||
out.write("</b> <td> </td></tr></table></div>\n");
|
||||
}
|
||||
@ -295,6 +296,26 @@ public class TunnelRenderer {
|
||||
return ((Hash)l).toBase64().compareTo(((Hash)r).toBase64());
|
||||
}
|
||||
}
|
||||
|
||||
private static class CountryComparator implements Comparator<Hash> {
|
||||
public CountryComparator(CommSystemFacade comm) {
|
||||
this.comm = comm;
|
||||
}
|
||||
public int compare(Hash l, Hash r) {
|
||||
// get both countries
|
||||
String lc = this.comm.getCountry(l);
|
||||
String rc = this.comm.getCountry(r);
|
||||
|
||||
// make them non-null
|
||||
lc = (lc == null) ? "zzzz" : lc;
|
||||
rc = (rc == null) ? "zzzz" : rc;
|
||||
|
||||
// let String handle the rest
|
||||
return lc.compareTo(rc);
|
||||
}
|
||||
|
||||
private CommSystemFacade comm;
|
||||
}
|
||||
|
||||
private String getCapacity(Hash peer) {
|
||||
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
|
||||
|
@ -52,5 +52,24 @@ class Dummy {
|
||||
_("dark");
|
||||
_("light");
|
||||
_("midnight");
|
||||
|
||||
// stat groups for stats.jsp
|
||||
_("Bandwidth");
|
||||
_("BandwidthLimiter");
|
||||
_("ClientMessages");
|
||||
_("Encryption");
|
||||
_("i2cp");
|
||||
_("I2PTunnel");
|
||||
_("InNetPool");
|
||||
_("JobQueue");
|
||||
_("NetworkDatabase");
|
||||
_("ntcp");
|
||||
_("Peers");
|
||||
_("Router");
|
||||
_("Stream");
|
||||
_("Throttle");
|
||||
_("Transport");
|
||||
_("Tunnels");
|
||||
_("udp");
|
||||
}
|
||||
}
|
||||
|
@ -32,15 +32,18 @@
|
||||
<div class="wideload"><p><table><tr><td><input style="text-align: right; width: 5em;" name="inboundrate" type="text" size="5" maxlength="5" value="<jsp:getProperty name="nethelper" property="inboundRate" />" />
|
||||
<%=intl._("KBps In")%>
|
||||
</td><td>(<jsp:getProperty name="nethelper" property="inboundRateBits" />)</td>
|
||||
<% /********
|
||||
<!-- let's keep this simple...
|
||||
bursting up to
|
||||
<input name="inboundburstrate" type="text" size="5" value="<jsp:getProperty name="nethelper" property="inboundBurstRate" />" /> KBps for
|
||||
<jsp:getProperty name="nethelper" property="inboundBurstFactorBox" /><br>
|
||||
-->
|
||||
*********/ %>
|
||||
</tr><tr>
|
||||
<td><input style="text-align: right; width: 5em;" name="outboundrate" type="text" size="5" maxlength="5" value="<jsp:getProperty name="nethelper" property="outboundRate" />" />
|
||||
<%=intl._("KBps Out")%>
|
||||
</td><td>(<jsp:getProperty name="nethelper" property="outboundRateBits" />)</td>
|
||||
<% /********
|
||||
<!-- let's keep this simple...
|
||||
bursting up to
|
||||
<input name="outboundburstrate" type="text" size="2" value="<jsp:getProperty name="nethelper" property="outboundBurstRate" />" /> KBps for
|
||||
@ -48,6 +51,7 @@
|
||||
<i>KBps = kilobytes per second = 1024 bytes per second = 8192 bits per second.<br>
|
||||
A negative rate sets the default.</i><br>
|
||||
-->
|
||||
*********/ %>
|
||||
</tr><tr>
|
||||
<td><jsp:getProperty name="nethelper" property="sharePercentageBox" /> <%=intl._("Share")%></td>
|
||||
<td>(<jsp:getProperty name="nethelper" property="shareRateBits" />)
|
||||
@ -121,6 +125,7 @@
|
||||
</p><p><b><%=intl._("UDP Configuration:")%></b><br>
|
||||
<%=intl._("UDP port:")%>
|
||||
<input name ="udpPort" type="text" size="5" maxlength="5" value="<jsp:getProperty name="nethelper" property="configuredUdpPort" />" /><br>
|
||||
<% /********
|
||||
<!-- let's keep this simple...
|
||||
<input type="checkbox" class="optbox" name="requireIntroductions" value="true" <jsp:getProperty name="nethelper" property="requireIntroductionsChecked" /> />
|
||||
Require SSU introductions
|
||||
@ -128,6 +133,7 @@
|
||||
</p><p>
|
||||
Current External UDP address: <i><jsp:getProperty name="nethelper" property="udpAddress" /></i><br>
|
||||
-->
|
||||
*********/ %>
|
||||
</p><p>
|
||||
<b><%=intl._("TCP Configuration")%>:</b><br>
|
||||
<%=intl._("Externally reachable hostname or IP address")%>:<br>
|
||||
@ -163,10 +169,12 @@
|
||||
<%=intl._("Most of the options above are for special situations, for example where UPnP does not work correctly, or a firewall not under your control is doing harm.")%>
|
||||
<%=intl._("Certain firewalls such as symmetric NATs may not work well with I2P.")%>
|
||||
</p>
|
||||
<% /********
|
||||
<!-- let's keep this simple...
|
||||
<input type="submit" name="recheckReachability" value="Check network reachability..." />
|
||||
</p>
|
||||
-->
|
||||
*********/ %>
|
||||
<p>
|
||||
<%=intl._("UPnP is used to communicate with Internet Gateway Devices (IGDs) to detect the external IP address and forward ports.")%>
|
||||
<%=intl._("UPnP support is beta, and may not work for any number of reasons")%>:
|
||||
|
@ -39,7 +39,7 @@ button span.hide{
|
||||
<%=intl._("All changes require restart to take effect.")%></i>
|
||||
</p><hr><div class="formaction">
|
||||
<input type="submit" name="action" value="<%=intl._("Save Client Configuration")%>" />
|
||||
</div></div><h3><%=intl._("WebApp Configuration")%></h3><p>
|
||||
</div></div><h3><a name="webapp"></a><%=intl._("WebApp Configuration")%></h3><p>
|
||||
<%=intl._("The Java web applications listed below are started by the webConsole client and run in the same JVM as the router. They are usually web applications accessible through the router console. They may be complete applications (e.g. i2psnark),front-ends to another client or application which must be separately enabled (e.g. susidns, i2ptunnel), or have no web interface at all (e.g. addressbook).")%>
|
||||
</p><p>
|
||||
<%=intl._("A web app may also be disabled by removing the .war file from the webapps directory; however the .war file and web app will reappear when you update your router to a newer version, so disabling the web app here is the preferred method.")%>
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
<% String peer = "";
|
||||
if (request.getParameter("peer") != null)
|
||||
peer = request.getParameter("peer");
|
||||
peer = net.i2p.data.DataHelper.stripHTML(request.getParameter("peer")); // XSS
|
||||
%>
|
||||
<div class="configure">
|
||||
<form action="configpeer.jsp" method="POST">
|
||||
|
@ -3,5 +3,5 @@
|
||||
<meta http-equiv="pragma" content="no-cache" />
|
||||
</head>
|
||||
<body>
|
||||
The I2P Tunnel Manager is not currently running. Please visit the<a href="/configclients.jsp">Client Configuration</a> page to start it.
|
||||
The I2P Tunnel Manager is not currently running. Please visit the <a href="/configclients.jsp">Client Configuration</a> page to start it.
|
||||
</body></html>
|
||||
|
@ -20,10 +20,10 @@
|
||||
<b>Encoding:</b> <%=System.getProperty("file.encoding")%></p>
|
||||
<jsp:useBean class="net.i2p.router.web.LogsHelper" id="logsHelper" scope="request" />
|
||||
<jsp:setProperty name="logsHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<h3>Critical Logs</h3><a name="criticallogs"> </a>
|
||||
<h3><%=intl._("Critical Logs")%></h3><a name="criticallogs"> </a>
|
||||
<jsp:getProperty name="logsHelper" property="criticalLogs" />
|
||||
<h3>Router Logs [<a href="configlogging.jsp">configure</a>]</h3>
|
||||
<h3><%=intl._("Router Logs")%> (<a href="configlogging.jsp"><%=intl._("configure")%></a>)</h3>
|
||||
<jsp:getProperty name="logsHelper" property="logs" />
|
||||
<h3>Service (Wrapper) Logs</h3><a name="servicelogs"> </a>
|
||||
<h3><%=intl._("Service (Wrapper) Logs")%></h3><a name="servicelogs"> </a>
|
||||
<jsp:getProperty name="logsHelper" property="serviceLogs" />
|
||||
</div><hr></div></body></html>
|
||||
|
16
apps/routerconsole/jsp/nowebapp.jsp
Normal file
16
apps/routerconsole/jsp/nowebapp.jsp
Normal file
@ -0,0 +1,16 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<%
|
||||
response.setStatus(404, "Not Found");
|
||||
%>
|
||||
<html><head>
|
||||
<%@include file="css.jsi" %>
|
||||
<%=intl.title("WebApp Not Found")%>
|
||||
</head><body>
|
||||
<%@include file="summary.jsi" %>
|
||||
<h1><%=intl._("Web Application Not Running")%></h1>
|
||||
<div class="sorry" id="warning">
|
||||
<%=intl._("The requested web application is not running.")%>
|
||||
<%=intl._("Please visit the <a href=\"/configclients.jsp#webapp\">config clients page</a> to start it.")%>
|
||||
</div></body></html>
|
@ -11,6 +11,7 @@
|
||||
<jsp:useBean class="net.i2p.router.web.ProfilesHelper" id="profilesHelper" scope="request" />
|
||||
<jsp:setProperty name="profilesHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||
<jsp:setProperty name="profilesHelper" property="writer" value="<%=out%>" />
|
||||
<jsp:setProperty name="profilesHelper" property="full" value="<%=request.getParameter("f")%>" />
|
||||
<jsp:getProperty name="profilesHelper" property="profileSummary" />
|
||||
<a name="shitlist"> </a><h2><%=intl._("Banned Peers")%></h2>
|
||||
<jsp:getProperty name="profilesHelper" property="shitlistSummary" />
|
||||
|
@ -11,7 +11,7 @@
|
||||
// pass the new delay parameter to the iframe
|
||||
newDelay = "?refresh=" + d;
|
||||
if (!"0".equals(d))
|
||||
out.print("<iframe src=\"summaryframe.jsp" + newDelay + "\" height=\"1500\" width=\"200\" scrolling=\"auto\" frameborder=\"0\" title=\"sidepanel\">\n");
|
||||
out.print("<iframe src=\"/summaryframe.jsp" + newDelay + "\" height=\"1500\" width=\"200\" scrolling=\"auto\" frameborder=\"0\" title=\"sidepanel\">\n");
|
||||
%>
|
||||
<div class="routersummary">
|
||||
<%@include file="summarynoframe.jsi" %>
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
4861
apps/routerconsole/locale/messages_ru.po
Normal file
4861
apps/routerconsole/locale/messages_ru.po
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -191,9 +191,9 @@ public class Connection {
|
||||
+ _activeResends + "), waiting " + timeLeft);
|
||||
try { _outboundPackets.wait(Math.min(timeLeft,250l)); } catch (InterruptedException ie) { if (_log.shouldLog(Log.DEBUG)) _log.debug("InterruptedException while Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends +")"); return false;}
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends
|
||||
+ "), waiting indefinitely");
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends
|
||||
// + "), waiting indefinitely");
|
||||
try { _outboundPackets.wait(250); } catch (InterruptedException ie) {if (_log.shouldLog(Log.DEBUG)) _log.debug("InterruptedException while Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends + ")"); return false;} //10*1000
|
||||
}
|
||||
} else {
|
||||
@ -299,37 +299,48 @@ public class Connection {
|
||||
|
||||
if ( (packet.getSequenceNum() == 0) && (!packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) ) {
|
||||
ackOnly = true;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("No resend for " + packet);
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("No resend for " + packet);
|
||||
} else {
|
||||
int remaining = 0;
|
||||
int windowSize;
|
||||
int remaining;
|
||||
synchronized (_outboundPackets) {
|
||||
_outboundPackets.put(new Long(packet.getSequenceNum()), packet);
|
||||
remaining = _options.getWindowSize() - _outboundPackets.size() ;
|
||||
windowSize = _options.getWindowSize();
|
||||
remaining = windowSize - _outboundPackets.size() ;
|
||||
_outboundPackets.notifyAll();
|
||||
}
|
||||
if (remaining < 0)
|
||||
remaining = 0;
|
||||
if (packet.isFlagSet(Packet.FLAG_CLOSE) || (remaining < 2)) {
|
||||
// the other end has no idea what our window size is, so
|
||||
// help him out by requesting acks below the 1/3 point,
|
||||
// if remaining < 3, and every 8 minimum.
|
||||
if (packet.isFlagSet(Packet.FLAG_CLOSE) ||
|
||||
(remaining < (windowSize + 2) / 3) ||
|
||||
(remaining < 3) ||
|
||||
(packet.getSequenceNum() % 8 == 0)) {
|
||||
packet.setOptionalDelay(0);
|
||||
packet.setFlag(Packet.FLAG_DELAY_REQUESTED);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Requesting no ack delay for packet " + packet);
|
||||
} else {
|
||||
int delay = _options.getRTO() / 2;
|
||||
// This is somewhat of a waste of time, unless the RTT < 4000,
|
||||
// since the other end limits it to getSendAckDelay()
|
||||
// which is always 2000, but it's good for diagnostics to see what the other end thinks
|
||||
// the RTT is.
|
||||
int delay = _options.getRTT() / 2;
|
||||
packet.setOptionalDelay(delay);
|
||||
if (delay > 0)
|
||||
packet.setFlag(Packet.FLAG_DELAY_REQUESTED);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Requesting ack delay of " + delay + "ms for packet " + packet);
|
||||
}
|
||||
// WHY always set?
|
||||
packet.setFlag(Packet.FLAG_DELAY_REQUESTED);
|
||||
|
||||
long timeout = _options.getRTO();
|
||||
if (timeout > MAX_RESEND_DELAY)
|
||||
timeout = MAX_RESEND_DELAY;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Resend in " + timeout + " for " + packet, new Exception("Sent by"));
|
||||
_log.debug("Resend in " + timeout + " for " + packet);
|
||||
|
||||
// schedules itself
|
||||
ResendPacketEvent rpe = new ResendPacketEvent(packet, timeout);
|
||||
@ -372,6 +383,10 @@ public class Connection {
|
||||
}
|
||||
*********/
|
||||
|
||||
/**
|
||||
* Process the acks and nacks received in a packet
|
||||
* @return List of packets acked or null
|
||||
*/
|
||||
List ackPackets(long ackThrough, long nacks[]) {
|
||||
if (ackThrough < _highestAckedThrough) {
|
||||
// dupack which won't tell us anything
|
||||
@ -687,6 +702,14 @@ public class Connection {
|
||||
* @return the next time the scheduler will want to send a packet, or -1 if never.
|
||||
*/
|
||||
public long getNextSendTime() { return _nextSendTime; }
|
||||
|
||||
/**
|
||||
* If the next send time is currently >= 0 (i.e. not "never"),
|
||||
* this may make the next time sooner but will not make it later.
|
||||
* If the next send time is currently < 0 (i.e. "never"),
|
||||
* this will set it to the time specified, but not later than
|
||||
* options.getSendAckDelay() from now (2000 ms)
|
||||
*/
|
||||
public void setNextSendTime(long when) {
|
||||
if (_nextSendTime >= 0) {
|
||||
if (when < _nextSendTime)
|
||||
@ -701,12 +724,12 @@ public class Connection {
|
||||
_nextSendTime = max;
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG) && false) {
|
||||
if (_nextSendTime <= 0)
|
||||
_log.debug("set next send time to an unknown time", new Exception(toString()));
|
||||
else
|
||||
_log.debug("set next send time to " + (_nextSendTime-_context.clock().now()) + "ms from now", new Exception(toString()));
|
||||
}
|
||||
//if (_log.shouldLog(Log.DEBUG) && false) {
|
||||
// if (_nextSendTime <= 0)
|
||||
// _log.debug("set next send time to an unknown time", new Exception(toString()));
|
||||
// else
|
||||
// _log.debug("set next send time to " + (_nextSendTime-_context.clock().now()) + "ms from now", new Exception(toString()));
|
||||
//}
|
||||
}
|
||||
|
||||
/** how many packets have we sent and the other side has ACKed?
|
||||
@ -839,8 +862,8 @@ public class Connection {
|
||||
}
|
||||
long howLong = _options.getInactivityTimeout();
|
||||
howLong += _randomWait; // randomize it a bit, so both sides don't do it at once
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Resetting the inactivity timer to " + howLong, new Exception(toString()));
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("Resetting the inactivity timer to " + howLong);
|
||||
// this will get rescheduled, and rescheduled, and rescheduled...
|
||||
_activityTimer.reschedule(howLong, false); // use the later of current and previous timeout
|
||||
}
|
||||
@ -1091,6 +1114,8 @@ public class Connection {
|
||||
// we want to resend this packet, but there are already active
|
||||
// resends in the air and we dont want to make a bad situation
|
||||
// worse. wait another second
|
||||
// BUG? seq# = 0, activeResends = 0, loop forever - why?
|
||||
// also seen with seq# > 0. Is the _activeResends count reliable?
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Delaying resend of " + _packet + " as there are "
|
||||
+ _activeResends + " active resends already in play");
|
||||
@ -1108,6 +1133,7 @@ public class Connection {
|
||||
_packet.setOptionalDelay(choke);
|
||||
if (choke > 0)
|
||||
_packet.setFlag(Packet.FLAG_DELAY_REQUESTED);
|
||||
// this seems unnecessary to send the MSS again:
|
||||
_packet.setOptionalMaxSize(getOptions().getMaxMessageSize());
|
||||
// bugfix release 0.7.8, we weren't dividing by 1000
|
||||
_packet.setResendDelay(getOptions().getResendDelay() / 1000);
|
||||
|
@ -166,6 +166,7 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
||||
packet.setReceiveStreamId(con.getReceiveStreamId());
|
||||
|
||||
con.getInputStream().updateAcks(packet);
|
||||
// note that the optional delay is usually rewritten in Connection.sendPacket()
|
||||
int choke = con.getOptions().getChoke();
|
||||
packet.setOptionalDelay(choke);
|
||||
if (choke > 0)
|
||||
@ -197,12 +198,9 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
||||
( (size > 0) || (con.getUnackedPacketsSent() <= 0) || (packet.getSequenceNum() > 0) ) ) {
|
||||
packet.setFlag(Packet.FLAG_CLOSE);
|
||||
con.setCloseSentOn(_context.clock().now());
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Closed is set for a new packet on " + con + ": " + packet);
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Closed is not set for a new packet on " + _connection + ": " + packet);
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("New outbound packet on " + _connection + ": " + packet);
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
|
||||
public static final String PROP_INITIAL_RESEND_DELAY = "i2p.streaming.initialResendDelay";
|
||||
public static final String PROP_INITIAL_ACK_DELAY = "i2p.streaming.initialAckDelay";
|
||||
public static final String PROP_INITIAL_WINDOW_SIZE = "i2p.streaming.initialWindowSize";
|
||||
/** unused */
|
||||
public static final String PROP_INITIAL_RECEIVE_WINDOW = "i2p.streaming.initialReceiveWindow";
|
||||
public static final String PROP_INACTIVITY_TIMEOUT = "i2p.streaming.inactivityTimeout";
|
||||
public static final String PROP_INACTIVITY_ACTION = "i2p.streaming.inactivityAction";
|
||||
@ -58,6 +59,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
|
||||
static final int INITIAL_WINDOW_SIZE = 6;
|
||||
static final int DEFAULT_MAX_SENDS = 8;
|
||||
public static final int DEFAULT_INITIAL_RTT = 8*1000;
|
||||
public static final int DEFAULT_INITIAL_ACK_DELAY = 2*1000;
|
||||
static final int MIN_WINDOW_SIZE = 1;
|
||||
private static final boolean DEFAULT_ANSWER_PINGS = true;
|
||||
|
||||
@ -217,7 +219,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
|
||||
setRTT(getInt(opts, PROP_INITIAL_RTT, DEFAULT_INITIAL_RTT));
|
||||
setReceiveWindow(getInt(opts, PROP_INITIAL_RECEIVE_WINDOW, 1));
|
||||
setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000));
|
||||
setSendAckDelay(getInt(opts, PROP_INITIAL_ACK_DELAY, 2000));
|
||||
setSendAckDelay(getInt(opts, PROP_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY));
|
||||
setWindowSize(getInt(opts, PROP_INITIAL_WINDOW_SIZE, INITIAL_WINDOW_SIZE));
|
||||
setMaxResends(getInt(opts, PROP_MAX_RESENDS, DEFAULT_MAX_SENDS));
|
||||
setWriteTimeout(getInt(opts, PROP_WRITE_TIMEOUT, -1));
|
||||
@ -249,7 +251,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
|
||||
if (opts.containsKey(PROP_INITIAL_RESEND_DELAY))
|
||||
setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000));
|
||||
if (opts.containsKey(PROP_INITIAL_ACK_DELAY))
|
||||
setSendAckDelay(getInt(opts, PROP_INITIAL_ACK_DELAY, 2000));
|
||||
setSendAckDelay(getInt(opts, PROP_INITIAL_ACK_DELAY, DEFAULT_INITIAL_ACK_DELAY));
|
||||
if (opts.containsKey(PROP_INITIAL_WINDOW_SIZE))
|
||||
setWindowSize(getInt(opts, PROP_INITIAL_WINDOW_SIZE, INITIAL_WINDOW_SIZE));
|
||||
if (opts.containsKey(PROP_MAX_RESENDS))
|
||||
@ -295,6 +297,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
|
||||
* @return if we want signatures on all packets.
|
||||
*/
|
||||
public boolean getRequireFullySigned() { return _fullySigned; }
|
||||
/** unused, see above */
|
||||
public void setRequireFullySigned(boolean sign) { _fullySigned = sign; }
|
||||
|
||||
/**
|
||||
@ -325,7 +328,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
|
||||
}
|
||||
|
||||
/** after how many consecutive messages should we ack?
|
||||
* This doesn't appear to be used.
|
||||
* @deprecated This doesn't appear to be used.
|
||||
* @return receive window size.
|
||||
*/
|
||||
public int getReceiveWindow() { return _receiveWindow; }
|
||||
@ -405,6 +408,10 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
|
||||
* @return ACK delay in ms
|
||||
*/
|
||||
public int getSendAckDelay() { return _sendAckDelay; }
|
||||
/**
|
||||
* Unused except here, so expect the default initial delay of 2000 ms unless set by the user
|
||||
* to remain constant.
|
||||
*/
|
||||
public void setSendAckDelay(int delayMs) { _sendAckDelay = delayMs; }
|
||||
|
||||
/** What is the largest message we want to send or receive?
|
||||
|
@ -131,11 +131,14 @@ public class ConnectionPacketHandler {
|
||||
isNew = false;
|
||||
}
|
||||
|
||||
if ( (packet.getSequenceNum() == 0) && (packet.getPayloadSize() > 0) ) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("seq=0 && size=" + packet.getPayloadSize() + ": isNew? " + isNew
|
||||
+ " packet: " + packet + " con: " + con);
|
||||
}
|
||||
//if ( (packet.getSequenceNum() == 0) && (packet.getPayloadSize() > 0) ) {
|
||||
// if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("seq=0 && size=" + packet.getPayloadSize() + ": isNew? " + isNew
|
||||
// + " packet: " + packet + " con: " + con);
|
||||
//}
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug((isNew ? "New" : "Dup or ack-only") + " inbound packet on " + con + ": " + packet);
|
||||
|
||||
// close *after* receiving the data, as well as after verifying the signatures / etc
|
||||
if (packet.isFlagSet(Packet.FLAG_CLOSE) && packet.isFlagSet(Packet.FLAG_SIGNATURE_INCLUDED))
|
||||
@ -151,7 +154,9 @@ public class ConnectionPacketHandler {
|
||||
if (packet.isFlagSet(Packet.FLAG_DELAY_REQUESTED) && (packet.getOptionalDelay() <= 0) ) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Scheduling immediate ack for " + packet);
|
||||
con.setNextSendTime(_context.clock().now() + con.getOptions().getSendAckDelay());
|
||||
//con.setNextSendTime(_context.clock().now() + con.getOptions().getSendAckDelay());
|
||||
// honor request "almost" immediately
|
||||
con.setNextSendTime(_context.clock().now() + 250);
|
||||
} else {
|
||||
int delay = con.getOptions().getSendAckDelay();
|
||||
if (packet.isFlagSet(Packet.FLAG_DELAY_REQUESTED)) // delayed ACK requested
|
||||
@ -222,6 +227,10 @@ public class ConnectionPacketHandler {
|
||||
// con.fastRetransmit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the acks in a received packet, and adjust our window and RTT
|
||||
* @return are we congested?
|
||||
*/
|
||||
private boolean ack(Connection con, long ackThrough, long nacks[], Packet packet, boolean isNew, boolean choke) {
|
||||
if (ackThrough < 0) return false;
|
||||
//if ( (nacks != null) && (nacks.length > 0) )
|
||||
@ -287,7 +296,7 @@ public class ConnectionPacketHandler {
|
||||
return adjustWindow(con, isNew, packet.getSequenceNum(), numResends, (acked != null ? acked.size() : 0), choke);
|
||||
}
|
||||
|
||||
|
||||
/** @return are we congested? */
|
||||
private boolean adjustWindow(Connection con, boolean isNew, long sequenceNum, int numResends, int acked, boolean choke) {
|
||||
boolean congested = false;
|
||||
if ( (!isNew) && (sequenceNum > 0) ) {
|
||||
|
@ -99,9 +99,9 @@ public class MessageInputStream extends InputStream {
|
||||
}
|
||||
}
|
||||
private long[] locked_getNacks() {
|
||||
List ids = null;
|
||||
List<Long> ids = null;
|
||||
for (long i = _highestReadyBlockId + 1; i < _highestBlockId; i++) {
|
||||
Long l = new Long(i);
|
||||
Long l = Long.valueOf(i);
|
||||
if (_notYetReadyBlocks.containsKey(l)) {
|
||||
// ACK
|
||||
} else {
|
||||
@ -113,7 +113,7 @@ public class MessageInputStream extends InputStream {
|
||||
if (ids != null) {
|
||||
long rv[] = new long[ids.size()];
|
||||
for (int i = 0; i < rv.length; i++)
|
||||
rv[i] = ((Long)ids.get(i)).longValue();
|
||||
rv[i] = ids.get(i).longValue();
|
||||
return rv;
|
||||
} else {
|
||||
return null;
|
||||
|
22
apps/susidns/locale/messages_de.po
Normal file
22
apps/susidns/locale/messages_de.po
Normal file
@ -0,0 +1,22 @@
|
||||
# I2P
|
||||
# Copyright (C) 2009 The I2P Project
|
||||
# This file is distributed under the same license as the susidns package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
# foo <foo@bar>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P susidns\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-12-10 01:53+0000\n"
|
||||
"PO-Revision-Date: 2009-10-19 12:50+0000\n"
|
||||
"Last-Translator: foo <foo@bar>\n"
|
||||
"Language-Team: foo <foo@bar>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: German\n"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:88
|
||||
msgid "Introduction - SusiDNS"
|
||||
msgstr ""
|
395
apps/susidns/locale/messages_ru.po
Normal file
395
apps/susidns/locale/messages_ru.po
Normal file
@ -0,0 +1,395 @@
|
||||
# I2P
|
||||
# Copyright (C) 2009 The I2P Project
|
||||
# This file is distributed under the same license as the susidns package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
# foo <foo@bar>, 2009.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P susidns\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2009-12-19 11:30+0000\n"
|
||||
"PO-Revision-Date: 2009-12-20 07:03+0000\n"
|
||||
"Last-Translator: 4get <forget@mail.i2p>\n"
|
||||
"Language-Team: foo <foo@bar>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Poedit-Language: Russian\n"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:197
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:188
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:192
|
||||
msgid "Search"
|
||||
msgstr "Поиск"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:201
|
||||
msgid "Search within filtered list"
|
||||
msgstr "Поиск в отфильтрованном списке"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:203
|
||||
msgid "Filtered list"
|
||||
msgstr "Отфильтрованный список"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:207
|
||||
msgid "no matches"
|
||||
msgstr "ничего не найдено"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:210
|
||||
msgid "Addressbook"
|
||||
msgstr "Адресная книга"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:212
|
||||
msgid "contains no entries"
|
||||
msgstr "не содержит записей"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:214
|
||||
msgid "contains 1 entry"
|
||||
msgstr "содержит одну запись"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:216
|
||||
#, java-format
|
||||
msgid "contains {0} entries"
|
||||
msgstr "содержит {0} записей"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:226
|
||||
#, java-format
|
||||
msgid "Showing {0} of {1}"
|
||||
msgstr "Показаны {0} из {1}"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:257
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:359
|
||||
msgid "Add"
|
||||
msgstr "Добавить"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:261
|
||||
msgid "Destination added."
|
||||
msgstr "Адрес добавлен."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:265
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:307
|
||||
msgid "Delete"
|
||||
msgstr "Удалить"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:275
|
||||
#, java-format
|
||||
msgid "Destination {0} deleted."
|
||||
msgstr "Адрес {0} удален."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:277
|
||||
#, java-format
|
||||
msgid "{0} destinations deleted."
|
||||
msgstr "{0} адресов удалено."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:283
|
||||
msgid "Addressbook saved."
|
||||
msgstr "Адресная книга сохранена."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:286
|
||||
msgid "ERROR: Could not write addressbook file."
|
||||
msgstr "ОШИБКА: Не удалось сохранить файл адресной книги."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:291
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:148
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:150
|
||||
msgid "Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit."
|
||||
msgstr "Форма не принята, скорее всего это произошло из-за того, что Вы нажимали кнопку \"Назад\" или \"Обновить\" в браузере. Пожалуйста, заполните форму заново."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:139
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:129
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:123
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:123
|
||||
msgid "Save"
|
||||
msgstr "Сохранить"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:141
|
||||
msgid "Configuration saved."
|
||||
msgstr "Настройки сохранены."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:142
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:144
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:125
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:125
|
||||
msgid "Reload"
|
||||
msgstr "Перезагрузить"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:144
|
||||
msgid "Configuration reloaded."
|
||||
msgstr "Настройки перезагружены."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:138
|
||||
msgid "Subscriptions saved, updating addressbook from subscription sources now."
|
||||
msgstr "Подписки сохранены, запущена загрузка подписок и обновление адресной книги."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:142
|
||||
msgid "Subscriptions saved."
|
||||
msgstr "Подписки сохранены."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:146
|
||||
msgid "Subscriptions reloaded."
|
||||
msgstr "Подписки перезагружены."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:120
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:140
|
||||
msgid "addressbook"
|
||||
msgstr "адресная книга"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:122
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:99
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:88
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:99
|
||||
msgid "addressbooks"
|
||||
msgstr "адресные книги"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:124
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:101
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:90
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:101
|
||||
msgid "private"
|
||||
msgstr "приватная"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:126
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:103
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:92
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:103
|
||||
msgid "master"
|
||||
msgstr "основная"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:128
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:105
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:94
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:105
|
||||
msgid "router"
|
||||
msgstr "маршрутизатор"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:130
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:107
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:96
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:107
|
||||
msgid "published"
|
||||
msgstr "публикуемая"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:132
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:109
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:98
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:97
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:109
|
||||
msgid "subscriptions"
|
||||
msgstr "подписки"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:134
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:97
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:111
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:100
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:111
|
||||
msgid "configuration"
|
||||
msgstr "настройки"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:136
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:113
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:102
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:113
|
||||
msgid "overview"
|
||||
msgstr "введение"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:158
|
||||
msgid "Filter"
|
||||
msgstr "Фильтр"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:161
|
||||
msgid "all"
|
||||
msgstr "[без фильтра]"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:172
|
||||
msgid "Current filter"
|
||||
msgstr "Текущий фильтр"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:177
|
||||
msgid "clear filter"
|
||||
msgstr "сбросить фильтр"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:219
|
||||
msgid "Name"
|
||||
msgstr "Имя"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:221
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:355
|
||||
msgid "Destination"
|
||||
msgstr "Адрес назначения"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:252
|
||||
msgid "Mark for deletion"
|
||||
msgstr "Пометить для удаления"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:274
|
||||
msgid "address helper link"
|
||||
msgstr "addresshelper-ссылка"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:338
|
||||
msgid "This addressbook is empty."
|
||||
msgstr "Эта адресная книга пуста."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:349
|
||||
msgid "Add new destination"
|
||||
msgstr "Добавить новый адрес"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:351
|
||||
msgid "Hostname"
|
||||
msgstr "Имя узла"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:127
|
||||
msgid "Hints"
|
||||
msgstr "Примечания"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:129
|
||||
msgid "File and directory paths here are relative to the addressbook's working directory, which is normally ~/.i2p/addressbook/ (Linux) or %APPDATA%\\I2P\\addressbook\\ (Windows)."
|
||||
msgstr "Пути указываются относительно домашней директории адресной книги, которая обычно расположена в ~/.i2p/addressbook/ (под Linux) или в %APPDATA%\\I2P\\addressbook\\ (под Windows)."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:131
|
||||
msgid "If you want to manually add lines to an addressbook, add them to the private or master addressbooks."
|
||||
msgstr "Если Вы хотите вручную добавлять записи в адресную книгу, то добавляйте их в «приватную» или «основную»."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:133
|
||||
msgid "The router addressbook and the published addressbook are updated by the addressbook application."
|
||||
msgstr "Адресные книги «маршрутизатор» и «публикуемая» создаются/перезаписываются автоматически."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:135
|
||||
msgid "When you publish your addressbook, ALL destinations from the master and router addressbooks appear there."
|
||||
msgstr "Когда Вы публикуете свою адресную книгу, то публикуются ВСЕ записи из адресных книг «основная» и «маршрутизатор»."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:137
|
||||
msgid "Use the private addressbook for private destinations, these are not published."
|
||||
msgstr "Пользуйтесь «приватной» адресной книгой для адресов, которые Вы не хотите публиковать."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:139
|
||||
msgid "Options"
|
||||
msgstr "Параметры"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:141
|
||||
msgid "File containing the list of subscriptions URLs (no need to change)"
|
||||
msgstr "Файл для хранения списка URL подписок (перенастраивать нет необходимости)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:143
|
||||
msgid "Update interval in hours"
|
||||
msgstr "Интервал обновления (часы)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:145
|
||||
msgid "Your public hosts.txt file (choose a path within your webserver document root)"
|
||||
msgstr "hosts.txt для публикации (по умолчанию сохраняется в корневой директории встроенного в I2P маршутизатор вебсервера)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:147
|
||||
msgid "Your hosts.txt (don't change)"
|
||||
msgstr "hosts.txt используемый маршрутизатором (перенастраивать не надо)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:149
|
||||
msgid "Your personal addressbook, these hosts will be published"
|
||||
msgstr "Ваша публичная адресная книга, эти записи будут публиковаться"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:151
|
||||
msgid "Your private addressbook, it is never published"
|
||||
msgstr "Ваша приватная адресная книга, она никогда не публикуется"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:153
|
||||
msgid "Port for your eepProxy (no need to change)"
|
||||
msgstr "Порт eepProxy (перенастраивать нет необходимости)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:155
|
||||
msgid "Hostname for your eepProxy (no need to change)"
|
||||
msgstr "Адрес eepProxy (перенастраивать нет необходимости)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:157
|
||||
msgid "Whether to update the published addressbook"
|
||||
msgstr "Обновлять ли публикуемую адресную книгу (true/false)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:159
|
||||
msgid "File containing the etags header from the fetched subscription URLs (no need to change)"
|
||||
msgstr "Файл для хранения etags-заголовков от загруженных адресов подписок (перенастраивать нет необходимости)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:161
|
||||
msgid "File containing the modification timestamp for each fetched subscription URL (no need to change)"
|
||||
msgstr "Файл для хранения даты/времени модификации каждого загруженного адреса подписки (перенастраивать нет необходимости)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:163
|
||||
msgid "File to log activity to (change to /dev/null if you like)"
|
||||
msgstr "Файл для записи журнала действий"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:86
|
||||
msgid "Introduction"
|
||||
msgstr "Введение - SusiDNS"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:104
|
||||
msgid "What is the addressbook?"
|
||||
msgstr "Что такое адресная книга?"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:106
|
||||
msgid "The addressbook application is part of your i2p installation."
|
||||
msgstr "Адресная книга — это приложение в составе Вашего I2P маршрутизатора."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:108
|
||||
msgid "It regularly updates your hosts.txt file from distributed sources or \"subscriptions\"."
|
||||
msgstr "Его задача регулярно пополнять Ваш hosts.txt адресами из настраиваемых источников («подписок»)."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:110
|
||||
msgid "In the default configuration, the addressbook is only subscribed to www.i2p2.i2p."
|
||||
msgstr "По умолчанию в адресной книге настроена лишь одна подписка — на www.i2p2.i2p."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:112
|
||||
msgid "Subscribing to additional sites is easy, just add them to your <a href=\"subscriptions.jsp\">subscriptions</a> file."
|
||||
msgstr "Добавить другие подписки просто, достаточно вписать их URL в <a href=\"subscriptions.jsp\">файл подписок</a>."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:114
|
||||
msgid "For more information on naming in i2p, see <a href=\"http://www.i2p2.i2p/naming.html\">the overview on www.i2p2.i2p</a>."
|
||||
msgstr "Подробнее о механизме доменных имен в I2P читайте на странице <a href=\"http://www.i2p2.i2p/naming.html\">Naming in I2P</a>."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:116
|
||||
msgid "How does the addressbook work?"
|
||||
msgstr "Как работает адресная книга?"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:118
|
||||
msgid "The addressbook application regularly polls your subscriptions and merges their content into your \"router\" addressbook, stored in the hosts.txt file."
|
||||
msgstr "Адресная книга периодически опрашивает Ваши подписки и добавляет их содержимое в Вашу «маршрутизаторную» адресную книгу, которая хранится в файле hosts.txt."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:120
|
||||
msgid "Then it merges your \"master\" addressbook (userhosts.txt) into the router addressbook as well."
|
||||
msgstr "После этого туда добавляется содержимое Вашей «основной» адресной книги (userhosts.txt)."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:122
|
||||
msgid "If configured, the router addressbook is now written to the \"published\" addressbook, which will be publicly available if you are running an eepsite."
|
||||
msgstr "Если разрешена публикация, то «маршрутизаторная» адресная книга копируется в «публикуемую» адресную книгу. «Публикуемая» адресная книга доступна публично, если у Вас запущен Ваш I2P-сайт."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:124
|
||||
msgid "The router also uses a private addressbook (privatehosts.txt, not shown in the picture), which is not merged or published."
|
||||
msgstr "Маршрутизатор также использует приватную адресную книгу (privatehosts.txt, на иллюстрации не показано), которая никуда не копируется и не публикуется."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:126
|
||||
msgid "Hosts in the private addressbook can be accessed by you but their addresses are never distributed to others."
|
||||
msgstr "Таким образом Вы можете пользоваться адресами из этой адресной книги, не раскрывая другим её содержимое."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:128
|
||||
msgid "The private addressbook can also be used for aliases of hosts in your other addressbooks."
|
||||
msgstr "Приватную адресную книгу также удобно иcпользовать для хранения альтернативных/коротких адресов."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:127
|
||||
msgid "The subscription file contains a list of i2p URLs."
|
||||
msgstr "Файл подписок содержит список i2p URL."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:129
|
||||
msgid "The addressbook application regularly checks this list for new eepsites."
|
||||
msgstr "Адресная книга периодически проверяет этот список на наличие новых адресов I2P-сайтов."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:131
|
||||
msgid "Those URLs refer to published hosts.txt files."
|
||||
msgstr "Каждый URL указывает на опубликованный hosts.txt файл."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:133
|
||||
msgid "The default subscription is the hosts.txt from www.i2p2.i2p, which is updated infrequently."
|
||||
msgstr "По умолчанию в списке задана только ссылка на hosts.txt с www.i2p2.i2p, который обновляется очень редко."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:135
|
||||
msgid "So it is a good idea to add additional subscriptions to sites that have the latest addresses."
|
||||
msgstr "Поэтому не помешает дополнительно подписаться на hosts.txt с более часто обновляемых сайтов."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:137
|
||||
msgid "See the FAQ for a list of subscription URLs."
|
||||
msgstr "В соответствующем разделе FAQ можно найти несколько таких адресов."
|
||||
|
17
apps/susidns/src/bmsg.sh
Normal file
17
apps/susidns/src/bmsg.sh
Normal file
@ -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
|
@ -61,22 +61,53 @@
|
||||
<srcfiles dir= "." includes="jsp/*.jsp, WEB-INF/web-template.xml"/>
|
||||
</uptodate>
|
||||
|
||||
<target name="all" depends="compile,precompilejsp,war"/>
|
||||
<target name="all" depends="compile,precompilejsp,bundle,war"/>
|
||||
<target name="war">
|
||||
<war destfile="${project}.war" webxml="WEB-INF/web-out.xml">
|
||||
<fileset dir=".">
|
||||
<include name="WEB-INF/**/*.class"/>
|
||||
<include name="WEB-INF/lib/*.jar"/>
|
||||
<include name="jsp/*.jsp"/>
|
||||
<include name="images/*.png"/>
|
||||
<include name="css.css"/>
|
||||
<include name="index.html"/>
|
||||
<include name="WEB-INF/web-template.xml"/>
|
||||
<include name="WEB-INF/web-out.xml"/>
|
||||
<include name="WEB-INF/classes/${project}.properties"/>
|
||||
</fileset>
|
||||
</war>
|
||||
</target>
|
||||
|
||||
<target name="bundle" depends="compile, precompilejsp">
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="false" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="false" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="cmd" osfamily="windows" failifexecutionfails="false" >
|
||||
<arg value="/c" />
|
||||
<arg value="bundle-messages.bat" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="poupdate" depends="compile, precompilejsp">
|
||||
<!-- Update the messages_*.po files. -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
<arg value="-p" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" >
|
||||
<arg value="./bundle-messages.sh" />
|
||||
<arg value="-p" />
|
||||
</exec>
|
||||
<exec executable="cmd" osfamily="windows" failifexecutionfails="true" >
|
||||
<arg value="/c" />
|
||||
<arg value="bundle-messages.bat" />
|
||||
<arg value="-p" />
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<delete file="susidns.war" />
|
||||
<delete>
|
||||
|
26
apps/susidns/src/bundle-messages.bat
Normal file
26
apps/susidns/src/bundle-messages.bat
Normal file
@ -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
|
87
apps/susidns/src/bundle-messages.sh
Executable file
87
apps/susidns/src/bundle-messages.sh
Executable file
@ -0,0 +1,87 @@
|
||||
#
|
||||
# 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=i2p.susi.dns.messages
|
||||
TMPFILE=tmp/javafiles.txt
|
||||
export TZ=UTC
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
POUPDATE=1
|
||||
fi
|
||||
|
||||
# add ../src/ so the refs will work in the po file
|
||||
JPATHS="../src/java/ ../src/tmp/"
|
||||
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 WEB-INF/classes/i2p/susi/dns/messages_$LG.class -a \
|
||||
WEB-INF/classes/i2p/susi/dns/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")
|
||||
# intl._("foo")
|
||||
# In a jsp, you must use a helper or handler that has the context set.
|
||||
# To start a new translation, copy the header from an old translation to the new .po file,
|
||||
# then ant distclean updater.
|
||||
find $JPATHS -name *.java > $TMPFILE
|
||||
xgettext -f $TMPFILE -F -L java --from-code=UTF-8 \
|
||||
--keyword=_ --keyword=_x --keyword=intl._ --keyword=intl.title \
|
||||
-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 --statistics -r $CLASS -l $LG -d WEB-INF/classes $i
|
||||
if [ $? -ne 0 ]
|
||||
then
|
||||
echo 'Warning - msgfmt failed, not updating translations'
|
||||
break
|
||||
fi
|
||||
done
|
||||
rm -f $TMPFILE
|
||||
# todo: return failure
|
||||
exit 0
|
@ -121,4 +121,32 @@ p.footer {
|
||||
font-size: 10pt !important;
|
||||
line-height: 160% !important;
|
||||
-moz-box-shadow: inset 0px 0px 1px 0px #002;
|
||||
}
|
||||
}
|
||||
|
||||
input[type=submit] {
|
||||
border: 1px outset #999;
|
||||
background: #ddf;
|
||||
color: #001;
|
||||
margin: 5px;
|
||||
font: bold 8pt "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
|
||||
padding: 1px 2px;
|
||||
text-decoration: none;
|
||||
min-width: 110px;
|
||||
border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-khtml-border-radius: 4px;
|
||||
-moz-box-shadow: inset 0px 2px 8px 0px #fff;
|
||||
color: #006;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
|
||||
input[type=submit]:hover {
|
||||
background: #22a;
|
||||
color: #fff;
|
||||
border: 1px solid #f60;
|
||||
opacity: 1.0;
|
||||
-moz-box-shadow: inset 0px 0px 0px 1px #fff;
|
||||
|
||||
}
|
||||
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 2.4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.6 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.7 KiB |
@ -35,6 +35,8 @@ import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
|
||||
public class AddressbookBean
|
||||
{
|
||||
private String book, action, serial, lastSerial, filter, search, hostname, destination;
|
||||
@ -140,7 +142,7 @@ public class AddressbookBean
|
||||
return book;
|
||||
}
|
||||
public void setBook(String book) {
|
||||
this.book = book;
|
||||
this.book = DataHelper.stripHTML(book); // XSS
|
||||
}
|
||||
public String getSerial() {
|
||||
lastSerial = "" + Math.random();
|
||||
@ -192,20 +194,27 @@ public class AddressbookBean
|
||||
// addressbook.jsp catches the case where the whole book is empty.
|
||||
String filterArg = "";
|
||||
if( search != null && search.length() > 0 ) {
|
||||
message = "Search ";
|
||||
message = _("Search") + ' ';
|
||||
}
|
||||
if( filter != null && filter.length() > 0 ) {
|
||||
if( search != null && search.length() > 0 )
|
||||
message += "within ";
|
||||
message += "Filtered list ";
|
||||
message = _("Search within filtered list") + ' ';
|
||||
else
|
||||
message = _("Filtered list") + ' ';
|
||||
filterArg = "&filter=" + filter;
|
||||
}
|
||||
if (entries.length == 0) {
|
||||
message += "- no matches";
|
||||
message += "- " + _("no matches") + '.';
|
||||
} else if (getBeginInt() == 0 && getEndInt() == entries.length - 1) {
|
||||
if (message.length() == 0)
|
||||
message = "Addressbook ";
|
||||
message += "contains " + entries.length + " entries";
|
||||
message = _("Addressbook") + ' ';
|
||||
if (entries.length <= 0)
|
||||
message += _("contains no entries");
|
||||
else if (entries.length == 1)
|
||||
message += _("contains 1 entry");
|
||||
else
|
||||
message += _("contains {0} entries", entries.length);
|
||||
message += '.';
|
||||
} else {
|
||||
if (getBeginInt() > 0) {
|
||||
int newBegin = Math.max(0, getBeginInt() - DISPLAY_SIZE);
|
||||
@ -214,7 +223,7 @@ public class AddressbookBean
|
||||
"&begin=" + newBegin + "&end=" + newEnd + "\">" + newBegin +
|
||||
'-' + newEnd + "</a> | ";
|
||||
}
|
||||
message += "Showing " + getBegin() + '-' + getEnd() + " of " + entries.length;
|
||||
message += _("Showing {0} of {1}", "" + getBegin() + '-' + getEnd(), entries.length);
|
||||
if (getEndInt() < entries.length - 1) {
|
||||
int newBegin = Math.min(entries.length - 1, getEndInt() + 1);
|
||||
int newEnd = Math.min(entries.length, getEndInt() + DISPLAY_SIZE);
|
||||
@ -243,38 +252,43 @@ public class AddressbookBean
|
||||
if( action != null ) {
|
||||
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
||||
boolean changed = false;
|
||||
if( action.compareToIgnoreCase( "add") == 0 ) {
|
||||
int deleted = 0;
|
||||
String name = null;
|
||||
if (action.equals(_("Add"))) {
|
||||
if( addressbook != null && hostname != null && destination != null ) {
|
||||
addressbook.put( hostname, destination );
|
||||
changed = true;
|
||||
message += "Destination added.<br/>";
|
||||
message = _("Destination added.");
|
||||
// clear search when adding
|
||||
search = null;
|
||||
}
|
||||
}
|
||||
if( action.compareToIgnoreCase( "delete" ) == 0 ) {
|
||||
} else if (action.equals(_("Delete"))) {
|
||||
Iterator it = deletionMarks.iterator();
|
||||
int deleted = 0;
|
||||
while( it.hasNext() ) {
|
||||
String name = (String)it.next();
|
||||
name = (String)it.next();
|
||||
addressbook.remove( name );
|
||||
changed = true;
|
||||
deleted++;
|
||||
}
|
||||
if( changed ) {
|
||||
message += "" + deleted + " destination(s) deleted.<br/>";
|
||||
if (deleted == 1)
|
||||
message = _("Destination {0} deleted.", name);
|
||||
else
|
||||
message = _("{0} destinations deleted.", deleted);
|
||||
}
|
||||
}
|
||||
if( changed ) {
|
||||
try {
|
||||
save();
|
||||
message += "Addressbook saved.<br/>";
|
||||
message += "<br>" + _("Addressbook saved.");
|
||||
} catch (Exception e) {
|
||||
Debug.debug( e.getClass().getName() + ": " + e.getMessage() );
|
||||
message += "ERROR: Could not write addressbook file.<br/>";
|
||||
message += "<br>" + _("ERROR: Could not write addressbook file.");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
message = "Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit.";
|
||||
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.");
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,7 +340,7 @@ public class AddressbookBean
|
||||
return destination;
|
||||
}
|
||||
public void setDestination(String destination) {
|
||||
this.destination = destination;
|
||||
this.destination = DataHelper.stripHTML(destination); // XSS
|
||||
}
|
||||
public String getHostname() {
|
||||
return hostname;
|
||||
@ -338,7 +352,7 @@ public class AddressbookBean
|
||||
deletionMarks.addLast( name );
|
||||
}
|
||||
public void setHostname(String hostname) {
|
||||
this.hostname = hostname;
|
||||
this.hostname = DataHelper.stripHTML(hostname); // XSS
|
||||
}
|
||||
private int getBeginInt() {
|
||||
return Math.max(0, Math.min(entries.length - 1, beginIndex));
|
||||
@ -362,4 +376,19 @@ public class AddressbookBean
|
||||
endIndex = Integer.parseInt(s);
|
||||
} catch (NumberFormatException nfe) {}
|
||||
}
|
||||
|
||||
/** translate */
|
||||
private static String _(String s) {
|
||||
return Messages.getString(s);
|
||||
}
|
||||
|
||||
/** translate */
|
||||
private static String _(String s, Object o) {
|
||||
return Messages.getString(s, o);
|
||||
}
|
||||
|
||||
/** translate */
|
||||
private static String _(String s, Object o, Object o2) {
|
||||
return Messages.getString(s, o, o2);
|
||||
}
|
||||
}
|
||||
|
@ -136,17 +136,16 @@ public class ConfigBean implements Serializable {
|
||||
String message = "";
|
||||
if( action != null ) {
|
||||
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
||||
if( action.compareToIgnoreCase( "save") == 0 ) {
|
||||
if(action.equals(_("Save"))) {
|
||||
save();
|
||||
message = "Configuration saved.";
|
||||
}
|
||||
else if( action.compareToIgnoreCase( "reload") == 0 ) {
|
||||
message = _("Configuration saved.");
|
||||
} else if (action.equals(_("Reload"))) {
|
||||
reload();
|
||||
message = "Configuration reloaded.";
|
||||
message = _("Configuration reloaded.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
message = "Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit.";
|
||||
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.");
|
||||
}
|
||||
}
|
||||
if( message.length() > 0 )
|
||||
@ -162,4 +161,9 @@ public class ConfigBean implements Serializable {
|
||||
public void setSerial(String serial ) {
|
||||
this.serial = serial;
|
||||
}
|
||||
|
||||
/** translate */
|
||||
private static String _(String s) {
|
||||
return Messages.getString(s);
|
||||
}
|
||||
}
|
||||
|
33
apps/susidns/src/java/src/i2p/susi/dns/Messages.java
Normal file
33
apps/susidns/src/java/src/i2p/susi/dns/Messages.java
Normal file
@ -0,0 +1,33 @@
|
||||
package i2p.susi.dns;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.Translate;
|
||||
|
||||
/**
|
||||
* Translate strings for this package.
|
||||
*/
|
||||
public class Messages {
|
||||
private static final String BUNDLE_NAME = "i2p.susi.dns.messages";
|
||||
private final I2PAppContext _context;
|
||||
|
||||
public Messages() {
|
||||
_context = I2PAppContext.getGlobalContext();
|
||||
}
|
||||
|
||||
/** lang in routerconsole.lang property, else current locale */
|
||||
public String _(String key) {
|
||||
return Translate.getString(key, _context, BUNDLE_NAME);
|
||||
}
|
||||
|
||||
public static String getString(String s) {
|
||||
return Translate.getString(s, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
|
||||
}
|
||||
|
||||
public static String getString(String s, Object o) {
|
||||
return Translate.getString(s, o, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
|
||||
}
|
||||
|
||||
public static String getString(String s, Object o, Object o2) {
|
||||
return Translate.getString(s, o, o2, I2PAppContext.getGlobalContext(), BUNDLE_NAME);
|
||||
}
|
||||
}
|
@ -126,17 +126,28 @@ public class SubscriptionsBean
|
||||
String message = "";
|
||||
if( action != null ) {
|
||||
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
||||
if( action.compareToIgnoreCase( "save") == 0 ) {
|
||||
if (action.equals(_("Save"))) {
|
||||
save();
|
||||
message = "Subscriptions saved.";
|
||||
}
|
||||
else if( action.compareToIgnoreCase( "reload") == 0 ) {
|
||||
String nonce = System.getProperty("addressbook.nonce");
|
||||
if (nonce != null) {
|
||||
// Yes this is a hack.
|
||||
// No it doesn't work on a text-mode browser.
|
||||
// Fetching from the addressbook servlet
|
||||
// with the correct parameters will kick off a
|
||||
// config reload and fetch.
|
||||
message = _("Subscriptions saved, updating addressbook from subscription sources now.") +
|
||||
"<img height=\"1\" width=\"1\" alt=\"\" " +
|
||||
"src=\"/addressbook/?wakeup=1&nonce=" + nonce + "\">";
|
||||
} else {
|
||||
message = _("Subscriptions saved.");
|
||||
}
|
||||
} else if (action.equals(_("Reload"))) {
|
||||
reload();
|
||||
message = "Subscriptions reloaded.";
|
||||
message = _("Subscriptions reloaded.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
message = "Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit.";
|
||||
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.");
|
||||
}
|
||||
}
|
||||
if( message.length() > 0 )
|
||||
@ -171,4 +182,9 @@ public class SubscriptionsBean
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
/** translate */
|
||||
private static String _(String s) {
|
||||
return Messages.getString(s);
|
||||
}
|
||||
}
|
||||
|
@ -22,11 +22,18 @@
|
||||
*
|
||||
* $Revision: 1.3 $
|
||||
*/
|
||||
|
||||
// http://www.crazysquirrel.com/computing/general/form-encoding.jspx
|
||||
if (request.getCharacterEncoding() == null)
|
||||
request.setCharacterEncoding("UTF-8");
|
||||
|
||||
%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<%@ page contentType="text/html"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<jsp:useBean id="version" class="i2p.susi.dns.VersionBean" scope="application" />
|
||||
<jsp:useBean id="book" class="i2p.susi.dns.AddressbookBean" scope="session" />
|
||||
<jsp:useBean id="intl" class="i2p.susi.dns.Messages" scope="application" />
|
||||
<jsp:setProperty name="book" property="*" />
|
||||
<jsp:setProperty name="book" property="resetDeletionMarks" value="1"/>
|
||||
<c:forEach items="${paramValues.checked}" var="checked">
|
||||
@ -35,7 +42,8 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>${book.book} addressbook - susidns v${version.version}</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>${book.book} <%=intl._("addressbook")%> - susidns</title>
|
||||
<link rel="stylesheet" type="text/css" href="css.css">
|
||||
</head>
|
||||
<body>
|
||||
@ -45,19 +53,20 @@
|
||||
</div>
|
||||
<hr>
|
||||
<div id="navi">
|
||||
<p>addressbooks
|
||||
<a href="addressbook.jsp?book=master&filter=none&begin=0&end=99">master</a> |
|
||||
<a href="addressbook.jsp?book=router&filter=none&begin=0&end=99">router</a> |
|
||||
<a href="addressbook.jsp?book=published&filter=none&begin=0&end=99">published</a> |
|
||||
<a href="addressbook.jsp?book=private&filter=none&begin=0&end=99">private</a> *
|
||||
<a href="subscriptions.jsp">subscriptions</a> *
|
||||
<a href="config.jsp">configuration</a> *
|
||||
<a href="index.jsp">overview</a>
|
||||
<p>
|
||||
<%=intl._("addressbooks")%>
|
||||
<a href="addressbook.jsp?book=private&filter=none&begin=0&end=99"><%=intl._("private")%></a> |
|
||||
<a href="addressbook.jsp?book=master&filter=none&begin=0&end=99"><%=intl._("master")%></a> |
|
||||
<a href="addressbook.jsp?book=router&filter=none&begin=0&end=99"><%=intl._("router")%></a> |
|
||||
<a href="addressbook.jsp?book=published&filter=none&begin=0&end=99"><%=intl._("published")%></a> *
|
||||
<a href="subscriptions.jsp"><%=intl._("subscriptions")%></a> *
|
||||
<a href="config.jsp"><%=intl._("configuration")%></a> *
|
||||
<a href="index.jsp"><%=intl._("overview")%></a>
|
||||
</p>
|
||||
</div>
|
||||
<hr>
|
||||
<div id="headline">
|
||||
<h3>${book.book} addressbook at ${book.fileName}</h3>
|
||||
<h3><%=intl._(book.getBook())%> <%=intl._("addressbook")%>: ${book.fileName}</h3>
|
||||
</div>
|
||||
|
||||
<div id="messages">${book.messages}</div>
|
||||
@ -66,7 +75,7 @@
|
||||
|
||||
<c:if test="${book.notEmpty}">
|
||||
<div id="filter">
|
||||
<p>Filter:
|
||||
<p><%=intl._("Filter")%>:
|
||||
<a href="addressbook.jsp?filter=a&begin=0&end=99">a</a>
|
||||
<a href="addressbook.jsp?filter=b&begin=0&end=99">b</a>
|
||||
<a href="addressbook.jsp?filter=c&begin=0&end=99">c</a>
|
||||
@ -94,10 +103,10 @@
|
||||
<a href="addressbook.jsp?filter=y&begin=0&end=99">y</a>
|
||||
<a href="addressbook.jsp?filter=z&begin=0&end=99">z</a>
|
||||
<a href="addressbook.jsp?filter=0-9&begin=0&end=99">0-9</a>
|
||||
<a href="addressbook.jsp?filter=none&begin=0&end=99">all</a></p>
|
||||
<a href="addressbook.jsp?filter=none&begin=0&end=99"><%=intl._("all")%></a></p>
|
||||
<c:if test="${book.hasFilter}">
|
||||
<p>Current filter: ${book.filter}
|
||||
(<a href="addressbook.jsp?filter=none&begin=0&end=99">clear filter</a>)</p>
|
||||
<p><%=intl._("Current filter")%>: ${book.filter}
|
||||
(<a href="addressbook.jsp?filter=none&begin=0&end=99"><%=intl._("clear filter")%></a>)</p>
|
||||
</c:if>
|
||||
</div>
|
||||
|
||||
@ -106,8 +115,8 @@
|
||||
<input type="hidden" name="end" value="99">
|
||||
<div id="search">
|
||||
<table><tr>
|
||||
<td class="search">Search: <input type="text" name="search" value="${book.search}" size="20" ></td>
|
||||
<td class="search"><input type="image" src="images/search.png" name="submitsearch" value="search" alt="Search" ></td>
|
||||
<td class="search"><%=intl._("Search")%>: <input type="text" name="search" value="${book.search}" size="20" ></td>
|
||||
<td class="search"><input type="submit" name="submitsearch" value="<%=intl._("Search")%>" ></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
@ -131,17 +140,17 @@
|
||||
<th> </th>
|
||||
</c:if>
|
||||
|
||||
<th>Name</th>
|
||||
<th>Destination</th>
|
||||
<th><%=intl._("Name")%></th>
|
||||
<th><%=intl._("Destination")%></th>
|
||||
</tr>
|
||||
<!-- limit iterator, or "Form too large" may result on submit, and is a huge web page if we don't -->
|
||||
<c:forEach items="${book.entries}" var="addr" begin="${book.begin}" end="${book.end}">
|
||||
<tr class="list${book.trClass}">
|
||||
<c:if test="${book.master || book.router || book.published || book.private}">
|
||||
<td class="checkbox"><input type="checkbox" name="checked" value="${addr.name}" alt="Mark for deletion"></td>
|
||||
<td class="checkbox"><input type="checkbox" name="checked" value="${addr.name}" title="<%=intl._("Mark for deletion")%>"></td>
|
||||
</c:if>
|
||||
<td class="names"><a href="http://${addr.name}/">${addr.name}</a> -
|
||||
<span class="addrhlpr"><a href="http://${addr.name}/?i2paddresshelper=${addr.destination}">(addrhlpr)</a></span>
|
||||
<span class="addrhlpr">(<a href="http://${addr.name}/?i2paddresshelper=${addr.destination}"><%=intl._("address helper link")%></a>)</span>
|
||||
</td>
|
||||
<td class="destinations"><textarea rows="1" style="height: 3em;" cols="40" wrap="off" readonly="readonly" name="dest_${addr.name}" >${addr.destination}</textarea></td>
|
||||
</tr>
|
||||
@ -151,7 +160,7 @@
|
||||
|
||||
<c:if test="${book.master || book.router || book.published || book.private}">
|
||||
<div id="buttons">
|
||||
<p class="buttons"><input type="image" name="action" value="delete" src="images/delete.png" alt="Delete checked" >
|
||||
<p class="buttons"><input type="submit" name="action" value="<%=intl._("Delete")%>" >
|
||||
</p>
|
||||
</div>
|
||||
</c:if>
|
||||
@ -160,17 +169,17 @@
|
||||
|
||||
<c:if test="${book.isEmpty}">
|
||||
<div id="book">
|
||||
<p class="book">The ${book.book} addressbook is empty.</p>
|
||||
<p class="book"><%=intl._("This addressbook is empty.")%></p>
|
||||
</div>
|
||||
</c:if>
|
||||
|
||||
<div id="add">
|
||||
<p class="add">
|
||||
<h3>Add new destination:</h3>
|
||||
<b>Hostname:</b> <input type="text" name="hostname" value="${book.hostname}" size="20">
|
||||
<b>Destination:</b> <textarea name="destination" rows="1" style="height: 3em;" cols="40" wrap="off" >${book.destination}</textarea><br/>
|
||||
<h3><%=intl._("Add new destination")%>:</h3>
|
||||
<b><%=intl._("Hostname")%>:</b> <input type="text" name="hostname" value="${book.hostname}" size="20">
|
||||
<b><%=intl._("Destination")%>:</b> <textarea name="destination" rows="1" style="height: 3em;" cols="40" wrap="off" >${book.destination}</textarea><br/>
|
||||
</p><p>
|
||||
<input type="image" name="action" value="add" src="images/add.png" alt="Add destination" >
|
||||
<input type="submit" name="action" value="<%=intl._("Add")%>" >
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -22,16 +22,24 @@
|
||||
*
|
||||
* $Revision: 1.1 $
|
||||
*/
|
||||
|
||||
// http://www.crazysquirrel.com/computing/general/form-encoding.jspx
|
||||
if (request.getCharacterEncoding() == null)
|
||||
request.setCharacterEncoding("UTF-8");
|
||||
|
||||
%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<%@ page contentType="text/html" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<jsp:useBean id="version" class="i2p.susi.dns.VersionBean" scope="application"/>
|
||||
<jsp:useBean id="cfg" class="i2p.susi.dns.ConfigBean" scope="session"/>
|
||||
<jsp:useBean id="intl" class="i2p.susi.dns.Messages" scope="application" />
|
||||
<jsp:setProperty name="cfg" property="*" />
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>configuration - susidns v${version.version}</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title><%=intl._("configuration")%> - susidns</title>
|
||||
<link rel="stylesheet" type="text/css" href="css.css">
|
||||
</head>
|
||||
<body>
|
||||
@ -41,14 +49,14 @@
|
||||
</div><hr>
|
||||
<div id="navi">
|
||||
<p>
|
||||
addressbooks
|
||||
<a href="addressbook.jsp?book=master">master</a> |
|
||||
<a href="addressbook.jsp?book=router">router</a> |
|
||||
<a href="addressbook.jsp?book=published">published</a> |
|
||||
<a href="addressbook.jsp?book=private">private</a> *
|
||||
<a href="subscriptions.jsp">subscriptions</a> *
|
||||
configuration *
|
||||
<a href="index.jsp">overview</a>
|
||||
<%=intl._("addressbooks")%>
|
||||
<a href="addressbook.jsp?book=private"><%=intl._("private")%></a> |
|
||||
<a href="addressbook.jsp?book=master"><%=intl._("master")%></a> |
|
||||
<a href="addressbook.jsp?book=router"><%=intl._("router")%></a> |
|
||||
<a href="addressbook.jsp?book=published"><%=intl._("published")%></a> *
|
||||
<a href="subscriptions.jsp"><%=intl._("subscriptions")%></a> *
|
||||
<%=intl._("configuration")%> *
|
||||
<a href="index.jsp"><%=intl._("overview")%></a>
|
||||
</p>
|
||||
</div><hr>
|
||||
<div id="headline">
|
||||
@ -61,35 +69,63 @@ configuration *
|
||||
<textarea name="config" rows="10" cols="80">${cfg.config}</textarea>
|
||||
</div>
|
||||
<div id="buttons">
|
||||
<input type="image" src="images/save.png" name="action" value="save" alt="Save Config">
|
||||
<input type="image" src="images/reload.png" name="action" value="reload" alt="Reload Config">
|
||||
<input type="submit" name="action" value="<%=intl._("Save")%>" >
|
||||
<input type="submit" name="action" value="<%=intl._("Reload")%>" >
|
||||
</div>
|
||||
</form>
|
||||
<div id="help">
|
||||
<h3>Hints</h3>
|
||||
<h3><%=intl._("Hints")%></h3>
|
||||
<ol>
|
||||
<li>All file or directory paths here are relative to the addressbook's working directory, which normally
|
||||
is located at $I2P/addressbook/.</li>
|
||||
<li>If you want to manually add lines to an addressbook, add them to the private or master addressbooks. The router
|
||||
addressbook and the published addressbook are overwritten by the addressbook application.</li>
|
||||
<li><b>Important:</b>When you publish your addressbook, <b>ALL</b> destinations from the master and router addressbooks appear there.
|
||||
Use the private addressbook for private destinations, these are not published.
|
||||
<li>
|
||||
<%=intl._("File and directory paths here are relative to the addressbook's working directory, which is normally ~/.i2p/addressbook/ (Linux) or %APPDATA%\\I2P\\addressbook\\ (Windows).")%>
|
||||
</li>
|
||||
<li>
|
||||
<%=intl._("If you want to manually add lines to an addressbook, add them to the private or master addressbooks.")%>
|
||||
<%=intl._("The router addressbook and the published addressbook are updated by the addressbook application.")%>
|
||||
</li>
|
||||
<li>
|
||||
<%=intl._("When you publish your addressbook, ALL destinations from the master and router addressbooks appear there.")%>
|
||||
<%=intl._("Use the private addressbook for private destinations, these are not published.")%>
|
||||
</li>
|
||||
</ol>
|
||||
<h3>Options</h3>
|
||||
<h3><%=intl._("Options")%></h3>
|
||||
<ul>
|
||||
<li><b>subscriptions</b> - file containing the list of subscriptions URLs (no need to change)</li>
|
||||
<li><b>update_delay</b> - update interval in hours (no need to change)</li>
|
||||
<li><b>published_addressbook</b> - your public hosts.txt file (choose a path within your webserver document root)</li>
|
||||
<li><b>router_addressbook</b> - your hosts.txt (don't change)</li>
|
||||
<li><b>master_addressbook</b> - your personal addressbook, it never gets overwritten by the addressbook (don't change)</li>
|
||||
<li><b>private_addressbook</b> - your private addressbook, it is never published (defaults to ../privatehosts.txt, don't change)</li>
|
||||
<li><b>proxy_port</b> - http port for your eepProxy (no need to change)</li>
|
||||
<li><b>proxy_host</b> - hostname for your eepProxy (no need to change)</li>
|
||||
<li><b>should_publish</b> - true/false whether to write the published addressbook</li>
|
||||
<li><b>etags</b> - file containing the etags header from the fetched subscription URLs (no need to change)</li>
|
||||
<li><b>last_modified</b> - file containing the modification timestamp for each fetched subscription URL (no need to change)</li>
|
||||
<li><b>log</b> - file to log activity to (change to /dev/null if you like)</li>
|
||||
<li><b>subscriptions</b> -
|
||||
<%=intl._("File containing the list of subscriptions URLs (no need to change)")%>
|
||||
</li>
|
||||
<li><b>update_delay</b> -
|
||||
<%=intl._("Update interval in hours")%>
|
||||
</li>
|
||||
<li><b>published_addressbook</b> -
|
||||
<%=intl._("Your public hosts.txt file (choose a path within your webserver document root)")%>
|
||||
</li>
|
||||
<li><b>router_addressbook</b> -
|
||||
<%=intl._("Your hosts.txt (don't change)")%>
|
||||
</li>
|
||||
<li><b>master_addressbook</b> -
|
||||
<%=intl._("Your personal addressbook, these hosts will be published")%>
|
||||
</li>
|
||||
<li><b>private_addressbook</b> -
|
||||
<%=intl._("Your private addressbook, it is never published")%>
|
||||
</li>
|
||||
<li><b>proxy_port</b> -
|
||||
<%=intl._("Port for your eepProxy (no need to change)")%>
|
||||
</li>
|
||||
<li><b>proxy_host</b> -
|
||||
<%=intl._("Hostname for your eepProxy (no need to change)")%>
|
||||
</li>
|
||||
<li><b>should_publish</b> -
|
||||
<%=intl._("Whether to update the published addressbook")%>
|
||||
</li>
|
||||
<li><b>etags</b> -
|
||||
<%=intl._("File containing the etags header from the fetched subscription URLs (no need to change)")%>
|
||||
</li>
|
||||
<li><b>last_modified</b> -
|
||||
<%=intl._("File containing the modification timestamp for each fetched subscription URL (no need to change)")%>
|
||||
</li>
|
||||
<li><b>log</b> -
|
||||
<%=intl._("File to log activity to (change to /dev/null if you like)")%>
|
||||
</li>
|
||||
</ul>
|
||||
</div><hr>
|
||||
<div id="footer">
|
||||
|
@ -22,14 +22,22 @@
|
||||
*
|
||||
* $Revision: 1.2 $
|
||||
*/
|
||||
|
||||
// http://www.crazysquirrel.com/computing/general/form-encoding.jspx
|
||||
if (request.getCharacterEncoding() == null)
|
||||
request.setCharacterEncoding("UTF-8");
|
||||
|
||||
%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<%@ page contentType="text/html"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<jsp:useBean id="version" class="i2p.susi.dns.VersionBean" scope="application" />
|
||||
<jsp:useBean id="intl" class="i2p.susi.dns.Messages" scope="application" />
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>introduction - susidns v${version.version}</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title><%=intl._("Introduction")%> - SusiDNS</title>
|
||||
<link rel="stylesheet" type="text/css" href="css.css">
|
||||
</head>
|
||||
<body>
|
||||
@ -39,40 +47,40 @@
|
||||
</div>
|
||||
<hr>
|
||||
<div id="navi">
|
||||
<p>addressbooks
|
||||
<a href="addressbook.jsp?book=master">master</a> |
|
||||
<a href="addressbook.jsp?book=router">router</a> |
|
||||
<a href="addressbook.jsp?book=published">published</a> |
|
||||
<a href="addressbook.jsp?book=private">private</a> *
|
||||
<a href="subscriptions.jsp">subscriptions</a> *
|
||||
<a href="config.jsp">configuration</a> *
|
||||
overview
|
||||
<p>
|
||||
<%=intl._("addressbooks")%>
|
||||
<a href="addressbook.jsp?book=private"><%=intl._("private")%></a> |
|
||||
<a href="addressbook.jsp?book=master"><%=intl._("master")%></a> |
|
||||
<a href="addressbook.jsp?book=router"><%=intl._("router")%></a> |
|
||||
<a href="addressbook.jsp?book=published"><%=intl._("published")%></a> *
|
||||
<a href="subscriptions.jsp"><%=intl._("subscriptions")%></a> *
|
||||
<a href="config.jsp"><%=intl._("configuration")%></a> *
|
||||
<%=intl._("overview")%>
|
||||
</p>
|
||||
</div>
|
||||
<hr>
|
||||
<div id="content">
|
||||
<h3>Huh? what addressbook?</h3>
|
||||
<h3><%=intl._("What is the addressbook?")%></h3>
|
||||
<p>
|
||||
The addressbook application is part of your i2p installation. It regularly updates your hosts.txt file
|
||||
from distributed sources. It keeps your hosts.txt up to date, so it can automatically add
|
||||
eepsites announced on other sites if you subscribe to those sites' addressbooks.
|
||||
<%=intl._("The addressbook application is part of your i2p installation.")%>
|
||||
<%=intl._("It regularly updates your hosts.txt file from distributed sources or \"subscriptions\".")%>
|
||||
</p>
|
||||
<p>
|
||||
(To speak the truth: In its default configuration the addressbook does not poll
|
||||
additional sites, but www.i2p2.i2p only. Subscribing to additional sites is an easy task,
|
||||
just add them to your <a href="subscriptions.jsp">subscriptions</a> file.)
|
||||
<%=intl._("In the default configuration, the addressbook is only subscribed to www.i2p2.i2p.")%>
|
||||
<%=intl._("Subscribing to additional sites is easy, just add them to your <a href=\"subscriptions.jsp\">subscriptions</a> file.")%>
|
||||
</p>
|
||||
<p>If you have questions about naming in i2p, there is an excellent <a href="http://forum.i2p/viewtopic.php?t=134">introduction</a>
|
||||
from duck in the forum and <a href="http://www.i2p2.i2p/naming.html">additional information on www.i2p2.i2p</a>.</p>
|
||||
<h3>How does the addressbook work?</h3>
|
||||
<p>The addressbook application regularly (normally once per hour) polls your subscriptions and merges their content
|
||||
into your so-called router addressbook (normally your plain hosts.txt). Then it merges your so-called master addressbook (normally
|
||||
your userhosts.txt) into the router addressbook as well. If configured, the router addressbook is now written to the published addressbook,
|
||||
which is a publicly available copy of your hosts.txt somewhere in your eepsite's document root.
|
||||
<p>
|
||||
<%=intl._("For more information on naming in i2p, see <a href=\"http://www.i2p2.i2p/naming.html\">the overview on www.i2p2.i2p</a>.")%>
|
||||
</p>
|
||||
<h3><%=intl._("How does the addressbook work?")%></h3>
|
||||
<p>
|
||||
<%=intl._("The addressbook application regularly polls your subscriptions and merges their content into your \"router\" addressbook, stored in the hosts.txt file.")%>
|
||||
<%=intl._("Then it merges your \"master\" addressbook (userhosts.txt) into the router addressbook as well.")%>
|
||||
<%=intl._("If configured, the router addressbook is now written to the \"published\" addressbook, which will be publicly available if you are running an eepsite.")%>
|
||||
</p><p>
|
||||
The router also uses a private addressbook (privatehosts.txt, not shown in the picture), which is not merged or published.
|
||||
Hosts in the private addressbook can be accessed by you but their addresses are never distributed to others.
|
||||
The private addressbook can also be used for aliases of hosts in your other addressbooks.
|
||||
<%=intl._("The router also uses a private addressbook (privatehosts.txt, not shown in the picture), which is not merged or published.")%>
|
||||
<%=intl._("Hosts in the private addressbook can be accessed by you but their addresses are never distributed to others.")%>
|
||||
<%=intl._("The private addressbook can also be used for aliases of hosts in your other addressbooks.")%>
|
||||
</p>
|
||||
<p><center><img src="images/how.png" border="0" alt="addressbook working scheme" title="How the addressbook works" class="illustrate" /></center></p>
|
||||
</div>
|
||||
|
@ -22,16 +22,24 @@
|
||||
*
|
||||
* $Revision: 1.2 $
|
||||
*/
|
||||
|
||||
// http://www.crazysquirrel.com/computing/general/form-encoding.jspx
|
||||
if (request.getCharacterEncoding() == null)
|
||||
request.setCharacterEncoding("UTF-8");
|
||||
|
||||
%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<%@ page contentType="text/html"%>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
||||
<jsp:useBean id="version" class="i2p.susi.dns.VersionBean" scope="application" />
|
||||
<jsp:useBean id="subs" class="i2p.susi.dns.SubscriptionsBean" scope="session" />
|
||||
<jsp:useBean id="intl" class="i2p.susi.dns.Messages" scope="application" />
|
||||
<jsp:setProperty name="subs" property="*" />
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>subscriptions - susidns v${version.version}</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title><%=intl._("subscriptions")%> - susidns</title>
|
||||
<link rel="stylesheet" type="text/css" href="css.css">
|
||||
</head>
|
||||
<body>
|
||||
@ -40,14 +48,15 @@
|
||||
<img src="images/logo.png" alt="susidns logo" border="0"/>
|
||||
</div><hr>
|
||||
<div id="navi">
|
||||
<p>addressbooks
|
||||
<a href="addressbook.jsp?book=master">master</a> |
|
||||
<a href="addressbook.jsp?book=router">router</a> |
|
||||
<a href="addressbook.jsp?book=published">published</a> |
|
||||
<a href="addressbook.jsp?book=private">private</a> *
|
||||
subscriptions *
|
||||
<a href="config.jsp">configuration</a> *
|
||||
<a href="index.jsp">overview</a>
|
||||
<p>
|
||||
<%=intl._("addressbooks")%>
|
||||
<a href="addressbook.jsp?book=private"><%=intl._("private")%></a> |
|
||||
<a href="addressbook.jsp?book=master"><%=intl._("master")%></a> |
|
||||
<a href="addressbook.jsp?book=router"><%=intl._("router")%></a> |
|
||||
<a href="addressbook.jsp?book=published"><%=intl._("published")%></a> *
|
||||
<%=intl._("subscriptions")%> *
|
||||
<a href="config.jsp"><%=intl._("configuration")%></a> *
|
||||
<a href="index.jsp"><%=intl._("overview")%></a>
|
||||
</p>
|
||||
</div><hr>
|
||||
<div id="headline">
|
||||
@ -60,18 +69,18 @@ subscriptions *
|
||||
<textarea name="content" rows="10" cols="80">${subs.content}</textarea>
|
||||
</div>
|
||||
<div id="buttons">
|
||||
<input type="image" src="images/save.png" name="action" value="save" alt="Save Subscriptions" >
|
||||
<input type="image" src="images/reload.png" name="action" value="reload" alt="Reload Subscriptions" >
|
||||
<input type="submit" name="action" value="<%=intl._("Save")%>" >
|
||||
<input type="submit" name="action" value="<%=intl._("Reload")%>" >
|
||||
</div>
|
||||
</form>
|
||||
<div id="help">
|
||||
<h3>Explanation</h3>
|
||||
<p class="help">
|
||||
The subscription file contains a list of (i2p) URLs. The addressbook application
|
||||
regularly (once per hour) checks this list for new eepsites. Those URLs simply contain the published hosts.txt
|
||||
file of other people. The default subscription is the hosts.txt from www.i2p2.i2p, which is updated infrequently.
|
||||
So it is a good idea to add additional subscriptions to sites that have the latest addresses.
|
||||
<a href="http://www.i2p2.i2p/faq.html#subscriptions">See the FAQ for a list of subscription URLs.</a>
|
||||
<%=intl._("The subscription file contains a list of i2p URLs.")%>
|
||||
<%=intl._("The addressbook application regularly checks this list for new eepsites.")%>
|
||||
<%=intl._("Those URLs refer to published hosts.txt files.")%>
|
||||
<%=intl._("The default subscription is the hosts.txt from www.i2p2.i2p, which is updated infrequently.")%>
|
||||
<%=intl._("So it is a good idea to add additional subscriptions to sites that have the latest addresses.")%>
|
||||
<a href="http://www.i2p2.i2p/faq.html#subscriptions"><%=intl._("See the FAQ for a list of subscription URLs.")%></a>
|
||||
</p>
|
||||
</div><hr>
|
||||
<div id="footer">
|
||||
|
26
build.xml
26
build.xml
@ -141,6 +141,9 @@
|
||||
</target>
|
||||
<target name="poupdate">
|
||||
<ant dir="apps/routerconsole/java/" target="poupdate" />
|
||||
<ant dir="apps/i2psnark/java/" target="poupdate" />
|
||||
<ant dir="apps/i2ptunnel/java/" target="poupdate" />
|
||||
<ant dir="apps/susidns/src/" target="poupdate" />
|
||||
</target>
|
||||
<target name="javadoc">
|
||||
<mkdir dir="./build" />
|
||||
@ -205,6 +208,7 @@
|
||||
<ant dir="apps/susidns/src/" target="distclean" />
|
||||
<ant dir="apps/systray/java/" target="distclean" />
|
||||
<ant dir="apps/i2psnark/java/" target="distclean" />
|
||||
<ant dir="apps/jetty/" target="distclean" />
|
||||
<delete>
|
||||
<fileset dir="." includes="**/*.class" />
|
||||
<fileset dir="." includes="**/*.java~" />
|
||||
@ -285,9 +289,10 @@
|
||||
<copy todir="pkg-temp/lib/wrapper/win32/">
|
||||
<fileset dir="installer/lib/wrapper/win32/" />
|
||||
</copy>
|
||||
<copy file="hosts.txt" todir="pkg-temp/" />
|
||||
<copy file="installer/resources/hosts.txt" todir="pkg-temp/" />
|
||||
<copy file="INSTALL-headless.txt" todir="pkg-temp/" />
|
||||
<copy file="history.txt" todir="pkg-temp/" />
|
||||
<!-- overwrite the truncated history put in by the updater -->
|
||||
<copy file="history.txt" todir="pkg-temp/" overwrite="true" />
|
||||
<mkdir dir="pkg-temp/scripts" />
|
||||
<copy file="apps/proxyscript/i2pProxy.pac" todir="pkg-temp/scripts/" />
|
||||
<!-- test classes aren't in the jars anymore
|
||||
@ -343,19 +348,19 @@
|
||||
</copy>
|
||||
<!-- make a "classic" theme -->
|
||||
<copy todir="pkg-temp/docs/themes/console/classic/" >
|
||||
<fileset dir="installer/resources/themes/console/classic/" />
|
||||
<fileset dir="installer/resources/themes/console/classic/" excludes="**/i2plogo.png" />
|
||||
</copy>
|
||||
<!-- Add dark theme -->
|
||||
<copy todir="pkg-temp/docs/themes/console/dark/" >
|
||||
<fileset dir="installer/resources/themes/console/dark/" />
|
||||
<fileset dir="installer/resources/themes/console/dark/" excludes="**/i2plogo.png" />
|
||||
</copy>
|
||||
<!-- Add light theme -->
|
||||
<copy todir="pkg-temp/docs/themes/console/light/" >
|
||||
<fileset dir="installer/resources/themes/console/light/" />
|
||||
<fileset dir="installer/resources/themes/console/light/" excludes="**/i2plogo.png" />
|
||||
</copy>
|
||||
<!-- Add midnight theme -->
|
||||
<copy todir="pkg-temp/docs/themes/console/midnight/" >
|
||||
<fileset dir="installer/resources/themes/console/midnight/" />
|
||||
<fileset dir="installer/resources/themes/console/midnight/" excludes="**/i2plogo.png" />
|
||||
</copy>
|
||||
<!-- Add shared images.. these are subject to flux and change! -->
|
||||
<copy todir="pkg-temp/docs/themes/console/images/" >
|
||||
@ -409,6 +414,15 @@
|
||||
<copy file="build/susidns.war" todir="pkg-temp/webapps/" />
|
||||
<copy file="build/i2psnark.war" todir="pkg-temp/webapps/" />
|
||||
<copy file="history.txt" todir="pkg-temp/" />
|
||||
<!-- the following overwrites history.txt on unix to shrink the update file -->
|
||||
<exec executable="head" osfamily="unix" failifexecutionfails="true" output="pkg-temp/history.txt">
|
||||
<arg value="-n" />
|
||||
<arg value="1500" />
|
||||
<arg value="history.txt" />
|
||||
</exec>
|
||||
<exec executable="echo" osfamily="unix" failifexecutionfails="true" output="pkg-temp/history.txt" append="true">
|
||||
<arg value="EARLIER HISTORY IS AVAILABLE IN THE SOURCE PACKAGE" />
|
||||
</exec>
|
||||
<!-- may be pointless now, people with split directories will never see this -->
|
||||
<copy file="installer/resources/news.xml" todir="pkg-temp/docs/" />
|
||||
</target>
|
||||
|
@ -16,7 +16,7 @@ package net.i2p;
|
||||
public class CoreVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Monotone";
|
||||
public final static String VERSION = "0.7.7";
|
||||
public final static String VERSION = "0.7.8";
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Core version: " + VERSION);
|
||||
|
@ -432,12 +432,14 @@ public class I2PAppContext {
|
||||
}
|
||||
}
|
||||
|
||||
/** @deprecated unused */
|
||||
public PetNameDB petnameDb() {
|
||||
if (!_petnameDbInitialized)
|
||||
initializePetnameDb();
|
||||
return _petnameDb;
|
||||
}
|
||||
|
||||
/** @deprecated unused */
|
||||
private void initializePetnameDb() {
|
||||
synchronized (this) {
|
||||
if (_petnameDb == null) {
|
||||
@ -720,4 +722,11 @@ public class I2PAppContext {
|
||||
return new HashSet(_shutdownTasks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this instead of context instanceof RouterContext
|
||||
* @since 0.7.9
|
||||
*/
|
||||
public boolean isRouterContext() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user