diff --git a/lib/preference-stub/src/main/java/android/support/v7/preference/CheckBoxPreference.java b/lib/preference-stub/src/main/java/android/support/v7/preference/CheckBoxPreference.java new file mode 100644 index 000000000..7d503ec74 --- /dev/null +++ b/lib/preference-stub/src/main/java/android/support/v7/preference/CheckBoxPreference.java @@ -0,0 +1,9 @@ +package android.support.v7.preference; + +import android.content.Context; + +public class CheckBoxPreference extends Preference { + + public CheckBoxPreference(Context context) { throw new RuntimeException("Stub!"); } + +} diff --git a/lib/preference-stub/src/main/java/android/support/v7/preference/Preference.java b/lib/preference-stub/src/main/java/android/support/v7/preference/Preference.java index beda8ba9d..1884e02c2 100644 --- a/lib/preference-stub/src/main/java/android/support/v7/preference/Preference.java +++ b/lib/preference-stub/src/main/java/android/support/v7/preference/Preference.java @@ -26,6 +26,10 @@ public class Preference { throw new RuntimeException("Stub!"); } + public void setEnabled(boolean enabled) { + throw new RuntimeException("Stub!"); + } + public String getKey() { throw new RuntimeException("Stub!"); } diff --git a/lib/preference-stub/src/main/java/android/support/v7/preference/TwoStatePreference.java b/lib/preference-stub/src/main/java/android/support/v7/preference/TwoStatePreference.java new file mode 100644 index 000000000..ef21669ce --- /dev/null +++ b/lib/preference-stub/src/main/java/android/support/v7/preference/TwoStatePreference.java @@ -0,0 +1,25 @@ +package android.support.v7.preference; + +import android.content.Context; + +public class TwoStatePreference extends Preference { + + public TwoStatePreference(Context context) { throw new RuntimeException("Stub!"); } + + public boolean isChecked() { throw new RuntimeException("Stub!"); } + + public void setChecked(boolean checked) { throw new RuntimeException("Stub!"); } + + public CharSequence getSummaryOn() { throw new RuntimeException("Stub!"); } + + public void setSummaryOn(CharSequence summary) { throw new RuntimeException("Stub!"); } + + public CharSequence getSummaryOff() { throw new RuntimeException("Stub!"); } + + public void setSummaryOff(CharSequence summary) { throw new RuntimeException("Stub!"); } + + public boolean getDisableDependentsState() { throw new RuntimeException("Stub!"); } + + public void setDisableDependentsState(boolean disableDependentsState) { throw new RuntimeException("Stub!"); } + +} diff --git a/lib/preference-stub/src/main/java/androidx/preference/CheckBoxPreference.java b/lib/preference-stub/src/main/java/androidx/preference/CheckBoxPreference.java new file mode 100644 index 000000000..6c986abd1 --- /dev/null +++ b/lib/preference-stub/src/main/java/androidx/preference/CheckBoxPreference.java @@ -0,0 +1,11 @@ +package androidx.preference; + +import android.content.Context; + +public class CheckBoxPreference extends Preference { + + public CheckBoxPreference(Context context) { + throw new RuntimeException("Stub!"); + } + +} diff --git a/lib/preference-stub/src/main/java/androidx/preference/Preference.java b/lib/preference-stub/src/main/java/androidx/preference/Preference.java index e0b94c403..502c39f45 100644 --- a/lib/preference-stub/src/main/java/androidx/preference/Preference.java +++ b/lib/preference-stub/src/main/java/androidx/preference/Preference.java @@ -26,6 +26,10 @@ public class Preference { throw new RuntimeException("Stub!"); } + public void setEnabled(boolean enabled) { + throw new RuntimeException("Stub!"); + } + public String getKey() { throw new RuntimeException("Stub!"); } diff --git a/lib/preference-stub/src/main/java/androidx/preference/TwoStatePreference.java b/lib/preference-stub/src/main/java/androidx/preference/TwoStatePreference.java new file mode 100644 index 000000000..6d0565699 --- /dev/null +++ b/lib/preference-stub/src/main/java/androidx/preference/TwoStatePreference.java @@ -0,0 +1,25 @@ +package androidx.preference; + +import android.content.Context; + +public class TwoStatePreference extends Preference { + + public TwoStatePreference(Context context) { throw new RuntimeException("Stub!"); } + + public boolean isChecked() { throw new RuntimeException("Stub!"); } + + public void setChecked(boolean checked) { throw new RuntimeException("Stub!"); } + + public CharSequence getSummaryOn() { throw new RuntimeException("Stub!"); } + + public void setSummaryOn(CharSequence summary) { throw new RuntimeException("Stub!"); } + + public CharSequence getSummaryOff() { throw new RuntimeException("Stub!"); } + + public void setSummaryOff(CharSequence summary) { throw new RuntimeException("Stub!"); } + + public boolean getDisableDependentsState() { throw new RuntimeException("Stub!"); } + + public void setDisableDependentsState(boolean disableDependentsState) { throw new RuntimeException("Stub!"); } + +} diff --git a/src/ko/mangashowme/build.gradle b/src/ko/mangashowme/build.gradle index b89a85c57..bd0a86336 100644 --- a/src/ko/mangashowme/build.gradle +++ b/src/ko/mangashowme/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: ManaMoa' pkgNameSuffix = 'ko.mangashowme' extClass = '.ManaMoa' - extVersionCode = 16 + extVersionCode = 17 libVersion = '1.2' } diff --git a/src/ko/mangashowme/src/eu/kanade/tachiyomi/extension/ko/mangashowme/MSMImageDecoder.kt b/src/ko/mangashowme/src/eu/kanade/tachiyomi/extension/ko/mangashowme/MSMImageDecoder.kt index 9bc5b8178..04be8a331 100644 --- a/src/ko/mangashowme/src/eu/kanade/tachiyomi/extension/ko/mangashowme/MSMImageDecoder.kt +++ b/src/ko/mangashowme/src/eu/kanade/tachiyomi/extension/ko/mangashowme/MSMImageDecoder.kt @@ -11,6 +11,11 @@ import okhttp3.ResponseBody import java.io.ByteArrayOutputStream import java.io.IOException import java.io.InputStream +import kotlin.math.cos +import kotlin.math.floor +import kotlin.math.sin +import kotlin.math.tan + /* * `v1` means url padding of image host. @@ -19,7 +24,7 @@ import java.io.InputStream internal class ImageDecoder(scripts: String) { private val cnt = substringBetween(scripts, "var view_cnt = ", ";") - .toIntOrNull() ?: 0 + .toIntOrNull() ?: 0 private val chapter = substringBetween(scripts, "var chapter = ", ";") .toIntOrNull() ?: 0 @@ -73,28 +78,27 @@ internal class ImageDecoderInterceptor : Interceptor { * * MIT License * - * * Copyright (c) 2019 junheah */ - private fun imageDecoder(input: Bitmap, chapter: Int, view_cnt: Int, half: Int = 0, _CX: Int = ManaMoa.V1_CX, _CY: Int = ManaMoa.V1_CY): Bitmap { + private fun imageDecoder(input: Bitmap, chapter: Int, view_cnt: Int, half: Int = 0): Bitmap { if (view_cnt == 0) return input val viewCnt = view_cnt / 10 - var CX = _CX - var CY = _CY + var cx = ManaMoa.V1_CX + var cy = ManaMoa.V1_CY //view_cnt / 10 > 30000 ? (this._CX = 1, this._CY = 6) : view_cnt / 10 > 20000 ? this._CX = 1 : view_cnt / 10 > 10000 && (this._CY = 1) // DO NOT (AUTOMATICALLY) REPLACE TO when USING IDEA. seems it doesn't detect correct condition if (viewCnt > 30000) { - CX = 1 - CY = 6 + cx = 1 + cy = 6 } else if (viewCnt > 20000) { - CX = 1 + cx = 1 } else if (viewCnt > 10000) { - CY = 1 + cy = 1 } //decode image - val order = Array(CX * CY) { IntArray(2) } + val order = Array(cx * cy) { IntArray(2) } val oSize = order.size - 1 for (i in 0..oSize) { @@ -102,22 +106,22 @@ internal class ImageDecoderInterceptor : Interceptor { order[i][1] = decoderRandom(chapter, viewCnt, i) } - java.util.Arrays.sort(order) { a, b -> java.lang.Double.compare(a[1].toDouble(), b[1].toDouble()) } + java.util.Arrays.sort(order) { a, b -> a[1].toDouble().compareTo(b[1].toDouble()) } //create new bitmap val outputWidth = if (half == 0) input.width else input.width / 2 val output = Bitmap.createBitmap(outputWidth, input.height, Bitmap.Config.ARGB_8888) val canvas = Canvas(output) - val rowWidth = input.width / CX - val rowHeight = input.height / CY + val rowWidth = input.width / cx + val rowHeight = input.height / cy for (i in 0..oSize) { val o = order[i] - val ox = i % CX - val oy = i / CX - val tx = o[0] % CX - val ty = o[0] / CX + val ox = i % cx + val oy = i / cx + val tx = o[0] % cx + val ty = o[0] / cx val sx = if (half == 2) -input.width / 2 else 0 val srcX = ox * rowWidth @@ -126,9 +130,9 @@ internal class ImageDecoderInterceptor : Interceptor { val destY = ty * rowHeight canvas.drawBitmap(input, - Rect(srcX, srcY, srcX + rowWidth, srcY + rowHeight), - Rect(destX, destY, destX + rowWidth, destY + rowHeight), - null) + Rect(srcX, srcY, srcX + rowWidth, srcY + rowHeight), + Rect(destX, destY, destX + rowWidth, destY + rowHeight), + null) } return output @@ -144,21 +148,21 @@ internal class ImageDecoderInterceptor : Interceptor { */ private fun decoderRandom(chapter: Int, view_cnt: Int, index: Int): Int { if (chapter < 554714) { - val x = 10000 * Math.sin((view_cnt + index).toDouble()) - return Math.floor(100000 * (x - Math.floor(x))).toInt() + val x = 10000 * sin((view_cnt + index).toDouble()) + return floor(100000 * (x - floor(x))).toInt() } val seed = view_cnt + index + 1 - val t = 100 * Math.sin((10 * seed).toDouble()) - val n = 1000 * Math.cos((13 * seed).toDouble()) - val a = 10000 * Math.tan((14 * seed).toDouble()) + val t = 100 * sin((10 * seed).toDouble()) + val n = 1000 * cos((13 * seed).toDouble()) + val a = 10000 * tan((14 * seed).toDouble()) - return (Math.floor(100 * (t - Math.floor(t))) + - Math.floor(1000 * (n - Math.floor(n))) + - Math.floor(10000 * (a - Math.floor(a)))).toInt() + return (floor(100 * (t - floor(t))) + + floor(1000 * (n - floor(n))) + + floor(10000 * (a - floor(a)))).toInt() } } private fun substringBetween(target: String, prefix: String, suffix: String): String = { target.substringAfter(prefix).substringBefore(suffix) -}() \ No newline at end of file +}() diff --git a/src/ko/mangashowme/src/eu/kanade/tachiyomi/extension/ko/mangashowme/MangaShowMe.kt b/src/ko/mangashowme/src/eu/kanade/tachiyomi/extension/ko/mangashowme/MangaShowMe.kt index 9cf6c5646..301aa6f9e 100644 --- a/src/ko/mangashowme/src/eu/kanade/tachiyomi/extension/ko/mangashowme/MangaShowMe.kt +++ b/src/ko/mangashowme/src/eu/kanade/tachiyomi/extension/ko/mangashowme/MangaShowMe.kt @@ -1,8 +1,11 @@ package eu.kanade.tachiyomi.extension.ko.mangashowme import android.annotation.SuppressLint +import android.annotation.TargetApi import android.app.Application import android.content.SharedPreferences +import android.os.Build +import android.support.v7.preference.CheckBoxPreference import android.support.v7.preference.EditTextPreference import android.support.v7.preference.PreferenceScreen import android.widget.Toast @@ -12,19 +15,20 @@ import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.util.asJsoup -import okhttp3.OkHttpClient -import okhttp3.Request -import okhttp3.Response +import okhttp3.* import org.json.JSONArray import org.jsoup.nodes.Document import org.jsoup.nodes.Element import org.jsoup.select.Elements import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import java.io.IOException import java.text.SimpleDateFormat import java.util.* +import java.util.concurrent.CompletableFuture import java.util.concurrent.TimeUnit + /** * ManaMoa Source * @@ -39,9 +43,9 @@ class ManaMoa : ConfigurableSource, ParsedHttpSource() { override val name = "ManaMoa" - // This keeps updating: https://twitter.com/manamoa20 - private val defaultBaseUrl = "https://manamoa23.net" - override val baseUrl by lazy { getPrefBaseUrl() } + // This keeps updating: https://twitter.com/manamoa24 + private val defaultBaseUrl = "https://manamoa26.net" + override val baseUrl by lazy { getCurrentBaseUrl() } override val lang: String = "ko" @@ -99,14 +103,14 @@ class ManaMoa : ConfigurableSource, ParsedHttpSource() { override fun mangaDetailsParse(document: Document): SManga { val info = document.select("div.left-info").first() val thumbnailElement = info.select("div.manga-thumbnail").first() - val publishTypeText = trimElementText(thumbnailElement.select("a.publish_type"), "Unknown") - val authorText = trimElementText(thumbnailElement.select("a.author")) + val publishTypeText = thumbnailElement.select("a.publish_type").trimText("Unknown") + val authorText = thumbnailElement.select("a.author").trimText() val mangaStatus = info.select("div.recommend") - val mangaLike = trimElementText(mangaStatus.select(".fa-thumbs-up"), "0") + val mangaLike = mangaStatus.select(".fa-thumbs-up").trimText("0") //val mangaViews = trimElementText(mangaStatus.select(".fa-smile-o"), "0") - val mangaComments = trimElementText(mangaStatus.select(".fa-comment"), "0") - val mangaBookmarks = trimElementText(info.select(".fa-bookmark"), "0") + val mangaComments = mangaStatus.select(".fa-comment").trimText("0") + val mangaBookmarks = info.select(".fa-bookmark").trimText("0") val mangaChaptersLike = mangaElementsSum(document.select(".title i.fa.fa-thumbs-up > span")) val mangaChaptersComments = mangaElementsSum(document.select(".title i.fa.fa-comment > span")) @@ -269,8 +273,8 @@ class ManaMoa : ConfigurableSource, ParsedHttpSource() { return style.substringAfter("background-image:url(").substringBefore(")") } - private fun trimElementText(element: Elements, fallback: String = ""): String { - return element.text()?.trim()?.takeUnless { it.isBlank() } ?: fallback + private fun Elements.trimText(fallback: String = ""): String { + return this.text()?.trim()?.takeUnless { it.isBlank() } ?: fallback } private val preferences: SharedPreferences by lazy { @@ -298,7 +302,26 @@ class ManaMoa : ConfigurableSource, ParsedHttpSource() { } } + val autoFetchUrlPref = androidx.preference.CheckBoxPreference (screen.context).apply { + key = AUTOFETCH_URL_PREF_TITLE + title = AUTOFETCH_URL_PREF_TITLE + summary = AUTOFETCH_URL_PREF_SUMMARY + this.setEnabled(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + + setOnPreferenceChangeListener { _, newValue -> + try { + val res = preferences.edit().putBoolean(AUTOFETCH_URL_PREF, newValue as Boolean).commit() + Toast.makeText(screen.context, RESTART_TACHIYOMI, Toast.LENGTH_LONG).show() + res + } catch (e: Exception) { + e.printStackTrace() + false + } + } + } + screen.addPreference(baseUrlPref) + screen.addPreference(autoFetchUrlPref) } override fun setupPreferenceScreen(screen: PreferenceScreen) { @@ -322,17 +345,82 @@ class ManaMoa : ConfigurableSource, ParsedHttpSource() { } } + val autoFetchUrlPref = CheckBoxPreference(screen.context).apply { + key = AUTOFETCH_URL_PREF_TITLE + title = AUTOFETCH_URL_PREF_TITLE + summary = AUTOFETCH_URL_PREF_SUMMARY + this.setEnabled(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + + setOnPreferenceChangeListener { _, newValue -> + try { + val res = preferences.edit().putBoolean(AUTOFETCH_URL_PREF, newValue as Boolean).commit() + Toast.makeText(screen.context, RESTART_TACHIYOMI, Toast.LENGTH_LONG).show() + res + } catch (e: Exception) { + e.printStackTrace() + false + } + } + } + screen.addPreference(baseUrlPref) + screen.addPreference(autoFetchUrlPref) } + private fun getCurrentBaseUrl(): String { + val prefBaseUrl = getPrefBaseUrl() + if (!preferences.getBoolean(AUTOFETCH_URL_PREF, false)) { + return prefBaseUrl + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + try { + @TargetApi(Build.VERSION_CODES.N) + class CallbackFuture : CompletableFuture(), Callback { + override fun onResponse(call: Call?, response: Response?) { + super.complete(response) + } + + override fun onFailure(call: Call?, e: IOException?) { + super.completeExceptionally(e) + } + } + + val request: Request = Request.Builder().get() + .url("http://13.229.223.203") + .build() + + val future = CallbackFuture() + network.client.newCall(request).enqueue(future) + + val response = future.get()!! + return "https://${response.request().url().host()}" + } catch (e: Exception) { + e.printStackTrace() + return prefBaseUrl + } + } else { + return prefBaseUrl + } + } + + private fun getPrefBaseUrl(): String = preferences.getString(BASE_URL_PREF, defaultBaseUrl)!! override fun getFilterList() = getFilters() companion object { + // Setting: Override BaseUrl private const val BASE_URL_PREF_TITLE = "Override BaseUrl" private const val BASE_URL_PREF = "overrideBaseUrl_v${BuildConfig.VERSION_NAME}" private const val BASE_URL_PREF_SUMMARY = "For temporary uses. Update extension will erase this setting." + // Setting: Fetch Domain + private const val AUTOFETCH_URL_PREF_TITLE = "Automatically fetch new domain" + private const val AUTOFETCH_URL_PREF = "autoFetchNewUrl" + private const val AUTOFETCH_URL_PREF_SUMMARY = + "Experimental, May cause Tachiyomi unstable.\n" + + "Requires Android Nougat or newer." + private const val RESTART_TACHIYOMI = "Restart Tachiyomi to apply new setting." // Image Decoder