Skip to content

Commit de2f1ee

Browse files
committed
Fix Mitaku
1 parent 1fa50a4 commit de2f1ee

3 files changed

Lines changed: 66 additions & 51 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@ docs
1717
# mac stuff
1818
.DS_Store
1919
package-lock.json
20+
notes
21+
/ignore_this

src/Mitaku/Mitaku.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
BadgeColor,
1111
Request,
1212
Response,
13-
TagSection,
1413
SourceIntents,
1514
HomeSectionType,
1615
ChapterProviding,
@@ -198,29 +197,6 @@ export class Mitaku implements SearchResultsProviding, MangaProviding, ChapterPr
198197
})
199198
}
200199

201-
async getSearchTags(): Promise<TagSection[]> {
202-
const request = App.createRequest({
203-
url: `${MT_DOMAIN}/wp-json/wp/v2/tags?per_page=100`,
204-
method: 'GET'
205-
})
206-
207-
const response = await this.requestManager.schedule(request, 1)
208-
const tagJSON = JSON.parse(response.data as string)
209-
210-
const arrayTags: Tag[] = []
211-
212-
for (const tag of tagJSON) {
213-
const label = tag.name
214-
const id = tag.slug
215-
216-
if (!id || !label) continue
217-
arrayTags.push({ id: id, label: label })
218-
}
219-
220-
const tagSections: TagSection[] = [App.createTagSection({ id: '0', label: 'genres', tags: arrayTags.map(x => App.createTag(x)) })]
221-
return tagSections
222-
}
223-
224200
async getSearchResults(query: SearchRequest, metadata: any): Promise<PagedResults> {
225201
const page: number = metadata?.page ?? 1
226202

src/Mitaku/MitakuParser.ts

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,24 @@ import {
1616

1717
import { type Element } from 'domhandler'
1818

19+
const MT_DOMAIN = 'https://mitaku.net'
20+
1921
export const parseMangaDetails = ($: CheerioAPI, mangaId: string): SourceManga => {
2022
const images = parseImages($)
2123

22-
const title = decodeHTMLEntity($('h1.cm-entry-title').first().text().trim())
24+
const title = decodeHTMLEntity($('.cm-entry-title').first().text().trim())
2325
const artist = decodeHTMLEntity($('p:contains(Cosplayer:)').text().trim().replace('Cosplayer:', '').trim())
2426
const description = `Cosplayer: ${artist}\n\nGallery: ${title}\n\nImages: ${images.length}`
2527

2628

2729
const arrayTags: Tag[] = []
28-
for (const tag of $('a', 'span.tag-links').toArray()) {
29-
const id = $(tag).attr('href')?.split('/tag/')[1]?.replace(/\//g, '')
30-
const label = $(tag).text().trim()
31-
if (!id || !label) continue
32-
arrayTags.push({ id: id, label: label })
30+
for (const obj of $('div.genres-content a').toArray()) {
31+
const id = idCleaner($(obj).attr('href') ?? '')
32+
const title = $(obj).text().trim()
33+
34+
if (!title || !id) continue
35+
36+
arrayTags.push({ label: title, id: id })
3337
}
3438
const tagSections: TagSection[] = [App.createTagSection({ id: '0', label: 'genres', tags: arrayTags.map(x => App.createTag(x)) })]
3539

@@ -70,14 +74,17 @@ export const parseHomeSections = ($: CheerioAPI): PartialSourceManga[] => {
7074
const collectedIds: string[] = []
7175
const itemArray: PartialSourceManga[] = []
7276

73-
for (const item of $('article', 'div#cm-primary').toArray()) {
77+
for (const item of $('article').toArray()) {
7478
const postId = $(item).attr('id')
7579
const id = postId?.split('post-').pop()
80+
7681
const image: string = getImageSrc($('img', item).first()) ?? ''
77-
const title: string = $('h2.cm-entry-title', item).text().trim() ?? ''
78-
const subtitle: string = $('span.cm-tag-links > a', item).toArray().map(x => $(x).text().trim()).join(', ')
82+
const title: string = $('a', item).first().attr('title')?.trim() ?? ''
83+
84+
const subtitle = $('a[rel="tag"]', item).map((i, el) => $(el).text().trim()).get().join(', ')
85+
86+
if (!id || isNaN(Number(id)) || !title || !subtitle) continue
7987

80-
if (!id || isNaN(Number(id)) || !title || collectedIds.includes(id) || !subtitle) continue
8188
itemArray.push(App.createPartialSourceManga({
8289
image: encodeURI(image),
8390
title: decodeHTMLEntity(title),
@@ -105,27 +112,57 @@ const parseImages = ($: CheerioAPI): string[] => {
105112
return images
106113
}
107114

108-
const getImageSrc = (imageObj: Cheerio<Element>): string => {
115+
// Utils
116+
const getImageSrc = (imageObj: Cheerio<Element> | undefined): string => {
109117
let image: string | undefined
110-
if ((typeof imageObj?.attr('data-src')) != 'undefined') {
111-
image = imageObj?.attr('data-src')
112-
}
113-
else if ((typeof imageObj?.attr('data-lazy-src')) != 'undefined') {
114-
image = imageObj?.attr('data-lazy-src')
115-
}
116-
else if ((typeof imageObj?.attr('srcset')) != 'undefined') {
117-
image = imageObj?.attr('srcset')?.split(' ')[0] ?? ''
118+
const sources = [
119+
'data-src',
120+
'data-lazy-src',
121+
'srcset',
122+
'src',
123+
'data-cfsrc'
124+
]
125+
126+
for (const attr of sources) {
127+
const val = imageObj?.attr(attr)
128+
129+
if (val == null || val.trim() === '') continue
130+
131+
// If it's srcset, extract the first URL
132+
if (attr === 'srcset') {
133+
image = val.split(',')[0]?.trim().split(' ')[0] ?? ''
134+
} else {
135+
image = val
136+
}
137+
138+
break
118139
}
119-
else if ((typeof imageObj?.attr('src')) != 'undefined') {
120-
image = imageObj?.attr('src')
121-
}
122-
else if ((typeof imageObj?.attr('data-cfsrc')) != 'undefined') {
123-
image = imageObj?.attr('data-cfsrc')
124-
} else {
125-
image = ''
140+
141+
image = image?.replace(/-\d+x\d+/g, '')
142+
143+
if (image?.startsWith('/')) {
144+
image = MT_DOMAIN + image
126145
}
127146

128-
return encodeURI(decodeURI(decodeHTMLEntity(image?.trim() ?? '')))
147+
image = image
148+
?.trim()
149+
.replace(/(\s{2,})/gi, '')
150+
151+
image = image?.replace(/http:\/\/\//g, 'http://') // only changes urls with http protocol
152+
image = image?.replace(/http:\/\//g, 'https://')
153+
// Malforumed url fix (Turns https:///example.com into https://example.com (or the http:// equivalent))
154+
image = image?.replace(/https:\/\/\//g, 'https://') // only changes urls with https protocol
155+
156+
return decodeURI(decodeHTMLEntity(image ?? ''))
157+
}
158+
159+
const idCleaner = (str: string): string => {
160+
let cleanId: string | null = str
161+
cleanId = cleanId.replace(/\/$/, '')
162+
cleanId = cleanId.split('/').pop() ?? null
163+
164+
if (!cleanId) throw new Error(`Unable to parse id for ${str}`)
165+
return cleanId
129166
}
130167

131168
export const isLastPage = ($: CheerioAPI): boolean => {

0 commit comments

Comments
 (0)