Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b496959
Save current work before sparse update
towermom9 Jul 14, 2026
172d3e6
Save current work before sparse update
towermom9 Jul 14, 2026
523e51e
Revert "MangaGeko, RageScans, Mangago, FlameComics: Split/add alt tit…
towermom9 Jul 14, 2026
32037b9
Reapply "MangaGeko, RageScans, Mangago, FlameComics: Split/add alt ti…
towermom9 Jul 14, 2026
2d43878
Delete gradle/gradle-daemon-jvm.properties
towermom9 Jul 14, 2026
56c5273
Merge branch 'main' into main
towermom9 Jul 15, 2026
716cd88
Update lib-multisrc/pawchive/build.gradle.kts
towermom9 Jul 15, 2026
710e95a
Update lib-multisrc/pawchive/build.gradle.kts
towermom9 Jul 15, 2026
c1c9620
Update lib-multisrc/pawchive/src/eu/kanade/tachiyomi/multisrc/pawchiv…
towermom9 Jul 15, 2026
3a79bf8
Update lib-multisrc/pawchive/src/eu/kanade/tachiyomi/multisrc/pawchiv…
towermom9 Jul 15, 2026
1f32995
Merge branch 'main' into main
towermom9 Jul 15, 2026
8364f2f
Delete lib-multisrc/pawchive directory
towermom9 Jul 15, 2026
fba8334
Moved multisrc to src and stripped some code
towermom9 Jul 15, 2026
c64cb94
Merge branch 'main' of https://github.com/towermom9/extensions-source
towermom9 Jul 15, 2026
0eb4f6f
Merge branch 'main' into main
towermom9 Jul 15, 2026
45a2484
Merge branch 'main' into main
towermom9 Jul 15, 2026
5a4560d
Merge branch 'main' into main
towermom9 Jul 16, 2026
8c334aa
Merge branch 'main' into main
towermom9 Jul 16, 2026
81e547e
Merge branch 'main' into main
towermom9 Jul 16, 2026
aaae469
1.6
towermom9 Jul 16, 2026
ac881f0
Merge branch 'main' of https://github.com/towermom9/extensions-source…
towermom9 Jul 16, 2026
7dc3de5
Update src/all/pawchive/src/eu/kanade/tachiyomi/extension/all/pawchiv…
towermom9 Jul 17, 2026
49e1193
Update src/all/pawchive/src/eu/kanade/tachiyomi/extension/all/pawchiv…
towermom9 Jul 17, 2026
be6fa16
Update src/all/pawchive/src/eu/kanade/tachiyomi/extension/all/pawchiv…
towermom9 Jul 17, 2026
155e483
Update src/all/pawchive/src/eu/kanade/tachiyomi/extension/all/pawchiv…
towermom9 Jul 17, 2026
a9a5c61
Merge branch 'keiyoushi:main' into main
towermom9 Jul 17, 2026
9178b45
hopefully final
towermom9 Jul 17, 2026
a58d1bd
hopefully final
towermom9 Jul 17, 2026
066d3ff
Merge branch 'main' into main
towermom9 Jul 18, 2026
4408059
hopefully final 2
towermom9 Jul 18, 2026
5e47a8e
fixed apiUrl to url
towermom9 Jul 18, 2026
7bf825a
Remove redundant '.use {}' wrapper since 'parseAs()' automatically cl…
towermom9 Jul 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/all/pawchive/build.gradle.kts
Comment thread
towermom9 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import io.github.keiyoushi.gradle.api.ContentWarning

plugins {
alias(kei.plugins.extension)
}

keiyoushi {
name = "Pawchive"
versionCode = 1
contentWarning = ContentWarning.NSFW
libVersion = "1.6"

source {
lang = "all"
baseUrl = "https://pawchive.pw"
}
}
Binary file added src/all/pawchive/res/mipmap-hdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/all/pawchive/res/mipmap-mdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/all/pawchive/res/mipmap-xhdpi/ic_launcher.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
107 changes: 107 additions & 0 deletions src/all/pawchive/src/eu/kanade/tachiyomi/extension/all/pawchive/Dto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package eu.kanade.tachiyomi.extension.all.pawchive

import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.double
import kotlin.time.Instant

@Serializable
class PawchiveFavoritesDto(
val id: String,
val faved_seq: Long,
)

@Serializable
class PawchiveCreatorDto(
val id: String,
val name: String,
val service: String,
private val updated: JsonPrimitive,
val favorited: Int = -1,
) {
@Transient
var fav: Long = 0L

val updatedDate get() = when {
updated.isString -> Instant.parseOrNull(updated.content)?.toEpochMilliseconds() ?: 0L
else -> (updated.double * 1000).toLong()
}

fun toSManga(baseUrl: String) = SManga.create().apply {
url = "/$service/user/$id"
Comment thread
AwkwardPeak7 marked this conversation as resolved.
title = name
author = service.serviceName()
thumbnail_url = "$baseUrl/icons/$service/$id"
description = Pawchive.PROMPT
initialized = true
}

companion object {
fun String.serviceName() = when (this) {
"fanbox" -> "Pixiv Fanbox"
else -> replaceFirstChar { it.uppercase() }
}
}
}

@Serializable
class PawchivePostDto(
private val id: String,
private val service: String,
private val user: String,
private val title: String,
private val added: String? = null,
private val published: String? = null,
private val edited: String? = null,
private val file: PawchiveFileDto? = null,
private val attachments: List<PawchiveFileDto> = emptyList(),
) {
val images: List<String>
get() = (listOfNotNull(file) + attachments)
.filter { it.path != null && it.path.substringAfterLast('.').lowercase() in validImageExtensions }
.distinctBy { it.path }
.map { it.toString() }

fun toSChapter(serviceName: String?, datePref: String) = SChapter.create().apply {
val dateStr = when (datePref) {
"added" -> added ?: published ?: edited
"edited" -> edited ?: published ?: added
else -> published ?: added ?: edited // Default to published
}

val postDate = dateStr?.let {
val dateWithTz = if (it.endsWith("Z") || it.contains("+")) {
it
} else {
it + if (serviceName == "Pixiv Fanbox") "+09:00" else "Z"
}
Instant.parseOrNull(dateWithTz)?.toEpochMilliseconds()
} ?: 0L

url = "/$service/user/$user/post/$id"
date_upload = postDate

name = title.ifBlank {
val postDateString = if (postDate != 0L && dateStr != null) {
// Strips any unexpected timezone markers and recreates "yyyy-MM-dd 'at' HH:mm:ss" natively
dateStr.substringBefore("+").substringBefore("Z").replace("T", " at ")
} else {
"unknown date"
}
"Post from $postDateString"
}
chapter_number = -2f
}

companion object {
private val validImageExtensions = setOf("png", "jpg", "gif", "jpeg", "webp")
}
}

@Serializable
class PawchiveFileDto(val name: String? = null, val path: String? = null) {
override fun toString() = path + if (name != null) "?f=$name" else ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package eu.kanade.tachiyomi.extension.all.pawchive

import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
val getTypes = listOf("Patreon", "Pixiv Fanbox")

val getSortsList: List<Pair<String, String>> = listOf(
Pair("Popularity", "pop"),
Pair("Date Indexed", "new"),
Pair("Date Updated", "lat"),
Pair("Alphabetical Order", "tit"),
Pair("Service", "serv"),
Pair("Date Favorited", "fav"),
)

class TypeFilter(name: String, vals: List<String>) : Filter.Group<TriFilter>(name, vals.map { TriFilter(it, it.lowercase()) })

class FavoritesFilter : Filter.Group<TriFilter>("Favorites", listOf(TriFilter("Favorites Only", "fav")))

class TriFilter(name: String, val value: String) : Filter.TriState(name)

class SortFilter(name: String, selection: Selection, private val vals: List<Pair<String, String>>) : Filter.Sort(name, vals.map { it.first }.toTypedArray(), selection) {
fun getValue() = vals[state!!.index].second
}

fun getLatestUpdatesFilterList(): FilterList = FilterList(
SortFilter("Sort by", Filter.Sort.Selection(2, false), getSortsList),
TypeFilter("Types", getTypes),
FavoritesFilter(),
)

fun getDefaultFilterList(): FilterList = FilterList(
SortFilter("Sort by", Filter.Sort.Selection(0, false), getSortsList),
TypeFilter("Types", getTypes),
FavoritesFilter(),
)
Loading