feat: add support for searching within a channel (#262)

* feat(Channel): add support for searching

* dev: add channel search test

* chore: update docs
This commit is contained in:
LuanRT
2022-12-26 18:56:37 -03:00
committed by GitHub
parent fb2e237284
commit 2b3642ba63
5 changed files with 31 additions and 8 deletions

View File

@@ -479,6 +479,7 @@ Retrieves contents for a given channel.
- `<channel>#getCommunity()`
- `<channel>#getChannels()`
- `<channel>#getAbout()`
- `<channel>#search(query)`
- `<channel>#getContinuation()`
- `<channel>#filters`
- `<channel>#page`

View File

@@ -14,28 +14,34 @@ import { Innertube, UniversalCache, YTNodes } from 'youtubei.js';
console.info('Country:', about.country.toString());
console.info('\nLists the following videos:');
console.info('\nVideos:');
const videos = await channel.getVideos();
for (const video of videos.videos) {
console.info('Video:', video.title.toString());
}
console.info('\nLists the following playlists:');
console.info('\nPopular videos:');
const popular_videos = await videos.applyFilter('Popular');
for (const video of popular_videos.videos) {
console.info('Video:', video.title.toString());
}
console.info('\nPlaylists:');
const playlists = await channel.getPlaylists();
for (const playlist of playlists.playlists) {
console.info('Playlist:', playlist.title.toString());
}
console.info('\nLists the following channels:');
console.info('\nChannels:');
const channels = await channel.getChannels();
for (const channel of channels.channels) {
console.info('Channel:', channel.author.name);
}
console.info('\nLists the following community posts:');
console.info('\nCommunity posts:');
const posts = await channel.getCommunity();
for (const post of posts.posts) {

View File

@@ -15,7 +15,7 @@ class ExpandableTab extends YTNode {
this.title = data.title;
this.endpoint = new NavigationEndpoint(data.endpoint);
this.selected = data.selected; // If this.selected then we may have content else we do not
this.content = data.content ? Parser.parse(data.content) : null;
this.content = data.content ? Parser.parseItem(data.content) : null;
}
}

View File

@@ -15,6 +15,7 @@ import FilterableFeed from '../../core/FilterableFeed';
import Feed from '../../core/Feed';
import { InnertubeError } from '../../utils/Utils';
import ExpandableTab from '../classes/ExpandableTab';
export default class Channel extends TabbedFeed {
header;
@@ -37,9 +38,7 @@ export default class Channel extends TabbedFeed {
this.subscribe_button = this.page.header_memo.getType(SubscribeButton)?.[0];
const tab = this.page.contents.item().key('tabs').parsed().array().filterType(Tab).get({ selected: true });
this.current_tab = tab;
this.current_tab = this.page.contents.item().key('tabs').parsed().array().filterType(Tab, ExpandableTab).get({ selected: true });
}
/**
@@ -114,6 +113,20 @@ export default class Channel extends TabbedFeed {
return tab.memo.getType(ChannelAboutFullMetadata)?.[0];
}
/**
* Searches within the channel.
*/
async search(query: string) {
const tab = this.memo.getType(ExpandableTab)?.[0];
if (!tab)
throw new InnertubeError('Search tab not found', this);
const page = await tab.endpoint?.call(this.actions, { query, parse: true });
return new Channel(this.actions, page, true);
}
/**
* Retrives list continuation.
*/

View File

@@ -114,6 +114,9 @@ describe('YouTube.js Tests', () => {
const filtered_list = await videos_tab.applyFilter('Popular');
expect(filtered_list.videos.length).toBeGreaterThan(0);
const search = await channel.search('e-ink');
expect(search.videos.length).toBeGreaterThan(0);
});
it('should retrieve home feed', async () => {