Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add automatic-generated documentation #6

Merged
merged 15 commits into from
Aug 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
33 changes: 33 additions & 0 deletions .github/workflows/docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Generate docs

on:
push:
branches:
- main
paths-ignore:
- '**.md'
- '**.yaml'
workflow_dispatch:

permissions:
contents: write
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up JDK
uses: actions/setup-java@v3
with:
java-version: 11
distribution: adopt

- name: Build documentation
run: ./gradlew :library:dokkaHtml

- name: Publish documentation
uses: JamesIves/github-pages-deploy-action@releases/v4
with:
BRANCH: gh-pages
FOLDER: library/build/docs
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ buildscript {
}
}

plugins {
id 'org.jetbrains.dokka' version '1.7.20' apply false
}

allprojects {
repositories {
mavenCentral()
Expand Down
30 changes: 30 additions & 0 deletions library/Module.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Module extensions-lib
The Aniyomi API exposed to extensions via stubs.

# Package androidx.preference
Android preferences classes exposed to extensions.

## NOTE
Not all classes from [*androidx.preference*](https://developer.android.com/reference/androidx/preference/package-summary) package
were implemented as stubs, so if you need to use a non-implemented class, you must add the following into the extension's build.gradle file:
```kotlin
dependencies {
compileOnly("androidx.preference:preference-ktx:1.2.0")
}
```

# Package eu.kanade.tachiyomi.animesource
Classes and interfaces for more complex extensions, like ones with multiple sources or user preferences.

# Package eu.kanade.tachiyomi.animesource.model
Required data classes to interact with Aniyomi.

# Package eu.kanade.tachiyomi.animesource.online
Single-source creation classes, sufficient to most extensions.

# Package eu.kanade.tachiyomi.network
Useful methods for creating http requests and manipulate responses.

# Package eu.kanade.tachiyomi.network.interceptor
Useful methods to slow down http requests and prevent IP-ban or accidental DDoS.

42 changes: 42 additions & 0 deletions library/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import org.jetbrains.dokka.gradle.DokkaTask
import org.jetbrains.dokka.DokkaConfiguration.Visibility

plugins {
id 'com.android.library'
id 'kotlin-android'
id 'maven-publish'
id 'org.jetbrains.dokka'
}

android {
Expand Down Expand Up @@ -33,6 +37,44 @@ task androidSourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
}

tasks.withType(DokkaTask.class) {
dokkaSourceSets {
named("main") {
moduleName.set("extensions-lib")
moduleVersion.set(android.defaultConfig.versionName)
outputDirectory.set(file("build/docs/"))
// Speedup doc generation
// offlineMode.set(true)
includes.from("Module.md")

perPackageOption {
matchingRegex.set("android.content")
suppress.set(true)
}

documentedVisibilities.set([
Visibility.PUBLIC,
Visibility.PROTECTED
])

externalDocumentationLink {
url.set(new URL("https://square.github.io/okhttp/4.x/"))
// https://github.com/square/okhttp/issues/7338
packageListUrl.set(new URL("https://colinwhite.me/okhttp3-package-list"))
}

externalDocumentationLink {
url.set(new URL("https://jsoup.org/apidocs/"))
packageListUrl.set(new URL("https://jsoup.org/apidocs/element-list"))
}

externalDocumentationLink {
url.set(new URL("https://reactivex.io/RxJava/1.x/javadoc/"))
}
}
}
}

project.afterEvaluate {
publishing {
publications {
Expand Down
4 changes: 4 additions & 0 deletions library/src/main/java/eu/kanade/tachiyomi/AppInfo.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package eu.kanade.tachiyomi

/**
* Info about the installed aniyomi app (NOT THE EXTENSION!).
* Can be useful for temporary fixes, preferences, header values, logging, etc.
*/
object AppInfo {
fun getVersionCode(): Int = throw Exception("Stub!")
fun getVersionName(): String = throw Exception("Stub!")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
package eu.kanade.tachiyomi.animesource

/**
* A factory for creating sources at runtime.
* A factory for creating multiple sources at runtime. Use this in case of a source
* that supports multiple languages or mirrors of the same website.
*
* **Note:** Your animesource factory classname must be used in the `extClass` param
* of your `build.gradle` file instead of the true animesource class.
*
* **Example usage:**
* ```kotlin
* class SomeSourceFactory : AnimeSourceFactory {
* override fun createSources() = listOf(
* SomeSource("SomeSource ENG", "en", "https://somesource.en"),
* SomeSource("SomeSource ESP", "es", "https://somesource.es"),
* SomeSource("SomeSource RUS", "ru", "https://somesource.ru"),
* )
* }
*
* class SomeSource(
* override val name: String,
* override val lang: String,
* override val baseUrl: String,
* ) : ParsedAnimeHttpSource() {
* // some code
* }
* ```
*/
interface AnimeSourceFactory {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,64 @@ package eu.kanade.tachiyomi.animesource

import androidx.preference.PreferenceScreen

/**
* A interface to add user preferences to the source.
*
* The usual implementation looks like this:
* ```
* import android.app.Application
* import android.content.SharedPreferences
* import androidx.preference.PreferenceScreen
* import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource
* import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
* import uy.kohesive.injekt.Injekt
* import uy.kohesive.injekt.api.get
* // some other imports...
*
* class SomeSource : ConfigurableAnimeSource, AnimeHttpSource() {
* // some code...
*
* private val preferences: SharedPreferences by lazy {
* Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
* }
*
* override fun setupPreferenceScreen(screen: PreferenceScreen) {
* // some preferences...
* }
* }
* ```
*/
interface ConfigurableAnimeSource {

/**
* Implementations must override this method to add the user preferences.
*
* You can use some stubbed inheritors of [androidx.preference.Preference] here.
*
* **Common usage example:**
* ```
* // ============================== Settings ==============================
* override fun setupPreferenceScreen(screen: PreferenceScreen) {
* val videoQualityPref = ListPreference(screen.context).apply {
* key = PREF_QUALITY_KEY // String, like "pref_quality"
* title = PREF_QUALITY_TITLE // String, like "Preferred quality:"
* entries = PREF_QUALITY_ENTRIES // Array<String>, like arrayOf("240p", "720p"...)
* // Another Array<String>. Can be different from the property above, as long it have the same size
* // and equivalent values per index.
* entryValues = PREF_QUALITY_VALUES
* setDefaultValue(PREF_QUALITY_DEFAULT)
* summary = "%s"
* setOnPreferenceChangeListener { _, newValue ->
* val selected = newValue as String
* val index = findIndexOfValue(selected)
* val entry = entryValues[index] as String
* preferences.edit().putString(key, entry).commit()
* }
* }
* screen.addPreference(videoQualityPref)
* }
* ```
*/
fun setupPreferenceScreen(screen: PreferenceScreen)

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
package eu.kanade.tachiyomi.animesource.model

sealed class AnimeFilter<T>(val name: String, var state: T) {
/**
* A simple header. Useful for separating sections in the list or showing any note or warning to the user.
*/
open class Header(name: String) : AnimeFilter<Any>(name, 0)

/**
* A line separator. Useful for visual distinction between sections.
*/
open class Separator(name: String = "") : AnimeFilter<Any>(name, 0)

/**
* A select control, similar to HTML's `<select>`. Only one item can be selected.
*
* @param name The filter text.
* @param values The options list.
* @param state The index of the selected item.
*/
abstract class Select<V>(name: String, val values: Array<V>, state: Int = 0) : AnimeFilter<Int>(name, state)

/**
* A text control, similar to HTML's `<input type="text">`.
*
* @param name The placeholder text.
* @param state The text written on it.
*/
abstract class Text(name: String, state: String = "") : AnimeFilter<String>(name, state)

/**
* A checkbox control, similar to HTML's `<input type="checkbox">`.
*
* @param name The checkbox text
* @param state A boolean that will be `true` if it's checked.
*/
abstract class CheckBox(name: String, state: Boolean = false) : AnimeFilter<Boolean>(name, state)

/**
* A enhanced checkbox control that supports an excluding state.
* The state can be compared with `STATE_IGNORE`, `STATE_INCLUDE` and `STATE_EXCLUDE` constants of the class.
*/
abstract class TriState(name: String, state: Int = STATE_IGNORE) : AnimeFilter<Int>(name, state) {
fun isIgnored() = state == STATE_IGNORE
fun isIncluded() = state == STATE_INCLUDE
Expand All @@ -17,11 +51,23 @@ sealed class AnimeFilter<T>(val name: String, var state: T) {
const val STATE_EXCLUDE = 2
}
}

/**
* A group of filters.
* Usually used for multiple related [CheckBox]/[TriState] instances, like in a genres filter
*
* @param name The filter group name
* @param state a `List` with all the states.
*/
abstract class Group<V>(name: String, state: List<V>): AnimeFilter<List<V>>(name, state)

/**
* A control for sorting, with support for the ordering.
* The state indicates which item index is selected and if the sorting is ascending.
*/
abstract class Sort(name: String, val values: Array<String>, state: Selection? = null)
: AnimeFilter<Sort.Selection?>(name, state) {
data class Selection(val index: Int, val ascending: Boolean)
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,27 @@ interface SAnime {

var description: String?

/**
* A string containing list of all genres separated with `", "`
*/
var genre: String?

/**
* An "enum" value. Refer to the values in the [SAnime companion object](https://github.com/jmir1/extensions-lib/blob/a2afb04d892e94d21cd4ade7094dca27f4c0c180/library/src/main/java/eu/kanade/tachiyomi/animesource/model/SAnime.kt#L25).
*/
var status: Int

var thumbnail_url: String?

/**
* Useful to exclude animes/movies that will always only have the same episode list
* from the global updates.
*/
var update_strategy: UpdateStrategy

/**
* Tells the app if it should call [fetchAnimeDetails].
*/
var initialized: Boolean

companion object {
Expand All @@ -36,4 +49,4 @@ interface SAnime {
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ package eu.kanade.tachiyomi.animesource.model
import android.net.Uri
import okhttp3.Headers

/**
* A sub/dub track.
*/
data class Track(val url: String, val lang: String)

/**
* The instance that contains the data needed to watch a video.
*/
data class Video(val url: String,
val quality: String,
var videoUrl: String?,
Expand Down
Loading