forked from I2P_Developers/i2p.i2p
- Refactor tracker map
This commit is contained in:
@ -8,6 +8,7 @@ import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
@ -18,7 +19,6 @@ import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
@ -58,7 +58,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
private ConnectionAcceptor _connectionAcceptor;
|
||||
private Thread _monitor;
|
||||
private volatile boolean _running;
|
||||
private final Map<String, String> _trackerMap;
|
||||
private final Map<String, Tracker> _trackerMap;
|
||||
|
||||
public static final String PROP_I2CP_HOST = "i2psnark.i2cpHost";
|
||||
public static final String PROP_I2CP_PORT = "i2psnark.i2cpPort";
|
||||
@ -130,7 +130,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
_configFile = new File(CONFIG_FILE);
|
||||
if (!_configFile.isAbsolute())
|
||||
_configFile = new File(_context.getConfigDir(), CONFIG_FILE);
|
||||
_trackerMap = Collections.synchronizedMap(new TreeMap(new IgnoreCaseComparator()));
|
||||
_trackerMap = new ConcurrentHashMap(4);
|
||||
loadConfig(null);
|
||||
}
|
||||
|
||||
@ -1404,40 +1404,67 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorted map of name to announceURL=baseURL
|
||||
* Unsorted map of name to Tracker object
|
||||
* Modifiable, not a copy
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public Map<String, String> getTrackers() {
|
||||
public Map<String, Tracker> getTrackerMap() {
|
||||
return _trackerMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsorted, do not modify
|
||||
*/
|
||||
public Collection<Tracker> getTrackers() {
|
||||
return _trackerMap.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorted copy
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public List<Tracker> getSortedTrackers() {
|
||||
List<Tracker> rv = new ArrayList(_trackerMap.values());
|
||||
Collections.sort(rv, new IgnoreCaseComparator());
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** @since 0.9 */
|
||||
private void initTrackerMap() {
|
||||
String trackers = _config.getProperty(PROP_TRACKERS);
|
||||
if ( (trackers == null) || (trackers.trim().length() <= 0) )
|
||||
trackers = _context.getProperty(PROP_TRACKERS);
|
||||
_trackerMap.clear();
|
||||
if ( (trackers == null) || (trackers.trim().length() <= 0) ) {
|
||||
for (int i = 0; i < DEFAULT_TRACKERS.length; i += 2)
|
||||
_trackerMap.put(DEFAULT_TRACKERS[i], DEFAULT_TRACKERS[i+1]);
|
||||
setDefaultTrackerMap(true);
|
||||
} else {
|
||||
String[] toks = trackers.split(",");
|
||||
for (int i = 0; i < toks.length; i += 2) {
|
||||
String name = toks[i].trim().replace(",", ",");
|
||||
String url = toks[i+1].trim().replace(",", ",");
|
||||
if ( (name.length() > 0) && (url.length() > 0) )
|
||||
_trackerMap.put(name, url);
|
||||
if ( (name.length() > 0) && (url.length() > 0) ) {
|
||||
String urls[] = DEFAULT_TRACKERS[i+1].split("=", 2);
|
||||
String url2 = urls.length > 1 ? urls[1] : null;
|
||||
_trackerMap.put(name, new Tracker(name, urls[0], url2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.9 */
|
||||
public void setDefaultTrackerMap() {
|
||||
setDefaultTrackerMap(true);
|
||||
}
|
||||
|
||||
/** @since 0.9.1 */
|
||||
private void setDefaultTrackerMap(boolean save) {
|
||||
_trackerMap.clear();
|
||||
for (int i = 0; i < DEFAULT_TRACKERS.length; i += 2) {
|
||||
_trackerMap.put(DEFAULT_TRACKERS[i], DEFAULT_TRACKERS[i+1]);
|
||||
String name = DEFAULT_TRACKERS[i];
|
||||
String urls[] = DEFAULT_TRACKERS[i+1].split("=", 2);
|
||||
String url2 = urls.length > 1 ? urls[1] : null;
|
||||
_trackerMap.put(name, new Tracker(name, urls[0], url2));
|
||||
}
|
||||
if (_config.remove(PROP_TRACKERS) != null) {
|
||||
if (save && _config.remove(PROP_TRACKERS) != null) {
|
||||
saveConfig();
|
||||
}
|
||||
}
|
||||
@ -1446,12 +1473,15 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
public void saveTrackerMap() {
|
||||
StringBuilder buf = new StringBuilder(2048);
|
||||
boolean comma = false;
|
||||
for (Map.Entry<String, String> e : _trackerMap.entrySet()) {
|
||||
for (Map.Entry<String, Tracker> e : _trackerMap.entrySet()) {
|
||||
if (comma)
|
||||
buf.append(',');
|
||||
else
|
||||
comma = true;
|
||||
buf.append(e.getKey().replace(",", ",")).append(',').append(e.getValue().replace(",", ","));
|
||||
Tracker t = e.getValue();
|
||||
buf.append(e.getKey().replace(",", ",")).append(',').append(t.announceURL.replace(",", ","));
|
||||
if (t.baseURL != null)
|
||||
buf.append('=').append(t.baseURL);
|
||||
}
|
||||
_config.setProperty(PROP_TRACKERS, buf.toString());
|
||||
saveConfig();
|
||||
@ -1481,9 +1511,9 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
* ignore case, current locale
|
||||
* @since 0.9
|
||||
*/
|
||||
private static class IgnoreCaseComparator implements Comparator<String> {
|
||||
public int compare(String l, String r) {
|
||||
return l.toLowerCase().compareTo(r.toLowerCase());
|
||||
private static class IgnoreCaseComparator implements Comparator<Tracker> {
|
||||
public int compare(Tracker l, Tracker r) {
|
||||
return l.name.toLowerCase().compareTo(r.name.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
28
apps/i2psnark/java/src/org/klomp/snark/Tracker.java
Normal file
28
apps/i2psnark/java/src/org/klomp/snark/Tracker.java
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
*/
|
||||
package org.klomp.snark;
|
||||
|
||||
/**
|
||||
* A structure for known trackers
|
||||
*
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public class Tracker {
|
||||
|
||||
public final String name;
|
||||
public final String announceURL;
|
||||
public final String baseURL;
|
||||
public final boolean supportsDetails;
|
||||
|
||||
/**
|
||||
* @param baseURL The web site, may be null
|
||||
*/
|
||||
public Tracker(String name, String announceURL, String baseURL) {
|
||||
this.name = name;
|
||||
this.announceURL = announceURL;
|
||||
this.baseURL = baseURL;
|
||||
this.supportsDetails = name.contains("tracker2.postman.i2p");
|
||||
}
|
||||
}
|
@ -37,6 +37,7 @@ import org.klomp.snark.Peer;
|
||||
import org.klomp.snark.Snark;
|
||||
import org.klomp.snark.SnarkManager;
|
||||
import org.klomp.snark.Storage;
|
||||
import org.klomp.snark.Tracker;
|
||||
import org.klomp.snark.TrackerClient;
|
||||
|
||||
import org.mortbay.jetty.servlet.DefaultServlet;
|
||||
@ -239,6 +240,7 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
else
|
||||
out.write("<body onload=\"initAjax()\">");
|
||||
out.write("<center>");
|
||||
List<Tracker> sortedTrackers = null;
|
||||
if (isConfigure) {
|
||||
out.write("<div class=\"snarknavbar\"><a href=\"/i2psnark/\" title=\"");
|
||||
out.write(_("Torrents"));
|
||||
@ -256,16 +258,11 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
out.write(_("Forum"));
|
||||
out.write("</a>\n");
|
||||
|
||||
Map trackers = _manager.getTrackers();
|
||||
for (Iterator iter = trackers.entrySet().iterator(); iter.hasNext(); ) {
|
||||
Map.Entry entry = (Map.Entry)iter.next();
|
||||
String name = (String)entry.getKey();
|
||||
String baseURL = (String)entry.getValue();
|
||||
int e = baseURL.indexOf('=');
|
||||
if (e < 0)
|
||||
sortedTrackers = _manager.getSortedTrackers();
|
||||
for (Tracker t : sortedTrackers) {
|
||||
if (t.baseURL == null || !t.baseURL.startsWith("http"))
|
||||
continue;
|
||||
baseURL = baseURL.substring(e + 1);
|
||||
out.write(" <a href=\"" + baseURL + "\" class=\"snarkRefresh\" target=\"_blank\">" + name + "</a>");
|
||||
out.write(" <a href=\"" + t.baseURL + "\" class=\"snarkRefresh\" target=\"_blank\">" + t.name + "</a>");
|
||||
}
|
||||
}
|
||||
out.write("</div>\n");
|
||||
@ -286,7 +283,7 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
// end of mainsection div
|
||||
out.write("</div><div id=\"lowersection\">\n");
|
||||
writeAddForm(out, req);
|
||||
writeSeedForm(out, req);
|
||||
writeSeedForm(out, req, sortedTrackers);
|
||||
writeConfigLink(out);
|
||||
// end of lowersection div
|
||||
out.write("</div>\n");
|
||||
@ -773,7 +770,7 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
private void processTrackerForm(String action, HttpServletRequest req) {
|
||||
if (action.equals(_("Delete selected"))) {
|
||||
boolean changed = false;
|
||||
Map<String, String> trackers = _manager.getTrackers();
|
||||
Map<String, Tracker> trackers = _manager.getTrackerMap();
|
||||
Enumeration e = req.getParameterNames();
|
||||
while (e.hasMoreElements()) {
|
||||
Object o = e.nextElement();
|
||||
@ -800,8 +797,8 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
hurl = hurl.trim();
|
||||
aurl = aurl.trim().replace("=", "=");
|
||||
if (name.length() > 0 && hurl.startsWith("http://") && aurl.startsWith("http://")) {
|
||||
Map<String, String> trackers = _manager.getTrackers();
|
||||
trackers.put(name, aurl + '=' + hurl);
|
||||
Map<String, Tracker> trackers = _manager.getTrackerMap();
|
||||
trackers.put(name, new Tracker(name, aurl, hurl));
|
||||
_manager.saveTrackerMap();
|
||||
} else {
|
||||
_manager.addMessage(_("Enter valid tracker name and URLs"));
|
||||
@ -1271,18 +1268,14 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
if (announce != null && (announce.startsWith("http://YRgrgTLG") || announce.startsWith("http://8EoJZIKr") ||
|
||||
announce.startsWith("http://lnQ6yoBT") || announce.startsWith("http://tracker2.postman.i2p/") ||
|
||||
announce.startsWith("http://ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna.b32.i2p/"))) {
|
||||
Map<String, String> trackers = _manager.getTrackers();
|
||||
for (Map.Entry<String, String> entry : trackers.entrySet()) {
|
||||
String baseURL = entry.getValue();
|
||||
if (!(baseURL.startsWith(announce) || // vvv hack for non-b64 announce in list vvv
|
||||
(announce.startsWith("http://lnQ6yoBT") && baseURL.startsWith("http://tracker2.postman.i2p/")) ||
|
||||
(announce.startsWith("http://ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna.b32.i2p/") && baseURL.startsWith("http://tracker2.postman.i2p/"))))
|
||||
for (Tracker t : _manager.getTrackers()) {
|
||||
String aURL = t.announceURL;
|
||||
if (!(aURL.startsWith(announce) || // vvv hack for non-b64 announce in list vvv
|
||||
(announce.startsWith("http://lnQ6yoBT") && aURL.startsWith("http://tracker2.postman.i2p/")) ||
|
||||
(announce.startsWith("http://ahsplxkbhemefwvvml7qovzl5a2b5xo5i7lyai7ntdunvcyfdtna.b32.i2p/") && aURL.startsWith("http://tracker2.postman.i2p/"))))
|
||||
continue;
|
||||
int e = baseURL.indexOf('=');
|
||||
if (e < 0)
|
||||
continue;
|
||||
baseURL = baseURL.substring(e + 1);
|
||||
String name = entry.getKey();
|
||||
String baseURL = t.baseURL;
|
||||
String name = t.name;
|
||||
StringBuilder buf = new StringBuilder(128);
|
||||
buf.append("<a href=\"").append(baseURL).append("details.php?dllist=1&filelist=1&info_hash=")
|
||||
.append(TrackerClient.urlencode(infohash))
|
||||
@ -1336,7 +1329,7 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
out.write("</div></form></div>");
|
||||
}
|
||||
|
||||
private void writeSeedForm(PrintWriter out, HttpServletRequest req) throws IOException {
|
||||
private void writeSeedForm(PrintWriter out, HttpServletRequest req, List<Tracker> sortedTrackers) throws IOException {
|
||||
String baseFile = req.getParameter("baseFile");
|
||||
if (baseFile == null || baseFile.trim().length() <= 0)
|
||||
baseFile = "";
|
||||
@ -1372,13 +1365,9 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
//out.write(_("Open trackers and DHT only"));
|
||||
out.write(_("Open trackers only"));
|
||||
out.write("</option>\n");
|
||||
Map<String, String> trackers = _manager.getTrackers();
|
||||
for (Map.Entry<String, String> entry : trackers.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
String announceURL = entry.getValue();
|
||||
int e = announceURL.indexOf('=');
|
||||
if (e > 0)
|
||||
announceURL = announceURL.substring(0, e).replace("=", "=");
|
||||
for (Tracker t : sortedTrackers) {
|
||||
String name = t.name;
|
||||
String announceURL = t.announceURL.replace("=", "=");
|
||||
if (announceURL.equals(_lastAnnounceURL))
|
||||
announceURL += "\" selected=\"selected";
|
||||
out.write("\t<option value=\"" + announceURL + "\">" + name + "</option>\n");
|
||||
@ -1605,15 +1594,10 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
.append("</th><th>")
|
||||
.append(_("Announce URL"))
|
||||
.append("</th></tr>\n");
|
||||
Map<String, String> trackers = _manager.getTrackers();
|
||||
for (Map.Entry<String, String> entry : trackers.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
String announceURL = entry.getValue();
|
||||
int e = announceURL.indexOf('=');
|
||||
if (e <= 0)
|
||||
continue;
|
||||
String homeURL = announceURL.substring(e + 1);
|
||||
announceURL = announceURL.substring(0, e).replace("=", "=");
|
||||
for (Tracker t : _manager.getSortedTrackers()) {
|
||||
String name = t.name;
|
||||
String homeURL = t.baseURL;
|
||||
String announceURL = t.announceURL.replace("=", "=");
|
||||
buf.append("<tr><td align=\"center\"><input type=\"checkbox\" class=\"optbox\" name=\"delete_")
|
||||
.append(name).append("\">" +
|
||||
"</td><td align=\"left\">").append(name)
|
||||
|
Reference in New Issue
Block a user