added source: Aurora to fulfill #9985 (#9986)

* added source: Aurora to fulfill #9985

* Update src/en/aurora/src/eu/kanade/tachiyomi/extension/en/aurora/Aurora.kt

added headers to the get request

Co-authored-by: ObserverOfTime <chronobserver@disroot.org>

* Update src/en/aurora/src/eu/kanade/tachiyomi/extension/en/aurora/Aurora.kt

removed a filter

Co-authored-by: ObserverOfTime <chronobserver@disroot.org>

* Update src/en/aurora/src/eu/kanade/tachiyomi/extension/en/aurora/Aurora.kt

removed filter

Co-authored-by: ObserverOfTime <chronobserver@disroot.org>

* used client.newCall instead of Jsoup to fullfill code review of #9986

* chapters to mangas and pages to chapters to fix automatic updates. #9985

* added automatic status fetching when a chapter (in form of a manga) is updated

* added the name of the manga/comic in front of the chapter name so it can be more easily differenciated from other manga

* Update src/en/aurora/src/eu/kanade/tachiyomi/extension/en/aurora/Aurora.kt

removed some regex stuff

Co-authored-by: ObserverOfTime <chronobserver@disroot.org>

* Update src/en/aurora/src/eu/kanade/tachiyomi/extension/en/aurora/Aurora.kt

removed some logging that isn't needed anymore

Co-authored-by: ObserverOfTime <chronobserver@disroot.org>

* Apply suggestions from code review

accepted some code review changes

Co-authored-by: ObserverOfTime <chronobserver@disroot.org>

* implemented some more code review suggestions

* Apply suggestions from code review

Co-authored-by: ObserverOfTime <chronobserver@disroot.org>

Co-authored-by: ObserverOfTime <chronobserver@disroot.org>
This commit is contained in:
THE-ORONCO 2021-12-08 14:24:44 +01:00 committed by GitHub
parent 5c5e997c04
commit fc4d99e1e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 218 additions and 0 deletions

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="eu.kanade.tachiyomi.extension" />

View File

@ -0,0 +1,11 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = 'aurora'
pkgNameSuffix = 'en.aurora'
extClass = '.Aurora'
extVersionCode = 1
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

View File

@ -0,0 +1,205 @@
package eu.kanade.tachiyomi.extension.en.aurora
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.HttpSource
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Request
import okhttp3.Response
import rx.Observable
import java.lang.Exception
import java.text.SimpleDateFormat
import java.util.Locale
/**
* @author THE_ORONCO <the_oronco@posteo.net>
*/
class Aurora : HttpSource() {
override val name = "Aurora"
override val baseUrl = "https://comicaurora.com"
override val lang = "en"
override val supportsLatest = false
private val authorName = "OSP-Red"
private val auroraGenre = "fantasy"
private val dateFormat = SimpleDateFormat("MMMM dd, yyyy", Locale.US)
override fun chapterListRequest(manga: SManga): Request = throw Exception("Not used")
override fun chapterListParse(response: Response): List<SChapter> = throw Exception("Not used")
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> {
return Observable.just(fetchChapterListTR(baseUrl + manga.url, mutableListOf()))
}
private tailrec fun fetchChapterListTR(
currentUrl: String,
foundChapters: MutableList<SChapter>
): MutableList<SChapter> {
val currentPage = client.newCall(GET(currentUrl, headers)).execute().asJsoup()
val pagesAsChapters = currentPage.select(".post-content")
.map { postContent ->
val chapterUrl = postContent.select("a.webcomic-link").attr("href")
val title = postContent.select(".post-title a").text()
val chapterNr = title.substringAfter('.').toFloat()
val dateString = postContent.select(".post-date").text()
val date = dateFormat.parse(dateString)?.time ?: 0L
SChapter.create().apply {
setUrlWithoutDomain(chapterUrl)
name = title
chapter_number = chapterNr
date_upload = date
}
}
foundChapters.addAll(pagesAsChapters)
// get a potential next page of the chapter overview
val nextPageNavUrl = currentPage.selectFirst(".paginav-next a")?.attr("href")
// check if a next page actually exits and if not exit
return if (nextPageNavUrl == null) {
foundChapters
} else {
fetchChapterListTR(nextPageNavUrl, foundChapters)
}
}
override fun fetchImageUrl(page: Page): Observable<String> {
return Observable.just(page.imageUrl)
}
override fun imageUrlParse(response: Response): String = throw Exception("Not used")
override fun latestUpdatesParse(response: Response): MangasPage = throw Exception("Not used")
override fun latestUpdatesRequest(page: Int): Request = throw Exception("Not used")
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
val chapterNr = manga.title.substringAfter(' ').toFloatOrNull() ?: 0f
val updatedManga = SManga.create().apply {
setUrlWithoutDomain(manga.url)
title = manga.title
artist = authorName
author = authorName
description = auroraDescription
genre = auroraGenre
status = getChapterStatusForChapter(chapterNr)
thumbnail_url = manga.thumbnail_url
}
return Observable.just(updatedManga)
}
/**
* @param chapter chapter the status should be fetched for
* @return the status of the chapter (as Enum value of SManga because chapters are mangas)
*/
private fun getChapterStatusForChapter(chapter: Float): Int {
val newestPage = client.newCall(GET(baseUrl)).execute().asJsoup()
val postTitle = newestPage.selectFirst(".post-title").text()
// title is "<arc>.<chapter>.<page>"
val chapterOfNewestPage = postTitle.split(".")[1].toFloat()
return if (chapter >= chapterOfNewestPage) SManga.UNKNOWN else SManga.COMPLETED
}
private val auroraDescription = """
Aurora is a fantasy webcomic (updates M/W/F) written and illustrated by Red, better known for her work on the YouTube channel Overly Sarcastic Productions. Its been in the works for over a decade, and shes finally decided to stop putting it off.
If youd like to discuss the comic, it now has a subreddit, as well as a dedicated twitter and a tumblr where you can ask questions. Theres also a dedicated room on the channel discord for conversations about it!
Find Reds general ramblings on Twitter, alongside her cohost Blue, at OSPYouTube.
""".trimIndent()
override fun mangaDetailsParse(response: Response): SManga = throw Exception("Not used")
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
val singlePageChapterDoc = client.newCall(
GET(baseUrl + chapter.url, headers)
).execute().asJsoup()
val imageUrl = singlePageChapterDoc.selectFirst(
".webcomic-media .webcomic-link .attachment-full"
).attr("src")
val singlePageChapter = Page(0, "", imageUrl)
return Observable.just(listOf(singlePageChapter))
}
override fun pageListRequest(chapter: SChapter): Request = throw Exception("Not used")
override fun pageListParse(response: Response): List<Page> = throw Exception("Not used")
/**
* Because the comic is updated 1 page at a time the chapters are turned into different mangas
* so that the pages can be turned into different chapters which can be automatically updated by
* Tachiyomi.
*
* @return List of all Chapters as separate mangas
*/
private fun fetchChaptersAsMangas(): List<SManga> {
val descriptionText = auroraDescription
val chapterArchiveUrl = "$baseUrl/archive/"
val chapterOverviewDoc = client.newCall(GET(chapterArchiveUrl, headers)).execute().asJsoup()
val chapterBlockElements = chapterOverviewDoc.select(".blocks-gallery-item")
val mangasFromChapters = chapterBlockElements
.mapIndexed { chapterIndex, chapter ->
val chapterOverviewLink = chapter.selectFirst(".blocks-gallery-item__caption a")
val chapterOverviewUrl = chapterOverviewLink.attr("href")
val chapterTitle = "$name - ${chapterOverviewLink.text()}"
val chapterThumbnail = chapter.selectFirst("figure img").attr("src")
SManga.create().apply {
setUrlWithoutDomain(chapterOverviewUrl)
title = chapterTitle
author = authorName
artist = authorName
description = descriptionText
genre = auroraGenre
// this will mark every chapter except the last one as completed
status =
if (chapterIndex >= chapterBlockElements.size - 1) SManga.UNKNOWN
else SManga.COMPLETED
thumbnail_url = chapterThumbnail
}
}
return mangasFromChapters
}
/**
* Turn the list of chapters as mangas into the mangas page that can be returned for every
* request.
*/
private fun generateAuroraMangasPage(): MangasPage {
return MangasPage(fetchChaptersAsMangas(), false)
}
override fun fetchPopularManga(page: Int): Observable<MangasPage> {
return Observable.just(generateAuroraMangasPage())
}
override fun popularMangaParse(response: Response): MangasPage = throw Exception("Not used")
override fun popularMangaRequest(page: Int): Request = throw Exception("Not used")
override fun fetchSearchManga(
page: Int,
query: String,
filters: FilterList
): Observable<MangasPage> {
return Observable.just(generateAuroraMangasPage())
}
override fun searchMangaParse(response: Response): MangasPage = throw Exception("Not used")
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request =
throw Exception("Not used")
}