import { NextFunction , Request , Response } from 'express' ; import Parser from 'rss-parser' ; import urls from '../utils/urls' ; import { obtainPreviewNews } from '../utils/obtainPreviews' ; import { requestGot } from '../utils/requestCall' ; import RadioStationModel , { RadioStation , } from '../database/models/radiostation.model' ; import ThemeModel , { Theme } from '../database/models/theme.model' ; import ThemeParser from '../utils/animeTheme' ; import { structureThemes } from '../utils/util' ; import { getThemes } from '../utils/util' ; import WaifuModel , { Waifu } from '../database/models/waifu.model' ; import util from 'util' ; import { hashStringMd5 } from '../utils/util' ; import { redisClient } from '../database/connection' ; redisClient . get = util . promisify ( redisClient . get ) ; const themeParser = new ThemeParser ( ) ; type CustomFeed = { foo : string ; } ; type CustomItem = { bar : number ; itunes : { duration : string ; image : string ; } ; 'content:encoded' : string ; 'content:encodedSnippet' : string ; } ; const parser = new Parser ( { customFields : { feed : [ 'foo' ] , item : [ 'bar' ] , } , } ) ; interface News { title ? : string ; url ? : string ; author ? : string ; thumbnail ? : string ; content ? : string ; } interface Podcast { title ? : string ; duration ? : string ; created ? : Date | string ; mp3 ? : string ; } interface rssPage { url : string ; author : string ; content : string ; } export default class UtilsController { async getAnitakume ( req , res , next ) { let feed ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `anitakume_${ hashStringMd5 ( 'anitakume' ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } feed = await parser . parseURL ( urls . BASE_IVOOX ) ; } catch ( err ) { return next ( err ) ; } const podcast = [ ] ; const monthNames = [ 'Enero' , 'Febrero' , 'Marzo' , 'Abril' , 'Mayo' , 'Junio' , 'Julio' , 'Agosto' , 'Septiembre' , 'Octubre' , 'Noviembre' , 'Diciembre' , ] ; feed . items . forEach ( ( item ) => { const date = new Date ( item . pubDate ! ) ; const formattedObject = { title : item . title , duration : item . itunes . duration , created : `${ date . getDate ( ) } de ${ monthNames [ date . getMonth ( ) ] } de ${ date . getFullYear ( ) }` , mp3 : item . enclosure ?. url , } ; podcast . push ( formattedObject ) ; } ) ; if ( podcast . length > 0 ) { if ( redisClient . connected ) { redisClient . set ( `anitakume_${ hashStringMd5 ( 'anitakume' ) }` , JSON . stringify ( { podcast } ) ) ; redisClient . expireat ( `anitakume_${ hashStringMd5 ( 'anitakume' ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } res . status ( 200 ) . json ( { podcast } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getNews ( req , res , next ) { const news = [ ] ; const pagesRss = [ { url : urls . BASE_KUDASAI , author : 'Kudasai' , content : 'content_encoded' } , { url : urls . BASE_RAMENPARADOS , author : 'Ramen para dos' , content : 'content' , } , { url : urls . BASE_CRUNCHYROLL , author : 'Crunchyroll' , content : 'content_encoded' , } , ] ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `news_${ hashStringMd5 ( 'news' ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } for ( const rssPage of pagesRss ) { const feed = await parser . parseURL ( rssPage . url ) ; feed . items . forEach ( ( item ) => { const formattedObject = { title : item . title , url : item . link , author : feed . title ?. includes ( 'Crunchyroll' ) ? 'Crunchyroll' : feed . title , thumbnail : obtainPreviewNews ( item [ 'content:encoded' ] ) , content : item [ 'content:encoded' ] , } ; news . push ( formattedObject ) ; } ) ; } } catch ( err ) { return next ( err ) ; } if ( news . length > 0 ) { if ( redisClient . connected ) { redisClient . set ( `news_${ hashStringMd5 ( 'news' ) }` , JSON . stringify ( { news } ) ) ; redisClient . expireat ( `news_${ hashStringMd5 ( 'news' ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } res . status ( 200 ) . json ( { news } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getImages ( req , res , next ) { const { title } = req . params ; let data ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `images_${ hashStringMd5 ( title ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } data = await requestGot ( `${ urls . BASE_QWANT }t=images&q=${ encodeURIComponent ( title ) }&count=51&locale=es_ES&safesearch=1` , { scrapy : false , parse : true } ) ; } catch ( err ) { return next ( err ) ; } const results = data . data . result . items . map ( ( item ) => { return { type : item . thumb_type , thumbnail : `https:${ item . thumbnail }` , fullsize : `https:${ item . media_fullsize }` , } ; } ) ; if ( results . length > 0 ) { if ( redisClient . connected ) { redisClient . set ( `images_${ hashStringMd5 ( title ) }` , JSON . stringify ( { images : results } ) ) ; redisClient . expireat ( `images_${ hashStringMd5 ( title ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } res . set ( 'Cache-Control' , 'max-age=604800' ) ; res . status ( 200 ) . json ( { images : results } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getVideos ( req , res , next ) { const { channelId } = req . params ; let data ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `videos_${ hashStringMd5 ( channelId ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } data = await requestGot ( `${ urls . BASE_YOUTUBE }${ channelId }&part=snippet,id&order=date&maxResults=50` , { scrapy : false , parse : true } ) ; } catch ( err ) { return next ( err ) ; } const results = data . items . map ( ( item ) => { 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 ) { redisClient . set ( `videos_${ hashStringMd5 ( channelId ) }` , JSON . stringify ( { videos : results } ) ) ; redisClient . expireat ( `videos_${ hashStringMd5 ( channelId ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } res . status ( 200 ) . json ( { videos : results } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getPlaylists ( req , res , next ) { const { playlistId } = req . params ; let data ; try { if ( redisClient . connected ) { const resultQueryRedis = redisClient . get ( `videos_${ hashStringMd5 ( playlistId ) }` ) ; if ( resultQueryRedis ) { const resultRedis = 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 = data . items . map ( ( item ) => { 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 , res , next ) { const { type } = req . params ; let y1 , y2 , y3 ; let data ; try { if ( type === 'learn' ) { data = await requestGot ( `${ urls . BASE_YOUTUBE }UCCyQwSS6m2mVB0-H2FOFJtw&part=snippet,id&order=date&maxResults=50` , { parse : true , scrapy : false } ) ; } else if ( type === 'amv' ) { y1 = await requestGot ( `${ urls . BASE_YOUTUBE }UCkTFkshjAsLMKwhAe1uPC1A&part=snippet,id&order=date&maxResults=25` , { parse : true , scrapy : false } ) ; y2 = await requestGot ( `${ urls . BASE_YOUTUBE }UC2cpvlLeowpqnR6bQofwNew&part=snippet,id&order=date&maxResults=25` , { parse : true , scrapy : false } ) ; } else if ( type === 'produccer' ) { y1 = await requestGot ( `${ urls . BASE_YOUTUBE }UC-5MT-BUxTzkPTWMediyV0w&part=snippet,id&order=date&maxResults=25` , { parse : true , scrapy : false } ) ; y2 = await requestGot ( `${ urls . BASE_YOUTUBE }UCwUeTOXP3DD9DIvHttowuSA&part=snippet,id&order=date&maxResults=25` , { parse : true , scrapy : false } ) ; y3 = await requestGot ( `${ urls . BASE_YOUTUBE }UCA8Vj7nN8bzT3rsukD2ypUg&part=snippet,id&order=date&maxResults=25` , { parse : true , scrapy : false } ) ; } } catch ( err ) { return next ( err ) ; } if ( data && ! y1 && ! y2 && ! y3 ) { const results = data . items . map ( ( item ) => ( { 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 , } ) ) ; res . status ( 200 ) . json ( { videos : results } ) ; } else if ( ! data && y1 && y2 && ! y3 ) { const results = y1 . items . concat ( y2 . items ) . map ( ( item ) => ( { 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 , } ) ) ; res . status ( 200 ) . json ( { videos : results } ) ; } else if ( ! data && y1 && y2 && y3 ) { const results = y1 . items . concat ( y2 . items . concat ( y3 . items ) ) . map ( ( item ) => ( { 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 , } ) ) ; res . status ( 200 ) . json ( { videos : results } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getRadioStations ( req , res , next ) { let data ; try { data = await RadioStationModel . find ( ) ; } catch ( err ) { return next ( err ) ; } const results = data . map ( ( item ) => { return { name : item . name , url : item . url , } ; } ) ; if ( results . length > 0 ) { res . status ( 200 ) . json ( { stations : results } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getAllThemes ( req , res , next ) { let data ; try { data = await ThemeModel . find ( ) ; } catch ( err ) { return next ( err ) ; } const results = data . map ( ( item ) => { return { id : item . id , title : item . title , year : item . year , themes : item . themes , } ; } ) ; if ( results . length > 0 ) { res . status ( 200 ) . json ( { themes : results } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getOpAndEd ( req , res , next ) { const { title } = req . params ; let themes ; try { if ( redisClient . connected ) { const resultQueryRedis = await redisClient . get ( `oped_${ hashStringMd5 ( title ) }` ) ; if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } themes = await structureThemes ( await themeParser . serie ( title ) , true ) ; } catch ( err ) { return next ( err ) ; } if ( themes ) { if ( redisClient . connected ) { redisClient . set ( `oped_${ hashStringMd5 ( title ) }` , JSON . stringify ( { themes } ) ) ; redisClient . expireat ( `oped_${ hashStringMd5 ( title ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } res . status ( 200 ) . json ( { themes } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getThemesYear ( req , res , next ) { const { year } = req . params ; let themes ; let resultQueryRedis ; try { if ( redisClient . connected ) { if ( year ) { resultQueryRedis = await redisClient . get ( `themesyear_${ hashStringMd5 ( year ) }` ) ; } else { resultQueryRedis = await redisClient . get ( `themesyear_${ hashStringMd5 ( 'allYear' ) }` ) ; } if ( resultQueryRedis ) { const resultRedis = JSON . parse ( resultQueryRedis ) ; return res . status ( 200 ) . json ( resultRedis ) ; } } if ( year === undefined ) { themes = await themeParser . allYears ( ) ; } else { themes = await structureThemes ( await themeParser . year ( year ) , false ) ; } } catch ( err ) { return next ( err ) ; } if ( themes . length > 0 ) { if ( redisClient . connected ) { if ( year ) { redisClient . set ( `themesyear_${ hashStringMd5 ( year ) }` , JSON . stringify ( { themes } ) ) ; } else { redisClient . set ( `themesyear_${ hashStringMd5 ( 'allYear' ) }` , JSON . stringify ( { themes } ) ) ; } if ( year ) { redisClient . expireat ( `themesyear_${ hashStringMd5 ( year ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } else { redisClient . expireat ( `themesyear_${ hashStringMd5 ( 'allYear' ) }` , parseInt ( `${ + new Date ( ) / 1000 }` , 10 ) + 7200 ) ; } } res . status ( 200 ) . json ( { themes } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async randomTheme ( req , res , next ) { let data ; try { data = await requestGot ( `${ urls . BASE_THEMEMOE }roulette` , { parse : true , scrapy : false , } ) ; } catch ( err ) { return next ( err ) ; } const random = getThemes ( data . themes ) ; if ( random . length > 0 ) { res . set ( 'Cache-Control' , 'no-store' ) ; res . status ( 200 ) . json ( { random } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getArtist ( req , res , next ) { const { id } = req . params ; let artists ; try { if ( id === undefined ) { artists = await themeParser . artists ( ) ; } else { artists = await structureThemes ( await themeParser . artist ( id ) , false ) ; } } catch ( err ) { return next ( err ) ; } if ( artists . length > 0 ) { res . status ( 200 ) . json ( { artists } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getDestAnimePlatforms ( req , res , next ) { let data ; try { data = await requestGot ( `${ urls . BASE_ARUPPI }res/documents/animelegal/top.json` , { parse : true , scrapy : false } ) ; } catch ( err ) { return next ( err ) ; } const destPlatforms = data . map ( ( item ) => { return { id : item . id , name : item . name , logo : item . logo , link : item . link , } ; } ) ; if ( destPlatforms . length > 0 ) { res . status ( 200 ) . json ( { destPlatforms } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getPlatforms ( req , res , next ) { const { id } = req . params ; let data ; try { if ( id === undefined ) { data = await requestGot ( `${ urls . BASE_ARUPPI }res/documents/animelegal/typeplatforms.json` , { parse : true , scrapy : false } ) ; } else if ( id === 'producers' || id === 'apps' || id === 'publishers' || 'events' ) { data = await requestGot ( `${ urls . BASE_ARUPPI }res/documents/animelegal/type/${ id }.json` , { parse : true , scrapy : false } ) ; } else { data = await requestGot ( `${ urls . BASE_ARUPPI }res/documents/animelegal/type/${ id }.json` , { parse : true , scrapy : false } ) ; } } catch ( err ) { return next ( err ) ; } const platforms = data . map ( ( item ) => { if ( id === undefined ) { return { id : item . id , name : item . name , comming : item . comming || false , cover : item . cover , } ; } else if ( id === 'producers' || id === 'apps' || id === 'publishers' || 'events' ) { return { id : item . id , name : item . name , logo : item . logo , cover : item . cover , description : item . description , type : item . type , moreInfo : item . moreInfo , facebook : item . facebook , twitter : item . twitter , instagram : item . instagram , webInfo : item . webInfo , webpage : item . webpage , } ; } else { return { id : item . id , name : item . name , type : item . type , logo : item . logo , cover : item . cover , webpage : item . webpage , } ; } } ) ; if ( platforms . length > 0 ) { res . status ( 200 ) . json ( { platforms } ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } async getWaifuRandom ( req , res , next ) { let waifuQuery ; let waifuResult ; try { waifuQuery = await WaifuModel . aggregate ( [ { $sample : { size : 1 } } ] ) ; } catch ( err ) { return next ( err ) ; } if ( waifuQuery . length > 0 ) { waifuResult = { id : waifuQuery [ 0 ] . id , name : waifuQuery [ 0 ] . name , weight : waifuQuery [ 0 ] . weight , series : waifuQuery [ 0 ] . series , height : waifuQuery [ 0 ] . height , birthday : waifuQuery [ 0 ] . birthday , likes : waifuQuery [ 0 ] . likes , trash : waifuQuery [ 0 ] . trash , blood_type : waifuQuery [ 0 ] . blood_type , hip : waifuQuery [ 0 ] . hip , bust : waifuQuery [ 0 ] . bust , description : waifuQuery [ 0 ] . description , display_picture : waifuQuery [ 0 ] . display_picture , waist : waifuQuery [ 0 ] . waist , } ; } if ( waifuResult ) { res . set ( 'Cache-Control' , 'no-store' ) ; res . status ( 200 ) . json ( waifuResult ) ; } else { res . status ( 500 ) . json ( { message : 'Aruppi lost in the shell' } ) ; } } }