package de.danoeh.antennapod.core.feed;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FeedFilter {
private static final String TAG = "FeedFilter";
private String includeFilter;
private String excludeFilter;
public FeedFilter() {
this("", "");
}
public FeedFilter(String includeFilter, String excludeFilter) {
// We're storing the strings and not the parsed terms because
// 1. It's easier to show the user exactly what they typed in this way
// (we don't have to recreate it)
// 2. We don't know if we'll actually be asked to parse anything anyways.
this.includeFilter = includeFilter;
this.excludeFilter = excludeFilter;
}
/**
* Parses the text in to a list of single words or quoted strings.
* Example: "One "Two Three"" returns ["One", "Two Three"]
* @param filter string to parse in to terms
* @return list of terms
*/
private List<String> parseTerms(String filter) {
// from http://stackoverflow.com/questions/7804335/split-string-on-spaces-in-java-except-if-between-quotes-i-e-treat-hello-wor
List<String> list = new ArrayList<>();
Matcher m = Pattern.compile("([^\"]\\S*|\".+?\")\\s*").matcher(filter);
while (m.find())
list.add(m.group(1).replace("\"", ""));
return list;
}
/**
* @param item
* @return true if the item should be downloaded
*/
public boolean shouldAutoDownload(FeedItem item) {
List<String> includeTerms = parseTerms(includeFilter);
List<String> excludeTerms = parseTerms(excludeFilter);
if (includeTerms.size() == 0 && excludeTerms.size() == 0) {
// nothing has been specified, so include everything
return true;
}
// check using lowercase so the users don't have to worry about case.
String title = item.getTitle().toLowerCase();
// if it's explicitly excluded, it shouldn't be autodownloaded
// even if it has include terms
for (String term : excludeTerms) {
if (title.contains(term.trim().toLowerCase())) {
return false;
}
}
for (String term : includeTerms) {
if (title.contains(term.trim().toLowerCase())) {
return true;
}
}
// now's the tricky bit
// if they haven't set an include filter, but they have set an exclude filter
// default to including, but if they've set both, then exclude
if (!hasIncludeFilter() && hasExcludeFilter()) {
return true;
}
return false;
}
public String getIncludeFilter() {
return includeFilter;
}
public String getExcludeFilter() { return excludeFilter; }
/**
* @return true if only include is set
*/
public boolean includeOnly() {
return hasIncludeFilter() && !hasExcludeFilter();
}
/**
* @return true if only exclude is set
*/
public boolean excludeOnly() {
return hasExcludeFilter() && !hasIncludeFilter();
}
public boolean hasIncludeFilter() {
return includeFilter.length() > 0;
}
public boolean hasExcludeFilter() {
return excludeFilter.length() > 0;
}
}