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
|
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
|
To build and install I2P from source, you must first build
|
||||||
and package up the appropriate installer by running:
|
and package up the appropriate installer by running:
|
||||||
|
|
||||||
ant pkg
|
ant pkg
|
||||||
|
|
||||||
|
|
||||||
This will produce a few key files:
|
This will produce a few key files:
|
||||||
* install.jar: the GUI and console installer
|
* install.jar: the GUI and console installer
|
||||||
* i2pinstall.exe: the GUI and console installer wrapped for cross-platform execution
|
* 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.
|
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:
|
Supported JVMs:
|
||||||
Windows: Latest available from http://java.sun.com/ (1.5+ supported)
|
Windows: Latest available from http://java.sun.com/ (1.5+ supported)
|
||||||
Linux: 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:
|
Prerequisites to build from source:
|
||||||
Java SDK (preferably Sun) 1.5.0 or higher (1.6 recommended)
|
Java SDK (preferably Sun) 1.5.0 or higher (1.6 recommended)
|
||||||
Apache Ant 1.7.0 or higher
|
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:
|
To build:
|
||||||
ant pkg
|
ant pkg
|
||||||
Run 'ant' with no arguments to see other build options.
|
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:
|
Documentation:
|
||||||
http://www.i2p2.de/
|
http://www.i2p2.de/
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
|
||||||
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
|
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
|
||||||
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/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>
|
</open-files>
|
||||||
</project-private>
|
</project-private>
|
||||||
|
@ -50,7 +50,7 @@ public class DoCMDS implements Runnable {
|
|||||||
|
|
||||||
// FIX ME
|
// FIX ME
|
||||||
// I need a better way to do versioning, but this will do for now.
|
// 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;
|
public static final String BOBversion = BMAJ + "." + BMIN + "." + BREV + BEXT;
|
||||||
private Socket server;
|
private Socket server;
|
||||||
private Properties props;
|
private Properties props;
|
||||||
|
@ -60,20 +60,9 @@ public class I2Plistener implements Runnable {
|
|||||||
this._log = _log;
|
this._log = _log;
|
||||||
this.socketManager = S;
|
this.socketManager = S;
|
||||||
this.serverSocket = SS;
|
this.serverSocket = SS;
|
||||||
// tgwatch = 1;
|
|
||||||
this.lives = lives;
|
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
|
* Simply listen on I2P port, and thread connections
|
||||||
*
|
*
|
||||||
@ -83,34 +72,31 @@ public class I2Plistener implements Runnable {
|
|||||||
I2PSocket sessSocket = null;
|
I2PSocket sessSocket = null;
|
||||||
int conn = 0;
|
int conn = 0;
|
||||||
try {
|
try {
|
||||||
die:
|
try {
|
||||||
{
|
serverSocket.setSoTimeout(50);
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
while (lives.get()) {
|
||||||
|
try {
|
||||||
|
sessSocket = serverSocket.accept();
|
||||||
|
g = true;
|
||||||
|
} catch (ConnectException ce) {
|
||||||
|
g = false;
|
||||||
|
} catch (SocketTimeoutException ste) {
|
||||||
|
g = false;
|
||||||
}
|
}
|
||||||
} catch (I2PException e) {
|
if (g) {
|
||||||
// bad shit
|
g = false;
|
||||||
System.out.println("Exception " + e);
|
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 {
|
} finally {
|
||||||
try {
|
try {
|
||||||
|
@ -104,10 +104,10 @@ public class MUXlisten implements Runnable {
|
|||||||
this.database.releaseReadLock();
|
this.database.releaseReadLock();
|
||||||
this.info.releaseReadLock();
|
this.info.releaseReadLock();
|
||||||
|
|
||||||
socketManager = I2PSocketManagerFactory.createManager(prikey, Q);
|
|
||||||
if (this.come_in) {
|
if (this.come_in) {
|
||||||
this.listener = new ServerSocket(port, backlog, host);
|
this.listener = new ServerSocket(port, backlog, host);
|
||||||
}
|
}
|
||||||
|
socketManager = I2PSocketManagerFactory.createManager(prikey, Q);
|
||||||
// I2PException, IOException, RuntimeException
|
// I2PException, IOException, RuntimeException
|
||||||
// To bad we can't just catch and enumerate....
|
// To bad we can't just catch and enumerate....
|
||||||
// } catch (I2PException e) {
|
// } catch (I2PException e) {
|
||||||
@ -141,8 +141,6 @@ public class MUXlisten implements Runnable {
|
|||||||
this.info.add("STARTING", new Boolean(false));
|
this.info.add("STARTING", new Boolean(false));
|
||||||
this.info.releaseWriteLock();
|
this.info.releaseWriteLock();
|
||||||
this.database.releaseWriteLock();
|
this.database.releaseWriteLock();
|
||||||
// throw new Exception(e);
|
|
||||||
// Debugging, I guess.
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -78,16 +78,20 @@ public class TCPio implements Runnable {
|
|||||||
* --Sponge
|
* --Sponge
|
||||||
*
|
*
|
||||||
* Tested with 128 bytes, and there was no performance gain.
|
* 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
|
* --Sponge
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int b;
|
int b;
|
||||||
byte a[] = new byte[1];
|
byte a[] = new byte[8192];
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
while (lives.get()) {
|
while (lives.get()) {
|
||||||
b = Ain.read(a, 0, 1);
|
b = Ain.read(a, 0, 8192);
|
||||||
if (b > 0) {
|
if (b > 0) {
|
||||||
Aout.write(a, 0, b);
|
Aout.write(a, 0, b);
|
||||||
} else if (b == 0) {
|
} else if (b == 0) {
|
||||||
|
@ -64,16 +64,6 @@ public class TCPlistener implements Runnable {
|
|||||||
this.lives = lives;
|
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
|
* Simply listen on TCP port, and thread connections
|
||||||
*
|
*
|
||||||
@ -81,30 +71,27 @@ public class TCPlistener implements Runnable {
|
|||||||
public void run() {
|
public void run() {
|
||||||
boolean g = false;
|
boolean g = false;
|
||||||
int conn = 0;
|
int conn = 0;
|
||||||
|
Socket server = null;
|
||||||
try {
|
try {
|
||||||
die:
|
try {
|
||||||
{
|
listener.setSoTimeout(50); // We don't block, we cycle and check.
|
||||||
try {
|
while (lives.get()) {
|
||||||
Socket server = new Socket();
|
try {
|
||||||
listener.setSoTimeout(50); // We don't block, we cycle and check.
|
server = listener.accept();
|
||||||
while (lives.get()) {
|
g = true;
|
||||||
try {
|
} catch (SocketTimeoutException ste) {
|
||||||
server = listener.accept();
|
g = false;
|
||||||
g = true;
|
}
|
||||||
} catch (SocketTimeoutException ste) {
|
if (g) {
|
||||||
g = false;
|
conn++;
|
||||||
}
|
// toss the connection to a new thread.
|
||||||
if (g) {
|
TCPtoI2P conn_c = new TCPtoI2P(socketManager, server, info, database, lives);
|
||||||
conn++;
|
Thread t = new Thread(conn_c, Thread.currentThread().getName() + " TCPtoI2P " + conn);
|
||||||
// toss the connection to a new thread.
|
t.start();
|
||||||
TCPtoI2P conn_c = new TCPtoI2P(socketManager, server, info, database, lives);
|
g = false;
|
||||||
Thread t = new Thread(conn_c, Thread.currentThread().getName() + " TCPtoI2P " + conn);
|
|
||||||
t.start();
|
|
||||||
g = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) {
|
|
||||||
}
|
}
|
||||||
|
} catch (IOException ioe) {
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
|
@ -21,24 +21,48 @@
|
|||||||
|
|
||||||
package net.i2p.addressbook;
|
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.ServletConfig;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper for addressbook to allow it to be started as a web application.
|
* 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
|
* @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)
|
/* (non-Javadoc)
|
||||||
@ -49,15 +73,19 @@ public class Servlet extends GenericServlet {
|
|||||||
try {
|
try {
|
||||||
super.init(config);
|
super.init(config);
|
||||||
} catch (ServletException exp) {
|
} 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];
|
String[] args = new String[1];
|
||||||
args[0] = config.getInitParameter("home");
|
args[0] = config.getInitParameter("home");
|
||||||
DaemonThread thread = new DaemonThread(args);
|
this.thread = new DaemonThread(args);
|
||||||
thread.setDaemon(true);
|
this.thread.setDaemon(true);
|
||||||
thread.setName("Addressbook");
|
this.thread.setName("Addressbook");
|
||||||
thread.start();
|
this.thread.start();
|
||||||
System.out.println("INFO: Starting Addressbook " + Daemon.VERSION);
|
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>
|
</init-param>
|
||||||
<load-on-startup>1</load-on-startup>
|
<load-on-startup>1</load-on-startup>
|
||||||
</servlet>
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>addressbook</servlet-name>
|
||||||
|
<url-pattern>/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
</web-app>
|
</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>
|
</javac>
|
||||||
</target>
|
</target>
|
||||||
<target name="jar" depends="builddep, compile">
|
<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>
|
<manifest>
|
||||||
<attribute name="Main-Class" value="org.klomp.snark.Snark" />
|
<attribute name="Main-Class" value="org.klomp.snark.Snark" />
|
||||||
<attribute name="Class-Path" value="i2p.jar mstreaming.jar streaming.jar" />
|
<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.
|
- So we must continue to duplicate everything in the war.
|
||||||
<classes dir="./build/obj" includes="**/I2PSnarkServlet*.class" />
|
<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">
|
<war destfile="../i2psnark.war" webxml="../web.xml">
|
||||||
<classes dir="./build/obj" includes="**/*.class" excludes="**/RunStandalone.class" />
|
<classes dir="./build/obj" includes="**/*.class" excludes="**/RunStandalone.class" />
|
||||||
</war>
|
</war>
|
||||||
</target>
|
</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">
|
<target name="standalone" depends="standalone_prep">
|
||||||
<zip destfile="i2psnark-standalone.zip">
|
<zip destfile="i2psnark-standalone.zip">
|
||||||
<zipfileset dir="./dist/" prefix="i2psnark/" />
|
<zipfileset dir="./dist/" prefix="i2psnark/" />
|
||||||
@ -95,9 +127,7 @@
|
|||||||
<delete dir="./dist" />
|
<delete dir="./dist" />
|
||||||
</target>
|
</target>
|
||||||
<target name="cleandep" depends="clean">
|
<target name="cleandep" depends="clean">
|
||||||
<ant dir="../../ministreaming/java/" target="distclean" />
|
|
||||||
</target>
|
</target>
|
||||||
<target name="distclean" depends="clean">
|
<target name="distclean" depends="clean">
|
||||||
<ant dir="../../ministreaming/java/" target="distclean" />
|
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</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.Log;
|
||||||
import net.i2p.util.SimpleScheduler;
|
import net.i2p.util.SimpleScheduler;
|
||||||
import net.i2p.util.SimpleTimer;
|
import net.i2p.util.SimpleTimer;
|
||||||
|
import net.i2p.util.Translate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* I2P specific helpers for I2PSnark
|
* I2P specific helpers for I2PSnark
|
||||||
@ -402,4 +403,32 @@ public class I2PSnarkUtil {
|
|||||||
break;
|
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.data.DataHelper;
|
||||||
import net.i2p.util.I2PAppThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
import net.i2p.util.OrderedProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage multiple snarks
|
* Manage multiple snarks
|
||||||
@ -80,7 +81,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
_peerCoordinatorSet = new PeerCoordinatorSet();
|
_peerCoordinatorSet = new PeerCoordinatorSet();
|
||||||
_connectionAcceptor = new ConnectionAcceptor(_util);
|
_connectionAcceptor = new ConnectionAcceptor(_util);
|
||||||
int minutes = getStartupDelayMinutes();
|
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");
|
I2PAppThread monitor = new I2PAppThread(new DirMonitor(), "Snark DirMonitor");
|
||||||
monitor.setDaemon(true);
|
monitor.setDaemon(true);
|
||||||
monitor.start();
|
monitor.start();
|
||||||
@ -126,7 +127,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
/** null to set initial defaults */
|
/** null to set initial defaults */
|
||||||
public void loadConfig(String filename) {
|
public void loadConfig(String filename) {
|
||||||
if (_config == null)
|
if (_config == null)
|
||||||
_config = new Properties();
|
_config = new OrderedProperties();
|
||||||
if (filename != null) {
|
if (filename != null) {
|
||||||
File cfg = new File(filename);
|
File cfg = new File(filename);
|
||||||
if (!cfg.isAbsolute())
|
if (!cfg.isAbsolute())
|
||||||
@ -216,6 +217,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
String upLimit, String upBW, boolean useOpenTrackers, String openTrackers) {
|
String upLimit, String upBW, boolean useOpenTrackers, String openTrackers) {
|
||||||
boolean changed = false;
|
boolean changed = false;
|
||||||
if (eepHost != null) {
|
if (eepHost != null) {
|
||||||
|
// unused, we use socket eepget
|
||||||
int port = _util.getEepProxyPort();
|
int port = _util.getEepProxyPort();
|
||||||
try { port = Integer.parseInt(eepPort); } catch (NumberFormatException nfe) {}
|
try { port = Integer.parseInt(eepPort); } catch (NumberFormatException nfe) {}
|
||||||
String host = _util.getEepProxyHost();
|
String host = _util.getEepProxyHost();
|
||||||
@ -236,9 +238,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
_util.setMaxUploaders(limit);
|
_util.setMaxUploaders(limit);
|
||||||
changed = true;
|
changed = true;
|
||||||
_config.setProperty(PROP_UPLOADERS_TOTAL, "" + limit);
|
_config.setProperty(PROP_UPLOADERS_TOTAL, "" + limit);
|
||||||
addMessage("Total uploaders limit changed to " + limit);
|
addMessage(_("Total uploaders limit changed to {0}", limit));
|
||||||
} else {
|
} 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);
|
_util.setMaxUpBW(limit);
|
||||||
changed = true;
|
changed = true;
|
||||||
_config.setProperty(PROP_UPBW_MAX, "" + limit);
|
_config.setProperty(PROP_UPBW_MAX, "" + limit);
|
||||||
addMessage("Up BW limit changed to " + limit + "KBps");
|
addMessage(_("Up BW limit changed to {0}KBps", limit));
|
||||||
} else {
|
} 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) {
|
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
|
_log.debug("i2cp host [" + i2cpHost + "] i2cp port " + port + " opts [" + opts
|
||||||
+ "] oldOpts [" + oldOpts + "]");
|
+ "] oldOpts [" + oldOpts + "]");
|
||||||
} else {
|
} else {
|
||||||
if (_util.connected()) {
|
if (_util.connected()) {
|
||||||
_util.disconnect();
|
_util.disconnect();
|
||||||
addMessage("Disconnecting old I2CP destination");
|
addMessage(_("Disconnecting old I2CP destination"));
|
||||||
}
|
}
|
||||||
Properties p = new Properties();
|
Properties p = new Properties();
|
||||||
p.putAll(opts);
|
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);
|
_util.setI2CPConfig(i2cpHost, port, p);
|
||||||
boolean ok = _util.connect();
|
boolean ok = _util.connect();
|
||||||
if (!ok) {
|
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);
|
_util.setI2CPConfig(oldI2CPHost, oldI2CPPort, oldOpts);
|
||||||
ok = _util.connect();
|
ok = _util.connect();
|
||||||
if (!ok)
|
if (!ok)
|
||||||
addMessage("Unable to reconnect with the old settings!");
|
addMessage(_("Unable to reconnect with the old settings!"));
|
||||||
} else {
|
} 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_HOST, i2cpHost.trim());
|
||||||
_config.setProperty(PROP_I2CP_PORT, "" + port);
|
_config.setProperty(PROP_I2CP_PORT, "" + port);
|
||||||
_config.setProperty(PROP_I2CP_OPTS, i2cpOpts.trim());
|
_config.setProperty(PROP_I2CP_OPTS, i2cpOpts.trim());
|
||||||
@ -327,7 +329,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
Snark snark = getTorrent(name);
|
Snark snark = getTorrent(name);
|
||||||
if ( (snark != null) && (snark.acceptor != null) ) {
|
if ( (snark != null) && (snark.acceptor != null) ) {
|
||||||
snark.acceptor.restart();
|
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) {
|
if (shouldAutoStart() != autoStart) {
|
||||||
_config.setProperty(PROP_AUTO_START, autoStart + "");
|
_config.setProperty(PROP_AUTO_START, autoStart + "");
|
||||||
addMessage("Adjusted autostart to " + autoStart);
|
if (autoStart)
|
||||||
|
addMessage(_("Enabled autostart"));
|
||||||
|
else
|
||||||
|
addMessage(_("Disabled autostart"));
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (_util.shouldUseOpenTrackers() != useOpenTrackers) {
|
if (_util.shouldUseOpenTrackers() != useOpenTrackers) {
|
||||||
_config.setProperty(I2PSnarkUtil.PROP_USE_OPENTRACKERS, 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;
|
changed = true;
|
||||||
}
|
}
|
||||||
if (openTrackers != null) {
|
if (openTrackers != null) {
|
||||||
if (openTrackers.trim().length() > 0 && !openTrackers.trim().equals(_util.getOpenTrackerString())) {
|
if (openTrackers.trim().length() > 0 && !openTrackers.trim().equals(_util.getOpenTrackerString())) {
|
||||||
_config.setProperty(I2PSnarkUtil.PROP_OPENTRACKERS, openTrackers.trim());
|
_config.setProperty(I2PSnarkUtil.PROP_OPENTRACKERS, openTrackers.trim());
|
||||||
_util.setOpenTrackerString(openTrackers);
|
_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;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
saveConfig();
|
saveConfig();
|
||||||
} else {
|
} else {
|
||||||
addMessage("Configuration unchanged.");
|
addMessage(_("Configuration unchanged."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,7 +374,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
DataHelper.storeProps(_config, _configFile);
|
DataHelper.storeProps(_config, _configFile);
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) {
|
} 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) { addTorrent(filename, false); }
|
||||||
public void addTorrent(String filename, boolean dontAutoStart) {
|
public void addTorrent(String filename, boolean dontAutoStart) {
|
||||||
if ((!dontAutoStart) && !_util.connected()) {
|
if ((!dontAutoStart) && !_util.connected()) {
|
||||||
addMessage("Connecting to I2P");
|
addMessage(_("Connecting to I2P"));
|
||||||
boolean ok = _util.connect();
|
boolean ok = _util.connect();
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
addMessage("Error connecting to I2P - check your I2CP settings!");
|
addMessage(_("Error connecting to I2P - check your I2CP settings!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,7 +404,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
filename = sfile.getCanonicalPath();
|
filename = sfile.getCanonicalPath();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
_log.error("Unable to add the torrent " + filename, 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;
|
return;
|
||||||
}
|
}
|
||||||
File dataDir = getDataDir();
|
File dataDir = getDataDir();
|
||||||
@ -435,7 +443,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) {
|
} 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())
|
if (sfile.exists())
|
||||||
sfile.delete();
|
sfile.delete();
|
||||||
return;
|
return;
|
||||||
@ -450,9 +458,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
File f = new File(filename);
|
File f = new File(filename);
|
||||||
if (!dontAutoStart && shouldAutoStart()) {
|
if (!dontAutoStart && shouldAutoStart()) {
|
||||||
torrent.startTorrent();
|
torrent.startTorrent();
|
||||||
addMessage("Torrent added and started: '" + f.getName() + "'.");
|
addMessage(_("Torrent added and started: \"{0}\"", f.getName()));
|
||||||
} else {
|
} 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
|
// basic validation of url
|
||||||
if ((!announce.startsWith("http://")) ||
|
if ((!announce.startsWith("http://")) ||
|
||||||
(announce.indexOf(".i2p/") < 0)) // need to do better than this
|
(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();
|
List files = info.getFiles();
|
||||||
if ( (files != null) && (files.size() > MAX_FILES_PER_TORRENT) ) {
|
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")) ) {
|
} 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) {
|
} 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) {
|
} 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) {
|
} else if (info.getPieceLength(0) > Storage.MAX_PIECE_SIZE) {
|
||||||
return "Pieces are too large in " + info.getName() + " (" + DataHelper.formatSize(info.getPieceLength(0)) +
|
return _("Pieces are too large in \"{0}\" ({1}B), deleting it.", info.getName(), DataHelper.formatSize(info.getPieceLength(0))) + ' ' +
|
||||||
"B, limit is " + DataHelper.formatSize(Storage.MAX_PIECE_SIZE) + "B), deleting it.";
|
_("Limit is {0}B", DataHelper.formatSize(Storage.MAX_PIECE_SIZE));
|
||||||
} else if (info.getTotalLength() > Storage.MAX_TOTAL_SIZE) {
|
} else if (info.getTotalLength() > Storage.MAX_TOTAL_SIZE) {
|
||||||
System.out.println("torrent info: " + info.toString());
|
System.out.println("torrent info: " + info.toString());
|
||||||
List lengths = info.getLengths();
|
List lengths = info.getLengths();
|
||||||
@ -568,8 +576,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
for (int i = 0; i < lengths.size(); i++)
|
for (int i = 0; i < lengths.size(); i++)
|
||||||
System.out.println("File " + i + " is " + lengths.get(i) + " long.");
|
System.out.println("File " + i + " is " + lengths.get(i) + " long.");
|
||||||
|
|
||||||
return "Torrents larger than " + DataHelper.formatSize(Storage.MAX_TOTAL_SIZE) +
|
return _("Torrents larger than {0}B are not supported yet, deleting \"{1}\"", Storage.MAX_TOTAL_SIZE, info.getName());
|
||||||
"B are not supported yet (because we're paranoid): " + info.getName() + ", deleting it!";
|
|
||||||
} else {
|
} else {
|
||||||
// ok
|
// ok
|
||||||
return null;
|
return null;
|
||||||
@ -585,7 +592,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
filename = sfile.getCanonicalPath();
|
filename = sfile.getCanonicalPath();
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
_log.error("Unable to remove the torrent " + filename, 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;
|
return null;
|
||||||
}
|
}
|
||||||
int remaining = 0;
|
int remaining = 0;
|
||||||
@ -606,7 +613,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
////_util.
|
////_util.
|
||||||
}
|
}
|
||||||
if (!wasStopped)
|
if (!wasStopped)
|
||||||
addMessage("Torrent stopped: '" + sfile.getName() + "'.");
|
addMessage(_("Torrent stopped: \"{0}\"", sfile.getName()));
|
||||||
}
|
}
|
||||||
return torrent;
|
return torrent;
|
||||||
}
|
}
|
||||||
@ -621,7 +628,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
torrentFile.delete();
|
torrentFile.delete();
|
||||||
if (torrent.storage != null)
|
if (torrent.storage != null)
|
||||||
removeTorrentStatus(torrent.storage.getMetaInfo());
|
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) {
|
public void torrentComplete(Snark snark) {
|
||||||
File f = new File(snark.torrent);
|
File f = new File(snark.torrent);
|
||||||
long len = snark.meta.getTotalLength();
|
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);
|
updateStatus(snark);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,7 +689,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
|||||||
// already known. noop
|
// already known. noop
|
||||||
} else {
|
} else {
|
||||||
if (shouldAutoStart() && !_util.connect())
|
if (shouldAutoStart() && !_util.connect())
|
||||||
addMessage("Unable to connect to I2P!");
|
addMessage(_("Unable to connect to I2P!"));
|
||||||
addTorrent((String)foundNames.get(i), !shouldAutoStart());
|
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
|
* "name", "announceURL=websiteURL" pairs
|
||||||
*/
|
*/
|
||||||
|
@ -80,13 +80,25 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PrintWriter out = resp.getWriter();
|
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
|
// 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("<meta http-equiv=\"refresh\" content=\"60;" + req.getRequestURI() + peerString + "\">\n");
|
||||||
out.write(HEADER);
|
out.write(HEADER);
|
||||||
out.write("</head><body>");
|
out.write("</head><body>");
|
||||||
out.write("<center>");
|
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();
|
Map trackers = _manager.getTrackers();
|
||||||
for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) {
|
for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) {
|
||||||
Map.Entry entry = (Map.Entry)iter.next();
|
Map.Entry entry = (Map.Entry)iter.next();
|
||||||
@ -110,22 +122,51 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
List snarks = getSortedSnarks(req);
|
List snarks = getSortedSnarks(req);
|
||||||
String uri = req.getRequestURI();
|
String uri = req.getRequestURI();
|
||||||
out.write(TABLE_HEADER);
|
out.write(TABLE_HEADER);
|
||||||
|
out.write(_("Status"));
|
||||||
if (_manager.util().connected() && snarks.size() > 0) {
|
if (_manager.util().connected() && snarks.size() > 0) {
|
||||||
if (peerParam != null)
|
out.write(" (<a href=\"");
|
||||||
out.write("(<a href=\"" + req.getRequestURI() + "\">Hide Peers</a>)<br>\n");
|
out.write(req.getRequestURI());
|
||||||
else
|
if (peerParam != null) {
|
||||||
out.write("(<a href=\"" + req.getRequestURI() + "?p=1" + "\">Show Peers</a>)<br>\n");
|
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\">");
|
out.write("<th align=\"center\">");
|
||||||
if (_manager.util().connected())
|
if (_manager.util().connected()) {
|
||||||
out.write("<a href=\"" + uri + "?action=StopAll&nonce=" + _nonce +
|
out.write("<a href=\"" + uri + "?action=StopAll&nonce=" + _nonce +
|
||||||
"\" title=\"Stop all torrents and the I2P tunnel\">Stop All</a>");
|
"\" title=\"");
|
||||||
else if (snarks.size() > 0)
|
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 +
|
out.write("<a href=\"" + uri + "?action=StartAll&nonce=" + _nonce +
|
||||||
"\" title=\"Start all torrents and the I2P tunnel\">Start All</a>");
|
"\" title=\"");
|
||||||
else
|
out.write(_("Start all torrents and the I2P tunnel"));
|
||||||
|
out.write("\">");
|
||||||
|
out.write(_("Start All"));
|
||||||
|
out.write("</a>");
|
||||||
|
} else {
|
||||||
out.write(" ");
|
out.write(" ");
|
||||||
|
}
|
||||||
out.write("</th></tr></thead>\n");
|
out.write("</th></tr></thead>\n");
|
||||||
for (int i = 0; i < snarks.size(); i++) {
|
for (int i = 0; i < snarks.size(); i++) {
|
||||||
Snark snark = (Snark)snarks.get(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);
|
boolean showPeers = showDebug || "1".equals(peerParam) || Base64.encode(snark.meta.getInfoHash()).equals(peerParam);
|
||||||
displaySnark(out, snark, uri, i, stats, showPeers, showDebug);
|
displaySnark(out, snark, uri, i, stats, showPeers, showDebug);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snarks.size() <= 0) {
|
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) {
|
} else if (snarks.size() > 1) {
|
||||||
out.write("<tfoot><tr>\n" +
|
out.write("<tfoot><tr>\n" +
|
||||||
" <th align=\"left\" colspan=\"2\">Totals (" +
|
" <th align=\"left\" colspan=\"2\">");
|
||||||
snarks.size() + " torrents, " +
|
out.write(_("Totals"));
|
||||||
DataHelper.formatSize(stats[5]) + "B, " +
|
out.write(" (");
|
||||||
stats[4] + " connected peers)</th>\n" +
|
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> </th>\n" +
|
||||||
" <th align=\"right\">" + formatSize(stats[0]) + "</th>\n" +
|
" <th align=\"right\">" + formatSize(stats[0]) + "</th>\n" +
|
||||||
" <th align=\"right\">" + formatSize(stats[1]) + "</th>\n" +
|
" <th align=\"right\">" + formatSize(stats[1]) + "</th>\n" +
|
||||||
@ -166,7 +216,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
String action = req.getParameter("action");
|
String action = req.getParameter("action");
|
||||||
if (action == null) {
|
if (action == null) {
|
||||||
// noop
|
// noop
|
||||||
} else if ("Add torrent".equals(action)) {
|
} else if ("Add".equals(action)) {
|
||||||
String newFile = req.getParameter("newFile");
|
String newFile = req.getParameter("newFile");
|
||||||
String newURL = req.getParameter("newURL");
|
String newURL = req.getParameter("newURL");
|
||||||
// NOTE - newFile currently disabled in HTML form - see below
|
// 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) )
|
if ( (newFile != null) && (newFile.trim().length() > 0) )
|
||||||
f = new File(newFile.trim());
|
f = new File(newFile.trim());
|
||||||
if ( (f != null) && (!f.exists()) ) {
|
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()) ) {
|
if ( (f != null) && (f.exists()) ) {
|
||||||
File local = new File(_manager.getDataDir(), f.getName());
|
File local = new File(_manager.getDataDir(), f.getName());
|
||||||
@ -184,16 +234,16 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
|
|
||||||
if (local.exists()) {
|
if (local.exists()) {
|
||||||
if (_manager.getTorrent(canonical) != null)
|
if (_manager.getTorrent(canonical) != null)
|
||||||
_manager.addMessage("Torrent already running: " + newFile);
|
_manager.addMessage(_("Torrent already running: {0}", newFile));
|
||||||
else
|
else
|
||||||
_manager.addMessage("Torrent already in the queue: " + newFile);
|
_manager.addMessage(_("Torrent already in the queue: {0}", newFile));
|
||||||
} else {
|
} else {
|
||||||
boolean ok = FileUtil.copy(f.getAbsolutePath(), local.getAbsolutePath(), true);
|
boolean ok = FileUtil.copy(f.getAbsolutePath(), local.getAbsolutePath(), true);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
_manager.addMessage("Copying torrent to " + local.getAbsolutePath());
|
_manager.addMessage(_("Copying torrent to {0}", local.getAbsolutePath()));
|
||||||
_manager.addTorrent(canonical);
|
_manager.addTorrent(canonical);
|
||||||
} else {
|
} 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) {
|
} catch (IOException ioe) {
|
||||||
@ -201,11 +251,11 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
}
|
}
|
||||||
} else if (newURL != null) {
|
} else if (newURL != null) {
|
||||||
if (newURL.startsWith("http://")) {
|
if (newURL.startsWith("http://")) {
|
||||||
_manager.addMessage("Fetching " + newURL);
|
_manager.addMessage(_("Fetching {0}", newURL));
|
||||||
I2PAppThread fetch = new I2PAppThread(new FetchAndAdd(_manager, newURL), "Fetch and add");
|
I2PAppThread fetch = new I2PAppThread(new FetchAndAdd(_manager, newURL), "Fetch and add");
|
||||||
fetch.start();
|
fetch.start();
|
||||||
} else {
|
} else {
|
||||||
_manager.addMessage("Invalid URL - must start with http://");
|
_manager.addMessage(_("Invalid URL - must start with http://"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no file or URL specified
|
// no file or URL specified
|
||||||
@ -235,7 +285,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
Snark snark = _manager.getTorrent(name);
|
Snark snark = _manager.getTorrent(name);
|
||||||
if ( (snark != null) && (DataHelper.eq(infoHash, snark.meta.getInfoHash())) ) {
|
if ( (snark != null) && (DataHelper.eq(infoHash, snark.meta.getInfoHash())) ) {
|
||||||
snark.startTorrent();
|
snark.startTorrent();
|
||||||
_manager.addMessage("Starting up torrent " + name);
|
_manager.addMessage(_("Starting up torrent {0}", name));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,7 +305,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
// yeah, need to, otherwise it'll get autoadded again (at the moment
|
// yeah, need to, otherwise it'll get autoadded again (at the moment
|
||||||
File f = new File(name);
|
File f = new File(name);
|
||||||
f.delete();
|
f.delete();
|
||||||
_manager.addMessage("Torrent file deleted: " + f.getAbsolutePath());
|
_manager.addMessage(_("Torrent file deleted: {0}", f.getAbsolutePath()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,15 +323,15 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
_manager.stopTorrent(name, true);
|
_manager.stopTorrent(name, true);
|
||||||
File f = new File(name);
|
File f = new File(name);
|
||||||
f.delete();
|
f.delete();
|
||||||
_manager.addMessage("Torrent file deleted: " + f.getAbsolutePath());
|
_manager.addMessage(_("Torrent file deleted: {0}", f.getAbsolutePath()));
|
||||||
List files = snark.meta.getFiles();
|
List files = snark.meta.getFiles();
|
||||||
String dataFile = snark.meta.getName();
|
String dataFile = snark.meta.getName();
|
||||||
f = new File(_manager.getDataDir(), dataFile);
|
f = new File(_manager.getDataDir(), dataFile);
|
||||||
if (files == null) { // single file torrent
|
if (files == null) { // single file torrent
|
||||||
if (f.delete())
|
if (f.delete())
|
||||||
_manager.addMessage("Data file deleted: " + f.getAbsolutePath());
|
_manager.addMessage(_("Data file deleted: {0}", f.getAbsolutePath()));
|
||||||
else
|
else
|
||||||
_manager.addMessage("Data file could not be deleted: " + f.getAbsolutePath());
|
_manager.addMessage(_("Data file could not be deleted: {0}", f.getAbsolutePath()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < files.size(); i++) { // pass 1 delete files
|
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...
|
// each of those lists just contain a single file afaict...
|
||||||
File df = Storage.getFileFromNames(f, (List) files.get(i));
|
File df = Storage.getFileFromNames(f, (List) files.get(i));
|
||||||
if (df.delete())
|
if (df.delete())
|
||||||
_manager.addMessage("Data file deleted: " + df.getAbsolutePath());
|
_manager.addMessage(_("Data file deleted: {0}", df.getAbsolutePath()));
|
||||||
else
|
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,
|
for (int i = files.size() - 1; i >= 0; i--) { // pass 2 delete dirs - not foolproof,
|
||||||
// we could sort and do a strict bottom-up
|
// we could sort and do a strict bottom-up
|
||||||
@ -300,14 +350,14 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
if (df == null || !df.exists())
|
if (df == null || !df.exists())
|
||||||
continue;
|
continue;
|
||||||
if(df.delete())
|
if(df.delete())
|
||||||
_manager.addMessage("Data dir deleted: " + df.getAbsolutePath());
|
_manager.addMessage(_("Data dir deleted: {0}", df.getAbsolutePath()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ("Save configuration".equals(action)) {
|
} else if ("Save".equals(action)) {
|
||||||
String dataDir = req.getParameter("dataDir");
|
String dataDir = req.getParameter("dataDir");
|
||||||
boolean autoStart = req.getParameter("autoStart") != null;
|
boolean autoStart = req.getParameter("autoStart") != null;
|
||||||
String seedPct = req.getParameter("seedPct");
|
String seedPct = req.getParameter("seedPct");
|
||||||
@ -321,7 +371,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
boolean useOpenTrackers = req.getParameter("useOpenTrackers") != null;
|
boolean useOpenTrackers = req.getParameter("useOpenTrackers") != null;
|
||||||
String openTrackers = req.getParameter("openTrackers");
|
String openTrackers = req.getParameter("openTrackers");
|
||||||
_manager.updateConfig(dataDir, autoStart, seedPct, eepHost, eepPort, i2cpHost, i2cpPort, i2cpOpts, upLimit, upBW, useOpenTrackers, 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");
|
String baseData = req.getParameter("baseFile");
|
||||||
if (baseData != null && baseData.trim().length() > 0) {
|
if (baseData != null && baseData.trim().length() > 0) {
|
||||||
File baseFile = new File(_manager.getDataDir(), baseData);
|
File baseFile = new File(_manager.getDataDir(), baseData);
|
||||||
@ -331,7 +381,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
announceURL = announceURLOther;
|
announceURL = announceURLOther;
|
||||||
|
|
||||||
if (announceURL == null || announceURL.length() <= 0)
|
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()) {
|
else if (baseFile.exists()) {
|
||||||
try {
|
try {
|
||||||
Storage s = new Storage(_manager.util(), baseFile, announceURL, null);
|
Storage s = new Storage(_manager.util(), baseFile, announceURL, null);
|
||||||
@ -346,21 +396,21 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
FileOutputStream out = new FileOutputStream(torrentFile);
|
FileOutputStream out = new FileOutputStream(torrentFile);
|
||||||
out.write(info.getTorrentData());
|
out.write(info.getTorrentData());
|
||||||
out.close();
|
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
|
// now fire it up, but don't automatically seed it
|
||||||
_manager.addTorrent(torrentFile.getCanonicalPath(), true);
|
_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) {
|
} 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 {
|
} 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 {
|
} 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)) {
|
} 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);
|
List snarks = getSortedSnarks(req);
|
||||||
for (int i = 0; i < snarks.size(); i++) {
|
for (int i = 0; i < snarks.size(); i++) {
|
||||||
Snark snark = (Snark)snarks.get(i);
|
Snark snark = (Snark)snarks.get(i);
|
||||||
@ -369,10 +419,10 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
}
|
}
|
||||||
if (_manager.util().connected()) {
|
if (_manager.util().connected()) {
|
||||||
_manager.util().disconnect();
|
_manager.util().disconnect();
|
||||||
_manager.addMessage("I2P tunnel closed.");
|
_manager.addMessage(_("I2P tunnel closed."));
|
||||||
}
|
}
|
||||||
} else if ("StartAll".equals(action)) {
|
} 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);
|
List snarks = getSortedSnarks(req);
|
||||||
for (int i = 0; i < snarks.size(); i++) {
|
for (int i = 0; i < snarks.size(); i++) {
|
||||||
Snark snark = (Snark)snarks.get(i);
|
Snark snark = (Snark)snarks.get(i);
|
||||||
@ -449,45 +499,45 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
knownPeers = snark.coordinator.trackerSeenPeers;
|
knownPeers = snark.coordinator.trackerSeenPeers;
|
||||||
}
|
}
|
||||||
|
|
||||||
String statusString = "Unknown";
|
String statusString = _("Unknown");
|
||||||
if (err != null) {
|
if (err != null) {
|
||||||
if (isRunning && curPeers > 0 && !showPeers)
|
if (isRunning && curPeers > 0 && !showPeers)
|
||||||
statusString = "<a title=\"" + err + "\">TrackerErr</a> (" +
|
statusString = "<a title=\"" + err + "\">" + _("TrackerErr") + "</a> (" +
|
||||||
curPeers + "/" + knownPeers +
|
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)
|
else if (isRunning)
|
||||||
statusString = "<a title=\"" + err + "\">TrackerErr (" + curPeers + "/" + knownPeers + " peers)";
|
statusString = "<a title=\"" + err + "\">" + _("TrackerErr") + " (" + curPeers + '/' + knownPeers + ' ' + _("peers") + ')';
|
||||||
else {
|
else {
|
||||||
if (err.length() > MAX_DISPLAYED_ERROR_LENGTH)
|
if (err.length() > MAX_DISPLAYED_ERROR_LENGTH)
|
||||||
err = err.substring(0, MAX_DISPLAYED_ERROR_LENGTH) + "…";
|
err = err.substring(0, MAX_DISPLAYED_ERROR_LENGTH) + "…";
|
||||||
statusString = "TrackerErr<br>(" + err + ")";
|
statusString = _("TrackerErr") + "<br>(" + err + ")";
|
||||||
}
|
}
|
||||||
} else if (remaining <= 0) {
|
} else if (remaining <= 0) {
|
||||||
if (isRunning && curPeers > 0 && !showPeers)
|
if (isRunning && curPeers > 0 && !showPeers)
|
||||||
statusString = "Seeding (" +
|
statusString = _("Seeding") + " (" +
|
||||||
curPeers + "/" + knownPeers +
|
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)
|
else if (isRunning)
|
||||||
statusString = "Seeding (" + curPeers + "/" + knownPeers + " peers)";
|
statusString = _("Seeding") + " (" + curPeers + "/" + knownPeers + ' ' + _("peers") + ')';
|
||||||
else
|
else
|
||||||
statusString = "Complete";
|
statusString = _("Complete");
|
||||||
} else {
|
} else {
|
||||||
if (isRunning && curPeers > 0 && downBps > 0 && !showPeers)
|
if (isRunning && curPeers > 0 && downBps > 0 && !showPeers)
|
||||||
statusString = "OK (" +
|
statusString = _("OK") + " (" +
|
||||||
curPeers + "/" + knownPeers +
|
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)
|
else if (isRunning && curPeers > 0 && downBps > 0)
|
||||||
statusString = "OK (" + curPeers + "/" + knownPeers + " peers)";
|
statusString = _("OK") + " (" + curPeers + "/" + knownPeers + ' ' + _("peers") + ')';
|
||||||
else if (isRunning && curPeers > 0 && !showPeers)
|
else if (isRunning && curPeers > 0 && !showPeers)
|
||||||
statusString = "Stalled (" +
|
statusString = _("Stalled") + " (" +
|
||||||
curPeers + "/" + knownPeers +
|
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)
|
else if (isRunning && curPeers > 0)
|
||||||
statusString = "Stalled (" + curPeers + "/" + knownPeers + " peers)";
|
statusString = _("Stalled") + " (" + curPeers + '/' + knownPeers + ' ' + _("peers") + ')';
|
||||||
else if (isRunning)
|
else if (isRunning)
|
||||||
statusString = "No Peers (0/" + knownPeers + ")";
|
statusString = _("No Peers") + " (0/" + knownPeers + ')';
|
||||||
else
|
else
|
||||||
statusString = "Stopped";
|
statusString = _("Stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
String rowClass = (row % 2 == 0 ? "snarkTorrentEven" : "snarkTorrentOdd");
|
String rowClass = (row % 2 == 0 ? "snarkTorrentEven" : "snarkTorrentOdd");
|
||||||
@ -496,9 +546,15 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
out.write(statusString + "</td>\n\t");
|
out.write(statusString + "</td>\n\t");
|
||||||
out.write("<td align=\"left\" class=\"snarkTorrentName " + rowClass + "\">");
|
out.write("<td align=\"left\" class=\"snarkTorrentName " + rowClass + "\">");
|
||||||
|
|
||||||
if (remaining == 0)
|
if (remaining == 0) {
|
||||||
out.write("<a href=\"" + _manager.linkPrefix() + snark.meta.getName()
|
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);
|
out.write(filename);
|
||||||
if (remaining == 0)
|
if (remaining == 0)
|
||||||
out.write("</a>");
|
out.write("</a>");
|
||||||
@ -520,7 +576,9 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
baseURL = baseURL.substring(e + 1);
|
baseURL = baseURL.substring(e + 1);
|
||||||
out.write(" [<a href=\"" + baseURL + "details.php?dllist=1&filelist=1&info_hash=");
|
out.write(" [<a href=\"" + baseURL + "details.php?dllist=1&filelist=1&info_hash=");
|
||||||
out.write(TrackerClient.urlencode(snark.meta.getInfoHash()));
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -552,17 +610,35 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
parameters = parameters + "&p=1";
|
parameters = parameters + "&p=1";
|
||||||
if (isRunning) {
|
if (isRunning) {
|
||||||
out.write("<a href=\"" + uri + "?action=Stop" + parameters
|
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 {
|
} else {
|
||||||
if (isValid)
|
if (isValid) {
|
||||||
out.write("<a href=\"" + uri + "?action=Start" + parameters
|
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
|
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
|
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");
|
out.write("</td>\n</tr>\n");
|
||||||
|
|
||||||
if(showPeers && isRunning && curPeers > 0) {
|
if(showPeers && isRunning && curPeers > 0) {
|
||||||
List peers = snark.coordinator.peerList();
|
List peers = snark.coordinator.peerList();
|
||||||
Iterator it = peers.iterator();
|
Iterator it = peers.iterator();
|
||||||
@ -573,11 +649,11 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
out.write("<tr class=\"" + rowClass + "\">");
|
out.write("<tr class=\"" + rowClass + "\">");
|
||||||
out.write("<td align=\"center\" class=\"snarkTorrentStatus " + rowClass + "\">");
|
out.write("<td align=\"center\" class=\"snarkTorrentStatus " + rowClass + "\">");
|
||||||
out.write("</td>\n\t");
|
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 ch = peer.toString().substring(0, 4);
|
||||||
String client;
|
String client;
|
||||||
if ("AwMD".equals(ch))
|
if ("AwMD".equals(ch))
|
||||||
client = "I2PSnark";
|
client = _("I2PSnark");
|
||||||
else if ("BFJT".equals(ch))
|
else if ("BFJT".equals(ch))
|
||||||
client = "I2PRufus";
|
client = "I2PRufus";
|
||||||
else if ("TTMt".equals(ch))
|
else if ("TTMt".equals(ch))
|
||||||
@ -591,7 +667,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
else if ("VUZP".equals(ch))
|
else if ("VUZP".equals(ch))
|
||||||
client = "Robert";
|
client = "Robert";
|
||||||
else
|
else
|
||||||
client = "Unknown (" + ch + ')';
|
client = _("Unknown") + " (" + ch + ')';
|
||||||
out.write(client + " " + peer.toString().substring(5, 9));
|
out.write(client + " " + peer.toString().substring(5, 9));
|
||||||
if (showDebug)
|
if (showDebug)
|
||||||
out.write(" inactive " + (peer.getInactiveTime() / 1000) + "s");
|
out.write(" inactive " + (peer.getInactiveTime() / 1000) + "s");
|
||||||
@ -601,7 +677,7 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
out.write("<td align=\"right\" class=\"snarkTorrentStatus " + rowClass + "\">");
|
out.write("<td align=\"right\" class=\"snarkTorrentStatus " + rowClass + "\">");
|
||||||
float pct = (float) (100.0 * (float) peer.completed() / snark.meta.getPieces());
|
float pct = (float) (100.0 * (float) peer.completed() / snark.meta.getPieces());
|
||||||
if (pct == 100.0)
|
if (pct == 100.0)
|
||||||
out.write("Seed");
|
out.write(_("Seed"));
|
||||||
else {
|
else {
|
||||||
String ps = String.valueOf(pct);
|
String ps = String.valueOf(pct);
|
||||||
if (ps.length() > 5)
|
if (ps.length() > 5)
|
||||||
@ -619,9 +695,10 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
} else {
|
} else {
|
||||||
out.write("<font color=#a00000><a title=\"");
|
out.write("<font color=#a00000><a title=\"");
|
||||||
if (!peer.isInteresting())
|
if (!peer.isInteresting())
|
||||||
out.write("Uninteresting\">");
|
out.write(_("Uninteresting (The peer has no pieces we need)"));
|
||||||
else
|
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>");
|
out.write(formatSize(peer.getDownloadRate()) + "ps</a></font>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -634,9 +711,10 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
} else {
|
} else {
|
||||||
out.write("<font color=#a00000><a title=\"");
|
out.write("<font color=#a00000><a title=\"");
|
||||||
if (!peer.isInterested())
|
if (!peer.isInterested())
|
||||||
out.write("Uninterested\">");
|
out.write(_("Uninterested (We have no pieces the peer needs)"));
|
||||||
else
|
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>");
|
out.write(formatSize(peer.getUploadRate()) + "ps</a></font>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -659,14 +737,23 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
out.write("<span class=\"snarkNewTorrent\">\n");
|
out.write("<span class=\"snarkNewTorrent\">\n");
|
||||||
// *not* enctype="multipart/form-data", so that the input type=file sends the filename, not the file
|
// *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("<form action=\"" + uri + "\" method=\"POST\">\n");
|
||||||
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" />\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("<input type=\"hidden\" name=\"action\" value=\"Add\" >\n");
|
||||||
out.write("From URL : <input type=\"text\" name=\"newURL\" size=\"80\" value=\"" + newURL + "\" /> \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)
|
// 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("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("<tr><td> <td><input type=\"submit\" value=\"");
|
||||||
out.write("<span class=\"snarkAddInfo\">Alternately, you can copy .torrent files to " + _manager.getDataDir().getAbsolutePath() + "<br>\n");
|
out.write(_("Add torrent"));
|
||||||
out.write("Removing that .torrent file will cause the torrent to stop.<br></span>\n");
|
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>");
|
out.write("</form>\n</span></div>");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -679,13 +766,22 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
out.write("<div class=\"newtorrentsection\"><span class=\"snarkNewTorrent\">\n");
|
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
|
// *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("<form action=\"" + uri + "\" method=\"POST\">\n");
|
||||||
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" />\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=\"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("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
|
+ "<input type=\"text\" name=\"baseFile\" size=\"20\" value=\"" + baseFile
|
||||||
+ "\" title=\"File to seed (must be within the specified path)\" /><br>\n");
|
+ "\" title=\"");
|
||||||
out.write("Tracker: <select name=\"announceURL\"><option value=\"\">Select a tracker</option>\n");
|
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();
|
Map trackers = _manager.getTrackers();
|
||||||
for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) {
|
for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) {
|
||||||
Map.Entry entry = (Map.Entry)iter.next();
|
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("\t<option value=\"" + announceURL + "\">" + name + "</option>\n");
|
||||||
}
|
}
|
||||||
out.write("</select>\n");
|
out.write("</select>\n");
|
||||||
out.write("or <input type=\"text\" name=\"announceURLOther\" size=\"50\" value=\"http://\" " +
|
out.write(_("or"));
|
||||||
"title=\"Custom tracker URL\" /> ");
|
out.write("<tr><td> <td><input type=\"text\" name=\"announceURLOther\" size=\"50\" value=\"http://\" " +
|
||||||
out.write("<input type=\"submit\" value=\"Create torrent\" name=\"action\" />\n");
|
"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>");
|
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("<form action=\"" + uri + "\" method=\"POST\">\n");
|
||||||
out.write("<div class=\"configsection\"><span class=\"snarkConfig\">\n");
|
out.write("<div class=\"configsection\"><span class=\"snarkConfig\">\n");
|
||||||
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" />\n");
|
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n");
|
||||||
out.write("<span class=\"snarkConfigTitle\">Configuration:</span><br>\n");
|
out.write("<input type=\"hidden\" name=\"action\" value=\"Save\" >\n");
|
||||||
out.write("Data directory: <input type=\"text\" size=\"40\" name=\"dataDir\" value=\"" + dataDir + "\" ");
|
out.write("<span class=\"snarkConfigTitle\">");
|
||||||
out.write("title=\"Directory to store torrents and data\" disabled=\"true\" /> <i>(Edit i2psnark.config and restart to change)</i><br>\n");
|
out.write(_("Configuration"));
|
||||||
out.write("Auto start: <input type=\"checkbox\" class=\"optbox\" name=\"autoStart\" value=\"true\" "
|
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 " : "")
|
+ (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 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" />
|
//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");
|
//out.write("<br>\n");
|
||||||
@ -739,26 +855,51 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
out.write("<option value=\"150\">150%</option>\n\t");
|
out.write("<option value=\"150\">150%</option>\n\t");
|
||||||
out.write("</select><br>\n");
|
out.write("</select><br>\n");
|
||||||
*/
|
*/
|
||||||
out.write("Total uploader limit: <input type=\"text\" name=\"upLimit\" value=\""
|
out.write("<tr><td>");
|
||||||
+ _manager.util().getMaxUploaders() + "\" size=\"3\" maxlength=\"3\" /> peers<br>\n");
|
out.write(_("Total uploader limit"));
|
||||||
out.write("Up bandwidth limit: <input type=\"text\" name=\"upBW\" value=\""
|
out.write(": <td><input type=\"text\" name=\"upLimit\" value=\""
|
||||||
+ _manager.util().getMaxUpBW() + "\" size=\"3\" maxlength=\"3\" /> KBps <i>(Half <a href=\"/config.jsp\" target=\"blank\">available bandwidth</a> recommended.)</i><br>\n");
|
+ _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 " : "")
|
+ (useOpenTrackers ? "checked " : "")
|
||||||
+ "title=\"If true, uses open trackers in addition\" /> ");
|
+ "title=\"");
|
||||||
out.write("Announce URLs: <input type=\"text\" name=\"openTrackers\" value=\""
|
out.write(_("If checked, announce torrents to open trackers as well as the tracker listed in the torrent file"));
|
||||||
+ openTrackers + "\" size=\"50\" /><br>\n");
|
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("\n");
|
||||||
//out.write("EepProxy host: <input type=\"text\" name=\"eepHost\" value=\""
|
//out.write("EepProxy host: <input type=\"text\" name=\"eepHost\" value=\""
|
||||||
// + _manager.util().getEepProxyHost() + "\" size=\"15\" /> ");
|
// + _manager.util().getEepProxyHost() + "\" size=\"15\" /> ");
|
||||||
//out.write("port: <input type=\"text\" name=\"eepPort\" value=\""
|
//out.write("port: <input type=\"text\" name=\"eepPort\" value=\""
|
||||||
// + _manager.util().getEepProxyPort() + "\" size=\"5\" maxlength=\"5\" /><br>\n");
|
// + _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("<tr><td>");
|
||||||
out.write("port: <input type=\"text\" name=\"i2cpPort\" value=\"" +
|
out.write(_("I2CP host"));
|
||||||
+ _manager.util().getI2CPPort() + "\" size=\"5\" maxlength=\"5\" /> <br>\n");
|
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);
|
StringBuilder opts = new StringBuilder(64);
|
||||||
Map options = new TreeMap(_manager.util().getI2CPOptions());
|
Map options = new TreeMap(_manager.util().getI2CPOptions());
|
||||||
for (Iterator iter = options.entrySet().iterator(); iter.hasNext(); ) {
|
for (Iterator iter = options.entrySet().iterator(); iter.hasNext(); ) {
|
||||||
@ -767,13 +908,28 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
String val = (String)entry.getValue();
|
String val = (String)entry.getValue();
|
||||||
opts.append(key).append('=').append(val).append(' ');
|
opts.append(key).append('=').append(val).append(' ');
|
||||||
}
|
}
|
||||||
out.write("I2CP opts: <input type=\"text\" name=\"i2cpOpts\" size=\"80\" value=\""
|
out.write("<tr><td>");
|
||||||
+ opts.toString() + "\" /><br>\n");
|
out.write(_("I2CP options"));
|
||||||
out.write("<input type=\"submit\" value=\"Save configuration\" name=\"action\" />\n");
|
out.write(": <td><textarea name=\"i2cpOpts\" cols=\"60\" rows=\"1\" wrap=\"off\" >"
|
||||||
out.write("</span>\n");
|
+ 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>");
|
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 :)
|
// rounding makes us look faster :)
|
||||||
private String formatSize(long bytes) {
|
private String formatSize(long bytes) {
|
||||||
if (bytes < 5*1024)
|
if (bytes < 5*1024)
|
||||||
@ -786,28 +942,12 @@ public class I2PSnarkServlet extends HttpServlet {
|
|||||||
return ((bytes + 512*1024*1024)/(1024*1024*1024)) + "GB";
|
return ((bytes + 512*1024*1024)/(1024*1024*1024)) + "GB";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String HEADER_BEGIN = "<html>\n" +
|
private static final String HEADER = "<link href=\"../themes/console/snark.css\" rel=\"stylesheet\" type=\"text/css\" >";
|
||||||
"<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 TABLE_HEADER = "<table border=\"0\" class=\"snarkTorrents\" width=\"100%\" cellpadding=\"0 10px\">\n" +
|
private static final String TABLE_HEADER = "<table border=\"0\" class=\"snarkTorrents\" width=\"100%\" cellpadding=\"0 10px\">\n" +
|
||||||
"<thead>\n" +
|
"<thead>\n" +
|
||||||
"<tr><th align=\"center\">Status \n";
|
"<tr><th align=\"center\">";
|
||||||
|
|
||||||
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";
|
|
||||||
|
|
||||||
private static final String TABLE_FOOTER = "</table></div>\n";
|
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);
|
File file = _manager.util().get(_url, false, 3);
|
||||||
try {
|
try {
|
||||||
if ( (file != null) && (file.exists()) && (file.length() > 0) ) {
|
if ( (file != null) && (file.exists()) && (file.length() > 0) ) {
|
||||||
_manager.addMessage("Torrent fetched from " + _url);
|
_manager.addMessage(_("Torrent fetched from {0}", _url));
|
||||||
FileInputStream in = null;
|
FileInputStream in = null;
|
||||||
try {
|
try {
|
||||||
in = new FileInputStream(file);
|
in = new FileInputStream(file);
|
||||||
MetaInfo info = new MetaInfo(in);
|
MetaInfo info = new MetaInfo(in);
|
||||||
String name = info.getName();
|
String name = info.getName();
|
||||||
|
name = DataHelper.stripHTML(name); // XSS
|
||||||
name = name.replace('/', '_');
|
name = name.replace('/', '_');
|
||||||
name = name.replace('\\', '_');
|
name = name.replace('\\', '_');
|
||||||
name = name.replace('&', '+');
|
name = name.replace('&', '+');
|
||||||
@ -846,25 +987,30 @@ private static class FetchAndAdd implements Runnable {
|
|||||||
|
|
||||||
if (torrentFile.exists()) {
|
if (torrentFile.exists()) {
|
||||||
if (_manager.getTorrent(canonical) != null)
|
if (_manager.getTorrent(canonical) != null)
|
||||||
_manager.addMessage("Torrent already running: " + name);
|
_manager.addMessage(_("Torrent already running: {0}", name));
|
||||||
else
|
else
|
||||||
_manager.addMessage("Torrent already in the queue: " + name);
|
_manager.addMessage(_("Torrent already in the queue: {0}", name));
|
||||||
} else {
|
} else {
|
||||||
FileUtil.copy(file.getAbsolutePath(), canonical, true);
|
FileUtil.copy(file.getAbsolutePath(), canonical, true);
|
||||||
_manager.addTorrent(canonical);
|
_manager.addTorrent(canonical);
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) {
|
} 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 {
|
} finally {
|
||||||
try { in.close(); } catch (IOException ioe) {}
|
try { in.close(); } catch (IOException ioe) {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_manager.addMessage("Torrent was not retrieved from " + _url);
|
_manager.addMessage(_("Torrent was not retrieved from {0}", _url));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (file != null) file.delete();
|
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" />
|
<attribute name="Class-Path" value="i2p.jar mstreaming.jar" />
|
||||||
</manifest>
|
</manifest>
|
||||||
</jar>
|
</jar>
|
||||||
|
<ant target="bundle" />
|
||||||
<ant target="war" />
|
<ant target="war" />
|
||||||
</target>
|
</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">
|
<target name="war" depends="precompilejsp">
|
||||||
<war destfile="build/i2ptunnel.war" webxml="../jsp/web-out.xml"
|
<war destfile="build/i2ptunnel.war" webxml="../jsp/web-out.xml"
|
||||||
basedir="../jsp/" excludes="web.xml, **/*.java, *.jsp">
|
basedir="../jsp/" excludes="web.xml, **/*.java, *.jsp">
|
||||||
</war>
|
</war>
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="precompilejsp" unless="precompilejsp.uptodate">
|
<target name="precompilejsp" unless="precompilejsp.uptodate">
|
||||||
<delete dir="../jsp/WEB-INF/" />
|
<delete dir="../jsp/WEB-INF/" />
|
||||||
<delete file="../jsp/web-fragment.xml" />
|
<delete file="../jsp/web-fragment.xml" />
|
||||||
@ -113,11 +148,7 @@
|
|||||||
<delete file="../jsp/web-out.xml" />
|
<delete file="../jsp/web-out.xml" />
|
||||||
</target>
|
</target>
|
||||||
<target name="cleandep" depends="clean">
|
<target name="cleandep" depends="clean">
|
||||||
<!-- ministreaming will clean core -->
|
|
||||||
<ant dir="../../ministreaming/java/" target="distclean" />
|
|
||||||
</target>
|
</target>
|
||||||
<target name="distclean" depends="clean">
|
<target name="distclean" depends="clean">
|
||||||
<!-- ministreaming will clean core -->
|
|
||||||
<ant dir="../../ministreaming/java/" target="distclean" />
|
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</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.I2PAppContext;
|
||||||
import net.i2p.data.ByteArray;
|
import net.i2p.data.ByteArray;
|
||||||
import net.i2p.util.ByteCache;
|
import net.i2p.util.ByteCache;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,7 +219,7 @@ class HTTPResponseOutputStream extends FilterOutputStream {
|
|||||||
//out.flush();
|
//out.flush();
|
||||||
PipedInputStream pi = new PipedInputStream();
|
PipedInputStream pi = new PipedInputStream();
|
||||||
PipedOutputStream po = new PipedOutputStream(pi);
|
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;
|
out = po;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ import net.i2p.client.streaming.I2PSocketManagerFactory;
|
|||||||
import net.i2p.client.streaming.I2PSocketOptions;
|
import net.i2p.client.streaming.I2PSocketOptions;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.util.EventDispatcher;
|
import net.i2p.util.EventDispatcher;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.SimpleScheduler;
|
import net.i2p.util.SimpleScheduler;
|
||||||
import net.i2p.util.SimpleTimer;
|
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
|
} // else delay creating session until createI2PSocket() is called
|
||||||
|
|
||||||
Thread t = new I2PThread(this);
|
Thread t = new I2PAppThread(this);
|
||||||
t.setName("Client " + _clientId);
|
t.setName("Client " + _clientId);
|
||||||
listenerReady = false;
|
listenerReady = false;
|
||||||
t.start();
|
t.start();
|
||||||
@ -207,7 +207,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
|||||||
|
|
||||||
for (int i = 0; i < _numConnectionBuilders; i++) {
|
for (int i = 0; i < _numConnectionBuilders; i++) {
|
||||||
String name = "ClientBuilder" + _clientId + '.' + i;
|
String name = "ClientBuilder" + _clientId + '.' + i;
|
||||||
I2PThread b = new I2PThread(new TunnelConnectionBuilder(), name);
|
I2PAppThread b = new I2PAppThread(new TunnelConnectionBuilder(), name);
|
||||||
b.setDaemon(true);
|
b.setDaemon(true);
|
||||||
b.start();
|
b.start();
|
||||||
}
|
}
|
||||||
@ -350,7 +350,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
|||||||
* called by derived classes after initialization.
|
* called by derived classes after initialization.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public final void startRunning() {
|
public void startRunning() {
|
||||||
synchronized (startLock) {
|
synchronized (startLock) {
|
||||||
startRunning = true;
|
startRunning = true;
|
||||||
startLock.notify();
|
startLock.notify();
|
||||||
@ -490,7 +490,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
|
|||||||
protected void manageConnection(Socket s) {
|
protected void manageConnection(Socket s) {
|
||||||
if (s == null) return;
|
if (s == null) return;
|
||||||
if (_numConnectionBuilders <= 0) {
|
if (_numConnectionBuilders <= 0) {
|
||||||
new I2PThread(new BlockingRunner(s), "Clinet run").start();
|
new I2PAppThread(new BlockingRunner(s), "Clinet run").start();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,11 +233,35 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
return opts;
|
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;
|
private static final boolean DEFAULT_GZIP = true;
|
||||||
// all default to false
|
// all default to false
|
||||||
public static final String PROP_REFERER = "i2ptunnel.httpclient.sendReferer";
|
public static final String PROP_REFERER = "i2ptunnel.httpclient.sendReferer";
|
||||||
public static final String PROP_USER_AGENT = "i2ptunnel.httpclient.sendUserAgent";
|
public static final String PROP_USER_AGENT = "i2ptunnel.httpclient.sendUserAgent";
|
||||||
public static final String PROP_VIA = "i2ptunnel.httpclient.sendVia";
|
public static final String PROP_VIA = "i2ptunnel.httpclient.sendVia";
|
||||||
|
public static final String PROP_JUMP_SERVERS = "i2ptunnel.httpclient.jumpServers";
|
||||||
|
|
||||||
private static long __requestId = 0;
|
private static long __requestId = 0;
|
||||||
protected void clientConnectionRun(Socket s) {
|
protected void clientConnectionRun(Socket s) {
|
||||||
@ -245,6 +269,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
OutputStream out = null;
|
OutputStream out = null;
|
||||||
String targetRequest = null;
|
String targetRequest = null;
|
||||||
boolean usingWWWProxy = false;
|
boolean usingWWWProxy = false;
|
||||||
|
boolean usingInternalServer = false;
|
||||||
String currentProxy = null;
|
String currentProxy = null;
|
||||||
long requestId = ++__requestId;
|
long requestId = ++__requestId;
|
||||||
try {
|
try {
|
||||||
@ -271,6 +296,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
int pos = line.indexOf(" ");
|
int pos = line.indexOf(" ");
|
||||||
if (pos == -1) break;
|
if (pos == -1) break;
|
||||||
method = line.substring(0, pos);
|
method = line.substring(0, pos);
|
||||||
|
// TODO use Java URL class to make all this simpler and more robust
|
||||||
String request = line.substring(pos + 1);
|
String request = line.substring(pos + 1);
|
||||||
if (request.startsWith("/") && getTunnel().getClientOptions().getProperty("i2ptunnel.noproxy") != null) {
|
if (request.startsWith("/") && getTunnel().getClientOptions().getProperty("i2ptunnel.noproxy") != null) {
|
||||||
request = "http://i2p" + request;
|
request = "http://i2p" + request;
|
||||||
@ -316,8 +342,11 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quick hack for foo.bar.i2p
|
if (host.toLowerCase().equals("proxy.i2p")) {
|
||||||
if (host.toLowerCase().endsWith(".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 gets the host name
|
||||||
destination = host;
|
destination = host;
|
||||||
// Host becomes the destination key
|
// Host becomes the destination key
|
||||||
@ -454,15 +483,15 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
}
|
}
|
||||||
destination = request.substring(0, pos);
|
destination = request.substring(0, pos);
|
||||||
line = method + " " + request.substring(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 (!isValid) {
|
||||||
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "notValid(" + host + ")");
|
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "notValid(" + host + ")");
|
||||||
method = null;
|
method = null;
|
||||||
destination = null;
|
destination = null;
|
||||||
break;
|
break;
|
||||||
} else if (!usingWWWProxy) {
|
} else if ((!usingWWWProxy) && (!usingInternalServer)) {
|
||||||
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "host=getHostName(" + destination + ")");
|
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "host=getHostName(" + destination + ")");
|
||||||
host = getHostName(destination); // hide original host
|
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) + "HOST :" + host + ":");
|
||||||
_log.debug(getPrefix(requestId) + "DEST :" + destination + ":");
|
_log.debug(getPrefix(requestId) + "DEST :" + destination + ":");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// end first line processing
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (lowercaseLine.startsWith("host: ") && !usingWWWProxy) {
|
if (lowercaseLine.startsWith("host: ") && !usingWWWProxy) {
|
||||||
line = "Host: " + host;
|
line = "Host: " + host;
|
||||||
@ -505,14 +536,14 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
continue; // completely strip the line
|
continue; // completely strip the line
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line.length() == 0) {
|
if (line.length() == 0) {
|
||||||
|
|
||||||
String ok = getTunnel().getClientOptions().getProperty("i2ptunnel.gzip");
|
String ok = getTunnel().getClientOptions().getProperty("i2ptunnel.gzip");
|
||||||
boolean gzip = DEFAULT_GZIP;
|
boolean gzip = DEFAULT_GZIP;
|
||||||
if (ok != null)
|
if (ok != null)
|
||||||
gzip = Boolean.valueOf(ok).booleanValue();
|
gzip = Boolean.valueOf(ok).booleanValue();
|
||||||
if (gzip) {
|
if (gzip && !usingInternalServer) {
|
||||||
// according to rfc2616 s14.3, this *should* force identity, even if
|
// 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
|
// an explicit q=0 for gzip doesn't. tested against orion.i2p, and it
|
||||||
// seems to work.
|
// seems to work.
|
||||||
@ -526,7 +557,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
} else {
|
} else {
|
||||||
newRequest.append(line).append("\r\n"); // HTTP spec
|
newRequest.append(line).append("\r\n"); // HTTP spec
|
||||||
}
|
}
|
||||||
}
|
} // end header processing
|
||||||
|
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug(getPrefix(requestId) + "NewRequest header: [" + newRequest.toString() + "]");
|
_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)
|
// Serve local proxy files (images, css linked from error pages)
|
||||||
// Ignore all the headers
|
// Ignore all the headers
|
||||||
if (destination.equals("proxy.i2p")) {
|
if (usingInternalServer) {
|
||||||
serveLocalFile(out, method, targetRequest);
|
serveLocalFile(out, method, targetRequest);
|
||||||
s.close();
|
s.close();
|
||||||
return;
|
return;
|
||||||
@ -560,7 +592,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
if (_log.shouldLog(Log.WARN))
|
if (_log.shouldLog(Log.WARN))
|
||||||
_log.warn("Unable to resolve " + destination + " (proxy? " + usingWWWProxy + ", request: " + targetRequest);
|
_log.warn("Unable to resolve " + destination + " (proxy? " + usingWWWProxy + ", request: " + targetRequest);
|
||||||
byte[] header;
|
byte[] header;
|
||||||
boolean showAddrHelper = false;
|
String jumpServers = null;
|
||||||
if (usingWWWProxy)
|
if (usingWWWProxy)
|
||||||
header = getErrorPage("dnfp", ERR_DESTINATION_UNKNOWN);
|
header = getErrorPage("dnfp", ERR_DESTINATION_UNKNOWN);
|
||||||
else if(ahelper != 0)
|
else if(ahelper != 0)
|
||||||
@ -569,9 +601,11 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
header = getErrorPage("dnf", ERR_DESTINATION_UNKNOWN);
|
header = getErrorPage("dnf", ERR_DESTINATION_UNKNOWN);
|
||||||
else {
|
else {
|
||||||
header = getErrorPage("dnfh", ERR_DESTINATION_UNKNOWN);
|
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();
|
s.close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -726,15 +760,16 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String jumpServers[] = {
|
private static String DEFAULT_JUMP_SERVERS =
|
||||||
"http://i2host.i2p/cgi-bin/i2hostjump?",
|
"http://i2host.i2p/cgi-bin/i2hostjump?," +
|
||||||
// "http://orion.i2p/jump/",
|
"http://stats.i2p/cgi-bin/jump.cgi?a=," +
|
||||||
"http://stats.i2p/cgi-bin/jump.cgi?a=",
|
"http://i2jump.i2p/";
|
||||||
// "http://trevorreznik.i2p/cgi-bin/jump.php?hostname=",
|
|
||||||
"http://i2jump.i2p/"
|
/**
|
||||||
};
|
* @param jumpServers comma- or space-separated list, or null
|
||||||
|
*/
|
||||||
private static void writeErrorMessage(byte[] errMessage, OutputStream out, String targetRequest,
|
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) {
|
if (out != null) {
|
||||||
out.write(errMessage);
|
out.write(errMessage);
|
||||||
if (targetRequest != null) {
|
if (targetRequest != null) {
|
||||||
@ -750,12 +785,17 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
out.write(uri.getBytes());
|
out.write(uri.getBytes());
|
||||||
out.write("</a>".getBytes());
|
out.write("</a>".getBytes());
|
||||||
if (usingWWWProxy) out.write(("<br>WWW proxy: " + wwwProxy).getBytes());
|
if (usingWWWProxy) out.write(("<br>WWW proxy: " + wwwProxy).getBytes());
|
||||||
if (showAddrHelper) {
|
if (jumpServers != null && jumpServers.length() > 0) {
|
||||||
// Fixme untranslated
|
// Fixme untranslated
|
||||||
out.write("<br><br>Click a link below to look for an address helper by using a \"jump\" service:<br>".getBytes());
|
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
|
// 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('/'));
|
jumphost = jumphost.substring(0, jumphost.indexOf('/'));
|
||||||
try {
|
try {
|
||||||
Destination dest = I2PTunnel.destFromName(jumphost);
|
Destination dest = I2PTunnel.destFromName(jumphost);
|
||||||
@ -765,10 +805,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
out.write("<br><a href=\"".getBytes());
|
out.write("<br><a href=\"".getBytes());
|
||||||
out.write(jumpServers[i].getBytes());
|
out.write(jurl.getBytes());
|
||||||
out.write(uri.getBytes());
|
out.write(uri.getBytes());
|
||||||
out.write("\">".getBytes());
|
out.write("\">".getBytes());
|
||||||
out.write(jumpServers[i].getBytes());
|
out.write(jurl.getBytes());
|
||||||
out.write(uri.getBytes());
|
out.write(uri.getBytes());
|
||||||
out.write("</a>".getBytes());
|
out.write("</a>".getBytes());
|
||||||
}
|
}
|
||||||
@ -792,7 +832,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
|
|||||||
header = getErrorPage(I2PAppContext.getGlobalContext(), "dnfp", ERR_DESTINATION_UNKNOWN);
|
header = getErrorPage(I2PAppContext.getGlobalContext(), "dnfp", ERR_DESTINATION_UNKNOWN);
|
||||||
else
|
else
|
||||||
header = getErrorPage(I2PAppContext.getGlobalContext(), "dnf", ERR_DESTINATION_UNKNOWN);
|
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) {
|
} catch (IOException ioe) {
|
||||||
// static
|
// static
|
||||||
//_log.warn(getPrefix(requestId) + "Error writing out the 'destination was unknown' " + "message", ioe);
|
//_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.client.streaming.I2PSocket;
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.util.EventDispatcher;
|
import net.i2p.util.EventDispatcher;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.data.Base32;
|
import net.i2p.data.Base32;
|
||||||
|
|
||||||
@ -118,7 +118,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
|
|||||||
useGZIP = true;
|
useGZIP = true;
|
||||||
|
|
||||||
if (allowGZIP && useGZIP) {
|
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();
|
req.start();
|
||||||
} else {
|
} else {
|
||||||
new I2PTunnelRunner(s, socket, slock, null, modifiedHeader.getBytes(), null);
|
new I2PTunnelRunner(s, socket, slock, null, modifiedHeader.getBytes(), null);
|
||||||
@ -174,7 +174,7 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
|
|||||||
_log.info("request headers: " + _headers);
|
_log.info("request headers: " + _headers);
|
||||||
serverout.write(_headers.getBytes());
|
serverout.write(_headers.getBytes());
|
||||||
browserin = _browser.getInputStream();
|
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();
|
sender.start();
|
||||||
|
|
||||||
browserout = _browser.getOutputStream();
|
browserout = _browser.getOutputStream();
|
||||||
|
@ -14,7 +14,7 @@ import net.i2p.client.streaming.I2PSocket;
|
|||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.util.EventDispatcher;
|
import net.i2p.util.EventDispatcher;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable {
|
public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable {
|
||||||
@ -83,9 +83,9 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
i2ps = createI2PSocket(clientDest);
|
i2ps = createI2PSocket(clientDest);
|
||||||
i2ps.setReadTimeout(readTimeout);
|
i2ps.setReadTimeout(readTimeout);
|
||||||
StringBuilder expectedPong = new StringBuilder();
|
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();
|
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();
|
out.start();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
if (_log.shouldLog(Log.ERROR))
|
if (_log.shouldLog(Log.ERROR))
|
||||||
|
@ -16,10 +16,10 @@ import net.i2p.client.streaming.I2PSocket;
|
|||||||
import net.i2p.data.ByteArray;
|
import net.i2p.data.ByteArray;
|
||||||
import net.i2p.util.ByteCache;
|
import net.i2p.util.ByteCache;
|
||||||
import net.i2p.util.Clock;
|
import net.i2p.util.Clock;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.Log;
|
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 final static Log _log = new Log(I2PTunnelRunner.class);
|
||||||
|
|
||||||
private static volatile long __runnerId;
|
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;
|
InputStream in;
|
||||||
OutputStream out;
|
OutputStream out;
|
||||||
|
@ -24,7 +24,7 @@ import net.i2p.client.streaming.I2PSocketManager;
|
|||||||
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
import net.i2p.client.streaming.I2PSocketManagerFactory;
|
||||||
import net.i2p.data.Base64;
|
import net.i2p.data.Base64;
|
||||||
import net.i2p.util.EventDispatcher;
|
import net.i2p.util.EventDispatcher;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
||||||
@ -132,7 +132,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void startRunning() {
|
public void startRunning() {
|
||||||
Thread t = new I2PThread(this);
|
Thread t = new I2PAppThread(this);
|
||||||
t.setName("Server " + (++__serverId));
|
t.setName("Server " + (++__serverId));
|
||||||
t.start();
|
t.start();
|
||||||
}
|
}
|
||||||
@ -204,7 +204,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
|||||||
I2PServerSocket i2pS_S = sockMgr.getServerSocket();
|
I2PServerSocket i2pS_S = sockMgr.getServerSocket();
|
||||||
int handlers = getHandlerCount();
|
int handlers = getHandlerCount();
|
||||||
for (int i = 0; i < handlers; i++) {
|
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();
|
handler.start();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -213,7 +213,7 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
|
|||||||
try {
|
try {
|
||||||
final I2PSocket i2ps = i2pS_S.accept();
|
final I2PSocket i2ps = i2pS_S.accept();
|
||||||
if (i2ps == null) throw new I2PException("I2PServerSocket closed");
|
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) {
|
} catch (I2PException ipe) {
|
||||||
if (_log.shouldLog(Log.ERROR))
|
if (_log.shouldLog(Log.ERROR))
|
||||||
_log.error("Error accepting - KILLING THE TUNNEL SERVER", ipe);
|
_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.client.streaming.I2PSocketManager;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.util.EventDispatcher;
|
import net.i2p.util.EventDispatcher;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
public class I2Ping extends I2PTunnelTask implements Runnable {
|
public class I2Ping extends I2PTunnelTask implements Runnable {
|
||||||
@ -59,7 +59,7 @@ public class I2Ping extends I2PTunnelTask implements Runnable {
|
|||||||
sockMgr = I2PTunnelClient.getSocketManager(tunnel);
|
sockMgr = I2PTunnelClient.getSocketManager(tunnel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Thread t = new I2PThread(this);
|
Thread t = new I2PAppThread(this);
|
||||||
t.setName("Client");
|
t.setName("Client");
|
||||||
t.start();
|
t.start();
|
||||||
open = true;
|
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;
|
private String destination;
|
||||||
|
|
||||||
public PingHandler(String dest) {
|
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.client.I2PSession;
|
||||||
import net.i2p.data.Base32;
|
import net.i2p.data.Base32;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -106,7 +106,7 @@ public class TunnelController implements Logging {
|
|||||||
public void startTunnelBackground() {
|
public void startTunnelBackground() {
|
||||||
if (_running) return;
|
if (_running) return;
|
||||||
_starting = true;
|
_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.I2PSession;
|
||||||
import net.i2p.client.I2PSessionException;
|
import net.i2p.client.I2PSessionException;
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PAppThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,7 +94,7 @@ public class TunnelControllerGroup {
|
|||||||
_controllers.add(controller);
|
_controllers.add(controller);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
I2PThread startupThread = new I2PThread(new StartControllers(), "Startup tunnels");
|
I2PAppThread startupThread = new I2PAppThread(new StartControllers(), "Startup tunnels");
|
||||||
startupThread.start();
|
startupThread.start();
|
||||||
|
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
|
@ -55,7 +55,7 @@ public class I2PSOCKSTunnel extends I2PTunnelClientBase {
|
|||||||
I2PSocket destSock = serv.getDestinationI2PSocket(this);
|
I2PSocket destSock = serv.getDestinationI2PSocket(this);
|
||||||
new I2PTunnelRunner(clientSock, destSock, sockLock, null, mySockets);
|
new I2PTunnelRunner(clientSock, destSock, sockLock, null, mySockets);
|
||||||
} catch (SOCKSException e) {
|
} catch (SOCKSException e) {
|
||||||
_log.error("Error from SOCKS connection: " + e.getMessage());
|
_log.error("Error from SOCKS connection", e);
|
||||||
closeSocket(s);
|
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"?>
|
<%@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">
|
<!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.EditBean" id="editBean" scope="request" />
|
||||||
|
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />
|
||||||
<% String tun = request.getParameter("tunnel");
|
<% String tun = request.getParameter("tunnel");
|
||||||
int curTunnel = -1;
|
int curTunnel = -1;
|
||||||
if (tun != null) {
|
if (tun != null) {
|
||||||
@ -13,7 +14,7 @@
|
|||||||
%>
|
%>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<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="text/html; charset=UTF-8" />
|
||||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
|
||||||
|
|
||||||
@ -205,9 +206,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="depthField" class="rowItem">
|
<div id="depthField" class="rowItem">
|
||||||
<label for="tunnelDepth" accesskey="t">
|
<label for="tunnelDepth" accesskey="t">
|
||||||
Dep<span class="accessKey">t</span>h:
|
Leng<span class="accessKey">t</span>h:
|
||||||
</label>
|
</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);
|
<% int tunnelDepth = editBean.getTunnelDepth(curTunnel, 2);
|
||||||
%><option value="0"<%=(tunnelDepth == 0 ? " selected=\"selected\"" : "") %>>0 hop tunnel (low anonymity, low latency)</option>
|
%><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>
|
<option value="1"<%=(tunnelDepth == 1 ? " selected=\"selected\"" : "") %>>1 hop tunnel (medium anonymity, medium latency)</option>
|
||||||
@ -222,7 +223,7 @@
|
|||||||
<label for="tunnelVariance" accesskey="v">
|
<label for="tunnelVariance" accesskey="v">
|
||||||
<span class="accessKey">V</span>ariance:
|
<span class="accessKey">V</span>ariance:
|
||||||
</label>
|
</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);
|
<% int tunnelVariance = editBean.getTunnelVariance(curTunnel, 0);
|
||||||
%><option value="0"<%=(tunnelVariance == 0 ? " selected=\"selected\"" : "") %>>0 hop variance (no randomisation, consistant performance)</option>
|
%><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>
|
<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"?>
|
<%@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">
|
<!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.EditBean" id="editBean" scope="request" />
|
||||||
|
<jsp:useBean class="net.i2p.i2ptunnel.web.Messages" id="intl" scope="request" />
|
||||||
<% String tun = request.getParameter("tunnel");
|
<% String tun = request.getParameter("tunnel");
|
||||||
int curTunnel = -1;
|
int curTunnel = -1;
|
||||||
if (tun != null) {
|
if (tun != null) {
|
||||||
@ -13,7 +14,7 @@
|
|||||||
%>
|
%>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<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="text/html; charset=UTF-8" />
|
||||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
|
||||||
|
|
||||||
@ -172,9 +173,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="depthField" class="rowItem">
|
<div id="depthField" class="rowItem">
|
||||||
<label for="tunnelDepth" accesskey="t">
|
<label for="tunnelDepth" accesskey="t">
|
||||||
Dep<span class="accessKey">t</span>h:
|
Leng<span class="accessKey">t</span>h:
|
||||||
</label>
|
</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);
|
<% int tunnelDepth = editBean.getTunnelDepth(curTunnel, 2);
|
||||||
%><option value="0"<%=(tunnelDepth == 0 ? " selected=\"selected\"" : "") %>>0 hop tunnel (low anonymity, low latency)</option>
|
%><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>
|
<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">
|
<!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:useBean class="net.i2p.i2ptunnel.web.IndexBean" id="indexBean" scope="request" />
|
||||||
<jsp:setProperty name="indexBean" property="*" />
|
<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">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<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="text/html; charset=UTF-8" />
|
||||||
<meta http-equiv="Content-Type" content="application/xhtml+xml; 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 again to get the latest messages_*.class files -->
|
||||||
<jar destfile="./build/routerconsole.jar" basedir="./build/obj" includes="**/*.class" update="true" />
|
<jar destfile="./build/routerconsole.jar" basedir="./build/obj" includes="**/*.class" update="true" />
|
||||||
</target>
|
</target>
|
||||||
<target name="poupdate" depends="compile">
|
<target name="poupdate" depends="build">
|
||||||
<ant target="war" />
|
<ant target="war" />
|
||||||
<!-- Update the messages_*.po files.
|
<!-- Update the messages_*.po files.
|
||||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
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..."
|
echo "Generating ${CLASS}_$LG ResourceBundle..."
|
||||||
|
|
||||||
# convert to class files in build/obj
|
# 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 ]
|
if [ $? -ne 0 ]
|
||||||
then
|
then
|
||||||
echo 'Warning - msgfmt failed, not updating translations'
|
echo 'Warning - msgfmt failed, not updating translations'
|
||||||
|
@ -232,7 +232,7 @@ public class ConfigNetHandler extends FormHandler {
|
|||||||
|
|
||||||
if (_requireIntroductions) {
|
if (_requireIntroductions) {
|
||||||
_context.router().setConfigSetting(UDPTransport.PROP_FORCE_INTRODUCERS, "true");
|
_context.router().setConfigSetting(UDPTransport.PROP_FORCE_INTRODUCERS, "true");
|
||||||
addFormNotice(_("Requiring SSU introduers"));
|
addFormNotice(_("Requiring SSU introducers"));
|
||||||
} else {
|
} else {
|
||||||
_context.router().removeConfigSetting(UDPTransport.PROP_FORCE_INTRODUCERS);
|
_context.router().removeConfigSetting(UDPTransport.PROP_FORCE_INTRODUCERS);
|
||||||
}
|
}
|
||||||
@ -256,24 +256,26 @@ public class ConfigNetHandler extends FormHandler {
|
|||||||
if (switchRequired) {
|
if (switchRequired) {
|
||||||
hiddenSwitch();
|
hiddenSwitch();
|
||||||
} else if (restartRequired) {
|
} else if (restartRequired) {
|
||||||
// Wow this dumps all conns immediately and really isn't nice
|
if (System.getProperty("wrapper.version") == null) {
|
||||||
//addFormNotice("Performing a soft restart");
|
// Wow this dumps all conns immediately and really isn't nice
|
||||||
//_context.router().restart();
|
addFormNotice("Performing a soft restart");
|
||||||
//addFormNotice("Soft restart complete");
|
_context.router().restart();
|
||||||
|
addFormNotice("Soft restart complete");
|
||||||
|
|
||||||
// Most of the time we aren't changing addresses, just enabling or disabling
|
// 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.
|
// things, so let's try just a new routerInfo and see how that works.
|
||||||
// Maybe we should restart if we change addresses though?
|
// Maybe we should restart if we change addresses though?
|
||||||
// No, this doesn't work well, really need to call SSU Transport externalAddressReceived(),
|
// 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.
|
// but that's hard to get to, and doesn't handle port changes, etc.
|
||||||
// So don't do this...
|
// So don't do this...
|
||||||
//_context.router().rebuildRouterInfo();
|
//_context.router().rebuildRouterInfo();
|
||||||
//addFormNotice("Router Info rebuilt");
|
//addFormNotice("Router Info rebuilt");
|
||||||
|
} else {
|
||||||
// There's a few changes that don't really require restart (e.g. enabling inbound TCP)
|
// 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.
|
// But it would be hard to get right, so just do a restart.
|
||||||
addFormError(_("Gracefully restarting I2P to change published router address"));
|
addFormError(_("Gracefully restarting I2P to change published router address"));
|
||||||
_context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
|
_context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,12 @@ public class ConfigRestartBean {
|
|||||||
long timeRemaining = ctx.router().getShutdownTimeRemaining();
|
long timeRemaining = ctx.router().getShutdownTimeRemaining();
|
||||||
StringBuilder buf = new StringBuilder(128);
|
StringBuilder buf = new StringBuilder(128);
|
||||||
if ((shuttingDown || restarting) && timeRemaining <= 0) {
|
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) {
|
} else if (shuttingDown) {
|
||||||
buf.append("<center><b>");
|
buf.append("<center><b>");
|
||||||
buf.append(_("Shutdown in {0}", DataHelper.formatDuration(timeRemaining), ctx));
|
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");
|
// buf.append("<tr><th></th><th>Inbound</th><th>Outbound</th></tr>\n");
|
||||||
|
|
||||||
// tunnel depth
|
// 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");
|
buf.append("<td align=\"center\"><select name=\"").append(index).append(".depthInbound\">\n");
|
||||||
int now = in.getLength();
|
int now = in.getLength();
|
||||||
renderOptions(buf, 0, MAX_LENGTH, now, "", HOP);
|
renderOptions(buf, 0, MAX_LENGTH, now, "", HOP);
|
||||||
|
@ -36,10 +36,10 @@ public class ConfigUIHelper extends HelperBase {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String langs[] = {"de", "en", "fr", "nl", "se", "zh"};
|
private static final String langs[] = {"de", "en", "fr", "nl", "ru", "sv", "zh"};
|
||||||
private static final String flags[] = {"de", "us", "fr", "nl", "se", "cn"};
|
private static final String flags[] = {"de", "us", "fr", "nl", "ru", "se", "cn"};
|
||||||
private static final String xlangs[] = {_x("German"), _x("English"), _x("French"),
|
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 */
|
/** todo sort by translated string */
|
||||||
public String getLangSettings() {
|
public String getLangSettings() {
|
||||||
|
@ -34,7 +34,7 @@ public class LogsHelper extends HelperBase {
|
|||||||
return "";
|
return "";
|
||||||
else {
|
else {
|
||||||
str = str.replaceAll("<", "<").replaceAll(">", ">");
|
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;
|
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.I2PAppContext;
|
||||||
import net.i2p.util.ConcurrentHashSet;
|
import net.i2p.util.Translate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate strings efficiently.
|
* Translate strings for this package.
|
||||||
* 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.
|
|
||||||
*/
|
*/
|
||||||
public class Messages {
|
public class Messages extends Translate {
|
||||||
public static final String PROP_LANG = "routerconsole.lang";
|
|
||||||
private static final String BUNDLE_NAME = "net.i2p.router.web.messages";
|
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 */
|
/** lang in routerconsole.lang property, else current locale */
|
||||||
public static String getString(String key, I2PAppContext ctx) {
|
public static String getString(String key, I2PAppContext ctx) {
|
||||||
String lang = getLanguage(ctx);
|
return Translate.getString(key, ctx, BUNDLE_NAME);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,45 +27,6 @@ public class Messages {
|
|||||||
* Use autoboxing to call with ints, longs, floats, etc.
|
* Use autoboxing to call with ints, longs, floats, etc.
|
||||||
*/
|
*/
|
||||||
public static String getString(String s, Object o, I2PAppContext ctx) {
|
public static String getString(String s, Object o, I2PAppContext ctx) {
|
||||||
String lang = getLanguage(ctx);
|
return Translate.getString(s, o, ctx, BUNDLE_NAME);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
|
|
||||||
|
import net.i2p.data.DataHelper;
|
||||||
|
|
||||||
public class NetDbHelper extends HelperBase {
|
public class NetDbHelper extends HelperBase {
|
||||||
private String _routerPrefix;
|
private String _routerPrefix;
|
||||||
@ -12,7 +13,11 @@ public class NetDbHelper extends HelperBase {
|
|||||||
|
|
||||||
public NetDbHelper() {}
|
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) {
|
public void setFull(String f) {
|
||||||
try {
|
try {
|
||||||
_full = Integer.parseInt(f);
|
_full = Integer.parseInt(f);
|
||||||
|
@ -179,7 +179,7 @@ public class NewsFetcher implements Runnable, EepGet.StatusListener {
|
|||||||
if (get.fetch()) {
|
if (get.fetch()) {
|
||||||
String lastmod = get.getLastModified();
|
String lastmod = get.getLastModified();
|
||||||
if (lastmod != null) {
|
if (lastmod != null) {
|
||||||
if (!(_context instanceof RouterContext)) return;
|
if (!(_context.isRouterContext())) return;
|
||||||
long modtime = parse822Date(lastmod);
|
long modtime = parse822Date(lastmod);
|
||||||
if (modtime <= 0) return;
|
if (modtime <= 0) return;
|
||||||
String lastUpdate = _context.getProperty(UpdateHandler.PROP_LAST_UPDATE_TIME);
|
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))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Policy requests update, so we update");
|
_log.debug("Policy requests update, so we update");
|
||||||
UpdateHandler handler = null;
|
UpdateHandler handler = null;
|
||||||
if (_context instanceof RouterContext) {
|
if (_context.isRouterContext()) {
|
||||||
handler = new UpdateHandler((RouterContext)_context);
|
handler = new UpdateHandler((RouterContext)_context);
|
||||||
} else {
|
} else {
|
||||||
List contexts = RouterContext.listContexts();
|
List contexts = RouterContext.listContexts();
|
||||||
|
@ -32,7 +32,7 @@ class ProfileOrganizerRenderer {
|
|||||||
_organizer = organizer;
|
_organizer = organizer;
|
||||||
_comparator = new ProfileComparator();
|
_comparator = new ProfileComparator();
|
||||||
}
|
}
|
||||||
public void renderStatusHTML(Writer out) throws IOException {
|
public void renderStatusHTML(Writer out, boolean full) throws IOException {
|
||||||
Set peers = _organizer.selectAllPeers();
|
Set peers = _organizer.selectAllPeers();
|
||||||
|
|
||||||
long now = _context.clock().now();
|
long now = _context.clock().now();
|
||||||
@ -40,18 +40,27 @@ class ProfileOrganizerRenderer {
|
|||||||
|
|
||||||
TreeSet order = new TreeSet(_comparator);
|
TreeSet order = new TreeSet(_comparator);
|
||||||
TreeSet integratedPeers = new TreeSet(_comparator);
|
TreeSet integratedPeers = new TreeSet(_comparator);
|
||||||
|
int older = 0;
|
||||||
|
int standard = 0;
|
||||||
for (Iterator iter = peers.iterator(); iter.hasNext();) {
|
for (Iterator iter = peers.iterator(); iter.hasNext();) {
|
||||||
Hash peer = (Hash)iter.next();
|
Hash peer = (Hash)iter.next();
|
||||||
if (_organizer.getUs().equals(peer)) continue;
|
if (_organizer.getUs().equals(peer)) continue;
|
||||||
PeerProfile prof = _organizer.getProfile(peer);
|
PeerProfile prof = _organizer.getProfile(peer);
|
||||||
if (_organizer.isWellIntegrated(peer)) {
|
//if (_organizer.isWellIntegrated(peer)) {
|
||||||
integratedPeers.add(prof);
|
// integratedPeers.add(prof);
|
||||||
} else {
|
//} else {
|
||||||
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
|
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
|
||||||
if (info != null && info.getCapabilities().indexOf("f") >= 0)
|
if (info != null && info.getCapabilities().indexOf("f") >= 0)
|
||||||
integratedPeers.add(prof);
|
integratedPeers.add(prof);
|
||||||
|
//}
|
||||||
|
if (prof.getLastSendSuccessful() <= hideBefore) {
|
||||||
|
older++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((!full) && !_organizer.isHighCapacity(peer)) {
|
||||||
|
standard++;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if (prof.getLastSendSuccessful() <= hideBefore) continue;
|
|
||||||
order.add(prof);
|
order.add(prof);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +71,10 @@ class ProfileOrganizerRenderer {
|
|||||||
StringBuilder buf = new StringBuilder(16*1024);
|
StringBuilder buf = new StringBuilder(16*1024);
|
||||||
buf.append("<h2>").append(_("Peer Profiles")).append("</h2>\n<p>");
|
buf.append("<h2>").append(_("Peer Profiles")).append("</h2>\n<p>");
|
||||||
buf.append(_("Showing {0} recent profiles.", order.size())).append('\n');
|
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("</p>");
|
||||||
buf.append("<table>");
|
buf.append("<table>");
|
||||||
buf.append("<tr>");
|
buf.append("<tr>");
|
||||||
@ -169,7 +181,7 @@ class ProfileOrganizerRenderer {
|
|||||||
}
|
}
|
||||||
buf.append("</table>");
|
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("<table>");
|
||||||
buf.append("<tr>");
|
buf.append("<tr>");
|
||||||
buf.append("<th class=\"smallhead\">").append(_("Peer")).append("</th>");
|
buf.append("<th class=\"smallhead\">").append(_("Peer")).append("</th>");
|
||||||
@ -231,6 +243,7 @@ class ProfileOrganizerRenderer {
|
|||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
buf.append("<td align=\"right\">").append(_(NA));
|
buf.append("<td align=\"right\">").append(_(NA));
|
||||||
}
|
}
|
||||||
|
buf.append("</tr>\n");
|
||||||
}
|
}
|
||||||
buf.append("</table>");
|
buf.append("</table>");
|
||||||
|
|
||||||
@ -324,12 +337,15 @@ class ProfileOrganizerRenderer {
|
|||||||
private String davg (DBHistory dbh, long rate) {
|
private String davg (DBHistory dbh, long rate) {
|
||||||
RateStat rs = dbh.getFailedLookupRate();
|
RateStat rs = dbh.getFailedLookupRate();
|
||||||
if (rs == null)
|
if (rs == null)
|
||||||
return _(NA);
|
return "0%";
|
||||||
Rate r = rs.getRate(rate);
|
Rate r = rs.getRate(rate);
|
||||||
if (r == null)
|
if (r == null)
|
||||||
return _(NA);
|
return "0%";
|
||||||
long c = r.getCurrentEventCount() + r.getLastEventCount();
|
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 */
|
/** translate a string */
|
||||||
|
@ -4,13 +4,19 @@ import java.io.IOException;
|
|||||||
|
|
||||||
|
|
||||||
public class ProfilesHelper extends HelperBase {
|
public class ProfilesHelper extends HelperBase {
|
||||||
|
private boolean _full;
|
||||||
|
|
||||||
public ProfilesHelper() {}
|
public ProfilesHelper() {}
|
||||||
|
|
||||||
|
public void setFull(String f) {
|
||||||
|
_full = f != null;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return empty string, writes directly to _out */
|
/** @return empty string, writes directly to _out */
|
||||||
public String getProfileSummary() {
|
public String getProfileSummary() {
|
||||||
try {
|
try {
|
||||||
ProfileOrganizerRenderer rend = new ProfileOrganizerRenderer(_context.profileOrganizer(), _context);
|
ProfileOrganizerRenderer rend = new ProfileOrganizerRenderer(_context.profileOrganizer(), _context);
|
||||||
rend.renderStatusHTML(_out);
|
rend.renderStatusHTML(_out, _full);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
ioe.printStackTrace();
|
ioe.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.i2p.router.web;
|
package net.i2p.router.web;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
import java.io.FilenameFilter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -20,6 +21,7 @@ import org.mortbay.http.SecurityConstraint;
|
|||||||
import org.mortbay.http.handler.SecurityHandler;
|
import org.mortbay.http.handler.SecurityHandler;
|
||||||
import org.mortbay.jetty.Server;
|
import org.mortbay.jetty.Server;
|
||||||
import org.mortbay.jetty.servlet.WebApplicationContext;
|
import org.mortbay.jetty.servlet.WebApplicationContext;
|
||||||
|
import org.mortbay.jetty.servlet.WebApplicationHandler;
|
||||||
|
|
||||||
public class RouterConsoleRunner {
|
public class RouterConsoleRunner {
|
||||||
private Server _server;
|
private Server _server;
|
||||||
@ -87,6 +89,8 @@ public class RouterConsoleRunner {
|
|||||||
if (!_webAppsDir.endsWith("/"))
|
if (!_webAppsDir.endsWith("/"))
|
||||||
_webAppsDir += '/';
|
_webAppsDir += '/';
|
||||||
|
|
||||||
|
List<String> notStarted = new ArrayList();
|
||||||
|
WebApplicationHandler baseHandler = null;
|
||||||
try {
|
try {
|
||||||
StringTokenizer tok = new StringTokenizer(_listenHost, " ,");
|
StringTokenizer tok = new StringTokenizer(_listenHost, " ,");
|
||||||
int boundAddresses = 0;
|
int boundAddresses = 0;
|
||||||
@ -111,7 +115,8 @@ public class RouterConsoleRunner {
|
|||||||
File tmpdir = new File(workDir, ROUTERCONSOLE + "-" + _listenPort);
|
File tmpdir = new File(workDir, ROUTERCONSOLE + "-" + _listenPort);
|
||||||
tmpdir.mkdir();
|
tmpdir.mkdir();
|
||||||
wac.setTempDirectory(tmpdir);
|
wac.setTempDirectory(tmpdir);
|
||||||
wac.addHandler(0, new LocaleWebAppHandler(I2PAppContext.getGlobalContext()));
|
baseHandler = new LocaleWebAppHandler(I2PAppContext.getGlobalContext());
|
||||||
|
wac.addHandler(0, baseHandler);
|
||||||
initialize(wac);
|
initialize(wac);
|
||||||
File dir = new File(_webAppsDir);
|
File dir = new File(_webAppsDir);
|
||||||
String fileNames[] = dir.list(WarFilenameFilter.instance());
|
String fileNames[] = dir.list(WarFilenameFilter.instance());
|
||||||
@ -132,6 +137,8 @@ public class RouterConsoleRunner {
|
|||||||
props.setProperty(PREFIX + appName + ENABLED, "true");
|
props.setProperty(PREFIX + appName + ENABLED, "true");
|
||||||
rewrite = true;
|
rewrite = true;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
notStarted.add(appName);
|
||||||
}
|
}
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
System.err.println("Error resolving '" + fileNames[i] + "' in '" + dir);
|
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" +
|
"\"::1,\" in the \"clientApp.0.args\" line of the clients.config file.\n" +
|
||||||
"Exception: " + me);
|
"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 {
|
try {
|
||||||
SysTray tray = SysTray.getInstance();
|
SysTray tray = SysTray.getInstance();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
@ -40,7 +40,7 @@ public class StatsGenerator {
|
|||||||
String group = (String)entry.getKey();
|
String group = (String)entry.getKey();
|
||||||
Set stats = (Set)entry.getValue();
|
Set stats = (Set)entry.getValue();
|
||||||
buf.append("<option value=\"/stats.jsp#").append(group).append("\">");
|
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(); ) {
|
for (Iterator statIter = stats.iterator(); statIter.hasNext(); ) {
|
||||||
String stat = (String)statIter.next();
|
String stat = (String)statIter.next();
|
||||||
buf.append("<option value=\"/stats.jsp#");
|
buf.append("<option value=\"/stats.jsp#");
|
||||||
@ -52,7 +52,7 @@ public class StatsGenerator {
|
|||||||
out.write(buf.toString());
|
out.write(buf.toString());
|
||||||
buf.setLength(0);
|
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("</form>");
|
||||||
|
|
||||||
buf.append(_("Statistics gathered during this router's uptime")).append(" (");
|
buf.append(_("Statistics gathered during this router's uptime")).append(" (");
|
||||||
@ -69,7 +69,7 @@ public class StatsGenerator {
|
|||||||
buf.append("<h3><a name=\"");
|
buf.append("<h3><a name=\"");
|
||||||
buf.append(group);
|
buf.append(group);
|
||||||
buf.append("\">");
|
buf.append("\">");
|
||||||
buf.append(group);
|
buf.append(_(group));
|
||||||
buf.append("</a></h3>");
|
buf.append("</a></h3>");
|
||||||
buf.append("<ul>");
|
buf.append("<ul>");
|
||||||
out.write(buf.toString());
|
out.write(buf.toString());
|
||||||
@ -88,7 +88,7 @@ public class StatsGenerator {
|
|||||||
out.write(buf.toString());
|
out.write(buf.toString());
|
||||||
buf.setLength(0);
|
buf.setLength(0);
|
||||||
}
|
}
|
||||||
out.write("</ul><br>");
|
out.write("</ul><br>\n");
|
||||||
}
|
}
|
||||||
out.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ public class StatsGenerator {
|
|||||||
for (int i = 0; i < periods.length; i++) {
|
for (int i = 0; i < periods.length; i++) {
|
||||||
if (periods[i] > uptime)
|
if (periods[i] > uptime)
|
||||||
break;
|
break;
|
||||||
renderPeriod(buf, periods[i], "frequency");
|
renderPeriod(buf, periods[i], _("frequency"));
|
||||||
Frequency curFreq = freq.getFrequency(periods[i]);
|
Frequency curFreq = freq.getFrequency(periods[i]);
|
||||||
buf.append(" <i>avg per period:</i> (");
|
buf.append(" <i>avg per period:</i> (");
|
||||||
buf.append(num(curFreq.getAverageEventsPerPeriod()));
|
buf.append(num(curFreq.getAverageEventsPerPeriod()));
|
||||||
@ -124,9 +124,9 @@ public class StatsGenerator {
|
|||||||
buf.append(" using the lifetime of ");
|
buf.append(" using the lifetime of ");
|
||||||
buf.append(curFreq.getEventCount());
|
buf.append(curFreq.getEventCount());
|
||||||
buf.append(" events)");
|
buf.append(" events)");
|
||||||
buf.append("<br>");
|
buf.append("<br>\n");
|
||||||
}
|
}
|
||||||
buf.append("<br>");
|
buf.append("<br>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderRate(String name, StringBuilder buf) {
|
private void renderRate(String name, StringBuilder buf) {
|
||||||
@ -138,7 +138,7 @@ public class StatsGenerator {
|
|||||||
buf.append("</i><br>");
|
buf.append("</i><br>");
|
||||||
}
|
}
|
||||||
if (rate.getLifetimeEventCount() <= 0) {
|
if (rate.getLifetimeEventCount() <= 0) {
|
||||||
buf.append("No lifetime events<br>");
|
buf.append(_("No lifetime events")).append("<br>\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long now = _context.clock().now();
|
long now = _context.clock().now();
|
||||||
@ -150,9 +150,9 @@ public class StatsGenerator {
|
|||||||
if (curRate.getLastCoalesceDate() <= curRate.getCreationDate())
|
if (curRate.getLastCoalesceDate() <= curRate.getCreationDate())
|
||||||
break;
|
break;
|
||||||
buf.append("<li>");
|
buf.append("<li>");
|
||||||
renderPeriod(buf, periods[i], "rate");
|
renderPeriod(buf, periods[i], _("rate"));
|
||||||
if (curRate.getLastEventCount() > 0) {
|
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(num(curRate.getAverageValue()));
|
||||||
buf.append(" peak ");
|
buf.append(" peak ");
|
||||||
buf.append(num(curRate.getExtremeAverageValue()));
|
buf.append(num(curRate.getExtremeAverageValue()));
|
||||||
@ -181,21 +181,21 @@ public class StatsGenerator {
|
|||||||
buf.append(num(curRate.getExtremeSaturationLimit()));
|
buf.append(num(curRate.getExtremeSaturationLimit()));
|
||||||
buf.append(")");
|
buf.append(")");
|
||||||
}
|
}
|
||||||
buf.append(" <i>events:</i> ");
|
buf.append(" <i>").append(_("events")).append(":</i> ");
|
||||||
buf.append(curRate.getLastEventCount());
|
buf.append(curRate.getLastEventCount());
|
||||||
buf.append(" <i>in this period which ended:</i> ");
|
buf.append(" <i>in this period which ended:</i> ");
|
||||||
buf.append(DataHelper.formatDuration(now - curRate.getLastCoalesceDate()));
|
buf.append(DataHelper.formatDuration(now - curRate.getLastCoalesceDate()));
|
||||||
buf.append(" ago ");
|
buf.append(" ago ");
|
||||||
} else {
|
} else {
|
||||||
buf.append(" <i>No events</i> ");
|
buf.append(" <i>").append(_("No events")).append("</i> ");
|
||||||
}
|
}
|
||||||
long numPeriods = curRate.getLifetimePeriods();
|
long numPeriods = curRate.getLifetimePeriods();
|
||||||
if (numPeriods > 0) {
|
if (numPeriods > 0) {
|
||||||
double avgFrequency = curRate.getLifetimeEventCount() / (double)numPeriods;
|
double avgFrequency = curRate.getLifetimeEventCount() / (double)numPeriods;
|
||||||
double peakFrequency = curRate.getExtremeEventCount();
|
double peakFrequency = curRate.getExtremeEventCount();
|
||||||
buf.append(" (lifetime average: ");
|
buf.append(" (").append(_("lifetime average")).append(": ");
|
||||||
buf.append(num(avgFrequency));
|
buf.append(num(avgFrequency));
|
||||||
buf.append(", peak average: ");
|
buf.append(", ").append(_("peak average")).append(": ");
|
||||||
buf.append(curRate.getExtremeEventCount());
|
buf.append(curRate.getExtremeEventCount());
|
||||||
buf.append(")");
|
buf.append(")");
|
||||||
}
|
}
|
||||||
@ -210,16 +210,16 @@ public class StatsGenerator {
|
|||||||
buf.append("&format=xml\" title=\"Dump stat history as XML\">XML</a>");
|
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(" 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
|
// 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(num(rate.getLifetimeAverageValue()));
|
||||||
buf.append(" over ");
|
buf.append(" over ");
|
||||||
buf.append(rate.getLifetimeEventCount());
|
buf.append(rate.getLifetimeEventCount());
|
||||||
buf.append(" events<br></li>");
|
buf.append(" events<br></li>");
|
||||||
buf.append("</ul>");
|
buf.append("</ul>");
|
||||||
buf.append("<br>");
|
buf.append("<br>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void renderPeriod(StringBuilder buf, long period, String name) {
|
private static void renderPeriod(StringBuilder buf, long period, String name) {
|
||||||
@ -240,4 +240,9 @@ public class StatsGenerator {
|
|||||||
private String _(String s) {
|
private String _(String s) {
|
||||||
return Messages.getString(s, _context);
|
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;
|
_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 {
|
public void renderSummaryHTML(Writer out) throws IOException {
|
||||||
StringBuilder buf = new StringBuilder(8*1024);
|
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(_("I2P Router Console"))
|
||||||
.append("\" title=\"")
|
.append("\" title=\"")
|
||||||
.append(_("I2P Router Console"))
|
.append(_("I2P Router Console"))
|
||||||
@ -44,19 +48,19 @@ public class SummaryBarRenderer {
|
|||||||
|
|
||||||
"<hr><table>" +
|
"<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(_("Manage your I2P hosts file here (I2P domain name resolution)"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Addressbook"))
|
.append(_("Addressbook"))
|
||||||
.append("</a>\n" +
|
.append("</a>\n" +
|
||||||
|
|
||||||
"<a href=\"i2psnark/\" target=\"_blank\" title=\"")
|
"<a href=\"/i2psnark/\" target=\"_blank\" title=\"")
|
||||||
.append(_("Built-in anonymous BitTorrent Client"))
|
.append(_("Built-in anonymous BitTorrent Client"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Torrents"))
|
.append(_("Torrents"))
|
||||||
.append("</a>\n" +
|
.append("</a>\n" +
|
||||||
|
|
||||||
"<a href=\"susimail/susimail\" target=\"blank\" title=\"")
|
"<a href=\"/susimail/susimail\" target=\"blank\" title=\"")
|
||||||
.append(_("Anonymous webmail client"))
|
.append(_("Anonymous webmail client"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Webmail"))
|
.append(_("Webmail"))
|
||||||
@ -68,7 +72,7 @@ public class SummaryBarRenderer {
|
|||||||
.append(_("Webserver"))
|
.append(_("Webserver"))
|
||||||
.append("</a></td></tr></table>\n" +
|
.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(_("Configure I2P Router"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("I2P Internals"))
|
.append(_("I2P Internals"))
|
||||||
@ -76,49 +80,49 @@ public class SummaryBarRenderer {
|
|||||||
|
|
||||||
"<table><tr><td>\n" +
|
"<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(_("View existing tunnels and tunnel build status"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Tunnels"))
|
.append(_("Tunnels"))
|
||||||
.append("</a>\n" +
|
.append("</a>\n" +
|
||||||
|
|
||||||
"<a href=\"peers.jsp\" target=\"_top\" title=\"")
|
"<a href=\"/peers.jsp\" target=\"_top\" title=\"")
|
||||||
.append(_("Show all current peer connections"))
|
.append(_("Show all current peer connections"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Peers"))
|
.append(_("Peers"))
|
||||||
.append("</a>\n" +
|
.append("</a>\n" +
|
||||||
|
|
||||||
"<a href=\"profiles.jsp\" target=\"_top\" title=\"")
|
"<a href=\"/profiles.jsp\" target=\"_top\" title=\"")
|
||||||
.append(_("Show recent peer performance profiles"))
|
.append(_("Show recent peer performance profiles"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Profiles"))
|
.append(_("Profiles"))
|
||||||
.append("</a>\n" +
|
.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(_("Show list of all known I2P routers"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("NetDB"))
|
.append(_("NetDB"))
|
||||||
.append("</a>\n" +
|
.append("</a>\n" +
|
||||||
|
|
||||||
"<a href=\"logs.jsp\" target=\"_top\" title=\"")
|
"<a href=\"/logs.jsp\" target=\"_top\" title=\"")
|
||||||
.append(_("Health Report"))
|
.append(_("Health Report"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Logs"))
|
.append(_("Logs"))
|
||||||
.append("</a>\n" +
|
.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(_("Show the router's workload, and how it's performing"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Jobs"))
|
.append(_("Jobs"))
|
||||||
.append("</a>\n" +
|
.append("</a>\n" +
|
||||||
|
|
||||||
"<a href=\"graphs.jsp\" target=\"_top\" title=\"")
|
"<a href=\"/graphs.jsp\" target=\"_top\" title=\"")
|
||||||
.append(_("Graph router performance"))
|
.append(_("Graph router performance"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Graphs"))
|
.append(_("Graphs"))
|
||||||
.append("</a>\n" +
|
.append("</a>\n" +
|
||||||
|
|
||||||
"<a href=\"stats.jsp\" target=\"_top\" title=\"")
|
"<a href=\"/stats.jsp\" target=\"_top\" title=\"")
|
||||||
.append(_("Textual router performance statistics"))
|
.append(_("Textual router performance statistics"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Stats"))
|
.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(_("I2P Router Help"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("General"))
|
.append(_("General"))
|
||||||
@ -141,7 +145,7 @@ public class SummaryBarRenderer {
|
|||||||
.append(_helper.getIdent())
|
.append(_helper.getIdent())
|
||||||
.append(", ")
|
.append(", ")
|
||||||
.append(_("never reveal it to anyone"))
|
.append(_("never reveal it to anyone"))
|
||||||
.append("\" href=\"netdb.jsp?r=.\" target=\"_top\">")
|
.append("\" href=\"/netdb.jsp?r=.\" target=\"_top\">")
|
||||||
.append(_("Local Identity"))
|
.append(_("Local Identity"))
|
||||||
.append("</a></h4><hr>\n" +
|
.append("</a></h4><hr>\n" +
|
||||||
|
|
||||||
@ -163,7 +167,7 @@ public class SummaryBarRenderer {
|
|||||||
.append(_helper.getUptime())
|
.append(_helper.getUptime())
|
||||||
.append("</td></tr></table>\n" +
|
.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(_("Help with configuring your firewall and router for optimal I2P performance"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_helper.getReachability())
|
.append(_helper.getReachability())
|
||||||
@ -172,7 +176,7 @@ public class SummaryBarRenderer {
|
|||||||
|
|
||||||
if (_helper.updateAvailable() || _helper.unsignedUpdateAvailable()) {
|
if (_helper.updateAvailable() || _helper.unsignedUpdateAvailable()) {
|
||||||
// display all the time so we display the final failure message
|
// 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"))) {
|
if ("true".equals(System.getProperty("net.i2p.router.web.UpdateHandler.updateInProgress"))) {
|
||||||
// nothing
|
// nothing
|
||||||
} else if(
|
} 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.noncePrev", prev);
|
||||||
System.setProperty("net.i2p.router.web.UpdateHandler.nonce", nonce+"");
|
System.setProperty("net.i2p.router.web.UpdateHandler.nonce", nonce+"");
|
||||||
String uri = _helper.getRequestURI();
|
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");
|
buf.append("<input type=\"hidden\" name=\"updateNonce\" value=\"").append(nonce).append("\" >\n");
|
||||||
if (_helper.updateAvailable()) {
|
if (_helper.updateAvailable()) {
|
||||||
buf.append("<button type=\"submit\" name=\"updateAction\" value=\"signed\" >")
|
buf.append("<button type=\"submit\" name=\"updateAction\" value=\"signed\" >")
|
||||||
@ -217,7 +221,7 @@ public class SummaryBarRenderer {
|
|||||||
buf.append("<p>")
|
buf.append("<p>")
|
||||||
.append(ConfigRestartBean.renderStatus(_helper.getRequestURI(), _helper.getAction(), _helper.getConsoleNonce()))
|
.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(_("Show all current peer connections"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Peers"))
|
.append(_("Peers"))
|
||||||
@ -266,7 +270,7 @@ public class SummaryBarRenderer {
|
|||||||
|
|
||||||
boolean anotherLine = false;
|
boolean anotherLine = false;
|
||||||
if (_helper.showFirewallWarning()) {
|
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(_("Help with firewall configuration"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Check NAT/firewall"))
|
.append(_("Check NAT/firewall"))
|
||||||
@ -305,7 +309,7 @@ public class SummaryBarRenderer {
|
|||||||
buf.append("<hr>");
|
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(_("Configure router bandwidth allocation"))
|
||||||
.append("\" target=\"_top\">")
|
.append("\" target=\"_top\">")
|
||||||
.append(_("Bandwidth in/out"))
|
.append(_("Bandwidth in/out"))
|
||||||
@ -340,7 +344,7 @@ public class SummaryBarRenderer {
|
|||||||
.append(_helper.getOutboundTransferred())
|
.append(_helper.getOutboundTransferred())
|
||||||
.append("</td></tr></table>\n" +
|
.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(_("View existing tunnels and tunnel build status"))
|
||||||
.append("\">")
|
.append("\">")
|
||||||
.append(_("Tunnels in/out"))
|
.append(_("Tunnels in/out"))
|
||||||
|
@ -62,6 +62,9 @@ public class SummaryHelper extends HelperBase {
|
|||||||
return DataHelper.formatDuration(router.getUptime());
|
return DataHelper.formatDuration(router.getUptime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
this displayed offset, not skew - now handled in reachability()
|
||||||
|
|
||||||
private String timeSkew() {
|
private String timeSkew() {
|
||||||
if (_context == null) return "";
|
if (_context == null) return "";
|
||||||
//if (!_context.clock().getUpdatedSuccessfully())
|
//if (!_context.clock().getUpdatedSuccessfully())
|
||||||
@ -72,6 +75,7 @@ public class SummaryHelper extends HelperBase {
|
|||||||
return "";
|
return "";
|
||||||
return " (" + DataHelper.formatDuration(diff) + " " + _("skew") + ")";
|
return " (" + DataHelper.formatDuration(diff) + " " + _("skew") + ")";
|
||||||
}
|
}
|
||||||
|
**/
|
||||||
|
|
||||||
public boolean allowReseed() {
|
public boolean allowReseed() {
|
||||||
return _context.netDb().isInitialized() &&
|
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 int getAllPeers() { return Math.max(_context.netDb().getKnownRouters() - 1, 0); }
|
||||||
|
|
||||||
public String getReachability() {
|
public String getReachability() {
|
||||||
return reachability() + timeSkew();
|
return reachability(); // + timeSkew();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String reachability() {
|
private String reachability() {
|
||||||
if (_context.router().getUptime() > 60*1000 && (!_context.router().gracefulShutdownInProgress()) &&
|
if (_context.router().getUptime() > 60*1000 && (!_context.router().gracefulShutdownInProgress()) &&
|
||||||
!_context.clientManager().isAlive())
|
!_context.clientManager().isAlive())
|
||||||
return _("ERR-Client Manager I2CP Error - check logs"); // not a router problem but the user should know
|
return _("ERR-Client Manager I2CP Error - check logs"); // not a router problem but the user should know
|
||||||
if (!_context.clock().getUpdatedSuccessfully())
|
// Warn based on actual skew from peers, not update status, so if we successfully offset
|
||||||
return _("ERR-ClockSkew");
|
// 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())
|
if (_context.router().isHidden())
|
||||||
return _("Hidden");
|
return _("Hidden");
|
||||||
|
|
||||||
@ -118,7 +127,9 @@ public class SummaryHelper extends HelperBase {
|
|||||||
default:
|
default:
|
||||||
ra = _context.router().getRouterInfo().getTargetAddress("SSU");
|
ra = _context.router().getRouterInfo().getTargetAddress("SSU");
|
||||||
if (ra == null && _context.router().getUptime() > 5*60*1000) {
|
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)
|
_context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_PORT) == null)
|
||||||
return _("ERR-UDP Disabled and Inbound TCP host/port not set");
|
return _("ERR-UDP Disabled and Inbound TCP host/port not set");
|
||||||
else
|
else
|
||||||
|
@ -23,6 +23,7 @@ import net.i2p.router.TunnelInfo;
|
|||||||
import net.i2p.router.TunnelPoolSettings;
|
import net.i2p.router.TunnelPoolSettings;
|
||||||
import net.i2p.router.tunnel.HopConfig;
|
import net.i2p.router.tunnel.HopConfig;
|
||||||
import net.i2p.router.tunnel.pool.TunnelPool;
|
import net.i2p.router.tunnel.pool.TunnelPool;
|
||||||
|
import net.i2p.router.CommSystemFacade;
|
||||||
import net.i2p.stat.RateStat;
|
import net.i2p.stat.RateStat;
|
||||||
import net.i2p.util.ObjectCounter;
|
import net.i2p.util.ObjectCounter;
|
||||||
|
|
||||||
@ -229,10 +230,10 @@ public class TunnelRenderer {
|
|||||||
Set<Hash> peers = new HashSet(lc.objects());
|
Set<Hash> peers = new HashSet(lc.objects());
|
||||||
peers.addAll(pc.objects());
|
peers.addAll(pc.objects());
|
||||||
List<Hash> peerList = new ArrayList(peers);
|
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("<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) {
|
for (Hash h : peerList) {
|
||||||
out.write("<tr> <td class=\"cells\" align=\"center\">");
|
out.write("<tr> <td class=\"cells\" align=\"center\">");
|
||||||
out.write(netDbLink(h));
|
out.write(netDbLink(h));
|
||||||
@ -250,7 +251,7 @@ public class TunnelRenderer {
|
|||||||
out.write('0');
|
out.write('0');
|
||||||
out.write('\n');
|
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> <td align=\"center\"><b>" + partCount);
|
||||||
out.write("</b> <td> </td></tr></table></div>\n");
|
out.write("</b> <td> </td></tr></table></div>\n");
|
||||||
}
|
}
|
||||||
@ -295,6 +296,26 @@ public class TunnelRenderer {
|
|||||||
return ((Hash)l).toBase64().compareTo(((Hash)r).toBase64());
|
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) {
|
private String getCapacity(Hash peer) {
|
||||||
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
|
RouterInfo info = _context.netDb().lookupRouterInfoLocally(peer);
|
||||||
|
@ -52,5 +52,24 @@ class Dummy {
|
|||||||
_("dark");
|
_("dark");
|
||||||
_("light");
|
_("light");
|
||||||
_("midnight");
|
_("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" />" />
|
<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")%>
|
<%=intl._("KBps In")%>
|
||||||
</td><td>(<jsp:getProperty name="nethelper" property="inboundRateBits" />)</td>
|
</td><td>(<jsp:getProperty name="nethelper" property="inboundRateBits" />)</td>
|
||||||
|
<% /********
|
||||||
<!-- let's keep this simple...
|
<!-- let's keep this simple...
|
||||||
bursting up to
|
bursting up to
|
||||||
<input name="inboundburstrate" type="text" size="5" value="<jsp:getProperty name="nethelper" property="inboundBurstRate" />" /> KBps for
|
<input name="inboundburstrate" type="text" size="5" value="<jsp:getProperty name="nethelper" property="inboundBurstRate" />" /> KBps for
|
||||||
<jsp:getProperty name="nethelper" property="inboundBurstFactorBox" /><br>
|
<jsp:getProperty name="nethelper" property="inboundBurstFactorBox" /><br>
|
||||||
-->
|
-->
|
||||||
|
*********/ %>
|
||||||
</tr><tr>
|
</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" />" />
|
<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")%>
|
<%=intl._("KBps Out")%>
|
||||||
</td><td>(<jsp:getProperty name="nethelper" property="outboundRateBits" />)</td>
|
</td><td>(<jsp:getProperty name="nethelper" property="outboundRateBits" />)</td>
|
||||||
|
<% /********
|
||||||
<!-- let's keep this simple...
|
<!-- let's keep this simple...
|
||||||
bursting up to
|
bursting up to
|
||||||
<input name="outboundburstrate" type="text" size="2" value="<jsp:getProperty name="nethelper" property="outboundBurstRate" />" /> KBps for
|
<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>
|
<i>KBps = kilobytes per second = 1024 bytes per second = 8192 bits per second.<br>
|
||||||
A negative rate sets the default.</i><br>
|
A negative rate sets the default.</i><br>
|
||||||
-->
|
-->
|
||||||
|
*********/ %>
|
||||||
</tr><tr>
|
</tr><tr>
|
||||||
<td><jsp:getProperty name="nethelper" property="sharePercentageBox" /> <%=intl._("Share")%></td>
|
<td><jsp:getProperty name="nethelper" property="sharePercentageBox" /> <%=intl._("Share")%></td>
|
||||||
<td>(<jsp:getProperty name="nethelper" property="shareRateBits" />)
|
<td>(<jsp:getProperty name="nethelper" property="shareRateBits" />)
|
||||||
@ -121,6 +125,7 @@
|
|||||||
</p><p><b><%=intl._("UDP Configuration:")%></b><br>
|
</p><p><b><%=intl._("UDP Configuration:")%></b><br>
|
||||||
<%=intl._("UDP port:")%>
|
<%=intl._("UDP port:")%>
|
||||||
<input name ="udpPort" type="text" size="5" maxlength="5" value="<jsp:getProperty name="nethelper" property="configuredUdpPort" />" /><br>
|
<input name ="udpPort" type="text" size="5" maxlength="5" value="<jsp:getProperty name="nethelper" property="configuredUdpPort" />" /><br>
|
||||||
|
<% /********
|
||||||
<!-- let's keep this simple...
|
<!-- let's keep this simple...
|
||||||
<input type="checkbox" class="optbox" name="requireIntroductions" value="true" <jsp:getProperty name="nethelper" property="requireIntroductionsChecked" /> />
|
<input type="checkbox" class="optbox" name="requireIntroductions" value="true" <jsp:getProperty name="nethelper" property="requireIntroductionsChecked" /> />
|
||||||
Require SSU introductions
|
Require SSU introductions
|
||||||
@ -128,6 +133,7 @@
|
|||||||
</p><p>
|
</p><p>
|
||||||
Current External UDP address: <i><jsp:getProperty name="nethelper" property="udpAddress" /></i><br>
|
Current External UDP address: <i><jsp:getProperty name="nethelper" property="udpAddress" /></i><br>
|
||||||
-->
|
-->
|
||||||
|
*********/ %>
|
||||||
</p><p>
|
</p><p>
|
||||||
<b><%=intl._("TCP Configuration")%>:</b><br>
|
<b><%=intl._("TCP Configuration")%>:</b><br>
|
||||||
<%=intl._("Externally reachable hostname or IP address")%>:<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._("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.")%>
|
<%=intl._("Certain firewalls such as symmetric NATs may not work well with I2P.")%>
|
||||||
</p>
|
</p>
|
||||||
|
<% /********
|
||||||
<!-- let's keep this simple...
|
<!-- let's keep this simple...
|
||||||
<input type="submit" name="recheckReachability" value="Check network reachability..." />
|
<input type="submit" name="recheckReachability" value="Check network reachability..." />
|
||||||
</p>
|
</p>
|
||||||
-->
|
-->
|
||||||
|
*********/ %>
|
||||||
<p>
|
<p>
|
||||||
<%=intl._("UPnP is used to communicate with Internet Gateway Devices (IGDs) to detect the external IP address and forward ports.")%>
|
<%=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")%>:
|
<%=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>
|
<%=intl._("All changes require restart to take effect.")%></i>
|
||||||
</p><hr><div class="formaction">
|
</p><hr><div class="formaction">
|
||||||
<input type="submit" name="action" value="<%=intl._("Save Client Configuration")%>" />
|
<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).")%>
|
<%=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>
|
</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.")%>
|
<%=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 = "";
|
<% String peer = "";
|
||||||
if (request.getParameter("peer") != null)
|
if (request.getParameter("peer") != null)
|
||||||
peer = request.getParameter("peer");
|
peer = net.i2p.data.DataHelper.stripHTML(request.getParameter("peer")); // XSS
|
||||||
%>
|
%>
|
||||||
<div class="configure">
|
<div class="configure">
|
||||||
<form action="configpeer.jsp" method="POST">
|
<form action="configpeer.jsp" method="POST">
|
||||||
|
@ -3,5 +3,5 @@
|
|||||||
<meta http-equiv="pragma" content="no-cache" />
|
<meta http-equiv="pragma" content="no-cache" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<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>
|
</body></html>
|
||||||
|
@ -20,10 +20,10 @@
|
|||||||
<b>Encoding:</b> <%=System.getProperty("file.encoding")%></p>
|
<b>Encoding:</b> <%=System.getProperty("file.encoding")%></p>
|
||||||
<jsp:useBean class="net.i2p.router.web.LogsHelper" id="logsHelper" scope="request" />
|
<jsp:useBean class="net.i2p.router.web.LogsHelper" id="logsHelper" scope="request" />
|
||||||
<jsp:setProperty name="logsHelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
<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" />
|
<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" />
|
<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" />
|
<jsp:getProperty name="logsHelper" property="serviceLogs" />
|
||||||
</div><hr></div></body></html>
|
</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: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="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
|
||||||
<jsp:setProperty name="profilesHelper" property="writer" value="<%=out%>" />
|
<jsp:setProperty name="profilesHelper" property="writer" value="<%=out%>" />
|
||||||
|
<jsp:setProperty name="profilesHelper" property="full" value="<%=request.getParameter("f")%>" />
|
||||||
<jsp:getProperty name="profilesHelper" property="profileSummary" />
|
<jsp:getProperty name="profilesHelper" property="profileSummary" />
|
||||||
<a name="shitlist"> </a><h2><%=intl._("Banned Peers")%></h2>
|
<a name="shitlist"> </a><h2><%=intl._("Banned Peers")%></h2>
|
||||||
<jsp:getProperty name="profilesHelper" property="shitlistSummary" />
|
<jsp:getProperty name="profilesHelper" property="shitlistSummary" />
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// pass the new delay parameter to the iframe
|
// pass the new delay parameter to the iframe
|
||||||
newDelay = "?refresh=" + d;
|
newDelay = "?refresh=" + d;
|
||||||
if (!"0".equals(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">
|
<div class="routersummary">
|
||||||
<%@include file="summarynoframe.jsi" %>
|
<%@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);
|
+ _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;}
|
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 {
|
} else {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
//if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends
|
// _log.debug("Outbound window is full (" + _outboundPackets.size() + "/" + _activeResends
|
||||||
+ "), waiting indefinitely");
|
// + "), 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
|
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 {
|
} else {
|
||||||
@ -299,37 +299,48 @@ public class Connection {
|
|||||||
|
|
||||||
if ( (packet.getSequenceNum() == 0) && (!packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) ) {
|
if ( (packet.getSequenceNum() == 0) && (!packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) ) {
|
||||||
ackOnly = true;
|
ackOnly = true;
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
//if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("No resend for " + packet);
|
// _log.debug("No resend for " + packet);
|
||||||
} else {
|
} else {
|
||||||
int remaining = 0;
|
int windowSize;
|
||||||
|
int remaining;
|
||||||
synchronized (_outboundPackets) {
|
synchronized (_outboundPackets) {
|
||||||
_outboundPackets.put(new Long(packet.getSequenceNum()), packet);
|
_outboundPackets.put(new Long(packet.getSequenceNum()), packet);
|
||||||
remaining = _options.getWindowSize() - _outboundPackets.size() ;
|
windowSize = _options.getWindowSize();
|
||||||
|
remaining = windowSize - _outboundPackets.size() ;
|
||||||
_outboundPackets.notifyAll();
|
_outboundPackets.notifyAll();
|
||||||
}
|
}
|
||||||
if (remaining < 0)
|
// the other end has no idea what our window size is, so
|
||||||
remaining = 0;
|
// help him out by requesting acks below the 1/3 point,
|
||||||
if (packet.isFlagSet(Packet.FLAG_CLOSE) || (remaining < 2)) {
|
// 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.setOptionalDelay(0);
|
||||||
packet.setFlag(Packet.FLAG_DELAY_REQUESTED);
|
packet.setFlag(Packet.FLAG_DELAY_REQUESTED);
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Requesting no ack delay for packet " + packet);
|
_log.debug("Requesting no ack delay for packet " + packet);
|
||||||
} else {
|
} 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);
|
packet.setOptionalDelay(delay);
|
||||||
if (delay > 0)
|
if (delay > 0)
|
||||||
packet.setFlag(Packet.FLAG_DELAY_REQUESTED);
|
packet.setFlag(Packet.FLAG_DELAY_REQUESTED);
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Requesting ack delay of " + delay + "ms for packet " + packet);
|
_log.debug("Requesting ack delay of " + delay + "ms for packet " + packet);
|
||||||
}
|
}
|
||||||
|
// WHY always set?
|
||||||
packet.setFlag(Packet.FLAG_DELAY_REQUESTED);
|
packet.setFlag(Packet.FLAG_DELAY_REQUESTED);
|
||||||
|
|
||||||
long timeout = _options.getRTO();
|
long timeout = _options.getRTO();
|
||||||
if (timeout > MAX_RESEND_DELAY)
|
if (timeout > MAX_RESEND_DELAY)
|
||||||
timeout = MAX_RESEND_DELAY;
|
timeout = MAX_RESEND_DELAY;
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
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
|
// schedules itself
|
||||||
ResendPacketEvent rpe = new ResendPacketEvent(packet, timeout);
|
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[]) {
|
List ackPackets(long ackThrough, long nacks[]) {
|
||||||
if (ackThrough < _highestAckedThrough) {
|
if (ackThrough < _highestAckedThrough) {
|
||||||
// dupack which won't tell us anything
|
// 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.
|
* @return the next time the scheduler will want to send a packet, or -1 if never.
|
||||||
*/
|
*/
|
||||||
public long getNextSendTime() { return _nextSendTime; }
|
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) {
|
public void setNextSendTime(long when) {
|
||||||
if (_nextSendTime >= 0) {
|
if (_nextSendTime >= 0) {
|
||||||
if (when < _nextSendTime)
|
if (when < _nextSendTime)
|
||||||
@ -701,12 +724,12 @@ public class Connection {
|
|||||||
_nextSendTime = max;
|
_nextSendTime = max;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_log.shouldLog(Log.DEBUG) && false) {
|
//if (_log.shouldLog(Log.DEBUG) && false) {
|
||||||
if (_nextSendTime <= 0)
|
// if (_nextSendTime <= 0)
|
||||||
_log.debug("set next send time to an unknown time", new Exception(toString()));
|
// _log.debug("set next send time to an unknown time", new Exception(toString()));
|
||||||
else
|
// else
|
||||||
_log.debug("set next send time to " + (_nextSendTime-_context.clock().now()) + "ms from now", new Exception(toString()));
|
// _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?
|
/** how many packets have we sent and the other side has ACKed?
|
||||||
@ -839,8 +862,8 @@ public class Connection {
|
|||||||
}
|
}
|
||||||
long howLong = _options.getInactivityTimeout();
|
long howLong = _options.getInactivityTimeout();
|
||||||
howLong += _randomWait; // randomize it a bit, so both sides don't do it at once
|
howLong += _randomWait; // randomize it a bit, so both sides don't do it at once
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
//if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Resetting the inactivity timer to " + howLong, new Exception(toString()));
|
// _log.debug("Resetting the inactivity timer to " + howLong);
|
||||||
// this will get rescheduled, and rescheduled, and rescheduled...
|
// this will get rescheduled, and rescheduled, and rescheduled...
|
||||||
_activityTimer.reschedule(howLong, false); // use the later of current and previous timeout
|
_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
|
// we want to resend this packet, but there are already active
|
||||||
// resends in the air and we dont want to make a bad situation
|
// resends in the air and we dont want to make a bad situation
|
||||||
// worse. wait another second
|
// 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))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Delaying resend of " + _packet + " as there are "
|
_log.info("Delaying resend of " + _packet + " as there are "
|
||||||
+ _activeResends + " active resends already in play");
|
+ _activeResends + " active resends already in play");
|
||||||
@ -1108,6 +1133,7 @@ public class Connection {
|
|||||||
_packet.setOptionalDelay(choke);
|
_packet.setOptionalDelay(choke);
|
||||||
if (choke > 0)
|
if (choke > 0)
|
||||||
_packet.setFlag(Packet.FLAG_DELAY_REQUESTED);
|
_packet.setFlag(Packet.FLAG_DELAY_REQUESTED);
|
||||||
|
// this seems unnecessary to send the MSS again:
|
||||||
_packet.setOptionalMaxSize(getOptions().getMaxMessageSize());
|
_packet.setOptionalMaxSize(getOptions().getMaxMessageSize());
|
||||||
// bugfix release 0.7.8, we weren't dividing by 1000
|
// bugfix release 0.7.8, we weren't dividing by 1000
|
||||||
_packet.setResendDelay(getOptions().getResendDelay() / 1000);
|
_packet.setResendDelay(getOptions().getResendDelay() / 1000);
|
||||||
|
@ -166,6 +166,7 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
|||||||
packet.setReceiveStreamId(con.getReceiveStreamId());
|
packet.setReceiveStreamId(con.getReceiveStreamId());
|
||||||
|
|
||||||
con.getInputStream().updateAcks(packet);
|
con.getInputStream().updateAcks(packet);
|
||||||
|
// note that the optional delay is usually rewritten in Connection.sendPacket()
|
||||||
int choke = con.getOptions().getChoke();
|
int choke = con.getOptions().getChoke();
|
||||||
packet.setOptionalDelay(choke);
|
packet.setOptionalDelay(choke);
|
||||||
if (choke > 0)
|
if (choke > 0)
|
||||||
@ -197,12 +198,9 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
|
|||||||
( (size > 0) || (con.getUnackedPacketsSent() <= 0) || (packet.getSequenceNum() > 0) ) ) {
|
( (size > 0) || (con.getUnackedPacketsSent() <= 0) || (packet.getSequenceNum() > 0) ) ) {
|
||||||
packet.setFlag(Packet.FLAG_CLOSE);
|
packet.setFlag(Packet.FLAG_CLOSE);
|
||||||
con.setCloseSentOn(_context.clock().now());
|
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;
|
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_RESEND_DELAY = "i2p.streaming.initialResendDelay";
|
||||||
public static final String PROP_INITIAL_ACK_DELAY = "i2p.streaming.initialAckDelay";
|
public static final String PROP_INITIAL_ACK_DELAY = "i2p.streaming.initialAckDelay";
|
||||||
public static final String PROP_INITIAL_WINDOW_SIZE = "i2p.streaming.initialWindowSize";
|
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_INITIAL_RECEIVE_WINDOW = "i2p.streaming.initialReceiveWindow";
|
||||||
public static final String PROP_INACTIVITY_TIMEOUT = "i2p.streaming.inactivityTimeout";
|
public static final String PROP_INACTIVITY_TIMEOUT = "i2p.streaming.inactivityTimeout";
|
||||||
public static final String PROP_INACTIVITY_ACTION = "i2p.streaming.inactivityAction";
|
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 INITIAL_WINDOW_SIZE = 6;
|
||||||
static final int DEFAULT_MAX_SENDS = 8;
|
static final int DEFAULT_MAX_SENDS = 8;
|
||||||
public static final int DEFAULT_INITIAL_RTT = 8*1000;
|
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;
|
static final int MIN_WINDOW_SIZE = 1;
|
||||||
private static final boolean DEFAULT_ANSWER_PINGS = true;
|
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));
|
setRTT(getInt(opts, PROP_INITIAL_RTT, DEFAULT_INITIAL_RTT));
|
||||||
setReceiveWindow(getInt(opts, PROP_INITIAL_RECEIVE_WINDOW, 1));
|
setReceiveWindow(getInt(opts, PROP_INITIAL_RECEIVE_WINDOW, 1));
|
||||||
setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000));
|
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));
|
setWindowSize(getInt(opts, PROP_INITIAL_WINDOW_SIZE, INITIAL_WINDOW_SIZE));
|
||||||
setMaxResends(getInt(opts, PROP_MAX_RESENDS, DEFAULT_MAX_SENDS));
|
setMaxResends(getInt(opts, PROP_MAX_RESENDS, DEFAULT_MAX_SENDS));
|
||||||
setWriteTimeout(getInt(opts, PROP_WRITE_TIMEOUT, -1));
|
setWriteTimeout(getInt(opts, PROP_WRITE_TIMEOUT, -1));
|
||||||
@ -249,7 +251,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
|
|||||||
if (opts.containsKey(PROP_INITIAL_RESEND_DELAY))
|
if (opts.containsKey(PROP_INITIAL_RESEND_DELAY))
|
||||||
setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000));
|
setResendDelay(getInt(opts, PROP_INITIAL_RESEND_DELAY, 1000));
|
||||||
if (opts.containsKey(PROP_INITIAL_ACK_DELAY))
|
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))
|
if (opts.containsKey(PROP_INITIAL_WINDOW_SIZE))
|
||||||
setWindowSize(getInt(opts, PROP_INITIAL_WINDOW_SIZE, INITIAL_WINDOW_SIZE));
|
setWindowSize(getInt(opts, PROP_INITIAL_WINDOW_SIZE, INITIAL_WINDOW_SIZE));
|
||||||
if (opts.containsKey(PROP_MAX_RESENDS))
|
if (opts.containsKey(PROP_MAX_RESENDS))
|
||||||
@ -295,6 +297,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
|
|||||||
* @return if we want signatures on all packets.
|
* @return if we want signatures on all packets.
|
||||||
*/
|
*/
|
||||||
public boolean getRequireFullySigned() { return _fullySigned; }
|
public boolean getRequireFullySigned() { return _fullySigned; }
|
||||||
|
/** unused, see above */
|
||||||
public void setRequireFullySigned(boolean sign) { _fullySigned = sign; }
|
public void setRequireFullySigned(boolean sign) { _fullySigned = sign; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -325,7 +328,7 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** after how many consecutive messages should we ack?
|
/** 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.
|
* @return receive window size.
|
||||||
*/
|
*/
|
||||||
public int getReceiveWindow() { return _receiveWindow; }
|
public int getReceiveWindow() { return _receiveWindow; }
|
||||||
@ -405,6 +408,10 @@ public class ConnectionOptions extends I2PSocketOptionsImpl {
|
|||||||
* @return ACK delay in ms
|
* @return ACK delay in ms
|
||||||
*/
|
*/
|
||||||
public int getSendAckDelay() { return _sendAckDelay; }
|
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; }
|
public void setSendAckDelay(int delayMs) { _sendAckDelay = delayMs; }
|
||||||
|
|
||||||
/** What is the largest message we want to send or receive?
|
/** What is the largest message we want to send or receive?
|
||||||
|
@ -131,11 +131,14 @@ public class ConnectionPacketHandler {
|
|||||||
isNew = false;
|
isNew = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (packet.getSequenceNum() == 0) && (packet.getPayloadSize() > 0) ) {
|
//if ( (packet.getSequenceNum() == 0) && (packet.getPayloadSize() > 0) ) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
// if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("seq=0 && size=" + packet.getPayloadSize() + ": isNew? " + isNew
|
// _log.debug("seq=0 && size=" + packet.getPayloadSize() + ": isNew? " + isNew
|
||||||
+ " packet: " + packet + " con: " + con);
|
// + " 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
|
// 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))
|
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 (packet.isFlagSet(Packet.FLAG_DELAY_REQUESTED) && (packet.getOptionalDelay() <= 0) ) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Scheduling immediate ack for " + packet);
|
_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 {
|
} else {
|
||||||
int delay = con.getOptions().getSendAckDelay();
|
int delay = con.getOptions().getSendAckDelay();
|
||||||
if (packet.isFlagSet(Packet.FLAG_DELAY_REQUESTED)) // delayed ACK requested
|
if (packet.isFlagSet(Packet.FLAG_DELAY_REQUESTED)) // delayed ACK requested
|
||||||
@ -222,6 +227,10 @@ public class ConnectionPacketHandler {
|
|||||||
// con.fastRetransmit();
|
// 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) {
|
private boolean ack(Connection con, long ackThrough, long nacks[], Packet packet, boolean isNew, boolean choke) {
|
||||||
if (ackThrough < 0) return false;
|
if (ackThrough < 0) return false;
|
||||||
//if ( (nacks != null) && (nacks.length > 0) )
|
//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 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) {
|
private boolean adjustWindow(Connection con, boolean isNew, long sequenceNum, int numResends, int acked, boolean choke) {
|
||||||
boolean congested = false;
|
boolean congested = false;
|
||||||
if ( (!isNew) && (sequenceNum > 0) ) {
|
if ( (!isNew) && (sequenceNum > 0) ) {
|
||||||
|
@ -99,9 +99,9 @@ public class MessageInputStream extends InputStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
private long[] locked_getNacks() {
|
private long[] locked_getNacks() {
|
||||||
List ids = null;
|
List<Long> ids = null;
|
||||||
for (long i = _highestReadyBlockId + 1; i < _highestBlockId; i++) {
|
for (long i = _highestReadyBlockId + 1; i < _highestBlockId; i++) {
|
||||||
Long l = new Long(i);
|
Long l = Long.valueOf(i);
|
||||||
if (_notYetReadyBlocks.containsKey(l)) {
|
if (_notYetReadyBlocks.containsKey(l)) {
|
||||||
// ACK
|
// ACK
|
||||||
} else {
|
} else {
|
||||||
@ -113,7 +113,7 @@ public class MessageInputStream extends InputStream {
|
|||||||
if (ids != null) {
|
if (ids != null) {
|
||||||
long rv[] = new long[ids.size()];
|
long rv[] = new long[ids.size()];
|
||||||
for (int i = 0; i < rv.length; i++)
|
for (int i = 0; i < rv.length; i++)
|
||||||
rv[i] = ((Long)ids.get(i)).longValue();
|
rv[i] = ids.get(i).longValue();
|
||||||
return rv;
|
return rv;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
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"/>
|
<srcfiles dir= "." includes="jsp/*.jsp, WEB-INF/web-template.xml"/>
|
||||||
</uptodate>
|
</uptodate>
|
||||||
|
|
||||||
<target name="all" depends="compile,precompilejsp,war"/>
|
<target name="all" depends="compile,precompilejsp,bundle,war"/>
|
||||||
<target name="war">
|
<target name="war">
|
||||||
<war destfile="${project}.war" webxml="WEB-INF/web-out.xml">
|
<war destfile="${project}.war" webxml="WEB-INF/web-out.xml">
|
||||||
<fileset dir=".">
|
<fileset dir=".">
|
||||||
<include name="WEB-INF/**/*.class"/>
|
<include name="WEB-INF/**/*.class"/>
|
||||||
<include name="WEB-INF/lib/*.jar"/>
|
<include name="WEB-INF/lib/*.jar"/>
|
||||||
<include name="jsp/*.jsp"/>
|
|
||||||
<include name="images/*.png"/>
|
<include name="images/*.png"/>
|
||||||
<include name="css.css"/>
|
<include name="css.css"/>
|
||||||
<include name="index.html"/>
|
<include name="index.html"/>
|
||||||
<include name="WEB-INF/web-template.xml"/>
|
|
||||||
<include name="WEB-INF/web-out.xml"/>
|
<include name="WEB-INF/web-out.xml"/>
|
||||||
<include name="WEB-INF/classes/${project}.properties"/>
|
<include name="WEB-INF/classes/${project}.properties"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
</war>
|
</war>
|
||||||
</target>
|
</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">
|
<target name="clean">
|
||||||
<delete file="susidns.war" />
|
<delete file="susidns.war" />
|
||||||
<delete>
|
<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;
|
font-size: 10pt !important;
|
||||||
line-height: 160% !important;
|
line-height: 160% !important;
|
||||||
-moz-box-shadow: inset 0px 0px 1px 0px #002;
|
-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.LinkedList;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import net.i2p.data.DataHelper;
|
||||||
|
|
||||||
public class AddressbookBean
|
public class AddressbookBean
|
||||||
{
|
{
|
||||||
private String book, action, serial, lastSerial, filter, search, hostname, destination;
|
private String book, action, serial, lastSerial, filter, search, hostname, destination;
|
||||||
@ -140,7 +142,7 @@ public class AddressbookBean
|
|||||||
return book;
|
return book;
|
||||||
}
|
}
|
||||||
public void setBook(String book) {
|
public void setBook(String book) {
|
||||||
this.book = book;
|
this.book = DataHelper.stripHTML(book); // XSS
|
||||||
}
|
}
|
||||||
public String getSerial() {
|
public String getSerial() {
|
||||||
lastSerial = "" + Math.random();
|
lastSerial = "" + Math.random();
|
||||||
@ -192,20 +194,27 @@ public class AddressbookBean
|
|||||||
// addressbook.jsp catches the case where the whole book is empty.
|
// addressbook.jsp catches the case where the whole book is empty.
|
||||||
String filterArg = "";
|
String filterArg = "";
|
||||||
if( search != null && search.length() > 0 ) {
|
if( search != null && search.length() > 0 ) {
|
||||||
message = "Search ";
|
message = _("Search") + ' ';
|
||||||
}
|
}
|
||||||
if( filter != null && filter.length() > 0 ) {
|
if( filter != null && filter.length() > 0 ) {
|
||||||
if( search != null && search.length() > 0 )
|
if( search != null && search.length() > 0 )
|
||||||
message += "within ";
|
message = _("Search within filtered list") + ' ';
|
||||||
message += "Filtered list ";
|
else
|
||||||
|
message = _("Filtered list") + ' ';
|
||||||
filterArg = "&filter=" + filter;
|
filterArg = "&filter=" + filter;
|
||||||
}
|
}
|
||||||
if (entries.length == 0) {
|
if (entries.length == 0) {
|
||||||
message += "- no matches";
|
message += "- " + _("no matches") + '.';
|
||||||
} else if (getBeginInt() == 0 && getEndInt() == entries.length - 1) {
|
} else if (getBeginInt() == 0 && getEndInt() == entries.length - 1) {
|
||||||
if (message.length() == 0)
|
if (message.length() == 0)
|
||||||
message = "Addressbook ";
|
message = _("Addressbook") + ' ';
|
||||||
message += "contains " + entries.length + " entries";
|
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 {
|
} else {
|
||||||
if (getBeginInt() > 0) {
|
if (getBeginInt() > 0) {
|
||||||
int newBegin = Math.max(0, getBeginInt() - DISPLAY_SIZE);
|
int newBegin = Math.max(0, getBeginInt() - DISPLAY_SIZE);
|
||||||
@ -214,7 +223,7 @@ public class AddressbookBean
|
|||||||
"&begin=" + newBegin + "&end=" + newEnd + "\">" + newBegin +
|
"&begin=" + newBegin + "&end=" + newEnd + "\">" + newBegin +
|
||||||
'-' + newEnd + "</a> | ";
|
'-' + newEnd + "</a> | ";
|
||||||
}
|
}
|
||||||
message += "Showing " + getBegin() + '-' + getEnd() + " of " + entries.length;
|
message += _("Showing {0} of {1}", "" + getBegin() + '-' + getEnd(), entries.length);
|
||||||
if (getEndInt() < entries.length - 1) {
|
if (getEndInt() < entries.length - 1) {
|
||||||
int newBegin = Math.min(entries.length - 1, getEndInt() + 1);
|
int newBegin = Math.min(entries.length - 1, getEndInt() + 1);
|
||||||
int newEnd = Math.min(entries.length, getEndInt() + DISPLAY_SIZE);
|
int newEnd = Math.min(entries.length, getEndInt() + DISPLAY_SIZE);
|
||||||
@ -243,38 +252,43 @@ public class AddressbookBean
|
|||||||
if( action != null ) {
|
if( action != null ) {
|
||||||
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
||||||
boolean changed = false;
|
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 ) {
|
if( addressbook != null && hostname != null && destination != null ) {
|
||||||
addressbook.put( hostname, destination );
|
addressbook.put( hostname, destination );
|
||||||
changed = true;
|
changed = true;
|
||||||
message += "Destination added.<br/>";
|
message = _("Destination added.");
|
||||||
|
// clear search when adding
|
||||||
|
search = null;
|
||||||
}
|
}
|
||||||
}
|
} else if (action.equals(_("Delete"))) {
|
||||||
if( action.compareToIgnoreCase( "delete" ) == 0 ) {
|
|
||||||
Iterator it = deletionMarks.iterator();
|
Iterator it = deletionMarks.iterator();
|
||||||
int deleted = 0;
|
|
||||||
while( it.hasNext() ) {
|
while( it.hasNext() ) {
|
||||||
String name = (String)it.next();
|
name = (String)it.next();
|
||||||
addressbook.remove( name );
|
addressbook.remove( name );
|
||||||
changed = true;
|
changed = true;
|
||||||
deleted++;
|
deleted++;
|
||||||
}
|
}
|
||||||
if( changed ) {
|
if( changed ) {
|
||||||
message += "" + deleted + " destination(s) deleted.<br/>";
|
if (deleted == 1)
|
||||||
|
message = _("Destination {0} deleted.", name);
|
||||||
|
else
|
||||||
|
message = _("{0} destinations deleted.", deleted);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( changed ) {
|
if( changed ) {
|
||||||
try {
|
try {
|
||||||
save();
|
save();
|
||||||
message += "Addressbook saved.<br/>";
|
message += "<br>" + _("Addressbook saved.");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Debug.debug( e.getClass().getName() + ": " + e.getMessage() );
|
Debug.debug( e.getClass().getName() + ": " + e.getMessage() );
|
||||||
message += "ERROR: Could not write addressbook file.<br/>";
|
message += "<br>" + _("ERROR: Could not write addressbook file.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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;
|
return destination;
|
||||||
}
|
}
|
||||||
public void setDestination(String destination) {
|
public void setDestination(String destination) {
|
||||||
this.destination = destination;
|
this.destination = DataHelper.stripHTML(destination); // XSS
|
||||||
}
|
}
|
||||||
public String getHostname() {
|
public String getHostname() {
|
||||||
return hostname;
|
return hostname;
|
||||||
@ -338,7 +352,7 @@ public class AddressbookBean
|
|||||||
deletionMarks.addLast( name );
|
deletionMarks.addLast( name );
|
||||||
}
|
}
|
||||||
public void setHostname(String hostname) {
|
public void setHostname(String hostname) {
|
||||||
this.hostname = hostname;
|
this.hostname = DataHelper.stripHTML(hostname); // XSS
|
||||||
}
|
}
|
||||||
private int getBeginInt() {
|
private int getBeginInt() {
|
||||||
return Math.max(0, Math.min(entries.length - 1, beginIndex));
|
return Math.max(0, Math.min(entries.length - 1, beginIndex));
|
||||||
@ -362,4 +376,19 @@ public class AddressbookBean
|
|||||||
endIndex = Integer.parseInt(s);
|
endIndex = Integer.parseInt(s);
|
||||||
} catch (NumberFormatException nfe) {}
|
} 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 = "";
|
String message = "";
|
||||||
if( action != null ) {
|
if( action != null ) {
|
||||||
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
||||||
if( action.compareToIgnoreCase( "save") == 0 ) {
|
if(action.equals(_("Save"))) {
|
||||||
save();
|
save();
|
||||||
message = "Configuration saved.";
|
message = _("Configuration saved.");
|
||||||
}
|
} else if (action.equals(_("Reload"))) {
|
||||||
else if( action.compareToIgnoreCase( "reload") == 0 ) {
|
|
||||||
reload();
|
reload();
|
||||||
message = "Configuration reloaded.";
|
message = _("Configuration reloaded.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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 )
|
if( message.length() > 0 )
|
||||||
@ -162,4 +161,9 @@ public class ConfigBean implements Serializable {
|
|||||||
public void setSerial(String serial ) {
|
public void setSerial(String serial ) {
|
||||||
this.serial = 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 = "";
|
String message = "";
|
||||||
if( action != null ) {
|
if( action != null ) {
|
||||||
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) {
|
||||||
if( action.compareToIgnoreCase( "save") == 0 ) {
|
if (action.equals(_("Save"))) {
|
||||||
save();
|
save();
|
||||||
message = "Subscriptions saved.";
|
String nonce = System.getProperty("addressbook.nonce");
|
||||||
}
|
if (nonce != null) {
|
||||||
else if( action.compareToIgnoreCase( "reload") == 0 ) {
|
// 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();
|
reload();
|
||||||
message = "Subscriptions reloaded.";
|
message = _("Subscriptions reloaded.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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 )
|
if( message.length() > 0 )
|
||||||
@ -171,4 +182,9 @@ public class SubscriptionsBean
|
|||||||
|
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** translate */
|
||||||
|
private static String _(String s) {
|
||||||
|
return Messages.getString(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,18 @@
|
|||||||
*
|
*
|
||||||
* $Revision: 1.3 $
|
* $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"%>
|
<%@ page contentType="text/html"%>
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
<%@ 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="version" class="i2p.susi.dns.VersionBean" scope="application" />
|
||||||
<jsp:useBean id="book" class="i2p.susi.dns.AddressbookBean" scope="session" />
|
<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="*" />
|
||||||
<jsp:setProperty name="book" property="resetDeletionMarks" value="1"/>
|
<jsp:setProperty name="book" property="resetDeletionMarks" value="1"/>
|
||||||
<c:forEach items="${paramValues.checked}" var="checked">
|
<c:forEach items="${paramValues.checked}" var="checked">
|
||||||
@ -35,7 +42,8 @@
|
|||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<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">
|
<link rel="stylesheet" type="text/css" href="css.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -45,19 +53,20 @@
|
|||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div id="navi">
|
<div id="navi">
|
||||||
<p>addressbooks
|
<p>
|
||||||
<a href="addressbook.jsp?book=master&filter=none&begin=0&end=99">master</a> |
|
<%=intl._("addressbooks")%>
|
||||||
<a href="addressbook.jsp?book=router&filter=none&begin=0&end=99">router</a> |
|
<a href="addressbook.jsp?book=private&filter=none&begin=0&end=99"><%=intl._("private")%></a> |
|
||||||
<a href="addressbook.jsp?book=published&filter=none&begin=0&end=99">published</a> |
|
<a href="addressbook.jsp?book=master&filter=none&begin=0&end=99"><%=intl._("master")%></a> |
|
||||||
<a href="addressbook.jsp?book=private&filter=none&begin=0&end=99">private</a> *
|
<a href="addressbook.jsp?book=router&filter=none&begin=0&end=99"><%=intl._("router")%></a> |
|
||||||
<a href="subscriptions.jsp">subscriptions</a> *
|
<a href="addressbook.jsp?book=published&filter=none&begin=0&end=99"><%=intl._("published")%></a> *
|
||||||
<a href="config.jsp">configuration</a> *
|
<a href="subscriptions.jsp"><%=intl._("subscriptions")%></a> *
|
||||||
<a href="index.jsp">overview</a>
|
<a href="config.jsp"><%=intl._("configuration")%></a> *
|
||||||
|
<a href="index.jsp"><%=intl._("overview")%></a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div id="headline">
|
<div id="headline">
|
||||||
<h3>${book.book} addressbook at ${book.fileName}</h3>
|
<h3><%=intl._(book.getBook())%> <%=intl._("addressbook")%>: ${book.fileName}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="messages">${book.messages}</div>
|
<div id="messages">${book.messages}</div>
|
||||||
@ -66,7 +75,7 @@
|
|||||||
|
|
||||||
<c:if test="${book.notEmpty}">
|
<c:if test="${book.notEmpty}">
|
||||||
<div id="filter">
|
<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=a&begin=0&end=99">a</a>
|
||||||
<a href="addressbook.jsp?filter=b&begin=0&end=99">b</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>
|
<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=y&begin=0&end=99">y</a>
|
||||||
<a href="addressbook.jsp?filter=z&begin=0&end=99">z</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=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}">
|
<c:if test="${book.hasFilter}">
|
||||||
<p>Current filter: ${book.filter}
|
<p><%=intl._("Current filter")%>: ${book.filter}
|
||||||
(<a href="addressbook.jsp?filter=none&begin=0&end=99">clear filter</a>)</p>
|
(<a href="addressbook.jsp?filter=none&begin=0&end=99"><%=intl._("clear filter")%></a>)</p>
|
||||||
</c:if>
|
</c:if>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -106,8 +115,8 @@
|
|||||||
<input type="hidden" name="end" value="99">
|
<input type="hidden" name="end" value="99">
|
||||||
<div id="search">
|
<div id="search">
|
||||||
<table><tr>
|
<table><tr>
|
||||||
<td class="search">Search: <input type="text" name="search" value="${book.search}" size="20" ></td>
|
<td class="search"><%=intl._("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"><input type="submit" name="submitsearch" value="<%=intl._("Search")%>" ></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -131,17 +140,17 @@
|
|||||||
<th> </th>
|
<th> </th>
|
||||||
</c:if>
|
</c:if>
|
||||||
|
|
||||||
<th>Name</th>
|
<th><%=intl._("Name")%></th>
|
||||||
<th>Destination</th>
|
<th><%=intl._("Destination")%></th>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- limit iterator, or "Form too large" may result on submit, and is a huge web page if we don't -->
|
<!-- 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}">
|
<c:forEach items="${book.entries}" var="addr" begin="${book.begin}" end="${book.end}">
|
||||||
<tr class="list${book.trClass}">
|
<tr class="list${book.trClass}">
|
||||||
<c:if test="${book.master || book.router || book.published || book.private}">
|
<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>
|
</c:if>
|
||||||
<td class="names"><a href="http://${addr.name}/">${addr.name}</a> -
|
<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>
|
||||||
<td class="destinations"><textarea rows="1" style="height: 3em;" cols="40" wrap="off" readonly="readonly" name="dest_${addr.name}" >${addr.destination}</textarea></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>
|
</tr>
|
||||||
@ -151,7 +160,7 @@
|
|||||||
|
|
||||||
<c:if test="${book.master || book.router || book.published || book.private}">
|
<c:if test="${book.master || book.router || book.published || book.private}">
|
||||||
<div id="buttons">
|
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</c:if>
|
</c:if>
|
||||||
@ -160,17 +169,17 @@
|
|||||||
|
|
||||||
<c:if test="${book.isEmpty}">
|
<c:if test="${book.isEmpty}">
|
||||||
<div id="book">
|
<div id="book">
|
||||||
<p class="book">The ${book.book} addressbook is empty.</p>
|
<p class="book"><%=intl._("This addressbook is empty.")%></p>
|
||||||
</div>
|
</div>
|
||||||
</c:if>
|
</c:if>
|
||||||
|
|
||||||
<div id="add">
|
<div id="add">
|
||||||
<p class="add">
|
<p class="add">
|
||||||
<h3>Add new destination:</h3>
|
<h3><%=intl._("Add new destination")%>:</h3>
|
||||||
<b>Hostname:</b> <input type="text" name="hostname" value="${book.hostname}" size="20">
|
<b><%=intl._("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/>
|
<b><%=intl._("Destination")%>:</b> <textarea name="destination" rows="1" style="height: 3em;" cols="40" wrap="off" >${book.destination}</textarea><br/>
|
||||||
</p><p>
|
</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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -22,16 +22,24 @@
|
|||||||
*
|
*
|
||||||
* $Revision: 1.1 $
|
* $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" %>
|
<%@ page contentType="text/html" %>
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
<%@ 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="version" class="i2p.susi.dns.VersionBean" scope="application"/>
|
||||||
<jsp:useBean id="cfg" class="i2p.susi.dns.ConfigBean" scope="session"/>
|
<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="*" />
|
<jsp:setProperty name="cfg" property="*" />
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<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">
|
<link rel="stylesheet" type="text/css" href="css.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -41,14 +49,14 @@
|
|||||||
</div><hr>
|
</div><hr>
|
||||||
<div id="navi">
|
<div id="navi">
|
||||||
<p>
|
<p>
|
||||||
addressbooks
|
<%=intl._("addressbooks")%>
|
||||||
<a href="addressbook.jsp?book=master">master</a> |
|
<a href="addressbook.jsp?book=private"><%=intl._("private")%></a> |
|
||||||
<a href="addressbook.jsp?book=router">router</a> |
|
<a href="addressbook.jsp?book=master"><%=intl._("master")%></a> |
|
||||||
<a href="addressbook.jsp?book=published">published</a> |
|
<a href="addressbook.jsp?book=router"><%=intl._("router")%></a> |
|
||||||
<a href="addressbook.jsp?book=private">private</a> *
|
<a href="addressbook.jsp?book=published"><%=intl._("published")%></a> *
|
||||||
<a href="subscriptions.jsp">subscriptions</a> *
|
<a href="subscriptions.jsp"><%=intl._("subscriptions")%></a> *
|
||||||
configuration *
|
<%=intl._("configuration")%> *
|
||||||
<a href="index.jsp">overview</a>
|
<a href="index.jsp"><%=intl._("overview")%></a>
|
||||||
</p>
|
</p>
|
||||||
</div><hr>
|
</div><hr>
|
||||||
<div id="headline">
|
<div id="headline">
|
||||||
@ -61,35 +69,63 @@ configuration *
|
|||||||
<textarea name="config" rows="10" cols="80">${cfg.config}</textarea>
|
<textarea name="config" rows="10" cols="80">${cfg.config}</textarea>
|
||||||
</div>
|
</div>
|
||||||
<div id="buttons">
|
<div id="buttons">
|
||||||
<input type="image" src="images/save.png" name="action" value="save" alt="Save Config">
|
<input type="submit" name="action" value="<%=intl._("Save")%>" >
|
||||||
<input type="image" src="images/reload.png" name="action" value="reload" alt="Reload Config">
|
<input type="submit" name="action" value="<%=intl._("Reload")%>" >
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div id="help">
|
<div id="help">
|
||||||
<h3>Hints</h3>
|
<h3><%=intl._("Hints")%></h3>
|
||||||
<ol>
|
<ol>
|
||||||
<li>All file or directory paths here are relative to the addressbook's working directory, which normally
|
<li>
|
||||||
is located at $I2P/addressbook/.</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>If you want to manually add lines to an addressbook, add them to the private or master addressbooks. The router
|
</li>
|
||||||
addressbook and the published addressbook are overwritten by the addressbook application.</li>
|
<li>
|
||||||
<li><b>Important:</b>When you publish your addressbook, <b>ALL</b> destinations from the master and router addressbooks appear there.
|
<%=intl._("If you want to manually add lines to an addressbook, add them to the private or master addressbooks.")%>
|
||||||
Use the private addressbook for private destinations, these are not published.
|
<%=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>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<h3>Options</h3>
|
<h3><%=intl._("Options")%></h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><b>subscriptions</b> - file containing the list of subscriptions URLs (no need to change)</li>
|
<li><b>subscriptions</b> -
|
||||||
<li><b>update_delay</b> - update interval in hours (no need to change)</li>
|
<%=intl._("File containing the list of subscriptions URLs (no need to change)")%>
|
||||||
<li><b>published_addressbook</b> - your public hosts.txt file (choose a path within your webserver document root)</li>
|
</li>
|
||||||
<li><b>router_addressbook</b> - your hosts.txt (don't change)</li>
|
<li><b>update_delay</b> -
|
||||||
<li><b>master_addressbook</b> - your personal addressbook, it never gets overwritten by the addressbook (don't change)</li>
|
<%=intl._("Update interval in hours")%>
|
||||||
<li><b>private_addressbook</b> - your private addressbook, it is never published (defaults to ../privatehosts.txt, don't change)</li>
|
</li>
|
||||||
<li><b>proxy_port</b> - http port for your eepProxy (no need to change)</li>
|
<li><b>published_addressbook</b> -
|
||||||
<li><b>proxy_host</b> - hostname for your eepProxy (no need to change)</li>
|
<%=intl._("Your public hosts.txt file (choose a path within your webserver document root)")%>
|
||||||
<li><b>should_publish</b> - true/false whether to write the published addressbook</li>
|
</li>
|
||||||
<li><b>etags</b> - file containing the etags header from the fetched subscription URLs (no need to change)</li>
|
<li><b>router_addressbook</b> -
|
||||||
<li><b>last_modified</b> - file containing the modification timestamp for each fetched subscription URL (no need to change)</li>
|
<%=intl._("Your hosts.txt (don't change)")%>
|
||||||
<li><b>log</b> - file to log activity to (change to /dev/null if you like)</li>
|
</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>
|
</ul>
|
||||||
</div><hr>
|
</div><hr>
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
|
@ -22,14 +22,22 @@
|
|||||||
*
|
*
|
||||||
* $Revision: 1.2 $
|
* $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"%>
|
<%@ page contentType="text/html"%>
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
<%@ 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="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">
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<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">
|
<link rel="stylesheet" type="text/css" href="css.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -39,40 +47,40 @@
|
|||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div id="navi">
|
<div id="navi">
|
||||||
<p>addressbooks
|
<p>
|
||||||
<a href="addressbook.jsp?book=master">master</a> |
|
<%=intl._("addressbooks")%>
|
||||||
<a href="addressbook.jsp?book=router">router</a> |
|
<a href="addressbook.jsp?book=private"><%=intl._("private")%></a> |
|
||||||
<a href="addressbook.jsp?book=published">published</a> |
|
<a href="addressbook.jsp?book=master"><%=intl._("master")%></a> |
|
||||||
<a href="addressbook.jsp?book=private">private</a> *
|
<a href="addressbook.jsp?book=router"><%=intl._("router")%></a> |
|
||||||
<a href="subscriptions.jsp">subscriptions</a> *
|
<a href="addressbook.jsp?book=published"><%=intl._("published")%></a> *
|
||||||
<a href="config.jsp">configuration</a> *
|
<a href="subscriptions.jsp"><%=intl._("subscriptions")%></a> *
|
||||||
overview
|
<a href="config.jsp"><%=intl._("configuration")%></a> *
|
||||||
|
<%=intl._("overview")%>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<h3>Huh? what addressbook?</h3>
|
<h3><%=intl._("What is the addressbook?")%></h3>
|
||||||
<p>
|
<p>
|
||||||
The addressbook application is part of your i2p installation. It regularly updates your hosts.txt file
|
<%=intl._("The addressbook application is part of your i2p installation.")%>
|
||||||
from distributed sources. It keeps your hosts.txt up to date, so it can automatically add
|
<%=intl._("It regularly updates your hosts.txt file from distributed sources or \"subscriptions\".")%>
|
||||||
eepsites announced on other sites if you subscribe to those sites' addressbooks.
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
(To speak the truth: In its default configuration the addressbook does not poll
|
<%=intl._("In the default configuration, the addressbook is only subscribed to www.i2p2.i2p.")%>
|
||||||
additional sites, but www.i2p2.i2p only. Subscribing to additional sites is an easy task,
|
<%=intl._("Subscribing to additional sites is easy, just add them to your <a href=\"subscriptions.jsp\">subscriptions</a> file.")%>
|
||||||
just add them to your <a href="subscriptions.jsp">subscriptions</a> file.)
|
|
||||||
</p>
|
</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>
|
<p>
|
||||||
from duck in the forum and <a href="http://www.i2p2.i2p/naming.html">additional information on www.i2p2.i2p</a>.</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>.")%>
|
||||||
<h3>How does the addressbook work?</h3>
|
</p>
|
||||||
<p>The addressbook application regularly (normally once per hour) polls your subscriptions and merges their content
|
<h3><%=intl._("How does the addressbook work?")%></h3>
|
||||||
into your so-called router addressbook (normally your plain hosts.txt). Then it merges your so-called master addressbook (normally
|
<p>
|
||||||
your userhosts.txt) into the router addressbook as well. If configured, the router addressbook is now written to the published addressbook,
|
<%=intl._("The addressbook application regularly polls your subscriptions and merges their content into your \"router\" addressbook, stored in the hosts.txt file.")%>
|
||||||
which is a publicly available copy of your hosts.txt somewhere in your eepsite's document root.
|
<%=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>
|
</p><p>
|
||||||
The router also uses a private addressbook (privatehosts.txt, not shown in the picture), which is not merged or published.
|
<%=intl._("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.
|
<%=intl._("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 private addressbook can also be used for aliases of hosts in your other addressbooks.")%>
|
||||||
</p>
|
</p>
|
||||||
<p><center><img src="images/how.png" border="0" alt="addressbook working scheme" title="How the addressbook works" class="illustrate" /></center></p>
|
<p><center><img src="images/how.png" border="0" alt="addressbook working scheme" title="How the addressbook works" class="illustrate" /></center></p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,16 +22,24 @@
|
|||||||
*
|
*
|
||||||
* $Revision: 1.2 $
|
* $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"%>
|
<%@ page contentType="text/html"%>
|
||||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
|
<%@ 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="version" class="i2p.susi.dns.VersionBean" scope="application" />
|
||||||
<jsp:useBean id="subs" class="i2p.susi.dns.SubscriptionsBean" scope="session" />
|
<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="*" />
|
<jsp:setProperty name="subs" property="*" />
|
||||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<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">
|
<link rel="stylesheet" type="text/css" href="css.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -40,14 +48,15 @@
|
|||||||
<img src="images/logo.png" alt="susidns logo" border="0"/>
|
<img src="images/logo.png" alt="susidns logo" border="0"/>
|
||||||
</div><hr>
|
</div><hr>
|
||||||
<div id="navi">
|
<div id="navi">
|
||||||
<p>addressbooks
|
<p>
|
||||||
<a href="addressbook.jsp?book=master">master</a> |
|
<%=intl._("addressbooks")%>
|
||||||
<a href="addressbook.jsp?book=router">router</a> |
|
<a href="addressbook.jsp?book=private"><%=intl._("private")%></a> |
|
||||||
<a href="addressbook.jsp?book=published">published</a> |
|
<a href="addressbook.jsp?book=master"><%=intl._("master")%></a> |
|
||||||
<a href="addressbook.jsp?book=private">private</a> *
|
<a href="addressbook.jsp?book=router"><%=intl._("router")%></a> |
|
||||||
subscriptions *
|
<a href="addressbook.jsp?book=published"><%=intl._("published")%></a> *
|
||||||
<a href="config.jsp">configuration</a> *
|
<%=intl._("subscriptions")%> *
|
||||||
<a href="index.jsp">overview</a>
|
<a href="config.jsp"><%=intl._("configuration")%></a> *
|
||||||
|
<a href="index.jsp"><%=intl._("overview")%></a>
|
||||||
</p>
|
</p>
|
||||||
</div><hr>
|
</div><hr>
|
||||||
<div id="headline">
|
<div id="headline">
|
||||||
@ -60,18 +69,18 @@ subscriptions *
|
|||||||
<textarea name="content" rows="10" cols="80">${subs.content}</textarea>
|
<textarea name="content" rows="10" cols="80">${subs.content}</textarea>
|
||||||
</div>
|
</div>
|
||||||
<div id="buttons">
|
<div id="buttons">
|
||||||
<input type="image" src="images/save.png" name="action" value="save" alt="Save Subscriptions" >
|
<input type="submit" name="action" value="<%=intl._("Save")%>" >
|
||||||
<input type="image" src="images/reload.png" name="action" value="reload" alt="Reload Subscriptions" >
|
<input type="submit" name="action" value="<%=intl._("Reload")%>" >
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div id="help">
|
<div id="help">
|
||||||
<h3>Explanation</h3>
|
|
||||||
<p class="help">
|
<p class="help">
|
||||||
The subscription file contains a list of (i2p) URLs. The addressbook application
|
<%=intl._("The subscription file contains a list of i2p URLs.")%>
|
||||||
regularly (once per hour) checks this list for new eepsites. Those URLs simply contain the published hosts.txt
|
<%=intl._("The addressbook application regularly checks this list for new eepsites.")%>
|
||||||
file of other people. The default subscription is the hosts.txt from www.i2p2.i2p, which is updated infrequently.
|
<%=intl._("Those URLs refer to published hosts.txt files.")%>
|
||||||
So it is a good idea to add additional subscriptions to sites that have the latest addresses.
|
<%=intl._("The default subscription is the hosts.txt from www.i2p2.i2p, which is updated infrequently.")%>
|
||||||
<a href="http://www.i2p2.i2p/faq.html#subscriptions">See the FAQ for a list of subscription URLs.</a>
|
<%=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>
|
</p>
|
||||||
</div><hr>
|
</div><hr>
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
|
26
build.xml
26
build.xml
@ -141,6 +141,9 @@
|
|||||||
</target>
|
</target>
|
||||||
<target name="poupdate">
|
<target name="poupdate">
|
||||||
<ant dir="apps/routerconsole/java/" target="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>
|
||||||
<target name="javadoc">
|
<target name="javadoc">
|
||||||
<mkdir dir="./build" />
|
<mkdir dir="./build" />
|
||||||
@ -205,6 +208,7 @@
|
|||||||
<ant dir="apps/susidns/src/" target="distclean" />
|
<ant dir="apps/susidns/src/" target="distclean" />
|
||||||
<ant dir="apps/systray/java/" target="distclean" />
|
<ant dir="apps/systray/java/" target="distclean" />
|
||||||
<ant dir="apps/i2psnark/java/" target="distclean" />
|
<ant dir="apps/i2psnark/java/" target="distclean" />
|
||||||
|
<ant dir="apps/jetty/" target="distclean" />
|
||||||
<delete>
|
<delete>
|
||||||
<fileset dir="." includes="**/*.class" />
|
<fileset dir="." includes="**/*.class" />
|
||||||
<fileset dir="." includes="**/*.java~" />
|
<fileset dir="." includes="**/*.java~" />
|
||||||
@ -285,9 +289,10 @@
|
|||||||
<copy todir="pkg-temp/lib/wrapper/win32/">
|
<copy todir="pkg-temp/lib/wrapper/win32/">
|
||||||
<fileset dir="installer/lib/wrapper/win32/" />
|
<fileset dir="installer/lib/wrapper/win32/" />
|
||||||
</copy>
|
</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="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" />
|
<mkdir dir="pkg-temp/scripts" />
|
||||||
<copy file="apps/proxyscript/i2pProxy.pac" todir="pkg-temp/scripts/" />
|
<copy file="apps/proxyscript/i2pProxy.pac" todir="pkg-temp/scripts/" />
|
||||||
<!-- test classes aren't in the jars anymore
|
<!-- test classes aren't in the jars anymore
|
||||||
@ -343,19 +348,19 @@
|
|||||||
</copy>
|
</copy>
|
||||||
<!-- make a "classic" theme -->
|
<!-- make a "classic" theme -->
|
||||||
<copy todir="pkg-temp/docs/themes/console/classic/" >
|
<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>
|
</copy>
|
||||||
<!-- Add dark theme -->
|
<!-- Add dark theme -->
|
||||||
<copy todir="pkg-temp/docs/themes/console/dark/" >
|
<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>
|
</copy>
|
||||||
<!-- Add light theme -->
|
<!-- Add light theme -->
|
||||||
<copy todir="pkg-temp/docs/themes/console/light/" >
|
<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>
|
</copy>
|
||||||
<!-- Add midnight theme -->
|
<!-- Add midnight theme -->
|
||||||
<copy todir="pkg-temp/docs/themes/console/midnight/" >
|
<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>
|
</copy>
|
||||||
<!-- Add shared images.. these are subject to flux and change! -->
|
<!-- Add shared images.. these are subject to flux and change! -->
|
||||||
<copy todir="pkg-temp/docs/themes/console/images/" >
|
<copy todir="pkg-temp/docs/themes/console/images/" >
|
||||||
@ -409,6 +414,15 @@
|
|||||||
<copy file="build/susidns.war" todir="pkg-temp/webapps/" />
|
<copy file="build/susidns.war" todir="pkg-temp/webapps/" />
|
||||||
<copy file="build/i2psnark.war" todir="pkg-temp/webapps/" />
|
<copy file="build/i2psnark.war" todir="pkg-temp/webapps/" />
|
||||||
<copy file="history.txt" todir="pkg-temp/" />
|
<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 -->
|
<!-- may be pointless now, people with split directories will never see this -->
|
||||||
<copy file="installer/resources/news.xml" todir="pkg-temp/docs/" />
|
<copy file="installer/resources/news.xml" todir="pkg-temp/docs/" />
|
||||||
</target>
|
</target>
|
||||||
|
@ -16,7 +16,7 @@ package net.i2p;
|
|||||||
public class CoreVersion {
|
public class CoreVersion {
|
||||||
/** deprecated */
|
/** deprecated */
|
||||||
public final static String ID = "Monotone";
|
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[]) {
|
public static void main(String args[]) {
|
||||||
System.out.println("I2P Core version: " + VERSION);
|
System.out.println("I2P Core version: " + VERSION);
|
||||||
|
@ -432,12 +432,14 @@ public class I2PAppContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @deprecated unused */
|
||||||
public PetNameDB petnameDb() {
|
public PetNameDB petnameDb() {
|
||||||
if (!_petnameDbInitialized)
|
if (!_petnameDbInitialized)
|
||||||
initializePetnameDb();
|
initializePetnameDb();
|
||||||
return _petnameDb;
|
return _petnameDb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @deprecated unused */
|
||||||
private void initializePetnameDb() {
|
private void initializePetnameDb() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
if (_petnameDb == null) {
|
if (_petnameDb == null) {
|
||||||
@ -720,4 +722,11 @@ public class I2PAppContext {
|
|||||||
return new HashSet(_shutdownTasks);
|
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