Skip to content

Commit 3bc8b08

Browse files
committed
removed Azynovel due to not existing
removed RanobesProvider due to capcha added cloudflarekiller to MTLNovel (still not working) fixed NovelFull+AllNovel pages fixed TTS Lock made overscroll more sensative bump
1 parent b0e425e commit 3bc8b08

File tree

6 files changed

+153
-99
lines changed

6 files changed

+153
-99
lines changed

app/build.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ android {
1414
applicationId "com.lagradost.quicknovel"
1515
minSdkVersion 22
1616
targetSdkVersion 33
17-
versionCode 52
18-
versionName "3.1.2"
17+
versionCode 53
18+
versionName "3.1.3"
1919
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
2020
}
2121

app/src/main/java/com/lagradost/quicknovel/ReadActivity2.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -524,11 +524,11 @@ class ReadActivity2 : AppCompatActivity(), ColorPickerDialogListener {
524524
val topScroll = top.top - getTopY()
525525
lockTop = currentScroll + topScroll
526526
val bottomScroll =
527-
bottom.bottom - getBottomY() + if (binding.readOverlay.isVisible) binding.readOverlay.height else 0
527+
bottom.bottom - getBottomY()
528528
lockBottom = currentScroll + bottomScroll
529529

530530
// binding.tmpTtsStart.fixLine(top.top)
531-
// binding.tmpTtsEnd.fixLine(bottom.bottom)
531+
//binding.tmpTtsEnd.fixLine(bottom.bottom)
532532

533533
// we have reached the end, scroll to the top
534534
if (bottomScroll > 0) {
@@ -953,12 +953,12 @@ class ReadActivity2 : AppCompatActivity(), ColorPickerDialogListener {
953953
if (event.historySize <= 1) return@setOnTouchListener false
954954
val start = event.getHistoricalY(0, event.historySize - 1)
955955
val end = event.getY(0)
956-
val dy = (end - start).div(Resources.getSystem().displayMetrics.density).coerceIn(-1.0f,1.0f)
956+
val dy = (end - start).div(Resources.getSystem().displayMetrics.density).coerceIn(-2.0f,2.0f)
957957
// if cant scroll in the direction then translate Y with the dy
958958
val translated = !canScrollVertically(-1) || !canScrollVertically(1)
959959
if (translated) {
960960
// * (maxScrollOver - currentOverScroll.absoluteValue))
961-
currentOverScroll += dy * 0.3f
961+
currentOverScroll += dy * 0.4f
962962
}
963963

964964
// if we can scroll down then we cant translate down
@@ -1026,7 +1026,7 @@ class ReadActivity2 : AppCompatActivity(), ColorPickerDialogListener {
10261026
currentScroll += dy
10271027
val delta = rdy - dy
10281028
if (delta != 0 && canScrollVertically(delta)) {
1029-
updateFromCode = true
1029+
//updateFromCode = true
10301030
scrollBy(0, delta)
10311031
}
10321032
} else {

app/src/main/java/com/lagradost/quicknovel/providers/AllNovelProvider.kt

+53-33
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import com.lagradost.quicknovel.*
44
import com.lagradost.quicknovel.MainActivity.Companion.app
55
import org.jsoup.Jsoup
66

7-
class AllNovelProvider : MainAPI() {
7+
open class AllNovelProvider : MainAPI() {
88
override val name = "AllNovel"
99
override val mainUrl = "https://allnovel.org"
1010
override val hasMainPage = true
@@ -64,55 +64,75 @@ class AllNovelProvider : MainAPI() {
6464
Pair("invayne", "invayne"),
6565
Pair("LitRPG", "LitRPG"),
6666
Pair("LGBT", "LGBT"),
67-
Pair(
68-
"Comedy Drama Romance Shounen Ai Supernatural",
69-
"Comedy Drama Romance Shounen Ai Supernatural"
70-
),
67+
"Comedy" to "Comedy",
68+
"Drama" to "Drama",
69+
"Shounen+Ai" to "Shounen+Ai",
70+
"Supernatural" to "Supernatural",
7171
Pair("Shoujo Ai", "Shoujo Ai"),
7272
Pair("Supernatura", "Supernatura"),
7373
Pair("Canopy", "Canopy")
7474
)
7575

76+
override val orderBys = listOf(
77+
"Genre" to "",
78+
"Latest Release" to "latest-release-novel",
79+
"Hot Novel" to "hot-novel",
80+
"Completed Novel" to "completed-novel",
81+
"Most Popular" to "most-popular",
82+
)
83+
84+
7685
override suspend fun loadMainPage(
7786
page: Int,
7887
mainCategory: String?,
7988
orderBy: String?,
8089
tag: String?
8190
): HeadMainPageResponse {
82-
val firstresponse = app.get(mainUrl)
83-
val firstdocument = Jsoup.parse(firstresponse.text)
84-
fun getId(tagvalue: String?): String? {
85-
return firstdocument.select("#hot-genre-select>option")
86-
.firstOrNull { it.text() == tagvalue }?.attr("value")
87-
}
88-
89-
// I cant fix this because idk how it works
90-
val url = "$mainUrl/ajax-search?type=hot&genre=${getId(tag)}"
91-
val response = app.get(url)
92-
val document = Jsoup.parse(response.text)
93-
val headers = document.select("div.item")
94-
if (headers.size <= 0) return HeadMainPageResponse(url, ArrayList())
95-
val returnValue: ArrayList<SearchResponse> = ArrayList()
96-
for (h in headers) {
97-
val h3 = h?.selectFirst("a")
98-
val cUrl = mainUrl + h3?.attr("href")
99-
val name = h3?.attr("title") ?: throw ErrorLoadingException("Invalid name")
91+
val url =
92+
if (orderBy == "" && tag != "All") "$mainUrl/genre/$tag?page=$page" else "$mainUrl/${if (orderBy.isNullOrBlank()) "hot-novel" else orderBy}?page=$page"
93+
val document = app.get(url).document
10094

101-
val posterUrl =
102-
mainUrl + h.selectFirst("img")?.attr("src")
103-
104-
returnValue.add(
95+
return HeadMainPageResponse(
96+
url,
97+
list = document.select("div.list>div.row").mapNotNull { element ->
98+
val a =
99+
element.selectFirst("div > div > h3.truyen-title > a") ?: return@mapNotNull null
105100
SearchResponse(
106-
name,
107-
cUrl,
108-
fixUrlNull(posterUrl),
101+
name = a.text(),
102+
url = fixUrlNull(a.attr("href")) ?: return@mapNotNull null,
103+
fixUrlNull(element.selectFirst("div > div > img")?.attr("src")),
109104
null,
110105
null,
111106
this.name
112107
)
113-
)
114-
}
115-
return HeadMainPageResponse(url, returnValue)
108+
})
109+
110+
/*val url = "$mainUrl/ajax-search?type=hot&genre=${getId(tag)}"
111+
val response = app.get(url)
112+
val document = Jsoup.parse(response.text)
113+
val headers = document.select("div.item")
114+
if (headers.size <= 0) return HeadMainPageResponse(url, ArrayList())
115+
val returnValue: ArrayList<SearchResponse> = ArrayList()
116+
for (h in headers) {
117+
val h3 = h?.selectFirst("a")
118+
val cUrl = mainUrl + h3?.attr("href")
119+
val name = h3?.attr("title") ?: throw ErrorLoadingException("Invalid name")
120+
121+
val posterUrl =
122+
mainUrl + h.selectFirst("img")?.attr("src")
123+
124+
returnValue.add(
125+
SearchResponse(
126+
name,
127+
cUrl,
128+
fixUrlNull(posterUrl),
129+
null,
130+
null,
131+
this.name
132+
)
133+
)
134+
}
135+
return HeadMainPageResponse(url, returnValue)*/
116136
}
117137

118138
override suspend fun loadHtml(url: String): String? {

app/src/main/java/com/lagradost/quicknovel/providers/MtlNovelsProvider.kt

+78-52
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty
44
import com.fasterxml.jackson.module.kotlin.readValue
55
import com.lagradost.quicknovel.*
66
import com.lagradost.quicknovel.MainActivity.Companion.app
7+
import com.lagradost.quicknovel.network.CloudflareKiller
78
import org.jsoup.Jsoup
89

910
class MtlNovelProvider : MainAPI() {
@@ -17,47 +18,48 @@ class MtlNovelProvider : MainAPI() {
1718

1819
override val tags = listOf(
1920
Pair("All", ""),
20-
Pair("Adult","adult"),
21-
Pair("Adventure","adventure"),
22-
Pair("Comedy","comedy"),
23-
Pair("Drama","drama"),
24-
Pair("Ecchi","ecchi"),
25-
Pair("Erciyuan","erciyuan"),
26-
Pair("Fan-Fiction","fan-fiction"),
27-
Pair("Fantasy","fantasy"),
28-
Pair("Game","game"),
29-
Pair("Gender Bender","Gender-Bender"),
30-
Pair("Harem","harem"),
31-
Pair("Historical","historical"),
32-
Pair("Horror","horror"),
33-
Pair("Josei","josei"),
34-
Pair("Martial Arts","martial-arts"),
35-
Pair("Mature","mature"),
36-
Pair("Mecha","mecha"),
37-
Pair("Military","military"),
38-
Pair("Mystery","mystery"),
39-
Pair("Psychological","psychological"),
40-
Pair("Romance","romance"),
41-
Pair("School Life","school-life"),
42-
Pair("Sci-fi","sci-fi"),
43-
Pair("Seinen","seinen"),
44-
Pair("Shoujo","shoujo"),
45-
Pair("Shoujo Ai","shoujo-ai"),
46-
Pair("Shounen","shounen"),
47-
Pair("Shounen Ai","shounen-ai"),
48-
Pair("Slice of Life","slice-of-life"),
49-
Pair("Smut","smut"),
50-
Pair("Sports","sports"),
51-
Pair("Supernatural","supernatural"),
52-
Pair("Tragedy","tragedy"),
53-
Pair("Two-dimensional","two-dimensional"),
54-
Pair("Urban Life","urban-life"),
55-
Pair("Wuxia","wuxia"),
56-
Pair("Xianxia","xianxia"),
57-
Pair("Xuanhuan","xuanhuan"),
58-
Pair("Yaoi","yaoi"),
59-
Pair("Yuri","yuri"),
21+
Pair("Adult", "adult"),
22+
Pair("Adventure", "adventure"),
23+
Pair("Comedy", "comedy"),
24+
Pair("Drama", "drama"),
25+
Pair("Ecchi", "ecchi"),
26+
Pair("Erciyuan", "erciyuan"),
27+
Pair("Fan-Fiction", "fan-fiction"),
28+
Pair("Fantasy", "fantasy"),
29+
Pair("Game", "game"),
30+
Pair("Gender Bender", "Gender-Bender"),
31+
Pair("Harem", "harem"),
32+
Pair("Historical", "historical"),
33+
Pair("Horror", "horror"),
34+
Pair("Josei", "josei"),
35+
Pair("Martial Arts", "martial-arts"),
36+
Pair("Mature", "mature"),
37+
Pair("Mecha", "mecha"),
38+
Pair("Military", "military"),
39+
Pair("Mystery", "mystery"),
40+
Pair("Psychological", "psychological"),
41+
Pair("Romance", "romance"),
42+
Pair("School Life", "school-life"),
43+
Pair("Sci-fi", "sci-fi"),
44+
Pair("Seinen", "seinen"),
45+
Pair("Shoujo", "shoujo"),
46+
Pair("Shoujo Ai", "shoujo-ai"),
47+
Pair("Shounen", "shounen"),
48+
Pair("Shounen Ai", "shounen-ai"),
49+
Pair("Slice of Life", "slice-of-life"),
50+
Pair("Smut", "smut"),
51+
Pair("Sports", "sports"),
52+
Pair("Supernatural", "supernatural"),
53+
Pair("Tragedy", "tragedy"),
54+
Pair("Two-dimensional", "two-dimensional"),
55+
Pair("Urban Life", "urban-life"),
56+
Pair("Wuxia", "wuxia"),
57+
Pair("Xianxia", "xianxia"),
58+
Pair("Xuanhuan", "xuanhuan"),
59+
Pair("Yaoi", "yaoi"),
60+
Pair("Yuri", "yuri"),
6061
)
62+
val interceptor = CloudflareKiller()
6163

6264
override suspend fun loadMainPage(
6365
page: Int,
@@ -69,13 +71,14 @@ class MtlNovelProvider : MainAPI() {
6971
if (tag.isNullOrBlank()) "$mainUrl/alltime-rank/page/$page" else "$mainUrl/genre/$tag/page/$page"
7072

7173

72-
val document = app.get(url).document
74+
val document = app.get(url, interceptor = interceptor).document
7375

74-
val headers = document.select("div.box")
76+
val headers = document.select("div.box")
7577
if (headers.size <= 0) return HeadMainPageResponse(url, ArrayList())
7678
val returnValue: ArrayList<SearchResponse> = ArrayList()
7779
for (h in headers) {
78-
val name = h?.selectFirst("a")?.attr("aria-label")?.substringBeforeLast("Cover") ?: continue
80+
val name =
81+
h?.selectFirst("a")?.attr("aria-label")?.substringBeforeLast("Cover") ?: continue
7982
val cUrl = h.selectFirst("a")?.attr("href") ?: throw ErrorLoadingException()
8083
val posterUrl = h.selectFirst("amp-img amp-img")?.attr("src")
8184
returnValue.add(
@@ -93,14 +96,29 @@ class MtlNovelProvider : MainAPI() {
9396
}
9497

9598
override suspend fun loadHtml(url: String): String? {
96-
return app.get(url).document.selectFirst("div.par")?.html()
99+
return app.get(url, interceptor = interceptor).document.selectFirst("div.par")?.html()
97100
}
98101

99102

100103
override suspend fun search(query: String): List<SearchResponse> {
101104
val response =
102-
SearchResults.fromJson(app.get("https://www.mtlnovel.com/wp-admin/admin-ajax.php?action=autosuggest&q=$query").text)
103-
return response?.items?.first()?.results?.map { SearchResponse(Jsoup.parse(it.title).text(), it.permalink!!, it.thumbnail, null, null, name) }!! }
105+
SearchResults.fromJson(
106+
app.get(
107+
"$mainUrl/wp-admin/admin-ajax.php?action=autosuggest&q=$query",
108+
interceptor = interceptor
109+
).text
110+
)
111+
return response.items?.first()?.results?.mapNotNull {
112+
SearchResponse(
113+
name = Jsoup.parse(it.title ?: return@mapNotNull null).text(),
114+
url = it.permalink ?: return@mapNotNull null,
115+
it.thumbnail,
116+
null,
117+
null,
118+
name
119+
)
120+
}!!
121+
}
104122

105123

106124
override suspend fun load(url: String): LoadResponse? {
@@ -119,16 +137,23 @@ class MtlNovelProvider : MainAPI() {
119137
val synopsis = document.selectFirst("div.desc")?.text()
120138

121139
val data: ArrayList<ChapterData> = ArrayList()
122-
val chapters = app.get(url+"/chapter-list/").document.select("div.ch-list a").reversed()
140+
val chapters = app.get(
141+
"$url/chapter-list/",
142+
interceptor = interceptor
143+
).document.select("div.ch-list a").reversed()
123144
for (c in chapters) {
124145
val href = c?.attr("href") ?: continue
125146
val cName = c.text()
126147
data.add(ChapterData(cName, href, null, null))
127148

128149
}
129150

130-
val rating = document.selectFirst("span.rating-info")?.selectFirst("strong")?.text()?.toFloat()?.times(200)?.toInt()
131-
val peopleVoted = "\\((.+) re".toRegex().find(document.selectFirst("span.rating-info")?.text().toString())?.groupValues?.last()?.toInt()
151+
val rating =
152+
document.selectFirst("span.rating-info")?.selectFirst("strong")?.text()?.toFloat()
153+
?.times(200)?.toInt()
154+
val peopleVoted = "\\((.+) re".toRegex()
155+
.find(document.selectFirst("span.rating-info")?.text().toString())?.groupValues?.last()
156+
?.toInt()
132157

133158

134159
return StreamResponse(
@@ -148,19 +173,20 @@ class MtlNovelProvider : MainAPI() {
148173
}
149174

150175

151-
private data class SearchResults (
176+
private data class SearchResults(
152177
@get:JsonProperty("items") val items: List<Item>? = null
153178
) {
154179
companion object {
155180
fun fromJson(json: String) = mapper.readValue<SearchResults>(json)
156181
}
157182
}
158-
private data class Item (
183+
184+
private data class Item(
159185
@get:JsonProperty("query") val query: String? = null,
160186
@get:JsonProperty("results") val results: List<Result>? = null
161187
)
162188

163-
private data class Result (
189+
private data class Result(
164190
@get:JsonProperty("title") val title: String? = null,
165191
@get:JsonProperty("permalink") val permalink: String? = null,
166192
@get:JsonProperty("thumbnail") val thumbnail: String? = null,

app/src/main/java/com/lagradost/quicknovel/providers/NovelFullProvider.kt

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
package com.lagradost.quicknovel.providers
22

3-
import com.lagradost.quicknovel.*
4-
import com.lagradost.quicknovel.MainActivity.Companion.app
5-
import org.jsoup.Jsoup
6-
import java.lang.Exception
7-
import kotlin.collections.ArrayList
3+
import com.lagradost.quicknovel.R
84

5+
class NovelFullProvider : AllNovelProvider() {
6+
override val name = "NovelFull"
7+
override val mainUrl = "https://novelfull.com"
8+
override val hasMainPage = true
9+
10+
override val iconId = R.drawable.icon_novelfull
11+
12+
override val iconBackgroundId = R.color.white
13+
}
14+
15+
/*
916
class NovelFullProvider : MainAPI() {
1017
override val name = "NovelFull"
1118
override val mainUrl = "https://novelfull.com"
@@ -236,3 +243,4 @@ class NovelFullProvider : MainAPI() {
236243
)
237244
}
238245
}
246+
*/

0 commit comments

Comments
 (0)