Skip to content

Commit 47ad26c

Browse files
evermind-zzInfinityLoop1308
authored andcommitted
searchfilters: a framework to create sort and content filter objects
1 parent 3400a6f commit 47ad26c

4 files changed

Lines changed: 302 additions & 0 deletions

File tree

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.schabi.newpipe.extractor.search.filter;
2+
3+
public final class Filter {
4+
5+
public static final int ITEM_IDENTIFIER_UNKNOWN = -1;
6+
private final FilterGroup[] sortGroups;
7+
private int size = 0;
8+
9+
private Filter(final FilterGroup[] sortGroups) {
10+
this.sortGroups = sortGroups;
11+
}
12+
13+
public FilterGroup[] getFilterGroups() {
14+
return sortGroups;
15+
}
16+
17+
public static class Builder {
18+
final Filter filter;
19+
20+
public Builder(final FilterGroup[] sortGroups) {
21+
filter = new Filter(sortGroups);
22+
}
23+
24+
public Builder setNoOfFilters(final int noOfFilters) {
25+
filter.size = noOfFilters;
26+
return this;
27+
}
28+
29+
public Filter build() {
30+
return filter;
31+
}
32+
}
33+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package org.schabi.newpipe.extractor.search.filter;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
public class FilterGroup {
7+
public final String groupName;
8+
public final FilterItem[] filterItems;
9+
public final int identifier;
10+
public boolean onlyOneCheckable;
11+
12+
public FilterGroup(final int identifier, final String groupName,
13+
final boolean onlyOneCheckable,
14+
final FilterItem[] filterItems) {
15+
this.identifier = identifier;
16+
this.groupName = groupName;
17+
this.onlyOneCheckable = onlyOneCheckable;
18+
this.filterItems = filterItems;
19+
}
20+
21+
public static class Builder {
22+
public final Map<Integer, FilterItem> filtersMap = new HashMap<>();
23+
private final Map<String, Integer> filtersSortGroupMap = new HashMap<>();
24+
public int noOfSortFilters;
25+
public FilterGroup[] filterGroups = null;
26+
/**
27+
* used to give each added filter an unique identifier
28+
*/
29+
private int identifierIncrement;
30+
private int noOfContentFilters;
31+
32+
public Builder() {
33+
this.noOfSortFilters = 0;
34+
this.noOfContentFilters = 0;
35+
this.identifierIncrement = 0;
36+
}
37+
38+
public int addSortItem(final FilterItem filter) {
39+
this.noOfSortFilters++;
40+
return addItem(filter);
41+
}
42+
43+
public int addFilterItem(final FilterItem filter) {
44+
this.noOfContentFilters++;
45+
return addItem(filter);
46+
}
47+
48+
private int addItem(final FilterItem filter) {
49+
final FilterItem.Builder filterItemBuilder =
50+
FilterItem.builder(filter);
51+
filterItemBuilder.setIdentifier(this.identifierIncrement);
52+
filtersMap.put(this.identifierIncrement, filterItemBuilder.build());
53+
return this.identifierIncrement++;
54+
}
55+
56+
public int getNoOfSortFilters() {
57+
return this.noOfSortFilters;
58+
}
59+
60+
public FilterGroup createSortGroup(final String groupName,
61+
final boolean onlyOneCheckable,
62+
final FilterItem[] filterItems) {
63+
final int identifier;
64+
if (filtersSortGroupMap.containsKey(groupName)) {
65+
identifier = filtersSortGroupMap.get(groupName);
66+
} else {
67+
identifier = this.identifierIncrement++;
68+
filtersSortGroupMap.put(groupName, identifier);
69+
}
70+
71+
return new FilterGroup(identifier, groupName, onlyOneCheckable, filterItems);
72+
}
73+
74+
public FilterItem getFilterForId(final int filterId) {
75+
return filtersMap.get(filterId);
76+
}
77+
}
78+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.schabi.newpipe.extractor.search.filter;
2+
3+
public class FilterItem {
4+
private final String name;
5+
private int identifier;
6+
/**
7+
* check if a {@link #FilterItem} was build using the {@link Builder}
8+
*/
9+
private boolean isBuild = false;
10+
11+
public FilterItem(final int identifier, final String name) {
12+
this.identifier = identifier;
13+
this.name = name;
14+
}
15+
16+
public static Builder builder(final FilterItem filterItem) {
17+
return new Builder(filterItem);
18+
}
19+
20+
public int getIdentifier() {
21+
return this.identifier;
22+
}
23+
24+
public String getName() {
25+
return this.name;
26+
}
27+
28+
public static class Builder {
29+
30+
private final FilterItem filterItem;
31+
32+
public Builder(final FilterItem filterItem) {
33+
this.filterItem = filterItem;
34+
}
35+
36+
public Builder setIdentifier(final int itemIdentifier) {
37+
filterItem.identifier = itemIdentifier;
38+
return this;
39+
}
40+
41+
public FilterItem build() {
42+
if (filterItem.isBuild) {
43+
throw new RuntimeException("filter is already build()");
44+
}
45+
if (filterItem.identifier == Filter.ITEM_IDENTIFIER_UNKNOWN) {
46+
throw new RuntimeException("itemIdentifier is not set");
47+
}
48+
49+
filterItem.isBuild = true;
50+
return filterItem;
51+
}
52+
}
53+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
package org.schabi.newpipe.extractor.search.filter;
2+
3+
import org.schabi.newpipe.extractor.services.youtube.search.filter.YoutubeFilters;
4+
5+
import java.util.HashMap;
6+
import java.util.LinkedList;
7+
import java.util.List;
8+
import java.util.Map;
9+
import java.util.Set;
10+
11+
/**
12+
* Deriving class must always call {@link SearchFiltersBase#init()} and {@link SearchFiltersBase#build()}
13+
* in constructor manually.
14+
*/
15+
public abstract class SearchFiltersBase {
16+
17+
protected final Map<Integer, Filter> sortFilterVariants = new HashMap<>();
18+
protected int defaultContentFilterId = Filter.ITEM_IDENTIFIER_UNKNOWN;
19+
protected Integer[] contentFilters;
20+
protected FilterGroup.Builder builder = new FilterGroup.Builder();
21+
protected List<FilterItem> selectedContentFilter = null;
22+
protected List<FilterItem> selectedSortFilter;
23+
protected Filter contentFiltersVariant;
24+
protected List<FilterGroup> contentFiltersList = new LinkedList<>();
25+
private Filter allSortFiltersVariant = null;
26+
27+
/**
28+
* Set the user selected sort filters which the user has selected in the UI.
29+
*
30+
* @param selectedSortFilter list with sort filters identifiers
31+
*/
32+
public void setSelectedSortFilter(final List<FilterItem> selectedSortFilter) {
33+
this.selectedSortFilter = selectedSortFilter;
34+
}
35+
36+
/**
37+
* Set the selected content filter
38+
*
39+
* @param selectedContentFilter the name of the content filter
40+
*/
41+
public void setSelectedContentFilter(final List<FilterItem> selectedContentFilter) {
42+
this.selectedContentFilter = selectedContentFilter;
43+
}
44+
45+
/**
46+
* Evaluate content and sort filters. This method should be run after:
47+
* {@link #setSelectedContentFilter(List)} and {@link #setSelectedSortFilter(List)}
48+
*
49+
* @return the query that should be appended to the searchUrl/whatever
50+
*/
51+
public String evaluateSelectedFilters(final String searchString) {
52+
return "";
53+
}
54+
55+
/**
56+
* Evaluate content filters. This method should be run after:
57+
* {@link #setSelectedContentFilter(List)}
58+
*
59+
* @return the sortQuery that should be appended to the searchUrl/whatever
60+
*/
61+
public String evaluateSelectedContentFilters() {
62+
return "";
63+
}
64+
65+
/**
66+
* Evaluate sort filters. This method should be run after:
67+
* {@link #setSelectedSortFilter(List)}
68+
*
69+
* @return the contentQuery that should be appended to the searchUrl/whatever
70+
*/
71+
public String evaluateSelectedSortFilters() {
72+
return "";
73+
}
74+
75+
/**
76+
* create all 'sort' and 'content filter' items and all 'sort filter variants' in this method.
77+
* See eg. {@link YoutubeFilters#init()}
78+
*/
79+
protected abstract void init();
80+
81+
public Integer[] getAvailableContentFilter() {
82+
return contentFilters;
83+
}
84+
85+
protected void build() {
86+
final Set<Map.Entry<Integer, Filter>> entrySet =
87+
this.sortFilterVariants.entrySet();
88+
this.contentFilters = new Integer[entrySet.size()];
89+
int count = 0;
90+
for (final Map.Entry<Integer, Filter> entry : entrySet) {
91+
this.contentFilters[count++] = entry.getKey();
92+
93+
}
94+
95+
this.contentFiltersVariant = new Filter.Builder(
96+
this.contentFiltersList.toArray(new FilterGroup[0]))
97+
.setNoOfFilters(builder.getNoOfSortFilters()).build();
98+
}
99+
100+
/**
101+
* Add content Filter SortVariants.
102+
* <p>
103+
* Calling the method the first time {@variant} will be set
104+
* as all variants sortFilter when called {@link #getSortFilters()}
105+
*
106+
* @param contentFilterId
107+
* @param variant
108+
*/
109+
protected void addContentFilterSortVariant(
110+
final int contentFilterId,
111+
final Filter variant) {
112+
if (this.sortFilterVariants.isEmpty()) {
113+
this.allSortFiltersVariant = variant;
114+
}
115+
this.sortFilterVariants.put(contentFilterId, variant);
116+
}
117+
118+
public Filter getContentFilterSortFilterVariant(
119+
final int contentFilterName) {
120+
return this.sortFilterVariants.get(contentFilterName);
121+
}
122+
123+
public Filter getSortFilters() {
124+
return this.allSortFiltersVariant;
125+
}
126+
127+
public Filter getContentFilters() {
128+
return this.contentFiltersVariant;
129+
}
130+
131+
public FilterItem getFilterItem(final int filterId) {
132+
return builder.getFilterForId(filterId);
133+
}
134+
135+
protected void addContentFilter(final FilterGroup hds) {
136+
this.contentFiltersList.add(hds);
137+
}
138+
}

0 commit comments

Comments
 (0)