diff --git a/javascript/anime/src/en/animegg.js b/javascript/anime/src/en/animegg.js new file mode 100644 index 00000000..1e705dd9 --- /dev/null +++ b/javascript/anime/src/en/animegg.js @@ -0,0 +1,220 @@ +const mangayomiSources = [{ + "name": "AnimeGG", + "lang": "en", + "baseUrl": "https://www.animegg.org", + "apiUrl": "", + "iconUrl": "https://www.google.com/s2/favicons?sz=256&domain=https://www.animegg.org/", + "typeSource": "single", + "itemType": 1, + "version": "1.0.0", + "pkgPath": "anime/src/en/animegg.js" +}]; + +class DefaultExtension extends MProvider { + + constructor() { + super(); + this.client = new Client(); + } + + getHeaders(url) { + return { + "Referer": this.source.baseUrl, + "Origin": this.source.baseUrl + } + } + + getPreference(key) { + return new SharedPreferences().get(key); + } + + async requestText(slug) { + var url = `${this.source.baseUrl}${slug}` + var res = await this.client.get(url, this.getHeaders()); + return res.body; + } + async request(slug) { + return new Document(await this.requestText(slug)); + } + + async fetchPopularnLatest(slug) { + var body = await this.request(slug) + var items = body.select("li.fea") + var list = [] + var hasNextPage = true + if (items.length > 0) { + for (var item of items) { + var imageUrl = item.selectFirst('img').getSrc + var linkSection = item.selectFirst('.rightpop').selectFirst('a') + var link = linkSection.getHref + var name = linkSection.text + list.push({ + name, + imageUrl, + link + }); + + } + } + else { + hasNextPage = false + } + return { list, hasNextPage } + } + + async getPopular(page) { + var start = (page - 1) * 25; + var limit = start + 25; + + var category = "" + var pop = parseInt(this.getPreference("animegg_popular_category")) + switch (pop) { + case 1: { + category = "sortBy=createdAt&sortDirection=DESC&"; + break; + } + case 2: { + category = "ongoing=true&"; + break; + } + case 3: { + category = "ongoing=false&"; + break; + } + case 4: { + category = "sortBy=sortLetter&sortDirection=ASC&"; + break; + } + + } + var slug = `/popular-series?${category}start=${start}&limit=${limit}` + return await this.fetchPopularnLatest(slug) + + + } + get supportsLatest() { + throw new Error("supportsLatest not implemented"); + } + async getLatestUpdates(page) { + var start = (page - 1) * 25; + var limit = start + 25; + + var slug = `/releases?start=${start}&limit=${limit}` + return await this.fetchPopularnLatest(slug) + + } + async search(query, page, filters) { + var slug = `/search?q=${query}` + var body = await this.request(slug) + var items = body.select(".moose.page > a") + var list = [] + for (var item of items) { + var imageUrl = item.selectFirst('img').getSrc + var link = item.getHref + var name = item.selectFirst("h2").text + list.push({ + name, + imageUrl, + link + }); + + } + + return { list, hasNextPage: false } + } + + statusCode(status) { + return { + "Ongoing": 0, + "Completed": 1, + }[status] ?? 5; + } + + async getDetail(url) { + var link = this.source.baseUrl + url; + + var body = await this.request(url) + + var media = body.selectFirst(".media") + var title = media.selectFirst("h1").text + var spans = media.selectFirst("p.infoami").select("span") + var statusText = spans[spans.length - 1].text.replace("Status: ", '') + var status = this.statusCode(statusText) + + + var tagscat = media.select(".tagscat > li") + var genre = [] + tagscat.forEach(tag => genre.push(tag.text)) + var description = body.selectFirst("p.ptext").text + var chapters = [] + + var episodesList = body.select(".newmanga > li") + episodesList.forEach(ep => { + var epTitle = ep.selectFirst('i.anititle').text + var epNumber = ep.selectFirst('strong').text.replace(title, "Episode") + var epName = epNumber == epTitle ? epNumber : `${epNumber} - ${epTitle}` + var epUrl = ep.selectFirst("a").getHref + + var scanlator = ""; + var type = ep.select("span.btn-xs") + type.forEach(t => { + scanlator += t.text + ", "; + + }) + scanlator = scanlator.slice(0, -2); + + chapters.push({ name: epName, url: epUrl, scanlator }) + }) + + + return { description, status, genre, chapters, link } + + + + } + + // For anime episode video list + async getVideoList(url) { + var body = await this.request(url) + var iframe = body.selectFirst("iframe") + var src = iframe.attr('src') + + body = await this.requestText(src) + var sKey = "var videoSources = " + var eKey = "var httpProtocol" + var start = body.indexOf(sKey) + sKey.length + var end = body.indexOf(eKey) - 8 + var videoSourcesStr = body.substring(start, end) + let videoSources = eval("(" + videoSourcesStr + ")"); + var streams = [] + var headers = this.getHeaders(); + videoSources.forEach(videoSource => { + var url = this.source.baseUrl +videoSource.file + var quality = videoSource.label + + streams.push({ + url, + originalUrl: url, + quality, + headers + }); + }); + return streams.reverse(); + + } + + getSourcePreferences() { + return [ + { + key: "animegg_popular_category", + listPreference: { + title: 'Preferred popular category', + summary: '', + valueIndex: 0, + entries: ["Popular", "Newest", "Ongoing", "Completed", "Alphabetical"], + entryValues: ["0", "1", "2", "3", "4"] + } + } + ] + } +}