mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Fix gallery browsing
This commit is contained in:
		@@ -11,7 +11,9 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.all.EHentai
 | 
			
		||||
import eu.kanade.tachiyomi.util.launchUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.powerManager
 | 
			
		||||
import eu.kanade.tachiyomi.util.toast
 | 
			
		||||
import eu.kanade.tachiyomi.util.wifiManager
 | 
			
		||||
import exh.EH_METADATA_SOURCE_ID
 | 
			
		||||
import exh.EXH_SOURCE_ID
 | 
			
		||||
@@ -117,6 +119,11 @@ class FavoritesSyncHelper(val context: Context) {
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            val theContext = context
 | 
			
		||||
            launchUI {
 | 
			
		||||
                theContext.toast("Sync complete!")
 | 
			
		||||
            }
 | 
			
		||||
        } catch(e: IgnoredException) {
 | 
			
		||||
            //Do not display error as this error has already been reported
 | 
			
		||||
            Timber.w(e, "Ignoring exception!")
 | 
			
		||||
 
 | 
			
		||||
@@ -160,8 +160,12 @@ open class ExGalleryMetadata : RealmObject(), SearchableGalleryMetadata {
 | 
			
		||||
    companion object {
 | 
			
		||||
        private fun splitGalleryUrl(url: String)
 | 
			
		||||
                = url.let {
 | 
			
		||||
            Uri.parse(it).pathSegments
 | 
			
		||||
                    .filterNot(String::isNullOrBlank)
 | 
			
		||||
            //Only parse URL if is full URL
 | 
			
		||||
            val pathSegments = if(it.startsWith("http"))
 | 
			
		||||
                Uri.parse(it).pathSegments
 | 
			
		||||
            else
 | 
			
		||||
                it.split('/')
 | 
			
		||||
            pathSegments.filterNot(String::isNullOrBlank)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fun galleryId(url: String) = splitGalleryUrl(url).let { it[it.size - 2] }
 | 
			
		||||
 
 | 
			
		||||
@@ -89,7 +89,7 @@ open class NHentaiMetadata : RealmObject(), SearchableGalleryMetadata {
 | 
			
		||||
        if(mediaId != null)
 | 
			
		||||
            NHentaiMetadata.typeToExtension(thumbnailImageType)?.let {
 | 
			
		||||
                manga.thumbnail_url = "https://t.nhentai.net/galleries/$mediaId/${
 | 
			
		||||
                if(Injekt.get<PreferencesHelper>().eh_useHighQualityThumbs().getOrDefault())
 | 
			
		||||
                if(Injekt.get<PreferencesHelper>().eh_nh_useHighQualityThumbs().getOrDefault())
 | 
			
		||||
                    "cover"
 | 
			
		||||
                else
 | 
			
		||||
                    "thumb"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										65
									
								
								app/src/main/java/exh/uconfig/ConfiguringDialogController.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								app/src/main/java/exh/uconfig/ConfiguringDialogController.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
package exh.uconfig
 | 
			
		||||
 | 
			
		||||
import android.app.Dialog
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.view.View
 | 
			
		||||
import com.afollestad.materialdialogs.MaterialDialog
 | 
			
		||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
 | 
			
		||||
import eu.kanade.tachiyomi.util.launchUI
 | 
			
		||||
import eu.kanade.tachiyomi.util.toast
 | 
			
		||||
import kotlin.concurrent.thread
 | 
			
		||||
 | 
			
		||||
class ConfiguringDialogController : DialogController() {
 | 
			
		||||
    private var materialDialog: MaterialDialog? = null
 | 
			
		||||
 | 
			
		||||
    override fun onCreateDialog(savedViewState: Bundle?): Dialog {
 | 
			
		||||
        return MaterialDialog.Builder(activity!!)
 | 
			
		||||
                .title("Uploading settings to server")
 | 
			
		||||
                .content("Please wait, this may take some time...")
 | 
			
		||||
                .progress(true, 0)
 | 
			
		||||
                .cancelable(false)
 | 
			
		||||
                .build().also {
 | 
			
		||||
            materialDialog = it
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onAttach(view: View) {
 | 
			
		||||
        super.onAttach(view)
 | 
			
		||||
        thread {
 | 
			
		||||
            try {
 | 
			
		||||
                EHConfigurator().configureAll()
 | 
			
		||||
                launchUI {
 | 
			
		||||
                    activity?.toast("Settings successfully uploaded!")
 | 
			
		||||
                }
 | 
			
		||||
            } catch (e: Exception) {
 | 
			
		||||
                activity?.let {
 | 
			
		||||
                    it.runOnUiThread {
 | 
			
		||||
                        MaterialDialog.Builder(it)
 | 
			
		||||
                                .title("Configuration failed!")
 | 
			
		||||
                                .content("An error occurred during the configuration process: " + e.message)
 | 
			
		||||
                                .positiveText("Ok")
 | 
			
		||||
                                .show()
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            launchUI {
 | 
			
		||||
                finish()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onDestroyView(view: View) {
 | 
			
		||||
        super.onDestroyView(view)
 | 
			
		||||
        materialDialog = null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onRestoreInstanceState(savedInstanceState: Bundle) {
 | 
			
		||||
        super.onRestoreInstanceState(savedInstanceState)
 | 
			
		||||
        finish()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun finish() {
 | 
			
		||||
        router.popController(this)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										125
									
								
								app/src/main/java/exh/uconfig/EHConfigurator.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										125
									
								
								app/src/main/java/exh/uconfig/EHConfigurator.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,125 @@
 | 
			
		||||
package exh.uconfig
 | 
			
		||||
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.all.EHentai
 | 
			
		||||
import eu.kanade.tachiyomi.util.asJsoup
 | 
			
		||||
import exh.EH_SOURCE_ID
 | 
			
		||||
import exh.EXH_SOURCE_ID
 | 
			
		||||
import okhttp3.FormBody
 | 
			
		||||
import okhttp3.OkHttpClient
 | 
			
		||||
import okhttp3.Request
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
 | 
			
		||||
class EHConfigurator {
 | 
			
		||||
    private val prefs: PreferencesHelper by injectLazy()
 | 
			
		||||
    private val sources: SourceManager by injectLazy()
 | 
			
		||||
 | 
			
		||||
    private val configuratorClient = OkHttpClient.Builder().build()
 | 
			
		||||
 | 
			
		||||
    private fun EHentai.requestWithCreds(sp: Int = 1) = Request.Builder()
 | 
			
		||||
            .addHeader("Cookie", cookiesHeader(sp))
 | 
			
		||||
 | 
			
		||||
    private fun EHentai.execProfileActions(action: String,
 | 
			
		||||
                                           name: String,
 | 
			
		||||
                                           set: String,
 | 
			
		||||
                                           sp: Int)
 | 
			
		||||
        = configuratorClient.newCall(requestWithCreds(sp)
 | 
			
		||||
                .url(uconfigUrl)
 | 
			
		||||
                .post(FormBody.Builder()
 | 
			
		||||
                        .add("profile_action", action)
 | 
			
		||||
                        .add("profile_name", name)
 | 
			
		||||
                        .add("profile_set", set)
 | 
			
		||||
                        .build())
 | 
			
		||||
                .build())
 | 
			
		||||
                .execute().asJsoup()
 | 
			
		||||
 | 
			
		||||
    private val EHentai.uconfigUrl get() = baseUrl + UCONFIG_URL
 | 
			
		||||
 | 
			
		||||
    fun configureAll() {
 | 
			
		||||
        val ehSource = sources.get(EH_SOURCE_ID) as EHentai
 | 
			
		||||
        val exhSource = sources.get(EXH_SOURCE_ID) as EHentai
 | 
			
		||||
 | 
			
		||||
        //Get hath perks
 | 
			
		||||
        val perksPage = configuratorClient.newCall(ehSource.requestWithCreds()
 | 
			
		||||
                .url(HATH_PERKS_URL)
 | 
			
		||||
                .build())
 | 
			
		||||
                .execute().asJsoup()
 | 
			
		||||
 | 
			
		||||
        val hathPerks = EHHathPerksResponse()
 | 
			
		||||
 | 
			
		||||
        perksPage.select(".stuffbox tr").forEach {
 | 
			
		||||
            val name = it.child(0).text().toLowerCase()
 | 
			
		||||
            val purchased = it.child(2).getElementsByTag("form").isEmpty()
 | 
			
		||||
 | 
			
		||||
            when(name) {
 | 
			
		||||
                //Thumbnail rows
 | 
			
		||||
                "more thumbs" -> hathPerks.moreThumbs = purchased
 | 
			
		||||
                "thumbs up" -> hathPerks.thumbsUp = purchased
 | 
			
		||||
                "all thumbs" -> hathPerks.allThumbs = purchased
 | 
			
		||||
 | 
			
		||||
                //Pagination sizing
 | 
			
		||||
                "paging enlargement i" -> hathPerks.pagingEnlargementI = purchased
 | 
			
		||||
                "paging enlargement ii" -> hathPerks.pagingEnlargementII = purchased
 | 
			
		||||
                "paging enlargement iii" -> hathPerks.pagingEnlargementIII = purchased
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Timber.d("Hath perks: $hathPerks")
 | 
			
		||||
 | 
			
		||||
        configure(ehSource, hathPerks)
 | 
			
		||||
        configure(exhSource, hathPerks)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun configure(source: EHentai, hathPerks: EHHathPerksResponse) {
 | 
			
		||||
        //Delete old app profiles
 | 
			
		||||
        val scanReq = source.requestWithCreds().url(source.uconfigUrl).build()
 | 
			
		||||
        val resp = configuratorClient.newCall(scanReq).execute().asJsoup()
 | 
			
		||||
        var lastDoc = resp
 | 
			
		||||
        resp.select(PROFILE_SELECTOR).forEach {
 | 
			
		||||
            if(it.text() == PROFILE_NAME) {
 | 
			
		||||
                val id = it.attr("value")
 | 
			
		||||
                //Delete old profile
 | 
			
		||||
                lastDoc = source.execProfileActions("delete", "", id, id.toInt())
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Find available profile slot
 | 
			
		||||
        val availableProfiles = (1 .. 3).toMutableList()
 | 
			
		||||
        lastDoc.select(PROFILE_SELECTOR).forEach {
 | 
			
		||||
            availableProfiles.remove(it.attr("value").toInt())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //No profile slots left :(
 | 
			
		||||
        if(availableProfiles.isEmpty())
 | 
			
		||||
            throw IllegalStateException("You are out of profile slots on ${source.name}, please delete a profile!")
 | 
			
		||||
 | 
			
		||||
        //Create profile in available slot
 | 
			
		||||
        val slot = availableProfiles.first()
 | 
			
		||||
        source.execProfileActions("create",
 | 
			
		||||
                PROFILE_NAME,
 | 
			
		||||
                slot.toString(),
 | 
			
		||||
                1)
 | 
			
		||||
 | 
			
		||||
        //Build new profile
 | 
			
		||||
        val form = EhUConfigBuilder().build(hathPerks)
 | 
			
		||||
 | 
			
		||||
        //Send new profile to server
 | 
			
		||||
        configuratorClient.newCall(source.requestWithCreds(sp = slot)
 | 
			
		||||
                .url(source.uconfigUrl)
 | 
			
		||||
                .post(form)
 | 
			
		||||
                .build()).execute()
 | 
			
		||||
 | 
			
		||||
        //Persist slot
 | 
			
		||||
        source.spPref().set(slot)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        private const val PROFILE_NAME = "TachiyomiEH App"
 | 
			
		||||
        private const val UCONFIG_URL = "/uconfig.php"
 | 
			
		||||
        //Always use E-H here as EXH does not have a perks page
 | 
			
		||||
        private const val HATH_PERKS_URL = "https://e-hentai.org/hathperks.php"
 | 
			
		||||
        private const val PROFILE_SELECTOR = "[name=profile_set] > option"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								app/src/main/java/exh/uconfig/EHHathPerksResponse.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								app/src/main/java/exh/uconfig/EHHathPerksResponse.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
package exh.uconfig
 | 
			
		||||
 | 
			
		||||
class EHHathPerksResponse {
 | 
			
		||||
    var moreThumbs = false
 | 
			
		||||
    var thumbsUp = false
 | 
			
		||||
    var allThumbs = false
 | 
			
		||||
 | 
			
		||||
    var pagingEnlargementI = false
 | 
			
		||||
    var pagingEnlargementII = false
 | 
			
		||||
    var pagingEnlargementIII = false
 | 
			
		||||
 | 
			
		||||
    override fun toString()
 | 
			
		||||
        = "EHHathPerksResponse(moreThumbs=$moreThumbs, thumbsUp=$thumbsUp, allThumbs=$allThumbs, pagingEnlargementI=$pagingEnlargementI, pagingEnlargementII=$pagingEnlargementII, pagingEnlargementIII=$pagingEnlargementIII)"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										142
									
								
								app/src/main/java/exh/uconfig/EhUConfigBuilder.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								app/src/main/java/exh/uconfig/EhUConfigBuilder.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,142 @@
 | 
			
		||||
package exh.uconfig
 | 
			
		||||
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import okhttp3.FormBody
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
 | 
			
		||||
class EhUConfigBuilder {
 | 
			
		||||
    private val prefs: PreferencesHelper by injectLazy()
 | 
			
		||||
 | 
			
		||||
    fun build(hathPerks: EHHathPerksResponse): FormBody {
 | 
			
		||||
        val configItems = mutableListOf<ConfigItem>()
 | 
			
		||||
 | 
			
		||||
        configItems += when(prefs.imageQuality()
 | 
			
		||||
                .getOrDefault()
 | 
			
		||||
                .toLowerCase()) {
 | 
			
		||||
            "ovrs_2400" -> Entry.ImageSize.`2400`
 | 
			
		||||
            "ovrs_1600" -> Entry.ImageSize.`1600`
 | 
			
		||||
            "high" -> Entry.ImageSize.`1280`
 | 
			
		||||
            "med" -> Entry.ImageSize.`980`
 | 
			
		||||
            "low" -> Entry.ImageSize.`780`
 | 
			
		||||
            "auto" -> Entry.ImageSize.AUTO
 | 
			
		||||
            else -> Entry.ImageSize.AUTO
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        configItems += if(prefs.useHentaiAtHome().getOrDefault())
 | 
			
		||||
            Entry.UseHentaiAtHome.YES
 | 
			
		||||
        else
 | 
			
		||||
            Entry.UseHentaiAtHome.NO
 | 
			
		||||
 | 
			
		||||
        configItems += if(prefs.useJapaneseTitle().getOrDefault())
 | 
			
		||||
            Entry.TitleDisplayLanguage.JAPANESE
 | 
			
		||||
        else
 | 
			
		||||
            Entry.TitleDisplayLanguage.DEFAULT
 | 
			
		||||
 | 
			
		||||
        configItems += if(prefs.eh_useOriginalImages().getOrDefault())
 | 
			
		||||
            Entry.UseOriginalImages.YES
 | 
			
		||||
        else
 | 
			
		||||
            Entry.UseOriginalImages.NO
 | 
			
		||||
 | 
			
		||||
        configItems += when {
 | 
			
		||||
            hathPerks.allThumbs -> Entry.ThumbnailRows.`40`
 | 
			
		||||
            hathPerks.thumbsUp -> Entry.ThumbnailRows.`20`
 | 
			
		||||
            hathPerks.moreThumbs -> Entry.ThumbnailRows.`10`
 | 
			
		||||
            else -> Entry.ThumbnailRows.`4`
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        configItems += when {
 | 
			
		||||
            hathPerks.pagingEnlargementIII -> Entry.SearchResultsCount.`200`
 | 
			
		||||
            hathPerks.pagingEnlargementII -> Entry.SearchResultsCount.`100`
 | 
			
		||||
            hathPerks.pagingEnlargementI -> Entry.SearchResultsCount.`50`
 | 
			
		||||
            else -> Entry.SearchResultsCount.`25`
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        configItems += Entry.DisplayMode()
 | 
			
		||||
        configItems += Entry.UseMPV()
 | 
			
		||||
        configItems += Entry.ShowPopularRightNowPane()
 | 
			
		||||
 | 
			
		||||
        //Actually build form body
 | 
			
		||||
        val formBody = FormBody.Builder()
 | 
			
		||||
        configItems.forEach {
 | 
			
		||||
            formBody.add(it.key, it.value)
 | 
			
		||||
        }
 | 
			
		||||
        formBody.add("apply", "Apply")
 | 
			
		||||
        return formBody.build()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object Entry {
 | 
			
		||||
    enum class UseHentaiAtHome(override val value: String): ConfigItem {
 | 
			
		||||
        YES("0"),
 | 
			
		||||
        NO("1");
 | 
			
		||||
 | 
			
		||||
        override val key = "uh"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enum class ImageSize(override val value: String): ConfigItem {
 | 
			
		||||
        AUTO("0"),
 | 
			
		||||
        `2400`("5"),
 | 
			
		||||
        `1600`("4"),
 | 
			
		||||
        `1280`("3"),
 | 
			
		||||
        `980`("2"),
 | 
			
		||||
        `780`("1");
 | 
			
		||||
 | 
			
		||||
        override val key = "xr"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enum class TitleDisplayLanguage(override val value: String): ConfigItem {
 | 
			
		||||
        DEFAULT("0"),
 | 
			
		||||
        JAPANESE("1");
 | 
			
		||||
 | 
			
		||||
        override val key = "tl"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Locked to list mode as that's what the parser and toplists use
 | 
			
		||||
    class DisplayMode: ConfigItem {
 | 
			
		||||
        override val key = "dm"
 | 
			
		||||
        override val value = "0"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enum class SearchResultsCount(override val value: String): ConfigItem {
 | 
			
		||||
        `25`("0"),
 | 
			
		||||
        `50`("1"),
 | 
			
		||||
        `100`("2"),
 | 
			
		||||
        `200`("3");
 | 
			
		||||
 | 
			
		||||
        override val key = "rc"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enum class ThumbnailRows(override val value: String): ConfigItem {
 | 
			
		||||
        `4`("0"),
 | 
			
		||||
        `10`("1"),
 | 
			
		||||
        `20`("2"),
 | 
			
		||||
        `40`("3");
 | 
			
		||||
 | 
			
		||||
        override val key = "tr"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    enum class UseOriginalImages(override val value: String): ConfigItem {
 | 
			
		||||
        NO("0"),
 | 
			
		||||
        YES("1");
 | 
			
		||||
 | 
			
		||||
        override val key = "oi"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Locked to no MPV as that's what the parser uses
 | 
			
		||||
    class UseMPV: ConfigItem {
 | 
			
		||||
        override val key = "qb"
 | 
			
		||||
        override val value = "0"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Locked to no popular pane as we can't parse it
 | 
			
		||||
    class ShowPopularRightNowPane: ConfigItem {
 | 
			
		||||
        override val key = "pp"
 | 
			
		||||
        override val value = "1"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
interface ConfigItem {
 | 
			
		||||
    val key: String
 | 
			
		||||
    val value: String
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user