import { NextFunction , Request , Response } from 'express' ; import { requestGot } from '../utils/requestCall' ; import { imageUrlToBase64 , jkanimeInfo , monoschinosInfo , tioanimeInfo , videoServersJK , videoServersMonosChinos , videoServersTioAnime , } from '../utils/util' ; 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 { animeExtraInfo , getAnimeVideoPromo , getAnimeCharacters , getRelatedAnimesMAL , } from '../utils/util' ; import urls from '../utils/urls' ; import { redisClient } from '../database/connection' ; redisClient . get = util . promisify ( redisClient . get ) ; interface Schedule { title : string ; mal_id : number ; image_url : any ; } interface Anime { index : string ; animeId : string ; title : string ; id : string ; type : string ; } interface Top { rank : string ; title : string ; url : string ; image_url : string ; type : string ; subtype : string ; page : number ; score : string ; } interface Episode { id : string ; title : string ; image : string ; episode : number ; servers : { id : string ; url : string ; direct : boolean ; } ; } interface Movie { id : string ; title : string ; type : string ; page : string ; banner : string ; image : string ; synopsis : string ; status : string ; rate : string ; genres : string [ ] ; episodes : object [ ] ; } export default class AnimeController { async schedule ( req , res , next ) { const { day } = req . params ; let data ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `schedule_${ hashStringMd5 ( day ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } data = await requestGot ( `${ urls . BASE_JIKAN }schedule/${ day }` , { parse : true , scrapy : false , } ) ; } catch ( err ) { return next ( err ) ; } const animeList = data [ day ] . map ( ( item ) => ( { title : item . title , malid : item . mal_id , image : item . image_url , } ) ) ; if ( animeList . length > 0 ) { if ( redisClient . connected ) { redisClient . set ( `schedule_${ hashStringMd5 ( day ) }` , JSON . stringify ( { day : animeList } ) ) ; redisClient . expireat ( `schedule_${ hashStringMd5 ( day ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } res . status ( 200 ) . json ( { day : animeList , } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async top ( req , res , next ) { const { type , subtype , page } = req . params ; let data ; try { if ( redisClient . connected ) { let resultQueryRedis ; if ( subtype ) { resultQueryRedis = await redisClient . get ( `top_${ hashStringMd5 ( `${ type }:${ subtype }:${ page }` ) }` ) ; } else { resultQueryRedis = await redisClient . get ( `top_${ hashStringMd5 ( `${ type }:${ page }` ) }` ) ; } if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } if ( subtype !== undefined ) { data = await requestGot ( `${ urls . BASE_JIKAN }top/${ type }/${ page }/${ subtype }` , { parse : true , scrapy : false } ) ; } else { data = await requestGot ( `${ urls . BASE_JIKAN }top/${ type }/${ page }` , { parse : true , scrapy : false , } ) ; } } catch ( err ) { return next ( err ) ; } const top = data . top . map ( ( item ) => ( { rank : item . rank , title : item . title , url : item . url , image_url : item . image_url , type : type , subtype : subtype , page : page , score : item . score , } ) ) ; if ( top . length > 0 ) { if ( redisClient . connected ) { if ( subtype ) { redisClient . set ( `top_${ hashStringMd5 ( `${ type }:${ subtype }:${ page }` ) }` , JSON . stringify ( { top } ) ) ; } else { redisClient . set ( `top_${ hashStringMd5 ( `${ type }:${ page }` ) }` , JSON . stringify ( { top } ) ) ; } if ( subtype ) { redisClient . expireat ( `top_${ hashStringMd5 ( `${ type }:${ subtype }:${ page }` ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } else { redisClient . expireat ( `top_${ hashStringMd5 ( `${ type }:${ page }` ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } } return res . status ( 200 ) . json ( { top } ) ; } else { return res . status ( 400 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getAllAnimes ( req , res , next ) { let data ; try { data = await requestGot ( `${ urls . BASE_ANIMEFLV }api/animes/list` , { parse : true , scrapy : false , } ) ; } catch ( err ) { return next ( err ) ; } const animes = data . map ( ( item ) => ( { index : item [ 0 ] , animeId : item [ 3 ] , title : item [ 1 ] , id : item [ 2 ] , type : item [ 4 ] , } ) ) ; if ( animes . length > 0 ) { res . status ( 200 ) . send ( { animes } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getLastEpisodes ( req , res , next ) { let lastEpisodes ; let episodes = [ ] ; let animeList = [ ] ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `lastEpisodes_${ hashStringMd5 ( 'lastEpisodes' ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } lastEpisodes = await requestGot ( `${ urls . BASE_ARUPPI_MONOSCHINOS }lastest` , { scrapy : false , parse : true , } ) ; } catch ( err ) { return next ( err ) ; } 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 ( { id : anime . id , title : anime . title , image : await imageUrlToBase64 ( anime . image ) , episode : anime . episode , servers : await videoServersMonosChinos ( anime . id ) , } ) ; } if ( episodes . length > 0 ) { if ( redisClient . connected ) { redisClient . set ( `lastEpisodes_${ hashStringMd5 ( 'lastEpisodes' ) }` , JSON . stringify ( { episodes } ) ) ; redisClient . expireat ( `lastEpisodes_${ hashStringMd5 ( 'lastEpisodes' ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 1800 ) ; } res . status ( 200 ) . json ( { episodes , } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getContentTv ( req , res , next ) { const { type , page } = req . params ; const url = 'tv' ; let data ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `contentTv_${ hashStringMd5 ( `${ type }:${ page }` ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } data = await requestGot ( `${ urls . BASE_ANIMEFLV_JELU }${ url . charAt ( 0 ) . toUpperCase ( ) + url . slice ( 1 ) }/${ type }/${ page }` , { parse : true , scrapy : false , } ) ; } catch ( err ) { return next ( err ) ; } const animes = data [ url ] . map ( ( item ) => { return { id : item . id , title : item . title , type : url , page : page , banner : item . banner , image : item . poster , synopsis : item . synopsis , status : item . debut , rate : item . rating , genres : item . genres . map ( ( genre ) => genre ) , episodes : item . episodes . map ( ( episode ) => episode ) , } ; } ) ; if ( animes . length > 0 ) { if ( redisClient . connected ) { redisClient . set ( `contentTv_${ hashStringMd5 ( `${ type }:${ page }` ) }` , JSON . stringify ( { animes } ) ) ; redisClient . expireat ( `contentTv_${ hashStringMd5 ( `${ type }:${ page }` ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } res . status ( 200 ) . json ( { animes , } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getContentSpecial ( req , res , next ) { const { type , page } = req . params ; const url = 'special' ; let data ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `contentSpecial_${ hashStringMd5 ( `${ type }:${ page }` ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } data = await requestGot ( `${ urls . BASE_ANIMEFLV_JELU }${ url . charAt ( 0 ) . toUpperCase ( ) + url . slice ( 1 ) }/${ type }/${ page }` , { parse : true , scrapy : false , } ) ; } catch ( err ) { return next ( err ) ; } const animes = data [ url ] . map ( ( item ) => { return { id : item . id , title : item . title , type : url , page : page , banner : item . banner , image : item . poster , synopsis : item . synopsis , status : item . debut , rate : item . rating , genres : item . genres . map ( ( genre ) => genre ) , episodes : item . episodes . map ( ( episode ) => episode ) , } ; } ) ; if ( animes . length > 0 ) { if ( redisClient . connected ) { redisClient . set ( `contentSpecial_${ hashStringMd5 ( `${ type }:${ page }` ) }` , JSON . stringify ( { animes } ) ) ; redisClient . expireat ( `contentSpecial_${ hashStringMd5 ( `${ type }:${ page }` ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } res . status ( 200 ) . json ( { animes , } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getContentOva ( req , res , next ) { const { type , page } = req . params ; const url = 'ova' ; let data ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `contentOva_${ hashStringMd5 ( `${ type }:${ page }` ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } data = await requestGot ( `${ urls . BASE_ANIMEFLV_JELU }${ url . charAt ( 0 ) . toUpperCase ( ) + url . slice ( 1 ) }/${ type }/${ page }` , { parse : true , scrapy : false , } ) ; } catch ( err ) { return next ( err ) ; } const animes = data [ url ] . map ( ( item ) => { return { id : item . id , title : item . title , type : url , page : page , banner : item . banner , image : item . poster , synopsis : item . synopsis , status : item . debut , rate : item . rating , genres : item . genres . map ( ( genre ) => genre ) , episodes : item . episodes . map ( ( episode ) => episode ) , } ; } ) ; if ( animes . length > 0 ) { if ( redisClient . connected ) { redisClient . set ( `contentOva_${ hashStringMd5 ( `${ type }:${ page }` ) }` , JSON . stringify ( { animes } ) ) ; redisClient . expireat ( `contentOva_${ hashStringMd5 ( `${ type }:${ page }` ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } res . status ( 200 ) . json ( { animes , } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getContentMovie ( req , res , next ) { const { type , page } = req . params ; const url = 'movies' ; let data ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `contentMovie_${ hashStringMd5 ( `${ type }:${ page }` ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } data = await requestGot ( `${ urls . BASE_ANIMEFLV_JELU }${ url . charAt ( 0 ) . toUpperCase ( ) + url . slice ( 1 ) }/${ type }/${ page }` , { parse : true , scrapy : false , } ) ; } catch ( err ) { return next ( err ) ; } const animes = data [ url ] . map ( ( item ) => { return { id : item . id , title : item . title , type : url , page : page , banner : item . banner , image : item . poster , synopsis : item . synopsis , status : item . debut , rate : item . rating , genres : item . genres . map ( ( genre ) => genre ) , episodes : item . episodes . map ( ( episode ) => episode ) , } ; } ) ; if ( animes . length > 0 ) { if ( redisClient . connected ) { redisClient . set ( `contentMovie_${ hashStringMd5 ( `${ type }:${ page }` ) }` , JSON . stringify ( { animes } ) ) ; redisClient . expireat ( `contentMovie_${ hashStringMd5 ( `${ type }:${ page }` ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } res . status ( 200 ) . json ( { animes , } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getEpisodes ( req , res , next ) { const { title } = req . params ; let searchAnime ; let episodes ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `episodes_${ hashStringMd5 ( title ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } searchAnime = await AnimeModel . findOne ( { $or : [ { title : { $eq : title } } , { title : { $eq : `${ title } (TV)` } } ] , } ) ; } catch ( err ) { return next ( err ) ; } switch ( searchAnime ?. source ) { case 'jkanime' : episodes = await jkanimeInfo ( searchAnime ?. id , searchAnime ?. mal_id ) ; break ; case 'monoschinos' : episodes = await monoschinosInfo ( searchAnime ?. id , searchAnime ?. mal_id ) ; break ; case 'tioanime' : episodes = await tioanimeInfo ( searchAnime ?. id , searchAnime ?. mal_id ) ; break ; default : episodes = undefined ; break ; } if ( episodes ) { if ( redisClient . connected ) { redisClient . set ( `episodes_${ hashStringMd5 ( title ) }` , JSON . stringify ( { episodes } ) ) ; redisClient . expireat ( `episodes_${ hashStringMd5 ( title ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } res . status ( 200 ) . json ( { episodes } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getServers ( req , res , next ) { const { id } = req . params ; let data ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `servers_${ hashStringMd5 ( id ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } let indicator = false ; if ( id . split ( '/' ) [ 0 ] === 'ver' && ! indicator ) { data = await videoServersTioAnime ( 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 ; } if ( data ) { if ( redisClient . connected ) { redisClient . set ( `servers_${ hashStringMd5 ( id ) }` , JSON . stringify ( { servers : data } ) ) ; redisClient . expireat ( `servers_${ hashStringMd5 ( id ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } res . status ( 200 ) . json ( { servers : data } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } catch ( err ) { return next ( err ) ; } } async getRandomAnime ( req , res , next ) { let animeQuery ; let animeResult ; try { animeQuery = await AnimeModel . aggregate ( [ { $sample : { size : 1 } } ] ) ; } catch ( err ) { return next ( err ) ; } animeResult = { title : animeQuery [ 0 ] . title || null , poster : animeQuery [ 0 ] . poster || null , synopsis : animeQuery [ 0 ] . description || null , type : animeQuery [ 0 ] . type || null , rating : animeQuery [ 0 ] . score || null , genres : animeQuery [ 0 ] . genres || null , moreInfo : [ await animeExtraInfo ( animeQuery [ 0 ] . mal_id ) ] , promo : await getAnimeVideoPromo ( animeQuery [ 0 ] . mal_id ) , characters : await getAnimeCharacters ( animeQuery [ 0 ] . mal_id ) , related : await getRelatedAnimesMAL ( animeQuery [ 0 ] . mal_id ) , } ; if ( animeResult ) { res . set ( 'Cache-Control' , 'no-store' ) ; res . status ( 200 ) . json ( animeResult ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } }