### Complete Preference Screen Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/ConfigurableSource.md An example of a complete preference screen setup, adding string, boolean, dropdown, and slider preferences. Ensure keys are unique and sensible defaults are provided. ```kotlin override fun setupPreferenceScreen(screen: PreferenceScreen) { screen.addString("base_url", "Base URL", "", "https://example.com") screen.addString("api_key", "API Key", "Optional API key", "") screen.addBoolean("use_cache", "Use Local Cache", true) screen.addDropdown("image_quality", "Image Quality", 1, arrayOf("Low", "Medium", "High")) screen.addSlider("timeout", "Timeout (s)", 10, 5, 60, 5) } ``` -------------------------------- ### Page Usage Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/types.md Demonstrates how to create and iterate over a list of Page objects, accessing their properties like number and imageUrl. ```kotlin val pages = listOf( Page(0, "/chapter/123", "https://cdn.example.com/image1.jpg"), Page(1, "/chapter/123", "https://cdn.example.com/image2.jpg"), Page(2, "/chapter/123", "https://cdn.example.com/image3.jpg"), ) pages.forEach { page -> println("Page ${page.number}: ${page.imageUrl}") println("Status: ${page.status}") } ``` -------------------------------- ### Source with Configuration Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/README.md Shows how to add user-configurable settings to a source by implementing ConfigurableSource. This includes defining preferences and reading them within the source. ```kotlin class MyConfigurableSource : HttpSource(), ConfigurableSource { override val name = "My Configurable Source" override val baseUrl = "https://config.example.com" override val lang = "en" companion object { private const val QUALITY_PREF_KEY = "quality" } override fun setupPreferenceScreen(screen: PreferenceScreen) { val qualityPref = ListPreference(screen.context).apply { key = QUALITY_PREF_KEY title = "Image Quality" entries = arrayOf("Low", "Medium", "High") entryValues = arrayOf("1", "2", "3") setDefaultValue("2") } screen.addPreference(qualityPref) } override fun headersBuilder(): Headers.Builder { val headers = super.headersBuilder() val quality = getSourcePreferences().getString(QUALITY_PREF_KEY, "2") // Use the quality preference in headers or request parameters // headers.add("X-Quality", quality) return headers } // Implement other HttpSource methods } ``` -------------------------------- ### Metadata-Rich Source (SY) Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/_GENERATION_REPORT.txt Demonstrates a source that provides rich metadata, indicated by '(SY)', for enhanced content information. ```Kotlin class RichMetadataSource : HttpSource() { override val id: Long = 1001L override val name: String = "Rich Metadata Source (SY)" override suspend fun fetchMangaDetails(manga: SManga): SManga { // Implementation to fetch and enrich manga metadata return manga } // Other methods as needed... } ``` -------------------------------- ### getManga Implementation Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/OptionalInterfaces.md Provides an example implementation of the getManga function. It parses the manga ID from the URI, makes an HTTP GET request, and then parses the response to return an SManga object. Includes basic error handling. ```kotlin override suspend fun getManga(uri: String): SManga? { return try { val id = uri.substringAfterLast("/") val request = GET("$baseUrl/manga/$id", headers) val response = client.newCall(request).awaitSuccess() mangaDetailsParse(response) } catch (e: Exception) { null } } ``` -------------------------------- ### Source with Authentication Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/README.md Demonstrates how to implement authentication for a source by extending LoginSource. This involves implementing login, logout, and isLogged methods, and managing credentials. ```kotlin class MyAuthSource : HttpSource(), LoginSource { override val name = "My Auth Source" override val baseUrl = "https://secure.example.com" override val lang = "en" private var loggedIn = false override fun login(password: String): List // Implement login logic, store credentials, set loggedIn = true // Example: return listOf(Credentials("username", password)) throw NotImplementedError() override fun logout() // Implement logout logic, clear credentials, set loggedIn = false = Unit override fun isLogged() = loggedIn override fun headersBuilder(): Headers.Builder { val headers = super.headersBuilder() // Add authentication headers if logged in // if (loggedIn) headers.add("Authorization", "Bearer YOUR_TOKEN") return headers } // Implement other HttpSource methods } ``` -------------------------------- ### Setup Preference Screen UI Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/ConfigurableSource.md Builds the preference screen UI for the source. This method is called to populate the settings interface shown to the user. ```kotlin fun setupPreferenceScreen(screen: PreferenceScreen) ``` ```kotlin override fun setupPreferenceScreen(screen: PreferenceScreen) { screen.addString("base_url", "Base URL", "", "https://example.com") screen.addBoolean("use_legacy_api", "Use Legacy API", false) screen.addDropdown("image_quality", "Image Quality", 0, arrayOf("Low", "Medium", "High")) } ``` -------------------------------- ### Minimal CatalogueSource Implementation Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/CatalogueSource.md A basic example of a CatalogueSource implementation in Kotlin, demonstrating essential overrides for manga fetching and details. ```kotlin import eu.kanade.tachiyomi.source.CatalogueSource 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 class SimpleCatalogueSource : CatalogueSource { override val id: Long = 111222333 override val name: String = "Simple Catalogue" override val lang: String = "en" override val supportsLatest: Boolean = true // Mock data for example private val mockManga = listOf( SManga.create().apply { url = "/manga/1" title = "Manga A" thumbnail_url = "https://example.com/a.jpg" }, SManga.create().apply { url = "/manga/2" title = "Manga B" thumbnail_url = "https://example.com/b.jpg" } ) override suspend fun getPopularManga(page: Int): MangasPage { return MangasPage(mockManga, hasNextPage = false) } override suspend fun getSearchManga( page: Int, query: String, filters: FilterList ): MangasPage { val results = mockManga.filter { it.title.contains(query, ignoreCase = true) } return MangasPage(results, hasNextPage = false) } override suspend fun getLatestUpdates(page: Int): MangasPage { return MangasPage(mockManga, hasNextPage = false) } override fun getFilterList(): FilterList { return FilterList() } override suspend fun getMangaDetails(manga: SManga): SManga { return manga } override suspend fun getChapterList(manga: SManga): List { return emptyList() } override suspend fun getPageList(chapter: SChapter): List { return emptyList() } } ``` -------------------------------- ### Basic Source Implementation Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/README.md Illustrates the fundamental steps for creating a basic web source by extending ParsedHttpSource. This includes setting essential properties and implementing methods for popular manga retrieval. ```kotlin class MyBasicSource : ParsedHttpSource() { override val name = "My Basic Source" override val baseUrl = "https://example.com" override val lang = "en" override val supportsLatest = true override fun popularMangaRequest(page: Int) = GET(baseUrl) override fun popularMangaSelector() = ".manga-list .manga-item" override fun popularMangaFromElement(element: Element) = SManga.create().apply { url = element.select("a").first().attr("href") title = element.select(".manga-title").first().text() thumbnailUrl = element.select("img").first().attr("abs:src") } // Implement search, latest, manga details, chapters, and pages methods } ``` -------------------------------- ### Get Full Chapter URL Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/HttpSource.md Returns the complete URL for a chapter. Requires extensions-lib version 1.4 or later. ```kotlin open fun getChapterUrl(chapter: SChapter): String ``` -------------------------------- ### User Follow Lists (SY) Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/_GENERATION_REPORT.txt Shows an implementation for managing user follow lists, marked with '(SY)', allowing users to track their followed content. ```Kotlin class UserFollowListSource : HttpSource() { override val id: Long = 1002L override val name: String = "User Follow List (SY)" override suspend fun getmangasToFollow(): List { // Implementation to retrieve user's followed manga list return emptyList() } // Other methods as needed... } ``` -------------------------------- ### URL Importable Source Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/README.md Illustrates how to implement URL importing for a source by extending UrlImportableSource. This involves defining matching hosts and implementing the URL resolution logic. ```kotlin class MyUrlImportSource : HttpSource(), UrlImportableSource { override val name = "My URL Import Source" override val baseUrl = "https://import.example.com" override val lang = "en" override val matchingHosts = listOf("import.example.com") override fun handleUrl(url: String): String { // Parse the URL and return the manga URL within your source // Example: return "https://import.example.com/manga?id=${url.substringAfterLast('/')}" throw NotImplementedError() } // Implement other HttpSource methods } ``` -------------------------------- ### Custom Manga Source Implementation Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/ConfigurableSource.md An example implementation of a ConfigurableSource, demonstrating how to use SharedPreferences for dynamic settings like base URL and image quality. ```kotlin import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.PreferenceScreen import eu.kanade.tachiyomi.source.online.ParsedHttpSource class CustomMangaSource : ParsedHttpSource(), ConfigurableSource { override val name = "Custom Manga" override val lang = "en" override val baseUrl: String get() { val prefs = getSourcePreferences() return prefs.getString("base_url", "https://example.com") ?: "https://example.com" } override val supportsLatest = true private fun getImageQuality(): String { val prefs = getSourcePreferences() return when(prefs.getInt("image_quality", 1)) { 0 -> "low" 1 -> "medium" 2 -> "high" else -> "medium" } } private fun useProxy(): Boolean { val prefs = getSourcePreferences() return prefs.getBoolean("use_proxy", false) } override fun setupPreferenceScreen(screen: PreferenceScreen) { // String preference screen.addString( "base_url", "Base URL", "https://example.com", "https://example.com" ) // Boolean preference screen.addBoolean( "use_proxy", "Use Proxy", false ) // Dropdown preference screen.addDropdown( "image_quality", "Image Quality", 1, arrayOf("Low", "Medium", "High") ) } // Use preferences in request building override fun popularMangaRequest(page: Int): Request { val quality = getImageQuality() val url = "$baseUrl/popular?page=$page&quality=$quality" return GET(url, headers) } // ... implement other abstract methods } ``` -------------------------------- ### Create Search Manga Request Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/HttpSource.md Illustrates how to implement the searchMangaRequest method to build an HTTP GET request for searching manga. This example dynamically constructs the URL with query parameters for search terms and pagination. ```kotlin override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { val url = "$baseUrl/search".toHttpUrl().newBuilder() .addQueryParameter("q", query) .addQueryParameter("page", page.toString()) .build() return GET(url, headers) } ``` -------------------------------- ### Random Manga Source Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/_GENERATION_REPORT.txt Illustrates a source that provides random manga, showcasing one of the additional capabilities available. ```Kotlin class RandomMangaSource : HttpSource() { override val id: Long = 1000L override val name: String = "Random Manga" override suspend fun popularManga(page: Int): MangasPage { // Implementation to fetch random manga return MangasPage(emptyList(), true) } // Other methods as needed... } ``` -------------------------------- ### FilterList Usage Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/types.md Demonstrates how to create and populate a FilterList with various filter types like Header, SortFilter, Separator, StatusFilter, and GenreFilter. ```kotlin override fun getFilterList() = FilterList( Filter.Header("Filters"), SortFilter(), Filter.Separator(), StatusFilter(), GenreFilter() ) private class SortFilter : Filter.Select( "Sort by", arrayOf("Popular", "Recent", "Title") ) private class StatusFilter : Filter.CheckBox("Completed only", false) private class GenreFilter : Filter.Text("Genre") ``` -------------------------------- ### UnmeteredSource Example Implementation Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/OptionalInterfaces.md Demonstrates how to implement the UnmeteredSource marker interface alongside HttpSource. This indicates that the source, like a local server, does not have traffic or rate limiting concerns. ```kotlin class LocalMangaServer : HttpSource(), UnmeteredSource { override val name = "Local Server" override val lang = "en" override val baseUrl = "http://192.168.1.100:8080" override val supportsLatest = true // Implementation... } ``` -------------------------------- ### Image URL Parsing Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/SourceFactory.md Extracts the source URL of the main image from a document. ```kotlin override fun imageUrlParse(document: Document): String { return document.selectFirst("img.main-image")?.attr("src") ?: "" } ``` -------------------------------- ### SharedPreferences Standard Operations Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/ConfigurableSource.md Demonstrates standard read and write operations for SharedPreferences, including getting values with defaults and applying changes. ```kotlin val prefs = source.getSourcePreferences() // Reading preferences val stringValue = prefs.getString("key", "default") val intValue = prefs.getInt("key", 0) val boolValue = prefs.getBoolean("key", false) // Writing preferences val editor = prefs.edit() editor.putString("key", "value") editor.putInt("key", 42) editor.putBoolean("key", true) editor.apply() // or commit() ``` -------------------------------- ### Create Popular Manga Request Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/HttpSource.md Provides an example of implementing the popularMangaRequest method to construct an HTTP GET request for fetching popular manga. It includes the base URL and page number, along with default headers. ```kotlin override fun popularMangaRequest(page: Int): Request { return GET("$baseUrl/popular?page=$page", headers) } ``` -------------------------------- ### Create SManga Object Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/types.md Example of creating and populating an SManga object with details like URL, title, author, description, genre, status, and thumbnail URL. Sets the initialized flag to true. ```kotlin val manga = SManga.create().apply { url = "/manga/sample" title = "Sample Manga" author = "John Doe" artist = "Jane Smith" description = "An interesting manga" genre = "Action, Adventure, Comedy" status = SManga.ONGOING thumbnail_url = "https://example.com/cover.jpg" initialized = true } ``` -------------------------------- ### Get Full Manga URL Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/HttpSource.md Returns the complete URL for a manga. Requires extensions-lib version 1.4 or later. ```kotlin open fun getMangaUrl(manga: SManga): String ``` -------------------------------- ### Implementation Patterns Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/_GENERATION_REPORT.txt The documentation covers various implementation patterns to guide developers in creating different types of manga sources, from simple web scrapers to complex API-based integrations. ```APIDOC ## Implementation Patterns This section highlights common patterns and provides examples for implementing various types of manga sources. ### 1. Simple Web Source - **Description**: Implementing sources that rely on parsing HTML content from websites using CSS selectors. - **Relevant Interface**: `ParsedHttpSource` - **File**: `api-reference/ParsedHttpSource.md` - **Features Covered**: Element parsing, pagination handling. ### 2. API-Based Source - **Description**: Creating sources that interact with web APIs, typically involving JSON parsing and custom request/response management. - **Relevant Interface**: `HttpSource` - **File**: `api-reference/HttpSource.md` - **Features Covered**: Custom request/response handling, error handling patterns. ### 3. Multi-Source Extension - **Description**: Techniques for managing and extending multiple sources within a single extension. - **Relevant Interface**: `SourceFactory` - **File**: `api-reference/SourceFactory.md` Additional patterns covered include: - Multi-language source support - Authenticated source implementation - Configurable source options - URL import handling - Random manga generation - Other advanced patterns. ``` -------------------------------- ### Get Source Preference Key Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/ConfigurableSource.md Returns the preference key for this source, formatted as "source_". ```kotlin fun ConfigurableSource.preferenceKey(): String ``` ```kotlin val source = MyConfigurableSource() val key = source.preferenceKey() // "source_123456789" ``` -------------------------------- ### Create Page Objects Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/types.md Generates a list of Page objects, each representing a page within a chapter. Includes page index, URL, and the image URL for the page. This example creates 20 pages. ```kotlin val pages = (1..20).map { i -> Page(i - 1, "/chapter/1", "https://cdn.example.com/page$i.jpg") } ``` -------------------------------- ### Page List Parsing Example Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/SourceFactory.md Parses a document to extract a list of pages, typically from image elements within a specific div. ```kotlin override fun pageListParse(document: Document): List { return document.select("div.image img").mapIndexed { index, element -> Page(index, "", element.attr("data-src")) } } ``` -------------------------------- ### Minimal TachiyomiSY Source Implementation Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/README.md A basic example of a TachiyomiSY source extension using ParsedHttpSource. It demonstrates how to extend the base class and implement essential methods for fetching popular manga. ```kotlin class MyMangaSource : ParsedHttpSource() { override val baseUrl = "https://example.com" override val lang = "en" override val name = "My Manga Site" override val supportsLatest = true override fun popularMangaRequest(page: Int) = GET("$baseUrl/popular?page=$page", headers) override fun popularMangaSelector() = "div.manga-item" override fun popularMangaFromElement(element: Element) = SManga.create().apply { title = element.selectFirst("h2")?.text() ?: "" url = element.selectFirst("a")?.attr("href") ?: "" thumbnail_url = element.selectFirst("img")?.attr("src") } override fun popularMangaNextPageSelector() = "a.next" // ... implement remaining methods } ``` -------------------------------- ### Complete ParsedHttpSource Implementation Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/ParsedHttpSource.md This Kotlin code provides a full example of a manga source extending ParsedHttpSource. It includes methods for fetching popular manga, searching, listing latest updates, parsing manga details, chapter lists, page lists, and image URLs. Ensure all necessary Jsoup selectors are correctly defined for each method. ```kotlin import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.online.ParsedHttpSource import okhttp3.Request import org.jsoup.nodes.Document import org.jsoup.nodes.Element class ExampleMangaSource : ParsedHttpSource() { override val baseUrl = "https://example-manga.com" override val lang = "en" override val name = "Example Manga" override val supportsLatest = true // Popular Manga override fun popularMangaRequest(page: Int): Request { return GET("$baseUrl/popular?page=$page", headers) } override fun popularMangaSelector() = "div.manga-card" override fun popularMangaFromElement(element: Element): SManga { return SManga.create().apply { title = element.selectFirst("a.title")?.text() ?: "" url = element.selectFirst("a")?.attr("href") ?: "" thumbnail_url = element.selectFirst("img")?.attr("src") } } override fun popularMangaNextPageSelector() = "a.next-page" // Search override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { return GET("$baseUrl/search?q=$query&page=$page", headers) } override fun searchMangaSelector() = "div.manga-card" override fun searchMangaFromElement(element: Element): SManga { return popularMangaFromElement(element) } override fun searchMangaNextPageSelector() = "a.next-page" // Latest Updates override fun latestUpdatesRequest(page: Int): Request { return GET("$baseUrl/latest?page=$page", headers) } override fun latestUpdatesSelector() = "div.manga-card" override fun latestUpdatesFromElement(element: Element): SManga { return popularMangaFromElement(element) } override fun latestUpdatesNextPageSelector() = "a.next-page" // Manga Details override fun mangaDetailsParse(document: Document): SManga { return SManga.create().apply { title = document.selectFirst("h1.title")?.text() ?: "" author = document.selectFirst("div.author")?.text() artist = document.selectFirst("div.artist")?.text() description = document.selectFirst("div.description")?.text() genre = document.select("span.tag").joinToString(", ") { it.text() } status = when(document.selectFirst("div.status")?.text()) { "Ongoing" -> SManga.ONGOING "Completed" -> SManga.COMPLETED else -> SManga.UNKNOWN } } } // Chapters override fun chapterListSelector() = "div.chapter-item" override fun chapterFromElement(element: Element): SChapter { return SChapter.create().apply { name = element.selectFirst("span.title")?.text() ?: "" url = element.selectFirst("a")?.attr("href") ?: "" date_upload = 0L chapter_number = -1f } } // Pages override fun pageListParse(document: Document): List { return document.select("img.page-image").mapIndexed { index, element -> Page(index, "", element.attr("src")) } } // Image URL override fun imageUrlParse(document: Document): String { return document.selectFirst("img.main-image")?.attr("src") ?: "" } override fun getFilterList() = FilterList() } ``` -------------------------------- ### Get Page List Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/Source.md Fetches and returns the list of pages for a given chapter, ordered for reading. This method is fundamental for the reading experience, allowing the application to display individual pages of a chapter. It may throw exceptions if network requests or parsing fail. ```kotlin val source = MyMangaSource() val chapter = SChapter.create().apply { url = "/chapter/example" name = "Chapter 1" } val pages = source.getPageList(chapter) println("Total pages: ${pages.size}") pages.forEach { page -> println("Page ${page.number}: ${page.url}") } ``` -------------------------------- ### Advanced Manga Source with URL Import and Deep Linking Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/OptionalInterfaces.md An example implementation of a manga source that supports URL importing and deep linking. It defines how to resolve different URI types and extract manga details from URLs. ```kotlin class AdvancedMangaSource : ParsedHttpSource(), UrlImportableSource, ResolvableSource { override val matchingHosts = listOf("example.com", "www.example.com") override fun getUriType(uri: String): ResolvableSource.UriType { return when { uri.contains("/manga/") -> ResolvableSource.UriType.Manga uri.contains("/chapter/") -> ResolvableSource.UriType.Chapter else -> ResolvableSource.UriType.Unknown } } override suspend fun getManga(uri: String): SManga? { val id = uri.substringAfterLast("/") return try { val response = client.newCall(GET("$baseUrl/manga/$id", headers)) .awaitSuccess() mangaDetailsParse(response) } catch (e: Exception) { null } } override suspend fun getChapter(uri: String): SChapter? { // Implementation... return null } override suspend fun mapUrlToMangaUrl(uri: Uri): String? { return uri.path?.takeIf { it.startsWith("/manga/") } } // ... other required methods } ``` -------------------------------- ### Set Chapter URL Without Domain Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/HttpSource.md Sets the chapter URL, removing the scheme and domain for better resilience. This example demonstrates how to use the extension function. ```kotlin fun SChapter.setUrlWithoutDomain(url: String) ``` ```kotlin val chapter = SChapter.create() chapter.setUrlWithoutDomain("https://example.com/chapter/123") // chapter.url is now "/chapter/123" ``` -------------------------------- ### Get Chapter List Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/Source.md Fetches and returns all available chapters for a specific manga. This method is crucial for displaying a list of chapters to the user and enabling them to select a chapter for reading. It may throw exceptions if network requests or parsing fail. ```kotlin val source = MyMangaSource() val manga = SManga.create().apply { url = "/manga/example" title = "Example Manga" } val chapters = source.getChapterList(manga) chapters.forEach { chapter -> println("${chapter.name} - ${chapter.date_upload}") } ``` -------------------------------- ### setupPreferenceScreen Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/ConfigurableSource.md Builds the preference screen UI, which is called to populate the settings interface shown to the user. ```APIDOC ## setupPreferenceScreen ### Description Builds the preference screen UI. This is called to populate the settings interface shown to the user. ### Parameters #### Path Parameters - **screen** (`PreferenceScreen`) - Required - The preference screen to populate with preference UI elements. ### Example ```kotlin override fun setupPreferenceScreen(screen: PreferenceScreen) { screen.addString("base_url", "Base URL", "", "https://example.com") screen.addBoolean("use_legacy_api", "Use Legacy API", false) screen.addDropdown("image_quality", "Image Quality", 0, arrayOf("Low", "Medium", "High")) } ``` ``` -------------------------------- ### sourcePreferences (Extension Function) Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/ConfigurableSource.md An extension function for getting source preferences, considered a legacy method. ```APIDOC ## sourcePreferences ### Description Extension function for getting source preferences (legacy). ### Returns `SharedPreferences` — The SharedPreferences for this source. ``` -------------------------------- ### Change Application ID in build.gradle.kts Source: https://github.com/jobobby04/tachiyomisy/blob/master/CONTRIBUTING.md Modify the `applicationId` in the `build.gradle.kts` file to avoid installation conflicts when creating a fork. ```kotlin defaultConfig { applicationId = "eu.kanade.tachiyomi.your_fork_package_name" } ``` -------------------------------- ### Create Multiple Sources Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/SourceFactory.md Implement this method to return a list of all Source implementations provided by your factory. The app calls this when loading the extension. ```kotlin fun createSources(): List ``` ```kotlin class MyMangaSourcesFactory : SourceFactory { override fun createSources(): List { return listOf( EnglishMangaSource(), JapaneseMangaSource(), KoreanMangaSource() ) } } ``` -------------------------------- ### Creating a New Manga Instance Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/Source.md Demonstrates how to create and populate a new SManga object with essential details like URL, title, author, and status. ```kotlin val newManga = SManga.create().apply { url = "/manga/123" title = "My Favorite Manga" author = "Author Name" artist = "Artist Name" description = "An amazing manga" genre = "Action, Adventure, Comedy" status = SManga.ONGOING thumbnail_url = "https://example.com/thumb.jpg" initialized = true } ``` -------------------------------- ### Get Source SharedPreferences Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/ConfigurableSource.md Retrieves a SharedPreferences instance scoped to the specific source. Use this to persist and retrieve source-specific settings. ```kotlin fun getSourcePreferences(): SharedPreferences ``` ```kotlin val source = MyConfigurableSource() val prefs = source.getSourcePreferences() val baseUrl = prefs.getString("base_url", "https://default.com") ``` -------------------------------- ### Creating Chapters with Various Data Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/Source.md Shows how to create SChapter objects using different data sources, including timestamps, parsed strings, and scanlator information. ```kotlin // From timestamp val chapter1 = SChapter.create().apply { name = "Chapter 1" url = "/ch/1" date_upload = System.currentTimeMillis() chapter_number = 1f } // From parsed string val chapter2 = SChapter.create().apply { name = "Chapter 2: The Beginning" url = "/ch/2" chapter_number = 2f } // With scanlation group val chapter3 = SChapter.create().apply { name = "Chapter 3" url = "/ch/3" chapter_number = 3f scanlator = "Translation Group XYZ" } ``` -------------------------------- ### Get Filter List Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/CatalogueSource.md Retrieves the available filters for a source's search functionality. Use this to populate filter UI elements. ```kotlin val source = MyCatalogueSource() val filters = source.getFilterList() filters.forEach { filter -> println("Filter: ${filter.name}") } ``` -------------------------------- ### SourceFactory Implementation Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/_GENERATION_REPORT.txt Demonstrates the implementation of the SourceFactory, which is responsible for managing multiple language variants and instances of sources. ```Kotlin class SourceFactoryImpl : SourceFactory { private val sources = mutableMapOf() override fun get(id: String): Source? = sources[id] override fun register(source: Source) { sources[source.id] = source } override fun unregister(id: String) { sources.remove(id) } override fun all(): List = sources.values.toList() } ``` -------------------------------- ### Get Logged-in Username Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/LoginSource.md Retrieve the username of the currently logged-in user using the `getUsername` method. This can be used for display purposes or logging. ```kotlin fun getUsername(): String ``` -------------------------------- ### Source Factory for Multiple Sources Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/README.md Demonstrates the use of SourceFactory to manage and provide multiple distinct sources from a single extension. ```kotlin class MySourceFactory : SourceFactory { override fun createSources(): List { return listOf( MyBasicSource(), MyAuthSource(), MyConfigurableSource() ) } } ``` -------------------------------- ### Create SChapter Object Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/types.md Demonstrates the creation of an SChapter object, setting its name, URL, upload date, chapter number, and scanlator information. Used for representing individual chapters. ```kotlin val chapter = SChapter.create().apply { name = "Chapter 1: Beginning" url = "/chapter/1" date_upload = System.currentTimeMillis() chapter_number = 1f scanlator = "Translation Group" } ``` -------------------------------- ### Get Genres from SManga Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/types.md Parses the genre string of an SManga object into a list of individual genre tags. Returns null if the genre is empty. ```kotlin val manga = SManga.create().apply { title = "Action Manga" genre = "Action, Adventure, Shounen" } val genres = manga.getGenres() // Returns: ["Action", "Adventure", "Shounen"] ``` -------------------------------- ### Implement Multi-Source Extension with SourceFactory Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/SourceFactory.md Implement the SourceFactory interface to provide a list of multiple sources. Ensure a new list of source instances is returned each time createSources() is called. ```kotlin class MyMultiSourceExtension : SourceFactory { override fun createSources(): List { return listOf( SourceA(), SourceB(), SourceC() ) } } ``` -------------------------------- ### Get Source Filter List Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/HttpSource.md Returns the list of filters available for the source, used for search functionality. Override this method to provide custom filters. ```kotlin override fun getFilterList(): FilterList ``` -------------------------------- ### createSources Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/SourceFactory.md Creates and returns a list of source instances. This method is called by the application when loading the extension. ```APIDOC ## createSources ### Description Creates and returns a list of source instances. Called by the app when loading the extension. ### Method ```kotlin fun createSources(): List ``` ### Returns `List` - A list of Source implementations provided by this factory. ### Example ```kotlin class MyMangaSourcesFactory : SourceFactory { override fun createSources(): List { return listOf( EnglishMangaSource(), JapaneseMangaSource(), KoreanMangaSource() ) } } ``` ``` -------------------------------- ### Fetch Random Manga URL Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/OptionalInterfaces.md Implement this method to fetch the URL of a random manga from the source. It requires an HTTP client to make a GET request. ```kotlin suspend fun fetchRandomMangaUrl(): String ``` ```kotlin class MyRandomSource : HttpSource(), RandomMangaSource { override suspend fun fetchRandomMangaUrl(): String { val response = client.newCall(GET("$baseUrl/random", headers)) .awaitSuccess() return response.request.url.toString() } } ``` -------------------------------- ### Get Stored Password Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/LoginSource.md Access the stored password for the logged-in user via the `getPassword` method. Note that this password should be securely stored and ideally encrypted. ```kotlin fun getPassword(): String ``` -------------------------------- ### Create HTTP Request for Chapter List Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/HttpSource.md Creates an HTTP request to fetch the list of chapters for a manga. Defaults to using the manga's URL. ```Kotlin protected open fun chapterListRequest(manga: SManga): Request ``` -------------------------------- ### Handle Pagination in getPopularManga Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/CatalogueSource.md Demonstrates how to calculate the offset for paginated requests and determine if there's a next page based on the number of items returned. ```kotlin override suspend fun getPopularManga(page: Int): MangasPage { val offset = (page - 1) * ITEMS_PER_PAGE val url = "$baseUrl/popular?offset=$offset&limit=$ITEMS_PER_PAGE" val mangaList = fetchAndParseUrl(url) val hasNextPage = mangaList.size == ITEMS_PER_PAGE return MangasPage(mangaList, hasNextPage) } ``` -------------------------------- ### login (Username and Password) Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/LoginSource.md Authenticates the user with username and password. Returns true if login was successful, false otherwise. ```APIDOC ## login (Username and Password) ### Description Authenticates the user with username and password, optionally including a two-factor authentication code. ### Method N/A (Method Signature) ### Endpoint N/A ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None #### Method Parameters - **username** (String) - Required - The username to login with. - **password** (String) - Required - The password to login with. - **twoFactorCode** (String?) - Optional - The two-factor authentication code. ### Response #### Success Response - **loginSuccess** (Boolean) - True if login was successful, false otherwise. ### Request Example ```kotlin val source = MyLoginSource() val success = source.login("user123", "password", null) if (success) { println("Login successful") } else { println("Login failed") } ``` ``` -------------------------------- ### Minimal Manga Source Implementation Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/Source.md A basic implementation of the Source interface for a manga source. It includes methods for fetching manga details, chapter lists, and page lists. ```kotlin import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga class MinimalMangaSource : Source { override val id: Long = 123456789 override val name: String = "Minimal Source" override val lang: String = "en" override suspend fun getMangaDetails(manga: SManga): SManga { // Fetch and return updated manga details return manga.apply { description = "A manga from our source" author = "Unknown Author" status = SManga.ONGOING } } override suspend fun getChapterList(manga: SManga): List { // Return list of chapters for the manga return listOf( SChapter.create().apply { name = "Chapter 1" url = "/chapter/1" chapter_number = 1f }, SChapter.create().apply { name = "Chapter 2" url = "/chapter/2" chapter_number = 2f } ) } override suspend fun getPageList(chapter: SChapter): List { // Return list of pages for the chapter return (0..19).map { Page(it, chapter.url, "https://example.com/page_${it + 1}.jpg") } } } ``` -------------------------------- ### ConfigurableSource Interface Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/_GENERATION_REPORT.txt Outlines the ConfigurableSource interface, enabling preference management and UI configuration for sources. ```Kotlin interface ConfigurableSource : Source { fun setupPreferenceScreen(screen: PreferenceScreen) fun getPreferences(): SharedPreferences } ``` -------------------------------- ### Prepare New Chapter for Database Insertion Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/HttpSource.md This method is called before a new chapter is inserted into the database. Override it to modify chapter fields like title or chapter number. The example shows trimming whitespace from the chapter name. ```kotlin open fun prepareNewChapter(chapter: SChapter, manga: SManga) ``` ```kotlin override fun prepareNewChapter(chapter: SChapter, manga: SManga) { // Clean up or normalize chapter data chapter.name = chapter.name.trim() } ``` -------------------------------- ### Read and Write Preferences Safely Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/ConfigurableSource.md Demonstrates caching preference values and safely setting a string preference with error handling. Use `getSourcePreferences()` to access SharedPreferences. ```kotlin class MyConfigurableSource : HttpSource(), ConfigurableSource { // Cache preference values private val cachedBaseUrl: String get() = getSourcePreferences().getString("base_url", "https://default.com") ?: "https://default.com" private val cachedUseProxy: Boolean get() = getSourcePreferences().getBoolean("use_proxy", false) // Set preference with error handling private fun setBaseUrl(url: String) { try { val prefs = getSourcePreferences() prefs.edit().putString("base_url", url).apply() } catch (e: Exception) { println("Failed to save preference: ${e.message}") } } } ``` -------------------------------- ### MetadataMangasPage Constructor Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/types.md An extended MangasPage class that includes metadata for each manga and an optional pagination token for the next page. Used for enhanced manga listing with additional details. ```kotlin class MetadataMangasPage( override val mangas: List, override val hasNextPage: Boolean, val mangasMetadata: List, val nextKey: Long? = null, ) : MangasPage(mangas, hasNextPage) ``` -------------------------------- ### Implement Custom Filters with FilterList Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/CatalogueSource.md Shows how to define and return a FilterList containing various custom filter types like Select, Group, Sort, and CheckBox. ```kotlin override fun getFilterList(): FilterList { return FilterList( Filter.Header("Search Filters"), StatusFilter(), GenreFilter(), SortFilter(), Filter.Separator("Advanced"), CompletedOnlyFilter() ) } private class StatusFilter : Filter.Select( "Status", arrayOf("All", "Ongoing", "Completed", "Hiatus") ) private class GenreFilter : Filter.Group( "Genre", listOf("Action", "Comedy", "Drama") ) private class SortFilter : Filter.Sort( "Sort By", arrayOf("Popular", "Latest", "Title"), Sort.Selection(0, true) ) private class CompletedOnlyFilter : Filter.CheckBox( "Show Only Completed", false ) ``` -------------------------------- ### Get Manga Details Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/Source.md Fetches and returns the updated details for a given manga. This method is essential for retrieving comprehensive information about a manga, such as its description, cover image, and status. It may throw exceptions if network requests or parsing fail. ```kotlin val source = MyMangaSource() val manga = SManga.create().apply { url = "/manga/example" title = "Example Manga" } val updatedManga = source.getMangaDetails(manga) println("Updated title: ${updatedManga.title}") println("Artist: ${updatedManga.artist}") ``` -------------------------------- ### Create HTTP Request for Manga Details Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/HttpSource.md Creates an HTTP request to fetch detailed information for a given manga. Defaults to using the manga's URL. ```Kotlin open fun mangaDetailsRequest(manga: SManga): Request ``` -------------------------------- ### Handling Missing Manga Details Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/Source.md Illustrates how to provide default values and handle missing or blank data for fields like description, genre, status, URL, and title when fetching manga details. ```kotlin override suspend fun getMangaDetails(manga: SManga): SManga { return manga.apply { // Always provide defaults for missing fields description = description?.takeIf { it.isNotBlank() } ?: "No description available" // Genre parsing with fallback genre = genre?.takeIf { it.isNotBlank() } ?: "" // Status with intelligent default if (status == SManga.UNKNOWN) { status = SManga.ONGOING } // URL validation url = url.takeIf { it.isNotBlank() } ?: "/" // Title is critical if (title.isBlank()) { title = "Unknown Manga" } } } ``` -------------------------------- ### Handle Search Results Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/types.md Shows how to fetch search results for manga using a source and process the returned list of SManga objects. It prints the number of found manga, their titles, and indicates if more results are available. ```kotlin val result = source.getSearchManga(1, "action", FilterList()) println("Found ${result.mangas.size} manga") result.mangas.forEach { manga -> println("- ${manga.title}") } if (result.hasNextPage) { println("More results available") } ``` -------------------------------- ### Implement Single Source Extension Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/api-reference/SourceFactory.md Implement ParsedHttpSource directly if your extension provides only one source. ```kotlin class MySingleSourceExtension : ParsedHttpSource() { // ... implementation } ``` -------------------------------- ### Method Documentation Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/_GENERATION_REPORT.txt The TachiyomiSY Source API exposes over 100 methods, including suspend functions, regular methods, abstract methods, and utility functions, to facilitate source implementation and interaction. ```APIDOC ## Methods The TachiyomiSY Source API provides a rich set of methods for interacting with manga sources. ### Method Categories - **Suspend functions**: Asynchronous operations, typically for network requests or I/O bound tasks (40+ documented). - **Regular methods**: Standard synchronous functions (50+ documented). - **Abstract methods**: Methods that must be implemented by concrete source classes (20+ documented). - **Utility functions**: Helper functions for common tasks (10+ documented). ### Method Details - **Signatures**: Full method signatures, including parameter names, types, and return types, are documented. - **Parameters**: Detailed descriptions for each parameter. - **Return Types**: Specification of what each method returns. - **Usage Examples**: Demonstrations of how to use various methods. - **Exception Information**: Details on potential exceptions that may be thrown. ``` -------------------------------- ### ConfigurableSource Interface Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/README.md Allows users to customize source behavior via preferences. ```APIDOC ## ConfigurableSource Interface Allows users to customize source behavior via preferences. **File:** `api-reference/ConfigurableSource.md` ``` -------------------------------- ### ResolvableSource and UrlImportableSource Interfaces Source: https://github.com/jobobby04/tachiyomisy/blob/master/_autodocs/_GENERATION_REPORT.txt Introduces the ResolvableSource and UrlImportableSource interfaces, supporting URL import functionality and deep linking. ```Kotlin interface ResolvableSource : Source { suspend fun resolveUrl(url: String): String } interface UrlImportableSource : Source { suspend fun canImportUrl(url: String): Boolean suspend fun importFromUrl(url: String): manga } ```