mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-04 08:08:55 +01:00 
			
		
		
		
	Add nhentai URL importing
Allow fast importing of single URLs by inputting the URL into the source's search bar
This commit is contained in:
		@@ -26,6 +26,8 @@ import okhttp3.CacheControl
 | 
			
		||||
import okhttp3.Headers
 | 
			
		||||
import okhttp3.Request
 | 
			
		||||
import org.jsoup.nodes.Document
 | 
			
		||||
import exh.GalleryAdder
 | 
			
		||||
import exh.util.urlImportFetchSearchManga
 | 
			
		||||
 | 
			
		||||
class EHentai(override val id: Long,
 | 
			
		||||
              val exh: Boolean,
 | 
			
		||||
@@ -50,6 +52,8 @@ class EHentai(override val id: Long,
 | 
			
		||||
 | 
			
		||||
    val metadataHelper = MetadataHelper()
 | 
			
		||||
 | 
			
		||||
    val galleryAdder = GalleryAdder()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gallery list entry
 | 
			
		||||
     */
 | 
			
		||||
@@ -142,6 +146,12 @@ class EHentai(override val id: Long,
 | 
			
		||||
    else
 | 
			
		||||
        exGet("$baseUrl/toplist.php?tl=15", page)
 | 
			
		||||
 | 
			
		||||
    //Support direct URL importing
 | 
			
		||||
    override fun fetchSearchManga(page: Int, query: String, filters: FilterList) =
 | 
			
		||||
            urlImportFetchSearchManga(query, {
 | 
			
		||||
                super.fetchSearchManga(page, query, filters)
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
 | 
			
		||||
        val uri = Uri.parse("$baseUrl$QUERY_PREFIX").buildUpon()
 | 
			
		||||
        uri.appendQueryParameter("f_search", query)
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ import exh.metadata.MetadataHelper
 | 
			
		||||
import exh.metadata.copyTo
 | 
			
		||||
import exh.metadata.models.NHentaiMetadata
 | 
			
		||||
import exh.metadata.models.Tag
 | 
			
		||||
import exh.util.urlImportFetchSearchManga
 | 
			
		||||
import okhttp3.Request
 | 
			
		||||
import okhttp3.Response
 | 
			
		||||
import rx.Observable
 | 
			
		||||
@@ -45,6 +46,12 @@ class NHentai(context: Context) : HttpSource() {
 | 
			
		||||
        TODO("Currently unavailable!")
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Support direct URL importing
 | 
			
		||||
    override fun fetchSearchManga(page: Int, query: String, filters: FilterList) =
 | 
			
		||||
            urlImportFetchSearchManga(query, {
 | 
			
		||||
                super.fetchSearchManga(page, query, filters)
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
    override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
 | 
			
		||||
        //Currently we have no filters
 | 
			
		||||
        //TODO Filter builder
 | 
			
		||||
@@ -82,7 +89,7 @@ class NHentai(context: Context) : HttpSource() {
 | 
			
		||||
            = nhGet(manga.url)
 | 
			
		||||
 | 
			
		||||
    fun urlToDetailsRequest(url: String)
 | 
			
		||||
            = nhGet(baseUrl + "/api/gallery/" + url.split("/").last())
 | 
			
		||||
            = nhGet(baseUrl + "/api/gallery/" + url.split("/").last { it.isNotBlank() })
 | 
			
		||||
 | 
			
		||||
    fun parseResultPage(response: Response): MangasPage {
 | 
			
		||||
        val res = jsonParser.parse(response.body()!!.string()).asJsonObject
 | 
			
		||||
 
 | 
			
		||||
@@ -62,38 +62,56 @@ class GalleryAdder {
 | 
			
		||||
        return "${uri.scheme}://${uri.host}/g/${obj["gid"].int}/${obj["token"].string}/"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun addGallery(url: String, fav: Boolean = false): GalleryAddEvent {
 | 
			
		||||
    fun addGallery(url: String,
 | 
			
		||||
                   fav: Boolean = false,
 | 
			
		||||
                   forceSource: Long? = null): GalleryAddEvent {
 | 
			
		||||
        try {
 | 
			
		||||
            val urlObj = Uri.parse(url)
 | 
			
		||||
            val source = when (urlObj.host) {
 | 
			
		||||
                "g.e-hentai.org", "e-hentai.org" -> EH_SOURCE_ID
 | 
			
		||||
                "exhentai.org" -> EXH_SOURCE_ID
 | 
			
		||||
                "nhentai.net" -> NHENTAI_SOURCE_ID
 | 
			
		||||
                else -> return GalleryAddEvent.Fail.UnknownType(url)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            val realUrl = when (urlObj.pathSegments.first().toLowerCase()) {
 | 
			
		||||
                "g" -> {
 | 
			
		||||
                    //Is already gallery page, do nothing
 | 
			
		||||
                    url
 | 
			
		||||
            if(forceSource != null && source != forceSource) {
 | 
			
		||||
                return GalleryAddEvent.Fail.UnknownType(url)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            val firstPathSegment = urlObj.pathSegments.firstOrNull()?.toLowerCase()
 | 
			
		||||
            val realUrl = when(source) {
 | 
			
		||||
                EH_SOURCE_ID, EXH_SOURCE_ID -> when (firstPathSegment) {
 | 
			
		||||
                    "g" -> {
 | 
			
		||||
                        //Is already gallery page, do nothing
 | 
			
		||||
                        url
 | 
			
		||||
                    }
 | 
			
		||||
                    "s" -> {
 | 
			
		||||
                        //Is page, fetch gallery token and use that
 | 
			
		||||
                        getGalleryUrlFromPage(url)
 | 
			
		||||
                    }
 | 
			
		||||
                    else -> return GalleryAddEvent.Fail.UnknownType(url)
 | 
			
		||||
                }
 | 
			
		||||
                "s" -> {
 | 
			
		||||
                    //Is page, fetch gallery token and use that
 | 
			
		||||
                    getGalleryUrlFromPage(url)
 | 
			
		||||
                }
 | 
			
		||||
                else -> {
 | 
			
		||||
                    return GalleryAddEvent.Fail.UnknownType(url)
 | 
			
		||||
                NHENTAI_SOURCE_ID -> when {
 | 
			
		||||
                    firstPathSegment == "g" -> url
 | 
			
		||||
                    urlObj.pathSegments.size >= 3 -> "https://nhentai.net/g/${urlObj.pathSegments[1]}/"
 | 
			
		||||
                    else -> return GalleryAddEvent.Fail.UnknownType(url)
 | 
			
		||||
                }
 | 
			
		||||
                else -> return GalleryAddEvent.Fail.UnknownType(url)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            val sourceObj = sourceManager.get(source)
 | 
			
		||||
                    ?: return GalleryAddEvent.Fail.Error(url, "Could not find EH source!")
 | 
			
		||||
 | 
			
		||||
            val pathOnlyUrl = getUrlWithoutDomain(realUrl)
 | 
			
		||||
            val cleanedUrl = when(source) {
 | 
			
		||||
                EH_SOURCE_ID, EXH_SOURCE_ID -> getUrlWithoutDomain(realUrl)
 | 
			
		||||
                NHENTAI_SOURCE_ID -> realUrl //nhentai uses URLs directly (oops, my bad when implementing this source)
 | 
			
		||||
                else -> return GalleryAddEvent.Fail.UnknownType(url)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //Use manga in DB if possible, otherwise, make a new manga
 | 
			
		||||
            val manga = db.getManga(pathOnlyUrl, source).executeAsBlocking()
 | 
			
		||||
            val manga = db.getManga(cleanedUrl, source).executeAsBlocking()
 | 
			
		||||
                    ?: Manga.create(source).apply {
 | 
			
		||||
                this.url = pathOnlyUrl
 | 
			
		||||
                this.url = cleanedUrl
 | 
			
		||||
                title = realUrl
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -101,7 +119,12 @@ class GalleryAdder {
 | 
			
		||||
            manga.copyFrom(sourceObj.fetchMangaDetails(manga).toBlocking().first())
 | 
			
		||||
 | 
			
		||||
            //Apply metadata
 | 
			
		||||
            metadataHelper.fetchEhMetadata(realUrl, isExSource(source))?.copyTo(manga)
 | 
			
		||||
            when(source) {
 | 
			
		||||
                EH_SOURCE_ID, EXH_SOURCE_ID ->
 | 
			
		||||
                    metadataHelper.fetchEhMetadata(realUrl, isExSource(source))?.copyTo(manga)
 | 
			
		||||
                NHENTAI_SOURCE_ID ->
 | 
			
		||||
                    metadataHelper.fetchNhentaiMetadata(realUrl)?.copyTo(manga)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (fav) manga.favorite = true
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@ class NHentaiMetadata : SearchableGalleryMetadata() {
 | 
			
		||||
    var url get() = id?.let { "$BASE_URL/g/$it" }
 | 
			
		||||
    set(a) {
 | 
			
		||||
        a?.let {
 | 
			
		||||
            id = a.split("/").last().toLong()
 | 
			
		||||
            id = a.split("/").last { it.isNotBlank() }.toLong()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										28
									
								
								app/src/main/java/exh/util/SearchOverride.kt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								app/src/main/java/exh/util/SearchOverride.kt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
package exh.util
 | 
			
		||||
 | 
			
		||||
import eu.kanade.tachiyomi.source.Source
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.MangasPage
 | 
			
		||||
import exh.GalleryAddEvent
 | 
			
		||||
import exh.GalleryAdder
 | 
			
		||||
import rx.Observable
 | 
			
		||||
 | 
			
		||||
private val galleryAdder by lazy {
 | 
			
		||||
    GalleryAdder()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A version of fetchSearchManga that supports URL importing
 | 
			
		||||
 */
 | 
			
		||||
fun Source.urlImportFetchSearchManga(query: String, fail: () -> Observable<MangasPage>) =
 | 
			
		||||
        when {
 | 
			
		||||
            query.startsWith("http://") || query.startsWith("https://") -> {
 | 
			
		||||
                Observable.fromCallable {
 | 
			
		||||
                    val res = galleryAdder.addGallery(query, false, id)
 | 
			
		||||
                    MangasPage((if(res is GalleryAddEvent.Success)
 | 
			
		||||
                        listOf(res.manga)
 | 
			
		||||
                    else
 | 
			
		||||
                        emptyList()), false)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else -> fail()
 | 
			
		||||
        }
 | 
			
		||||
		Reference in New Issue
	
	Block a user