mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 14:27:57 +01:00 
			
		
		
		
	Fix gallery browsing
This commit is contained in:
		| @@ -124,4 +124,12 @@ object PreferenceKeys { | ||||
|     const val eh_showSyncIntro = "eh_show_sync_intro" | ||||
|  | ||||
|     const val eh_readOnlySync = "eh_sync_read_only" | ||||
|  | ||||
|     const val eh_useOrigImages = "eh_useOrigImages" | ||||
|  | ||||
|     const val eh_ehSettingsProfile = "eh_ehSettingsProfile" | ||||
|  | ||||
|     const val eh_exhSettingsProfile = "eh_exhSettingsProfile" | ||||
|  | ||||
|     const val eh_enableExHentai = "enable_exhentai" | ||||
| } | ||||
|   | ||||
| @@ -171,7 +171,7 @@ class PreferencesHelper(val context: Context) { | ||||
|     fun migrateFlags() = rxPrefs.getInteger("migrate_flags", Int.MAX_VALUE) | ||||
|  | ||||
|     // --> EH | ||||
|     fun enableExhentai() = rxPrefs.getBoolean("enable_exhentai", false) | ||||
|     fun enableExhentai() = rxPrefs.getBoolean(Keys.eh_enableExHentai, false) | ||||
|  | ||||
|     fun secureEXH() = rxPrefs.getBoolean("secure_exh", true) | ||||
|  | ||||
| @@ -181,6 +181,8 @@ class PreferencesHelper(val context: Context) { | ||||
|  | ||||
|     fun useJapaneseTitle() = rxPrefs.getBoolean("use_jp_title", false) | ||||
|  | ||||
|     fun eh_useOriginalImages() = rxPrefs.getBoolean(Keys.eh_useOrigImages, false) | ||||
|  | ||||
|     fun ehSearchSize() = rxPrefs.getString("ex_search_size", "rc_0") | ||||
|  | ||||
|     fun thumbnailRows() = rxPrefs.getString("ex_thumb_rows", "tr_2") | ||||
| @@ -195,6 +197,8 @@ class PreferencesHelper(val context: Context) { | ||||
|     fun memberIdVal() = rxPrefs.getString("eh_ipb_member_id", null) | ||||
|     fun passHashVal() = rxPrefs.getString("eh_ipb_pass_hash", null) | ||||
|     fun igneousVal() = rxPrefs.getString("eh_igneous", null) | ||||
|     fun eh_ehSettingsProfile() = rxPrefs.getInteger(Keys.eh_ehSettingsProfile, -1) | ||||
|     fun eh_exhSettingsProfile() = rxPrefs.getInteger(Keys.eh_exhSettingsProfile, -1) | ||||
|  | ||||
|     //Lock | ||||
|     fun lockHash() = rxPrefs.getString("lock_hash", null) | ||||
| @@ -205,7 +209,7 @@ class PreferencesHelper(val context: Context) { | ||||
|  | ||||
|     fun lockUseFingerprint() = rxPrefs.getBoolean("lock_finger", false) | ||||
|  | ||||
|     fun eh_useHighQualityThumbs() = rxPrefs.getBoolean(Keys.eh_nh_useHighQualityThumbs, false) | ||||
|     fun eh_nh_useHighQualityThumbs() = rxPrefs.getBoolean(Keys.eh_nh_useHighQualityThumbs, false) | ||||
|  | ||||
|     fun eh_showSyncIntro() = rxPrefs.getBoolean(Keys.eh_showSyncIntro, true) | ||||
|  | ||||
|   | ||||
| @@ -21,10 +21,7 @@ import exh.util.UriFilter | ||||
| import exh.util.UriGroup | ||||
| import exh.util.ignore | ||||
| import exh.util.urlImportFetchSearchManga | ||||
| import okhttp3.CacheControl | ||||
| import okhttp3.Headers | ||||
| import okhttp3.Request | ||||
| import okhttp3.Response | ||||
| import okhttp3.* | ||||
| import org.jsoup.nodes.Document | ||||
| import org.jsoup.nodes.Element | ||||
| import rx.Observable | ||||
| @@ -42,11 +39,14 @@ class EHentai(override val id: Long, | ||||
|         else | ||||
|             "http" | ||||
|  | ||||
|     override val baseUrl: String | ||||
|     val domain: String | ||||
|         get() = if(exh) | ||||
|             "$schema://exhentai.org" | ||||
|             "exhentai.org" | ||||
|         else | ||||
|             "$schema://e-hentai.org" | ||||
|             "e-hentai.org" | ||||
|  | ||||
|     override val baseUrl: String | ||||
|         get() = "$schema://$domain" | ||||
|  | ||||
|     override val lang = "all" | ||||
|     override val supportsLatest = true | ||||
| @@ -68,7 +68,7 @@ class EHentai(override val id: Long, | ||||
|                         //Get title | ||||
|                         it.select(".itd .it5 a").first()?.apply { | ||||
|                             title = text() | ||||
|                             setUrlWithoutDomain(addParam(attr("href"), "nw", "always")) | ||||
|                             setUrlWithoutDomain(ExGalleryMetadata.normalizeUrl(attr("href"))) | ||||
|                         } | ||||
|                         //Get image | ||||
|                         it.select(".itd .it2").first()?.apply { | ||||
| @@ -81,7 +81,6 @@ class EHentai(override val id: Long, | ||||
|                             } | ||||
|                         } | ||||
|                     }) | ||||
|  | ||||
|         } | ||||
|         //Add to page if required | ||||
|         val hasNextPage = select("a[onclick=return false]").last()?.let { | ||||
| @@ -330,62 +329,32 @@ class EHentai(override val id: Long, | ||||
|         return Pair(result as List<ParsedManga>, favNames!!) | ||||
|     } | ||||
|  | ||||
|     val cookiesHeader by lazy { | ||||
|     fun spPref() = if(exh) | ||||
|         prefs.eh_exhSettingsProfile() | ||||
|     else | ||||
|         prefs.eh_ehSettingsProfile() | ||||
|  | ||||
|     fun rawCookies(sp: Int): Map<String, String> { | ||||
|         val cookies: MutableMap<String, String> = mutableMapOf() | ||||
|         if(prefs.enableExhentai().getOrDefault()) { | ||||
|             cookies[LoginController.MEMBER_ID_COOKIE] = prefs.memberIdVal().get()!! | ||||
|             cookies[LoginController.PASS_HASH_COOKIE] = prefs.passHashVal().get()!! | ||||
|             cookies[LoginController.IGNEOUS_COOKIE] = prefs.igneousVal().get()!! | ||||
|             cookies["sp"] = sp.toString() | ||||
|         } | ||||
|  | ||||
|         //Setup settings | ||||
|         val settings = mutableListOf<String?>() | ||||
|         //Image quality | ||||
|         settings.add(when(prefs.imageQuality() | ||||
|                 .getOrDefault() | ||||
|                 .toLowerCase()) { | ||||
|             "ovrs_2400" -> "xr_2400" | ||||
|             "ovrs_1600" -> "xr_1600" | ||||
|             "high" -> "xr_1280" | ||||
|             "med" -> "xr_980" | ||||
|             "low" -> "xr_780" | ||||
|             "auto" -> null | ||||
|             else -> null | ||||
|         }) | ||||
|         //Use Hentai@Home | ||||
|         settings.add(if(prefs.useHentaiAtHome().getOrDefault()) | ||||
|             null | ||||
|         else | ||||
|             "uh_n") | ||||
|         //Japanese titles | ||||
|         settings.add(if(prefs.useJapaneseTitle().getOrDefault()) | ||||
|             "tl_j" | ||||
|         else | ||||
|             null) | ||||
|         //Do not show popular right now pane as we can't parse it | ||||
|         settings.add("prn_n") | ||||
|         //Paging size | ||||
|         settings.add(prefs.ehSearchSize().getOrDefault()) | ||||
|         //Thumbnail rows | ||||
|         settings.add(prefs.thumbnailRows().getOrDefault()) | ||||
|         //Session-less list display mode (for users without ExHentai) | ||||
|         cookies["sl"] = "dm_0" | ||||
|  | ||||
|         cookies.put("uconfig", buildSettings(settings)) | ||||
|  | ||||
|         buildCookies(cookies) | ||||
|         return cookies | ||||
|     } | ||||
|  | ||||
|     fun cookiesHeader(sp: Int = spPref().getOrDefault()) | ||||
|             = buildCookies(rawCookies(sp)) | ||||
|  | ||||
|     //Headers | ||||
|     override fun headersBuilder() | ||||
|             = super.headersBuilder().add("Cookie", cookiesHeader)!! | ||||
|  | ||||
|     fun buildSettings(settings: List<String?>): String { | ||||
|         return settings.filterNotNull().joinToString(separator = "-") | ||||
|     } | ||||
|  | ||||
|     fun buildCookies(cookies: Map<String, String>) | ||||
|             = cookies.entries.joinToString(separator = "; ", postfix = ";") { | ||||
|         "${URLEncoder.encode(it.key, "UTF-8")}=${URLEncoder.encode(it.value, "UTF-8")}" | ||||
|     } | ||||
|             = super.headersBuilder().add("Cookie", cookiesHeader())!! | ||||
|  | ||||
|     fun addParam(url: String, param: String, value: String) | ||||
|             = Uri.parse(url) | ||||
| @@ -394,11 +363,13 @@ class EHentai(override val id: Long, | ||||
|             .toString() | ||||
|  | ||||
|     override val client = network.client.newBuilder() | ||||
|             .cookieJar(CookieJar.NO_COOKIES) | ||||
|             .addInterceptor { chain -> | ||||
|                 val newReq = chain | ||||
|                         .request() | ||||
|                         .newBuilder() | ||||
|                         .addHeader("Cookie", cookiesHeader) | ||||
|                         .removeHeader("Cookie") | ||||
|                         .addHeader("Cookie", cookiesHeader()) | ||||
|                         .build() | ||||
|  | ||||
|                 chain.proceed(newReq) | ||||
| @@ -470,5 +441,11 @@ class EHentai(override val id: Long, | ||||
|     companion object { | ||||
|         val QUERY_PREFIX = "?f_apply=Apply+Filter" | ||||
|         val TR_SUFFIX = "TR" | ||||
|  | ||||
|         fun buildCookies(cookies: Map<String, String>) | ||||
|                 = cookies.entries.joinToString(separator = "; ", postfix = ";") { | ||||
|             "${URLEncoder.encode(it.key, "UTF-8")}=${URLEncoder.encode(it.value, "UTF-8")}" | ||||
|         } | ||||
|  | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -5,10 +5,12 @@ import android.widget.Toast | ||||
| import com.afollestad.materialdialogs.MaterialDialog | ||||
| import com.bluelinelabs.conductor.RouterTransaction | ||||
| import com.bluelinelabs.conductor.changehandler.FadeChangeHandler | ||||
| import com.f2prateek.rx.preferences.Preference | ||||
| import eu.kanade.tachiyomi.data.preference.PreferenceKeys | ||||
| import eu.kanade.tachiyomi.util.toast | ||||
| import exh.favorites.FavoritesIntroDialog | ||||
| import exh.favorites.LocalFavoritesStorage | ||||
| import exh.uconfig.ConfiguringDialogController | ||||
| import exh.ui.login.LoginController | ||||
| import exh.util.trans | ||||
| import rx.android.schedulers.AndroidSchedulers | ||||
| @@ -19,13 +21,22 @@ import rx.schedulers.Schedulers | ||||
|  */ | ||||
|  | ||||
| class SettingsEhController : SettingsController() { | ||||
|     private fun Preference<*>.reconfigureOnChange() { | ||||
|         asObservable() | ||||
|                 .skip(1) //Skip first as it is emitted immediately | ||||
|                 .observeOn(AndroidSchedulers.mainThread()) | ||||
|                 .subscribeUntilDestroy { | ||||
|             ConfiguringDialogController().showDialog(router) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) { | ||||
|         title = "E-Hentai" | ||||
|  | ||||
|         switchPreference { | ||||
|             title = "Enable ExHentai" | ||||
|             summaryOff = "Requires login" | ||||
|             key = "enable_exhentai" | ||||
|             key = PreferenceKeys.eh_enableExHentai | ||||
|             isPersistent = false | ||||
|             defaultValue = false | ||||
|             preferences.enableExhentai() | ||||
| @@ -33,8 +44,8 @@ class SettingsEhController : SettingsController() { | ||||
|                     .subscribeOn(Schedulers.io()) | ||||
|                     .observeOn(AndroidSchedulers.mainThread()) | ||||
|                     .subscribeUntilDestroy { | ||||
|                 isChecked = it | ||||
|            } | ||||
|                         isChecked = it | ||||
|                     } | ||||
|  | ||||
|             onChange { newVal -> | ||||
|                 newVal as Boolean | ||||
| @@ -55,7 +66,9 @@ class SettingsEhController : SettingsController() { | ||||
|             summary = "Do you wish to load images through the Hentai@Home Network? Disabling this option will reduce the amount of pages you are able to view" | ||||
|             key = "enable_hah" | ||||
|             defaultValue = true | ||||
|         } | ||||
|  | ||||
|             preferences.useHentaiAtHome().reconfigureOnChange() | ||||
|         }.dependency = PreferenceKeys.eh_enableExHentai | ||||
|  | ||||
|         switchPreference { | ||||
|             title = "Show Japanese titles in search results" | ||||
| @@ -63,7 +76,19 @@ class SettingsEhController : SettingsController() { | ||||
|             summaryOff = "Currently showing English/Romanized titles in search results. Clear the chapter cache after changing this (in the Advanced section)" | ||||
|             key = "use_jp_title" | ||||
|             defaultValue = false | ||||
|         } | ||||
|  | ||||
|             preferences.useJapaneseTitle().reconfigureOnChange() | ||||
|         }.dependency = PreferenceKeys.eh_enableExHentai | ||||
|  | ||||
|         switchPreference { | ||||
|             title = "Use original images" | ||||
|             summaryOn = "Currently using original images" | ||||
|             summaryOff = "Currently using resampled images" | ||||
|             key = PreferenceKeys.eh_useOrigImages | ||||
|             defaultValue = false | ||||
|  | ||||
|             preferences.eh_useOriginalImages().reconfigureOnChange() | ||||
|         }.dependency = PreferenceKeys.eh_enableExHentai | ||||
|  | ||||
|         switchPreference { | ||||
|             defaultValue = true | ||||
| @@ -93,45 +118,9 @@ class SettingsEhController : SettingsController() { | ||||
|                     "med", | ||||
|                     "low" | ||||
|             ) | ||||
|         } | ||||
|  | ||||
|         listPreference { | ||||
|             title = "Search result count per page" | ||||
|             summary = "Requires the 'Paging Enlargement' hath perk" | ||||
|             defaultValue = "rc_0" | ||||
|             key = "ex_search_size" | ||||
|             entries = arrayOf( | ||||
|                     "25 results", | ||||
|                     "50 results", | ||||
|                     "100 results", | ||||
|                     "200 results" | ||||
|             ) | ||||
|             entryValues = arrayOf( | ||||
|                     "rc_0", | ||||
|                     "rc_1", | ||||
|                     "rc_2", | ||||
|                     "rc_3" | ||||
|             ) | ||||
|         }.dependency = "enable_exhentai" | ||||
|  | ||||
|         listPreference { | ||||
|             defaultValue = "tr_2" | ||||
|             title = "Thumbnail rows" | ||||
|             summary = "Affects loading speeds. It is recommended to set this to the maximum size your hath perks allow" | ||||
|             key = "ex_thumb_rows" | ||||
|             entries = arrayOf( | ||||
|                     "4", | ||||
|                     "10 (requires 'More Thumbs' hath perk)", | ||||
|                     "20 (requires 'Thumbs Up' hath perk)", | ||||
|                     "40 (requires 'All Thumbs' hath perk)" | ||||
|             ) | ||||
|             entryValues = arrayOf( | ||||
|                     "tr_2", | ||||
|                     "tr_5", | ||||
|                     "tr_10", | ||||
|                     "tr_20" | ||||
|             ) | ||||
|         }.dependency = "enable_exhentai" | ||||
|             preferences.imageQuality().reconfigureOnChange() | ||||
|         }.dependency = PreferenceKeys.eh_enableExHentai | ||||
|  | ||||
|         preferenceCategory { | ||||
|             title = "Favorites sync" | ||||
|   | ||||
| @@ -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