Remove A Pair Of 2+, migrate Sadscans from old multisrc (#4955)
* Remove A Pair Of 2+ * move Sadscans from multisrc
This commit is contained in:
		
							parent
							
								
									f8ab0d3f2f
								
							
						
					
					
						commit
						90eb12294c
					
				| @ -1,9 +0,0 @@ | |||||||
| plugins { |  | ||||||
|     id("lib-multisrc") |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| baseVersionCode = 1 |  | ||||||
| 
 |  | ||||||
| dependencies { |  | ||||||
|     api(project(":lib:dataimage")) |  | ||||||
| } |  | ||||||
| @ -1,141 +0,0 @@ | |||||||
| package eu.kanade.tachiyomi.multisrc.po2scans |  | ||||||
| 
 |  | ||||||
| import eu.kanade.tachiyomi.lib.dataimage.DataImageInterceptor |  | ||||||
| import eu.kanade.tachiyomi.lib.dataimage.dataImageAsUrl |  | ||||||
| import eu.kanade.tachiyomi.network.GET |  | ||||||
| import eu.kanade.tachiyomi.source.model.FilterList |  | ||||||
| import eu.kanade.tachiyomi.source.model.MangasPage |  | ||||||
| import eu.kanade.tachiyomi.source.model.Page |  | ||||||
| import eu.kanade.tachiyomi.source.model.SChapter |  | ||||||
| import eu.kanade.tachiyomi.source.model.SManga |  | ||||||
| import eu.kanade.tachiyomi.source.online.ParsedHttpSource |  | ||||||
| import org.jsoup.nodes.Document |  | ||||||
| import org.jsoup.nodes.Element |  | ||||||
| import rx.Observable |  | ||||||
| import java.text.SimpleDateFormat |  | ||||||
| import java.util.Locale |  | ||||||
| 
 |  | ||||||
| abstract class PO2Scans( |  | ||||||
|     override val name: String, |  | ||||||
|     override val baseUrl: String, |  | ||||||
|     override val lang: String, |  | ||||||
|     private val dateFormat: SimpleDateFormat = SimpleDateFormat("dd MMMM, yy", Locale.ENGLISH), |  | ||||||
| ) : ParsedHttpSource() { |  | ||||||
| 
 |  | ||||||
|     override val supportsLatest = true |  | ||||||
| 
 |  | ||||||
|     override val client = network.cloudflareClient.newBuilder() |  | ||||||
|         .addInterceptor(DataImageInterceptor()) |  | ||||||
|         .build() |  | ||||||
| 
 |  | ||||||
|     override fun headersBuilder() = super.headersBuilder() |  | ||||||
|         .add("Referer", "$baseUrl/") |  | ||||||
| 
 |  | ||||||
|     // popular |  | ||||||
|     override fun popularMangaRequest(page: Int) = GET("$baseUrl/series", headers) |  | ||||||
| 
 |  | ||||||
|     override fun popularMangaSelector() = "div.series-list" |  | ||||||
| 
 |  | ||||||
|     override fun popularMangaFromElement(element: Element) = SManga.create().apply { |  | ||||||
|         setUrlWithoutDomain(element.selectFirst("div > a")!!.absUrl("href")) |  | ||||||
|         title = element.selectFirst("div > h2")!!.text() |  | ||||||
|         thumbnail_url = element.selectFirst("img")?.absUrl("data-src") |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // TODO: add page selectors & url parameters when site have enough series for pagination |  | ||||||
|     override fun popularMangaNextPageSelector() = null |  | ||||||
| 
 |  | ||||||
|     // latest |  | ||||||
|     override fun latestUpdatesRequest(page: Int) = GET(baseUrl, headers) |  | ||||||
| 
 |  | ||||||
|     override fun latestUpdatesSelector() = "div.chap" |  | ||||||
| 
 |  | ||||||
|     override fun latestUpdatesFromElement(element: Element) = SManga.create().apply { |  | ||||||
|         element.selectFirst("div.chap-title a")!!.let { |  | ||||||
|             setUrlWithoutDomain(it.absUrl("href")) |  | ||||||
|             title = it.text() |  | ||||||
|         } |  | ||||||
|         thumbnail_url = element.selectFirst("img")?.absUrl("data-src") |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() |  | ||||||
| 
 |  | ||||||
|     // search |  | ||||||
|     override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> { |  | ||||||
|         if (!query.startsWith(SLUG_SEARCH_PREFIX)) { |  | ||||||
|             return super.fetchSearchManga(page, query, filters) |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         val url = "/series/${query.substringAfter(SLUG_SEARCH_PREFIX)}" |  | ||||||
|         return fetchMangaDetails(SManga.create().apply { this.url = url }) |  | ||||||
|             .map { |  | ||||||
|                 it.url = url |  | ||||||
|                 MangasPage(listOf(it), false) |  | ||||||
|             } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = |  | ||||||
|         GET("$baseUrl/series?search=$query", headers) |  | ||||||
| 
 |  | ||||||
|     override fun searchMangaSelector() = popularMangaSelector() |  | ||||||
| 
 |  | ||||||
|     override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element) |  | ||||||
| 
 |  | ||||||
|     override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() |  | ||||||
| 
 |  | ||||||
|     // manga details |  | ||||||
|     override fun mangaDetailsParse(document: Document): SManga { |  | ||||||
|         return SManga.create().apply { |  | ||||||
|             title = document.selectFirst(".title")!!.text() |  | ||||||
|             author = document.select(".author > span:nth-child(2)").text() |  | ||||||
|             artist = author |  | ||||||
|             status = document.select(".status > span:nth-child(2)").text().parseStatus() |  | ||||||
|             description = document.select(".summary p").text() |  | ||||||
|             thumbnail_url = document.select("div.series-image img").attr("abs:src") |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // chapter list |  | ||||||
|     override fun chapterListSelector() = "div.chap" |  | ||||||
| 
 |  | ||||||
|     override fun chapterFromElement(element: Element) = SChapter.create().apply { |  | ||||||
|         element.selectFirst("a")!!.let { |  | ||||||
|             setUrlWithoutDomain(it.absUrl("href")) |  | ||||||
|             name = it.text() |  | ||||||
|         } |  | ||||||
|         date_upload = parseDate(element.select("div > div > span:nth-child(2)").text()) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // page list |  | ||||||
|     override fun pageListParse(document: Document) = |  | ||||||
|         document.select(".swiper-slide img").mapIndexed { index, img -> |  | ||||||
|             Page(index, imageUrl = img.imgAttr()) |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     override fun imageUrlParse(document: Document) = throw UnsupportedOperationException() |  | ||||||
| 
 |  | ||||||
|     private val statusOngoing = listOf("ongoing", "devam ediyor") |  | ||||||
|     private val statusCompleted = listOf("complete", "tamamlandı", "bitti") |  | ||||||
| 
 |  | ||||||
|     private fun String.parseStatus(): Int { |  | ||||||
|         return when (this.lowercase()) { |  | ||||||
|             in statusOngoing -> SManga.ONGOING |  | ||||||
|             in statusCompleted -> SManga.COMPLETED |  | ||||||
|             else -> SManga.UNKNOWN |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private fun Element.imgAttr(): String = when { |  | ||||||
|         hasAttr("data-pagespeed-high-res-src") -> dataImageAsUrl("data-pagespeed-high-res-src") |  | ||||||
|         hasAttr("data-pagespeed-lazy-src") -> dataImageAsUrl("data-pagespeed-lazy-src") |  | ||||||
|         else -> dataImageAsUrl("src") |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private fun parseDate(dateStr: String) = |  | ||||||
|         runCatching { dateFormat.parse(dateStr)!!.time } |  | ||||||
|             .getOrDefault(0L) |  | ||||||
| 
 |  | ||||||
|     companion object { |  | ||||||
|         const val SLUG_SEARCH_PREFIX = "slug:" |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,9 +0,0 @@ | |||||||
| ext { |  | ||||||
|     extName = 'A Pair Of 2+' |  | ||||||
|     extClass = '.APairOf2' |  | ||||||
|     themePkg = 'po2scans' |  | ||||||
|     baseUrl = 'https://po2scans.com' |  | ||||||
|     overrideVersionCode = 31 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| apply from: "$rootDir/common.gradle" |  | ||||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 2.2 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 1.3 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 2.8 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 5.2 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 7.6 KiB | 
| @ -1,12 +0,0 @@ | |||||||
| package eu.kanade.tachiyomi.extension.en.apairof2 |  | ||||||
| 
 |  | ||||||
| import eu.kanade.tachiyomi.multisrc.po2scans.PO2Scans |  | ||||||
| import eu.kanade.tachiyomi.network.interceptor.rateLimit |  | ||||||
| 
 |  | ||||||
| class APairOf2 : PO2Scans("A Pair Of 2+", "https://po2scans.com", "en") { |  | ||||||
|     override val versionId = 2 |  | ||||||
| 
 |  | ||||||
|     override val client = super.client.newBuilder() |  | ||||||
|         .rateLimit(4) |  | ||||||
|         .build() |  | ||||||
| } |  | ||||||
| @ -3,7 +3,7 @@ | |||||||
| 
 | 
 | ||||||
|     <application> |     <application> | ||||||
|         <activity |         <activity | ||||||
|             android:name="eu.kanade.tachiyomi.multisrc.po2scans.PO2ScansUrlActivity" |             android:name="eu.kanade.tachiyomi.extension.tr.sadscans.SadscansUrlActivity" | ||||||
|             android:excludeFromRecents="true" |             android:excludeFromRecents="true" | ||||||
|             android:exported="true" |             android:exported="true" | ||||||
|             android:theme="@android:style/Theme.NoDisplay"> |             android:theme="@android:style/Theme.NoDisplay"> | ||||||
| @ -14,9 +14,9 @@ | |||||||
|                 <category android:name="android.intent.category.BROWSABLE" /> |                 <category android:name="android.intent.category.BROWSABLE" /> | ||||||
| 
 | 
 | ||||||
|                 <data |                 <data | ||||||
|                     android:host="${SOURCEHOST}" |                     android:host="sadscans.com" | ||||||
|                     android:pathPattern="/series/..*" |                     android:pathPattern="/series/..*" | ||||||
|                     android:scheme="${SOURCESCHEME}" /> |                     android:scheme="https" /> | ||||||
|             </intent-filter> |             </intent-filter> | ||||||
|         </activity> |         </activity> | ||||||
|     </application> |     </application> | ||||||
| @ -1,9 +1,11 @@ | |||||||
| ext { | ext { | ||||||
|     extName = 'Sadscans' |     extName = 'Sadscans' | ||||||
|     extClass = '.Sadscans' |     extClass = '.Sadscans' | ||||||
|     themePkg = 'po2scans' |     extVersionCode = 2 | ||||||
|     baseUrl = 'https://sadscans.com' |  | ||||||
|     overrideVersionCode = 0 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| apply from: "$rootDir/common.gradle" | apply from: "$rootDir/common.gradle" | ||||||
|  | 
 | ||||||
|  | dependencies { | ||||||
|  |     api(project(":lib:dataimage")) | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,5 +1,144 @@ | |||||||
| package eu.kanade.tachiyomi.extension.tr.sadscans | package eu.kanade.tachiyomi.extension.tr.sadscans | ||||||
| 
 | 
 | ||||||
| import eu.kanade.tachiyomi.multisrc.po2scans.PO2Scans | import eu.kanade.tachiyomi.lib.dataimage.DataImageInterceptor | ||||||
|  | import eu.kanade.tachiyomi.lib.dataimage.dataImageAsUrl | ||||||
|  | import eu.kanade.tachiyomi.network.GET | ||||||
|  | import eu.kanade.tachiyomi.source.model.FilterList | ||||||
|  | import eu.kanade.tachiyomi.source.model.MangasPage | ||||||
|  | import eu.kanade.tachiyomi.source.model.Page | ||||||
|  | import eu.kanade.tachiyomi.source.model.SChapter | ||||||
|  | import eu.kanade.tachiyomi.source.model.SManga | ||||||
|  | import eu.kanade.tachiyomi.source.online.ParsedHttpSource | ||||||
|  | import org.jsoup.nodes.Document | ||||||
|  | import org.jsoup.nodes.Element | ||||||
|  | import rx.Observable | ||||||
|  | import java.text.SimpleDateFormat | ||||||
|  | import java.util.Locale | ||||||
| 
 | 
 | ||||||
| class Sadscans : PO2Scans("Sadscans", "https://sadscans.com", "tr") | class Sadscans : ParsedHttpSource() { | ||||||
|  | 
 | ||||||
|  |     override val name = "Sadscans" | ||||||
|  | 
 | ||||||
|  |     override val baseUrl = "https://sadscans.com" | ||||||
|  | 
 | ||||||
|  |     override val lang = "tr" | ||||||
|  | 
 | ||||||
|  |     private val dateFormat = SimpleDateFormat("dd MMMM, yy", Locale.ENGLISH) | ||||||
|  | 
 | ||||||
|  |     override val supportsLatest = true | ||||||
|  | 
 | ||||||
|  |     override val client = network.cloudflareClient.newBuilder() | ||||||
|  |         .addInterceptor(DataImageInterceptor()) | ||||||
|  |         .build() | ||||||
|  | 
 | ||||||
|  |     override fun headersBuilder() = super.headersBuilder() | ||||||
|  |         .add("Referer", "$baseUrl/") | ||||||
|  | 
 | ||||||
|  |     // popular | ||||||
|  |     override fun popularMangaRequest(page: Int) = GET("$baseUrl/series", headers) | ||||||
|  | 
 | ||||||
|  |     override fun popularMangaSelector() = "div.series-list" | ||||||
|  | 
 | ||||||
|  |     override fun popularMangaFromElement(element: Element) = SManga.create().apply { | ||||||
|  |         setUrlWithoutDomain(element.selectFirst("div > a")!!.absUrl("href")) | ||||||
|  |         title = element.selectFirst("div > h2")!!.text() | ||||||
|  |         thumbnail_url = element.selectFirst("img")?.absUrl("data-src") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // TODO: add page selectors & url parameters when site have enough series for pagination | ||||||
|  |     override fun popularMangaNextPageSelector() = null | ||||||
|  | 
 | ||||||
|  |     // latest | ||||||
|  |     override fun latestUpdatesRequest(page: Int) = GET(baseUrl, headers) | ||||||
|  | 
 | ||||||
|  |     override fun latestUpdatesSelector() = "div.chap" | ||||||
|  | 
 | ||||||
|  |     override fun latestUpdatesFromElement(element: Element) = SManga.create().apply { | ||||||
|  |         element.selectFirst("div.chap-title a")!!.let { | ||||||
|  |             setUrlWithoutDomain(it.absUrl("href")) | ||||||
|  |             title = it.text() | ||||||
|  |         } | ||||||
|  |         thumbnail_url = element.selectFirst("img")?.absUrl("data-src") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() | ||||||
|  | 
 | ||||||
|  |     // search | ||||||
|  |     override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> { | ||||||
|  |         if (!query.startsWith(SLUG_SEARCH_PREFIX)) { | ||||||
|  |             return super.fetchSearchManga(page, query, filters) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         val url = "/series/${query.substringAfter(SLUG_SEARCH_PREFIX)}" | ||||||
|  |         return fetchMangaDetails(SManga.create().apply { this.url = url }) | ||||||
|  |             .map { | ||||||
|  |                 it.url = url | ||||||
|  |                 MangasPage(listOf(it), false) | ||||||
|  |             } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = | ||||||
|  |         GET("$baseUrl/series?search=$query", headers) | ||||||
|  | 
 | ||||||
|  |     override fun searchMangaSelector() = popularMangaSelector() | ||||||
|  | 
 | ||||||
|  |     override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element) | ||||||
|  | 
 | ||||||
|  |     override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() | ||||||
|  | 
 | ||||||
|  |     // manga details | ||||||
|  |     override fun mangaDetailsParse(document: Document): SManga { | ||||||
|  |         return SManga.create().apply { | ||||||
|  |             title = document.selectFirst(".title")!!.text() | ||||||
|  |             author = document.select(".author > span:nth-child(2)").text() | ||||||
|  |             artist = author | ||||||
|  |             status = document.select(".status > span:nth-child(2)").text().parseStatus() | ||||||
|  |             description = document.select(".summary p").text() | ||||||
|  |             thumbnail_url = document.select("div.series-image img").attr("abs:src") | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // chapter list | ||||||
|  |     override fun chapterListSelector() = "div.chap" | ||||||
|  | 
 | ||||||
|  |     override fun chapterFromElement(element: Element) = SChapter.create().apply { | ||||||
|  |         element.selectFirst("a")!!.let { | ||||||
|  |             setUrlWithoutDomain(it.absUrl("href")) | ||||||
|  |             name = it.text() | ||||||
|  |         } | ||||||
|  |         date_upload = parseDate(element.select("div > div > span:nth-child(2)").text()) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // page list | ||||||
|  |     override fun pageListParse(document: Document) = | ||||||
|  |         document.select(".swiper-slide img").mapIndexed { index, img -> | ||||||
|  |             Page(index, imageUrl = img.imgAttr()) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     override fun imageUrlParse(document: Document) = throw UnsupportedOperationException() | ||||||
|  | 
 | ||||||
|  |     private val statusOngoing = listOf("ongoing", "devam ediyor") | ||||||
|  |     private val statusCompleted = listOf("complete", "tamamlandı", "bitti") | ||||||
|  | 
 | ||||||
|  |     private fun String.parseStatus(): Int { | ||||||
|  |         return when (this.lowercase()) { | ||||||
|  |             in statusOngoing -> SManga.ONGOING | ||||||
|  |             in statusCompleted -> SManga.COMPLETED | ||||||
|  |             else -> SManga.UNKNOWN | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun Element.imgAttr(): String = when { | ||||||
|  |         hasAttr("data-pagespeed-high-res-src") -> dataImageAsUrl("data-pagespeed-high-res-src") | ||||||
|  |         hasAttr("data-pagespeed-lazy-src") -> dataImageAsUrl("data-pagespeed-lazy-src") | ||||||
|  |         else -> dataImageAsUrl("src") | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private fun parseDate(dateStr: String) = | ||||||
|  |         runCatching { dateFormat.parse(dateStr)!!.time } | ||||||
|  |             .getOrDefault(0L) | ||||||
|  | 
 | ||||||
|  |     companion object { | ||||||
|  |         const val SLUG_SEARCH_PREFIX = "slug:" | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| package eu.kanade.tachiyomi.multisrc.po2scans | package eu.kanade.tachiyomi.extension.tr.sadscans | ||||||
| 
 | 
 | ||||||
| import android.app.Activity | import android.app.Activity | ||||||
| import android.content.ActivityNotFoundException | import android.content.ActivityNotFoundException | ||||||
| @ -7,7 +7,7 @@ import android.os.Bundle | |||||||
| import android.util.Log | import android.util.Log | ||||||
| import kotlin.system.exitProcess | import kotlin.system.exitProcess | ||||||
| 
 | 
 | ||||||
| class PO2ScansUrlActivity : Activity() { | class SadscansUrlActivity : Activity() { | ||||||
|     override fun onCreate(savedInstanceState: Bundle?) { |     override fun onCreate(savedInstanceState: Bundle?) { | ||||||
|         super.onCreate(savedInstanceState) |         super.onCreate(savedInstanceState) | ||||||
|         val pathSegments = intent?.data?.pathSegments |         val pathSegments = intent?.data?.pathSegments | ||||||
| @ -15,17 +15,17 @@ class PO2ScansUrlActivity : Activity() { | |||||||
|             val slug = pathSegments[1] |             val slug = pathSegments[1] | ||||||
|             val mainIntent = Intent().apply { |             val mainIntent = Intent().apply { | ||||||
|                 action = "eu.kanade.tachiyomi.SEARCH" |                 action = "eu.kanade.tachiyomi.SEARCH" | ||||||
|                 putExtra("query", "${PO2Scans.SLUG_SEARCH_PREFIX}$slug") |                 putExtra("query", "${Sadscans.SLUG_SEARCH_PREFIX}$slug") | ||||||
|                 putExtra("filter", packageName) |                 putExtra("filter", packageName) | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             try { |             try { | ||||||
|                 startActivity(mainIntent) |                 startActivity(mainIntent) | ||||||
|             } catch (e: ActivityNotFoundException) { |             } catch (e: ActivityNotFoundException) { | ||||||
|                 Log.e("PO2ScansUrlActivity", "Could not start activity", e) |                 Log.e("SadscansUrlActivity", "Could not start activity", e) | ||||||
|             } |             } | ||||||
|         } else { |         } else { | ||||||
|             Log.e("PO2ScansUrlActivity", "could not parse URI from intent $intent") |             Log.e("SadscansUrlActivity", "could not parse URI from intent $intent") | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         finish() |         finish() | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Vetle Ledaal
						Vetle Ledaal