import cheerio from 'cheerio' ; import { requestGot } from './requestCall' ; import urls from './urls' ; export default class ThemeParser { animes : any [ ] = [ ] ; $ : any = '' ; async all ( ) { try { this . animes = [ ] ; this . $ = await redditocall ( 'year_index' ) ; return await this . parseLinks ( ) ; } catch ( err ) { console . log ( err ) ; } } async allYears ( ) { try { this . animes = [ ] ; this . $ = await redditocall ( 'year_index' ) ; return await this . parseYears ( ) ; } catch ( err ) { console . log ( err ) ; } } async serie ( title ) { try { this . animes = [ ] ; this . $ = await redditocall ( 'anime_index' ) ; return await this . parseSerie ( title ) ; } catch ( err ) { console . log ( err ) ; } } async artists ( ) { try { this . animes = [ ] ; this . $ = await redditocall ( 'artist' ) ; return await this . parseArtists ( ) ; } catch ( err ) { console . log ( err ) ; } } async artist ( id ) { try { this . animes = [ ] ; this . $ = await redditocall ( `artist/${ id }` ) ; return await this . parseArtist ( ) ; } catch ( err ) { console . log ( err ) ; } } async random ( ) { try { this . animes = [ ] ; this . $ = await redditocall ( 'anime_index' ) ; return await this . parseRandom ( ) ; } catch ( err ) { console . log ( err ) ; } } async year ( date ) { let animes = [ ] ; this . $ = await redditocall ( date ) ; this . $ ( 'h3' ) . each ( ( index , element ) => { let parsed = this . parseAnime ( this . $ ( element ) ) ; parsed . year = date ; animes . push ( parsed ) ; } ) ; return animes ; } parseRandom ( ) { return new Promise ( async ( resolve ) => { let data = this . $ ( 'p a' ) ; const origin = '1' ; let randomize = Math . round ( Math . random ( ) * ( data . length - 1 - origin ) + parseInt ( origin ) ) ; this . $ = await redditocall ( this . $ ( 'p a' ) [ randomize ] . attribs . href . split ( '/r/AnimeThemes/wiki/' ) [ 1 ] . split ( '#wiki' ) [ 0 ] ) ; let rand = Math . round ( Math . random ( ) * this . $ ( 'h3' ) . length - 1 ) ; let parsed = this . parseAnime ( this . $ ( 'h3' ) [ rand ] ) ; resolve ( parsed ) ; } ) ; } parseYears ( ) { return new Promise ( async ( resolve ) => { let years = [ ] ; this . $ ( 'h3 a' ) . each ( ( index , element ) => { years . push ( { id : this . $ ( element ) . attr ( 'href' ) . split ( '/' ) [ 4 ] , name : this . $ ( element ) . text ( ) , } ) ; } ) ; resolve ( years ) ; } ) ; } parseArtists ( ) { return new Promise ( async ( resolve ) => { let promises = [ ] ; let data = this . $ ( 'p a' ) . filter ( ( x ) => x > 0 ) ; for ( let i = 0 ; i < data . length ; i ++ ) { promises . push ( { id : data [ i ] . children [ 0 ] . parent . attribs . href . split ( '/' ) [ 5 ] , name : data [ i ] . children [ 0 ] . data , } ) ; if ( i === data . length - 1 ) { resolve ( promises ) ; } } } ) ; } parseArtist ( ) { return new Promise ( async ( resolve ) => { let promises = [ ] ; let data = this . $ ( 'h3' ) ; for ( let i = 0 ; i < data . length ; i ++ ) { let parsed = await this . parseAnime ( data [ i ] ) ; promises . push ( parsed ) ; if ( i === data . length - 1 ) { resolve ( promises ) ; } } } ) ; } parseSerie ( title ) { return new Promise ( async ( resolve ) => { let data = this . $ ( 'p a' ) ; for ( let i = 0 ; i < data . length ; i ++ ) { let serieElement = data [ i ] . children [ 0 ] . data ; if ( serieElement . split ( ' (' ) [ 0 ] === title ) { let year = this . $ ( 'p a' ) [ i ] . attribs . href . split ( '/r/AnimeThemes/wiki/' ) [ 1 ] . split ( '#wiki' ) [ 0 ] ; this . $ = await redditocall ( this . $ ( 'p a' ) [ i ] . attribs . href . split ( '/r/AnimeThemes/wiki/' ) [ 1 ] . split ( '#wiki' ) [ 0 ] ) ; for ( let i = 0 ; i < this . $ ( 'h3' ) . length ; i ++ ) { if ( this . $ ( 'h3' ) [ i ] . children [ 0 ] . children [ 0 ] . data === title ) { let parsed = this . parseAnime ( this . $ ( 'h3' ) [ i ] ) ; parsed . year = year ; resolve ( parsed ) ; } } } } } ) ; } parseLinks ( ) { return new Promise ( async ( resolve ) => { let years = this . $ ( 'h3 a' ) ; for ( let i = 0 ; i < years . length ; i ++ ) { let yearElement = years [ i ] ; await this . year ( this . $ ( yearElement ) . attr ( 'href' ) . split ( '/' ) [ 4 ] ) . then ( async ( animes ) => { this . animes = this . animes . concat ( animes ) ; if ( i === years . length - 1 ) { resolve ( this . animes ) ; } } ) ; } } ) ; } parseAnime ( element ) { let el = this . $ ( element ) . find ( 'a' ) ; let title = this . $ ( el ) . text ( ) ; let mal_id = this . $ ( el ) . attr ( 'href' ) . split ( '/' ) [ 4 ] ; let next = this . $ ( element ) . next ( ) ; let theme = { id : mal_id , title , } ; if ( this . $ ( next ) . prop ( 'tagName' ) === 'TABLE' ) { theme . themes = this . parseTable ( this . $ ( next ) ) ; } else if ( this . $ ( next ) . prop ( 'tagName' ) === 'P' ) { theme . themes = this . parseTable ( this . $ ( next ) . next ( ) ) ; } return theme ; } parseTable ( element ) { if ( this . $ ( element ) . prop ( 'tagName' ) !== 'TABLE' ) { return this . parseTable ( this . $ ( element ) . next ( ) ) ; } let themes = [ ] ; this . $ ( element ) . find ( 'tbody' ) . find ( 'tr' ) . each ( ( index , element ) => { let name = replaceAll ( this . $ ( element ) . find ( 'td' ) . eq ( 0 ) . text ( ) , '&quot;' , '"' ) ; let link = this . $ ( element ) . find ( 'td' ) . eq ( 1 ) . find ( 'a' ) . attr ( 'href' ) ; let linkDesc = this . $ ( element ) . find ( 'td' ) . eq ( 1 ) . find ( 'a' ) . text ( ) ; let episodes = this . $ ( element ) . find ( 'td' ) . eq ( 2 ) . text ( ) . length > 0 ? this . $ ( element ) . find ( 'td' ) . eq ( 2 ) . text ( ) : '' ; let notes = this . $ ( element ) . find ( 'td' ) . eq ( 3 ) . text ( ) . length > 0 ? this . $ ( element ) . find ( 'td' ) . eq ( 3 ) . text ( ) : '' ; themes . push ( { name , link , desc : linkDesc , type : name . startsWith ( 'OP' ) ? `OP${ name [ 2 ] }` : name . startsWith ( 'ED' ) ? `ED${ name [ 2 ] }` : 'OP/ED' , episodes , notes , } ) ; } ) ; return themes ; } } async function redditocall ( href ) { const resp = await requestGot ( urls . REDDIT_ANIMETHEMES + href + '.json' , { parse : true , scrapy : false , } ) ; return cheerio . load ( getHTML ( resp . data . content_html ) ) ; } function getHTML ( str ) { let html = replaceAll ( str , '&lt;' , '<' ) ; html = replaceAll ( html , '&gt;' , '>' ) ; return html ; } function replaceAll ( str , find , replace ) { return str . replace ( new RegExp ( find , 'g' ) , replace ) ; }