@@ -16,20 +16,24 @@ import {
1616
1717import { type Element } from 'domhandler'
1818
19+ const MT_DOMAIN = 'https://mitaku.net'
20+
1921export 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 ( / h t t p : \/ \/ \/ / g, 'http://' ) // only changes urls with http protocol
152+ image = image ?. replace ( / h t t p : \/ \/ / g, 'https://' )
153+ // Malforumed url fix (Turns https:///example.com into https://example.com (or the http:// equivalent))
154+ image = image ?. replace ( / h t t p s : \/ \/ \/ / 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
131168export const isLastPage = ( $ : CheerioAPI ) : boolean => {
0 commit comments