Compare commits

...

39 Commits
v4.0.8 ... v4

Author SHA1 Message Date
Darkangeel_hd 6c44d5a712 Fixed getImages urls
No more "https:https://"
Will this work tomorrow, i don't know
2 years ago
Darkangeel_hd cef7574083 Minor updates
Changed PromoVideos redis keyname, using mal_id now
Changed schedule key TTL from 2 to 6 hours
2 years ago
Darkangeel_hd 7c6307cb1e Expire getRelatedMAL_* faster
TTL set to 1h
Also, forgot to mention on last commit that we changed the key name to a more friendly one, using the mal_id now.
As the relation between mal_id and its content is 1:1 collisions are not possible
That way is easier to identify on the db
2 years ago
Darkangeel_hd 58ac761098 Reimplemented getRelatedAnimesMAL
Reimplemented getRelatedAnimesMAL using jikan v4 and aruppi DB
what a pain in the ass was this one...
2 years ago
Darkangeel_hd 3a633b2ff2 Migrating to jikan v4
moved v3 endpoints to jikan v4
Quick fixes, will review later (as in between a day and 2 years later UwU)
2 years ago
dependabot[bot] e39bb486b0 Bump http-cache-semantics from 4.1.0 to 4.1.1
Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1.
- [Release notes](https://github.com/kornelski/http-cache-semantics/releases)
- [Commits](https://github.com/kornelski/http-cache-semantics/compare/v4.1.0...v4.1.1)

---
updated-dependencies:
- dependency-name: http-cache-semantics
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
dependabot[bot] 189a5bfb79 Bump mongoose from 5.13.13 to 5.13.15
Bumps [mongoose](https://github.com/Automattic/mongoose) from 5.13.13 to 5.13.15.
- [Release notes](https://github.com/Automattic/mongoose/releases)
- [Changelog](https://github.com/Automattic/mongoose/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Automattic/mongoose/compare/5.13.13...5.13.15)

---
updated-dependencies:
- dependency-name: mongoose
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
dependabot[bot] df30fd785e Bump json5 from 1.0.1 to 1.0.2
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
dependabot[bot] 656d4ce1ba Bump express from 4.17.1 to 4.17.3
Bumps [express](https://github.com/expressjs/express) from 4.17.1 to 4.17.3.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.17.3)

---
updated-dependencies:
- dependency-name: express
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
dependabot[bot] a90e522c21 Bump minimatch from 3.0.4 to 3.1.2
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2 years ago
Darkangeel_hd faf0afee8c Updated utils/requestCall
Added new options to spoof user agent
New Aruppi APi user agent
Adapt relevant code to new funcionality

fixed line break on urls.ts
3 years ago
Darkangeel_hd 736ff79707 Update qwant api url 3 years ago
dependabot[bot] 2b4e3d0d7d
Bump minimist from 1.2.5 to 1.2.6 (#58)
Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6.
- [Release notes](https://github.com/substack/minimist/releases)
- [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6)

---
updated-dependencies:
- dependency-name: minimist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
3 years ago
Jesús María fdb744582f
Merge pull request #57 from aruppi/dependabot/npm_and_yarn/got-11.8.5
Bump got from 11.8.3 to 11.8.5
3 years ago
dependabot[bot] c3fa6cd854
Bump got from 11.8.3 to 11.8.5
Bumps [got](https://github.com/sindresorhus/got) from 11.8.3 to 11.8.5.
- [Release notes](https://github.com/sindresorhus/got/releases)
- [Commits](https://github.com/sindresorhus/got/compare/v11.8.3...v11.8.5)

---
updated-dependencies:
- dependency-name: got
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
3 years ago
Angel 868a958e36
Update README.md
Fixed Akiyama logo
Updated copyright year
3 years ago
Jesús María 99d636fa3f Fixed the episode number in recent episodes 4 years ago
Jesús María 361d0553e9 Fixed getEpisodes 4 years ago
Jesús María 08fb60749b Fixed lastEpisodes 4 years ago
Jesús María 5f3720446b Fixed MonosChinos failed queries 4 years ago
Jesús María 6912a2eddd Fixed video request 4 years ago
Jesús María 033b35aee9 Merge branch 'develop' into v4 4 years ago
Jesús María 9ba3e1035e Include updates for security dependant bots 4 years ago
Jesús María 11ed6d5731 Merge branch 'develop' into v4 4 years ago
Jesús María dafe02215a Update dependencies 4 years ago
Jesús María 90cb8bab66
Merge pull request #54 from aruppi/dependabot/npm_and_yarn/path-parse-1.0.7
Bump path-parse from 1.0.6 to 1.0.7
4 years ago
dependabot[bot] 31075ce33d
Bump path-parse from 1.0.6 to 1.0.7
Bumps [path-parse](https://github.com/jbgutierrez/path-parse) from 1.0.6 to 1.0.7.
- [Release notes](https://github.com/jbgutierrez/path-parse/releases)
- [Commits](https://github.com/jbgutierrez/path-parse/commits/v1.0.7)

---
updated-dependencies:
- dependency-name: path-parse
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
4 years ago
Jesús María 5c06108a3e
Merge pull request #50 from aruppi/dependabot/npm_and_yarn/css-what-5.0.1
Bump css-what from 5.0.0 to 5.0.1
4 years ago
dependabot[bot] 78315e4017
Bump css-what from 5.0.0 to 5.0.1
Bumps [css-what](https://github.com/fb55/css-what) from 5.0.0 to 5.0.1.
- [Release notes](https://github.com/fb55/css-what/releases)
- [Commits](https://github.com/fb55/css-what/compare/v5.0.0...v5.0.1)

---
updated-dependencies:
- dependency-name: css-what
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
4 years ago
Jesús María 7be55d1f87
Merge pull request #49 from aruppi/dependabot/npm_and_yarn/normalize-url-4.5.1
Bump normalize-url from 4.5.0 to 4.5.1
4 years ago
dependabot[bot] 3bcdc34012
Bump normalize-url from 4.5.0 to 4.5.1
Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/sindresorhus/normalize-url/releases)
- [Commits](https://github.com/sindresorhus/normalize-url/commits)

---
updated-dependencies:
- dependency-name: normalize-url
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
4 years ago
capitanwesler 24fa86de87 Merge remote-tracking branch 'origin/develop' into v4 4 years ago
capitanwesler a9bca94952 Merge branch 'v4' into origin/develop 4 years ago
capitanwesler 22141c16f8 Encoding URI 4 years ago
capitanwesler 5719ef1b17 Removing encodeURI 4 years ago
capitanwesler f32ca2bdcf 😎 Encoding URI parameters in qwant call 4 years ago
capitanwesler 57dedd3ab5 Setting cache-control in qwant 4 years ago
capitanwesler 0a60814065 😎 Refactoring the getAnimeServers
Adding the possibility to target another source, if one of them doesn't work, if any source doesn't work at all, just return undefined to the data options.
4 years ago
capitanwesler 2afd59cf7a 😎 Changing the version control 4 years ago

@ -1,4 +1,4 @@
# **Aruppi API** (v4.0.8)
# **Aruppi API** (v4.2.2)
> This API has everything about Japan, from anime, music, radio, images, videos ... to japanese culture
>
@ -116,7 +116,7 @@ Currently the Aruppi app on Android is already using the v4.x.x API services fro
</td>
<td align="center">
<a href="https://github.com/Fmaldonado6/Akiyama">
<img src="https://raw.githubusercontent.com/Fmaldonado6/Akiyama/master/images/logo/web-logo.png" width="75px;" alt="Jeluchu"/><br />
<img src="https://raw.githubusercontent.com/Fmaldonado6/Akiyama/master/images/logo/logo.png" width="75px;" alt="Jeluchu"/><br />
<sub>
<b>Akiyama</b>
</sub>
@ -156,4 +156,4 @@ There are also **people who have made contributions** and therefore it is also i
- [Jéluchu](https://github.com/Jeluchu) (Multiplatform Developer, designer, and others)
- [Capitanwesler](https://github.com/capitanwesler) (Backend developer, web developer and others)
Copyright © 2021 [Jéluchu](https://about.jeluchu.com/).
Copyright © 2022 [Jéluchu](https://about.jeluchu.com/).

@ -1,6 +1,6 @@
{
"name": "aruppi",
"version": "4.0.8",
"version": "4.2.2",
"description": "Aruppi is a custom API to obtain data from the Japanese culture for the mobile app",
"main": "./src/api/api.ts",
"scripts": {
@ -54,11 +54,11 @@
"compose-middleware": "^5.0.1",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"got": "^11.8.2",
"express": "^4.17.3",
"got": "^11.8.5",
"helmet": "^4.5.0",
"mongodb": "^3.6.6",
"mongoose": "^5.12.5",
"mongoose": "^5.13.15",
"redis": "^3.1.2",
"rss-parser": "^3.12.0",
"tough-cookie": "^4.0.0",

@ -1,5 +1,5 @@
import {NextFunction, Request, Response} from 'express';
import {requestGot} from '../utils/requestCall';
import { NextFunction, Request, Response } from 'express';
import { requestGot } from '../utils/requestCall';
import {
imageUrlToBase64,
jkanimeInfo,
@ -9,10 +9,10 @@ import {
videoServersMonosChinos,
videoServersTioAnime,
} from '../utils/util';
import {transformUrlServer} from '../utils/transformerUrl';
import AnimeModel, {Anime as ModelA} from '../database/models/anime.model';
import { transformUrlServer } from '../utils/transformerUrl';
import AnimeModel, { Anime as ModelA } from '../database/models/anime.model';
import util from 'util';
import {hashStringMd5} from '../utils/util';
import { hashStringMd5 } from '../utils/util';
import {
animeExtraInfo,
getAnimeVideoPromo,
@ -20,7 +20,7 @@ import {
getRelatedAnimesMAL,
} from '../utils/util';
import urls from '../utils/urls';
import {redisClient} from '../database/connection';
import { redisClient } from '../database/connection';
// @ts-ignore
redisClient.get = util.promisify(redisClient.get);
@ -80,8 +80,8 @@ interface Movie {
export default class AnimeController {
async schedule(req: Request, res: Response, next: NextFunction) {
const {day} = req.params;
let data: any;
const { day } = req.params;
let info: any;
try {
if (redisClient.connected) {
@ -96,7 +96,7 @@ export default class AnimeController {
}
}
data = await requestGot(`${urls.BASE_JIKAN}schedule/${day}`, {
info = await requestGot(`${urls.BASE_JIKAN}schedules?filter=${day}`, {
parse: true,
scrapy: false,
});
@ -104,10 +104,10 @@ export default class AnimeController {
return next(err);
}
const animeList: Schedule[] = data[day].map((item: Schedule) => ({
title: item.title,
const animeList: Schedule[] = info.data.map((item: any) => ({
title: item.titles.find((x: { type: string; }) => x.type === "Default").title,
malid: item.mal_id,
image: item.image_url,
image: item.images.jpg.image_url,
}));
if (animeList.length > 0) {
@ -116,14 +116,14 @@ export default class AnimeController {
redisClient.set(
`schedule_${hashStringMd5(day)}`,
JSON.stringify({day: animeList}),
JSON.stringify({ day: animeList }),
);
/* After 24hrs expire the key. */
/* After 6hrs expire the key. */
redisClient.expireat(
redisClient.expire(
`schedule_${hashStringMd5(day)}`,
parseInt(`${+new Date() / 1000}`, 10) + 7200,
+ 21600,
);
}
@ -131,13 +131,13 @@ export default class AnimeController {
day: animeList,
});
} else {
res.status(500).json({message: 'Aruppi lost in the shell'});
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async top(req: Request, res: Response, next: NextFunction) {
const {type, subtype, page} = req.params;
let data: any;
const { type, subtype, page } = req.params;
let info: any;
try {
if (redisClient.connected) {
@ -161,12 +161,12 @@ export default class AnimeController {
}
if (subtype !== undefined) {
data = await requestGot(
`${urls.BASE_JIKAN}top/${type}/${page}/${subtype}`,
{parse: true, scrapy: false},
info = await requestGot(
`${urls.BASE_JIKAN}top/${type}?filter=${subtype}&page=${page}`,
{ parse: true, scrapy: false },
);
} else {
data = await requestGot(`${urls.BASE_JIKAN}top/${type}/${page}`, {
info = await requestGot(`${urls.BASE_JIKAN}top/${type}?page=${page}`, {
parse: true,
scrapy: false,
});
@ -175,11 +175,12 @@ export default class AnimeController {
return next(err);
}
const top: Top[] = data.top.map((item: Top) => ({
rank: item.rank,
title: item.title,
const top: Top[] = info.data.map((item: any, index: number) => ({
// A little hacky way to fix null ranks
rank: item.rank || index + 1 + (info.pagination.current_page-1)*info.pagination.items.per_page,
title: item.titles.find((x: { type: string; }) => x.type === "Default").title,
url: item.url,
image_url: item.image_url,
image_url: item.images.jpg.image_url,
type: type,
subtype: subtype,
page: page,
@ -192,12 +193,12 @@ export default class AnimeController {
if (subtype) {
redisClient.set(
`top_${hashStringMd5(`${type}:${subtype}:${page}`)}`,
JSON.stringify({top}),
JSON.stringify({ top }),
);
} else {
redisClient.set(
`top_${hashStringMd5(`${type}:${page}`)}`,
JSON.stringify({top}),
JSON.stringify({ top }),
);
}
@ -216,9 +217,9 @@ export default class AnimeController {
}
}
return res.status(200).json({top});
return res.status(200).json({ top });
} else {
return res.status(400).json({message: 'Aruppi lost in the shell'});
return res.status(400).json({ message: 'Aruppi lost in the shell' });
}
}
@ -229,6 +230,7 @@ export default class AnimeController {
data = await requestGot(`${urls.BASE_ANIMEFLV}api/animes/list`, {
parse: true,
scrapy: false,
spoof: true,
});
} catch (err) {
return next(err);
@ -243,14 +245,15 @@ export default class AnimeController {
}));
if (animes.length > 0) {
res.status(200).send({animes});
res.status(200).send({ animes });
} else {
res.status(500).json({message: 'Aruppi lost in the shell'});
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async getLastEpisodes(req: Request, res: Response, next: NextFunction) {
let $: cheerio.Root;
let lastEpisodes;
let episodes: Episode[] = [];
let animeList: any[] = [];
@ -267,45 +270,23 @@ export default class AnimeController {
}
}
$ = await requestGot(`${urls.BASE_MONOSCHINOS}`, {
scrapy: true,
parse: false,
lastEpisodes = await requestGot(`${urls.BASE_ARUPPI_MONOSCHINOS}lastest`, {
scrapy: false,
parse: true,
});
} catch (err) {
return next(err);
}
let getLastest: any = $!('.container .caps .container')[0];
$!(getLastest)
.find('.row article')
.each((index: number, element: cheerio.Element) => {
let el: cheerio.Cheerio = $(element);
let title: string | undefined = el
.find('.Title')
.html()
?.split('\t')[0];
let img: any = el.find('.Image img').attr('src');
let type: any = el.find('.Image figure span').text();
type = type.substring(1, type.length);
let nEpisode: any = el.find('.dataEpi .episode').text();
nEpisode = parseInt(nEpisode.split('\n')[1]);
let id: any = el.find('a').attr('href');
id = id.split('/')[4];
id = id.split('-');
id.splice(id.length - 2, 2);
id = `${id.join('-')}-episodio-${nEpisode}`;
let anime = {
id: `ver/${id}`,
title,
image: img,
episode: nEpisode,
};
animeList.push(anime);
for (const anime of lastEpisodes) {
animeList.push({
id: `ver/${anime.id}`,
title: anime.title,
image: anime.image,
episode: anime.no,
});
}
for (const anime of animeList) {
episodes.push({
@ -323,7 +304,7 @@ export default class AnimeController {
redisClient.set(
`lastEpisodes_${hashStringMd5('lastEpisodes')}`,
JSON.stringify({episodes}),
JSON.stringify({ episodes }),
);
/* After 24hrs expire the key. */
@ -338,12 +319,12 @@ export default class AnimeController {
episodes,
});
} else {
res.status(500).json({message: 'Aruppi lost in the shell'});
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async getContentTv(req: Request, res: Response, next: NextFunction) {
const {type, page} = req.params;
const { type, page } = req.params;
const url = 'tv';
let data: any;
@ -395,7 +376,7 @@ export default class AnimeController {
redisClient.set(
`contentTv_${hashStringMd5(`${type}:${page}`)}`,
JSON.stringify({animes}),
JSON.stringify({ animes }),
);
/* After 24hrs expire the key. */
@ -410,12 +391,12 @@ export default class AnimeController {
animes,
});
} else {
res.status(500).json({message: 'Aruppi lost in the shell'});
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async getContentSpecial(req: Request, res: Response, next: NextFunction) {
const {type, page} = req.params;
const { type, page } = req.params;
const url = 'special';
let data: any;
@ -467,7 +448,7 @@ export default class AnimeController {
redisClient.set(
`contentSpecial_${hashStringMd5(`${type}:${page}`)}`,
JSON.stringify({animes}),
JSON.stringify({ animes }),
);
/* After 24hrs expire the key. */
@ -482,12 +463,12 @@ export default class AnimeController {
animes,
});
} else {
res.status(500).json({message: 'Aruppi lost in the shell'});
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async getContentOva(req: Request, res: Response, next: NextFunction) {
const {type, page} = req.params;
const { type, page } = req.params;
const url = 'ova';
let data: any;
@ -539,7 +520,7 @@ export default class AnimeController {
redisClient.set(
`contentOva_${hashStringMd5(`${type}:${page}`)}`,
JSON.stringify({animes}),
JSON.stringify({ animes }),
);
/* After 24hrs expire the key. */
@ -554,12 +535,12 @@ export default class AnimeController {
animes,
});
} else {
res.status(500).json({message: 'Aruppi lost in the shell'});
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async getContentMovie(req: Request, res: Response, next: NextFunction) {
const {type, page} = req.params;
const { type, page } = req.params;
const url = 'movies';
let data: any;
@ -611,7 +592,7 @@ export default class AnimeController {
redisClient.set(
`contentMovie_${hashStringMd5(`${type}:${page}`)}`,
JSON.stringify({animes}),
JSON.stringify({ animes }),
);
/* After 24hrs expire the key. */
@ -626,12 +607,12 @@ export default class AnimeController {
animes,
});
} else {
res.status(500).json({message: 'Aruppi lost in the shell'});
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async getEpisodes(req: Request, res: Response, next: NextFunction) {
const {title} = req.params;
const { title } = req.params;
let searchAnime: ModelA | null;
let episodes: any;
@ -649,7 +630,7 @@ export default class AnimeController {
}
searchAnime = await AnimeModel.findOne({
$or: [{title: {$eq: title}}, {title: {$eq: `${title} (TV)`}}],
$or: [{ title: { $eq: title } }, { title: { $eq: `${title} (TV)` } }],
});
} catch (err) {
return next(err);
@ -676,7 +657,7 @@ export default class AnimeController {
redisClient.set(
`episodes_${hashStringMd5(title)}`,
JSON.stringify({episodes}),
JSON.stringify({ episodes }),
);
/* After 24hrs expire the key. */
@ -687,14 +668,14 @@ export default class AnimeController {
);
}
res.status(200).json({episodes});
res.status(200).json({ episodes });
} else {
res.status(500).json({message: 'Aruppi lost in the shell'});
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async getServers(req: Request, res: Response, next: NextFunction) {
const {id} = req.params;
const { id } = req.params;
let data: any;
try {
@ -710,15 +691,36 @@ export default class AnimeController {
}
}
if (
id.split('/')[0] === 'ver' &&
id.split('-').indexOf('espanol') !== -1
) {
data = await videoServersMonosChinos(id);
} else if (id.split('/')[0] === 'ver') {
let indicator = false;
if (id.split('/')[0] === 'ver' && !indicator) {
data = await videoServersTioAnime(id);
} else {
data = await videoServersJK(id);
if (!data.name) {
indicator = true;
}
}
if (id.split('/')[0] === 'ver' && !indicator) {
data = await videoServersMonosChinos(id);
if (!data.name) {
console.log(data.name);
indicator = true;
}
}
if (!indicator) {
data = undefined;
indicator = true;
/*
This part is just for handling the error
if the two above doesn't complete the operation
does not make sense to have the getServers from
JKAnime.
*/
}
if (data) {
@ -727,7 +729,7 @@ export default class AnimeController {
redisClient.set(
`servers_${hashStringMd5(id)}`,
JSON.stringify({servers: data}),
JSON.stringify({ servers: data }),
);
/* After 24hrs expire the key. */
@ -738,9 +740,9 @@ export default class AnimeController {
);
}
res.status(200).json({servers: data});
res.status(200).json({ servers: data });
} else {
res.status(500).json({message: 'Aruppi lost in the shell'});
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
} catch (err) {
return next(err);
@ -752,7 +754,7 @@ export default class AnimeController {
let animeResult: any;
try {
animeQuery = await AnimeModel.aggregate([{$sample: {size: 1}}]);
animeQuery = await AnimeModel.aggregate([{ $sample: { size: 1 } }]);
} catch (err) {
return next(err);
}
@ -774,7 +776,7 @@ export default class AnimeController {
res.set('Cache-Control', 'no-store');
res.status(200).json(animeResult);
} else {
res.status(500).json({message: 'Aruppi lost in the shell'});
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
}

@ -104,7 +104,7 @@ export default class DirectoryController {
async getSeason(req: Request, res: Response, next: NextFunction) {
const { year, type } = req.params;
let data: any;
let info: any;
try {
if (redisClient.connected) {
@ -119,7 +119,7 @@ export default class DirectoryController {
}
}
data = await requestGot(`${urls.BASE_JIKAN}season/${year}/${type}`, {
info = await requestGot(`${urls.BASE_JIKAN}seasons/${year}/${type}`, {
scrapy: false,
parse: true,
});
@ -127,10 +127,10 @@ export default class DirectoryController {
return next(err);
}
const season: TypeAnime[] = data.anime.map((item: any) => {
const season: TypeAnime[] = info.data.map((item: any) => {
return {
title: item.title,
image: item.image_url,
title: item.titles.find((x: { type: string; }) => x.type === "Default").title,
image: item.images.jpg.image_url,
genres: item.genres.map((genre: any) => genre.name),
};
});
@ -161,7 +161,7 @@ export default class DirectoryController {
}
async allSeasons(req: Request, res: Response, next: NextFunction) {
let data: any;
let info: any;
try {
if (redisClient.connected) {
@ -176,7 +176,7 @@ export default class DirectoryController {
}
}
data = await requestGot(`${urls.BASE_JIKAN}season/archive`, {
info = await requestGot(`${urls.BASE_JIKAN}seasons`, {
parse: true,
scrapy: false,
});
@ -184,7 +184,7 @@ export default class DirectoryController {
return next(err);
}
const archive: Archive[] = data.archive.map((item: any) => {
const archive: Archive[] = info.data.map((item: any) => {
return {
year: item.year,
seasons: item.seasons,
@ -215,7 +215,7 @@ export default class DirectoryController {
}
async laterSeasons(req: Request, res: Response, next: NextFunction) {
let data: any;
let info: any;
try {
if (redisClient.connected) {
@ -230,7 +230,7 @@ export default class DirectoryController {
}
}
data = await requestGot(`${urls.BASE_JIKAN}season/later`, {
info = await requestGot(`${urls.BASE_JIKAN}seasons/upcoming`, {
parse: true,
scrapy: false,
});
@ -238,10 +238,10 @@ export default class DirectoryController {
return next(err);
}
const future: Season[] = data.anime.map((item: any) => {
const future: Season[] = info.data.map((item: any) => {
return {
title: item.title,
image: item.image_url,
title: item.titles.find((x: { type: string; }) => x.type === "Default").title,
image: item.images.jpg.image_url,
malink: item.url,
};
});
@ -294,6 +294,7 @@ export default class DirectoryController {
const extraInfo: any = await animeExtraInfo(resultQuery!.mal_id);
resultAnime = {
//aruppi_key: hashStringMd5(title),
title: resultQuery?.title,
poster: resultQuery?.poster,
synopsis: resultQuery?.description,

@ -231,8 +231,10 @@ export default class UtilsController {
}
data = await requestGot(
`${urls.BASE_QWANT}count=51&q=${title}&t=images&safesearch=1&locale=es_ES&uiv=4`,
{ scrapy: false, parse: true },
`${urls.BASE_QWANT}t=images&q=${encodeURIComponent(
title,
)}&count=51&locale=es_ES&safesearch=1`,
{ scrapy: false, parse: true, spoof: true, },
);
} catch (err) {
return next(err);
@ -241,8 +243,8 @@ export default class UtilsController {
const results: any[] = data.data.result.items.map((item: any) => {
return {
type: item.thumb_type,
thumbnail: `https:${item.thumbnail}`,
fullsize: `https:${item.media_fullsize}`,
thumbnail: `${item.thumbnail}`,
fullsize: `${item.media_fullsize}`,
};
});
@ -263,6 +265,7 @@ export default class UtilsController {
);
}
res.set('Cache-Control', 'max-age=604800');
res.status(200).json({ images: results });
} else {
res.status(500).json({ message: 'Aruppi lost in the shell' });
@ -327,6 +330,65 @@ export default class UtilsController {
}
}
async getPlaylists(req: Request, res: Response, next: NextFunction) {
const { playlistId } = req.params;
let data: any;
try {
if (redisClient.connected) {
const resultQueryRedis: any = redisClient.get(
`videos_${hashStringMd5(playlistId)}`,
);
if (resultQueryRedis) {
const resultRedis: any = JSON.parse(resultQueryRedis);
return res.status(200).json(resultRedis);
}
}
data = await requestGot(
`${urls.BASE_YOUTUBE_PLAYLIST}${playlistId}`,
{ scrapy: false, parse: true },
);
} catch (err) {
return next(err);
}
const results: any[] = data.items.map((item: any) => {
return {
title: item.snippet.title,
videoId: item.id.videoId,
thumbDefault: item.snippet.thumbnails.default.url,
thumbMedium: item.snippet.thumbnails.medium.url,
thumbHigh: item.snippet.thumbnails.high.url,
};
});
if (results.length > 0) {
if (redisClient.connected) {
/!* Set the key in the redis cache. *!/
redisClient.set(
`videos_${hashStringMd5(playlistId)}`,
JSON.stringify({ videos: results }),
);
/!* After 24hrs expire the key. *!/
redisClient.expireat(
`videos_${hashStringMd5(playlistId)}`,
parseInt(`${+new Date() / 1000}`, 10) + 7200,
);
}
res.status(200).json({ videos: results });
} else {
res.status(500).json({ message: 'Aruppi lost in the shell' });
}
}
async getSectionVideos(req: Request, res: Response, next: NextFunction) {
const { type } = req.params;
let y1: any, y2: any, y3: any;
@ -575,6 +637,7 @@ export default class UtilsController {
data = await requestGot(`${urls.BASE_THEMEMOE}roulette`, {
parse: true,
scrapy: false,
spoof: true,
});
} catch (err) {
return next(err);

@ -26,7 +26,7 @@ routes.get('/api/v4/', (req: Request, res: Response) => {
res.json({
message: 'Aruppi /api - 🎏',
author: 'Jéluchu',
version: '4.0.8',
version: '4.2.2',
credits: 'The bitch loves /apis that offers data to Aruppi App',
entries: [
{
@ -52,6 +52,7 @@ routes.get('/api/v4/', (req: Request, res: Response) => {
Search: '/api/v4/search/:title',
Images: '/api/v4/images/:query',
Videos: '/api/v4/videos/:channelId',
Playlist: '/api/v4/playlistVideos/:playlistId',
'Type Videos': '/api/v4/sectionedVideos/:type',
Radios: '/api/v4/radio',
'All Themes': '/api/v4/allThemes',
@ -104,6 +105,7 @@ routes.get('/api/v4/anitakume', utilsController.getAnitakume);
routes.get('/api/v4/news', utilsController.getNews);
routes.get('/api/v4/images/:title', utilsController.getImages);
routes.get('/api/v4/videos/:channelId', utilsController.getVideos);
routes.get('/api/v4/playlistVideos/:playlistId', utilsController.getPlaylists);
routes.get('/api/v4/sectionedVideos/:type', utilsController.getSectionVideos);
routes.get('/api/v4/radio', utilsController.getRadioStations);
routes.get('/api/v4/allThemes', utilsController.getAllThemes);

@ -285,6 +285,7 @@ async function redditocall(href: string) {
const resp = await requestGot(urls.REDDIT_ANIMETHEMES + href + '.json', {
parse: true,
scrapy: false,
spoof: true,
});
return cheerio.load(getHTML(resp.data.content_html));

@ -1,28 +1,52 @@
import got from 'got';
import cheerio from 'cheerio';
import { CookieJar } from 'tough-cookie';
// @ts-ignore
import * as got_pjson from 'got/package.json'
const pjson = require('../../package.json');
const cookieJar = new CookieJar();
const aruppi_options: any = {
cookieJar,
'headers': {
'user-agent': `Aruppi-API/${pjson.version} ${got_pjson.name}/${got_pjson.version}`,
'x-client': 'aruppi-api'
},
};
interface Options {
scrapy: boolean;
parse: boolean;
scrapy?: boolean,
parse?: boolean,
spoof?: boolean
}
export const requestGot = async (
url: string,
options?: Options,
url: string,
options?: Options,
): Promise<any> => {
if (options !== undefined) {
if (options.scrapy) {
const response = await got(url, { cookieJar });
return await cheerio.load(response.body);
}
const got_options: any = {...got.defaults.options, ...aruppi_options}
if (options) {
if (options.spoof != null) {
got_options.headers["user-agent"] = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:71.0) Gecko/20100101 Firefox/69.0";
delete got_options.headers['x-client'];
if (!options.spoof)
got_options.headers['user-agent'] = got.defaults.options.headers['user-agent'];
} else if (process.env.ALPI_KEY && (new URL(url)).hostname.match(/\.jeluchu\.xyz$/)) {
got_options.headers['x-aruppi-key'] = process.env.ALPI_KEY;
}
if (options.scrapy) {
const response = await got(url, got_options);
return cheerio.load(response.body);
}
if (options.parse) {
return await got(url, { cookieJar }).json();
if (options.parse) {
got_options.responseType = 'json';
const response = await got(url, got_options);
return response.body;
}
}
} else {
return await got.get(url, { cookieJar });
}
const response = await got.get(url, got_options);
return response;
};

@ -6,9 +6,9 @@ export default {
BASE_JKANIME: 'https://jkanime.net/',
BASE_ANIMEFLV_JELU: 'https://aruppi.jeluchu.xyz/apis/animeflv/v1/',
BASE_YOUTUBE: 'https://aruppi.jeluchu.xyz/api/Youtube/?channelId=',
BASE_JIKAN: 'https://aruppi.jeluchu.xyz/apis/jikan/v3/',
BASE_IVOOX:
'https://www.ivoox.com/podcast-anitakume_fg_f1660716_filtro_1.xml',
BASE_YOUTUBE_PLAYLIST: 'https://aruppi.jeluchu.xyz/api/Youtube/playlist/?playlistId=',
BASE_JIKAN: 'https://aruppi.jeluchu.xyz/apis/jikan/v4/',
BASE_IVOOX: 'https://www.ivoox.com/podcast-anitakume_fg_f1660716_filtro_1.xml',
BASE_KUDASAI: 'https://somoskudasai.com/feed/',
BASE_RAMENPARADOS: 'https://ramenparados.com/category/noticias/anime/feed/',
BASE_CRUNCHYROLL: 'https://www.crunchyroll.com/newsrss?lang=esES',
@ -16,7 +16,8 @@ export default {
ANIMEFLV_SEARCH: 'https://animeflv.net/browse?',
SEARCH_DIRECTORY: 'https://animeflv.net/browse?order=title&page=',
BASE_EPISODE_IMG_URL: 'https://cdn.animeflv.net/screenshots/',
BASE_QWANT: 'https://api.qwant.com/search/images?',
BASE_QWANT: 'https://api.qwant.com/v3/search/images?',
REDDIT_ANIMETHEMES: 'https://reddit.com/r/AnimeThemes/wiki/',
BASE_THEMEMOE: 'https://themes.moe/api/',
BASE_ARUPPI_MONOSCHINOS: 'https://aruppi.jeluchu.xyz/apis/monoschinos/',
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save