UNPKG

3.2 kBJavaScriptView Raw
1const cheerio = require('cheerio');
2const CloudHttp = require('../libs/http');
3const debug = require('debug')('anime-scraper');
4const html = require('./html');
5const Promise = require('bluebird');
6const _ = require('lodash');
7
8const BASE_URL = 'https://gogoanime.io';
9
10const cHttp = new CloudHttp();
11
12class Page {
13 static fromResponse(response) {
14 return cheerio.load(response.body);
15 }
16
17 static fromUrl(url, options = {}) {
18 return cHttp.request(url, options).then(Page.fromResponse);
19 }
20}
21
22class Episode {
23 constructor({
24 name,
25 url,
26 videoLinks
27 }) {
28 this.name = name || null;
29 this.url = url || null;
30 this.videoLinks = videoLinks || null;
31 }
32
33 fetch() {
34 return Page.fromUrl(this.url).then(html.parseVideo).then((videoLinks) => {
35 this.videoLinks = videoLinks;
36 }).then(() => this);
37 }
38}
39
40class Anime {
41 constructor({
42 name,
43 url,
44 id,
45 summary,
46 genres,
47 released,
48 episodes
49 }) {
50 this.name = name || null;
51 this.url = url || null;
52 this.id = id || null;
53 this.summary = summary || null;
54 this.genres = genres || null;
55 this.released = released || null;
56 this.episodes = episodes || null;
57 debug(`Anime created: ${this}`);
58 }
59
60 fetchEpisodes() {
61 const url = BASE_URL + '/load-list-episode';
62
63 const options = {
64 query: {
65 ep_start: 0,
66 ep_end: 2000,
67 id: this.id,
68 }
69 };
70
71 return Page.fromUrl(url, options).then(html.parseEpisodeListing).then((episodes) => {
72 this.episodes = episodes.map(x => new Episode(x));
73 }).then(() => this);
74 }
75
76 fetchAllEpisodes() {
77 debug(`Fetching all episodes for anime: ${this}`);
78 return Promise.map(this.episodes, episode => episode.fetch(), {
79 concurrency: 1
80 })
81 .then(() => this);
82 }
83
84 fetchInformation() {
85 return Anime.fromUrl(this.url).then((anime) => {
86 _.merge(this, anime);
87 }).then(() => this);
88 }
89
90 toString() {
91 return `${this.name} (${this.id}).`;
92 }
93
94 static fromName(name) {
95
96 return Anime.search(name).then((results) => {
97
98 return results[0]
99 }).then(result => result.toAnime());
100 }
101
102 static fromPage($) {
103 return new Anime(html.parseAnimePage($)).fetchEpisodes();
104 }
105
106 static fromUrl(url) {
107 return Page.fromUrl(url).then(Anime.fromPage);
108 }
109
110 static fromSearchResult(result) {
111 return Anime.fromUrl(result.url);
112 }
113
114 static search(query) {
115 const url = `${BASE_URL}/search.html`;
116
117 const options = {
118 method: 'GET',
119 query: {
120 keyword: query
121 },
122 };
123
124 debug(`Running search for ${query}`);
125
126 return Page.fromUrl(url, options).then(html.parseSearchResults)
127 .then(results => results.map(x => new SearchResult(x)));
128 }
129}
130
131class SearchResult {
132 constructor({
133 name,
134 url
135 }) {
136 this.name = name || null;
137 this.url = url || null;
138 debug(`Search result created: ${this.name}`);
139 }
140
141 toAnime() {
142 return Anime.fromSearchResult(this);
143 }
144}
145
146
147
148module.exports = {
149 Page,
150 Anime,
151 Episode,
152 SearchResult,
153};