Skip to content

Commit

Permalink
AsuraScans | 4.1.8
Browse files Browse the repository at this point in the history
  • Loading branch information
TheNetsky committed Aug 20, 2024
1 parent 53e0ec3 commit 23f4639
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 63 deletions.
48 changes: 26 additions & 22 deletions src/AsuraScans/AsuraScans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ import {
SourceStateManager
} from '@paperback/types/lib'

const simpleUrl = require('simple-url')
import simpleUrl from 'simple-url'

Check failure on line 45 in src/AsuraScans/AsuraScans.ts

View workflow job for this annotation

GitHub Actions / Bundle and Publish Sources (20.x)

Could not find a declaration file for module 'simple-url'. '/home/runner/work/community-extensions/community-extensions/node_modules/simple-url/url.js' implicitly has an 'any' type.

const ASURASCANS_DOMAIN = 'https://asuracomic.net'
const ASURASCANS_API_DOMAIN = 'https://gg.asuracomic.net'

export const AsuraScansInfo: SourceInfo = {
version: '4.1.7',
version: '4.1.8',
name: 'AsuraScans',
description: 'Extension that pulls manga from AsuraScans',
author: 'Seyden',
Expand Down Expand Up @@ -113,7 +113,7 @@ export class AsuraScans implements ChapterProviding, HomePageSectionsProviding,
request.headers = {
...(request.headers ?? {}), ...{
'user-agent': await this.requestManager.getDefaultUserAgent(),
referer: `${url}/`,
referer: `${url}/`
}
}

Expand All @@ -123,14 +123,14 @@ export class AsuraScans implements ChapterProviding, HomePageSectionsProviding,
request.url = simpleUrl.create(path)
}

if (path.host.includes(`localhost`)) {
if (path.host.includes('localhost')) {
const url: string = await this.getBaseUrl()
path.host = simpleUrl.parse(url, true).host
request.url = simpleUrl.create(path)
}

if (isImgLink(request.url)) {
let overrideUrl: string = await this.stateManager.retrieve('Domain')
const overrideUrl: string = await this.stateManager.retrieve('Domain')
if (overrideUrl && overrideUrl != this.baseUrl) {
const basePath: any = simpleUrl.parse(this.baseUrl, true)
const overridePath: any = simpleUrl.parse(overrideUrl, true)
Expand Down Expand Up @@ -166,7 +166,7 @@ export class AsuraScans implements ChapterProviding, HomePageSectionsProviding,
/**
* The language code which this source supports.
*/
language: string = '🇬🇧'
language = '🇬🇧'

/**
* The pathname between the domain and the manga.
Expand Down Expand Up @@ -214,14 +214,14 @@ export class AsuraScans implements ChapterProviding, HomePageSectionsProviding,
selectorFunc: ($: CheerioStatic) => $('div.w-full', $('h3:contains(Latest Updates)')?.parent()?.next()),
titleSelectorFunc: ($: CheerioStatic, element: CheerioElement) => $('span.font-medium', element).text().trim(),
subtitleSelectorFunc: ($: CheerioStatic, element: CheerioElement) => {
let obj = $('div.text-sm', element).first()
let hiddenObj = $('div.hidden', obj)
const obj = $('div.text-sm', element).first()
const hiddenObj = $('div.hidden', obj)
if (hiddenObj.length != 0)
return hiddenObj.text().trim()
return obj.text().trim()
},
getViewMoreItemsFunc: (page: string) => `page/${page}`,
sortIndex: 20,
sortIndex: 20
},
'top_alltime': {
...DefaultHomeSectionData,
Expand Down Expand Up @@ -250,16 +250,16 @@ export class AsuraScans implements ChapterProviding, HomePageSectionsProviding,
}

// Ugly workaround to fasten up migrations and updates, paperback doesnt support any other way for not double requesting
mangaDataRequests: { [Key: string]: { expires: number, data: Promise<string> } } = { }
mangaDataRequests: { [Key: string]: { expires: number, data: Promise<string> } } = {}

async getMangaRequest(mangaId: string): Promise<string> {
let request = this.mangaDataRequests[mangaId]
const request = this.mangaDataRequests[mangaId]
if (request && request.expires > Date.now()) {
return request.data
}

for (const key in this.mangaDataRequests) {
let tempRequest = this.mangaDataRequests[key]
const tempRequest = this.mangaDataRequests[key]
if (tempRequest!.expires < Date.now()) {
delete this.mangaDataRequests[key]
}
Expand Down Expand Up @@ -344,8 +344,13 @@ export class AsuraScans implements ChapterProviding, HomePageSectionsProviding,
}

async getSearchTags(): Promise<TagSection[]> {
const data = await this.loadRequestData(`${ASURASCANS_API_DOMAIN}/api/series/filters`)
return this.parser.parseTags(data)
try {
const data = await this.loadRequestData(`${ASURASCANS_API_DOMAIN}/api/series/filters`)
return this.parser.parseTags(JSON.parse(data)
)
} catch (error) {
throw new Error(error as any)
}
}

async getSearchResults(query: SearchRequest, metadata: any): Promise<PagedResults> {
Expand All @@ -355,8 +360,7 @@ export class AsuraScans implements ChapterProviding, HomePageSectionsProviding,
}
let manga: PartialSourceManga[] = []

while (manga.length == 0)
{
while (manga.length == 0) {
result = await this.search(metadata, query)
metadata = result.metadata
manga = result.manga
Expand Down Expand Up @@ -385,7 +389,7 @@ export class AsuraScans implements ChapterProviding, HomePageSectionsProviding,
const manga: PartialSourceManga[] = []
for (const result of results) {
if (chapterTag) {
const chapterCount = parseInt(chapterTag.id.replace(`chapters:`, ''))
const chapterCount = parseInt(chapterTag.id.replace('chapters:', ''))
const chapterCountRegex = result.subtitle?.match(/(\d+)/)
if (!chapterCountRegex || chapterCountRegex?.[1] && parseInt(chapterCountRegex[1]) < chapterCount)
continue
Expand All @@ -400,8 +404,8 @@ export class AsuraScans implements ChapterProviding, HomePageSectionsProviding,
}

metadata = !this.parser.isLastPage($, query?.title ? 'search_request' : 'view_more')
? { page: page + 1 }
: undefined
? { page: page + 1 }
: undefined
return {
metadata,
manga
Expand Down Expand Up @@ -467,7 +471,7 @@ export class AsuraScans implements ChapterProviding, HomePageSectionsProviding,
}

async getViewMoreItems(homepageSectionId: string, metadata: any): Promise<PagedResults> {
throw new Error(`Not implemented yet!`)
throw new Error('Not implemented yet!')

/*const page: number = metadata?.page ?? 1
Expand All @@ -491,7 +495,7 @@ export class AsuraScans implements ChapterProviding, HomePageSectionsProviding,
})*/
}

async loadRequestData(url: string, method: string = 'GET'): Promise<string> {
async loadRequestData(url: string, method = 'GET'): Promise<string> {
const request = App.createRequest({
url,
method
Expand All @@ -502,7 +506,7 @@ export class AsuraScans implements ChapterProviding, HomePageSectionsProviding,
return response.data as string
}

async loadCheerioData(url: string, method: string = 'GET'): Promise<CheerioStatic> {
async loadCheerioData(url: string, method = 'GET'): Promise<CheerioStatic> {
return this.cheerio.load(await this.loadRequestData(url, method), { _useHtmlParser2: true })
}

Expand Down
7 changes: 7 additions & 0 deletions src/AsuraScans/AsuraScansInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,11 @@ export interface StatusTypes {
DROPPED: string;
SEASONEND: string;
COMINGSOON: string;
}

export interface Filters {
types: any[];
genres: any[];
statuses: any[];
order: any[];
}
115 changes: 74 additions & 41 deletions src/AsuraScans/AsuraScansParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ChapterDetails,
PartialSourceManga,
SourceManga,
Tag,
TagSection
} from '@paperback/types'

Expand All @@ -12,10 +13,14 @@ import {
} from './AsuraScansHelper'

import entities = require('entities')
import {
FilterItem,

Check failure on line 17 in src/AsuraScans/AsuraScansParser.ts

View workflow job for this annotation

GitHub Actions / Bundle and Publish Sources (20.x)

Module '"./AsuraScansInterfaces"' has no exported member 'FilterItem'.
Filters
} from './AsuraScansInterfaces'

export class AsuraScansParser {
async parseMangaDetails(data: string, mangaId: string, source: any): Promise<SourceManga> {
const obj = extractMangaData(data.replace(/\\"/g, '"').replace(/\\\\"/g, '\\"'), "comic") ?? ''
const obj = extractMangaData(data.replace(/\\"/g, '"').replace(/\\\\"/g, '\\"'), 'comic') ?? ''
if (obj == '') {
throw new Error(`Failed to parse comic object for manga ${mangaId}`) // If null, throw error, else parse data to json.
}
Expand All @@ -35,7 +40,7 @@ export class AsuraScansParser {
const rating = comicObj.comic.rating

const slug = comicObj.comic.slug?.trim()
if (slug) {
if (slug) {
await source.setMangaSlug(mangaId, `series/${slug}`)
}

Expand Down Expand Up @@ -69,7 +74,7 @@ export class AsuraScansParser {
App.createTagSection({
id: '0',
label: 'genres',
tags: comicObj.comic.genres.map((tag: any) => App.createTag( { id: `genres:${tag.id.toString()}`, label: tag.name } ))
tags: comicObj.comic.genres.map((tag: any) => App.createTag({ id: `genres:${tag.id.toString()}`, label: tag.name }))
})
]

Expand All @@ -91,23 +96,23 @@ export class AsuraScansParser {

async parseChapterList(data: string, mangaId: string, source: any): Promise<Chapter[]> {
const tempData = data.replace(/\\"/g, '"').replace(/\\\\"/g, '\\"')
let obj = extractMangaData(tempData, "comic") ?? ''
let obj = extractMangaData(tempData, 'comic') ?? ''
if (obj == '') {
throw new Error(`Failed to parse comic object for manga ${mangaId}`) // If null, throw error, else parse data to json.
}

const comicObj = JSON.parse(obj)

obj = extractMangaData(tempData, "chapters") ?? ''
obj = extractMangaData(tempData, 'chapters') ?? ''
if (obj == '') {
throw new Error(`Failed to parse chapters object for manga ${mangaId}`) // If null, throw error, else parse data to json.
}

const chaptersObj = JSON.parse(obj)

const slug = comicObj.comic.slug?.trim()
let mangaUrl: string = ''
if (slug) {
let mangaUrl = ''
if (slug) {
mangaUrl = `series/${slug}`
await source.setMangaSlug(mangaId, mangaUrl)
}
Expand All @@ -118,8 +123,7 @@ export class AsuraScansParser {

const chapters: Chapter[] = []
let sortingIndex = 0
for (const chapter of chaptersObj.chapters.reverse())
{
for (const chapter of chaptersObj.chapters.reverse()) {
const id = chapter.id.toString()
if (!id || typeof id === 'undefined') {
throw new Error(`Could not parse out ID when getting chapters for postId:${mangaId}`)
Expand Down Expand Up @@ -167,44 +171,73 @@ export class AsuraScansParser {
})
}

parseTags(data: string): TagSection[] {
const tagSections: any[] = [
{ id: '0', label: 'chapters', tags: [
App.createTag({ id: 'chapters:10', label: '+10' }),
App.createTag({ id: 'chapters:20', label: '+20' }),
App.createTag({ id: 'chapters:30', label: '+30' }),
App.createTag({ id: 'chapters:40', label: '+40' }),
App.createTag({ id: 'chapters:50', label: '+50' }),
App.createTag({ id: 'chapters:60', label: '+60' }),
App.createTag({ id: 'chapters:70', label: '+70' }),
App.createTag({ id: 'chapters:80', label: '+80' }),
App.createTag({ id: 'chapters:90', label: '+90' }),
App.createTag({ id: 'chapters:100', label: '+100' }),
App.createTag({ id: 'chapters:150', label: '+150' }),
App.createTag({ id: 'chapters:200', label: '+200' }),
App.createTag({ id: 'chapters:250', label: '+250' }),
]},
{ id: '1', label: 'genres', tags: [] },
{ id: '2', label: 'status', tags: [] },
{ id: '3', label: 'type', tags: [] },
{ id: '4', label: 'order', tags: [] }
parseTags(filters: Filters): TagSection[] {

// Predefined chapters tags
const predefinedChaptersTags: Tag[] = [
{ id: 'chapters:10', label: '+10' },
{ id: 'chapters:20', label: '+20' },
{ id: 'chapters:30', label: '+30' },
{ id: 'chapters:40', label: '+40' },
{ id: 'chapters:50', label: '+50' },
{ id: 'chapters:60', label: '+60' },
{ id: 'chapters:70', label: '+70' },
{ id: 'chapters:80', label: '+80' },
{ id: 'chapters:90', label: '+90' },
{ id: 'chapters:100', label: '+100' },
{ id: 'chapters:150', label: '+150' },
{ id: 'chapters:200', label: '+200' },
{ id: 'chapters:250', label: '+250' }
]

const filters = JSON.parse(data)
filters.types.forEach((type: any) => { tagSections[3].tags.push(App.createTag({ id: `type:${type.id.toString()}`, label: type.name })) })
filters.genres.forEach((type: any) => { tagSections[1].tags.push(App.createTag({ id: `genres:${type.id.toString()}`, label: type.name })) })
filters.statuses.forEach((type: any) => { tagSections[2].tags.push(App.createTag({ id:`status:${type.id.toString()}`, label: type.name })) })
filters.order.forEach((type: any) => { tagSections[4].tags.push(App.createTag({ id: `order:${type}`, label: type })) })
const createTags = (filterItems: FilterItem[], prefix: string): Tag[] => {
return filterItems.map(item => ({
id: `${prefix}:${item.id ?? item.value}`, // Use `id` or `value` for `order` items
label: item.name
}))
}

return tagSections.map((x) => App.createTagSection(x))
const tagSections: TagSection[] = [
// Tag section for genres
App.createTagSection({
id: '0',
label: 'genres',
tags: createTags(filters.genres, 'genres').map(x => App.createTag(x))
}),
// Tag section for status
App.createTagSection({
id: '1',
label: 'status',
tags: createTags(filters.statuses, 'status').map(x => App.createTag(x))
}),
// Tag section for types
App.createTagSection({
id: '2',
label: 'type',
tags: createTags(filters.types, 'type').map(x => App.createTag(x))
}),
// Tag section for order
App.createTagSection({
id: '3',
label: 'order',
tags: createTags(filters.order.map(order => ({ id: order.value, name: order.name })), 'order').map(x => App.createTag(x))
}),
// Predefined chapters tag section
App.createTagSection({
id: '4',
label: 'chapters',
tags: predefinedChaptersTags.map(x => App.createTag(x))
})
]
return tagSections
}

async parseSearchResults($: CheerioSelector, source: any): Promise<any[]> {
const results: any[] = []

const mangas = $('a', $('h3:contains(Series list)')?.parent()?.next()?.next())
if (!mangas.length) {
console.log(`Unable to parse search results!`)
console.log('Unable to parse search results!')
return results
}

Expand Down Expand Up @@ -245,10 +278,10 @@ export class AsuraScansParser {
const path: string = ($('a', manga).attr('href') ?? '').replace(/\/$/, '').split('/').slice(-2).shift() ?? ''
const postId = $('a', manga).attr('rel')
const mangaId: string = source.usePostIds
? (isNaN(Number(postId))
? await source.slugToPostId(slug, path)
: postId)
: slug
? (isNaN(Number(postId))
? await source.slugToPostId(slug, path)
: postId)
: slug

if (!mangaId || !title) {
console.log(`Failed to parse homepage sections for ${source.baseUrl}`)
Expand Down

0 comments on commit 23f4639

Please sign in to comment.