mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 22:37:56 +01:00 
			
		
		
		
	Complete group filters
This commit is contained in:
		| @@ -93,8 +93,18 @@ class Batoto : ParsedOnlineSource(), LoginSource { | ||||
|                 is Status -> if (!filter.isIgnored()) { | ||||
|                     url.addQueryParameter("completed", if (filter.isExcluded()) "i" else "c") | ||||
|                 } | ||||
|                 is Genre -> if (!filter.isIgnored()) { | ||||
|                     genres += (if (filter.isExcluded()) ";e" else ";i") + filter.id | ||||
|                 is GenreList -> { | ||||
|                     filter.state.forEach { filter -> | ||||
|                         when (filter) { | ||||
|                             is Genre -> if (!filter.isIgnored()) { | ||||
|                                 genres += (if (filter.isExcluded()) ";e" else ";i") + filter.id | ||||
|                             } | ||||
|                             is SelectField -> { | ||||
|                                 val sel = filter.values[filter.state].value | ||||
|                                 if (!sel.isEmpty()) url.addQueryParameter(filter.key, sel) | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 is TextField -> { | ||||
|                     if (!filter.state.isEmpty()) url.addQueryParameter(filter.key, filter.state) | ||||
| @@ -292,23 +302,25 @@ class Batoto : ParsedOnlineSource(), LoginSource { | ||||
|     private class TextField(name: String, val key: String) : Filter.Text(name) | ||||
|     private class SelectField(name: String, val key: String, values: Array<ListValue>, state: Int = 0) : Filter.Select<ListValue>(name, values, state) | ||||
|     private class Flag(name: String, val key: String, val valTrue: String, val valFalse: String) : Filter.CheckBox(name) | ||||
|     private class OrderBy() : Filter.Sort("Order by", | ||||
|     private class GenreList(genres: List<Filter<*>>) : Filter.Group<Filter<*>>("Genres", genres) | ||||
|     private class OrderBy : Filter.Sort("Order by", | ||||
|             arrayOf("Title", "Author", "Artist", "Rating", "Views", "Last Update"), | ||||
|             Filter.Sort.Selection(4, false)) | ||||
|  | ||||
|     // [...document.querySelectorAll("#advanced_options div.genre_buttons")].map((el,i) => { | ||||
|     //     const onClick=el.getAttribute('onclick');const id=onClick.substr(14,onClick.length-16);return `Genre("${el.textContent.trim()}", ${id})` | ||||
|     // }).join(',\n') | ||||
|     // on https://bato.to/search | ||||
|     override fun getFilterList() = FilterList( | ||||
|             TextField("Author", "artist_name"), | ||||
|             SelectField("Type", "type", arrayOf(ListValue("Any", ""), ListValue("Manga (Jp)", "jp"), ListValue("Manhwa (Kr)", "kr"), ListValue("Manhua (Cn)", "cn"), ListValue("Artbook", "ar"), ListValue("Other", "ot"))), | ||||
|             Status(), | ||||
|             Flag("Exclude mature", "mature", "m", ""), | ||||
|             Filter.Separator(), | ||||
|             OrderBy(), | ||||
|             Filter.Separator(), | ||||
|             Filter.Header("Genres"), | ||||
|             GenreList(getGenreList()) | ||||
|     ) | ||||
|  | ||||
|     // [...document.querySelectorAll("#advanced_options div.genre_buttons")].map((el,i) => { | ||||
|     //     const onClick=el.getAttribute('onclick');const id=onClick.substr(14,onClick.length-16);return `Genre("${el.textContent.trim()}", ${id})` | ||||
|     // }).join(',\n') | ||||
|     // on https://bato.to/search | ||||
|     private fun getGenreList() = listOf( | ||||
|             SelectField("Inclusion mode", "genre_cond", arrayOf(ListValue("And (all selected genres)", "and"), ListValue("Or (any selected genres) ", "or"))), | ||||
|             Genre("4-Koma", 40), | ||||
|             Genre("Action", 1), | ||||
|   | ||||
| @@ -64,7 +64,7 @@ class Kissmanga : ParsedOnlineSource() { | ||||
|                 when (filter) { | ||||
|                     is Author -> add("authorArtist", filter.state) | ||||
|                     is Status -> add("status", arrayOf("", "Completed", "Ongoing")[filter.state]) | ||||
|                     is Genre -> add("genres", filter.state.toString()) | ||||
|                     is GenreList -> filter.state.forEach { genre -> add("genres", genre.state.toString()) } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -134,16 +134,20 @@ class Kissmanga : ParsedOnlineSource() { | ||||
|  | ||||
|     override fun imageUrlParse(document: Document) = "" | ||||
|  | ||||
|     private class Status() : Filter.TriState("Completed") | ||||
|     private class Author() : Filter.Text("Author") | ||||
|     private class Status : Filter.TriState("Completed") | ||||
|     private class Author : Filter.Text("Author") | ||||
|     private class Genre(name: String) : Filter.TriState(name) | ||||
|     private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres", genres) | ||||
|  | ||||
|     // $("select[name=\"genres\"]").map((i,el) => `Genre("${$(el).next().text().trim()}", ${i})`).get().join(',\n') | ||||
|     // on http://kissmanga.com/AdvanceSearch | ||||
|     override fun getFilterList() = FilterList( | ||||
|             Author(), | ||||
|             Status(), | ||||
|             Filter.Header("Genres"), | ||||
|             GenreList(getGenreList()) | ||||
|     ) | ||||
|  | ||||
|     // $("select[name=\"genres\"]").map((i,el) => `Genre("${$(el).next().text().trim()}", ${i})`).get().join(',\n') | ||||
|     // on http://kissmanga.com/AdvanceSearch | ||||
|     private fun getGenreList() = listOf( | ||||
|             Genre("4-Koma"), | ||||
|             Genre("Action"), | ||||
|             Genre("Adult"), | ||||
|   | ||||
| @@ -59,11 +59,7 @@ class Mangafox : ParsedOnlineSource() { | ||||
|         (if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> | ||||
|             when (filter) { | ||||
|                 is Status -> url.addQueryParameter(filter.id, filter.state.toString()) | ||||
|                 is GenreList -> { | ||||
|                     filter.state.forEach { genre -> | ||||
|                         url.addQueryParameter(genre.id, genre.state.toString()) | ||||
|                     } | ||||
|                 } | ||||
|                 is GenreList -> filter.state.forEach { genre -> url.addQueryParameter(genre.id, genre.state.toString()) } | ||||
|                 is TextField -> url.addQueryParameter(filter.key, filter.state) | ||||
|                 is Type -> url.addQueryParameter("type", if(filter.state == 0) "" else filter.state.toString()) | ||||
|                 is OrderBy -> { | ||||
| @@ -180,9 +176,7 @@ class Mangafox : ParsedOnlineSource() { | ||||
|             TextField("Artist", "artist"), | ||||
|             Type(), | ||||
|             Status(), | ||||
|             Filter.Separator(), | ||||
|             OrderBy(), | ||||
|             Filter.Separator(), | ||||
|             GenreList(getGenreList()) | ||||
|     ) | ||||
|  | ||||
|   | ||||
| @@ -61,7 +61,7 @@ class Mangahere : ParsedOnlineSource() { | ||||
|         (if (filters.isEmpty()) getFilterList() else filters).forEach { filter -> | ||||
|             when (filter) { | ||||
|                 is Status -> url.addQueryParameter("is_completed", arrayOf("", "1", "0")[filter.state]) | ||||
|                 is Genre -> url.addQueryParameter(filter.id, filter.state.toString()) | ||||
|                 is GenreList -> filter.state.forEach { genre -> url.addQueryParameter(genre.id, genre.state.toString()) } | ||||
|                 is TextField -> url.addQueryParameter(filter.key, filter.state) | ||||
|                 is Type -> url.addQueryParameter("direction", arrayOf("", "rl", "lr")[filter.state]) | ||||
|                 is OrderBy -> { | ||||
| @@ -169,18 +169,20 @@ class Mangahere : ParsedOnlineSource() { | ||||
|     private class OrderBy : Filter.Sort("Order by", | ||||
|             arrayOf("Series name", "Rating", "Views", "Total chapters", "Last chapter"), | ||||
|             Filter.Sort.Selection(2, false)) | ||||
|     private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres", genres) | ||||
|  | ||||
|     // [...document.querySelectorAll("select[id^='genres'")].map((el,i) => `Genre("${el.nextSibling.nextSibling.textContent.trim()}", "${el.getAttribute('name')}")`).join(',\n') | ||||
|     // http://www.mangahere.co/advsearch.htm | ||||
|     override fun getFilterList() = FilterList( | ||||
|             TextField("Author", "author"), | ||||
|             TextField("Artist", "artist"), | ||||
|             Type(), | ||||
|             Status(), | ||||
|             Filter.Separator(), | ||||
|             OrderBy(), | ||||
|             Filter.Separator(), | ||||
|             Filter.Header("Genres"), | ||||
|             GenreList(getGenreList()) | ||||
|     ) | ||||
|  | ||||
|     // [...document.querySelectorAll("select[id^='genres'")].map((el,i) => `Genre("${el.nextSibling.nextSibling.textContent.trim()}", "${el.getAttribute('name')}")`).join(',\n') | ||||
|     // http://www.mangahere.co/advsearch.htm | ||||
|     private fun getGenreList() = listOf( | ||||
|             Genre("Action"), | ||||
|             Genre("Adventure"), | ||||
|             Genre("Comedy"), | ||||
|   | ||||
| @@ -50,8 +50,8 @@ class Mangasee : ParsedOnlineSource() { | ||||
|     override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { | ||||
|         val url = HttpUrl.parse("$baseUrl/search/request.php").newBuilder() | ||||
|         if (!query.isEmpty()) url.addQueryParameter("keyword", query) | ||||
|         var genres: String? = null | ||||
|         var genresNo: String? = null | ||||
|         val genres = mutableListOf<String>() | ||||
|         val genresNo = mutableListOf<String>() | ||||
|         for (filter in if (filters.isEmpty()) getFilterList() else filters) { | ||||
|             when (filter) { | ||||
|                 is Sort -> { | ||||
| @@ -62,14 +62,16 @@ class Mangasee : ParsedOnlineSource() { | ||||
|                 } | ||||
|                 is SelectField -> if (filter.state != 0) url.addQueryParameter(filter.key, filter.values[filter.state]) | ||||
|                 is TextField -> if (!filter.state.isEmpty()) url.addQueryParameter(filter.key, filter.state) | ||||
|                 is Genre -> when (filter.state) { | ||||
|                     Filter.TriState.STATE_INCLUDE -> genres = if (genres == null) filter.name else genres + "," + filter.name | ||||
|                     Filter.TriState.STATE_EXCLUDE -> genresNo = if (genresNo == null) filter.name else genresNo + "," + filter.name | ||||
|                 is GenreList -> filter.state.forEach { genre -> | ||||
|                     when (genre.state) { | ||||
|                         Filter.TriState.STATE_INCLUDE -> genres.add(genre.name) | ||||
|                         Filter.TriState.STATE_EXCLUDE -> genresNo.add(genre.name) | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (genres != null) url.addQueryParameter("genre", genres) | ||||
|         if (genresNo != null) url.addQueryParameter("genreNo", genresNo) | ||||
|         if (genres.isNotEmpty()) url.addQueryParameter("genre", genres.joinToString(",")) | ||||
|         if (genresNo.isNotEmpty()) url.addQueryParameter("genreNo", genresNo.joinToString(",")) | ||||
|  | ||||
|         val (body, requestUrl) = convertQueryToPost(page, url.toString()) | ||||
|         return POST(requestUrl, headers, body.build()) | ||||
| @@ -155,23 +157,51 @@ class Mangasee : ParsedOnlineSource() { | ||||
|  | ||||
|     override fun imageUrlParse(document: Document): String = document.select("img.CurImage").attr("src") | ||||
|  | ||||
|     override fun latestUpdatesNextPageSelector() = "button.requestMore" | ||||
|  | ||||
|     override fun latestUpdatesSelector(): String = "a.latestSeries" | ||||
|  | ||||
|     override fun latestUpdatesRequest(page: Int): Request { | ||||
|         val url = "http://mangaseeonline.net/home/latest.request.php" | ||||
|         val (body, requestUrl) = convertQueryToPost(page, url) | ||||
|         return POST(requestUrl, headers, body.build()) | ||||
|     } | ||||
|  | ||||
|     override fun latestUpdatesFromElement(element: Element): SManga { | ||||
|         val manga = SManga.create() | ||||
|         element.select("a.latestSeries").first().let { | ||||
|             val chapterUrl = it.attr("href") | ||||
|             val indexOfMangaUrl = chapterUrl.indexOf("-chapter-") | ||||
|             val indexOfLastPath = chapterUrl.lastIndexOf("/") | ||||
|             val mangaUrl = chapterUrl.substring(indexOfLastPath, indexOfMangaUrl) | ||||
|             val defaultText = it.select("p.clamp2").text() | ||||
|             val m = recentUpdatesPattern.matcher(defaultText) | ||||
|             val title = if (m.matches()) m.group(1) else defaultText | ||||
|             manga.setUrlWithoutDomain("/manga" + mangaUrl) | ||||
|             manga.title = title | ||||
|         } | ||||
|         return manga | ||||
|     } | ||||
|  | ||||
|     private class Sort : Filter.Sort("Sort", arrayOf("Alphabetically", "Date updated", "Popularity"), Filter.Sort.Selection(2, false)) | ||||
|     private class Genre(name: String) : Filter.TriState(name) | ||||
|     private class TextField(name: String, val key: String) : Filter.Text(name) | ||||
|     private class SelectField(name: String, val key: String, values: Array<String>, state: Int = 0) : Filter.Select<String>(name, values, state) | ||||
|     private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres", genres) | ||||
|  | ||||
|     // [...document.querySelectorAll("label.triStateCheckBox input")].map(el => `Filter("${el.getAttribute('name')}", "${el.nextSibling.textContent.trim()}")`).join(',\n') | ||||
|     // http://mangasee.co/advanced-search/ | ||||
|     override fun getFilterList() = FilterList( | ||||
|             TextField("Years", "year"), | ||||
|             TextField("Author", "author"), | ||||
|             SelectField("Scan Status", "status", arrayOf("Any", "Complete", "Discontinued", "Hiatus", "Incomplete", "Ongoing")), | ||||
|             SelectField("Publish Status", "pstatus", arrayOf("Any", "Cancelled", "Complete", "Discontinued", "Hiatus", "Incomplete", "Ongoing", "Unfinished")), | ||||
|             SelectField("Type", "type", arrayOf("Any", "Doujinshi", "Manga", "Manhua", "Manhwa", "OEL", "One-shot")), | ||||
|             Filter.Separator(), | ||||
|             Sort(), | ||||
|             Filter.Separator(), | ||||
|             Filter.Header("Genres"), | ||||
|             GenreList(getGenreList()) | ||||
|     ) | ||||
|  | ||||
|     // [...document.querySelectorAll("label.triStateCheckBox input")].map(el => `Filter("${el.getAttribute('name')}", "${el.nextSibling.textContent.trim()}")`).join(',\n') | ||||
|     // http://mangasee.co/advanced-search/ | ||||
|     private fun getGenreList() = listOf( | ||||
|             Genre("Action"), | ||||
|             Genre("Adult"), | ||||
|             Genre("Adventure"), | ||||
| @@ -210,30 +240,4 @@ class Mangasee : ParsedOnlineSource() { | ||||
|             Genre("Yuri") | ||||
|     ) | ||||
|  | ||||
|     override fun latestUpdatesNextPageSelector() = "button.requestMore" | ||||
|  | ||||
|     override fun latestUpdatesSelector(): String = "a.latestSeries" | ||||
|  | ||||
|     override fun latestUpdatesRequest(page: Int): Request { | ||||
|         val url = "http://mangaseeonline.net/home/latest.request.php" | ||||
|         val (body, requestUrl) = convertQueryToPost(page, url) | ||||
|         return POST(requestUrl, headers, body.build()) | ||||
|     } | ||||
|  | ||||
|     override fun latestUpdatesFromElement(element: Element): SManga { | ||||
|         val manga = SManga.create() | ||||
|         element.select("a.latestSeries").first().let { | ||||
|             val chapterUrl = it.attr("href") | ||||
|             val indexOfMangaUrl = chapterUrl.indexOf("-chapter-") | ||||
|             val indexOfLastPath = chapterUrl.lastIndexOf("/") | ||||
|             val mangaUrl = chapterUrl.substring(indexOfLastPath, indexOfMangaUrl) | ||||
|             val defaultText = it.select("p.clamp2").text() | ||||
|             val m = recentUpdatesPattern.matcher(defaultText) | ||||
|             val title = if (m.matches()) m.group(1) else defaultText | ||||
|             manga.setUrlWithoutDomain("/manga" + mangaUrl) | ||||
|             manga.title = title | ||||
|         } | ||||
|         return manga | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -70,9 +70,11 @@ class Readmangatoday : ParsedOnlineSource() { | ||||
|                 is TextField -> builder.add(filter.key, filter.state) | ||||
|                 is Type -> builder.add("type", arrayOf("all", "japanese", "korean", "chinese")[filter.state]) | ||||
|                 is Status -> builder.add("status", arrayOf("both", "completed", "ongoing")[filter.state]) | ||||
|                 is Genre -> when (filter.state) { | ||||
|                     Filter.TriState.STATE_INCLUDE -> builder.add("include[]", filter.id.toString()) | ||||
|                     Filter.TriState.STATE_EXCLUDE -> builder.add("exclude[]", filter.id.toString()) | ||||
|                 is GenreList -> filter.state.forEach { genre -> | ||||
|                     when (genre.state) { | ||||
|                         Filter.TriState.STATE_INCLUDE -> builder.add("include[]", genre.id.toString()) | ||||
|                         Filter.TriState.STATE_EXCLUDE -> builder.add("exclude[]", genre.id.toString()) | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @@ -161,19 +163,23 @@ class Readmangatoday : ParsedOnlineSource() { | ||||
|  | ||||
|     override fun imageUrlParse(document: Document) = document.select("img.img-responsive-2").first().attr("src") | ||||
|  | ||||
|     private class Status() : Filter.TriState("Completed") | ||||
|     private class Status : Filter.TriState("Completed") | ||||
|     private class Genre(name: String, val id: Int) : Filter.TriState(name) | ||||
|     private class TextField(name: String, val key: String) : Filter.Text(name) | ||||
|     private class Type() : Filter.Select<String>("Type", arrayOf("All", "Japanese Manga", "Korean Manhwa", "Chinese Manhua")) | ||||
|     private class Type : Filter.Select<String>("Type", arrayOf("All", "Japanese Manga", "Korean Manhwa", "Chinese Manhua")) | ||||
|     private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres", genres) | ||||
|  | ||||
|     // [...document.querySelectorAll("ul.manga-cat span")].map(el => `Genre("${el.nextSibling.textContent.trim()}", ${el.getAttribute('data-id')})`).join(',\n') | ||||
|     // http://www.readmanga.today/advanced-search | ||||
|     override fun getFilterList() = FilterList( | ||||
|             TextField("Author", "author-name"), | ||||
|             TextField("Artist", "artist-name"), | ||||
|             Type(), | ||||
|             Status(), | ||||
|             Filter.Header("Genres"), | ||||
|             GenreList(getGenreList()) | ||||
|     ) | ||||
|  | ||||
|     // [...document.querySelectorAll("ul.manga-cat span")].map(el => `Genre("${el.nextSibling.textContent.trim()}", ${el.getAttribute('data-id')})`).join(',\n') | ||||
|     // http://www.readmanga.today/advanced-search | ||||
|     private fun getGenreList() = listOf( | ||||
|             Genre("Action", 2), | ||||
|             Genre("Adventure", 4), | ||||
|             Genre("Comedy", 5), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user