Fix broken thumbnails after expiration time at MangaPlus. (#3974)
This commit is contained in:
		
							parent
							
								
									064710af68
								
							
						
					
					
						commit
						8fdfba373f
					
				@ -6,7 +6,7 @@ ext {
 | 
			
		||||
    extName = 'MANGA Plus by SHUEISHA'
 | 
			
		||||
    pkgNameSuffix = 'all.mangaplus'
 | 
			
		||||
    extClass = '.MangaPlusFactory'
 | 
			
		||||
    extVersionCode = 10
 | 
			
		||||
    extVersionCode = 11
 | 
			
		||||
    libVersion = '1.2'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -54,6 +54,7 @@ abstract class MangaPlus(
 | 
			
		||||
 | 
			
		||||
    override val client: OkHttpClient = network.client.newBuilder()
 | 
			
		||||
        .addInterceptor { imageIntercept(it) }
 | 
			
		||||
        .addInterceptor { thumbnailIntercept(it) }
 | 
			
		||||
        .build()
 | 
			
		||||
 | 
			
		||||
    private val protobufJs: String by lazy {
 | 
			
		||||
@ -72,6 +73,8 @@ abstract class MangaPlus(
 | 
			
		||||
    private val splitImages: String
 | 
			
		||||
        get() = if (preferences.getBoolean("${SPLIT_PREF_KEY}_$lang", SPLIT_PREF_DEFAULT_VALUE)) "yes" else "no"
 | 
			
		||||
 | 
			
		||||
    private var titleList: List<Title>? = null
 | 
			
		||||
 | 
			
		||||
    override fun popularMangaRequest(page: Int): Request {
 | 
			
		||||
        val newHeaders = headersBuilder()
 | 
			
		||||
            .set("Referer", "$baseUrl/manga_list/hot")
 | 
			
		||||
@ -86,15 +89,16 @@ abstract class MangaPlus(
 | 
			
		||||
        if (result.success == null)
 | 
			
		||||
            throw Exception(result.error!!.langPopup.body)
 | 
			
		||||
 | 
			
		||||
        val mangas = result.success.titleRankingView!!.titles
 | 
			
		||||
        titleList = result.success.titleRankingView!!.titles
 | 
			
		||||
            .filter { it.language == langCode }
 | 
			
		||||
            .map {
 | 
			
		||||
                SManga.create().apply {
 | 
			
		||||
                    title = it.name
 | 
			
		||||
                    thumbnail_url = it.portraitImageUrl.toWeservUrl()
 | 
			
		||||
                    url = "#/titles/${it.titleId}"
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
        val mangas = titleList!!.map {
 | 
			
		||||
            SManga.create().apply {
 | 
			
		||||
                title = it.name
 | 
			
		||||
                thumbnail_url = it.portraitImageUrl
 | 
			
		||||
                url = "#/titles/${it.titleId}"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return MangasPage(mangas, false)
 | 
			
		||||
    }
 | 
			
		||||
@ -113,6 +117,14 @@ abstract class MangaPlus(
 | 
			
		||||
        if (result.success == null)
 | 
			
		||||
            throw Exception(result.error!!.langPopup.body)
 | 
			
		||||
 | 
			
		||||
        // Fetch all titles to get newer thumbnail urls at the interceptor.
 | 
			
		||||
        val popularResponse = client.newCall(popularMangaRequest(1)).execute().asProto()
 | 
			
		||||
 | 
			
		||||
        if (popularResponse.success != null) {
 | 
			
		||||
            titleList = popularResponse.success.titleRankingView!!.titles
 | 
			
		||||
                .filter { it.language == langCode }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val mangas = result.success.webHomeView!!.groups
 | 
			
		||||
            .flatMap { it.titles }
 | 
			
		||||
            .mapNotNull { it.title }
 | 
			
		||||
@ -120,7 +132,7 @@ abstract class MangaPlus(
 | 
			
		||||
            .map {
 | 
			
		||||
                SManga.create().apply {
 | 
			
		||||
                    title = it.name
 | 
			
		||||
                    thumbnail_url = it.portraitImageUrl.toWeservUrl()
 | 
			
		||||
                    thumbnail_url = it.portraitImageUrl
 | 
			
		||||
                    url = "#/titles/${it.titleId}"
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@ -148,15 +160,16 @@ abstract class MangaPlus(
 | 
			
		||||
        if (result.success == null)
 | 
			
		||||
            throw Exception(result.error!!.langPopup.body)
 | 
			
		||||
 | 
			
		||||
        val mangas = result.success.allTitlesView!!.titles
 | 
			
		||||
        titleList = result.success.allTitlesView!!.titles
 | 
			
		||||
            .filter { it.language == langCode }
 | 
			
		||||
            .map {
 | 
			
		||||
                SManga.create().apply {
 | 
			
		||||
                    title = it.name
 | 
			
		||||
                    thumbnail_url = it.portraitImageUrl.toWeservUrl()
 | 
			
		||||
                    url = "#/titles/${it.titleId}"
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
        val mangas = titleList!!.map {
 | 
			
		||||
            SManga.create().apply {
 | 
			
		||||
                title = it.name
 | 
			
		||||
                thumbnail_url = it.portraitImageUrl
 | 
			
		||||
                url = "#/titles/${it.titleId}"
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return MangasPage(mangas, false)
 | 
			
		||||
    }
 | 
			
		||||
@ -200,7 +213,7 @@ abstract class MangaPlus(
 | 
			
		||||
            artist = author
 | 
			
		||||
            description = details.overview + "\n\n" + details.viewingPeriodDescription
 | 
			
		||||
            status = if (isCompleted) SManga.COMPLETED else SManga.ONGOING
 | 
			
		||||
            thumbnail_url = title.portraitImageUrl.toWeservUrl()
 | 
			
		||||
            thumbnail_url = title.portraitImageUrl
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -385,12 +398,26 @@ abstract class MangaPlus(
 | 
			
		||||
        return ByteArray(content.size) { pos -> content[pos].toByte() }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun String.toWeservUrl(): String {
 | 
			
		||||
        val imageUrl = substringBefore("&duration")
 | 
			
		||||
    private fun thumbnailIntercept(chain: Interceptor.Chain): Response {
 | 
			
		||||
        val request = chain.request()
 | 
			
		||||
        val response = chain.proceed(request)
 | 
			
		||||
 | 
			
		||||
        return HttpUrl.parse(IMAGES_WESERV_URL)!!.newBuilder()
 | 
			
		||||
            .addEncodedQueryParameter("url", imageUrl)
 | 
			
		||||
            .toString()
 | 
			
		||||
        // Check if it is 404 to maintain compatibility when the extension used Weserv.
 | 
			
		||||
        val isBadCode = (response.code() == 401 || response.code() == 404)
 | 
			
		||||
 | 
			
		||||
        if (isBadCode && request.url().toString().contains(TITLE_THUMBNAIL_PATH)) {
 | 
			
		||||
            val titleId = request.url().toString()
 | 
			
		||||
                .substringBefore("/$TITLE_THUMBNAIL_PATH")
 | 
			
		||||
                .substringAfterLast("/")
 | 
			
		||||
                .toInt()
 | 
			
		||||
            val title = titleList?.find { it.titleId == titleId } ?: return response
 | 
			
		||||
 | 
			
		||||
            response.close()
 | 
			
		||||
            val thumbnailRequest = GET(title.portraitImageUrl, request.headers())
 | 
			
		||||
            return chain.proceed(thumbnailRequest)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return response
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val ErrorResult.langPopup: Popup
 | 
			
		||||
@ -429,7 +456,6 @@ abstract class MangaPlus(
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        private const val API_URL = "https://jumpg-webapi.tokyo-cdn.com/api"
 | 
			
		||||
        private const val IMAGES_WESERV_URL = "https://images.weserv.nl"
 | 
			
		||||
        private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36"
 | 
			
		||||
 | 
			
		||||
        private val HEX_GROUP = "(.{1,2})".toRegex()
 | 
			
		||||
@ -448,5 +474,7 @@ abstract class MangaPlus(
 | 
			
		||||
        private const val SPLIT_PREF_DEFAULT_VALUE = true
 | 
			
		||||
 | 
			
		||||
        private val COMPLETE_REGEX = "completado|complete".toRegex()
 | 
			
		||||
 | 
			
		||||
        private const val TITLE_THUMBNAIL_PATH = "title_thumbnail_portrait_list"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user