Update MSM Extension. (#1061)
* Improve Preference-stub * Re-arrange some stubs to correct class. * Add `EditTextPreference`. * Update MSM extension. * Update filter. * Fix image fetch due to site changes (v4 -> v11) * Add BaseUrl Override for site domain changes. - Korean sources are change domain every 1-2 weeks due to internet censorship. * Add missing file `EditTextPreference.java` * Fix tags.
This commit is contained in:
parent
47e9e9389d
commit
9105f9aef8
@ -4,4 +4,20 @@ package android.support.v7.preference;
|
|||||||
* Created by Carlos on 5/9/2018.
|
* Created by Carlos on 5/9/2018.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public abstract class DialogPreference extends Preference {}
|
public abstract class DialogPreference extends Preference {
|
||||||
|
public CharSequence getDialogTitle() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDialogTitle(CharSequence dialogTitle) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence getDialogMessage() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDialogMessage(CharSequence dialogMessage) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package android.support.v7.preference;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
public class EditTextPreference extends DialogPreference {
|
||||||
|
public EditTextPreference(Context context) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setText(String text) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
}
|
@ -12,27 +12,12 @@ public class ListPreference extends Preference {
|
|||||||
throw new RuntimeException("Stub!");
|
throw new RuntimeException("Stub!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharSequence getTitle() {
|
|
||||||
throw new RuntimeException("Stub!");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTitle(CharSequence title) {
|
|
||||||
throw new RuntimeException("Stub!");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEntries(CharSequence[] entries) {
|
public void setEntries(CharSequence[] entries) {
|
||||||
throw new RuntimeException("Stub!");
|
throw new RuntimeException("Stub!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public CharSequence[] getEntries() {
|
public CharSequence[] getEntries() {
|
||||||
throw new RuntimeException("Stub!");
|
throw new RuntimeException("Stub!");
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOnPreferenceChangeListener(OnPreferenceChangeListener onPreferenceChangeListener) {
|
|
||||||
throw new RuntimeException("Stub!");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int findIndexOfValue(String value) {
|
public int findIndexOfValue(String value) {
|
||||||
@ -58,12 +43,4 @@ public class ListPreference extends Preference {
|
|||||||
public void setValue(String value) {
|
public void setValue(String value) {
|
||||||
throw new RuntimeException("Stub!");
|
throw new RuntimeException("Stub!");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSummary(CharSequence summary) {
|
|
||||||
throw new RuntimeException("Stub!");
|
|
||||||
}
|
|
||||||
|
|
||||||
public CharSequence getSummary() {
|
|
||||||
throw new RuntimeException("Stub!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,26 @@ public class Preference {
|
|||||||
boolean onPreferenceChange(Preference preference, Object newValue);
|
boolean onPreferenceChange(Preference preference, Object newValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setOnPreferenceChangeListener(OnPreferenceChangeListener onPreferenceChangeListener) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnPreferenceClickListener(OnPreferenceClickListener onPreferenceClickListener) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence getTitle() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(CharSequence title) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharSequence getSummary() {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
public void setKey(String key) {
|
public void setKey(String key) {
|
||||||
throw new RuntimeException("Stub!");
|
throw new RuntimeException("Stub!");
|
||||||
}
|
}
|
||||||
@ -16,4 +36,16 @@ public class Preference {
|
|||||||
public String getKey() {
|
public String getKey() {
|
||||||
throw new RuntimeException("Stub!");
|
throw new RuntimeException("Stub!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSummary(CharSequence summary) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDefaultValue(Object defaultValue) {
|
||||||
|
throw new RuntimeException("Stub!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnPreferenceClickListener {
|
||||||
|
boolean onPreferenceClick(Preference preference);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,13 @@ ext {
|
|||||||
appName = 'Tachiyomi: MangaShow.Me (ManaMoa)'
|
appName = 'Tachiyomi: MangaShow.Me (ManaMoa)'
|
||||||
pkgNameSuffix = 'ko.mangashowme'
|
pkgNameSuffix = 'ko.mangashowme'
|
||||||
extClass = '.MangaShowMe'
|
extClass = '.MangaShowMe'
|
||||||
extVersionCode = 10
|
extVersionCode = 11
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly project(':preference-stub')
|
||||||
|
compileOnly 'com.github.inorichi.injekt:injekt-core:65b0440'
|
||||||
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
@ -9,13 +9,15 @@ import okhttp3.Request
|
|||||||
|
|
||||||
// TODO: Completely Implement/Update Filters(Genre/Artist).
|
// TODO: Completely Implement/Update Filters(Genre/Artist).
|
||||||
private class TextField(name: String, val key: String) : Filter.Text(name)
|
private class TextField(name: String, val key: String) : Filter.Text(name)
|
||||||
private class SearchCheckBox(val id: Int, name: String) : Filter.CheckBox(name)
|
|
||||||
|
private class SearchCheckBox(name: String, val id: String = name) : Filter.CheckBox(name)
|
||||||
|
|
||||||
private class SearchMatch : Filter.Select<String>("Match", arrayOf("AND", "OR"))
|
private class SearchMatch : Filter.Select<String>("Match", arrayOf("AND", "OR"))
|
||||||
private class SearchGenresList(genres: List<SearchCheckBox>) : Filter.Group<SearchCheckBox>("Genres", genres)
|
private class SearchGenresList(genres: List<SearchCheckBox>) : Filter.Group<SearchCheckBox>("Genres", genres)
|
||||||
private class SearchNamingList : Filter.Select<String>("Naming", searchNaming())
|
private class SearchNamingList : Filter.Select<String>("Naming", searchNaming())
|
||||||
private class SearchStatusList : Filter.Select<String>("Status", searchStatus())
|
private class SearchStatusList : Filter.Select<String>("Status", searchStatus())
|
||||||
|
|
||||||
|
// [`"Not Set"`, ...[...document.querySelectorAll(".categories ul[data-type='1'] li")].map((el, i) => `"${el.innerText.trim()}"`)].join(',\n')
|
||||||
private fun searchNaming() = arrayOf(
|
private fun searchNaming() = arrayOf(
|
||||||
"Not Set",
|
"Not Set",
|
||||||
"ㄱ",
|
"ㄱ",
|
||||||
@ -41,6 +43,7 @@ private fun searchNaming() = arrayOf(
|
|||||||
"0-9"
|
"0-9"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// [`"Not Set"`, ...[...document.querySelectorAll(".categories ul[data-type='2'] li")].map((el, i) => `"${el.innerText.trim()}"`)].join(',\n')
|
||||||
private fun searchStatus() = arrayOf(
|
private fun searchStatus() = arrayOf(
|
||||||
"Not Set",
|
"Not Set",
|
||||||
"주간",
|
"주간",
|
||||||
@ -52,36 +55,36 @@ private fun searchStatus() = arrayOf(
|
|||||||
"완결"
|
"완결"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// [...document.querySelectorAll(".categories ul[data-type='3'] li")].map((el, i) => `SearchCheckBox("${el.innerText.trim()}")`).join(',\n')
|
||||||
private fun searchGenres() = listOf(
|
private fun searchGenres() = listOf(
|
||||||
SearchCheckBox(0, "17"),
|
SearchCheckBox("17"),
|
||||||
SearchCheckBox(0, "BL"),
|
SearchCheckBox("BL"),
|
||||||
SearchCheckBox(0, "SF"),
|
SearchCheckBox("SF"),
|
||||||
SearchCheckBox(0, "TS"),
|
SearchCheckBox("TS"),
|
||||||
SearchCheckBox(0, "개그"),
|
SearchCheckBox("개그"),
|
||||||
SearchCheckBox(0, "게임"),
|
SearchCheckBox("게임"),
|
||||||
SearchCheckBox(0, "공포"),
|
SearchCheckBox("공포"),
|
||||||
SearchCheckBox(0, "도박"),
|
SearchCheckBox("도박"),
|
||||||
SearchCheckBox(0, "드라마"),
|
SearchCheckBox("드라마"),
|
||||||
SearchCheckBox(0, "라노벨"),
|
SearchCheckBox("라노벨"),
|
||||||
SearchCheckBox(0, "러브코미디"),
|
SearchCheckBox("러브코미디"),
|
||||||
SearchCheckBox(0, "먹방"),
|
SearchCheckBox("먹방"),
|
||||||
SearchCheckBox(0, "백합"),
|
SearchCheckBox("백합"),
|
||||||
SearchCheckBox(0, "붕탁"),
|
SearchCheckBox("붕탁"),
|
||||||
SearchCheckBox(0, "순정"),
|
SearchCheckBox("순정"),
|
||||||
SearchCheckBox(0, "스릴러"),
|
SearchCheckBox("스릴러"),
|
||||||
SearchCheckBox(0, "스포츠"),
|
SearchCheckBox("스포츠"),
|
||||||
SearchCheckBox(0, "시대"),
|
SearchCheckBox("시대"),
|
||||||
SearchCheckBox(0, "애니화"),
|
SearchCheckBox("애니화"),
|
||||||
SearchCheckBox(0, "액션"),
|
SearchCheckBox("액션"),
|
||||||
SearchCheckBox(0, "역사"),
|
SearchCheckBox("음악"),
|
||||||
SearchCheckBox(0, "음악"),
|
SearchCheckBox("이세계"),
|
||||||
SearchCheckBox(0, "이세계"),
|
SearchCheckBox("일상"),
|
||||||
SearchCheckBox(0, "일상"),
|
SearchCheckBox("전생"),
|
||||||
SearchCheckBox(0, "전생"),
|
SearchCheckBox("추리"),
|
||||||
SearchCheckBox(0, "추리"),
|
SearchCheckBox("판타지"),
|
||||||
SearchCheckBox(0, "판타지"),
|
SearchCheckBox("학원"),
|
||||||
SearchCheckBox(0, "학원"),
|
SearchCheckBox("호러")
|
||||||
SearchCheckBox(0, "호러")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
fun getFilters() = FilterList(
|
fun getFilters() = FilterList(
|
||||||
@ -136,7 +139,7 @@ fun searchComplexFilterMangaRequestBuilder(baseUrl: String, page: Int, query: St
|
|||||||
is SearchGenresList -> {
|
is SearchGenresList -> {
|
||||||
filter.state.forEach {
|
filter.state.forEach {
|
||||||
if (it.state) {
|
if (it.state) {
|
||||||
genresFilter.add(it.name)
|
genresFilter.add(it.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
package eu.kanade.tachiyomi.extension.ko.mangashowme
|
package eu.kanade.tachiyomi.extension.ko.mangashowme
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import android.support.v7.preference.EditTextPreference
|
||||||
|
import android.support.v7.preference.PreferenceScreen
|
||||||
|
import android.widget.Toast
|
||||||
|
import eu.kanade.tachiyomi.extension.BuildConfig
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
import eu.kanade.tachiyomi.source.model.*
|
import eu.kanade.tachiyomi.source.model.*
|
||||||
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
@ -12,6 +19,8 @@ import org.json.JSONArray
|
|||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import org.jsoup.nodes.Element
|
import org.jsoup.nodes.Element
|
||||||
import org.jsoup.select.Elements
|
import org.jsoup.select.Elements
|
||||||
|
import uy.kohesive.injekt.Injekt
|
||||||
|
import uy.kohesive.injekt.api.get
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -22,9 +31,10 @@ import java.util.concurrent.TimeUnit
|
|||||||
* PS. There's no Popular section. It's just a list of manga. Also not latest updates.
|
* PS. There's no Popular section. It's just a list of manga. Also not latest updates.
|
||||||
* `manga_list` returns latest 'added' manga. not a chapter updates.
|
* `manga_list` returns latest 'added' manga. not a chapter updates.
|
||||||
**/
|
**/
|
||||||
class MangaShowMe : ParsedHttpSource() {
|
class MangaShowMe : ConfigurableSource, ParsedHttpSource() {
|
||||||
override val name = "MangaShow.Me"
|
override val name = "MangaShow.Me"
|
||||||
override val baseUrl = "https://manamoa2.net"
|
private val defaultBaseUrl = "https://manamoa3.net"
|
||||||
|
override val baseUrl by lazy { getPrefBaseUrl() }
|
||||||
override val lang: String = "ko"
|
override val lang: String = "ko"
|
||||||
|
|
||||||
// Latest updates currently returns duplicate manga as it separates manga into chapters
|
// Latest updates currently returns duplicate manga as it separates manga into chapters
|
||||||
@ -37,15 +47,23 @@ class MangaShowMe : ParsedHttpSource() {
|
|||||||
val req = chain.request()
|
val req = chain.request()
|
||||||
|
|
||||||
// only for image Request
|
// only for image Request
|
||||||
if (!req.url().host().contains("filecdn.xyz")) return@addInterceptor chain.proceed(req)
|
val isFileCdn = !req.url().host().contains(".filecdn.xyz")
|
||||||
|
if (!req.url().toString().endsWith("?quick")) return@addInterceptor chain.proceed(req)
|
||||||
|
|
||||||
val secondUrl = req.header("SecondUrlToRequest")
|
val secondUrl = req.header("SecondUrlToRequest")
|
||||||
|
|
||||||
fun get(flag: Int = 0): Request {
|
fun get(flag: Int = 0): Request {
|
||||||
val url = when (flag) {
|
val url = if (isFileCdn) {
|
||||||
1 -> req.url().toString().replace("img.", "s3.")
|
when (flag) {
|
||||||
2 -> secondUrl!!
|
1 -> req.url().toString().replace("img.", "s3.")
|
||||||
else -> req.url().toString()
|
else -> req.url().toString()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
when (flag) {
|
||||||
|
1 -> secondUrl!!
|
||||||
|
2 -> secondUrl!!.replace("img.", "s3.")
|
||||||
|
else -> req.url().toString().substringBefore("?quick")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return req.newBuilder()!!.url(url)
|
return req.newBuilder()!!.url(url)
|
||||||
@ -55,13 +73,21 @@ class MangaShowMe : ParsedHttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val res = chain.proceed(get())
|
val res = chain.proceed(get())
|
||||||
val length = res.header("content-length")
|
|
||||||
if (length == null || length.toInt() < 50000) {
|
if (isFileCdn) {
|
||||||
val s3res = chain.proceed(get(1)) // s3
|
val length = res.header("content-length")
|
||||||
if (!s3res.isSuccessful && secondUrl != null) {
|
if (length == null || length.toInt() < 50000) {
|
||||||
chain.proceed(get(2)) // secondUrl
|
chain.proceed(get(1)) // s3
|
||||||
} else s3res
|
} else res
|
||||||
} else res
|
} else {
|
||||||
|
if (!res.isSuccessful && secondUrl != null) {
|
||||||
|
val fallbackRes = chain.proceed(get(1)) // img filecdn
|
||||||
|
val fallbackLength = fallbackRes.header("content-length")
|
||||||
|
if (fallbackLength == null || fallbackLength.toInt() < 50000) {
|
||||||
|
chain.proceed(get(2)) // s3
|
||||||
|
} else fallbackRes
|
||||||
|
} else res
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.build()!!
|
.build()!!
|
||||||
|
|
||||||
@ -116,7 +142,7 @@ class MangaShowMe : ParsedHttpSource() {
|
|||||||
val mangaChaptersLike = mangaElementsSum(document.select(".title i.fa.fa-thumbs-up > span"))
|
val mangaChaptersLike = mangaElementsSum(document.select(".title i.fa.fa-thumbs-up > span"))
|
||||||
val mangaComments = mangaElementsSum(document.select(".title i.fa.fa-comment > span"))
|
val mangaComments = mangaElementsSum(document.select(".title i.fa.fa-comment > span"))
|
||||||
val genres = mutableListOf<String>()
|
val genres = mutableListOf<String>()
|
||||||
document.select("div.left-info > .manga-tags > a.tag").forEach {
|
document.select("div.left-info div.information > .manga-tags > a.tag").forEach {
|
||||||
genres.add(it.text())
|
genres.add(it.text())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,10 +249,10 @@ class MangaShowMe : ParsedHttpSource() {
|
|||||||
.map { imageUrls.getString(it) }
|
.map { imageUrls.getString(it) }
|
||||||
.forEach { pages.add(Page(pages.size, decoder.request(it), "${it.substringBefore("!!")}?quick")) }
|
.forEach { pages.add(Page(pages.size, decoder.request(it), "${it.substringBefore("!!")}?quick")) }
|
||||||
} else {
|
} else {
|
||||||
(0 until imageUrls.length())
|
(0 until imageUrls1.length())
|
||||||
.map {
|
.map {
|
||||||
imageUrls.getString(it) + try {
|
imageUrls1.getString(it) + try {
|
||||||
"!!${imageUrls1.getString(it)}"
|
"!!${imageUrls.getString(it)}?quick"
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
@ -287,9 +313,45 @@ class MangaShowMe : ParsedHttpSource() {
|
|||||||
url[1].replace("&", "%26").replace("#", "%23")
|
url[1].replace("&", "%26").replace("#", "%23")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private val preferences: SharedPreferences by lazy {
|
||||||
|
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||||
|
val baseUrlPref = EditTextPreference(screen.context).apply {
|
||||||
|
key = BASE_URL_PREF_TITLE
|
||||||
|
title = BASE_URL_PREF_TITLE
|
||||||
|
summary = BASE_URL_PREF_SUMMARY
|
||||||
|
this.setDefaultValue(defaultBaseUrl)
|
||||||
|
dialogTitle = BASE_URL_PREF_TITLE
|
||||||
|
dialogMessage = "Default: $defaultBaseUrl"
|
||||||
|
|
||||||
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
try {
|
||||||
|
val res = preferences.edit().putString(BASE_URL_PREF, newValue as String).commit()
|
||||||
|
Toast.makeText(screen.context, RESTART_TACHIYOMI, Toast.LENGTH_LONG).show()
|
||||||
|
res
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
screen.addPreference(baseUrlPref)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getPrefBaseUrl(): String = preferences.getString(BASE_URL_PREF, defaultBaseUrl)
|
||||||
|
|
||||||
override fun getFilterList() = getFilters()
|
override fun getFilterList() = getFilters()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
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."
|
||||||
|
private const val RESTART_TACHIYOMI = "Restart Tachiyomi to apply new setting."
|
||||||
|
|
||||||
internal const val V1_CX = 5
|
internal const val V1_CX = 5
|
||||||
internal const val V1_CY = 5
|
internal const val V1_CY = 5
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user