diff --git a/src/en/grrlpower/AndroidManifest.xml b/src/en/grrlpower/AndroidManifest.xml new file mode 100644 index 000000000..30deb7f79 --- /dev/null +++ b/src/en/grrlpower/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/src/en/grrlpower/build.gradle b/src/en/grrlpower/build.gradle new file mode 100644 index 000000000..71b1f50db --- /dev/null +++ b/src/en/grrlpower/build.gradle @@ -0,0 +1,12 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlinx-serialization' + +ext { + extName = 'Grrl Power Comic' + pkgNameSuffix = 'en.grrlpower' + extClass = '.GrrlPower' + extVersionCode = 1 +} + +apply from: "$rootDir/common.gradle" diff --git a/src/en/grrlpower/res/mipmap-hdpi/ic_launcher.png b/src/en/grrlpower/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..bfbe82900 Binary files /dev/null and b/src/en/grrlpower/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/en/grrlpower/res/mipmap-mdpi/ic_launcher.png b/src/en/grrlpower/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..0234d4684 Binary files /dev/null and b/src/en/grrlpower/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/en/grrlpower/res/mipmap-xhdpi/ic_launcher.png b/src/en/grrlpower/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..955bbee65 Binary files /dev/null and b/src/en/grrlpower/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/en/grrlpower/res/mipmap-xxhdpi/ic_launcher.png b/src/en/grrlpower/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..258d85762 Binary files /dev/null and b/src/en/grrlpower/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/en/grrlpower/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/grrlpower/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..50a67e715 Binary files /dev/null and b/src/en/grrlpower/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/en/grrlpower/res/web_hi_res_512.png b/src/en/grrlpower/res/web_hi_res_512.png new file mode 100644 index 000000000..829cb2707 Binary files /dev/null and b/src/en/grrlpower/res/web_hi_res_512.png differ diff --git a/src/en/grrlpower/src/eu/kanade/tachiyomi/extension/en/grrlpower/GrrlPower.kt b/src/en/grrlpower/src/eu/kanade/tachiyomi/extension/en/grrlpower/GrrlPower.kt new file mode 100644 index 000000000..014c6b286 --- /dev/null +++ b/src/en/grrlpower/src/eu/kanade/tachiyomi/extension/en/grrlpower/GrrlPower.kt @@ -0,0 +1,107 @@ +package eu.kanade.tachiyomi.extension.en.grrlpower + +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.asObservableSuccess +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.text.SimpleDateFormat +import java.util.Calendar +import java.util.Locale +import kotlin.collections.ArrayList + +@Suppress("unused") +class GrrlPower( + override val baseUrl: String = "https://www.grrlpowercomic.com", + override val lang: String = "en", + override val name: String = "Grrl Power Comic", + override val supportsLatest: Boolean = false, +) : HttpSource() { + private val startingYear = 2010 + private val currentYear = Calendar.getInstance().get(Calendar.YEAR) + private val dateFormat = SimpleDateFormat("MMM dd yyyy", Locale.US) + + override fun fetchPopularManga(page: Int): Observable = Observable.just( + MangasPage( + listOf( + SManga.create().apply { + artist = "David Barrack" + author = "David Barrack" + description = "Grrl Power is a comic about a crazy nerdette that becomes a" + + " superheroine. Humor, action, cheesecake, beefcake, 'splosions," + + " and maybe some drama. Possibly ninjas. " + genre = "superhero, humor, action" + initialized = true + status = SManga.ONGOING + // TODO: Find Proper Thumbnail and Extension Icon + thumbnail_url = "https://fakeimg.pl/550x780/cc3333/1b2a82/?font=museo&text=Grrl%0APower" + title = "Grrl Power" + url = "/archive" + } + ), + false + ) + )!! + + /** + There are separate pages for each year. + A Separate call needs to be made for each year since publication + After we get the response send on like normal and collect all the chapters. + */ + override fun fetchChapterList(manga: SManga): Observable> { + val ret: ArrayList = ArrayList() + for (i in startingYear..currentYear) { + client + .newCall(GET("$baseUrl/archive/?archive_year=$i")) + .asObservableSuccess() + .map { chapterListParse(it) } + .subscribe { ret.addAll(it) } + // Using A List of Observables and calling .from() won't work due to the number of + // observables active at once. error shown below for reference in case someone knows a fix. + // java.lang.IllegalArgumentException: Sequence contains too many elements + } + return Observable.just(ret) + } + + override fun chapterListParse(response: Response): List { + val year = response.request.url.toString().substringAfter('=').toInt() + var num = 0 + return response.asJsoup().getElementsByClass("archive-date").map { + val date = dateFormat.parse("${it.text()} $year") + val link = it.nextElementSibling().child(0) + SChapter.create().apply { + name = link.text() + setUrlWithoutDomain(link.attr("href")) + chapter_number = num++.toFloat() + date_upload = date?.time ?: 0L + } + } + } + + override fun pageListParse(response: Response): List { + return listOf( + Page( + 0, response.request.url.toString(), + response.asJsoup().selectFirst("div#comic img").absUrl("src") + ) + ) + } + // This can be called when the user refreshes the comic even if initialized is true + override fun fetchMangaDetails(manga: SManga): Observable = Observable.just(manga) + + override fun popularMangaRequest(page: Int): Request = throw UnsupportedOperationException("Not Used") + override fun searchMangaParse(response: Response): MangasPage = throw UnsupportedOperationException("Not Used") + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw UnsupportedOperationException("Not Used") + override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not Used") + override fun latestUpdatesParse(response: Response): MangasPage = throw UnsupportedOperationException("Not Used") + override fun latestUpdatesRequest(page: Int): Request = throw UnsupportedOperationException("Not Used") + override fun mangaDetailsParse(response: Response): SManga = throw UnsupportedOperationException("Not Used") + override fun popularMangaParse(response: Response): MangasPage = throw UnsupportedOperationException("Not Used") +}