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

Marin #242

Merged
merged 5 commits into from
Feb 11, 2023
Merged

Marin #242

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
8 changes: 0 additions & 8 deletions src/providers/anime/gogoanime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,4 @@ class Gogoanime extends AnimeParser {
};
}

// (async () => {
// const anime = new Gogoanime({url: "https://cors.consumet.stream/"});
// const search = await anime.search('juuni taisen');
// // console.log(search);
// // const animeInfo = await anime.fetchEpisodeSources('juuni-taisen-dub-episode-6', StreamingServers.GogoCDN);
// console.log(search);
// })();

export default Gogoanime;
219 changes: 219 additions & 0 deletions src/providers/anime/marin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
import axios from 'axios';
import { load } from 'cheerio';

import {
AnimeParser,
ISearch,
IAnimeInfo,
MediaStatus,
IAnimeResult,
ISource,
IAnimeEpisode,
IEpisodeServer,
} from '../../models';

/**
* @attention Cloudflare bypass is **REQUIRED**.
*/
class Marin extends AnimeParser {
override readonly name = 'Marin';
protected override baseUrl = 'https://marin.moe';
protected override logo =
'https://i.pinimg.com/736x/62/8d/3f/628d3f2e60b0aa8c8fa9598e8dae6320.jpg';
protected override classPath = 'ANIME.Marin';

private async getToken(): Promise<string[]> {
let token: string[] = [];

let response = await axios.get('https://marin.moe/anime', {
headers: {
Referer: 'https://marin.moe/anime',
Cookie: '__ddg1_=;__ddg2_=;',
},
});

token.push(response.headers['set-cookie']![1].replace('marinmoe_session=', ''));
token.push(response.headers['set-cookie']![0].replace('XSRF-TOKEN=', ''));

return token;
}

/**
* @param query Search query
*/
override search = async (query: string, page: number = 1): Promise<ISearch<IAnimeResult>> => {
let token = await this.getToken()
let data;
try {
let response = await axios.post('https://marin.moe/anime',{"page" : page,"sort":"az-a","filter":{"type":[],"status":[],"content_rating":[],"genre":[],"group":[],"production":[],"source":[],"resolution":[],"audio":[],"subtitle":[]},"search": query}, {
headers: {
Origin: 'https://marin.moe/',
Referer: 'https://marin.moe/anime',
Cookie: `__ddg1=;__ddg2_=; XSRF-TOKEN=${token[1]}; marinmoe_session=${token[0]};`,
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
"x-xsrf-token": token[1].split(';')[0].replace("%3D", "="),

Check failure

Code scanning / CodeQL

Incomplete string escaping or encoding

This replaces only the first occurrence of "%3D".
"x-inertia": true
},
});
data = await response.data;
} catch (error) {
console.log(error)
}
let response_data = {
currentPage: page,
hasNextPage: data.props.anime_list.meta.last_page > page,
results: data.props.anime_list.data.map((el: any) => {
return {
id: el.slug,
title: el.title,
image: el.cover,
releaseDate: el.year,
type: el.type
};
})
}
return response_data;
};

/**
* @param id Anime id
*/
override fetchAnimeInfo = async (id: string): Promise<IAnimeInfo> => {
let data;
try {
let response = await axios.get(`https://marin.moe/anime/${id}`, {
headers: {
Origin: 'https://marin.moe/',
Referer: `https://marin.moe/anime/${id}`,
Cookie: `__ddg1=;__ddg2_=;`,
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
"x-inertia": true,
"x-inertia-version": "884345c4d568d16e3bb2fb3ae350cca9",
"x-requested-with": "XMLHttpRequest",
},
});
data = await response.data;
} catch (error) {
console.log(error)
}
let episodes: any[] = data.props.episode_list.data
if(data.props.anime.last_episode > 36) {
let token = await this.getToken()
for (let index = 2; index < data.props.anime.last_episode / 36; index++) {
let response = await axios.post(`https://marin.moe/anime/${id}`, {"filter":{"episodes":true,"specials":true},"eps_page": index}, {
headers: {
Origin: 'https://marin.moe/',
Referer: `https://marin.moe/anime/${id}`,
Cookie: `__ddg1=;__ddg2_=; XSRF-TOKEN=${token[1]}; marinmoe_session=${token[0]};`,
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
"x-inertia": true,
"x-inertia-version": "884345c4d568d16e3bb2fb3ae350cca9",
"x-requested-with": "XMLHttpRequest",
"x-xsrf-token": token[1].split(';')[0].replace("%3D", "="),

Check failure

Code scanning / CodeQL

Incomplete string escaping or encoding

This replaces only the first occurrence of "%3D".
},
});
let data = await response.data;
console.log(data.props.episode_list.data[0])
episodes = episodes.concat(data.props.episode_list.data);
}
}
//{"filter":{"episodes":true,"specials":true},"eps_page":2}

let response_data: IAnimeInfo = {
id: id,
title: {
native: data.props.anime.alt_titles["Official Title"][0].text,
romaji: data.props.anime.title,
english: data.props.anime.alt_titles["Official Title"][1].text
},
synonyms: data.props.anime.alt_titles["Synonym"].map((el: any) => {
return el.text
}),
image: data.props.anime.cover,
cover: data.props.anime.cover,
description: data.props.anime.description,
status: data.props.anime.status.name,
releaseDate: data.props.anime.release_date,
totalEpisodes: data.props.anime.last_episode,
currentEpisode: data.props.anime.last_episode,
genres: data.props.anime.genre_list.map((el: any) => {
return el.name
}),
studios: data.props.anime.production_list.map((el: any) => {
return el.name
}),
type: data.props.anime.type.name,
ageRating: data.props.anime.content_rating.name,
episodes: episodes.map((el: any) => {
return {
id: el.sort,
title: el.title,
number: el.sort,
image: el.cover,
airdate: el.release_date
};
})
}

return response_data;
};

/**
*
* @param episodeId Episode id
*/
override fetchEpisodeSources = async (id: string, episodeNumber: number): Promise<ISource> => {
let data;
try {
let response = await axios.get(`https://marin.moe/anime/${id}/${episodeNumber}`, {
headers: {
Origin: 'https://marin.moe/',
Referer: `https://marin.moe/anime/${id}/${episodeNumber}`,
Cookie: `__ddg1=;__ddg2_=;`,
'User-Agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36',
"x-inertia": true,
"x-inertia-version": "884345c4d568d16e3bb2fb3ae350cca9",
"x-requested-with": "XMLHttpRequest",
},
});
data = await response.data;
} catch (error) {
console.log(error)
}

let response_data = {
sources: data.props.video.data.mirror.map((el: any) => {
return {
url: el.code.file,
quality: el.resolution,
isM3U8: false,
duration: el.code.duration,
thumbnail: el.code.thumbnail
};
}),
sprites: data.props.video.data.mirror[0].code.sprite,
spriteVtt: data.props.video.data.mirror[0].code.vtt,
}

return response_data;
};

/**
*
* @param episodeId Episode id
*/
override fetchEpisodeServers = (episodeId: string): Promise<IEpisodeServer[]> => {
throw new Error('Method not implemented.');
};
}

export default Marin;

(async () => {
let marin = new Marin();
console.log(await marin.fetchEpisodeSources('dewhzcns', 1));
})();