Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support exact search #1220

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.prepareDesktopJsonBuilder;
import static org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory.ALL;
import static org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory.CHANNELS;
import static org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory.EXACT;
import static org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory.PLAYLISTS;
import static org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory.VIDEOS;
import static org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeSearchQueryHandlerFactory.getSearchParameter;
Expand Down Expand Up @@ -64,6 +65,7 @@ public class YoutubeSearchExtractor extends SearchExtractor {

@Nullable
private final String searchType;
public final boolean isExactSearch;
private final boolean extractVideoResults;
private final boolean extractChannelResults;
private final boolean extractPlaylistResults;
Expand All @@ -75,24 +77,28 @@ public YoutubeSearchExtractor(final StreamingService service,
super(service, linkHandler);
final List<String> contentFilters = linkHandler.getContentFilters();
searchType = isNullOrEmpty(contentFilters) ? null : contentFilters.get(0);

// Save whether we should extract video, channel and playlist results depending on the
// requested search type, as YouTube returns sometimes videos inside channel search results
// If no search type is provided or ALL filter is requested, extract everything
// If no search type is provided or ALL/EXACT (without another search type) filter
// is requested, extract everything
extractVideoResults = searchType == null || ALL.equals(searchType)
|| VIDEOS.equals(searchType);
|| VIDEOS.equals(searchType) || EXACT.equals(searchType);
extractChannelResults = searchType == null || ALL.equals(searchType)
|| CHANNELS.equals(searchType);
|| CHANNELS.equals(searchType) || EXACT.equals(searchType);
extractPlaylistResults = searchType == null || ALL.equals(searchType)
|| PLAYLISTS.equals(searchType);
|| PLAYLISTS.equals(searchType) || EXACT.equals(searchType);

// If EXACT is NOT the search type this is needed to filter for a content filter + EXACT
isExactSearch = !isNullOrEmpty(contentFilters) && contentFilters.contains(EXACT);
}

@Override
public void onFetchPage(@Nonnull final Downloader downloader) throws IOException,
ExtractionException {
final String query = super.getSearchString();
final Localization localization = getExtractorLocalization();
final String params = getSearchParameter(searchType);

final String params = getSearchParameter(searchType, isExactSearch);
final JsonBuilder<JsonObject> jsonBody = prepareDesktopJsonBuilder(localization,
getExtractorContentCountry())
.value("query", query);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public final class YoutubeSearchQueryHandlerFactory extends SearchQueryHandlerFa
new YoutubeSearchQueryHandlerFactory();

public static final String ALL = "all";
public static final String EXACT = "exact";
public static final String VIDEOS = "videos";
public static final String CHANNELS = "channels";
public static final String PLAYLISTS = "playlists";
Expand All @@ -33,20 +34,23 @@ public final class YoutubeSearchQueryHandlerFactory extends SearchQueryHandlerFa
public static YoutubeSearchQueryHandlerFactory getInstance() {
return INSTANCE;
}

@Override
public String getUrl(final String searchString,
@Nonnull final List<String> contentFilters,
final String sortFilter)
throws ParsingException, UnsupportedOperationException {
final String contentFilter = !contentFilters.isEmpty() ? contentFilters.get(0) : "";
final boolean isExactSearch = !contentFilters.isEmpty() && contentFilter.contains(EXACT);

switch (contentFilter) {
case EXACT:
return SEARCH_URL + encodeUrlUtf8(searchString) + "&sp=QgIIAQ%253D%253D";
case VIDEOS:
return SEARCH_URL + encodeUrlUtf8(searchString) + "&sp=EgIQAfABAQ%253D%253D";
return SEARCH_URL + encodeUrlUtf8(searchString) + (isExactSearch ? "&sp=EgIQAUICCAE%253D" : "&sp=EgIQAfABAQ%253D%253D");
case CHANNELS:
return SEARCH_URL + encodeUrlUtf8(searchString) + "&sp=EgIQAvABAQ%253D%253D";
return SEARCH_URL + encodeUrlUtf8(searchString) + (isExactSearch ? "&sp=EgIQAkICCAE%253D" : "&sp=EgIQAvABAQ%253D%253D");
case PLAYLISTS:
return SEARCH_URL + encodeUrlUtf8(searchString) + "&sp=EgIQA_ABAQ%253D%253D";
return SEARCH_URL + encodeUrlUtf8(searchString) + (isExactSearch ? "&sp=EgIQA0ICCAE%253D" : "&sp=EgIQA_ABAQ%253D%253D");
case MUSIC_SONGS:
case MUSIC_VIDEOS:
case MUSIC_ALBUMS:
Expand All @@ -62,6 +66,7 @@ public String getUrl(final String searchString,
public String[] getAvailableContentFilter() {
return new String[]{
ALL,
//EXACT, Not a separate content filter (yet)
VIDEOS,
CHANNELS,
PLAYLISTS,
Expand All @@ -74,26 +79,28 @@ public String[] getAvailableContentFilter() {
}

@Nonnull
public static String getSearchParameter(final String contentFilter) {
public static String getSearchParameter(final String contentFilter, final boolean isExactSearch) {
if (isNullOrEmpty(contentFilter)) {
return "8AEB";
}

switch (contentFilter) {
case VIDEOS:
return "EgIQAfABAQ%3D%3D";
case CHANNELS:
return "EgIQAvABAQ%3D%3D";
case PLAYLISTS:
return "EgIQA_ABAQ%3D%3D";
case MUSIC_SONGS:
case MUSIC_VIDEOS:
case MUSIC_ALBUMS:
case MUSIC_PLAYLISTS:
case MUSIC_ARTISTS:
return "";
default:
return "8AEB";
case EXACT:
return "QgIIAQ%3D%3D";
case VIDEOS:
return isExactSearch ? "EgIQAUICCAE%3D" : "EgIQAfABAQ%3D%3D";
case CHANNELS:
return isExactSearch ? "EgIQAkICCAE%3D" : "EgIQAvABAQ%3D%3D";
case PLAYLISTS:
return isExactSearch ? "EgIQA0ICCAE%3D" : "EgIQA_ABAQ%3D%3D";
case MUSIC_SONGS:
case MUSIC_VIDEOS:
case MUSIC_ALBUMS:
case MUSIC_PLAYLISTS:
case MUSIC_ARTISTS:
return "";
default:
return "8AEB";
}
}
}