* i2psnark:

- Move private tracker config from create box to torrent config
   - Refactor private and open tracker configuration
   - Add private indication on details page
This commit is contained in:
zzz
2012-06-08 16:11:55 +00:00
parent b304393bc3
commit 59df524a91
5 changed files with 142 additions and 62 deletions

View File

@ -3,6 +3,7 @@ package org.klomp.snark;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@ -64,7 +65,7 @@ public class I2PSnarkUtil {
private int _startupDelay; private int _startupDelay;
private boolean _shouldUseOT; private boolean _shouldUseOT;
private boolean _areFilesPublic; private boolean _areFilesPublic;
private String _openTrackerString; private List<String> _openTrackers;
private DHT _dht; private DHT _dht;
public static final int DEFAULT_STARTUP_DELAY = 3; public static final int DEFAULT_STARTUP_DELAY = 3;
@ -88,6 +89,8 @@ public class I2PSnarkUtil {
_maxConnections = MAX_CONNECTIONS; _maxConnections = MAX_CONNECTIONS;
_startupDelay = DEFAULT_STARTUP_DELAY; _startupDelay = DEFAULT_STARTUP_DELAY;
_shouldUseOT = DEFAULT_USE_OPENTRACKERS; _shouldUseOT = DEFAULT_USE_OPENTRACKERS;
// FIXME split if default has more than one
_openTrackers = Collections.singletonList(DEFAULT_OPENTRACKERS);
// This is used for both announce replies and .torrent file downloads, // This is used for both announce replies and .torrent file downloads,
// so it must be available even if not connected to I2CP. // so it must be available even if not connected to I2CP.
// so much for multiple instances // so much for multiple instances
@ -453,34 +456,17 @@ public class I2PSnarkUtil {
} }
/** @param ot non-null */ /** @param ot non-null */
public void setOpenTrackerString(String ot) { public void setOpenTrackers(List<String> ot) {
_openTrackerString = ot; _openTrackers = ot;
}
/** Comma delimited list of open trackers to use as backups
* non-null but possibly empty
*/
public String getOpenTrackerString() {
if (_openTrackerString == null)
return DEFAULT_OPENTRACKERS;
return _openTrackerString;
} }
/** List of open trackers to use as backups /** List of open trackers to use as backups
* Null if disabled * @return non-null, possibly unmodifiable, empty if disabled
*/ */
public List<String> getOpenTrackers() { public List<String> getOpenTrackers() {
if (!shouldUseOpenTrackers()) if (!shouldUseOpenTrackers())
return null; return Collections.EMPTY_LIST;
List<String> rv = new ArrayList(1); return _openTrackers;
String trackers = getOpenTrackerString();
StringTokenizer tok = new StringTokenizer(trackers, ", ");
while (tok.hasMoreTokens())
rv.add(tok.nextToken());
if (rv.isEmpty())
return null;
return rv;
} }
public void setUseOpenTrackers(boolean yes) { public void setUseOpenTrackers(boolean yes) {

View File

@ -8,6 +8,7 @@ import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -85,6 +86,7 @@ public class SnarkManager implements Snark.CompleteListener {
public static final String DEFAULT_THEME = "ubergine"; public static final String DEFAULT_THEME = "ubergine";
private static final String PROP_USE_OPENTRACKERS = "i2psnark.useOpentrackers"; private static final String PROP_USE_OPENTRACKERS = "i2psnark.useOpentrackers";
public static final String PROP_OPENTRACKERS = "i2psnark.opentrackers"; public static final String PROP_OPENTRACKERS = "i2psnark.opentrackers";
public static final String PROP_PRIVATETRACKERS = "i2psnark.privatetrackers";
public static final int MIN_UP_BW = 2; public static final int MIN_UP_BW = 2;
public static final int DEFAULT_MAX_UP_BW = 10; public static final int DEFAULT_MAX_UP_BW = 10;
@ -343,7 +345,7 @@ public class SnarkManager implements Snark.CompleteListener {
_util.setFilesPublic(areFilesPublic()); _util.setFilesPublic(areFilesPublic());
String ot = _config.getProperty(PROP_OPENTRACKERS); String ot = _config.getProperty(PROP_OPENTRACKERS);
if (ot != null) if (ot != null)
_util.setOpenTrackerString(ot); _util.setOpenTrackers(getOpenTrackers());
String useOT = _config.getProperty(PROP_USE_OPENTRACKERS); String useOT = _config.getProperty(PROP_USE_OPENTRACKERS);
boolean bOT = useOT == null || Boolean.valueOf(useOT).booleanValue(); boolean bOT = useOT == null || Boolean.valueOf(useOT).booleanValue();
_util.setUseOpenTrackers(bOT); _util.setUseOpenTrackers(bOT);
@ -563,20 +565,84 @@ public class SnarkManager implements Snark.CompleteListener {
} }
} }
/**
* Others should use the version in I2PSnarkUtil
* @return non-null, empty if disabled
* @since 0.9.1
*/
private List<String> getOpenTrackers() {
if (!_util.shouldUseOpenTrackers())
return Collections.EMPTY_LIST;
return getListConfig(PROP_OPENTRACKERS, I2PSnarkUtil.DEFAULT_OPENTRACKERS);
}
/**
* @return non-null, fixed size, may be empty or unmodifiable
* @since 0.9.1
*/
public List<String> getPrivateTrackers() {
return getListConfig(PROP_PRIVATETRACKERS, null);
}
/** /**
* @param ot null to restore default * @param ot null to restore default
* @since 0.9.1 * @since 0.9.1
*/ */
public void saveOpenTrackers(String ot) { public void saveOpenTrackers(List<String> ot) {
_util.setOpenTrackerString(ot); String val = setListConfig(PROP_OPENTRACKERS, ot);
if (ot != null) if (ot == null)
_config.setProperty(PROP_OPENTRACKERS, ot); ot = Collections.singletonList(I2PSnarkUtil.DEFAULT_OPENTRACKERS);
else _util.setOpenTrackers(ot);
_config.remove(PROP_OPENTRACKERS);
addMessage(_("Open Tracker list changed - torrent restart required to take effect.")); addMessage(_("Open Tracker list changed - torrent restart required to take effect."));
saveConfig(); saveConfig();
} }
/**
* @param ot null ok, default is none
* @since 0.9.1
*/
public void savePrivateTrackers(List<String> pt) {
setListConfig(PROP_PRIVATETRACKERS, pt);
addMessage(_("Private tracker list changed - affects newly created torrents only."));
saveConfig();
}
/**
* @param dflt default or null
* @return non-null, fixed size
* @since 0.9.1
*/
private List<String> getListConfig(String prop, String dflt) {
String val = _config.getProperty(prop);
if (val == null)
val = dflt;
if (val == null)
return Collections.EMPTY_LIST;
return Arrays.asList(val.split(","));
}
/**
* Sets the config, does NOT save it
* @param values may be null or empty
* @return the comma-separated config string, non-null
* @since 0.9.1
*/
private String setListConfig(String prop, List<String> values) {
if (values == null || values.isEmpty()) {
_config.remove(prop);
return "";
}
StringBuilder buf = new StringBuilder(64);
for (String s : values) {
if (buf.length() > 0)
buf.append(',');
buf.append(s);
}
String rv = buf.toString();
_config.setProperty(prop, rv);
return rv;
}
public void saveConfig() { public void saveConfig() {
try { try {
synchronized (_configFile) { synchronized (_configFile) {
@ -1449,7 +1515,7 @@ public class SnarkManager implements Snark.CompleteListener {
String url = toks[i+1].trim().replace("&#44;", ","); String url = toks[i+1].trim().replace("&#44;", ",");
if ( (name.length() > 0) && (url.length() > 0) ) { if ( (name.length() > 0) && (url.length() > 0) ) {
String urls[] = url.split("=", 2); String urls[] = url.split("=", 2);
String url2 = urls.length > 1 ? urls[1] : null; String url2 = urls.length > 1 ? urls[1] : "";
_trackerMap.put(name, new Tracker(name, urls[0], url2)); _trackerMap.put(name, new Tracker(name, urls[0], url2));
} }
} }

View File

@ -721,7 +721,8 @@ public class I2PSnarkServlet extends DefaultServlet {
try { try {
// This may take a long time to check the storage, but since it already exists, // This may take a long time to check the storage, but since it already exists,
// it shouldn't be THAT bad, so keep it in this thread. // it shouldn't be THAT bad, so keep it in this thread.
Storage s = new Storage(_manager.util(), baseFile, announceURL, req.getParameter("private") != null, null); boolean isPrivate = _manager.getPrivateTrackers().contains(announceURL);
Storage s = new Storage(_manager.util(), baseFile, announceURL, isPrivate, null);
s.close(); // close the files... maybe need a way to pass this Storage to addTorrent rather than starting over s.close(); // close the files... maybe need a way to pass this Storage to addTorrent rather than starting over
MetaInfo info = s.getMetaInfo(); MetaInfo info = s.getMetaInfo();
File torrentFile = new File(_manager.getDataDir(), s.getBaseName() + ".torrent"); File torrentFile = new File(_manager.getDataDir(), s.getBaseName() + ".torrent");
@ -729,7 +730,7 @@ public class I2PSnarkServlet extends DefaultServlet {
// now add it, but don't automatically start it // now add it, but don't automatically start it
_manager.addTorrent(info, s.getBitField(), torrentFile.getAbsolutePath(), true); _manager.addTorrent(info, s.getBitField(), torrentFile.getAbsolutePath(), true);
_manager.addMessage(_("Torrent created for \"{0}\"", baseFile.getName()) + ": " + torrentFile.getAbsolutePath()); _manager.addMessage(_("Torrent created for \"{0}\"", baseFile.getName()) + ": " + torrentFile.getAbsolutePath());
if (announceURL != null) if (announceURL != null && !_manager.util().getOpenTrackers().contains(announceURL))
_manager.addMessage(_("Many I2P trackers require you to register new torrents before seeding - please do so before starting \"{0}\"", 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 \"{0}\"", baseFile.getAbsolutePath()) + ": " + ioe.getMessage()); _manager.addMessage(_("Error creating a torrent for \"{0}\"", baseFile.getAbsolutePath()) + ": " + ioe.getMessage());
@ -771,11 +772,12 @@ public class I2PSnarkServlet extends DefaultServlet {
/** @since 0.9 */ /** @since 0.9 */
private void processTrackerForm(String action, HttpServletRequest req) { private void processTrackerForm(String action, HttpServletRequest req) {
if (action.equals(_("Delete selected")) || action.equals(_("Change open trackers"))) { if (action.equals(_("Delete selected")) || action.equals(_("Save tracker configuration"))) {
boolean changed = false; boolean changed = false;
Map<String, Tracker> trackers = _manager.getTrackerMap(); Map<String, Tracker> trackers = _manager.getTrackerMap();
List<String> removed = new ArrayList(); List<String> removed = new ArrayList();
List<String> open = new ArrayList(); List<String> open = new ArrayList();
List<String> priv = new ArrayList();
Enumeration e = req.getParameterNames(); Enumeration e = req.getParameterNames();
while (e.hasMoreElements()) { while (e.hasMoreElements()) {
Object o = e.nextElement(); Object o = e.nextElement();
@ -792,22 +794,30 @@ public class I2PSnarkServlet extends DefaultServlet {
} }
} else if (k.startsWith("open_")) { } else if (k.startsWith("open_")) {
open.add(k.substring(5)); open.add(k.substring(5));
} else if (k.startsWith("private_")) {
priv.add(k.substring(8));
} }
} }
if (changed) { if (changed) {
_manager.saveTrackerMap(); _manager.saveTrackerMap();
} }
open.removeAll(removed); open.removeAll(removed);
StringBuilder openBuf = new StringBuilder(128); List<String> oldOpen = new ArrayList(_manager.util().getOpenTrackers());
for (String s : open) { Collections.sort(oldOpen);
if (openBuf.length() > 0) Collections.sort(open);
openBuf.append(','); if (!open.equals(oldOpen))
openBuf.append(s); _manager.saveOpenTrackers(open);
}
String newOpen = openBuf.toString(); priv.removeAll(removed);
if (!newOpen.equals(_manager.util().getOpenTrackerString())) { // open trumps private
_manager.saveOpenTrackers(newOpen); priv.removeAll(open);
} List<String> oldPriv = new ArrayList(_manager.getPrivateTrackers());
Collections.sort(oldPriv);
Collections.sort(priv);
if (!priv.equals(oldPriv))
_manager.savePrivateTrackers(priv);
} else if (action.equals(_("Add tracker"))) { } else if (action.equals(_("Add tracker"))) {
String name = req.getParameter("tname"); String name = req.getParameter("tname");
String hurl = req.getParameter("thurl"); String hurl = req.getParameter("thurl");
@ -820,10 +830,15 @@ public class I2PSnarkServlet extends DefaultServlet {
Map<String, Tracker> trackers = _manager.getTrackerMap(); Map<String, Tracker> trackers = _manager.getTrackerMap();
trackers.put(name, new Tracker(name, aurl, hurl)); trackers.put(name, new Tracker(name, aurl, hurl));
_manager.saveTrackerMap(); _manager.saveTrackerMap();
// open trumps private
if (req.getParameter("_add_open_") != null) { if (req.getParameter("_add_open_") != null) {
String oldOpen = _manager.util().getOpenTrackerString(); List newOpen = new ArrayList(_manager.util().getOpenTrackers());
String newOpen = oldOpen.length() <= 0 ? aurl : oldOpen + ',' + aurl; newOpen.add(aurl);
_manager.saveOpenTrackers(newOpen); _manager.saveOpenTrackers(newOpen);
} else if (req.getParameter("_add_private_") != null) {
List newPriv = new ArrayList(_manager.getPrivateTrackers());
newPriv.add(aurl);
_manager.savePrivateTrackers(newPriv);
} }
} else { } else {
_manager.addMessage(_("Enter valid tracker name and URLs")); _manager.addMessage(_("Enter valid tracker name and URLs"));
@ -1426,14 +1441,7 @@ public class I2PSnarkServlet extends DefaultServlet {
out.write(" <input type=\"submit\" class=\"create\" value=\""); out.write(" <input type=\"submit\" class=\"create\" value=\"");
out.write(_("Create torrent")); out.write(_("Create torrent"));
out.write("\" name=\"foo\" >\n" + out.write("\" name=\"foo\" >\n" +
"</td></tr><tr><td>"); "</td></tr>" +
out.write(_("Private?"));
out.write(" </td><td> <input type=\"checkbox\" class=\"optbox\" name=\"private\" value=\"true\" title=\"");
out.write(_("Use for private trackers"));
out.write("\"");
if (req.getParameter("private") != null)
out.write(" checked");
out.write("></td></tr>" +
"</table>\n" + "</table>\n" +
"</form></div></div>"); "</form></div></div>");
} }
@ -1636,11 +1644,14 @@ public class I2PSnarkServlet extends DefaultServlet {
.append("</th><th>") .append("</th><th>")
.append(_("Website URL")) .append(_("Website URL"))
.append("</th><th>") .append("</th><th>")
.append(_("Open Tracker?")) .append(_("Open"))
.append("</th><th>")
.append(_("Private"))
.append("</th><th>") .append("</th><th>")
.append(_("Announce URL")) .append(_("Announce URL"))
.append("</th></tr>\n"); .append("</th></tr>\n");
List<String> openTrackers = _manager.util().getOpenTrackers(); List<String> openTrackers = _manager.util().getOpenTrackers();
List<String> privateTrackers = _manager.getPrivateTrackers();
for (Tracker t : _manager.getSortedTrackers()) { for (Tracker t : _manager.getSortedTrackers()) {
String name = t.name; String name = t.name;
String homeURL = t.baseURL; String homeURL = t.baseURL;
@ -1651,7 +1662,12 @@ public class I2PSnarkServlet extends DefaultServlet {
.append("</td><td align=\"left\">").append(urlify(homeURL, 35)) .append("</td><td align=\"left\">").append(urlify(homeURL, 35))
.append("</td><td align=\"center\"><input type=\"checkbox\" class=\"optbox\" name=\"open_") .append("</td><td align=\"center\"><input type=\"checkbox\" class=\"optbox\" name=\"open_")
.append(announceURL).append("\""); .append(announceURL).append("\"");
if (openTrackers != null && openTrackers.contains(t.announceURL)) if (openTrackers.contains(t.announceURL))
buf.append(" checked=\"checked\"");
buf.append(">" +
"</td><td align=\"center\"><input type=\"checkbox\" class=\"optbox\" name=\"private_")
.append(announceURL).append("\"");
if (privateTrackers.contains(t.announceURL))
buf.append(" checked=\"checked\""); buf.append(" checked=\"checked\"");
buf.append(">" + buf.append(">" +
"</td><td align=\"left\">").append(urlify(announceURL, 35)) "</td><td align=\"left\">").append(urlify(announceURL, 35))
@ -1662,11 +1678,12 @@ public class I2PSnarkServlet extends DefaultServlet {
"<td align=\"left\"><input type=\"text\" size=\"16\" name=\"tname\"></td>" + "<td align=\"left\"><input type=\"text\" size=\"16\" name=\"tname\"></td>" +
"<td align=\"left\"><input type=\"text\" size=\"40\" name=\"thurl\"></td>" + "<td align=\"left\"><input type=\"text\" size=\"40\" name=\"thurl\"></td>" +
"<td align=\"center\"><input type=\"checkbox\" class=\"optbox\" name=\"_add_open_\"></td>" + "<td align=\"center\"><input type=\"checkbox\" class=\"optbox\" name=\"_add_open_\"></td>" +
"<td align=\"center\"><input type=\"checkbox\" class=\"optbox\" name=\"_add_private_\"></td>" +
"<td align=\"left\"><input type=\"text\" size=\"40\" name=\"taurl\"></td></tr>\n" + "<td align=\"left\"><input type=\"text\" size=\"40\" name=\"taurl\"></td></tr>\n" +
"<tr><td colspan=\"2\"></td><td colspan=\"3\" align=\"left\">\n" + "<tr><td colspan=\"2\"></td><td colspan=\"4\" align=\"left\">\n" +
"<input type=\"submit\" name=\"taction\" class=\"default\" value=\"").append(_("Add tracker")).append("\">\n" + "<input type=\"submit\" name=\"taction\" class=\"default\" value=\"").append(_("Add tracker")).append("\">\n" +
"<input type=\"submit\" name=\"taction\" class=\"delete\" value=\"").append(_("Delete selected")).append("\">\n" + "<input type=\"submit\" name=\"taction\" class=\"delete\" value=\"").append(_("Delete selected")).append("\">\n" +
"<input type=\"submit\" name=\"taction\" class=\"accept\" value=\"").append(_("Change open trackers")).append("\">\n" + "<input type=\"submit\" name=\"taction\" class=\"accept\" value=\"").append(_("Save tracker configuration")).append("\">\n" +
// "<input type=\"reset\" class=\"cancel\" value=\"").append(_("Cancel")).append("\">\n" + // "<input type=\"reset\" class=\"cancel\" value=\"").append(_("Cancel")).append("\">\n" +
"<input type=\"submit\" name=\"taction\" class=\"reload\" value=\"").append(_("Restore defaults")).append("\">\n" + "<input type=\"submit\" name=\"taction\" class=\"reload\" value=\"").append(_("Restore defaults")).append("\">\n" +
"<input type=\"submit\" name=\"taction\" class=\"add\" value=\"").append(_("Add tracker")).append("\">\n" + "<input type=\"submit\" name=\"taction\" class=\"add\" value=\"").append(_("Add tracker")).append("\">\n" +
@ -2067,9 +2084,13 @@ public class I2PSnarkServlet extends DefaultServlet {
} }
String hex = I2PSnarkUtil.toHex(snark.getInfoHash()); String hex = I2PSnarkUtil.toHex(snark.getInfoHash());
buf.append("<br>").append(toImg("magnet", _("Magnet link"))).append(" <a href=\"") if (meta == null || !meta.isPrivate()) {
.append(MAGNET_FULL).append(hex).append("\">") buf.append("<br>").append(toImg("magnet", _("Magnet link"))).append(" <a href=\"")
.append(MAGNET_FULL).append(hex).append("</a>"); .append(MAGNET_FULL).append(hex).append("\">")
.append(MAGNET_FULL).append(hex).append("</a>");
} else {
buf.append("<br>").append(_("Private torrent"));
}
// We don't have the hash of the torrent file // We don't have the hash of the torrent file
//buf.append("<br>").append(_("Maggot link")).append(": <a href=\"").append(MAGGOT).append(hex).append(':').append(hex).append("\">") //buf.append("<br>").append(_("Maggot link")).append(": <a href=\"").append(MAGGOT).append(hex).append(':').append(hex).append("\">")
// .append(MAGGOT).append(hex).append(':').append(hex).append("</a>"); // .append(MAGGOT).append(hex).append(':').append(hex).append("</a>");

View File

@ -1,3 +1,10 @@
2012-06-08 zzz
* i2psnark:
- Move private tracker config from create box to torrent config
- Refactor private and open tracker configuration
- Add private indication on details page
* netdb.jsp: Don't show our info on summary page
2012-06-04 zzz 2012-06-04 zzz
* i2psnark: Take tracker out of opentracker list when removed * i2psnark: Take tracker out of opentracker list when removed

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 10; public final static long BUILD = 11;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";