forked from I2P_Developers/i2p.i2p
This commit is contained in:
@@ -126,6 +126,7 @@ public class SnarkManager implements CompleteListener {
|
|||||||
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 String PROP_PRIVATETRACKERS = "i2psnark.privatetrackers";
|
||||||
private static final String PROP_USE_DHT = "i2psnark.enableDHT";
|
private static final String PROP_USE_DHT = "i2psnark.enableDHT";
|
||||||
|
private static final String PROP_SMART_SORT = "i2psnark.smartSort";
|
||||||
|
|
||||||
public static final int MIN_UP_BW = 10;
|
public static final int MIN_UP_BW = 10;
|
||||||
public static final int DEFAULT_MAX_UP_BW = 25;
|
public static final int DEFAULT_MAX_UP_BW = 25;
|
||||||
@@ -340,6 +341,17 @@ public class SnarkManager implements CompleteListener {
|
|||||||
public boolean shouldAutoStart() {
|
public boolean shouldAutoStart() {
|
||||||
return Boolean.parseBoolean(_config.getProperty(PROP_AUTO_START, DEFAULT_AUTO_START));
|
return Boolean.parseBoolean(_config.getProperty(PROP_AUTO_START, DEFAULT_AUTO_START));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return default true
|
||||||
|
* @since 0.9.23
|
||||||
|
*/
|
||||||
|
public boolean isSmartSortEnabled() {
|
||||||
|
String val = _config.getProperty(PROP_SMART_SORT);
|
||||||
|
if (val == null)
|
||||||
|
return true;
|
||||||
|
return Boolean.parseBoolean(val);
|
||||||
|
}
|
||||||
|
|
||||||
/****
|
/****
|
||||||
public String linkPrefix() {
|
public String linkPrefix() {
|
||||||
@@ -736,19 +748,19 @@ public class SnarkManager implements CompleteListener {
|
|||||||
/**
|
/**
|
||||||
* all params may be null or need trimming
|
* all params may be null or need trimming
|
||||||
*/
|
*/
|
||||||
public void updateConfig(String dataDir, boolean filesPublic, boolean autoStart, String refreshDelay,
|
public void updateConfig(String dataDir, boolean filesPublic, boolean autoStart, boolean smartSort, String refreshDelay,
|
||||||
String startDelay, String pageSize, String seedPct, String eepHost,
|
String startDelay, String pageSize, String seedPct, String eepHost,
|
||||||
String eepPort, String i2cpHost, String i2cpPort, String i2cpOpts,
|
String eepPort, String i2cpHost, String i2cpPort, String i2cpOpts,
|
||||||
String upLimit, String upBW, boolean useOpenTrackers, boolean useDHT, String theme) {
|
String upLimit, String upBW, boolean useOpenTrackers, boolean useDHT, String theme) {
|
||||||
synchronized(_configLock) {
|
synchronized(_configLock) {
|
||||||
locked_updateConfig(dataDir, filesPublic, autoStart, refreshDelay,
|
locked_updateConfig(dataDir, filesPublic, autoStart, smartSort,refreshDelay,
|
||||||
startDelay, pageSize, seedPct, eepHost,
|
startDelay, pageSize, seedPct, eepHost,
|
||||||
eepPort, i2cpHost, i2cpPort, i2cpOpts,
|
eepPort, i2cpHost, i2cpPort, i2cpOpts,
|
||||||
upLimit, upBW, useOpenTrackers, useDHT, theme);
|
upLimit, upBW, useOpenTrackers, useDHT, theme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void locked_updateConfig(String dataDir, boolean filesPublic, boolean autoStart, String refreshDelay,
|
private void locked_updateConfig(String dataDir, boolean filesPublic, boolean autoStart, boolean smartSort, String refreshDelay,
|
||||||
String startDelay, String pageSize, String seedPct, String eepHost,
|
String startDelay, String pageSize, String seedPct, String eepHost,
|
||||||
String eepPort, String i2cpHost, String i2cpPort, String i2cpOpts,
|
String eepPort, String i2cpHost, String i2cpPort, String i2cpOpts,
|
||||||
String upLimit, String upBW, boolean useOpenTrackers, boolean useDHT, String theme) {
|
String upLimit, String upBW, boolean useOpenTrackers, boolean useDHT, String theme) {
|
||||||
@@ -966,6 +978,16 @@ public class SnarkManager implements CompleteListener {
|
|||||||
addMessage(_t("Disabled autostart"));
|
addMessage(_t("Disabled autostart"));
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isSmartSortEnabled() != smartSort) {
|
||||||
|
_config.setProperty(PROP_SMART_SORT, Boolean.toString(smartSort));
|
||||||
|
if (smartSort)
|
||||||
|
addMessage(_t("Enabled smart sort"));
|
||||||
|
else
|
||||||
|
addMessage(_t("Disabled smart sort"));
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (_util.shouldUseOpenTrackers() != useOpenTrackers) {
|
if (_util.shouldUseOpenTrackers() != useOpenTrackers) {
|
||||||
_config.setProperty(PROP_USE_OPENTRACKERS, useOpenTrackers + "");
|
_config.setProperty(PROP_USE_OPENTRACKERS, useOpenTrackers + "");
|
||||||
if (useOpenTrackers)
|
if (useOpenTrackers)
|
||||||
|
@@ -32,6 +32,7 @@ import net.i2p.data.DataHelper;
|
|||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.SecureFile;
|
import net.i2p.util.SecureFile;
|
||||||
|
import net.i2p.util.Translate;
|
||||||
|
|
||||||
import org.klomp.snark.I2PSnarkUtil;
|
import org.klomp.snark.I2PSnarkUtil;
|
||||||
import org.klomp.snark.MagnetURI;
|
import org.klomp.snark.MagnetURI;
|
||||||
@@ -1118,6 +1119,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
String dataDir = req.getParameter("nofilter_dataDir");
|
String dataDir = req.getParameter("nofilter_dataDir");
|
||||||
boolean filesPublic = req.getParameter("filesPublic") != null;
|
boolean filesPublic = req.getParameter("filesPublic") != null;
|
||||||
boolean autoStart = req.getParameter("autoStart") != null;
|
boolean autoStart = req.getParameter("autoStart") != null;
|
||||||
|
boolean smartSort = req.getParameter("smartSort") != null;
|
||||||
String seedPct = req.getParameter("seedPct");
|
String seedPct = req.getParameter("seedPct");
|
||||||
String eepHost = req.getParameter("eepHost");
|
String eepHost = req.getParameter("eepHost");
|
||||||
String eepPort = req.getParameter("eepPort");
|
String eepPort = req.getParameter("eepPort");
|
||||||
@@ -1133,7 +1135,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
boolean useDHT = req.getParameter("useDHT") != null;
|
boolean useDHT = req.getParameter("useDHT") != null;
|
||||||
//String openTrackers = req.getParameter("openTrackers");
|
//String openTrackers = req.getParameter("openTrackers");
|
||||||
String theme = req.getParameter("theme");
|
String theme = req.getParameter("theme");
|
||||||
_manager.updateConfig(dataDir, filesPublic, autoStart, refreshDel, startupDel, pageSize,
|
_manager.updateConfig(dataDir, filesPublic, autoStart, smartSort, refreshDel, startupDel, pageSize,
|
||||||
seedPct, eepHost, eepPort, i2cpHost, i2cpPort, i2cpOpts,
|
seedPct, eepHost, eepPort, i2cpHost, i2cpPort, i2cpOpts,
|
||||||
upLimit, upBW, useOpenTrackers, useDHT, theme);
|
upLimit, upBW, useOpenTrackers, useDHT, theme);
|
||||||
// update servlet
|
// update servlet
|
||||||
@@ -1401,6 +1403,10 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
sort = Integer.parseInt(ssort);
|
sort = Integer.parseInt(ssort);
|
||||||
} catch (NumberFormatException nfe) {}
|
} catch (NumberFormatException nfe) {}
|
||||||
}
|
}
|
||||||
|
if (_manager.isSmartSortEnabled())
|
||||||
|
Sorters.setPattern(Translate.getLanguage(_manager.util().getContext()));
|
||||||
|
else
|
||||||
|
Sorters.setPattern(null);
|
||||||
try {
|
try {
|
||||||
Collections.sort(rv, Sorters.getComparator(sort, this));
|
Collections.sort(rv, Sorters.getComparator(sort, this));
|
||||||
} catch (IllegalArgumentException iae) {
|
} catch (IllegalArgumentException iae) {
|
||||||
@@ -2144,6 +2150,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
String dataDir = _manager.getDataDir().getAbsolutePath();
|
String dataDir = _manager.getDataDir().getAbsolutePath();
|
||||||
boolean filesPublic = _manager.areFilesPublic();
|
boolean filesPublic = _manager.areFilesPublic();
|
||||||
boolean autoStart = _manager.shouldAutoStart();
|
boolean autoStart = _manager.shouldAutoStart();
|
||||||
|
boolean smartSort = _manager.isSmartSortEnabled();
|
||||||
boolean useOpenTrackers = _manager.util().shouldUseOpenTrackers();
|
boolean useOpenTrackers = _manager.util().shouldUseOpenTrackers();
|
||||||
//String openTrackers = _manager.util().getOpenTrackerString();
|
//String openTrackers = _manager.util().getOpenTrackerString();
|
||||||
boolean useDHT = _manager.util().shouldUseDHT();
|
boolean useDHT = _manager.util().shouldUseDHT();
|
||||||
@@ -2177,6 +2184,14 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
+ (autoStart ? "checked " : "")
|
+ (autoStart ? "checked " : "")
|
||||||
+ "title=\"");
|
+ "title=\"");
|
||||||
out.write(_t("If checked, automatically start torrents that are added"));
|
out.write(_t("If checked, automatically start torrents that are added"));
|
||||||
|
out.write("\" >" +
|
||||||
|
|
||||||
|
"<tr><td>");
|
||||||
|
out.write(_t("Smart torrent sorting"));
|
||||||
|
out.write(": <td><input type=\"checkbox\" class=\"optbox\" name=\"smartSort\" value=\"true\" "
|
||||||
|
+ (smartSort ? "checked " : "")
|
||||||
|
+ "title=\"");
|
||||||
|
out.write(_t("If checked, ignore words such as 'the' when sorting"));
|
||||||
out.write("\" >" +
|
out.write("\" >" +
|
||||||
|
|
||||||
"<tr><td>");
|
"<tr><td>");
|
||||||
|
@@ -6,6 +6,8 @@ import java.text.Collator;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.klomp.snark.MetaInfo;
|
import org.klomp.snark.MetaInfo;
|
||||||
import org.klomp.snark.Snark;
|
import org.klomp.snark.Snark;
|
||||||
@@ -18,6 +20,13 @@ import org.klomp.snark.Storage;
|
|||||||
*/
|
*/
|
||||||
class Sorters {
|
class Sorters {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See below
|
||||||
|
*/
|
||||||
|
private static final Pattern PATTERN_DE, PATTERN_EN, PATTERN_ES, PATTERN_FR,
|
||||||
|
PATTERN_IT, PATTERN_NL, PATTERN_PT;
|
||||||
|
private static Pattern _pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Negative is reverse
|
* Negative is reverse
|
||||||
*
|
*
|
||||||
@@ -113,8 +122,8 @@ class Sorters {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sort alphabetically in current locale, ignore case, ignore leading "the "
|
* Sort alphabetically in current locale, ignore case, ignore leading
|
||||||
* (I guess this is worth it, a lot of torrents start with "The "
|
* articles such as "the" if the pattern is set by setPattern()
|
||||||
* @since 0.7.14
|
* @since 0.7.14
|
||||||
*/
|
*/
|
||||||
private static class TorrentNameComparator implements Comparator<Snark>, Serializable {
|
private static class TorrentNameComparator implements Comparator<Snark>, Serializable {
|
||||||
@@ -130,13 +139,16 @@ class Sorters {
|
|||||||
if (l.getStorage() != null && r.getStorage() == null)
|
if (l.getStorage() != null && r.getStorage() == null)
|
||||||
return 1;
|
return 1;
|
||||||
String ls = l.getBaseName();
|
String ls = l.getBaseName();
|
||||||
String llc = ls.toLowerCase(Locale.US);
|
|
||||||
if (llc.startsWith("the ") || llc.startsWith("the.") || llc.startsWith("the_"))
|
|
||||||
ls = ls.substring(4);
|
|
||||||
String rs = r.getBaseName();
|
String rs = r.getBaseName();
|
||||||
String rlc = rs.toLowerCase(Locale.US);
|
Pattern p = _pattern;
|
||||||
if (rlc.startsWith("the ") || rlc.startsWith("the.") || rlc.startsWith("the_"))
|
if (p != null) {
|
||||||
rs = rs.substring(4);
|
Matcher m = p.matcher(ls);
|
||||||
|
if (m.matches())
|
||||||
|
ls = ls.substring(m.group(1).length());
|
||||||
|
m = p.matcher(rs);
|
||||||
|
if (m.matches())
|
||||||
|
rs = rs.substring(m.group(1).length());
|
||||||
|
}
|
||||||
return Collator.getInstance().compare(ls, rs);
|
return Collator.getInstance().compare(ls, rs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -528,4 +540,104 @@ class Sorters {
|
|||||||
return r.priority - l.priority;
|
return r.priority - l.priority;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Match an indefinite or definite article in the language,
|
||||||
|
* followed by one or more whitespace, '.', or '_'.
|
||||||
|
* Does not match "partitive" articles.
|
||||||
|
*
|
||||||
|
* https://en.wikipedia.org/wiki/Article_%28grammar%29
|
||||||
|
* http://www.loc.gov/marc/bibliographic/bdapndxf.html
|
||||||
|
*/
|
||||||
|
static {
|
||||||
|
PATTERN_DE = Pattern.compile(
|
||||||
|
// can't make the non-capturing innner group work
|
||||||
|
//"^((?:" +
|
||||||
|
"^((" +
|
||||||
|
"der|die|das|des|dem|den|ein|eine|einer|eines|einem|einen" +
|
||||||
|
")[\\s\\._]+).*",
|
||||||
|
Pattern.CASE_INSENSITIVE);
|
||||||
|
PATTERN_EN = Pattern.compile(
|
||||||
|
"^((" +
|
||||||
|
"a|an|the" +
|
||||||
|
")[\\s\\._]+).*",
|
||||||
|
Pattern.CASE_INSENSITIVE);
|
||||||
|
PATTERN_ES = Pattern.compile(
|
||||||
|
"^((" +
|
||||||
|
"el|la|lo|los|las|un|una|unos|unas" +
|
||||||
|
")[\\s\\._]+).*",
|
||||||
|
Pattern.CASE_INSENSITIVE);
|
||||||
|
PATTERN_FR = Pattern.compile(
|
||||||
|
// note l' doesn't require whitespace after
|
||||||
|
"^(l'|((" +
|
||||||
|
"le|la|les|un|une|des" +
|
||||||
|
")[\\s\\._]+)).*",
|
||||||
|
Pattern.CASE_INSENSITIVE);
|
||||||
|
PATTERN_IT = Pattern.compile(
|
||||||
|
// note l' and un' don't require whitespace after
|
||||||
|
"^(l'|un'|((" +
|
||||||
|
"il|lo|la|i|gli|le|uno|una|un" +
|
||||||
|
")[\\s\\._]+)).*",
|
||||||
|
Pattern.CASE_INSENSITIVE);
|
||||||
|
PATTERN_NL = Pattern.compile(
|
||||||
|
"^((" +
|
||||||
|
"de|het|het'n|een|een'n" +
|
||||||
|
")[\\s\\._]+).*",
|
||||||
|
Pattern.CASE_INSENSITIVE);
|
||||||
|
PATTERN_PT = Pattern.compile(
|
||||||
|
"^((" +
|
||||||
|
"o|a|os|as|um|uma|uns|umas" +
|
||||||
|
")[\\s\\._]+).*",
|
||||||
|
Pattern.CASE_INSENSITIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets static field, oh well
|
||||||
|
* @param lang null for none
|
||||||
|
* @since 0.9.23
|
||||||
|
*/
|
||||||
|
public static void setPattern(String lang) {
|
||||||
|
Pattern p;
|
||||||
|
if (lang == null)
|
||||||
|
p = null;
|
||||||
|
else if (lang.equals("de"))
|
||||||
|
p = PATTERN_DE;
|
||||||
|
else if (lang.equals("en"))
|
||||||
|
p = PATTERN_EN;
|
||||||
|
else if (lang.equals("es"))
|
||||||
|
p = PATTERN_ES;
|
||||||
|
else if (lang.equals("fr"))
|
||||||
|
p = PATTERN_FR;
|
||||||
|
else if (lang.equals("it"))
|
||||||
|
p = PATTERN_IT;
|
||||||
|
else if (lang.equals("nl"))
|
||||||
|
p = PATTERN_NL;
|
||||||
|
else if (lang.equals("pt"))
|
||||||
|
p = PATTERN_PT;
|
||||||
|
else
|
||||||
|
p = null;
|
||||||
|
_pattern = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****
|
||||||
|
public static final void main(String[] args) {
|
||||||
|
if (args.length != 2) {
|
||||||
|
System.out.println("Usage: Sorters lang 'string'");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
String lang = args[0];
|
||||||
|
setPattern(lang);
|
||||||
|
if (_pattern == null) {
|
||||||
|
System.out.println("Unsupported " + lang);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
String s = args[1];
|
||||||
|
Matcher m = _pattern.matcher(s);
|
||||||
|
if (m.matches()) {
|
||||||
|
System.out.println("Match is \"" + m.group(1) + '"');
|
||||||
|
} else {
|
||||||
|
System.out.println("No match for \"" + s + '"');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
****/
|
||||||
}
|
}
|
||||||
|
13
history.txt
13
history.txt
@@ -1,3 +1,16 @@
|
|||||||
|
2015-10-16 zzz
|
||||||
|
* i2psnark:
|
||||||
|
- Fix deadlock (ticket #1432)
|
||||||
|
- Add "smart sort" option, set sort based on language (tickets #637, #1303)
|
||||||
|
|
||||||
|
2015-10-14 zzz
|
||||||
|
* Update:
|
||||||
|
- Require Java 7 to download dev builds (ticket #1669)
|
||||||
|
- Fix persistence of the available dev version
|
||||||
|
|
||||||
|
2015-10-13 zzz
|
||||||
|
* Startup: Delete our old RI from netDB when rekeying
|
||||||
|
|
||||||
2015-10-11 zzz
|
2015-10-11 zzz
|
||||||
* Crypto: Test for broken Gentoo ECDSA support
|
* Crypto: Test for broken Gentoo ECDSA support
|
||||||
|
|
||||||
|
@@ -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 = 17;
|
public final static long BUILD = 18;
|
||||||
|
|
||||||
/** for example "-test" */
|
/** for example "-test" */
|
||||||
public final static String EXTRA = "";
|
public final static String EXTRA = "";
|
||||||
|
Reference in New Issue
Block a user