Skip to content

Commit

Permalink
add methodscans, leviatanscans and hiperdex
Browse files Browse the repository at this point in the history
  • Loading branch information
Yentis committed Aug 22, 2020
1 parent f8d1a2a commit a051ce7
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 17 deletions.
4 changes: 4 additions & 0 deletions src/classes/sites/baseSite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export abstract class BaseSite {
title: Cheerio | undefined
loggedIn = true

canSearch (): boolean {
return true
}

checkLogin (): void {
// Do nothing
}
Expand Down
4 changes: 4 additions & 0 deletions src/classes/sites/genkan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export class Genkan extends BaseSite {
this.siteType = siteType
}

canSearch (): boolean {
return this.siteType !== SiteType.MethodScans
}

getImage (): string {
return this.image?.css('background-image').replace(new RegExp('url\\("?', 'g'), this.getUrl()).replace(new RegExp('"?\\)', 'g'), '') || ''
}
Expand Down
4 changes: 4 additions & 0 deletions src/classes/sites/mangadex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ export class MangaDex extends BaseSite {
this.checkLogin()
}

canSearch (): boolean {
return this.loggedIn
}

checkLogin (): void {
this.search('together with the rain').then(results => {
this.loggedIn = !(results instanceof Error)
Expand Down
38 changes: 36 additions & 2 deletions src/classes/sites/wordpress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,15 @@ export class WordPress extends BaseSite {

readUrl (url: string): Promise<Manga> {
return new Promise((resolve, reject) => {
axios.get(url).then(response => {
axios.get(url).then(async response => {
const $ = cheerio.load(response.data)
this.chapter = $('.wp-manga-chapter a').first()

if (this.siteType === SiteType.HiperDEX) {
const mangaId = $('.rating-post-id').first().attr('value') || ''
await this.readChapters(mangaId)
} else {
this.chapter = $('.wp-manga-chapter a').first()
}
this.image = $('.summary_image img').first()
this.title = $('.post-title').first()

Expand All @@ -38,6 +44,34 @@ export class WordPress extends BaseSite {
})
}

readChapters (mangaId: string): Promise<void> {
return new Promise(resolve => {
const data = qs.stringify({
action: 'manga_get_chapters',
manga: mangaId
})

const config: AxiosRequestConfig = {
method: 'post',
url: `${this.getUrl()}/wp-admin/admin-ajax.php`,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data
}

axios(config).then((response) => {
const $ = cheerio.load(response.data)
this.chapter = $('.wp-manga-chapter a').first()

resolve()
}).catch(error => {
console.error(error)
resolve()
})
})
}

search (query: string): Promise<Error | Manga[]> {
return new Promise(resolve => {
const data = qs.stringify({
Expand Down
16 changes: 11 additions & 5 deletions src/enums/siteEnum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@ export enum SiteType {
FirstKissManga = '1stkissmanga.com',
Mangakakalot = 'mangakakalot.com',
MangaDex = 'mangadex.org',
MangaKomi = 'mangakomi.com'
MangaKomi = 'mangakomi.com',
MethodScans = 'methodscans.com',
LeviatanScans = 'leviatanscans.com',
HiperDEX = 'hiperdex.com'
}

export enum SiteName {
'manganelo.com' = 'Manganelo',
'kkjscans.co' = 'KKJScans',
'kkjscans.co' = 'KKJ Scans',
'webtoons.com' = 'Webtoons',
'hatigarmscanz.net' = 'HatigarmScans',
'1stkissmanga.com' = '1stKissManga',
'hatigarmscanz.net' = 'Hatigarm Scans',
'1stkissmanga.com' = '1st Kiss Manga',
'mangakakalot.com' = 'Mangakakalot',
'mangadex.org' = 'MangaDex',
'mangakomi.com' = 'MangaKomi'
'mangakomi.com' = 'Manga Komi',
'methodscans.com' = 'Method Scans',
'leviatanscans.com' = 'Leviatan Scans',
'hiperdex.com' = 'HiperDEX'
}
10 changes: 5 additions & 5 deletions src/pages/Index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@

<q-btn no-caps class="q-mt-lg full-width manga-dropdown" v-if="searchResults.length > 0" :label="title || 'Selected manga'">
<q-menu auto-close :max-width="$q.platform.is.mobile ? '60%' : '40%'" max-height="40%" v-model="searchDropdownShown">
<q-list>
<q-list separator>
<q-item v-for="manga in searchResults" :key="manga.url" clickable @click="url = manga.url; title = manga.title">
<q-item-section avatar>
<q-img contain class="manga-image-search" :src="manga.image"></q-img>
Expand Down Expand Up @@ -122,16 +122,16 @@
<q-toolbar-title>Supported sites</q-toolbar-title>
</q-toolbar>
<q-card-section class="q-pa-none">
<q-list :class="{ 'text-center': $q.platform.is.mobile }">
<q-list separator :class="{ 'text-center': $q.platform.is.mobile }">
<q-item
clickable
v-for="site in siteMap"
:key="site.siteType"
:class="{ 'bg-warning': !site.loggedIn, 'text-black': !site.loggedIn && $q.dark.isActive }"
:class="{ 'bg-warning': !site.canSearch(), 'text-black': !site.canSearch() && $q.dark.isActive }"
@click="site.loggedIn ? onLinkClick(site.getUrl()) : openLogin(site.getLoginUrl())">
<q-item-section>
<q-item-label :class="{ 'full-width': $q.platform.is.mobile }">{{ siteNames[site.siteType] }}</q-item-label>
<q-item-label v-if="!site.loggedIn" :class="{ 'text-grey-8': $q.dark.isActive }" caption>Search disabled | Click to login</q-item-label>
<q-item-label v-if="!site.canSearch()" :class="{ 'text-grey-8': $q.dark.isActive }" caption>Search disabled{{ !site.loggedIn ? ' | Click to login' : '' }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
Expand Down Expand Up @@ -173,7 +173,7 @@ function mangaSort (a: Manga, b: Manga): number {
}
function siteSort (a: BaseSite, b: BaseSite): number {
if (!a.loggedIn && b.loggedIn) {
if (!a.canSearch() && b.canSearch()) {
return -1
} else if (!b.loggedIn && a.loggedIn) {
return 1
Expand Down
5 changes: 4 additions & 1 deletion src/services/siteService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ const siteMap = new Map<SiteType, BaseSite>([
[SiteType.FirstKissManga, new WordPress(SiteType.FirstKissManga)],
[SiteType.MangaKomi, new WordPress(SiteType.MangaKomi)],
[SiteType.Mangakakalot, new Mangakakalot()],
[SiteType.MangaDex, new MangaDex()]
[SiteType.MangaDex, new MangaDex()],
[SiteType.MethodScans, new Genkan(SiteType.MethodScans)],
[SiteType.LeviatanScans, new Genkan(SiteType.LeviatanScans)],
[SiteType.HiperDEX, new WordPress(SiteType.HiperDEX)]
])

export function checkLogins (): void {
Expand Down
121 changes: 117 additions & 4 deletions test/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const DEV = false

if (DEV) {
describe('Dev', () => {
it(SiteType.Webtoons, () => {
return testSearchWebtoons()
it(SiteType.HiperDEX, () => {
return testSearchHiperDEX()
})
})
} else {
Expand Down Expand Up @@ -52,6 +52,18 @@ if (DEV) {
it(SiteType.MangaKomi, () => {
return testMangakomi()
})

it(SiteType.MethodScans, () => {
return testMethodScans()
})

it(SiteType.LeviatanScans, () => {
return testLeviatanScans()
})

it(SiteType.HiperDEX, () => {
return testHiperDEX()
})
})

describe('Search query', () => {
Expand Down Expand Up @@ -91,6 +103,18 @@ if (DEV) {
it(SiteType.MangaKomi, () => {
return testSearchMangaKomi()
})

it(SiteType.MethodScans, () => {
return testSearchMethodScans()
})

it(SiteType.LeviatanScans, () => {
return testSearchLeviatanScans()
})

it(SiteType.HiperDEX, () => {
return testSearchHiperDEX()
})
})
}

Expand All @@ -99,10 +123,10 @@ function testManganelo (): Promise<void> {
getMangaInfo('https://manganelo.com/manga/ia919396', SiteType.Manganelo).then(mangaInfo => {
if (mangaInfo.url !== 'https://manganelo.com/manga/ia919396') reject(Error('URL did not match'))
else if (mangaInfo.site !== SiteType.Manganelo) reject(Error('Site did not match'))
else if (mangaInfo.chapter !== 'Chapter 84: Amor Fati 4') reject(Error('Chapter did not match'))
else if (mangaInfo.chapter !== 'Chapter 85: A Desired Life 1') reject(Error('Chapter did not match'))
else if (mangaInfo.image !== 'https://avt.mkklcdnv6.com/30/p/18-1583498266.jpg') reject(Error('Image did not match'))
else if (mangaInfo.title !== 'The Eyes Of Sora') reject(Error('Title did not match'))
else if (mangaInfo.chapterUrl !== 'https://manganelo.com/chapter/ia919396/chapter_84') reject(Error('Chapter URL did not match'))
else if (mangaInfo.chapterUrl !== 'https://manganelo.com/chapter/ia919396/chapter_85') reject(Error('Chapter URL did not match'))
else if (mangaInfo.read !== undefined) reject(Error('Read did not match'))
else if (mangaInfo.readUrl !== undefined) reject(Error('Read URL did not match'))
else resolve()
Expand Down Expand Up @@ -238,6 +262,54 @@ function testMangakomi (): Promise<void> {
})
}

function testMethodScans (): Promise<void> {
return new Promise((resolve, reject) => {
getMangaInfo('https://methodscans.com/comics/773532-meng-shi-zai-shang', SiteType.MethodScans).then(mangaInfo => {
if (mangaInfo.url !== 'https://methodscans.com/comics/773532-meng-shi-zai-shang') reject(Error('URL did not match'))
else if (mangaInfo.site !== SiteType.MethodScans) reject(Error('Site did not match'))
else if (mangaInfo.chapter !== 'Yuan Yuan is as sharp as ever') reject(Error('Chapter did not match'))
else if (mangaInfo.image !== 'https://methodscans.com/storage/comics/32C023D5E17475B0A11F44D374454D1731B83F43D8576CF3/O7ExypuTakfFfImsojgiZqwd1dFTGevwYCKY2707.png') reject(Error('Image did not match'))
else if (mangaInfo.title !== 'Meng Shi Zai Shang') reject(Error('Title did not match'))
else if (mangaInfo.chapterUrl !== 'https://methodscans.com/comics/773532-meng-shi-zai-shang/1/172') reject(Error('Chapter URL did not match'))
else if (mangaInfo.read !== undefined) reject(Error('Read did not match'))
else if (mangaInfo.readUrl !== undefined) reject(Error('Read URL did not match'))
else resolve()
}).catch((error) => reject(error))
})
}

function testLeviatanScans (): Promise<void> {
return new Promise((resolve, reject) => {
getMangaInfo('https://leviatanscans.com/comics/909261-stresser', SiteType.LeviatanScans).then(mangaInfo => {
if (mangaInfo.url !== 'https://leviatanscans.com/comics/909261-stresser') reject(Error('URL did not match'))
else if (mangaInfo.site !== SiteType.LeviatanScans) reject(Error('Site did not match'))
else if (mangaInfo.chapter !== 'Chapter 8') reject(Error('Chapter did not match'))
else if (mangaInfo.image !== 'https://leviatanscans.com/storage/comics/BCB5DC2B80EFE1F1AA0CD616E62D075313A91F7CD6FFDFFC/BFzN2G6vA89PxW15VHliJxTLNXUO185Srlyt0GAH.jpeg') reject(Error('Image did not match'))
else if (mangaInfo.title !== 'Stresser') reject(Error('Title did not match'))
else if (mangaInfo.chapterUrl !== 'https://leviatanscans.com/comics/909261-stresser/1/8') reject(Error('Chapter URL did not match'))
else if (mangaInfo.read !== undefined) reject(Error('Read did not match'))
else if (mangaInfo.readUrl !== undefined) reject(Error('Read URL did not match'))
else resolve()
}).catch((error) => reject(error))
})
}

function testHiperDEX (): Promise<void> {
return new Promise((resolve, reject) => {
getMangaInfo('https://hiperdex.com/manga/arata-primal-the-new-primitive/', SiteType.HiperDEX).then(mangaInfo => {
if (mangaInfo.url !== 'https://hiperdex.com/manga/arata-primal-the-new-primitive/') reject(Error('URL did not match'))
else if (mangaInfo.site !== SiteType.HiperDEX) reject(Error('Site did not match'))
else if (mangaInfo.chapter !== '35 [END]') reject(Error(`Chapter ${mangaInfo.chapter} did not match`))
else if (mangaInfo.image !== 'https://hiperdex.com/wp-content/uploads/2020/04/Arata-Primal-193x278.jpg') reject(Error('Image did not match'))
else if (mangaInfo.title !== 'Arata Primal') reject(Error('Title did not match'))
else if (mangaInfo.chapterUrl !== 'https://hiperdex.com/manga/arata-primal-the-new-primitive/35-end/') reject(Error('Chapter URL did not match'))
else if (mangaInfo.read !== undefined) reject(Error('Read did not match'))
else if (mangaInfo.readUrl !== undefined) reject(Error('Read URL did not match'))
else resolve()
}).catch((error) => reject(error))
})
}

function testSearchManganelo (): Promise<void> {
return new Promise((resolve, reject) => {
searchManga('together with the rain', SiteType.Manganelo).then(result => {
Expand Down Expand Up @@ -373,3 +445,44 @@ function testSearchMangaKomi (): Promise<void> {
}).catch(error => reject(error))
})
}

function testSearchMethodScans (): Promise<void> {
// No search available
return new Promise(resolve => {
resolve()
})
}

function testSearchLeviatanScans (): Promise<void> {
return new Promise((resolve, reject) => {
searchManga('stresser', SiteType.LeviatanScans).then(result => {
const matchingManga = result.filter(manga => {
return manga.site === SiteType.LeviatanScans &&
manga.title === 'Stresser' &&
manga.image === 'https://leviatanscans.com/storage/comics/BCB5DC2B80EFE1F1AA0CD616E62D075313A91F7CD6FFDFFC/BFzN2G6vA89PxW15VHliJxTLNXUO185Srlyt0GAH.jpeg' &&
manga.chapter === 'Chapter 8' &&
manga.url === 'https://leviatanscans.com/comics/909261-stresser'
})

if (matchingManga.length === 0) reject(Error('No matching result'))
else resolve()
}).catch(error => reject(error))
})
}

function testSearchHiperDEX (): Promise<void> {
return new Promise((resolve, reject) => {
searchManga('cabalist', SiteType.HiperDEX).then(result => {
const matchingManga = result.filter(manga => {
return manga.site === SiteType.HiperDEX &&
manga.title === 'Cabalist' &&
manga.image === 'https://hiperdex.com/wp-content/uploads/2020/04/Cabalist-193x278.jpg' &&
manga.chapter === '44 [END]' &&
manga.url === 'https://hiperdex.com/manga/cabalistin/'
})

if (matchingManga.length === 0) reject(Error('No matching result'))
else resolve()
}).catch(error => reject(error))
})
}

0 comments on commit a051ce7

Please sign in to comment.