Skip to content

Commit

Permalink
feat: zoro - added continue watching
Browse files Browse the repository at this point in the history
  • Loading branch information
jasanpreetn9 committed Sep 5, 2024
1 parent 3a40463 commit b77057b
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 5 deletions.
37 changes: 37 additions & 0 deletions docs/providers/zoro.md
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,43 @@ output:
}
```

### fetchContinueWatching

<h4>Parameters</h4>


| Parameter | Type | Description |
| ----------- | -------- | ------------------------------------------------ |
| connectSid | `string` | The session ID obtained from the website cookies |

```ts
zoro.fetchContinueWatching("{user_connect_sid}").then(data => {
console.log(data);
})
```

returns a promise which resolves into an array of episodes. (*[`Promise<IAnimeEpisode[]>`](https://github.com/consumet/extensions/blob/master/src/models/types.ts#L13-L26)*)\
output:
```js
[
{
id: 'dragon-ball-super-broly-387$episode$58063',
title: 'Dragon Ball Super: Broly',
number: 1,
duration: '1:39:43',
watchedTime: '00:01',
url: 'http://hianime.to/watch/dragon-ball-super-broly-387?ep=58063',
image: 'https://cdn.noitatnemucod.net/thumbnail/300x400/100/6b138786ca53a86413d89806cb6836dd.jpg',
japaneseTitle: 'Dragon Ball Super Movie: Broly',
nsfw: false,
sub: 1,
dub: 1,
episodes: 0
},
{...},
...
]
```

Make sure to check the `headers` property of the returned object. It contains the referer header, which might be needed to bypass the 403 error and allow you to stream the video without any issues.

Expand Down
74 changes: 69 additions & 5 deletions src/providers/anime/zoro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
StreamingServers,
MediaFormat,
SubOrSub,
IAnimeEpisode,
} from '../../models';

import { StreamSB, RapidCloud, MegaCloud, StreamTape } from '../../utils';
Expand All @@ -25,11 +26,15 @@ class Zoro extends AnimeParser {

constructor(customBaseURL?: string) {
super(...arguments);
this.baseUrl = customBaseURL
? customBaseURL.startsWith('http://') || customBaseURL.startsWith('https://')
? customBaseURL
: `http://${customBaseURL}`
: this.baseUrl;
if (customBaseURL) {
if (customBaseURL.startsWith('http://') || customBaseURL.startsWith('https://')) {
this.baseUrl = customBaseURL;
} else {
this.baseUrl = `http://${customBaseURL}`;
}
} else {
this.baseUrl = this.baseUrl;

Check warning on line 36 in src/providers/anime/zoro.ts

View check run for this annotation

codefactor.io / CodeFactor

src/providers/anime/zoro.ts#L36

'this.baseUrl' is assigned to itself. (no-self-assign)
}
}

/**
Expand Down Expand Up @@ -233,6 +238,52 @@ class Zoro extends AnimeParser {
}
}

/**
* Fetches the list of episodes that the user is currently watching.
* @param connectSid The session ID of the user.
* @returns A promise that resolves to an array of anime episodes.
*/
async fetchContinueWatching(connectSid: string): Promise<IAnimeEpisode[]> {
try {
if (!(await this.verifyLoginState(connectSid))) {
throw new Error('Invalid session ID');
}
const res: IAnimeEpisode[] = [];
const { data } = await this.client.get(`${this.baseUrl}/user/continue-watching`, {
headers: {
Cookie: `connect.sid=${connectSid}`,
},
});
const $ = load(data);
$('.flw-item').each((i, ele) => {
const card = $(ele);
const atag = card.find('.film-name a');
const id = atag.attr('href')?.replace("/watch/", "")?.replace('?ep=', '$episode$');
const timeText = card.find('.fdb-time')?.text()?.split("/") ?? [];
const duration = timeText.pop()?.trim() ?? '';
const watchedTime = timeText.length > 0 ? timeText[0].trim() : '';
res.push({
id: id!,
title: atag.text(),
number: parseInt(card.find(".fdb-type").text().replace("EP", "").trim()),
duration: duration,
watchedTime: watchedTime,
url: `${this.baseUrl}${atag.attr('href')}`,
image: card.find('img')?.attr('data-src'),
japaneseTitle: atag.attr('data-jname'),
nsfw: card.find('.tick-rate')?.text() === '18+' ? true : false,
sub: parseInt(card.find('.tick-item.tick-sub')?.text()) || 0,
dub: parseInt(card.find('.tick-item.tick-dub')?.text()) || 0,
episodes: parseInt(card.find('.tick-item.tick-eps')?.text()) || 0,
});
});

return res;
} catch (err) {
throw new Error((err as Error).message);
}
}

/**
* @param id Anime id
*/
Expand Down Expand Up @@ -430,6 +481,19 @@ class Zoro extends AnimeParser {
}
};

private verifyLoginState = async (connectSid: string): Promise<boolean> => {
try {
const { data } = await this.client.get(`${this.baseUrl}/ajax/login-state`, {
headers: {
Cookie: `connect.sid=${connectSid}`,
},
});
return data.is_login;
} catch (err) {
return false;
}
};

private retrieveServerId = ($: any, index: number, subOrDub: 'sub' | 'dub') => {
return $(`.ps_-block.ps_-block-sub.servers-${subOrDub} > .ps__-list .server-item`)
.map((i: any, el: any) => ($(el).attr('data-server-id') == `${index}` ? $(el) : null))
Expand Down
7 changes: 7 additions & 0 deletions test/anime/zoro.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ test('returns a filled array of anime list', async () => {
expect(data.results).not.toEqual([]);
});

test('returns a filled array of episode list for continue watching', async () => {
const connectSid = 'users_connect_sid';
const data = await zoro.fetchContinueWatching(`${connectSid}`);
console.log(data)
expect(data).not.toEqual([]);
});

test('returns a filled object of anime data', async () => {
const res = await zoro.search('Overlord IV');
const data = await zoro.fetchAnimeInfo('one-piece-100'); // Overlord IV id
Expand Down

0 comments on commit b77057b

Please sign in to comment.