diff --git a/src/all/commitstrip/AndroidManifest.xml b/src/all/commitstrip/AndroidManifest.xml new file mode 100644 index 000000000..30deb7f79 --- /dev/null +++ b/src/all/commitstrip/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/src/all/commitstrip/build.gradle b/src/all/commitstrip/build.gradle new file mode 100644 index 000000000..edf02ce39 --- /dev/null +++ b/src/all/commitstrip/build.gradle @@ -0,0 +1,12 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +ext { + extName = 'Commit Strip' + pkgNameSuffix = 'all.commitstrip' + extClass = '.CommitStripFactory' + extVersionCode = 1 + libVersion = '1.2' +} + +apply from: "$rootDir/common.gradle" diff --git a/src/all/commitstrip/res/mipmap-anydpi-v26/ic_launcher.xml b/src/all/commitstrip/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 000000000..036d09bc5 --- /dev/null +++ b/src/all/commitstrip/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/all/commitstrip/res/mipmap-anydpi-v26/ic_launcher_round.xml b/src/all/commitstrip/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 000000000..036d09bc5 --- /dev/null +++ b/src/all/commitstrip/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/all/commitstrip/res/mipmap-hdpi/ic_launcher.png b/src/all/commitstrip/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..50c30a115 Binary files /dev/null and b/src/all/commitstrip/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/all/commitstrip/res/mipmap-hdpi/ic_launcher_foreground.png b/src/all/commitstrip/res/mipmap-hdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..04a9df908 Binary files /dev/null and b/src/all/commitstrip/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/src/all/commitstrip/res/mipmap-hdpi/ic_launcher_round.png b/src/all/commitstrip/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 000000000..36f58997a Binary files /dev/null and b/src/all/commitstrip/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/src/all/commitstrip/res/mipmap-mdpi/ic_launcher.png b/src/all/commitstrip/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..9f687b68d Binary files /dev/null and b/src/all/commitstrip/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/all/commitstrip/res/mipmap-mdpi/ic_launcher_foreground.png b/src/all/commitstrip/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..69e3d06e0 Binary files /dev/null and b/src/all/commitstrip/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/src/all/commitstrip/res/mipmap-mdpi/ic_launcher_round.png b/src/all/commitstrip/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 000000000..83ddf95dc Binary files /dev/null and b/src/all/commitstrip/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/src/all/commitstrip/res/mipmap-xhdpi/ic_launcher.png b/src/all/commitstrip/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..e62422674 Binary files /dev/null and b/src/all/commitstrip/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/all/commitstrip/res/mipmap-xhdpi/ic_launcher_foreground.png b/src/all/commitstrip/res/mipmap-xhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..08491121d Binary files /dev/null and b/src/all/commitstrip/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/src/all/commitstrip/res/mipmap-xhdpi/ic_launcher_round.png b/src/all/commitstrip/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 000000000..83cbee17c Binary files /dev/null and b/src/all/commitstrip/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/src/all/commitstrip/res/mipmap-xxhdpi/ic_launcher.png b/src/all/commitstrip/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..194804739 Binary files /dev/null and b/src/all/commitstrip/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/all/commitstrip/res/mipmap-xxhdpi/ic_launcher_foreground.png b/src/all/commitstrip/res/mipmap-xxhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..53a952b41 Binary files /dev/null and b/src/all/commitstrip/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/src/all/commitstrip/res/mipmap-xxhdpi/ic_launcher_round.png b/src/all/commitstrip/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..2274067a5 Binary files /dev/null and b/src/all/commitstrip/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/src/all/commitstrip/res/mipmap-xxxhdpi/ic_launcher.png b/src/all/commitstrip/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..90fa1a557 Binary files /dev/null and b/src/all/commitstrip/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/all/commitstrip/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/src/all/commitstrip/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 000000000..b881c366d Binary files /dev/null and b/src/all/commitstrip/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/src/all/commitstrip/res/mipmap-xxxhdpi/ic_launcher_round.png b/src/all/commitstrip/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 000000000..c1ad23122 Binary files /dev/null and b/src/all/commitstrip/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/src/all/commitstrip/res/values/ic_launcher_background.xml b/src/all/commitstrip/res/values/ic_launcher_background.xml new file mode 100644 index 000000000..c5d5899fd --- /dev/null +++ b/src/all/commitstrip/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #FFFFFF + \ No newline at end of file diff --git a/src/all/commitstrip/src/eu/kanade/tachiyomi/extension/all/commitstrip/CommitStrip.kt b/src/all/commitstrip/src/eu/kanade/tachiyomi/extension/all/commitstrip/CommitStrip.kt new file mode 100644 index 000000000..18421b52d --- /dev/null +++ b/src/all/commitstrip/src/eu/kanade/tachiyomi/extension/all/commitstrip/CommitStrip.kt @@ -0,0 +1,185 @@ +package eu.kanade.tachiyomi.extension.all.commitstrip + +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 eu.kanade.tachiyomi.util.asJsoup +import okhttp3.Response +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import rx.Observable +import java.text.SimpleDateFormat +import java.util.Calendar +import java.util.Locale + +abstract class CommitStrip( + override val lang: String, + private val siteLang: String +) : ParsedHttpSource() { + + override val name = "Commit Strip" + override val baseUrl = "https://www.commitstrip.com" + + override val supportsLatest = false + + // Helper + + private fun createManga(year: Int): SManga = SManga.create().apply { + url = "$baseUrl/$siteLang/$year" + title = "$name ($year)" + thumbnail_url = when (lang) { + "en" -> LOGO_EN + "fr" -> LOGO_FR + else -> LOGO_EN + } + author = when (lang) { + "en" -> AUTHOR_EN + "fr" -> AUTHOR_FR + else -> AUTHOR_EN + } + artist = ARTIST + status = if (year != currentYear) SManga.COMPLETED else SManga.ONGOING + description = when (lang) { + "en" -> "$SUMMARY_EN $NOTE $year" + "fr" -> "$SUMMARY_FR $NOTE $year" + else -> "$SUMMARY_EN $NOTE $year" + } + } + + // Popular + + override fun fetchPopularManga(page: Int): Observable { + // have one manga entry for each year + return (currentYear downTo 2012) + .map { createManga(it) } + .let { Observable.just(MangasPage(it, false))!! } + } + + // Search + + override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = + fetchPopularManga(1).map { mangaList -> + mangaList.copy(mangaList.mangas.filter { it.title.contains(query) }) + } + + // Details + + override fun fetchMangaDetails(manga: SManga) = Observable.just( + manga.apply { + initialized = true + } + )!! + + // Chapters + + override fun fetchChapterList(manga: SManga): Observable> { + // create a new call to parse the no of pages in the site + // example responseString - Page 1 of 11 + val responseString = client.newCall(GET("${manga.url}", headers)).execute().run { + asJsoup().select(".wp-pagenavi .pages").first().text() + } + // use regex to get the last number (i.e. 11 above) + val pages = Regex("\\d+").findAll(responseString).last().value.toInt() + + return (1..pages).map { + val response = chapterListRequest(manga, it) + chapterListParse(response) + }.let { Observable.just(it.flatten()) } + } + + private fun chapterListRequest(manga: SManga, page: Int): Response = + client.newCall(GET("${manga.url}/page/$page", headers)).execute().run { + if (!isSuccessful) { + close() + throw Exception("HTTP error $code") + } + this + } + + override fun chapterListParse(response: Response): List { + return super.chapterListParse(response).reversed().distinct().mapIndexed { index, chapter -> + chapter.apply { chapter_number = index.toFloat() } + } + } + + override fun chapterListSelector() = ".excerpt a" + + override fun chapterFromElement(element: Element) = SChapter.create().apply { + url = element.attr("href") + + // get the chapter date from the url + val date = Regex("\\d{4}\\/\\d{2}\\/\\d{2}").find(url)?.value + val parsedDate = SimpleDateFormat("yyyy/MM/dd", Locale.US).parse(date) + date_upload = parsedDate?.time ?: 0L + + name = element.select("span").text() + } + + // Page + + override fun fetchPageList(chapter: SChapter): Observable> { + return client.newCall(GET("${chapter.url}", headers)).execute().run { + asJsoup().select(".entry-content p img").attr("src") + }.let { + Observable.just(listOf(Page(0, "", it))) + } + } + + // Unsupported + + override fun pageListParse(document: Document): List = throw Exception("Not Used") + + override fun imageUrlParse(document: Document) = throw Exception("Not used") + + override fun popularMangaSelector() = throw Exception("Not used") + + override fun searchMangaFromElement(element: Element) = throw Exception("Not used") + + override fun searchMangaNextPageSelector() = throw Exception("Not used") + + override fun searchMangaSelector() = throw Exception("Not used") + + override fun popularMangaRequest(page: Int) = throw Exception("Not used") + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = throw Exception("Not used") + + override fun popularMangaNextPageSelector() = throw Exception("Not used") + + override fun popularMangaFromElement(element: Element) = throw Exception("Not used") + + override fun mangaDetailsParse(document: Document) = throw Exception("Not used") + + override fun latestUpdatesNextPageSelector() = throw Exception("Not used") + + override fun latestUpdatesFromElement(element: Element) = throw Exception("Not used") + + override fun latestUpdatesRequest(page: Int) = throw Exception("Not used") + + override fun latestUpdatesSelector() = throw Exception("Not used") + + companion object { + private const val LOGO_EN = "https://i.imgur.com/HODJlt9.jpg" + + private const val LOGO_FR = "https://i.imgur.com/I7ps9zS.jpg" + + private const val AUTHOR_EN = "Mark Nightingale" + + private const val AUTHOR_FR = "Thomas Gx" + + private const val ARTIST = "Etienne Issartial" + + private const val SUMMARY_EN = "The blog relating the daily life of web agency developers." + + private const val SUMMARY_FR = "Le blog qui raconte la vie des codeurs" + + private const val NOTE = "\n\nNote: This entry includes all the chapters published in" + + private val currentYear by lazy { + Calendar.getInstance()[Calendar.YEAR] + } + } +} diff --git a/src/all/commitstrip/src/eu/kanade/tachiyomi/extension/all/commitstrip/CommitStripFactory.kt b/src/all/commitstrip/src/eu/kanade/tachiyomi/extension/all/commitstrip/CommitStripFactory.kt new file mode 100644 index 000000000..332f0e198 --- /dev/null +++ b/src/all/commitstrip/src/eu/kanade/tachiyomi/extension/all/commitstrip/CommitStripFactory.kt @@ -0,0 +1,14 @@ +package eu.kanade.tachiyomi.extension.all.commitstrip + +import eu.kanade.tachiyomi.source.Source +import eu.kanade.tachiyomi.source.SourceFactory + +class CommitStripFactory : SourceFactory { + override fun createSources(): List = listOf( + CommitStripEnglish(), + CommitStripFrench(), + ) +} + +class CommitStripEnglish() : CommitStrip("en", "en") +class CommitStripFrench() : CommitStrip("fr", "fr")