diff --git a/.gitignore b/.gitignore index de7de41c2..898c9192c 100644 --- a/.gitignore +++ b/.gitignore @@ -287,6 +287,10 @@ jdk_17_maven/em/embedded/rest/familie-ba-sak/target/ /jdk_17_gradle/build/ /jdk_17_gradle/em/embedded/rest/bibliothek/build/ /jdk_17_gradle/em/external/rest/bibliothek/build/ +/jdk_17_gradle/.kotlin/ +/jdk_17_gradle/tmp/ +/jdk_17_gradle/em/embedded/rest/komga/build/ +/jdk_17_gradle/em/external/rest/komga/build/ /jdk_17_maven/cs/grpc/signal-registration/target/ /jdk_17_maven/em/embedded/grpc/signal-registration/target/ /jdk_17_maven/em/external/grpc/signal-registration/target/ diff --git a/README.md b/README.md index 52e1aa233..f14750bbe 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ How to setup authentication information, based on the current content of the ini Auth configuration files can found in the [auth](auth) folder. -### REST: Java/Kotlin (44) +### REST: Java/Kotlin (45) * **AdoptMe** (not-known license), [jdk_21_maven/cs/rest/adoptme](jdk_21_maven/cs/rest/adoptme), from [https://github.com/daanimelian/Programacion3-TPO](https://github.com/daanimelian/Programacion3-TPO) @@ -119,6 +119,8 @@ Auth configuration files can found in the [auth](auth) folder. * **JoinUs** (not-known license), [jdk_21_maven/cs/rest/joinus](jdk_21_maven/cs/rest/joinus), from [https://github.com/KLAJDI16/joinUs](https://github.com/KLAJDI16/joinUs) +* **Komga** (MIT), [jdk_17_gradle/cs/rest/komga](jdk_17_gradle/cs/rest/komga), from [https://github.com/gotson/komga](https://github.com/gotson/komga) + * **Languagetool** (LGPL), [jdk_8_maven/cs/rest/original/languagetool](jdk_8_maven/cs/rest/original/languagetool), from [https://github.com/languagetool-org/languagetool](https://github.com/languagetool-org/languagetool) * **LoveMining** (not-known license), [jdk_21_maven/cs/rest/lovemining](jdk_21_maven/cs/rest/lovemining), from [https://github.com/Andryd22/LoveMining](https://github.com/Andryd22/LoveMining) diff --git a/auth/komga-auth.yaml b/auth/komga-auth.yaml new file mode 100644 index 000000000..12d8f829b --- /dev/null +++ b/auth/komga-auth.yaml @@ -0,0 +1,17 @@ +auth: + - name: wfd_admin1 + fixedHeaders: + - name: Authorization + value: Basic d2ZkX2FkbWluMUB3ZmQuaW52YWxpZDpXZmQtQWRtaW4tUGFzczE= + - name: wfd_admin2 + fixedHeaders: + - name: Authorization + value: Basic d2ZkX2FkbWluMkB3ZmQuaW52YWxpZDpXZmQtQWRtaW4tUGFzczI= + - name: wfd_user1 + fixedHeaders: + - name: Authorization + value: Basic d2ZkX3VzZXIxQHdmZC5pbnZhbGlkOldmZC1Vc2VyLVBhc3Mx + - name: wfd_user2 + fixedHeaders: + - name: Authorization + value: Basic d2ZkX3VzZXIyQHdmZC5pbnZhbGlkOldmZC1Vc2VyLVBhc3My diff --git a/dockerfiles/additional_files/komga/komga-database.sqlite b/dockerfiles/additional_files/komga/komga-database.sqlite new file mode 100644 index 000000000..daff9c85a Binary files /dev/null and b/dockerfiles/additional_files/komga/komga-database.sqlite differ diff --git a/dockerfiles/komga.dockerfile b/dockerfiles/komga.dockerfile new file mode 100644 index 000000000..9698a547a --- /dev/null +++ b/dockerfiles/komga.dockerfile @@ -0,0 +1,18 @@ +FROM amazoncorretto:17-alpine-jdk + +COPY ./dist/komga-sut.jar . +COPY ./dist/jacocoagent.jar . + + + + +COPY ./dockerfiles/additional_files/komga/komga-database.sqlite . + + + + +ENTRYPOINT \ + java \ + -javaagent:jacocoagent.jar=output=tcpserver,address=*,port=6300,append=false,dumponexit=false \ + -jar komga-sut.jar \ + --server.port=8080 --komga.config-dir=/tmp/komga --komga.database.file=/komga-database.sqlite \ No newline at end of file diff --git a/dockerfiles/komga.yaml b/dockerfiles/komga.yaml new file mode 100644 index 000000000..48daabc09 --- /dev/null +++ b/dockerfiles/komga.yaml @@ -0,0 +1,30 @@ +services: + mitmproxy: + image: mitmproxy/mitmproxy:10.2.4 + user: "0:0" + environment: + MITM_LOG_DIR: /custom-logs + MITM_LOG_FILE: ${MITM_LOG_FILE:-minlog.csv} + command: > + mitmdump + --mode reverse:http://sut-komga:8080 + --listen-host 0.0.0.0 + --listen-port 8080 + --set keep_host_header=true + -s /addons/minlog.py + volumes: + - ${HOST_LOG_DIR:-./mitm-logs}:/custom-logs + - ./addons:/addons:ro + ports: + - "${HOST_PORT:-8080}:8080" + depends_on: + - sut-komga + sut-komga: + image: webfuzzing/wfd-komga:FINAL +# build: +# dockerfile: ./dockerfiles/komga.dockerfile +# context: .. + environment: + AUTH_PORT: ${AUTH_PORT:-8081} + ports: + - "${JACOCO_PORT:-6300}:6300" \ No newline at end of file diff --git a/experiments/bb-exp.py b/experiments/bb-exp.py index 00f2f5eba..da8fb838f 100644 --- a/experiments/bb-exp.py +++ b/experiments/bb-exp.py @@ -94,6 +94,7 @@ def __init__(self, name, auth, sleep, schemaformat, classfiles): Sut("gestaohospital",False,SLEEP,JSON,["jdk_8_maven/cs/rest-gui/gestaohospital/target/classes"]), Sut("http-patch-spring",False,SLEEP,JSON,["jdk_11_maven/cs/rest/http-patch-spring/target/classes"]), Sut("joinus",True,SLEEP,JSON,["jdk_21_maven/cs/rest/joinus/target/classes"]), + Sut("komga",True,SLEEP,JSON,["jdk_17_gradle/cs/rest/komga/komga/build/classes"]), Sut("languagetool",False,SLEEP,JSON,["jdk_8_maven/cs/rest/original/languagetool/languagetool-core/target/classes", "jdk_8_maven/cs/rest/original/languagetool/languagetool-gui-commons/target/classes", "jdk_8_maven/cs/rest/original/languagetool/languagetool-language-modules/all/target/classes", diff --git a/experiments/wb-exp.py b/experiments/wb-exp.py index 0ca5475ba..e09f19858 100644 --- a/experiments/wb-exp.py +++ b/experiments/wb-exp.py @@ -198,6 +198,7 @@ def __init__(self, name, platform): Sut("http-patch-spring", JDK_11), Sut("jasper", JDK_25), Sut("joinus", JDK_21), + Sut("komga", JDK_17), Sut("languagetool", JDK_8), Sut("lovemining", JDK_21), Sut("market", JDK_11), diff --git a/jacoco.dockerfile b/jacoco.dockerfile index ff880c7ac..b818f8fcb 100644 --- a/jacoco.dockerfile +++ b/jacoco.dockerfile @@ -30,6 +30,7 @@ COPY jdk_8_maven/cs/rest-gui/genome-nexus/web/target/classes ${CLASS_FILES}/jdk COPY jdk_8_maven/cs/rest-gui/gestaohospital/target/classes ${CLASS_FILES}/jdk_8_maven/cs/rest-gui/gestaohospital/target/classes COPY jdk_11_maven/cs/rest/http-patch-spring/target/classes ${CLASS_FILES}/jdk_11_maven/cs/rest/http-patch-spring/target/classes COPY jdk_21_maven/cs/rest/joinus/target/classes ${CLASS_FILES}/jdk_21_maven/cs/rest/joinus/target/classes +COPY jdk_17_gradle/cs/rest/komga/komga/build/classes ${CLASS_FILES}/jdk_17_gradle/cs/rest/komga/komga/build/classes COPY jdk_8_maven/cs/rest/original/languagetool/languagetool-core/target/classes ${CLASS_FILES}/jdk_8_maven/cs/rest/original/languagetool/languagetool-core/target/classes COPY jdk_8_maven/cs/rest/original/languagetool/languagetool-gui-commons/target/classes ${CLASS_FILES}/jdk_8_maven/cs/rest/original/languagetool/languagetool-gui-commons/target/classes COPY jdk_8_maven/cs/rest/original/languagetool/languagetool-language-modules/all/target/classes ${CLASS_FILES}/jdk_8_maven/cs/rest/original/languagetool/languagetool-language-modules/all/target/classes diff --git a/jdk_17_gradle/cs/rest/komga/komga/build.gradle.kts b/jdk_17_gradle/cs/rest/komga/komga/build.gradle.kts index 5a0fae29c..36390a08a 100644 --- a/jdk_17_gradle/cs/rest/komga/komga/build.gradle.kts +++ b/jdk_17_gradle/cs/rest/komga/komga/build.gradle.kts @@ -5,12 +5,18 @@ import org.jetbrains.kotlin.util.prefixIfNot import org.springframework.boot.gradle.plugin.SpringBootPlugin plugins { - kotlin("jvm") - kotlin("plugin.spring") - kotlin("kapt") + // MODIFIED: versions come from komga's own root build, which WFD does not use + run { + val kotlinVersion = "2.4.10" + kotlin("jvm") version kotlinVersion + kotlin("plugin.spring") version kotlinVersion + kotlin("kapt") version kotlinVersion + } id("org.springframework.boot") version libs.versions.springboot.get() alias(libs.plugins.gradleGitProperties) - id("nu.studer.jooq") version "10.2.1" + // MODIFIED: 10.2.1 needs Gradle >= 8.6 and a JDK 21 Gradle JVM, this level is 8.5 / JDK 17. + // jOOQ codegen stays 3.19.35, only the "this-escape" SuppressWarnings hint differs + id("nu.studer.jooq") version "9.0" id("org.flywaydb.flyway") version "13.1.0" id("com.github.johnrengelman.processes") version "0.5.0" id("org.springdoc.openapi-gradle-plugin") version "1.9.0" @@ -18,6 +24,19 @@ plugins { jacoco } +// MODIFIED: set by komga's own root build, which WFD does not use +group = "org.gotson" +version = "1.26.3" + +repositories { + mavenCentral() +} + +// MODIFIED: the WFD Docker build mounts only this level, so there is no .git to read +gitProperties { + failOnNoGitDirectory = false +} + val benchmarkSourceSet = sourceSets.create("benchmark") { java { @@ -181,6 +200,12 @@ tasks { enabled = true } + // MODIFIED: WFD expects a single self-contained jar named komga-sut.jar + bootJar { + archiveVersion.set("") + archiveClassifier.set("sut") + } + register("webuiCopyDist") { description = "Copies the WebUI build into resources/public" group = "web" @@ -251,7 +276,8 @@ springBoot { excludes = setOf("time") properties { // but rerun if the gradle.properties file changed - inputs.file("$rootDir/gradle.properties") + // MODIFIED: rootDir is the WFD level here, komga's own root is one folder up + inputs.file("$projectDir/../gradle.properties") } } } @@ -376,12 +402,13 @@ tasks.whenTaskAdded { } } -tasks.runKtlintFormatOverMainSourceSet { - dependsOn("generateTasksJooq") -} -tasks.runKtlintCheckOverMainSourceSet { - dependsOn("generateTasksJooq") -} +// MODIFIED: ktlint is applied by komga's own root build, which WFD does not use +// tasks.runKtlintFormatOverMainSourceSet { +// dependsOn("generateTasksJooq") +// } +// tasks.runKtlintCheckOverMainSourceSet { +// dependsOn("generateTasksJooq") +// } tasks.compileKotlin { dependsOn("generateTasksJooq") } @@ -399,11 +426,12 @@ tasks.jacocoTestReport { dependsOn(tasks.test) } -configure { - filter { - exclude("**/db/migration/**") - } -} +// MODIFIED: ktlint is applied by komga's own root build, which WFD does not use +// configure { +// filter { +// exclude("**/db/migration/**") +// } +// } project.afterEvaluate { tasks.named("forkedSpringBootRun") { diff --git a/jdk_17_gradle/em/embedded/rest/komga/build.gradle.kts b/jdk_17_gradle/em/embedded/rest/komga/build.gradle.kts new file mode 100644 index 000000000..efdd28cd2 --- /dev/null +++ b/jdk_17_gradle/em/embedded/rest/komga/build.gradle.kts @@ -0,0 +1,26 @@ + +repositories { + mavenLocal() + mavenCentral() +} + + +plugins { + `java-library` +} + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +val EVOMASTER_VERSION = project.ext.get("EVOMASTER_VERSION") + +dependencies{ + implementation("org.evomaster:evomaster-client-java-controller:$EVOMASTER_VERSION") + implementation("org.evomaster:evomaster-client-java-dependencies:$EVOMASTER_VERSION"){ + exclude("com.github.tomakehurst") + } + + api(project(":cs:rest:komga")) +} diff --git a/jdk_17_gradle/em/embedded/rest/komga/src/main/java/em/embedded/komga/EmbeddedEvoMasterController.java b/jdk_17_gradle/em/embedded/rest/komga/src/main/java/em/embedded/komga/EmbeddedEvoMasterController.java new file mode 100644 index 000000000..59bd87384 --- /dev/null +++ b/jdk_17_gradle/em/embedded/rest/komga/src/main/java/em/embedded/komga/EmbeddedEvoMasterController.java @@ -0,0 +1,221 @@ +package em.embedded.komga; + +import org.evomaster.client.java.controller.AuthUtils; +import org.evomaster.client.java.controller.EmbeddedSutController; +import org.evomaster.client.java.controller.InstrumentedSutStarter; +import org.evomaster.client.java.controller.api.dto.SutInfoDto; +import org.evomaster.client.java.controller.api.dto.auth.AuthenticationDto; +import org.evomaster.client.java.controller.problem.ProblemInfo; +import org.evomaster.client.java.controller.problem.RestProblem; +import org.evomaster.client.java.sql.DbSpecification; +import org.gotson.komga.Application; +import org.springframework.boot.SpringApplication; +import org.springframework.context.ConfigurableApplicationContext; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.time.Duration; +import java.util.Base64; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + +/** + * Class used to start/stop the SUT. + */ +public class EmbeddedEvoMasterController extends EmbeddedSutController { + + public static void main(String[] args) { + + int port = 40100; + if (args.length > 0) { + port = Integer.parseInt(args[0]); + } + + EmbeddedEvoMasterController controller = new EmbeddedEvoMasterController(port); + InstrumentedSutStarter starter = new InstrumentedSutStarter(controller); + + starter.start(); + } + + private static final String[][] SEEDED_USERS = { + {"wfd_admin1@wfd.invalid", "Wfd-Admin-Pass1", "[\"ADMIN\",\"FILE_DOWNLOAD\",\"PAGE_STREAMING\",\"KOBO_SYNC\",\"KOREADER_SYNC\"]"}, + {"wfd_admin2@wfd.invalid", "Wfd-Admin-Pass2", "[\"ADMIN\",\"FILE_DOWNLOAD\",\"PAGE_STREAMING\",\"KOBO_SYNC\",\"KOREADER_SYNC\"]"}, + {"wfd_user1@wfd.invalid", "Wfd-User-Pass1", "[\"FILE_DOWNLOAD\",\"PAGE_STREAMING\",\"KOBO_SYNC\",\"KOREADER_SYNC\"]"}, + {"wfd_user2@wfd.invalid", "Wfd-User-Pass2", "[\"FILE_DOWNLOAD\",\"PAGE_STREAMING\",\"KOBO_SYNC\",\"KOREADER_SYNC\"]"} + }; + + private static final Path CONFIG_DIR = Paths.get("tmp", "komga", "embedded").toAbsolutePath(); + + /** live database file -> snapshot taken right after seeding */ + private static final List DATABASES = List.of("database.sqlite", "tasks.sqlite"); + + private ConfigurableApplicationContext ctx; + + private final HttpClient http = HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(10)) + .build(); + + public EmbeddedEvoMasterController() { + this(0); + } + + public EmbeddedEvoMasterController(int port) { + setControllerPort(port); + } + + + @Override + public String startSut() { + + // a fresh config dir means a fresh SQLite database, with no user in it + deleteRecursively(CONFIG_DIR); + + // same as what Komga's own main() does before starting Spring + System.setProperty("org.jooq.no-logo", "true"); + System.setProperty("org.jooq.no-tips", "true"); + + ctx = SpringApplication.run(Application.class, + new String[]{"--server.port=0", + "--komga.config-dir=" + CONFIG_DIR, + // Logback holds this file open, it must sit outside the wiped config dir + "--logging.file.name=" + CONFIG_DIR.getParent().resolve("embedded.log") + }); + + seedUsers(); + eachDatabase("backup to"); + + return "http://localhost:" + getSutPort(); + } + + protected int getSutPort() { + return (Integer) ((Map) ctx.getEnvironment() + .getPropertySources().get("server.ports").getSource()) + .get("local.server.port"); + } + + + @Override + public boolean isSutRunning() { + return ctx != null && ctx.isRunning(); + } + + @Override + public void stopSut() { + ctx.stop(); + ctx.close(); + } + + @Override + public String getPackagePrefixesToCover() { + return "org.gotson.komga."; + } + + @Override + public void resetStateOfSUT() { + eachDatabase("restore from"); + } + + @Override + public List getDbSpecifications() { + return null; + } + + @Override + public List getInfoForAuthentication() { + return Stream.of(SEEDED_USERS) + .map(u -> AuthUtils.getForBasic(u[0], u[0], u[1])) + .collect(Collectors.toList()); + } + + @Override + public ProblemInfo getProblemInfo() { + return new RestProblem( + "http://localhost:" + getSutPort() + "/v3/api-docs", + null + ); + } + + @Override + public SutInfoDto.OutputFormat getPreferredOutputFormat() { + return SutInfoDto.OutputFormat.JAVA_JUNIT_5; + } + + + private void seedUsers() { + String baseUrl = "http://localhost:" + getSutPort(); + + send(HttpRequest.newBuilder(URI.create(baseUrl + "/api/v1/claim")) + .header("X-Komga-Email", SEEDED_USERS[0][0]) + .header("X-Komga-Password", SEEDED_USERS[0][1]) + .POST(HttpRequest.BodyPublishers.noBody())); + + String admin = "Basic " + Base64.getEncoder().encodeToString( + (SEEDED_USERS[0][0] + ":" + SEEDED_USERS[0][1]).getBytes()); + + for (int i = 1; i < SEEDED_USERS.length; i++) { + String body = "{\"email\":\"" + SEEDED_USERS[i][0] + "\",\"password\":\"" + SEEDED_USERS[i][1] + + "\",\"roles\":" + SEEDED_USERS[i][2] + "}"; + send(HttpRequest.newBuilder(URI.create(baseUrl + "/api/v2/users")) + .header("Authorization", admin) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(body))); + } + } + + private void send(HttpRequest.Builder builder) { + try { + HttpResponse response = http.send(builder.timeout(Duration.ofSeconds(30)).build(), + HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() >= 300) { + throw new IllegalStateException("Failed to seed users: " + response.statusCode() + " " + response.body()); + } + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); + } + } + + /** sqlite-jdbc extension over SQLite's Online Backup API: safe while the SUT is connected */ + private void eachDatabase(String command) { + for (String db : DATABASES) { + Path live = CONFIG_DIR.resolve(db); + try (Connection connection = DriverManager.getConnection( + "jdbc:sqlite:" + live + "?busy_timeout=30000"); + Statement statement = connection.createStatement()) { + statement.executeUpdate(command + " '" + live + ".seed'"); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + } + + private void deleteRecursively(Path root) { + if (!Files.exists(root)) { + return; + } + try (Stream paths = Files.walk(root)) { + paths.sorted(Comparator.reverseOrder()).forEach(p -> { + try { + Files.delete(p); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/jdk_17_gradle/em/external/rest/komga/build.gradle.kts b/jdk_17_gradle/em/external/rest/komga/build.gradle.kts new file mode 100644 index 000000000..e2aa80645 --- /dev/null +++ b/jdk_17_gradle/em/external/rest/komga/build.gradle.kts @@ -0,0 +1,51 @@ + +repositories { + mavenLocal() + mavenCentral() +} + + +plugins { + `java-library` + id("com.gradleup.shadow") version "8.3.8" +} + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + + +val EVOMASTER_VERSION = project.ext.get("EVOMASTER_VERSION") + +dependencies{ + implementation("org.evomaster:evomaster-client-java-controller:$EVOMASTER_VERSION") + implementation("org.evomaster:evomaster-client-java-instrumentation:$EVOMASTER_VERSION") + runtimeOnly("org.xerial:sqlite-jdbc:${libs.versions.sqliteJdbc.get()}") +} + + +tasks.shadowJar { + archiveBaseName.set("${project.name}-evomaster-runner") + archiveClassifier.set("") + archiveVersion.set("") + isZip64 = true + manifest { + attributes["Implementation-Title"] = "EM" + attributes["Implementation-Version"] = "1.0" + attributes["Main-Class"] = "em.external.komga.ExternalEvoMasterController" + attributes["Premain-Class"] = "org.evomaster.client.java.instrumentation.InstrumentingAgent" + attributes["Agent-Class"] = "org.evomaster.client.java.instrumentation.InstrumentingAgent" + attributes["Can-Redefine-Classes"] = "true" + attributes["Can-Retransform-Classes"] = "true" + } + relocate("org.slf4j", "shaded.emb.org.slf4j") + relocate("com.fasterxml.jackson", "shaded.emb.com.fasterxml.jackson") + mergeServiceFiles() +} + +tasks { + "build" { + dependsOn(shadowJar) + } +} diff --git a/jdk_17_gradle/em/external/rest/komga/src/main/java/em/external/komga/ExternalEvoMasterController.java b/jdk_17_gradle/em/external/rest/komga/src/main/java/em/external/komga/ExternalEvoMasterController.java new file mode 100644 index 000000000..1dc9a0aa3 --- /dev/null +++ b/jdk_17_gradle/em/external/rest/komga/src/main/java/em/external/komga/ExternalEvoMasterController.java @@ -0,0 +1,268 @@ +package em.external.komga; + +import org.evomaster.client.java.controller.AuthUtils; +import org.evomaster.client.java.controller.ExternalSutController; +import org.evomaster.client.java.controller.InstrumentedSutStarter; +import org.evomaster.client.java.controller.api.dto.SutInfoDto; +import org.evomaster.client.java.controller.api.dto.auth.AuthenticationDto; +import org.evomaster.client.java.controller.problem.ProblemInfo; +import org.evomaster.client.java.controller.problem.RestProblem; +import org.evomaster.client.java.sql.DbSpecification; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.time.Duration; +import java.util.Base64; +import java.util.Comparator; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class ExternalEvoMasterController extends ExternalSutController { + + + public static void main(String[] args) { + + int controllerPort = 40100; + if (args.length > 0) { + controllerPort = Integer.parseInt(args[0]); + } + int sutPort = 12345; + if (args.length > 1) { + sutPort = Integer.parseInt(args[1]); + } + String jarLocation = "cs/rest/komga/komga/build/libs"; + if (args.length > 2) { + jarLocation = args[2]; + } + if(! jarLocation.endsWith(".jar")) { + jarLocation += "/komga-sut.jar"; + } + + int timeoutSeconds = 120; + if(args.length > 3){ + timeoutSeconds = Integer.parseInt(args[3]); + } + String command = "java"; + if(args.length > 4){ + command = args[4]; + } + + + ExternalEvoMasterController controller = + new ExternalEvoMasterController(controllerPort, jarLocation, + sutPort, timeoutSeconds, command); + controller.setNeedsJdk17Options(true); + InstrumentedSutStarter starter = new InstrumentedSutStarter(controller); + + starter.start(); + } + + private static final String[][] SEEDED_USERS = { + {"wfd_admin1@wfd.invalid", "Wfd-Admin-Pass1", "[\"ADMIN\",\"FILE_DOWNLOAD\",\"PAGE_STREAMING\",\"KOBO_SYNC\",\"KOREADER_SYNC\"]"}, + {"wfd_admin2@wfd.invalid", "Wfd-Admin-Pass2", "[\"ADMIN\",\"FILE_DOWNLOAD\",\"PAGE_STREAMING\",\"KOBO_SYNC\",\"KOREADER_SYNC\"]"}, + {"wfd_user1@wfd.invalid", "Wfd-User-Pass1", "[\"FILE_DOWNLOAD\",\"PAGE_STREAMING\",\"KOBO_SYNC\",\"KOREADER_SYNC\"]"}, + {"wfd_user2@wfd.invalid", "Wfd-User-Pass2", "[\"FILE_DOWNLOAD\",\"PAGE_STREAMING\",\"KOBO_SYNC\",\"KOREADER_SYNC\"]"} + }; + + private final int timeoutSeconds; + private final int sutPort; + private String jarLocation; + + private final Path configDir; + + /** live database file -> snapshot taken right after seeding */ + private static final List DATABASES = List.of("database.sqlite", "tasks.sqlite"); + + private final HttpClient http = HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(10)) + .build(); + + + public ExternalEvoMasterController(){ + this(40100, "../core/target", 12345, 120, "java"); + } + + public ExternalEvoMasterController(String jarLocation) { + this(); + this.jarLocation = jarLocation; + } + + public ExternalEvoMasterController( + int controllerPort, String jarLocation, int sutPort, int timeoutSeconds, String command + ) { + + if(jarLocation==null || jarLocation.isEmpty()){ + throw new IllegalArgumentException("Missing jar location"); + } + + this.sutPort = sutPort; + this.jarLocation = jarLocation; + this.timeoutSeconds = timeoutSeconds; + this.configDir = Paths.get("tmp", "komga", "p" + sutPort).toAbsolutePath(); + setControllerPort(controllerPort); + setJavaCommand(command); + } + + + @Override + public String[] getInputParameters() { + return new String[]{ + "--server.port=" + sutPort, + "--komga.config-dir=" + configDir + }; + } + + public String[] getJVMParameters() { + return new String[]{}; + } + + @Override + public String getBaseURL() { + return "http://localhost:" + sutPort; + } + + @Override + public String getPathToExecutableJar() { + return jarLocation; + } + + @Override + public String getLogMessageOfInitializedServer() { + return "Started ApplicationKt in"; + } + + @Override + public long getMaxAwaitForInitializationInSeconds() { + return timeoutSeconds; + } + + @Override + public void preStart() { + // a fresh config dir means a fresh SQLite database, with no user in it + deleteRecursively(configDir); + } + + @Override + public void postStart() { + seedUsers(); + eachDatabase("backup to"); + } + + @Override + public void resetStateOfSUT() { + eachDatabase("restore from"); + } + + @Override + public void preStop() { + } + + @Override + public void postStop() { + } + + + @Override + public String getPackagePrefixesToCover() { + return "org.gotson.komga."; + } + + @Override + public ProblemInfo getProblemInfo() { + return new RestProblem( + getBaseURL() + "/v3/api-docs", + null + ); + } + + @Override + public SutInfoDto.OutputFormat getPreferredOutputFormat() { + return SutInfoDto.OutputFormat.JAVA_JUNIT_5; + } + + @Override + public List getInfoForAuthentication() { + return Stream.of(SEEDED_USERS) + .map(u -> AuthUtils.getForBasic(u[0], u[0], u[1])) + .collect(Collectors.toList()); + } + + @Override + public List getDbSpecifications() { + return null; + } + + + private void seedUsers() { + send(HttpRequest.newBuilder(URI.create(getBaseURL() + "/api/v1/claim")) + .header("X-Komga-Email", SEEDED_USERS[0][0]) + .header("X-Komga-Password", SEEDED_USERS[0][1]) + .POST(HttpRequest.BodyPublishers.noBody())); + + String admin = "Basic " + Base64.getEncoder().encodeToString( + (SEEDED_USERS[0][0] + ":" + SEEDED_USERS[0][1]).getBytes()); + + for (int i = 1; i < SEEDED_USERS.length; i++) { + String body = "{\"email\":\"" + SEEDED_USERS[i][0] + "\",\"password\":\"" + SEEDED_USERS[i][1] + + "\",\"roles\":" + SEEDED_USERS[i][2] + "}"; + send(HttpRequest.newBuilder(URI.create(getBaseURL() + "/api/v2/users")) + .header("Authorization", admin) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(body))); + } + } + + private void send(HttpRequest.Builder builder) { + try { + HttpResponse response = http.send(builder.timeout(Duration.ofSeconds(30)).build(), + HttpResponse.BodyHandlers.ofString()); + if (response.statusCode() >= 300) { + throw new IllegalStateException("Failed to seed users: " + response.statusCode() + " " + response.body()); + } + } catch (IOException | InterruptedException e) { + throw new RuntimeException(e); + } + } + + /** sqlite-jdbc extension over SQLite's Online Backup API: safe while the SUT is connected */ + private void eachDatabase(String command) { + for (String db : DATABASES) { + Path live = configDir.resolve(db); + try (Connection connection = DriverManager.getConnection( + "jdbc:sqlite:" + live + "?busy_timeout=30000"); + Statement statement = connection.createStatement()) { + statement.executeUpdate(command + " '" + live + ".seed'"); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + } + + private void deleteRecursively(Path root) { + if (!Files.exists(root)) { + return; + } + try (Stream paths = Files.walk(root)) { + paths.sorted(Comparator.reverseOrder()).forEach(p -> { + try { + Files.delete(p); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/jdk_17_gradle/gradle.properties b/jdk_17_gradle/gradle.properties new file mode 100644 index 000000000..eb1569156 --- /dev/null +++ b/jdk_17_gradle/gradle.properties @@ -0,0 +1,2 @@ +# komga is a large Kotlin codebase, the default heap is not enough to compile it +kotlin.daemon.jvmargs=-Xmx2G diff --git a/jdk_17_gradle/gradle/libs.versions.toml b/jdk_17_gradle/gradle/libs.versions.toml index b0ae4f337..dd289f636 100644 --- a/jdk_17_gradle/gradle/libs.versions.toml +++ b/jdk_17_gradle/gradle/libs.versions.toml @@ -1,5 +1,12 @@ [versions] indra = "3.1.1" +# komga +sqliteJdbc = "3.53.2.1" +nightmonkeys = "1.1.0" +twelvemonkeys = "3.14.0" +springboot = "3.5.16" +lucene = "9.9.1" # v10 requires JDK 21 +jooq = "3.19.35" # should be aligned with the version provided by Spring Boot [plugins] indra = { id = "net.kyori.indra", version.ref = "indra" } @@ -7,6 +14,8 @@ indra-checkstyle = { id = "net.kyori.indra.checkstyle", version.ref = "indra" } spotless = { id = "com.diffplug.spotless", version = "6.19.0" } spring-boot = { id = "org.springframework.boot", version = "3.1.1" } spring-dependency-management = { id = "io.spring.dependency-management", version = "1.1.1" } +# komga +gradleGitProperties = { id = "com.gorylenko.gradle-git-properties", version = "4.0.1" } [libraries] jetbrains-annotations = { group = "org.jetbrains", name = "annotations", version = "24.0.1" } diff --git a/jdk_17_gradle/gradle/wrapper/gradle-wrapper.properties b/jdk_17_gradle/gradle/wrapper/gradle-wrapper.properties index fae08049a..a59520664 100644 --- a/jdk_17_gradle/gradle/wrapper/gradle-wrapper.properties +++ b/jdk_17_gradle/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/jdk_17_gradle/settings.gradle.kts b/jdk_17_gradle/settings.gradle.kts index 2aa31f55c..82239f59b 100644 --- a/jdk_17_gradle/settings.gradle.kts +++ b/jdk_17_gradle/settings.gradle.kts @@ -2,7 +2,13 @@ rootProject.name = "emb_jdk_17_gradle" include("cs:rest:bibliothek") +// the komga SUT is a multi-module build; only its server module is needed here +include("cs:rest:komga") +project(":cs:rest:komga").projectDir = file("cs/rest/komga/komga") + if (System.getenv("BUILD_EVOMASTER") != "false") { include("em:embedded:rest:bibliothek") include("em:external:rest:bibliothek") + include("em:embedded:rest:komga") + include("em:external:rest:komga") } diff --git a/openapi/komga.json b/openapi/komga.json new file mode 100644 index 000000000..562ddb59b --- /dev/null +++ b/openapi/komga.json @@ -0,0 +1,14681 @@ +{ + "openapi": "3.1.0", + "info": { + "description": "Komga REST API.\n\n## Reference\n\nCheck the API reference:\n- on the [Komga website](https://komga.org/docs/openapi/komga-api)\n- on any running Komga instance at `/swagger-ui.html`\n- on [GitHub](https://raw.githubusercontent.com/gotson/komga/refs/heads/master/komga/docs/openapi.json)\n\n## Authentication\n\nMost endpoints require authentication. Authentication is done using either:\n- Basic Authentication\n- Passing an API Key in the `X-API-Key` header\n\n## Sessions\n\nUpon successful authentication, a session is created, and can be reused.\n\n- By default, a `KOMGA-SESSION` cookie is set via `Set-Cookie` response header. This works well for browsers and clients that can handle cookies.\n- If you specify a header `X-Auth-Token` during authentication, the session ID will be returned via this same header. You can then pass that header again for subsequent requests to reuse the session.\n\nIf you need to set the session cookie later on, you can call `/api/v1/login/set-cookie` with `X-Auth-Token`. The response will contain the `Set-Cookie` header.\n\n## Remember Me\n\nDuring authentication, if a request parameter `remember-me` is passed and set to `true`, the server will also return a `komga-remember-me` cookie. This cookie will be used to login automatically even if the session has expired.\n\n## Logout\n\nYou can explicitly logout an existing session by calling `/api/logout`. This would return a `204`.\n\n## Deprecation\n\nAPI endpoints marked as deprecated will be removed in the next major version.", + "license": { + "name": "MIT", + "url": "https://github.com/gotson/komga/blob/master/LICENSE" + }, + "title": "Komga API", + "version": "1.26.3" + }, + "externalDocs": { + "description": "Komga documentation", + "url": "https://komga.org" + }, + "servers": [ + { + "url": "http://localhost:12345", + "description": "Generated server url" + } + ], + "security": [ + { + "basicAuth": [] + }, + { + "apiKey": [] + } + ], + "tags": [ + { + "name": "Deprecated" + }, + { + "description": "Manage libraries.", + "name": "Libraries" + }, + { + "description": "Manage series.", + "name": "Series" + }, + { + "description": "Manage posters for series.", + "name": "Series Poster" + }, + { + "description": "Manage books.", + "name": "Books" + }, + { + "description": "Manage posters for books.", + "name": "Book Poster" + }, + { + "name": "Book Pages" + }, + { + "name": "WebPub Manifest" + }, + { + "name": "Import" + }, + { + "description": "Provide font files and CSS for the Epub Reader.", + "name": "Fonts" + }, + { + "description": "Manage duplicate pages. Duplicate pages are identified by a page hash.", + "name": "Duplicate Pages" + }, + { + "description": "Manage collections.", + "name": "Collections" + }, + { + "description": "Manage posters for collections.", + "name": "Collection Poster" + }, + { + "name": "Collection Series" + }, + { + "description": "Manage readlists.", + "name": "Readlists" + }, + { + "description": "Manage posters for readlists.", + "name": "Readlist Poster" + }, + { + "name": "Readlist Books" + }, + { + "description": "Retrieve referential metadata from all items in the Komga server.", + "name": "Referential metadata" + }, + { + "description": "Manage current user.", + "name": "Current user" + }, + { + "description": "Manage users.", + "name": "Users" + }, + { + "description": "Manage API Keys", + "name": "API Keys" + }, + { + "name": "User session" + }, + { + "description": "List registered OAuth2 providers", + "name": "OAuth2" + }, + { + "description": "Sync points are automatically created during a Kobo sync.", + "name": "Sync points" + }, + { + "description": "Claim a freshly installed Komga server.", + "name": "Claim" + }, + { + "description": "Manage server tasks", + "name": "Tasks" + }, + { + "description": "Server events history", + "name": "History" + }, + { + "description": "List files from the host server's file system", + "name": "File system" + }, + { + "description": "Store and retrieve server settings", + "name": "Server settings" + }, + { + "description": "Retrieve releases information", + "name": "Releases" + }, + { + "description": "Retrieve announcements from the Komga website", + "name": "Announcements" + }, + { + "description": "Manage server", + "name": "Management" + }, + { + "name": "Mihon" + }, + { + "name": "ComicRack" + }, + { + "description": "Store and retrieve global and per-user settings. Those settings are not used by Komga itself, but can be stored for convenience by client applications.", + "name": "Client settings" + } + ], + "paths": { + "/actuator/info": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getActuatorInfo", + "responses": { + "200": { + "content": { + "application/json": { + "examples": { + "Example": { + "value": "{\n \"git\": {\n \"branch\": \"master\",\n \"commit\": {\n \"id\": \"9be980d\",\n \"time\": \"2025-03-12T03:40:38Z\"\n }\n },\n \"build\": {\n \"artifact\": \"komga\",\n \"name\": \"komga\",\n \"version\": \"1.21.2\",\n \"group\": \"komga\"\n },\n \"java\": {\n \"version\": \"23.0.2\",\n \"vendor\": {\n \"name\": \"Eclipse Adoptium\",\n \"version\": \"Temurin-23.0.2+7\"\n },\n \"runtime\": {\n \"name\": \"OpenJDK Runtime Environment\",\n \"version\": \"23.0.2+7\"\n },\n \"jvm\": {\n \"name\": \"OpenJDK 64-Bit Server VM\",\n \"vendor\": \"Eclipse Adoptium\",\n \"version\": \"23.0.2+7\"\n }\n },\n \"os\": {\n \"name\": \"Linux\",\n \"version\": \"6.8.0-57-generic\",\n \"arch\": \"amd64\"\n }\n}" + } + }, + "schema": { + "additionalProperties": true + } + } + }, + "description": "OK" + } + }, + "summary": "Get server information", + "tags": [ + "Management" + ] + }, + "summary": "Get general information about the server" + }, + "/api/logout": { + "get": { + "description": "Invalidates the current session and clean up any remember-me authentication.", + "operationId": "postLogout", + "responses": { + "204": { + "description": "No Content" + } + }, + "summary": "Logout", + "tags": [ + "User session" + ] + }, + "post": { + "description": "Invalidates the current session and clean up any remember-me authentication.", + "operationId": "postLogout_1", + "responses": { + "204": { + "description": "No Content" + } + }, + "summary": "Logout", + "tags": [ + "User session" + ] + }, + "summary": "Logout current session" + }, + "/api/v1/age-ratings": { + "get": { + "deprecated": true, + "description": "Use GET /v2/age-ratings instead. Deprecated since 1.26.0", + "operationId": "getAgeRatings_1", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List age ratings", + "tags": [ + "Deprecated", + "Referential metadata" + ] + } + }, + "/api/v1/announcements": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getAnnouncements", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/JsonFeedDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Retrieve announcements", + "tags": [ + "Announcements" + ] + }, + "put": { + "description": "Required role: **ADMIN**", + "operationId": "markAnnouncementsRead", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Mark announcements as read", + "tags": [ + "Announcements" + ] + } + }, + "/api/v1/authors": { + "get": { + "deprecated": true, + "description": "Use GET /api/v2/authors instead. Deprecated since 1.20.0.", + "operationId": "getAuthorsDeprecated", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string", + "default": "" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "series_id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AuthorDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List authors", + "tags": [ + "Deprecated", + "Referential metadata" + ] + } + }, + "/api/v1/authors/names": { + "get": { + "deprecated": true, + "description": "Use GET /v2/authors/names instead. Deprecated since 1.26.0", + "operationId": "getAuthorsNames_1", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string", + "default": "" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List authors' names", + "tags": [ + "Deprecated", + "Referential metadata" + ] + } + }, + "/api/v1/authors/roles": { + "get": { + "deprecated": true, + "description": "Use GET /v2/authors/roles instead. Deprecated since 1.26.0", + "operationId": "getAuthorsRoles_1", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List authors' roles", + "tags": [ + "Deprecated", + "Referential metadata" + ] + } + }, + "/api/v1/books": { + "get": { + "deprecated": true, + "description": "Use POST /api/v1/books/list instead. Deprecated since 1.19.0.", + "operationId": "getAllBooksDeprecated", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "media_status", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "UNKNOWN", + "ERROR", + "READY", + "UNSUPPORTED", + "OUTDATED" + ] + } + } + }, + { + "in": "query", + "name": "read_status", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "UNREAD", + "READ", + "IN_PROGRESS" + ] + } + } + }, + { + "in": "query", + "name": "released_after", + "required": false, + "schema": { + "type": "string", + "format": "date" + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + }, + { + "description": "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "in": "query", + "name": "sort", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageBookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List books", + "tags": [ + "Books", + "Deprecated" + ] + } + }, + "/api/v1/books/duplicates": { + "get": { + "description": "Return books that have the same file hash.\n\nRequired role: **ADMIN**", + "operationId": "getBooksDuplicates", + "parameters": [ + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + }, + { + "description": "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "in": "query", + "name": "sort", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageBookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List duplicate books", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/import": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "importBooks", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BookImportBatchDto" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Import books", + "tags": [ + "Import" + ] + } + }, + "/api/v1/books/latest": { + "get": { + "description": "Return newly added or updated books.", + "operationId": "getBooksLatest", + "parameters": [ + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageBookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List latest books", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/list": { + "post": { + "operationId": "getBooks", + "parameters": [ + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + }, + { + "description": "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "in": "query", + "name": "sort", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BookSearch" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageBookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List books", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/metadata": { + "patch": { + "description": "Set a field to null to unset the metadata. You can omit fields you don't want to update.\n\nRequired role: **ADMIN**", + "operationId": "updateBookMetadataByBatch", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/BookMetadataUpdateDto" + }, + "description": "A map of book IDs which values are the metadata fields to update. Set a field to null to unset the metadata. You can omit fields you don't want to update." + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update book metadata in bulk", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/ondeck": { + "get": { + "description": "Return first unread book of series with at least one book read and no books in progress.", + "operationId": "getBooksOnDeck", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageBookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List books on deck", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/thumbnails": { + "put": { + "description": "Required role: **ADMIN**", + "operationId": "booksRegenerateThumbnails", + "parameters": [ + { + "in": "query", + "name": "for_bigger_result_only", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Regenerate books posters", + "tags": [ + "Book Poster" + ] + } + }, + "/api/v1/books/{bookId}": { + "get": { + "operationId": "getBookById", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "404": { + "description": "Not Found" + } + }, + "summary": "Get book details", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/{bookId}/analyze": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "bookAnalyze", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Analyze book", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/{bookId}/file": { + "delete": { + "description": "Required role: **ADMIN**", + "operationId": "deleteBookFile", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete book file", + "tags": [ + "Books" + ] + }, + "get": { + "description": "Download the book file.\n\nRequired role: **FILE_DOWNLOAD**", + "operationId": "downloadBookFile", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StreamingResponseBody" + } + }, + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/StreamingResponseBody" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Download book file", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/{bookId}/file/*": { + "get": { + "description": "Download the book file.\n\nRequired role: **FILE_DOWNLOAD**", + "operationId": "downloadBookFile_1", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StreamingResponseBody" + } + }, + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/StreamingResponseBody" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Download book file", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/{bookId}/manifest": { + "get": { + "operationId": "getBookWebPubManifest", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/divina+json": { + "schema": { + "$ref": "#/components/schemas/WPPublicationDto" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/WPPublicationDto" + } + }, + "application/webpub+json": { + "schema": { + "$ref": "#/components/schemas/WPPublicationDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get book's WebPub manifest", + "tags": [ + "WebPub Manifest" + ] + } + }, + "/api/v1/books/{bookId}/manifest/divina": { + "get": { + "operationId": "getBookWebPubManifestDivina", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/divina+json": { + "schema": { + "$ref": "#/components/schemas/WPPublicationDto" + } + }, + "application/json": { + "schema": { + "$ref": "#/components/schemas/WPPublicationDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get book's WebPub manifest (DiViNa)", + "tags": [ + "WebPub Manifest" + ] + } + }, + "/api/v1/books/{bookId}/manifest/epub": { + "get": { + "operationId": "getBookWebPubManifestEpub", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WPPublicationDto" + } + }, + "application/webpub+json": { + "schema": { + "$ref": "#/components/schemas/WPPublicationDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get book's WebPub manifest (Epub)", + "tags": [ + "WebPub Manifest" + ] + } + }, + "/api/v1/books/{bookId}/manifest/pdf": { + "get": { + "operationId": "getBookWebPubManifestPdf", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WPPublicationDto" + } + }, + "application/webpub+json": { + "schema": { + "$ref": "#/components/schemas/WPPublicationDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get book's WebPub manifest (PDF)", + "tags": [ + "WebPub Manifest" + ] + } + }, + "/api/v1/books/{bookId}/metadata": { + "patch": { + "description": "Set a field to null to unset the metadata. You can omit fields you don't want to update.\n\nRequired role: **ADMIN**", + "operationId": "updateBookMetadata", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BookMetadataUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update book metadata", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/{bookId}/metadata/refresh": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "bookRefreshMetadata", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Refresh book metadata", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/{bookId}/next": { + "get": { + "operationId": "getBookSiblingNext", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get next book in series", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/{bookId}/pages": { + "get": { + "operationId": "getBookPages", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PageDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List book pages", + "tags": [ + "Book Pages" + ] + } + }, + "/api/v1/books/{bookId}/pages/{pageNumber}": { + "get": { + "description": "Required role: **PAGE_STREAMING**", + "operationId": "getBookPageByNumber", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pageNumber", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + }, + { + "description": "Convert the image to the provided format.", + "in": "query", + "name": "convert", + "required": false, + "schema": { + "type": "string", + "enum": [ + "jpeg", + "png" + ] + } + }, + { + "description": "If set to true, pages will start at index 0. If set to false, pages will start at index 1.", + "in": "query", + "name": "zero_based", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + }, + { + "description": "Some very limited server driven content negotiation is handled. If a book is a PDF book, and the Accept header contains 'application/pdf' as a more specific type than other 'image/' types, a raw PDF page will be returned.", + "in": "header", + "name": "Accept", + "required": false, + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MediaType" + } + } + }, + { + "in": "query", + "name": "contentNegotiation", + "required": false, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "default": { + "content": { + "image/*": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "default response" + } + }, + "summary": "Get book page image", + "tags": [ + "Book Pages" + ] + } + }, + "/api/v1/books/{bookId}/pages/{pageNumber}/raw": { + "get": { + "description": "Returns the book page in raw format, without content negotiation.\n\nRequired role: **PAGE_STREAMING**", + "operationId": "getBookPageRawByNumber", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pageNumber", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "type": "string", + "format": "byte" + } + }, + "application/json": { + "schema": { + "type": "string", + "format": "byte" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get raw book page", + "tags": [ + "Book Pages" + ] + } + }, + "/api/v1/books/{bookId}/pages/{pageNumber}/thumbnail": { + "get": { + "description": "The image is resized to 300px on the largest dimension.", + "operationId": "getBookPageThumbnailByNumber", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pageNumber", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "default": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + }, + "image/jpeg": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "default response" + } + }, + "summary": "Get book page thumbnail", + "tags": [ + "Book Pages" + ] + } + }, + "/api/v1/books/{bookId}/positions": { + "get": { + "description": "The Positions API is a proposed standard for OPDS 2 and Readium. It is used by the Epub Reader.", + "operationId": "getBookPositions", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/R2Positions" + } + }, + "application/vnd.readium.position-list+json": { + "schema": { + "$ref": "#/components/schemas/R2Positions" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List book's positions", + "tags": [ + "WebPub Manifest" + ] + } + }, + "/api/v1/books/{bookId}/previous": { + "get": { + "operationId": "getBookSiblingPrevious", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get previous book in series", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/{bookId}/progression": { + "get": { + "description": "The Progression API is a proposed standard for OPDS 2 and Readium. It is used by the Epub Reader.", + "operationId": "getBookProgression", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/R2Progression" + } + }, + "application/vnd.readium.progression+json": { + "schema": { + "$ref": "#/components/schemas/R2Progression" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get book progression", + "tags": [ + "WebPub Manifest" + ] + }, + "put": { + "description": "The Progression API is a proposed standard for OPDS 2 and Readium. It is used by the Epub Reader.", + "operationId": "updateBookProgression", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/R2Progression" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Mark book progression", + "tags": [ + "WebPub Manifest" + ] + } + }, + "/api/v1/books/{bookId}/read-progress": { + "delete": { + "description": "Mark book as unread", + "operationId": "deleteBookReadProgress", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Mark book as unread", + "tags": [ + "Books" + ] + }, + "patch": { + "description": "Mark book as read and/or change page progress.", + "operationId": "markBookReadProgress", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadProgressUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Mark book's read progress", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/{bookId}/readlists": { + "get": { + "operationId": "getReadListsByBookId", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReadListDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List book's readlists", + "tags": [ + "Books" + ] + } + }, + "/api/v1/books/{bookId}/resource/{resource}": { + "get": { + "description": "Return a resource from within an Epub book.", + "operationId": "getBookEpubResource", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "resource", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "type": "string", + "format": "byte" + } + }, + "application/json": { + "schema": { + "type": "string", + "format": "byte" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "security": [], + "summary": "Get Epub resource", + "tags": [ + "WebPub Manifest" + ] + } + }, + "/api/v1/books/{bookId}/thumbnail": { + "get": { + "operationId": "getBookThumbnail", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "default": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + }, + "image/jpeg": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "default response" + } + }, + "summary": "Get book's poster image", + "tags": [ + "Book Poster" + ] + } + }, + "/api/v1/books/{bookId}/thumbnails": { + "get": { + "operationId": "getBookThumbnails", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ThumbnailBookDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List book posters", + "tags": [ + "Book Poster" + ] + }, + "post": { + "description": "Required role: **ADMIN**", + "operationId": "addUserUploadedBookThumbnail", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "selected", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "format": "binary" + } + }, + "required": [ + "file" + ] + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThumbnailBookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Add book poster", + "tags": [ + "Book Poster" + ] + } + }, + "/api/v1/books/{bookId}/thumbnails/{thumbnailId}": { + "delete": { + "description": "Only uploaded posters can be deleted.\n\nRequired role: **ADMIN**", + "operationId": "deleteUserUploadedBookThumbnail", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "thumbnailId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete book poster", + "tags": [ + "Book Poster" + ] + }, + "get": { + "operationId": "getBookThumbnailById", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "thumbnailId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "default": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + }, + "image/jpeg": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "default response" + } + }, + "summary": "Get book poster image", + "tags": [ + "Book Poster" + ] + } + }, + "/api/v1/books/{bookId}/thumbnails/{thumbnailId}/selected": { + "put": { + "description": "Required role: **ADMIN**", + "operationId": "markBookThumbnailSelected", + "parameters": [ + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "thumbnailId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Mark book poster as selected", + "tags": [ + "Book Poster" + ] + } + }, + "/api/v1/claim": { + "get": { + "description": "Check whether this server has already been claimed.", + "operationId": "getClaimStatus", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ClaimStatus" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "security": [], + "summary": "Retrieve claim status", + "tags": [ + "Claim" + ] + }, + "post": { + "description": "Creates an admin user with the provided credentials.", + "operationId": "claimServer", + "parameters": [ + { + "in": "header", + "name": "X-Komga-Email", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "header", + "name": "X-Komga-Password", + "required": true, + "schema": { + "type": "string", + "minLength": 1 + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "security": [], + "summary": "Claim server", + "tags": [ + "Claim" + ] + } + }, + "/api/v1/client-settings/global": { + "delete": { + "description": "Setting key should be a valid lowercase namespace string like 'application.domain.key'\n\nRequired role: **ADMIN**", + "operationId": "deleteGlobalSettings", + "requestBody": { + "content": { + "application/json": { + "example": [ + "application.key1", + "application.key2" + ], + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete global settings", + "tags": [ + "Client settings" + ] + }, + "patch": { + "description": "Setting key should be a valid lowercase namespace string like 'application.domain.key'\n\nRequired role: **ADMIN**", + "operationId": "saveGlobalSetting", + "requestBody": { + "content": { + "application/json": { + "example": { + "application.key1": { + "value": "a string value", + "allowUnauthorized": true + }, + "application.key2": { + "value": "{\"json\":\"object\"}", + "allowUnauthorized": false + } + }, + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/ClientSettingGlobalUpdateDto" + } + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Save global settings", + "tags": [ + "Client settings" + ] + } + }, + "/api/v1/client-settings/global/list": { + "get": { + "description": "For unauthenticated users, only settings with 'allowUnauthorized=true' will be returned.", + "operationId": "getGlobalSettings", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/ClientSettingDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "security": [], + "summary": "Retrieve global client settings", + "tags": [ + "Client settings" + ] + } + }, + "/api/v1/client-settings/user": { + "delete": { + "description": "Setting key should be a valid lowercase namespace string like 'application.domain.key'", + "operationId": "deleteUserSettings", + "requestBody": { + "content": { + "application/json": { + "example": [ + "application.key1", + "application.key2" + ], + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete user settings", + "tags": [ + "Client settings" + ] + }, + "patch": { + "description": "Setting key should be a valid lowercase namespace string like 'application.domain.key'", + "operationId": "saveUserSetting", + "requestBody": { + "content": { + "application/json": { + "example": { + "application.key1": { + "value": "a string value" + }, + "application.key2": { + "value": "{\"json\":\"object\"}" + } + }, + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/ClientSettingUserUpdateDto" + } + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Save user settings", + "tags": [ + "Client settings" + ] + } + }, + "/api/v1/client-settings/user/list": { + "get": { + "operationId": "getUserSettings", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/ClientSettingDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Retrieve user client settings", + "tags": [ + "Client settings" + ] + } + }, + "/api/v1/collections": { + "get": { + "operationId": "getCollections", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageCollectionDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List collections", + "tags": [ + "Collections" + ] + }, + "post": { + "description": "Required role: **ADMIN**", + "operationId": "createCollection", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollectionCreationDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollectionDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Create collection", + "tags": [ + "Collections" + ] + } + }, + "/api/v1/collections/{id}": { + "delete": { + "description": "Required role: **ADMIN**", + "operationId": "deleteCollectionById", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete collection", + "tags": [ + "Collections" + ] + }, + "get": { + "operationId": "getCollectionById", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollectionDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get collection details", + "tags": [ + "Collections" + ] + }, + "patch": { + "description": "Required role: **ADMIN**", + "operationId": "updateCollectionById", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollectionUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update collection", + "tags": [ + "Collections" + ] + } + }, + "/api/v1/collections/{id}/series": { + "get": { + "operationId": "getSeriesByCollectionId", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "status", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ENDED", + "ONGOING", + "ABANDONED", + "HIATUS" + ] + } + } + }, + { + "in": "query", + "name": "read_status", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "UNREAD", + "READ", + "IN_PROGRESS" + ] + } + } + }, + { + "in": "query", + "name": "publisher", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "genre", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "age_rating", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "release_year", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "deleted", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "complete", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + }, + { + "description": "Author criteria in the format: name,role. Multiple author criteria are supported.", + "in": "query", + "name": "author", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageSeriesDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List collection's series", + "tags": [ + "Collection Series" + ] + } + }, + "/api/v1/collections/{id}/thumbnail": { + "get": { + "operationId": "getCollectionThumbnail", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "default": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + }, + "image/jpeg": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "default response" + } + }, + "summary": "Get collection's poster image", + "tags": [ + "Collection Poster" + ] + } + }, + "/api/v1/collections/{id}/thumbnails": { + "get": { + "operationId": "getCollectionThumbnails", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ThumbnailSeriesCollectionDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List collection's posters", + "tags": [ + "Collection Poster" + ] + }, + "post": { + "description": "Required role: **ADMIN**", + "operationId": "addUserUploadedCollectionThumbnail", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "selected", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "format": "binary" + } + }, + "required": [ + "file" + ] + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThumbnailSeriesCollectionDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Add collection poster", + "tags": [ + "Collection Poster" + ] + } + }, + "/api/v1/collections/{id}/thumbnails/{thumbnailId}": { + "delete": { + "description": "Required role: **ADMIN**", + "operationId": "deleteUserUploadedCollectionThumbnail", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "thumbnailId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete collection poster", + "tags": [ + "Collection Poster" + ] + }, + "get": { + "operationId": "getCollectionThumbnailById", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "thumbnailId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "default": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + }, + "image/jpeg": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "default response" + } + }, + "summary": "Get collection poster image", + "tags": [ + "Collection Poster" + ] + } + }, + "/api/v1/collections/{id}/thumbnails/{thumbnailId}/selected": { + "put": { + "description": "Required role: **ADMIN**", + "operationId": "markCollectionThumbnailSelected", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "thumbnailId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Mark collection poster as selected", + "tags": [ + "Collection Poster" + ] + } + }, + "/api/v1/filesystem": { + "post": { + "description": "List folders and files from the host server's file system. If no request body is passed then the root directories are returned.\n\nRequired role: **ADMIN**", + "operationId": "getDirectoryListing", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DirectoryRequestDto" + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DirectoryListingDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Directory listing", + "tags": [ + "File system" + ] + } + }, + "/api/v1/fonts/families": { + "get": { + "description": "List all available font families.", + "operationId": "getFonts", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List font families", + "tags": [ + "Fonts" + ] + } + }, + "/api/v1/fonts/resource/{fontFamily}/css": { + "get": { + "description": "Download a CSS file with the @font-face block for the font family. This is used by the Epub Reader to change fonts.", + "operationId": "getFontFamilyAsCss", + "parameters": [ + { + "in": "path", + "name": "fontFamily", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + }, + "text/css": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "security": [], + "summary": "Download CSS file", + "tags": [ + "Fonts" + ] + } + }, + "/api/v1/fonts/resource/{fontFamily}/{fontFile}": { + "get": { + "operationId": "getFontFile", + "parameters": [ + { + "in": "path", + "name": "fontFamily", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "fontFile", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "security": [], + "summary": "Download font file", + "tags": [ + "Fonts" + ] + } + }, + "/api/v1/genres": { + "get": { + "deprecated": true, + "description": "Use GET /v2/genres instead. Deprecated since 1.26.0", + "operationId": "getGenres_1", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List genres", + "tags": [ + "Deprecated", + "Referential metadata" + ] + } + }, + "/api/v1/history": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getHistoricalEvents", + "parameters": [ + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + }, + { + "description": "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "in": "query", + "name": "sort", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageHistoricalEventDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List historical events", + "tags": [ + "History" + ] + } + }, + "/api/v1/languages": { + "get": { + "deprecated": true, + "description": "Use GET /v2/languages instead. Deprecated since 1.26.0", + "operationId": "getLanguages_1", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List languages", + "tags": [ + "Deprecated", + "Referential metadata" + ] + } + }, + "/api/v1/libraries": { + "get": { + "description": "The libraries are filtered based on the current user's permissions", + "operationId": "getLibraries", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/LibraryDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List all libraries", + "tags": [ + "Libraries" + ] + }, + "post": { + "description": "Required role: **ADMIN**", + "operationId": "addLibrary", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LibraryCreationDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LibraryDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Create a library", + "tags": [ + "Libraries" + ] + } + }, + "/api/v1/libraries/{libraryId}": { + "delete": { + "description": "Required role: **ADMIN**", + "operationId": "deleteLibraryById", + "parameters": [ + { + "in": "path", + "name": "libraryId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete a library", + "tags": [ + "Libraries" + ] + }, + "get": { + "operationId": "getLibraryById", + "parameters": [ + { + "in": "path", + "name": "libraryId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LibraryDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get details for a single library", + "tags": [ + "Libraries" + ] + }, + "patch": { + "description": "You can omit fields you don't want to update\n\nRequired role: **ADMIN**", + "operationId": "updateLibraryById", + "parameters": [ + { + "in": "path", + "name": "libraryId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LibraryUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update a library", + "tags": [ + "Libraries" + ] + }, + "put": { + "deprecated": true, + "description": "Use PATCH /api/v1/libraries/{libraryId} instead. Deprecated since 1.3.0.\n\nRequired role: **ADMIN**", + "operationId": "updateLibraryByIdDeprecated", + "parameters": [ + { + "in": "path", + "name": "libraryId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LibraryUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update a library", + "tags": [ + "Deprecated", + "Libraries" + ] + } + }, + "/api/v1/libraries/{libraryId}/analyze": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "libraryAnalyze", + "parameters": [ + { + "in": "path", + "name": "libraryId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Analyze a library", + "tags": [ + "Libraries" + ] + } + }, + "/api/v1/libraries/{libraryId}/empty-trash": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "libraryEmptyTrash", + "parameters": [ + { + "in": "path", + "name": "libraryId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Empty trash for a library", + "tags": [ + "Libraries" + ] + } + }, + "/api/v1/libraries/{libraryId}/metadata/refresh": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "libraryRefreshMetadata", + "parameters": [ + { + "in": "path", + "name": "libraryId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Refresh metadata for a library", + "tags": [ + "Libraries" + ] + } + }, + "/api/v1/libraries/{libraryId}/scan": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "libraryScan", + "parameters": [ + { + "in": "path", + "name": "libraryId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "deep", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Scan a library", + "tags": [ + "Libraries" + ] + } + }, + "/api/v1/login/set-cookie": { + "get": { + "description": "Forcefully return Set-Cookie header, even if the session is contained in the X-Auth-Token header.", + "operationId": "convertHeaderSessionToCookie", + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Set cookie", + "tags": [ + "User session" + ] + } + }, + "/api/v1/oauth2/providers": { + "get": { + "operationId": "getOAuth2Providers", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/OAuth2ClientDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "security": [], + "summary": "List registered OAuth2 providers", + "tags": [ + "OAuth2" + ] + } + }, + "/api/v1/page-hashes": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getKnownPageHashes", + "parameters": [ + { + "in": "query", + "name": "action", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "DELETE_AUTO", + "DELETE_MANUAL", + "IGNORE" + ] + } + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + }, + { + "description": "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "in": "query", + "name": "sort", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PagePageHashKnownDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List known duplicates", + "tags": [ + "Duplicate Pages" + ] + }, + "put": { + "description": "Required role: **ADMIN**", + "operationId": "createOrUpdateKnownPageHash", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageHashCreationDto" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Mark duplicate page as known", + "tags": [ + "Duplicate Pages" + ] + } + }, + "/api/v1/page-hashes/unknown": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getUnknownPageHashes", + "parameters": [ + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + }, + { + "description": "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "in": "query", + "name": "sort", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PagePageHashUnknownDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List unknown duplicates", + "tags": [ + "Duplicate Pages" + ] + } + }, + "/api/v1/page-hashes/unknown/{pageHash}/thumbnail": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getUnknownPageHashThumbnail", + "parameters": [ + { + "in": "path", + "name": "pageHash", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "resize", + "required": false, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "default": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + }, + "image/jpeg": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "default response" + } + }, + "summary": "Get unknown duplicate image thumbnail", + "tags": [ + "Duplicate Pages" + ] + } + }, + "/api/v1/page-hashes/{pageHash}": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getPageHashMatches", + "parameters": [ + { + "in": "path", + "name": "pageHash", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + }, + { + "description": "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "in": "query", + "name": "sort", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PagePageHashMatchDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List duplicate matches", + "tags": [ + "Duplicate Pages" + ] + } + }, + "/api/v1/page-hashes/{pageHash}/delete-all": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "deleteDuplicatePagesByPageHash", + "parameters": [ + { + "in": "path", + "name": "pageHash", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete all duplicate pages by hash", + "tags": [ + "Duplicate Pages" + ] + } + }, + "/api/v1/page-hashes/{pageHash}/delete-match": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "deleteSingleMatchByPageHash", + "parameters": [ + { + "in": "path", + "name": "pageHash", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageHashMatchDto" + } + } + }, + "required": true + }, + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete specific duplicate page", + "tags": [ + "Duplicate Pages" + ] + } + }, + "/api/v1/page-hashes/{pageHash}/thumbnail": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getKnownPageHashThumbnail", + "parameters": [ + { + "in": "path", + "name": "pageHash", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "default": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + }, + "image/jpeg": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "default response" + } + }, + "summary": "Get known duplicate image thumbnail", + "tags": [ + "Duplicate Pages" + ] + } + }, + "/api/v1/publishers": { + "get": { + "deprecated": true, + "description": "Use GET /v2/publishers instead. Deprecated since 1.26.0", + "operationId": "getPublishers_1", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List publishers", + "tags": [ + "Deprecated", + "Referential metadata" + ] + } + }, + "/api/v1/readlists": { + "get": { + "operationId": "getReadLists", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageReadListDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List readlists", + "tags": [ + "Readlists" + ] + }, + "post": { + "description": "Required role: **ADMIN**", + "operationId": "createReadList", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadListCreationDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadListDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Create readlist", + "tags": [ + "Readlists" + ] + } + }, + "/api/v1/readlists/match/comicrack": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "matchComicRackList", + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "format": "binary" + } + }, + "required": [ + "file" + ] + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadListRequestMatchDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Match ComicRack list", + "tags": [ + "ComicRack" + ] + } + }, + "/api/v1/readlists/{id}": { + "delete": { + "description": "Required role: **ADMIN**", + "operationId": "deleteReadListById", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete readlist", + "tags": [ + "Readlists" + ] + }, + "get": { + "operationId": "getReadListById", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadListDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get readlist details", + "tags": [ + "Readlists" + ] + }, + "patch": { + "description": "Required role: **ADMIN**", + "operationId": "updateReadListById", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadListUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update readlist", + "tags": [ + "Readlists" + ] + } + }, + "/api/v1/readlists/{id}/books": { + "get": { + "operationId": "getBooksByReadListId", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "read_status", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "UNREAD", + "READ", + "IN_PROGRESS" + ] + } + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "media_status", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "UNKNOWN", + "ERROR", + "READY", + "UNSUPPORTED", + "OUTDATED" + ] + } + } + }, + { + "in": "query", + "name": "deleted", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + }, + { + "description": "Author criteria in the format: name,role. Multiple author criteria are supported.", + "in": "query", + "name": "author", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageBookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List readlist's books", + "tags": [ + "Readlist Books" + ] + } + }, + "/api/v1/readlists/{id}/books/{bookId}/next": { + "get": { + "operationId": "getBookSiblingNextInReadList", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get next book in readlist", + "tags": [ + "Readlist Books" + ] + } + }, + "/api/v1/readlists/{id}/books/{bookId}/previous": { + "get": { + "operationId": "getBookSiblingPreviousInReadList", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "bookId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get previous book in readlist", + "tags": [ + "Readlist Books" + ] + } + }, + "/api/v1/readlists/{id}/file": { + "get": { + "description": "Download the whole readlist as a ZIP file.\n\nRequired role: **FILE_DOWNLOAD**", + "operationId": "downloadReadListAsZip", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StreamingResponseBody" + } + }, + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/StreamingResponseBody" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Download readlist", + "tags": [ + "Readlists" + ] + } + }, + "/api/v1/readlists/{id}/read-progress/tachiyomi": { + "get": { + "description": "Mihon specific, due to how read progress is handled in Mihon.", + "operationId": "getMihonReadProgressByReadListId", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TachiyomiReadProgressDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get readlist read progress (Mihon)", + "tags": [ + "Mihon" + ] + }, + "put": { + "description": "Mihon specific, due to how read progress is handled in Mihon.", + "operationId": "updateMihonReadProgressByReadListId", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TachiyomiReadProgressUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update readlist read progress (Mihon)", + "tags": [ + "Mihon" + ] + } + }, + "/api/v1/readlists/{id}/thumbnail": { + "get": { + "operationId": "getReadListThumbnail", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "default": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + }, + "image/jpeg": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "default response" + } + }, + "summary": "Get readlist's poster image", + "tags": [ + "Readlist Poster" + ] + } + }, + "/api/v1/readlists/{id}/thumbnails": { + "get": { + "operationId": "getReadListThumbnails", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ThumbnailReadListDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List readlist's posters", + "tags": [ + "Readlist Poster" + ] + }, + "post": { + "description": "Required role: **ADMIN**", + "operationId": "addUserUploadedReadListThumbnail", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "selected", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "format": "binary" + } + }, + "required": [ + "file" + ] + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThumbnailReadListDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Add readlist poster", + "tags": [ + "Readlist Poster" + ] + } + }, + "/api/v1/readlists/{id}/thumbnails/{thumbnailId}": { + "delete": { + "description": "Required role: **ADMIN**", + "operationId": "deleteUserUploadedReadListThumbnail", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "thumbnailId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete readlist poster", + "tags": [ + "Readlist Poster" + ] + }, + "get": { + "operationId": "getReadListThumbnailById", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "thumbnailId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "default": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + }, + "image/jpeg": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "default response" + } + }, + "summary": "Get readlist poster image", + "tags": [ + "Readlist Poster" + ] + } + }, + "/api/v1/readlists/{id}/thumbnails/{thumbnailId}/selected": { + "put": { + "description": "Required role: **ADMIN**", + "operationId": "markReadListThumbnailSelected", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "thumbnailId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Mark readlist poster as selected", + "tags": [ + "Readlist Poster" + ] + } + }, + "/api/v1/releases": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getReleases", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReleaseDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List releases", + "tags": [ + "Releases" + ] + } + }, + "/api/v1/series": { + "get": { + "deprecated": true, + "description": "Use POST /api/v1/series/list instead. Deprecated since 1.19.0.", + "operationId": "getSeriesDeprecated", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "status", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ENDED", + "ONGOING", + "ABANDONED", + "HIATUS" + ] + } + } + }, + { + "in": "query", + "name": "read_status", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "UNREAD", + "READ", + "IN_PROGRESS" + ] + } + } + }, + { + "in": "query", + "name": "publisher", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "genre", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "age_rating", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "release_year", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "sharing_label", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "deleted", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "complete", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "oneshot", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Search by regex criteria, in the form: regex,field. Supported fields are TITLE and TITLE_SORT.", + "in": "query", + "name": "search_regex", + "schema": { + "type": "string" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + }, + { + "description": "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "in": "query", + "name": "sort", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "description": "Author criteria in the format: name,role. Multiple author criteria are supported.", + "in": "query", + "name": "author", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageSeriesDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List series", + "tags": [ + "Series", + "Deprecated" + ] + } + }, + "/api/v1/series/alphabetical-groups": { + "get": { + "deprecated": true, + "description": "Use POST /api/v1/series/list/alphabetical-groups instead. Deprecated since 1.19.0.", + "operationId": "getSeriesAlphabeticalGroupsDeprecated", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "status", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "ENDED", + "ONGOING", + "ABANDONED", + "HIATUS" + ] + } + } + }, + { + "in": "query", + "name": "read_status", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "UNREAD", + "READ", + "IN_PROGRESS" + ] + } + } + }, + { + "in": "query", + "name": "publisher", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "language", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "genre", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "age_rating", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "release_year", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "sharing_label", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "deleted", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "complete", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "oneshot", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Search by regex criteria, in the form: regex,field. Supported fields are TITLE and TITLE_SORT.", + "in": "query", + "name": "search_regex", + "schema": { + "type": "string" + } + }, + { + "description": "Author criteria in the format: name,role. Multiple author criteria are supported.", + "in": "query", + "name": "author", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GroupCountDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List series groups", + "tags": [ + "Series", + "Deprecated" + ] + } + }, + "/api/v1/series/latest": { + "get": { + "description": "Return recently added or updated series.", + "operationId": "getSeriesLatest", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "deleted", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "oneshot", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageSeriesDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List latest series", + "tags": [ + "Series" + ] + } + }, + "/api/v1/series/list": { + "post": { + "operationId": "getSeries", + "parameters": [ + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + }, + { + "description": "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "in": "query", + "name": "sort", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SeriesSearch" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageSeriesDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List series", + "tags": [ + "Series" + ] + } + }, + "/api/v1/series/list/alphabetical-groups": { + "post": { + "description": "List series grouped by the first character of their sort title.", + "operationId": "getSeriesAlphabeticalGroups", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SeriesSearch" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GroupCountDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List series groups", + "tags": [ + "Series" + ] + } + }, + "/api/v1/series/new": { + "get": { + "description": "Return newly added series.", + "operationId": "getSeriesNew", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "deleted", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "oneshot", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageSeriesDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List new series", + "tags": [ + "Series" + ] + } + }, + "/api/v1/series/release-dates": { + "get": { + "deprecated": true, + "description": "Use GET /v2/series/release-years instead. Deprecated since 1.26.0", + "operationId": "getSeriesReleaseDates", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List series release dates", + "tags": [ + "Deprecated", + "Referential metadata" + ] + } + }, + "/api/v1/series/updated": { + "get": { + "description": "Return recently updated series, but not newly added ones.", + "operationId": "getSeriesUpdated", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "deleted", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "oneshot", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageSeriesDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List updated series", + "tags": [ + "Series" + ] + } + }, + "/api/v1/series/{seriesId}": { + "get": { + "operationId": "getSeriesById", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SeriesDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "404": { + "description": "Not Found" + } + }, + "summary": "Get series details", + "tags": [ + "Series" + ] + } + }, + "/api/v1/series/{seriesId}/analyze": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "seriesAnalyze", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Analyze series", + "tags": [ + "Series" + ] + } + }, + "/api/v1/series/{seriesId}/books": { + "get": { + "deprecated": true, + "description": "Use POST /api/v1/books/list instead. Deprecated since 1.19.0.", + "operationId": "getBooksBySeriesId", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "media_status", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "UNKNOWN", + "ERROR", + "READY", + "UNSUPPORTED", + "OUTDATED" + ] + } + } + }, + { + "in": "query", + "name": "read_status", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string", + "enum": [ + "UNREAD", + "READ", + "IN_PROGRESS" + ] + } + } + }, + { + "in": "query", + "name": "tag", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "in": "query", + "name": "deleted", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + }, + { + "description": "Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "in": "query", + "name": "sort", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "description": "Author criteria in the format: name,role. Multiple author criteria are supported.", + "in": "query", + "name": "author", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageBookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List series' books", + "tags": [ + "Series", + "Deprecated" + ] + } + }, + "/api/v1/series/{seriesId}/collections": { + "get": { + "operationId": "getCollectionsBySeriesId", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CollectionDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List series' collections", + "tags": [ + "Series" + ] + } + }, + "/api/v1/series/{seriesId}/file": { + "delete": { + "description": "Delete all of the series' books files on disk.\n\nRequired role: **ADMIN**", + "operationId": "deleteSeriesFile", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete series files", + "tags": [ + "Series" + ] + }, + "get": { + "description": "Download the whole series as a ZIP file.\n\nRequired role: **FILE_DOWNLOAD**", + "operationId": "downloadSeriesAsZip", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StreamingResponseBody" + } + }, + "application/octet-stream": { + "schema": { + "$ref": "#/components/schemas/StreamingResponseBody" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Download series", + "tags": [ + "Series" + ] + } + }, + "/api/v1/series/{seriesId}/metadata": { + "patch": { + "description": "Required role: **ADMIN**", + "operationId": "updateSeriesMetadata", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SeriesMetadataUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update series metadata", + "tags": [ + "Series" + ] + } + }, + "/api/v1/series/{seriesId}/metadata/refresh": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "seriesRefreshMetadata", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Refresh series metadata", + "tags": [ + "Series" + ] + } + }, + "/api/v1/series/{seriesId}/read-progress": { + "delete": { + "description": "Mark all book for series as unread", + "operationId": "markSeriesAsUnread", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Mark series as unread", + "tags": [ + "Series" + ] + }, + "post": { + "description": "Mark all book for series as read", + "operationId": "markSeriesAsRead", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Mark series as read", + "tags": [ + "Series" + ] + } + }, + "/api/v1/series/{seriesId}/thumbnail": { + "get": { + "operationId": "getSeriesThumbnail", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "default": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + }, + "image/jpeg": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "default response" + } + }, + "summary": "Get series' poster image", + "tags": [ + "Series Poster" + ] + } + }, + "/api/v1/series/{seriesId}/thumbnails": { + "get": { + "operationId": "getSeriesThumbnails", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ThumbnailSeriesDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List series posters", + "tags": [ + "Series Poster" + ] + }, + "post": { + "description": "Required role: **ADMIN**", + "operationId": "addUserUploadedSeriesThumbnail", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "selected", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "file": { + "type": "string", + "format": "binary" + } + }, + "required": [ + "file" + ] + } + } + } + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThumbnailSeriesDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Add series poster", + "tags": [ + "Series Poster" + ] + } + }, + "/api/v1/series/{seriesId}/thumbnails/{thumbnailId}": { + "delete": { + "description": "Required role: **ADMIN**", + "operationId": "deleteUserUploadedSeriesThumbnail", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "thumbnailId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete series poster", + "tags": [ + "Series Poster" + ] + }, + "get": { + "operationId": "getSeriesThumbnailById", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "thumbnailId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + }, + "default": { + "content": { + "application/json": { + "schema": { + "type": "string", + "format": "binary" + } + }, + "image/jpeg": { + "schema": { + "type": "string", + "format": "binary" + } + } + }, + "description": "default response" + } + }, + "summary": "Get series poster image", + "tags": [ + "Series Poster" + ] + } + }, + "/api/v1/series/{seriesId}/thumbnails/{thumbnailId}/selected": { + "put": { + "description": "Required role: **ADMIN**", + "operationId": "markSeriesThumbnailSelected", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "thumbnailId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "202": { + "description": "Accepted" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Mark series poster as selected", + "tags": [ + "Series Poster" + ] + } + }, + "/api/v1/settings": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getServerSettings", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SettingsDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Retrieve server settings", + "tags": [ + "Server settings" + ] + }, + "patch": { + "description": "You can omit fields you don't want to update\n\nRequired role: **ADMIN**", + "operationId": "updateServerSettings", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SettingsUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update server settings", + "tags": [ + "Server settings" + ] + } + }, + "/api/v1/sharing-labels": { + "get": { + "deprecated": true, + "description": "Use GET /v2/sharing-labels instead. Deprecated since 1.26.0", + "operationId": "getSharingLabels_1", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List sharing labels", + "tags": [ + "Deprecated", + "Referential metadata" + ] + } + }, + "/api/v1/syncpoints/me": { + "delete": { + "description": "If an API Key ID is passed, deletes only the sync points associated with that API Key. Deleting sync points will allow a Kobo to sync from scratch upon the next sync.", + "operationId": "deleteSyncPointsForCurrentUser", + "parameters": [ + { + "in": "query", + "name": "key_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete all sync points", + "tags": [ + "Sync points" + ] + } + }, + "/api/v1/tags": { + "get": { + "deprecated": true, + "description": "Use GET /v2/tags instead. Deprecated since 1.26.0", + "operationId": "getTags_1", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List tags", + "tags": [ + "Deprecated", + "Referential metadata" + ] + } + }, + "/api/v1/tags/book": { + "get": { + "deprecated": true, + "description": "Use GET /v2/tags instead. Deprecated since 1.26.0", + "operationId": "getBookTags", + "parameters": [ + { + "in": "query", + "name": "series_id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "readlist_id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List book tags", + "tags": [ + "Deprecated", + "Referential metadata" + ] + } + }, + "/api/v1/tags/series": { + "get": { + "deprecated": true, + "description": "Use GET /v2/tags instead. Deprecated since 1.26.0", + "operationId": "getSeriesTags", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List series tags", + "tags": [ + "Deprecated", + "Referential metadata" + ] + } + }, + "/api/v1/tasks": { + "delete": { + "description": "Cancel all tasks queued\n\nRequired role: **ADMIN**", + "operationId": "emptyTaskQueue", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "integer", + "format": "int32" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Clear task queue", + "tags": [ + "Tasks" + ] + } + }, + "/api/v1/transient-books": { + "post": { + "description": "Scan provided folder for transient books.\n\nRequired role: **ADMIN**", + "operationId": "scanTransientBooks", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ScanRequestDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TransientBookDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Scan folder for transient books", + "tags": [ + "Import" + ] + } + }, + "/api/v1/transient-books/{id}/analyze": { + "post": { + "description": "Required role: **ADMIN**", + "operationId": "analyzeTransientBook", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TransientBookDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Analyze transient book", + "tags": [ + "Import" + ] + } + }, + "/api/v1/transient-books/{id}/pages/{pageNumber}": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getPageByTransientBookId", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "path", + "name": "pageNumber", + "required": true, + "schema": { + "type": "integer", + "format": "int32" + } + } + ], + "responses": { + "200": { + "content": { + "*/*": { + "schema": { + "type": "string", + "format": "byte" + } + }, + "application/json": { + "schema": { + "type": "string", + "format": "byte" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get transient book page", + "tags": [ + "Import" + ] + } + }, + "/api/v2/age-ratings": { + "get": { + "description": "Can be filtered by various criteria", + "operationId": "getAgeRatings", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageInteger" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List age ratings", + "tags": [ + "Referential metadata" + ] + } + }, + "/api/v2/authors": { + "get": { + "description": "Can be filtered by various criteria", + "operationId": "getAuthors", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "role", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "series_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "readlist_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageAuthorDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List authors", + "tags": [ + "Referential metadata" + ] + } + }, + "/api/v2/authors/names": { + "get": { + "description": "Can be filtered by various criteria", + "operationId": "getAuthorsNames", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "role", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "series_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "readlist_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageString" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List authors names", + "tags": [ + "Referential metadata" + ] + } + }, + "/api/v2/authors/roles": { + "get": { + "description": "Can be filtered by various criteria", + "operationId": "getAuthorsRoles", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "series_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "readlist_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageString" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List authors roles", + "tags": [ + "Referential metadata" + ] + } + }, + "/api/v2/genres": { + "get": { + "description": "Can be filtered by various criteria", + "operationId": "getGenres", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageString" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List genres", + "tags": [ + "Referential metadata" + ] + } + }, + "/api/v2/languages": { + "get": { + "description": "Can be filtered by various criteria", + "operationId": "getLanguages", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageString" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List languages", + "tags": [ + "Referential metadata" + ] + } + }, + "/api/v2/publishers": { + "get": { + "description": "Can be filtered by various criteria", + "operationId": "getPublishers", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageString" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List publishers", + "tags": [ + "Referential metadata" + ] + } + }, + "/api/v2/series/release-years": { + "get": { + "description": "Can be filtered by various criteria", + "operationId": "getSeriesReleaseYears", + "parameters": [ + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageString" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List series release years", + "tags": [ + "Referential metadata" + ] + } + }, + "/api/v2/series/{seriesId}/read-progress/tachiyomi": { + "get": { + "description": "Mihon specific, due to how read progress is handled in Mihon.", + "operationId": "getMihonReadProgressBySeriesId", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TachiyomiReadProgressV2Dto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Get series read progress (Mihon)", + "tags": [ + "Mihon" + ] + }, + "put": { + "description": "Mihon specific, due to how read progress is handled in Mihon.", + "operationId": "updateMihonReadProgressBySeriesId", + "parameters": [ + { + "in": "path", + "name": "seriesId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TachiyomiReadProgressUpdateV2Dto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update series read progress (Mihon)", + "tags": [ + "Mihon" + ] + } + }, + "/api/v2/sharing-labels": { + "get": { + "description": "Can be filtered by various criteria", + "operationId": "getSharingLabels", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageString" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List sharing labels", + "tags": [ + "Referential metadata" + ] + } + }, + "/api/v2/tags": { + "get": { + "description": "Can be filtered by various criteria", + "operationId": "getTags", + "parameters": [ + { + "in": "query", + "name": "search", + "required": false, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "library_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "collection_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "series_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "readlist_id", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + { + "in": "query", + "name": "include", + "required": false, + "schema": { + "type": "string", + "enum": [ + "SERIES", + "BOOK", + "BOTH" + ] + } + }, + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer" + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageString" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List tags", + "tags": [ + "Referential metadata" + ] + } + }, + "/api/v2/users": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getUsers", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "List users", + "tags": [ + "Users" + ] + }, + "post": { + "description": "Required role: **ADMIN**", + "operationId": "addUser", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserCreationDto" + } + } + }, + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserDto" + } + } + }, + "description": "Created" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Create user", + "tags": [ + "Users" + ] + } + }, + "/api/v2/users/authentication-activity": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getAuthenticationActivity", + "parameters": [ + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer", + "default": 0 + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer", + "default": 20 + } + }, + { + "description": "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "in": "query", + "name": "sort", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageAuthenticationActivityDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Retrieve authentication activity", + "tags": [ + "Users" + ] + } + }, + "/api/v2/users/me": { + "get": { + "operationId": "getCurrentUser", + "parameters": [ + { + "in": "query", + "name": "remember-me", + "required": false, + "schema": { + "type": "boolean" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Retrieve current user", + "tags": [ + "Current user" + ] + } + }, + "/api/v2/users/me/api-keys": { + "get": { + "operationId": "getApiKeysForCurrentUser", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ApiKeyDto" + } + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Retrieve API keys", + "tags": [ + "API Keys" + ] + }, + "post": { + "operationId": "createApiKeyForCurrentUser", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiKeyRequestDto" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiKeyDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Create API key", + "tags": [ + "API Keys" + ] + } + }, + "/api/v2/users/me/api-keys/{keyId}": { + "delete": { + "operationId": "deleteApiKeyByKeyId", + "parameters": [ + { + "in": "path", + "name": "keyId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete API key", + "tags": [ + "API Keys" + ] + } + }, + "/api/v2/users/me/authentication-activity": { + "get": { + "operationId": "getAuthenticationActivityForCurrentUser", + "parameters": [ + { + "in": "query", + "name": "unpaged", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "description": "Zero-based page index (0..N)", + "in": "query", + "name": "page", + "schema": { + "type": "integer", + "default": 0 + } + }, + { + "description": "The size of the page to be returned", + "in": "query", + "name": "size", + "schema": { + "type": "integer", + "default": 20 + } + }, + { + "description": "Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.", + "in": "query", + "name": "sort", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PageAuthenticationActivityDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Retrieve authentication activity for the current user", + "tags": [ + "Current user" + ] + } + }, + "/api/v2/users/me/password": { + "patch": { + "operationId": "updatePasswordForCurrentUser", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PasswordUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update current user's password", + "tags": [ + "Current user" + ] + } + }, + "/api/v2/users/{id}": { + "delete": { + "description": "Required role: **ADMIN**", + "operationId": "deleteUserById", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Delete user", + "tags": [ + "Users" + ] + }, + "patch": { + "description": "Required role: **ADMIN**", + "operationId": "updateUserById", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update user", + "tags": [ + "Users" + ] + } + }, + "/api/v2/users/{id}/authentication-activity/latest": { + "get": { + "description": "Required role: **ADMIN**", + "operationId": "getLatestAuthenticationActivityByUserId", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "apikey_id", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthenticationActivityDto" + } + } + }, + "description": "OK" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Retrieve latest authentication activity for a user", + "tags": [ + "Users" + ] + } + }, + "/api/v2/users/{id}/password": { + "patch": { + "description": "Required role: **ADMIN**", + "operationId": "updatePasswordByUserId", + "parameters": [ + { + "in": "path", + "name": "id", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PasswordUpdateDto" + } + } + }, + "required": true + }, + "responses": { + "204": { + "description": "No Content" + }, + "400": { + "content": { + "*/*": { + "schema": { + "$ref": "#/components/schemas/ValidationErrorResponse" + } + } + }, + "description": "Bad Request" + } + }, + "summary": "Update user's password", + "tags": [ + "Users" + ] + } + } + }, + "components": { + "schemas": { + "AgeRestrictionDto": { + "type": "object", + "properties": { + "age": { + "type": "integer", + "format": "int32" + }, + "restriction": { + "type": "string", + "enum": [ + "ALLOW_ONLY", + "EXCLUDE" + ] + } + }, + "required": [ + "age", + "restriction" + ] + }, + "AgeRestrictionUpdateDto": { + "type": "object", + "properties": { + "age": { + "type": "integer", + "format": "int32" + }, + "restriction": { + "type": "string", + "enum": [ + "ALLOW_ONLY", + "EXCLUDE", + "NONE" + ] + } + }, + "required": [ + "age", + "restriction" + ] + }, + "AlternateTitleDto": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "label", + "title" + ] + }, + "AlternateTitleUpdateDto": { + "type": "object", + "properties": { + "label": { + "type": "string", + "minLength": 1 + }, + "title": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "label", + "title" + ] + }, + "ApiKeyDto": { + "type": "object", + "properties": { + "comment": { + "type": "string" + }, + "createdDate": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string" + }, + "key": { + "type": "string" + }, + "lastModifiedDate": { + "type": "string", + "format": "date-time" + }, + "userId": { + "type": "string" + } + }, + "required": [ + "comment", + "createdDate", + "id", + "key", + "lastModifiedDate", + "userId" + ] + }, + "ApiKeyRequestDto": { + "type": "object", + "properties": { + "comment": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "comment" + ] + }, + "AuthenticationActivityDto": { + "type": "object", + "properties": { + "apiKeyComment": { + "type": "string" + }, + "apiKeyId": { + "type": "string" + }, + "dateTime": { + "type": "string", + "format": "date-time" + }, + "email": { + "type": "string" + }, + "error": { + "type": "string" + }, + "ip": { + "type": "string" + }, + "source": { + "type": "string" + }, + "success": { + "type": "boolean" + }, + "userAgent": { + "type": "string" + }, + "userId": { + "type": "string" + } + }, + "required": [ + "dateTime", + "success" + ] + }, + "AuthorDto": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "role": { + "type": "string" + } + }, + "required": [ + "name", + "role" + ] + }, + "AuthorUpdateDto": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1 + }, + "role": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "name", + "role" + ] + }, + "BookDto": { + "type": "object", + "properties": { + "created": { + "type": "string", + "format": "date-time" + }, + "deleted": { + "type": "boolean" + }, + "fileHash": { + "type": "string" + }, + "fileLastModified": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string" + }, + "lastModified": { + "type": "string", + "format": "date-time" + }, + "libraryId": { + "type": "string" + }, + "media": { + "$ref": "#/components/schemas/MediaDto" + }, + "metadata": { + "$ref": "#/components/schemas/BookMetadataDto" + }, + "name": { + "type": "string" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "oneshot": { + "type": "boolean" + }, + "readProgress": { + "$ref": "#/components/schemas/ReadProgressDto" + }, + "seriesId": { + "type": "string" + }, + "seriesTitle": { + "type": "string" + }, + "size": { + "type": "string" + }, + "sizeBytes": { + "type": "integer", + "format": "int64" + }, + "url": { + "type": "string" + } + }, + "required": [ + "created", + "deleted", + "fileHash", + "fileLastModified", + "id", + "lastModified", + "libraryId", + "media", + "metadata", + "name", + "number", + "oneshot", + "seriesId", + "seriesTitle", + "size", + "sizeBytes", + "url" + ] + }, + "BookImportBatchDto": { + "type": "object", + "properties": { + "books": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BookImportDto" + } + }, + "copyMode": { + "type": "string", + "enum": [ + "MOVE", + "COPY", + "HARDLINK" + ] + } + }, + "required": [ + "books", + "copyMode" + ] + }, + "BookImportDto": { + "type": "object", + "properties": { + "destinationName": { + "type": "string" + }, + "seriesId": { + "type": "string" + }, + "sourceFile": { + "type": "string" + }, + "upgradeBookId": { + "type": "string" + } + }, + "required": [ + "seriesId", + "sourceFile" + ] + }, + "BookMetadataAggregationDto": { + "type": "object", + "properties": { + "authors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AuthorDto" + } + }, + "created": { + "type": "string", + "format": "date-time" + }, + "lastModified": { + "type": "string", + "format": "date-time" + }, + "releaseDate": { + "type": "string", + "format": "date" + }, + "summary": { + "type": "string" + }, + "summaryNumber": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + "required": [ + "authors", + "created", + "lastModified", + "summary", + "summaryNumber", + "tags" + ] + }, + "BookMetadataDto": { + "type": "object", + "properties": { + "authors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AuthorDto" + } + }, + "authorsLock": { + "type": "boolean" + }, + "created": { + "type": "string", + "format": "date-time" + }, + "isbn": { + "type": "string" + }, + "isbnLock": { + "type": "boolean" + }, + "lastModified": { + "type": "string", + "format": "date-time" + }, + "links": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WebLinkDto" + } + }, + "linksLock": { + "type": "boolean" + }, + "number": { + "type": "string" + }, + "numberLock": { + "type": "boolean" + }, + "numberSort": { + "type": "number", + "format": "float" + }, + "numberSortLock": { + "type": "boolean" + }, + "releaseDate": { + "type": "string", + "format": "date" + }, + "releaseDateLock": { + "type": "boolean" + }, + "summary": { + "type": "string" + }, + "summaryLock": { + "type": "boolean" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "tagsLock": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "titleLock": { + "type": "boolean" + } + }, + "required": [ + "authors", + "authorsLock", + "created", + "isbn", + "isbnLock", + "lastModified", + "links", + "linksLock", + "number", + "numberLock", + "numberSort", + "numberSortLock", + "releaseDateLock", + "summary", + "summaryLock", + "tags", + "tagsLock", + "title", + "titleLock" + ] + }, + "BookMetadataUpdateDto": { + "type": "object", + "description": "Metadata fields to update. Set a field to null to unset the metadata. You can omit fields you don't want to update.", + "properties": { + "authors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AuthorUpdateDto" + } + }, + "authorsLock": { + "type": "boolean" + }, + "isbn": { + "type": "string" + }, + "isbnLock": { + "type": "boolean" + }, + "links": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WebLinkUpdateDto" + } + }, + "linksLock": { + "type": "boolean" + }, + "number": { + "type": "string" + }, + "numberLock": { + "type": "boolean" + }, + "numberSort": { + "type": "number", + "format": "float" + }, + "numberSortLock": { + "type": "boolean" + }, + "releaseDate": { + "type": "string", + "format": "date" + }, + "releaseDateLock": { + "type": "boolean" + }, + "summary": { + "type": "string" + }, + "summaryLock": { + "type": "boolean" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "tagsLock": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "titleLock": { + "type": "boolean" + } + } + }, + "BookSearch": { + "type": "object", + "properties": { + "condition": { + "$ref": "#/components/schemas/SearchConditionBook" + }, + "fullTextSearch": { + "type": "string" + } + } + }, + "ClaimStatus": { + "type": "object", + "properties": { + "isClaimed": { + "type": "boolean" + } + }, + "required": [ + "isClaimed" + ] + }, + "ClientSettingDto": { + "type": "object", + "properties": { + "allowUnauthorized": { + "type": "boolean" + }, + "value": { + "type": "string" + } + }, + "required": [ + "value" + ] + }, + "ClientSettingGlobalUpdateDto": { + "type": "object", + "properties": { + "allowUnauthorized": { + "type": "boolean" + }, + "value": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "allowUnauthorized", + "value" + ] + }, + "ClientSettingUserUpdateDto": { + "type": "object", + "properties": { + "value": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "value" + ] + }, + "CollectionCreationDto": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1 + }, + "ordered": { + "type": "boolean" + }, + "seriesIds": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + } + }, + "required": [ + "name", + "ordered", + "seriesIds" + ] + }, + "CollectionDto": { + "type": "object", + "properties": { + "createdDate": { + "type": "string", + "format": "date-time" + }, + "filtered": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "lastModifiedDate": { + "type": "string", + "format": "date-time" + }, + "name": { + "type": "string" + }, + "ordered": { + "type": "boolean" + }, + "seriesIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "createdDate", + "filtered", + "id", + "lastModifiedDate", + "name", + "ordered", + "seriesIds" + ] + }, + "CollectionUpdateDto": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "ordered": { + "type": "boolean" + }, + "seriesIds": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "DirectoryListingDto": { + "type": "object", + "properties": { + "directories": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PathDto" + } + }, + "files": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PathDto" + } + }, + "parent": { + "type": "string" + } + }, + "required": [ + "directories", + "files" + ] + }, + "DirectoryRequestDto": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "showFiles": { + "type": "boolean" + } + }, + "required": [ + "path", + "showFiles" + ] + }, + "GroupCountDto": { + "type": "object", + "properties": { + "count": { + "type": "integer", + "format": "int32" + }, + "group": { + "type": "string" + } + }, + "required": [ + "count", + "group" + ] + }, + "HistoricalEventDto": { + "type": "object", + "properties": { + "bookId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "seriesId": { + "type": "string" + }, + "timestamp": { + "type": "string", + "format": "date-time" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "properties", + "timestamp", + "type" + ] + }, + "ItemAuthorDto": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Author's name", + "example": "gotson" + }, + "url": { + "type": "string", + "description": "URL of a site owned by the author", + "example": "https://github.com/gotson" + } + } + }, + "ItemDto": { + "type": "object", + "properties": { + "_komga": { + "$ref": "#/components/schemas/KomgaExtensionDto", + "description": "Additional fields for the item" + }, + "author": { + "$ref": "#/components/schemas/ItemAuthorDto", + "description": "Author of the item" + }, + "content_html": { + "type": "string", + "description": "HTML of the item", + "example": "

A longer text…

" + }, + "date_modified": { + "type": "string", + "format": "date-time", + "description": "Modification date in RFC 3339 format", + "example": "2023-12-15T00:00:00Z" + }, + "id": { + "type": "string", + "description": "Unique for that item for that feed over time", + "example": "https://komga.org/blog/ebook-drop2" + }, + "summary": { + "type": "string", + "description": "A plain text sentence or two describing the item", + "example": "Version 1.9.0 contains the second feature drop for Ebooks support." + }, + "tags": { + "type": "array", + "description": "Tags describing the item", + "examples": [ + "upgrade", + "komga" + ], + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "title": { + "type": "string", + "description": "Plain text title", + "example": "eBook drop 2" + }, + "url": { + "type": "string", + "description": "URL of the resource described by the item", + "example": "https://komga.org/blog/ebook-drop2" + } + }, + "required": [ + "id", + "tags" + ] + }, + "JsonFeedDto": { + "type": "object", + "example": { + "version": "https://jsonfeed.org/version/1", + "title": "Announcements", + "home_page_url": "https://komga.org/blog", + "description": "Latest Komga announcements", + "items": [ + { + "id": "https://komga.org/blog/ebook-drop2", + "url": "https://komga.org/blog/ebook-drop2", + "title": "eBook drop 2", + "summary": "Version 1.9.0 contains the second feature drop for Ebooks support.", + "content_html": "

A longer text…

", + "date_modified": "2023-12-15T00:00:00Z", + "author": { + "name": "gotson", + "url": "https://github.com/gotson" + }, + "tags": [ + "upgrade", + "komga" + ], + "_komga": { + "read": false + } + }, + { + "id": "https://komga.org/blog/ebook-support", + "url": "https://komga.org/blog/ebook-support", + "title": "eBook support", + "summary": "Version 1.8.0 is bringing a long awaited feature: proper eBook support!", + "content_html": "

A longer text…

", + "date_modified": "2023-11-29T00:00:00Z", + "author": { + "name": "gotson", + "url": "https://github.com/gotson" + }, + "tags": [ + "upgrade", + "komga" + ], + "_komga": { + "read": true + } + } + ] + }, + "properties": { + "description": { + "type": "string", + "description": "Provides more detail on what the feed is about", + "example": "Latest Komga announcements" + }, + "home_page_url": { + "type": "string", + "description": "URL of the resource that the feed describes", + "example": "https://komga.org/blog" + }, + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ItemDto" + } + }, + "title": { + "type": "string", + "description": "Name of the feed", + "example": "Announcements" + }, + "version": { + "type": "string", + "description": "URL of the version of the format the feed uses", + "example": "https://jsonfeed.org/version/1" + } + }, + "required": [ + "items", + "title", + "version" + ] + }, + "KomgaExtensionDto": { + "type": "object", + "properties": { + "read": { + "type": "boolean", + "description": "Whether the current item has been marked read by the current user", + "example": false + } + }, + "required": [ + "read" + ] + }, + "LibraryCreationDto": { + "type": "object", + "properties": { + "analyzeDimensions": { + "type": "boolean" + }, + "convertToCbz": { + "type": "boolean" + }, + "emptyTrashAfterScan": { + "type": "boolean" + }, + "hashFiles": { + "type": "boolean" + }, + "hashKoreader": { + "type": "boolean" + }, + "hashPages": { + "type": "boolean" + }, + "importBarcodeIsbn": { + "type": "boolean" + }, + "importComicInfoBook": { + "type": "boolean" + }, + "importComicInfoCollection": { + "type": "boolean" + }, + "importComicInfoReadList": { + "type": "boolean" + }, + "importComicInfoSeries": { + "type": "boolean" + }, + "importComicInfoSeriesAppendVolume": { + "type": "boolean" + }, + "importEpubBook": { + "type": "boolean" + }, + "importEpubSeries": { + "type": "boolean" + }, + "importLocalArtwork": { + "type": "boolean" + }, + "importMylarSeries": { + "type": "boolean" + }, + "name": { + "type": "string", + "minLength": 1 + }, + "oneshotsDirectory": { + "type": "string" + }, + "repairExtensions": { + "type": "boolean" + }, + "root": { + "type": "string", + "minLength": 1 + }, + "scanCbx": { + "type": "boolean" + }, + "scanDirectoryExclusions": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "scanEpub": { + "type": "boolean" + }, + "scanForceModifiedTime": { + "type": "boolean" + }, + "scanInterval": { + "type": "string", + "enum": [ + "DISABLED", + "HOURLY", + "EVERY_6H", + "EVERY_12H", + "DAILY", + "WEEKLY" + ] + }, + "scanOnStartup": { + "type": "boolean" + }, + "scanPdf": { + "type": "boolean" + }, + "seriesCover": { + "type": "string", + "enum": [ + "FIRST", + "FIRST_UNREAD_OR_FIRST", + "FIRST_UNREAD_OR_LAST", + "LAST" + ] + } + }, + "required": [ + "analyzeDimensions", + "convertToCbz", + "emptyTrashAfterScan", + "hashFiles", + "hashKoreader", + "hashPages", + "importBarcodeIsbn", + "importComicInfoBook", + "importComicInfoCollection", + "importComicInfoReadList", + "importComicInfoSeries", + "importComicInfoSeriesAppendVolume", + "importEpubBook", + "importEpubSeries", + "importLocalArtwork", + "importMylarSeries", + "name", + "repairExtensions", + "root", + "scanCbx", + "scanDirectoryExclusions", + "scanEpub", + "scanForceModifiedTime", + "scanInterval", + "scanOnStartup", + "scanPdf", + "seriesCover" + ] + }, + "LibraryDto": { + "type": "object", + "properties": { + "analyzeDimensions": { + "type": "boolean" + }, + "convertToCbz": { + "type": "boolean" + }, + "emptyTrashAfterScan": { + "type": "boolean" + }, + "hashFiles": { + "type": "boolean" + }, + "hashKoreader": { + "type": "boolean" + }, + "hashPages": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "importBarcodeIsbn": { + "type": "boolean" + }, + "importComicInfoBook": { + "type": "boolean" + }, + "importComicInfoCollection": { + "type": "boolean" + }, + "importComicInfoReadList": { + "type": "boolean" + }, + "importComicInfoSeries": { + "type": "boolean" + }, + "importComicInfoSeriesAppendVolume": { + "type": "boolean" + }, + "importEpubBook": { + "type": "boolean" + }, + "importEpubSeries": { + "type": "boolean" + }, + "importLocalArtwork": { + "type": "boolean" + }, + "importMylarSeries": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "oneshotsDirectory": { + "type": "string" + }, + "repairExtensions": { + "type": "boolean" + }, + "root": { + "type": "string" + }, + "scanCbx": { + "type": "boolean" + }, + "scanDirectoryExclusions": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "scanEpub": { + "type": "boolean" + }, + "scanForceModifiedTime": { + "type": "boolean" + }, + "scanInterval": { + "type": "string", + "enum": [ + "DISABLED", + "HOURLY", + "EVERY_6H", + "EVERY_12H", + "DAILY", + "WEEKLY" + ] + }, + "scanOnStartup": { + "type": "boolean" + }, + "scanPdf": { + "type": "boolean" + }, + "seriesCover": { + "type": "string", + "enum": [ + "FIRST", + "FIRST_UNREAD_OR_FIRST", + "FIRST_UNREAD_OR_LAST", + "LAST" + ] + }, + "unavailable": { + "type": "boolean" + } + }, + "required": [ + "analyzeDimensions", + "convertToCbz", + "emptyTrashAfterScan", + "hashFiles", + "hashKoreader", + "hashPages", + "id", + "importBarcodeIsbn", + "importComicInfoBook", + "importComicInfoCollection", + "importComicInfoReadList", + "importComicInfoSeries", + "importComicInfoSeriesAppendVolume", + "importEpubBook", + "importEpubSeries", + "importLocalArtwork", + "importMylarSeries", + "name", + "repairExtensions", + "root", + "scanCbx", + "scanDirectoryExclusions", + "scanEpub", + "scanForceModifiedTime", + "scanInterval", + "scanOnStartup", + "scanPdf", + "seriesCover", + "unavailable" + ] + }, + "LibraryUpdateDto": { + "type": "object", + "description": "Fields to update. You can omit fields you don't want to update.", + "properties": { + "analyzeDimensions": { + "type": "boolean" + }, + "convertToCbz": { + "type": "boolean" + }, + "emptyTrashAfterScan": { + "type": "boolean" + }, + "hashFiles": { + "type": "boolean" + }, + "hashKoreader": { + "type": "boolean" + }, + "hashPages": { + "type": "boolean" + }, + "importBarcodeIsbn": { + "type": "boolean" + }, + "importComicInfoBook": { + "type": "boolean" + }, + "importComicInfoCollection": { + "type": "boolean" + }, + "importComicInfoReadList": { + "type": "boolean" + }, + "importComicInfoSeries": { + "type": "boolean" + }, + "importComicInfoSeriesAppendVolume": { + "type": "boolean" + }, + "importEpubBook": { + "type": "boolean" + }, + "importEpubSeries": { + "type": "boolean" + }, + "importLocalArtwork": { + "type": "boolean" + }, + "importMylarSeries": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "oneshotsDirectory": { + "type": "string" + }, + "repairExtensions": { + "type": "boolean" + }, + "root": { + "type": "string" + }, + "scanCbx": { + "type": "boolean" + }, + "scanDirectoryExclusions": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "scanEpub": { + "type": "boolean" + }, + "scanForceModifiedTime": { + "type": "boolean" + }, + "scanInterval": { + "type": "string", + "enum": [ + "DISABLED", + "HOURLY", + "EVERY_6H", + "EVERY_12H", + "DAILY", + "WEEKLY" + ] + }, + "scanOnStartup": { + "type": "boolean" + }, + "scanPdf": { + "type": "boolean" + }, + "seriesCover": { + "type": "string", + "enum": [ + "FIRST", + "FIRST_UNREAD_OR_FIRST", + "FIRST_UNREAD_OR_LAST", + "LAST" + ] + } + } + }, + "Location": { + "type": "object", + "properties": { + "fragments": { + "type": "array", + "items": { + "type": "string" + } + }, + "position": { + "type": "integer", + "format": "int32" + }, + "progression": { + "type": "number", + "format": "float" + }, + "totalProgression": { + "type": "number", + "format": "float" + } + }, + "required": [ + "fragments" + ] + }, + "MediaDto": { + "type": "object", + "properties": { + "comment": { + "type": "string" + }, + "epubDivinaCompatible": { + "type": "boolean" + }, + "epubIsKepub": { + "type": "boolean" + }, + "mediaProfile": { + "type": "string" + }, + "mediaType": { + "type": "string" + }, + "pagesCount": { + "type": "integer", + "format": "int32" + }, + "status": { + "type": "string" + } + }, + "required": [ + "comment", + "epubDivinaCompatible", + "epubIsKepub", + "mediaProfile", + "mediaType", + "pagesCount", + "status" + ] + }, + "MediaType": { + "type": "object", + "properties": { + "charset": { + "type": "string" + }, + "concrete": { + "type": "boolean" + }, + "parameters": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "qualityValue": { + "type": "number", + "format": "double" + }, + "subtype": { + "type": "string" + }, + "subtypeSuffix": { + "type": "string" + }, + "type": { + "type": "string" + }, + "wildcardSubtype": { + "type": "boolean" + }, + "wildcardType": { + "type": "boolean" + } + } + }, + "OAuth2ClientDto": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "registrationId": { + "type": "string" + } + }, + "required": [ + "name", + "registrationId" + ] + }, + "PageAuthenticationActivityDto": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AuthenticationActivityDto" + } + }, + "empty": { + "type": "boolean" + }, + "first": { + "type": "boolean" + }, + "last": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "numberOfElements": { + "type": "integer", + "format": "int32" + }, + "pageable": { + "$ref": "#/components/schemas/PageableObject" + }, + "size": { + "type": "integer", + "format": "int32" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "totalElements": { + "type": "integer", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "format": "int32" + } + } + }, + "PageAuthorDto": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AuthorDto" + } + }, + "empty": { + "type": "boolean" + }, + "first": { + "type": "boolean" + }, + "last": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "numberOfElements": { + "type": "integer", + "format": "int32" + }, + "pageable": { + "$ref": "#/components/schemas/PageableObject" + }, + "size": { + "type": "integer", + "format": "int32" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "totalElements": { + "type": "integer", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "format": "int32" + } + } + }, + "PageBookDto": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/BookDto" + } + }, + "empty": { + "type": "boolean" + }, + "first": { + "type": "boolean" + }, + "last": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "numberOfElements": { + "type": "integer", + "format": "int32" + }, + "pageable": { + "$ref": "#/components/schemas/PageableObject" + }, + "size": { + "type": "integer", + "format": "int32" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "totalElements": { + "type": "integer", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "format": "int32" + } + } + }, + "PageCollectionDto": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/CollectionDto" + } + }, + "empty": { + "type": "boolean" + }, + "first": { + "type": "boolean" + }, + "last": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "numberOfElements": { + "type": "integer", + "format": "int32" + }, + "pageable": { + "$ref": "#/components/schemas/PageableObject" + }, + "size": { + "type": "integer", + "format": "int32" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "totalElements": { + "type": "integer", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "format": "int32" + } + } + }, + "PageDto": { + "type": "object", + "properties": { + "fileName": { + "type": "string" + }, + "height": { + "type": "integer", + "format": "int32" + }, + "mediaType": { + "type": "string" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "size": { + "type": "string" + }, + "sizeBytes": { + "type": "integer", + "format": "int64" + }, + "width": { + "type": "integer", + "format": "int32" + } + }, + "required": [ + "fileName", + "mediaType", + "number", + "size" + ] + }, + "PageHashCreationDto": { + "type": "object", + "properties": { + "action": { + "type": "string", + "enum": [ + "DELETE_AUTO", + "DELETE_MANUAL", + "IGNORE" + ] + }, + "hash": { + "type": "string", + "minLength": 1 + }, + "size": { + "type": "integer", + "format": "int64" + } + }, + "required": [ + "action", + "hash" + ] + }, + "PageHashKnownDto": { + "type": "object", + "properties": { + "action": { + "type": "string", + "enum": [ + "DELETE_AUTO", + "DELETE_MANUAL", + "IGNORE" + ] + }, + "created": { + "type": "string", + "format": "date-time" + }, + "deleteCount": { + "type": "integer", + "format": "int32" + }, + "hash": { + "type": "string" + }, + "lastModified": { + "type": "string", + "format": "date-time" + }, + "matchCount": { + "type": "integer", + "format": "int32" + }, + "size": { + "type": "integer", + "format": "int64" + } + }, + "required": [ + "action", + "created", + "deleteCount", + "hash", + "lastModified", + "matchCount" + ] + }, + "PageHashMatchDto": { + "type": "object", + "properties": { + "bookId": { + "type": "string" + }, + "fileName": { + "type": "string" + }, + "fileSize": { + "type": "integer", + "format": "int64" + }, + "mediaType": { + "type": "string" + }, + "pageNumber": { + "type": "integer", + "format": "int32" + }, + "url": { + "type": "string" + } + }, + "required": [ + "bookId", + "fileName", + "fileSize", + "mediaType", + "pageNumber", + "url" + ] + }, + "PageHashUnknownDto": { + "type": "object", + "properties": { + "hash": { + "type": "string" + }, + "matchCount": { + "type": "integer", + "format": "int32" + }, + "size": { + "type": "integer", + "format": "int64" + } + }, + "required": [ + "hash", + "matchCount" + ] + }, + "PageHistoricalEventDto": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HistoricalEventDto" + } + }, + "empty": { + "type": "boolean" + }, + "first": { + "type": "boolean" + }, + "last": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "numberOfElements": { + "type": "integer", + "format": "int32" + }, + "pageable": { + "$ref": "#/components/schemas/PageableObject" + }, + "size": { + "type": "integer", + "format": "int32" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "totalElements": { + "type": "integer", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "format": "int32" + } + } + }, + "PageInteger": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + }, + "empty": { + "type": "boolean" + }, + "first": { + "type": "boolean" + }, + "last": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "numberOfElements": { + "type": "integer", + "format": "int32" + }, + "pageable": { + "$ref": "#/components/schemas/PageableObject" + }, + "size": { + "type": "integer", + "format": "int32" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "totalElements": { + "type": "integer", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "format": "int32" + } + } + }, + "PagePageHashKnownDto": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PageHashKnownDto" + } + }, + "empty": { + "type": "boolean" + }, + "first": { + "type": "boolean" + }, + "last": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "numberOfElements": { + "type": "integer", + "format": "int32" + }, + "pageable": { + "$ref": "#/components/schemas/PageableObject" + }, + "size": { + "type": "integer", + "format": "int32" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "totalElements": { + "type": "integer", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "format": "int32" + } + } + }, + "PagePageHashMatchDto": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PageHashMatchDto" + } + }, + "empty": { + "type": "boolean" + }, + "first": { + "type": "boolean" + }, + "last": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "numberOfElements": { + "type": "integer", + "format": "int32" + }, + "pageable": { + "$ref": "#/components/schemas/PageableObject" + }, + "size": { + "type": "integer", + "format": "int32" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "totalElements": { + "type": "integer", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "format": "int32" + } + } + }, + "PagePageHashUnknownDto": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PageHashUnknownDto" + } + }, + "empty": { + "type": "boolean" + }, + "first": { + "type": "boolean" + }, + "last": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "numberOfElements": { + "type": "integer", + "format": "int32" + }, + "pageable": { + "$ref": "#/components/schemas/PageableObject" + }, + "size": { + "type": "integer", + "format": "int32" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "totalElements": { + "type": "integer", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "format": "int32" + } + } + }, + "PageReadListDto": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReadListDto" + } + }, + "empty": { + "type": "boolean" + }, + "first": { + "type": "boolean" + }, + "last": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "numberOfElements": { + "type": "integer", + "format": "int32" + }, + "pageable": { + "$ref": "#/components/schemas/PageableObject" + }, + "size": { + "type": "integer", + "format": "int32" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "totalElements": { + "type": "integer", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "format": "int32" + } + } + }, + "PageSeriesDto": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SeriesDto" + } + }, + "empty": { + "type": "boolean" + }, + "first": { + "type": "boolean" + }, + "last": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "numberOfElements": { + "type": "integer", + "format": "int32" + }, + "pageable": { + "$ref": "#/components/schemas/PageableObject" + }, + "size": { + "type": "integer", + "format": "int32" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "totalElements": { + "type": "integer", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "format": "int32" + } + } + }, + "PageString": { + "type": "object", + "properties": { + "content": { + "type": "array", + "items": { + "type": "string" + } + }, + "empty": { + "type": "boolean" + }, + "first": { + "type": "boolean" + }, + "last": { + "type": "boolean" + }, + "number": { + "type": "integer", + "format": "int32" + }, + "numberOfElements": { + "type": "integer", + "format": "int32" + }, + "pageable": { + "$ref": "#/components/schemas/PageableObject" + }, + "size": { + "type": "integer", + "format": "int32" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "totalElements": { + "type": "integer", + "format": "int64" + }, + "totalPages": { + "type": "integer", + "format": "int32" + } + } + }, + "PageableObject": { + "type": "object", + "properties": { + "offset": { + "type": "integer", + "format": "int64" + }, + "pageNumber": { + "type": "integer", + "format": "int32" + }, + "pageSize": { + "type": "integer", + "format": "int32" + }, + "paged": { + "type": "boolean" + }, + "sort": { + "$ref": "#/components/schemas/SortObject" + }, + "unpaged": { + "type": "boolean" + } + } + }, + "PasswordUpdateDto": { + "type": "object", + "properties": { + "password": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "password" + ] + }, + "PathDto": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "name", + "path", + "type" + ] + }, + "R2Device": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "id", + "name" + ] + }, + "R2Locator": { + "type": "object", + "properties": { + "href": { + "type": "string" + }, + "koboSpan": { + "type": "string" + }, + "locations": { + "$ref": "#/components/schemas/Location" + }, + "text": { + "$ref": "#/components/schemas/Text" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "href", + "type" + ] + }, + "R2Positions": { + "type": "object", + "properties": { + "positions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/R2Locator" + } + }, + "total": { + "type": "integer", + "format": "int32" + } + }, + "required": [ + "positions", + "total" + ] + }, + "R2Progression": { + "type": "object", + "properties": { + "device": { + "$ref": "#/components/schemas/R2Device" + }, + "locator": { + "$ref": "#/components/schemas/R2Locator" + }, + "modified": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "device", + "locator", + "modified" + ] + }, + "ReadListCreationDto": { + "type": "object", + "properties": { + "bookIds": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "name": { + "type": "string", + "minLength": 1 + }, + "ordered": { + "type": "boolean" + }, + "summary": { + "type": "string" + } + }, + "required": [ + "bookIds", + "name", + "ordered", + "summary" + ] + }, + "ReadListDto": { + "type": "object", + "properties": { + "bookIds": { + "type": "array", + "items": { + "type": "string" + } + }, + "createdDate": { + "type": "string", + "format": "date-time" + }, + "filtered": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "lastModifiedDate": { + "type": "string", + "format": "date-time" + }, + "name": { + "type": "string" + }, + "ordered": { + "type": "boolean" + }, + "summary": { + "type": "string" + } + }, + "required": [ + "bookIds", + "createdDate", + "filtered", + "id", + "lastModifiedDate", + "name", + "ordered", + "summary" + ] + }, + "ReadListMatchDto": { + "type": "object", + "properties": { + "errorCode": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "errorCode", + "name" + ] + }, + "ReadListRequestBookDto": { + "type": "object", + "properties": { + "number": { + "type": "string" + }, + "series": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + "required": [ + "number", + "series" + ] + }, + "ReadListRequestBookMatchBookDto": { + "type": "object", + "properties": { + "bookId": { + "type": "string" + }, + "number": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "bookId", + "number", + "title" + ] + }, + "ReadListRequestBookMatchDto": { + "type": "object", + "properties": { + "books": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReadListRequestBookMatchBookDto" + } + }, + "series": { + "$ref": "#/components/schemas/ReadListRequestBookMatchSeriesDto" + } + }, + "required": [ + "books", + "series" + ] + }, + "ReadListRequestBookMatchSeriesDto": { + "type": "object", + "properties": { + "releaseDate": { + "type": "string", + "format": "date" + }, + "seriesId": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": [ + "seriesId", + "title" + ] + }, + "ReadListRequestBookMatchesDto": { + "type": "object", + "properties": { + "matches": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReadListRequestBookMatchDto" + } + }, + "request": { + "$ref": "#/components/schemas/ReadListRequestBookDto" + } + }, + "required": [ + "matches", + "request" + ] + }, + "ReadListRequestMatchDto": { + "type": "object", + "properties": { + "errorCode": { + "type": "string" + }, + "readListMatch": { + "$ref": "#/components/schemas/ReadListMatchDto" + }, + "requests": { + "type": "array", + "items": { + "$ref": "#/components/schemas/ReadListRequestBookMatchesDto" + } + } + }, + "required": [ + "errorCode", + "readListMatch", + "requests" + ] + }, + "ReadListUpdateDto": { + "type": "object", + "properties": { + "bookIds": { + "type": "array", + "items": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "ordered": { + "type": "boolean" + }, + "summary": { + "type": "string" + } + } + }, + "ReadProgressDto": { + "type": "object", + "properties": { + "completed": { + "type": "boolean" + }, + "created": { + "type": "string", + "format": "date-time" + }, + "deviceId": { + "type": "string" + }, + "deviceName": { + "type": "string" + }, + "lastModified": { + "type": "string", + "format": "date-time" + }, + "page": { + "type": "integer", + "format": "int32" + }, + "readDate": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "completed", + "created", + "deviceId", + "deviceName", + "lastModified", + "page", + "readDate" + ] + }, + "ReadProgressUpdateDto": { + "type": "object", + "description": "page can be omitted if completed is set to true. completed can be omitted, and will be set accordingly depending on the page passed and the total number of pages in the book.", + "properties": { + "completed": { + "type": "boolean" + }, + "page": { + "type": "integer", + "format": "int32" + } + } + }, + "ReleaseDto": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "latest": { + "type": "boolean" + }, + "preRelease": { + "type": "boolean" + }, + "releaseDate": { + "type": "string", + "format": "date-time" + }, + "url": { + "type": "string" + }, + "version": { + "type": "string" + } + }, + "required": [ + "description", + "latest", + "preRelease", + "releaseDate", + "url", + "version" + ] + }, + "ScanRequestDto": { + "type": "object", + "properties": { + "path": { + "type": "string" + } + }, + "required": [ + "path" + ] + }, + "SearchConditionAgeRating": { + "properties": { + "ageRating": { + "$ref": "#/components/schemas/SearchOperatorNumericNullableInteger" + } + }, + "required": [ + "ageRating" + ] + }, + "SearchConditionAllOfBook": { + "properties": { + "allOf": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SearchConditionBook" + } + } + }, + "required": [ + "allOf" + ] + }, + "SearchConditionAllOfSeries": { + "properties": { + "allOf": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SearchConditionSeries" + } + } + }, + "required": [ + "allOf" + ] + }, + "SearchConditionAnyOfBook": { + "properties": { + "anyOf": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SearchConditionBook" + } + } + }, + "required": [ + "anyOf" + ] + }, + "SearchConditionAnyOfSeries": { + "properties": { + "anyOf": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SearchConditionSeries" + } + } + }, + "required": [ + "anyOf" + ] + }, + "SearchConditionAuthor": { + "properties": { + "author": { + "$ref": "#/components/schemas/SearchOperatorEqualityAuthorMatch" + } + }, + "required": [ + "author" + ] + }, + "SearchConditionBook": { + "oneOf": [ + { + "$ref": "#/components/schemas/SearchConditionAnyOfBook" + }, + { + "$ref": "#/components/schemas/SearchConditionAllOfBook" + }, + { + "$ref": "#/components/schemas/SearchConditionLibraryId" + }, + { + "$ref": "#/components/schemas/SearchConditionReadListId" + }, + { + "$ref": "#/components/schemas/SearchConditionSeriesId" + }, + { + "$ref": "#/components/schemas/SearchConditionDeleted" + }, + { + "$ref": "#/components/schemas/SearchConditionOneShot" + }, + { + "$ref": "#/components/schemas/SearchConditionTitle" + }, + { + "$ref": "#/components/schemas/SearchConditionReleaseDate" + }, + { + "$ref": "#/components/schemas/SearchConditionTag" + }, + { + "$ref": "#/components/schemas/SearchConditionNumberSort" + }, + { + "$ref": "#/components/schemas/SearchConditionReadStatus" + }, + { + "$ref": "#/components/schemas/SearchConditionMediaStatus" + }, + { + "$ref": "#/components/schemas/SearchConditionMediaProfile" + }, + { + "$ref": "#/components/schemas/SearchConditionAuthor" + }, + { + "$ref": "#/components/schemas/SearchConditionPoster" + } + ] + }, + "SearchConditionCollectionId": { + "properties": { + "collectionId": { + "$ref": "#/components/schemas/SearchOperatorEqualityString" + } + }, + "required": [ + "collectionId" + ] + }, + "SearchConditionComplete": { + "properties": { + "complete": { + "$ref": "#/components/schemas/SearchOperatorBoolean" + } + }, + "required": [ + "complete" + ] + }, + "SearchConditionDeleted": { + "properties": { + "deleted": { + "$ref": "#/components/schemas/SearchOperatorBoolean" + } + }, + "required": [ + "deleted" + ] + }, + "SearchConditionGenre": { + "properties": { + "genre": { + "$ref": "#/components/schemas/SearchOperatorEqualityNullableString" + } + }, + "required": [ + "genre" + ] + }, + "SearchConditionLanguage": { + "properties": { + "language": { + "$ref": "#/components/schemas/SearchOperatorEqualityString" + } + }, + "required": [ + "language" + ] + }, + "SearchConditionLibraryId": { + "properties": { + "libraryId": { + "$ref": "#/components/schemas/SearchOperatorEqualityString" + } + }, + "required": [ + "libraryId" + ] + }, + "SearchConditionMediaProfile": { + "properties": { + "mediaProfile": { + "$ref": "#/components/schemas/SearchOperatorEqualityMediaProfile" + } + }, + "required": [ + "mediaProfile" + ] + }, + "SearchConditionMediaStatus": { + "properties": { + "mediaStatus": { + "$ref": "#/components/schemas/SearchOperatorEqualityStatus" + } + }, + "required": [ + "mediaStatus" + ] + }, + "SearchConditionNumberSort": { + "properties": { + "numberSort": { + "$ref": "#/components/schemas/SearchOperatorNumericTFloat" + } + }, + "required": [ + "numberSort" + ] + }, + "SearchConditionOneShot": { + "properties": { + "oneShot": { + "$ref": "#/components/schemas/SearchOperatorBoolean" + } + }, + "required": [ + "oneShot" + ] + }, + "SearchConditionPoster": { + "properties": { + "poster": { + "$ref": "#/components/schemas/SearchOperatorEqualityPosterMatch" + } + }, + "required": [ + "poster" + ] + }, + "SearchConditionPublisher": { + "properties": { + "publisher": { + "$ref": "#/components/schemas/SearchOperatorEqualityString" + } + }, + "required": [ + "publisher" + ] + }, + "SearchConditionReadListId": { + "properties": { + "readListId": { + "$ref": "#/components/schemas/SearchOperatorEqualityString" + } + }, + "required": [ + "readListId" + ] + }, + "SearchConditionReadStatus": { + "properties": { + "readStatus": { + "$ref": "#/components/schemas/SearchOperatorEqualityReadStatus" + } + }, + "required": [ + "readStatus" + ] + }, + "SearchConditionReleaseDate": { + "properties": { + "releaseDate": { + "$ref": "#/components/schemas/SearchOperatorDate" + } + }, + "required": [ + "releaseDate" + ] + }, + "SearchConditionSeries": { + "oneOf": [ + { + "$ref": "#/components/schemas/SearchConditionAnyOfSeries" + }, + { + "$ref": "#/components/schemas/SearchConditionAllOfSeries" + }, + { + "$ref": "#/components/schemas/SearchConditionLibraryId" + }, + { + "$ref": "#/components/schemas/SearchConditionCollectionId" + }, + { + "$ref": "#/components/schemas/SearchConditionDeleted" + }, + { + "$ref": "#/components/schemas/SearchConditionComplete" + }, + { + "$ref": "#/components/schemas/SearchConditionOneShot" + }, + { + "$ref": "#/components/schemas/SearchConditionTitle" + }, + { + "$ref": "#/components/schemas/SearchConditionTitleSort" + }, + { + "$ref": "#/components/schemas/SearchConditionReleaseDate" + }, + { + "$ref": "#/components/schemas/SearchConditionTag" + }, + { + "$ref": "#/components/schemas/SearchConditionSharingLabel" + }, + { + "$ref": "#/components/schemas/SearchConditionPublisher" + }, + { + "$ref": "#/components/schemas/SearchConditionLanguage" + }, + { + "$ref": "#/components/schemas/SearchConditionGenre" + }, + { + "$ref": "#/components/schemas/SearchConditionAgeRating" + }, + { + "$ref": "#/components/schemas/SearchConditionReadStatus" + }, + { + "$ref": "#/components/schemas/SearchConditionSeriesStatus" + }, + { + "$ref": "#/components/schemas/SearchConditionAuthor" + } + ] + }, + "SearchConditionSeriesId": { + "properties": { + "seriesId": { + "$ref": "#/components/schemas/SearchOperatorEqualityString" + } + }, + "required": [ + "seriesId" + ] + }, + "SearchConditionSeriesStatus": { + "properties": { + "seriesStatus": { + "$ref": "#/components/schemas/SearchOperatorEqualityStatus" + } + }, + "required": [ + "seriesStatus" + ] + }, + "SearchConditionSharingLabel": { + "properties": { + "sharingLabel": { + "$ref": "#/components/schemas/SearchOperatorEqualityNullableString" + } + }, + "required": [ + "sharingLabel" + ] + }, + "SearchConditionTag": { + "properties": { + "tag": { + "$ref": "#/components/schemas/SearchOperatorEqualityNullableString" + } + }, + "required": [ + "tag" + ] + }, + "SearchConditionTitle": { + "properties": { + "title": { + "$ref": "#/components/schemas/SearchOperatorString" + } + }, + "required": [ + "title" + ] + }, + "SearchConditionTitleSort": { + "properties": { + "titleSort": { + "$ref": "#/components/schemas/SearchOperatorString" + } + }, + "required": [ + "titleSort" + ] + }, + "SearchOperatorAfter": { + "properties": { + "dateTime": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "dateTime" + ] + }, + "SearchOperatorBefore": { + "properties": { + "dateTime": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "dateTime" + ] + }, + "SearchOperatorBeginsWith": { + "properties": { + "value": { + "type": "string" + } + }, + "required": [ + "value" + ] + }, + "SearchOperatorBoolean": { + "discriminator": { + "mapping": { + "isFalse": "#/components/schemas/SearchOperatorIsFalse", + "isTrue": "#/components/schemas/SearchOperatorIsTrue" + }, + "propertyName": "operator" + }, + "oneOf": [ + { + "$ref": "#/components/schemas/SearchOperatorIsTrue" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsFalse" + } + ], + "properties": { + "operator": { + "type": "string" + } + }, + "required": [ + "operator" + ] + }, + "SearchOperatorContains": { + "properties": { + "value": { + "type": "string" + } + }, + "required": [ + "value" + ] + }, + "SearchOperatorDate": { + "discriminator": { + "mapping": { + "after": "#/components/schemas/SearchOperatorAfter", + "before": "#/components/schemas/SearchOperatorBefore", + "isInTheLast": "#/components/schemas/SearchOperatorIsInTheLast", + "isNotInTheLast": "#/components/schemas/SearchOperatorIsNotInTheLast", + "isNotNull": "#/components/schemas/SearchOperatorIsNotNull", + "isNull": "#/components/schemas/SearchOperatorIsNull" + }, + "propertyName": "operator" + }, + "oneOf": [ + { + "$ref": "#/components/schemas/SearchOperatorBefore" + }, + { + "$ref": "#/components/schemas/SearchOperatorAfter" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsInTheLast" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNotInTheLast" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNull" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNotNull" + } + ], + "properties": { + "operator": { + "type": "string" + } + }, + "required": [ + "operator" + ] + }, + "SearchOperatorDoesNotBeginWith": { + "properties": { + "value": { + "type": "string" + } + }, + "required": [ + "value" + ] + }, + "SearchOperatorDoesNotContain": { + "properties": { + "value": { + "type": "string" + } + }, + "required": [ + "value" + ] + }, + "SearchOperatorDoesNotEndWith": { + "properties": { + "value": { + "type": "string" + } + }, + "required": [ + "value" + ] + }, + "SearchOperatorEndsWith": { + "properties": { + "value": { + "type": "string" + } + }, + "required": [ + "value" + ] + }, + "SearchOperatorEqualityAuthorMatch": { + "discriminator": { + "mapping": { + "is": "#/components/schemas/SearchOperatorIs", + "isNot": "#/components/schemas/SearchOperatorIsNot" + }, + "propertyName": "operator" + }, + "oneOf": [ + { + "$ref": "#/components/schemas/SearchOperatorIs" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNot" + } + ], + "properties": { + "operator": { + "type": "string" + } + }, + "required": [ + "operator" + ] + }, + "SearchOperatorEqualityMediaProfile": { + "discriminator": { + "mapping": { + "is": "#/components/schemas/SearchOperatorIs", + "isNot": "#/components/schemas/SearchOperatorIsNot" + }, + "propertyName": "operator" + }, + "oneOf": [ + { + "$ref": "#/components/schemas/SearchOperatorIs" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNot" + } + ], + "properties": { + "operator": { + "type": "string" + } + }, + "required": [ + "operator" + ] + }, + "SearchOperatorEqualityNullableString": { + "discriminator": { + "mapping": { + "is": "#/components/schemas/SearchOperatorIs", + "isNot": "#/components/schemas/SearchOperatorIsNot", + "isNotNull": "#/components/schemas/SearchOperatorIsNotNullT", + "isNull": "#/components/schemas/SearchOperatorIsNullT" + }, + "propertyName": "operator" + }, + "oneOf": [ + { + "$ref": "#/components/schemas/SearchOperatorIs" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNot" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNullT" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNotNullT" + } + ], + "properties": { + "operator": { + "type": "string" + } + }, + "required": [ + "operator" + ] + }, + "SearchOperatorEqualityPosterMatch": { + "discriminator": { + "mapping": { + "is": "#/components/schemas/SearchOperatorIs", + "isNot": "#/components/schemas/SearchOperatorIsNot" + }, + "propertyName": "operator" + }, + "oneOf": [ + { + "$ref": "#/components/schemas/SearchOperatorIs" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNot" + } + ], + "properties": { + "operator": { + "type": "string" + } + }, + "required": [ + "operator" + ] + }, + "SearchOperatorEqualityReadStatus": { + "discriminator": { + "mapping": { + "is": "#/components/schemas/SearchOperatorIs", + "isNot": "#/components/schemas/SearchOperatorIsNot" + }, + "propertyName": "operator" + }, + "oneOf": [ + { + "$ref": "#/components/schemas/SearchOperatorIs" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNot" + } + ], + "properties": { + "operator": { + "type": "string" + } + }, + "required": [ + "operator" + ] + }, + "SearchOperatorEqualityStatus": { + "discriminator": { + "mapping": { + "is": "#/components/schemas/SearchOperatorIs", + "isNot": "#/components/schemas/SearchOperatorIsNot" + }, + "propertyName": "operator" + }, + "oneOf": [ + { + "$ref": "#/components/schemas/SearchOperatorIs" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNot" + } + ], + "properties": { + "operator": { + "type": "string" + } + }, + "required": [ + "operator" + ] + }, + "SearchOperatorEqualityString": { + "discriminator": { + "mapping": { + "is": "#/components/schemas/SearchOperatorIs", + "isNot": "#/components/schemas/SearchOperatorIsNot" + }, + "propertyName": "operator" + }, + "oneOf": [ + { + "$ref": "#/components/schemas/SearchOperatorIs" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNot" + } + ], + "properties": { + "operator": { + "type": "string" + } + }, + "required": [ + "operator" + ] + }, + "SearchOperatorGreaterThan": { + "properties": { + "value": {} + }, + "required": [ + "value" + ] + }, + "SearchOperatorIs": { + "properties": { + "value": {} + }, + "required": [ + "value" + ] + }, + "SearchOperatorIsFalse": { + "allOf": [ + { + "$ref": "#/components/schemas/SearchOperatorBoolean" + } + ] + }, + "SearchOperatorIsInTheLast": { + "properties": { + "duration": { + "type": "string" + } + }, + "required": [ + "duration" + ] + }, + "SearchOperatorIsNot": { + "properties": { + "value": {} + }, + "required": [ + "value" + ] + }, + "SearchOperatorIsNotInTheLast": { + "properties": { + "duration": { + "type": "string" + } + }, + "required": [ + "duration" + ] + }, + "SearchOperatorIsNotNull": { + "allOf": [ + { + "$ref": "#/components/schemas/SearchOperatorDate" + } + ] + }, + "SearchOperatorIsNotNullT": { + "allOf": [ + { + "$ref": "#/components/schemas/SearchOperatorNumericNullableInteger" + }, + { + "$ref": "#/components/schemas/SearchOperatorEqualityNullableString" + } + ] + }, + "SearchOperatorIsNull": { + "allOf": [ + { + "$ref": "#/components/schemas/SearchOperatorDate" + } + ] + }, + "SearchOperatorIsNullT": { + "allOf": [ + { + "$ref": "#/components/schemas/SearchOperatorNumericNullableInteger" + }, + { + "$ref": "#/components/schemas/SearchOperatorEqualityNullableString" + } + ] + }, + "SearchOperatorIsTrue": { + "allOf": [ + { + "$ref": "#/components/schemas/SearchOperatorBoolean" + } + ] + }, + "SearchOperatorLessThan": { + "properties": { + "value": {} + }, + "required": [ + "value" + ] + }, + "SearchOperatorNumericNullableInteger": { + "discriminator": { + "mapping": { + "greaterThan": "#/components/schemas/SearchOperatorGreaterThan", + "is": "#/components/schemas/SearchOperatorIs", + "isNot": "#/components/schemas/SearchOperatorIsNot", + "isNotNull": "#/components/schemas/SearchOperatorIsNotNullT", + "isNull": "#/components/schemas/SearchOperatorIsNullT", + "lessThan": "#/components/schemas/SearchOperatorLessThan" + }, + "propertyName": "operator" + }, + "oneOf": [ + { + "$ref": "#/components/schemas/SearchOperatorGreaterThan" + }, + { + "$ref": "#/components/schemas/SearchOperatorLessThan" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNullT" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNotNullT" + }, + { + "$ref": "#/components/schemas/SearchOperatorIs" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNot" + } + ], + "properties": { + "operator": { + "type": "string" + } + }, + "required": [ + "operator" + ] + }, + "SearchOperatorNumericTFloat": { + "discriminator": { + "mapping": { + "greaterThan": "#/components/schemas/SearchOperatorGreaterThan", + "is": "#/components/schemas/SearchOperatorIs", + "isNot": "#/components/schemas/SearchOperatorIsNot", + "lessThan": "#/components/schemas/SearchOperatorLessThan" + }, + "propertyName": "operator" + }, + "oneOf": [ + { + "$ref": "#/components/schemas/SearchOperatorGreaterThan" + }, + { + "$ref": "#/components/schemas/SearchOperatorLessThan" + }, + { + "$ref": "#/components/schemas/SearchOperatorIs" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNot" + } + ], + "properties": { + "operator": { + "type": "string" + } + }, + "required": [ + "operator" + ] + }, + "SearchOperatorString": { + "discriminator": { + "mapping": { + "beginsWith": "#/components/schemas/SearchOperatorBeginsWith", + "contains": "#/components/schemas/SearchOperatorContains", + "doesNotBeginWith": "#/components/schemas/SearchOperatorDoesNotBeginWith", + "doesNotContain": "#/components/schemas/SearchOperatorDoesNotContain", + "doesNotEndWith": "#/components/schemas/SearchOperatorDoesNotEndWith", + "endsWith": "#/components/schemas/SearchOperatorEndsWith", + "is": "#/components/schemas/SearchOperatorIs", + "isNot": "#/components/schemas/SearchOperatorIsNot" + }, + "propertyName": "operator" + }, + "oneOf": [ + { + "$ref": "#/components/schemas/SearchOperatorBeginsWith" + }, + { + "$ref": "#/components/schemas/SearchOperatorDoesNotBeginWith" + }, + { + "$ref": "#/components/schemas/SearchOperatorContains" + }, + { + "$ref": "#/components/schemas/SearchOperatorDoesNotContain" + }, + { + "$ref": "#/components/schemas/SearchOperatorEndsWith" + }, + { + "$ref": "#/components/schemas/SearchOperatorDoesNotEndWith" + }, + { + "$ref": "#/components/schemas/SearchOperatorIs" + }, + { + "$ref": "#/components/schemas/SearchOperatorIsNot" + } + ], + "properties": { + "operator": { + "type": "string" + } + }, + "required": [ + "operator" + ] + }, + "SeriesDto": { + "type": "object", + "properties": { + "booksCount": { + "type": "integer", + "format": "int32" + }, + "booksInProgressCount": { + "type": "integer", + "format": "int32" + }, + "booksMetadata": { + "$ref": "#/components/schemas/BookMetadataAggregationDto" + }, + "booksReadCount": { + "type": "integer", + "format": "int32" + }, + "booksUnreadCount": { + "type": "integer", + "format": "int32" + }, + "created": { + "type": "string", + "format": "date-time" + }, + "deleted": { + "type": "boolean" + }, + "fileLastModified": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string" + }, + "lastModified": { + "type": "string", + "format": "date-time" + }, + "libraryId": { + "type": "string" + }, + "metadata": { + "$ref": "#/components/schemas/SeriesMetadataDto" + }, + "name": { + "type": "string" + }, + "oneshot": { + "type": "boolean" + }, + "url": { + "type": "string" + } + }, + "required": [ + "booksCount", + "booksInProgressCount", + "booksMetadata", + "booksReadCount", + "booksUnreadCount", + "created", + "deleted", + "fileLastModified", + "id", + "lastModified", + "libraryId", + "metadata", + "name", + "oneshot", + "url" + ] + }, + "SeriesMetadataDto": { + "type": "object", + "properties": { + "ageRating": { + "type": "integer", + "format": "int32" + }, + "ageRatingLock": { + "type": "boolean" + }, + "alternateTitles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AlternateTitleDto" + } + }, + "alternateTitlesLock": { + "type": "boolean" + }, + "created": { + "type": "string", + "format": "date-time" + }, + "genres": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "genresLock": { + "type": "boolean" + }, + "language": { + "type": "string" + }, + "languageLock": { + "type": "boolean" + }, + "lastModified": { + "type": "string", + "format": "date-time" + }, + "links": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WebLinkDto" + } + }, + "linksLock": { + "type": "boolean" + }, + "publisher": { + "type": "string" + }, + "publisherLock": { + "type": "boolean" + }, + "readingDirection": { + "type": "string" + }, + "readingDirectionLock": { + "type": "boolean" + }, + "sharingLabels": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "sharingLabelsLock": { + "type": "boolean" + }, + "status": { + "type": "string" + }, + "statusLock": { + "type": "boolean" + }, + "summary": { + "type": "string" + }, + "summaryLock": { + "type": "boolean" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "tagsLock": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "titleLock": { + "type": "boolean" + }, + "titleSort": { + "type": "string" + }, + "titleSortLock": { + "type": "boolean" + }, + "totalBookCount": { + "type": "integer", + "format": "int32" + }, + "totalBookCountLock": { + "type": "boolean" + } + }, + "required": [ + "ageRatingLock", + "alternateTitles", + "alternateTitlesLock", + "created", + "genres", + "genresLock", + "language", + "languageLock", + "lastModified", + "links", + "linksLock", + "publisher", + "publisherLock", + "readingDirection", + "readingDirectionLock", + "sharingLabels", + "sharingLabelsLock", + "status", + "statusLock", + "summary", + "summaryLock", + "tags", + "tagsLock", + "title", + "titleLock", + "titleSort", + "titleSortLock", + "totalBookCountLock" + ] + }, + "SeriesMetadataUpdateDto": { + "type": "object", + "description": "Metadata fields to update. Set a field to null to unset the metadata. You can omit fields you don't want to update.", + "properties": { + "ageRating": { + "type": "integer", + "format": "int32" + }, + "ageRatingLock": { + "type": "boolean" + }, + "alternateTitles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AlternateTitleUpdateDto" + } + }, + "alternateTitlesLock": { + "type": "boolean" + }, + "genres": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "genresLock": { + "type": "boolean" + }, + "language": { + "type": "string" + }, + "languageLock": { + "type": "boolean" + }, + "links": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WebLinkUpdateDto" + } + }, + "linksLock": { + "type": "boolean" + }, + "publisher": { + "type": "string" + }, + "publisherLock": { + "type": "boolean" + }, + "readingDirection": { + "type": "string", + "enum": [ + "LEFT_TO_RIGHT", + "RIGHT_TO_LEFT", + "VERTICAL", + "WEBTOON" + ] + }, + "readingDirectionLock": { + "type": "boolean" + }, + "sharingLabels": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "sharingLabelsLock": { + "type": "boolean" + }, + "status": { + "type": "string", + "enum": [ + "ENDED", + "ONGOING", + "ABANDONED", + "HIATUS" + ] + }, + "statusLock": { + "type": "boolean" + }, + "summary": { + "type": "string" + }, + "summaryLock": { + "type": "boolean" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "tagsLock": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "titleLock": { + "type": "boolean" + }, + "titleSort": { + "type": "string" + }, + "titleSortLock": { + "type": "boolean" + }, + "totalBookCount": { + "type": "integer", + "format": "int32" + }, + "totalBookCountLock": { + "type": "boolean" + } + } + }, + "SeriesSearch": { + "type": "object", + "properties": { + "condition": { + "$ref": "#/components/schemas/SearchConditionSeries" + }, + "fullTextSearch": { + "type": "string" + } + } + }, + "SettingMultiSourceInteger": { + "type": "object", + "properties": { + "configurationSource": { + "type": "integer", + "format": "int32" + }, + "databaseSource": { + "type": "integer", + "format": "int32" + }, + "effectiveValue": { + "type": "integer", + "format": "int32" + } + } + }, + "SettingMultiSourceString": { + "type": "object", + "properties": { + "configurationSource": { + "type": "string" + }, + "databaseSource": { + "type": "string" + }, + "effectiveValue": { + "type": "string" + } + } + }, + "SettingsDto": { + "type": "object", + "properties": { + "deleteEmptyCollections": { + "type": "boolean" + }, + "deleteEmptyReadLists": { + "type": "boolean" + }, + "kepubifyPath": { + "$ref": "#/components/schemas/SettingMultiSourceString" + }, + "koboPort": { + "type": "integer", + "format": "int32" + }, + "koboProxy": { + "type": "boolean" + }, + "rememberMeDurationDays": { + "type": "integer", + "format": "int64" + }, + "serverContextPath": { + "$ref": "#/components/schemas/SettingMultiSourceString" + }, + "serverPort": { + "$ref": "#/components/schemas/SettingMultiSourceInteger" + }, + "taskPoolSize": { + "type": "integer", + "format": "int32" + }, + "thumbnailSize": { + "type": "string", + "enum": [ + "DEFAULT", + "MEDIUM", + "LARGE", + "XLARGE" + ] + } + }, + "required": [ + "deleteEmptyCollections", + "deleteEmptyReadLists", + "kepubifyPath", + "koboProxy", + "rememberMeDurationDays", + "serverContextPath", + "serverPort", + "taskPoolSize", + "thumbnailSize" + ] + }, + "SettingsUpdateDto": { + "type": "object", + "description": "Fields to update. You can omit fields you don't want to update.", + "properties": { + "deleteEmptyCollections": { + "type": "boolean" + }, + "deleteEmptyReadLists": { + "type": "boolean" + }, + "kepubifyPath": { + "type": "string", + "deprecated": true, + "description": "Will be removed in a future version" + }, + "koboPort": { + "type": "integer", + "format": "int32", + "maximum": 65535 + }, + "koboProxy": { + "type": "boolean" + }, + "rememberMeDurationDays": { + "type": "integer", + "format": "int64" + }, + "renewRememberMeKey": { + "type": "boolean" + }, + "serverContextPath": { + "type": "string", + "pattern": "^/[\\w-/]*[a-zA-Z0-9]$" + }, + "serverPort": { + "type": "integer", + "format": "int32", + "maximum": 65535 + }, + "taskPoolSize": { + "type": "integer", + "format": "int32" + }, + "thumbnailSize": { + "type": "string", + "enum": [ + "DEFAULT", + "MEDIUM", + "LARGE", + "XLARGE" + ] + } + } + }, + "SharedLibrariesUpdateDto": { + "type": "object", + "properties": { + "all": { + "type": "boolean" + }, + "libraryIds": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + "required": [ + "all", + "libraryIds" + ] + }, + "SortObject": { + "type": "object", + "properties": { + "empty": { + "type": "boolean" + }, + "sorted": { + "type": "boolean" + }, + "unsorted": { + "type": "boolean" + } + } + }, + "StreamingResponseBody": {}, + "TachiyomiReadProgressDto": { + "type": "object", + "properties": { + "booksCount": { + "type": "integer", + "format": "int32" + }, + "booksInProgressCount": { + "type": "integer", + "format": "int32" + }, + "booksReadCount": { + "type": "integer", + "format": "int32" + }, + "booksUnreadCount": { + "type": "integer", + "format": "int32" + }, + "lastReadContinuousIndex": { + "type": "integer", + "format": "int32" + } + }, + "required": [ + "booksCount", + "booksInProgressCount", + "booksReadCount", + "booksUnreadCount", + "lastReadContinuousIndex" + ] + }, + "TachiyomiReadProgressUpdateDto": { + "type": "object", + "properties": { + "lastBookRead": { + "type": "integer", + "format": "int32" + } + }, + "required": [ + "lastBookRead" + ] + }, + "TachiyomiReadProgressUpdateV2Dto": { + "type": "object", + "properties": { + "lastBookNumberSortRead": { + "type": "number", + "format": "float" + } + }, + "required": [ + "lastBookNumberSortRead" + ] + }, + "TachiyomiReadProgressV2Dto": { + "type": "object", + "properties": { + "booksCount": { + "type": "integer", + "format": "int32" + }, + "booksInProgressCount": { + "type": "integer", + "format": "int32" + }, + "booksReadCount": { + "type": "integer", + "format": "int32" + }, + "booksUnreadCount": { + "type": "integer", + "format": "int32" + }, + "lastReadContinuousNumberSort": { + "type": "number", + "format": "float" + }, + "maxNumberSort": { + "type": "number", + "format": "float" + } + }, + "required": [ + "booksCount", + "booksInProgressCount", + "booksReadCount", + "booksUnreadCount", + "lastReadContinuousNumberSort", + "maxNumberSort" + ] + }, + "Text": { + "type": "object", + "properties": { + "after": { + "type": "string" + }, + "before": { + "type": "string" + }, + "highlight": { + "type": "string" + } + } + }, + "ThumbnailBookDto": { + "type": "object", + "properties": { + "bookId": { + "type": "string" + }, + "fileSize": { + "type": "integer", + "format": "int64" + }, + "height": { + "type": "integer", + "format": "int32" + }, + "id": { + "type": "string" + }, + "mediaType": { + "type": "string" + }, + "selected": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "width": { + "type": "integer", + "format": "int32" + } + }, + "required": [ + "bookId", + "fileSize", + "height", + "id", + "mediaType", + "selected", + "type", + "width" + ] + }, + "ThumbnailReadListDto": { + "type": "object", + "properties": { + "fileSize": { + "type": "integer", + "format": "int64" + }, + "height": { + "type": "integer", + "format": "int32" + }, + "id": { + "type": "string" + }, + "mediaType": { + "type": "string" + }, + "readListId": { + "type": "string" + }, + "selected": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "width": { + "type": "integer", + "format": "int32" + } + }, + "required": [ + "fileSize", + "height", + "id", + "mediaType", + "readListId", + "selected", + "type", + "width" + ] + }, + "ThumbnailSeriesCollectionDto": { + "type": "object", + "properties": { + "collectionId": { + "type": "string" + }, + "fileSize": { + "type": "integer", + "format": "int64" + }, + "height": { + "type": "integer", + "format": "int32" + }, + "id": { + "type": "string" + }, + "mediaType": { + "type": "string" + }, + "selected": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "width": { + "type": "integer", + "format": "int32" + } + }, + "required": [ + "collectionId", + "fileSize", + "height", + "id", + "mediaType", + "selected", + "type", + "width" + ] + }, + "ThumbnailSeriesDto": { + "type": "object", + "properties": { + "fileSize": { + "type": "integer", + "format": "int64" + }, + "height": { + "type": "integer", + "format": "int32" + }, + "id": { + "type": "string" + }, + "mediaType": { + "type": "string" + }, + "selected": { + "type": "boolean" + }, + "seriesId": { + "type": "string" + }, + "type": { + "type": "string" + }, + "width": { + "type": "integer", + "format": "int32" + } + }, + "required": [ + "fileSize", + "height", + "id", + "mediaType", + "selected", + "seriesId", + "type", + "width" + ] + }, + "TransientBookDto": { + "type": "object", + "properties": { + "comment": { + "type": "string" + }, + "fileLastModified": { + "type": "string", + "format": "date-time" + }, + "files": { + "type": "array", + "items": { + "type": "string" + } + }, + "id": { + "type": "string" + }, + "mediaType": { + "type": "string" + }, + "name": { + "type": "string" + }, + "number": { + "type": "number", + "format": "float" + }, + "pages": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PageDto" + } + }, + "seriesId": { + "type": "string" + }, + "size": { + "type": "string" + }, + "sizeBytes": { + "type": "integer", + "format": "int64" + }, + "status": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "comment", + "fileLastModified", + "files", + "id", + "mediaType", + "name", + "pages", + "size", + "sizeBytes", + "status", + "url" + ] + }, + "UserCreationDto": { + "type": "object", + "properties": { + "ageRestriction": { + "$ref": "#/components/schemas/AgeRestrictionUpdateDto" + }, + "email": { + "type": "string" + }, + "labelsAllow": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "labelsExclude": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "password": { + "type": "string", + "minLength": 1 + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "sharedLibraries": { + "$ref": "#/components/schemas/SharedLibrariesUpdateDto" + } + }, + "required": [ + "email", + "password", + "roles" + ] + }, + "UserDto": { + "type": "object", + "properties": { + "ageRestriction": { + "$ref": "#/components/schemas/AgeRestrictionDto" + }, + "email": { + "type": "string" + }, + "id": { + "type": "string" + }, + "labelsAllow": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "labelsExclude": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "roles": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "sharedAllLibraries": { + "type": "boolean" + }, + "sharedLibrariesIds": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + }, + "required": [ + "email", + "id", + "labelsAllow", + "labelsExclude", + "roles", + "sharedAllLibraries", + "sharedLibrariesIds" + ] + }, + "UserUpdateDto": { + "type": "object", + "properties": { + "ageRestriction": { + "$ref": "#/components/schemas/AgeRestrictionUpdateDto" + }, + "labelsAllow": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "labelsExclude": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "roles": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, + "sharedLibraries": { + "$ref": "#/components/schemas/SharedLibrariesUpdateDto" + } + } + }, + "ValidationErrorResponse": { + "type": "object", + "properties": { + "violations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Violation" + } + } + }, + "required": [ + "violations" + ] + }, + "Violation": { + "type": "object", + "properties": { + "fieldName": { + "type": "string" + }, + "message": { + "type": "string" + } + } + }, + "WPBelongsToDto": { + "type": "object", + "properties": { + "collection": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WPContributorDto" + } + }, + "series": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WPContributorDto" + } + } + }, + "required": [ + "collection", + "series" + ] + }, + "WPContributorDto": { + "type": "object", + "properties": { + "links": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WPLinkDto" + } + }, + "name": { + "type": "string" + }, + "position": { + "type": "number", + "format": "float" + } + }, + "required": [ + "links", + "name" + ] + }, + "WPLinkDto": { + "type": "object", + "properties": { + "height": { + "type": "integer", + "format": "int32" + }, + "href": { + "type": "string" + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": {} + } + }, + "rel": { + "type": "string" + }, + "templated": { + "type": "boolean" + }, + "title": { + "type": "string" + }, + "type": { + "type": "string" + }, + "width": { + "type": "integer", + "format": "int32" + } + }, + "required": [ + "properties" + ] + }, + "WPMetadataDto": { + "type": "object", + "properties": { + "artist": { + "type": "array", + "items": { + "type": "string" + } + }, + "author": { + "type": "array", + "items": { + "type": "string" + } + }, + "belongsTo": { + "$ref": "#/components/schemas/WPBelongsToDto" + }, + "colorist": { + "type": "array", + "items": { + "type": "string" + } + }, + "conformsTo": { + "type": "string" + }, + "contributor": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": { + "type": "string" + }, + "editor": { + "type": "array", + "items": { + "type": "string" + } + }, + "identifier": { + "type": "string" + }, + "illustrator": { + "type": "array", + "items": { + "type": "string" + } + }, + "inker": { + "type": "array", + "items": { + "type": "string" + } + }, + "language": { + "type": "string" + }, + "letterer": { + "type": "array", + "items": { + "type": "string" + } + }, + "modified": { + "type": "string", + "format": "date-time" + }, + "numberOfPages": { + "type": "integer", + "format": "int32" + }, + "penciler": { + "type": "array", + "items": { + "type": "string" + } + }, + "published": { + "type": "string", + "format": "date" + }, + "publisher": { + "type": "array", + "items": { + "type": "string" + } + }, + "readingProgression": { + "type": "string", + "enum": [ + "rtl", + "ltr", + "ttb", + "btt", + "auto" + ] + }, + "rendition": { + "type": "object", + "additionalProperties": {} + }, + "sortAs": { + "type": "string" + }, + "subject": { + "type": "array", + "items": { + "type": "string" + } + }, + "subtitle": { + "type": "string" + }, + "title": { + "type": "string" + }, + "translator": { + "type": "array", + "items": { + "type": "string" + } + }, + "type": { + "type": "string" + } + }, + "required": [ + "artist", + "author", + "colorist", + "contributor", + "editor", + "illustrator", + "inker", + "letterer", + "penciler", + "publisher", + "rendition", + "subject", + "title", + "translator" + ] + }, + "WPPublicationDto": { + "type": "object", + "properties": { + "context": { + "type": "string" + }, + "images": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WPLinkDto" + } + }, + "landmarks": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WPLinkDto" + } + }, + "links": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WPLinkDto" + } + }, + "metadata": { + "$ref": "#/components/schemas/WPMetadataDto" + }, + "pageList": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WPLinkDto" + } + }, + "readingOrder": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WPLinkDto" + } + }, + "resources": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WPLinkDto" + } + }, + "toc": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WPLinkDto" + } + } + }, + "required": [ + "images", + "landmarks", + "links", + "metadata", + "pageList", + "readingOrder", + "resources", + "toc" + ] + }, + "WebLinkDto": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "required": [ + "label", + "url" + ] + }, + "WebLinkUpdateDto": { + "type": "object", + "properties": { + "label": { + "type": "string", + "minLength": 1 + }, + "url": { + "type": "string" + } + }, + "required": [ + "label" + ] + } + }, + "securitySchemes": { + "apiKey": { + "in": "header", + "name": "X-API-Key", + "type": "apiKey" + }, + "basicAuth": { + "scheme": "basic", + "type": "http" + } + } + }, + "x-tagGroups": [ + { + "name": "Deprecation", + "tags": [ + "Deprecated" + ] + }, + { + "name": "Libraries", + "tags": [ + "Libraries" + ] + }, + { + "name": "Series", + "tags": [ + "Series", + "Series Poster" + ] + }, + { + "name": "Books", + "tags": [ + "Books", + "Book Pages", + "Book Poster", + "Import", + "Duplicate Pages", + "WebPub Manifest", + "Fonts" + ] + }, + { + "name": "Collections", + "tags": [ + "Collections", + "Collection Series", + "Collection Poster" + ] + }, + { + "name": "Readlists", + "tags": [ + "Readlists", + "Readlist Books", + "Readlist Poster" + ] + }, + { + "name": "Referential", + "tags": [ + "Referential metadata" + ] + }, + { + "name": "Users", + "tags": [ + "Current user", + "Users", + "API Keys", + "User session", + "OAuth2", + "Sync points" + ] + }, + { + "name": "Server", + "tags": [ + "Claim", + "Server settings", + "Tasks", + "History", + "File system", + "Releases", + "Announcements", + "Management" + ] + }, + { + "name": "Integrations", + "tags": [ + "Client settings", + "Mihon", + "ComicRack" + ] + } + ] +} diff --git a/scripts/build/docker-compose.build.yml b/scripts/build/docker-compose.build.yml index e13c3b6a4..265b3e4aa 100644 --- a/scripts/build/docker-compose.build.yml +++ b/scripts/build/docker-compose.build.yml @@ -231,8 +231,10 @@ services: gradle build -x test -x spotlessCheck -x spotlessJavaCheck fi cp cs/rest/bibliothek/build/libs/bibliothek-sut.jar /dist/ + cp cs/rest/komga/komga/build/libs/komga-sut.jar /dist/ if [ "$${BUILD_EVOMASTER:-false}" = "true" ]; then cp em/external/rest/bibliothek/build/libs/bibliothek-evomaster-runner.jar /dist/ + cp em/external/rest/komga/build/libs/komga-evomaster-runner.jar /dist/ fi echo 'JDK 17 Gradle build completed' diff --git a/scripts/dist-wb.py b/scripts/dist-wb.py index 9fb8eea8b..f67ce750e 100644 --- a/scripts/dist-wb.py +++ b/scripts/dist-wb.py @@ -383,6 +383,9 @@ def build_jdk_17_gradle(): copy(folder + "/cs/rest/bibliothek/build/libs/bibliothek-sut.jar", DIST) copy(folder + "/em/external/rest/bibliothek/build/libs/bibliothek-evomaster-runner.jar", DIST) + copy(folder + "/cs/rest/komga/komga/build/libs/komga-sut.jar", DIST) + copy(folder + "/em/external/rest/komga/build/libs/komga-evomaster-runner.jar", DIST) + # Building JavaScript projects # def buildJS(path, name): diff --git a/scripts/dockerize/data/sut.csv b/scripts/dockerize/data/sut.csv index 22f2b5a2d..a08fe924e 100644 --- a/scripts/dockerize/data/sut.csv +++ b/scripts/dockerize/data/sut.csv @@ -43,3 +43,4 @@ arimaa,TRUE,,--server.port=8080 --spring.datasource.url=jdbc:mysql://db:3306/ari joinus,TRUE,,--server.port=8080 --spring.mongodb.uri=mongodb://db:27017/joinUs --spring.neo4j.uri=bolt://neo4j:7687 --spring.neo4j.authentication.username=neo4j --spring.neo4j.authentication.password=wfdNeo4jPass123 --logging.level.org.mongodb.driver=INFO --logging.level.org.neo4j.driver=INFO --logging.level.org.springframework.security=INFO,http://localhost:8080/v3/api-docs,http://localhost:8080,FALSE,db;neo4j,"[{""image_name"": ""mongo:7"", ""tmp_fs"": """", ""environment"": """", ""volume"": ""./additional_files/joinus/joinus-mongo-seed.js:/docker-entrypoint-initdb.d/joinus-mongo-seed.js"", ""health_check_command"": ""mongosh --quiet --eval \""db.adminCommand('ping')\""""}, {""name"": ""neo4j"", ""image_name"": ""neo4j:5.26"", ""tmp_fs"": """", ""environment"": ""NEO4J_AUTH: neo4j/wfdNeo4jPass123"", ""volume"": ""./additional_files/joinus/joinus-neo4j-seed.cypher:/seed.cypher"", ""health_check_command"": ""cypher-shell -u neo4j -p wfdNeo4jPass123 \""MATCH (:WfdSeedComplete) RETURN 1\"""", ""command"": ""[\""bash\"", \""-c\"", '/startup/docker-entrypoint.sh neo4j & pid=$!; until cypher-shell -u neo4j -p wfdNeo4jPass123 \""RETURN 1\"" >/dev/null 2>&1; do sleep 2; done; cypher-shell -u neo4j -p wfdNeo4jPass123 -f /seed.cypher; cypher-shell -u neo4j -p wfdNeo4jPass123 \""CREATE (:WfdSeedComplete)\""; wait $pid']""}]" lovemining,TRUE,,--server.port=8080 --spring.data.mongodb.uri=mongodb://db:27017/LoveMining --spring.neo4j.uri=bolt://neo4j:7687 --spring.neo4j.authentication.username=neo4j --spring.neo4j.authentication.password=wfdNeo4jPass123,http://localhost:8080/v3/api-docs,http://localhost:8080,FALSE,db;neo4j,"[{""image_name"": ""mongo:7"", ""tmp_fs"": """", ""environment"": """", ""volume"": ""./additional_files/lovemining/lovemining-mongo-seed.js:/docker-entrypoint-initdb.d/lovemining-mongo-seed.js"", ""health_check_command"": ""mongosh --quiet --eval \""db.adminCommand('ping')\""""}, {""name"": ""neo4j"", ""image_name"": ""neo4j:5.26"", ""tmp_fs"": """", ""environment"": ""NEO4J_AUTH: neo4j/wfdNeo4jPass123"", ""volume"": ""./additional_files/lovemining/lovemining-neo4j-seed.cypher:/seed.cypher"", ""health_check_command"": ""cypher-shell -u neo4j -p wfdNeo4jPass123 \""MATCH (:WfdSeedComplete) RETURN 1\"""", ""command"": ""[\""bash\"", \""-c\"", '/startup/docker-entrypoint.sh neo4j & pid=$!; until cypher-shell -u neo4j -p wfdNeo4jPass123 \""RETURN 1\"" >/dev/null 2>&1; do sleep 2; done; cypher-shell -u neo4j -p wfdNeo4jPass123 -f /seed.cypher; cypher-shell -u neo4j -p wfdNeo4jPass123 \""CREATE (:WfdSeedComplete)\""; wait $pid']""}]" digitalbanking,TRUE,,--server.port=8080 --REDIS_HOST=db --REDIS_PORT=6379 --REDIS_PASSWORD=jasonrocks --redis.host=db --redis.port=6379 --KAFKA_HOST=kafka --KAFKA_PORT=9092 --SPRING_CASSANDRA_HOST=cassandra --SPRING_CASSANDRA_PORT=9042 --SPRING_CASSANDRA_CLUSTER=test --SPRING_CASSANDRA_DATACENTER=datacenter1,http://localhost:8080/v3/api-docs,http://localhost:8080,FALSE,db;cassandra,"[{""image_name"": ""redis/redis-stack-server:7.4.0-v1"", ""tmp_fs"": """", ""environment"": ""REDIS_ARGS: --requirepass jasonrocks"", ""volume"": """", ""health_check_command"": ""redis-cli -a jasonrocks ping | grep PONG""}, {""name"": ""cassandra"", ""image_name"": ""cassandra:4.1"", ""tmp_fs"": """", ""environment"": ""CASSANDRA_CLUSTER_NAME: test;CASSANDRA_DC: datacenter1;CASSANDRA_ENDPOINT_SNITCH: SimpleSnitch;HEAP_NEWSIZE: 128M;MAX_HEAP_SIZE: 512M"", ""volume"": """", ""health_check_command"": ""cqlsh -e \""CREATE KEYSPACE IF NOT EXISTS banking WITH replication = {'class':'SimpleStrategy','replication_factor':1};CREATE TABLE IF NOT EXISTS banking.transaction (tranid text, accountno text, amounttype text, merchant text, referencekeytype text, referencekeyvalue text, originalamount text, amount text, trancd text, description text, initialdate text, settlementdate text, postingdate text, status text, disputeid text, transactionreturn text, location text, transactiontags text, primary key (tranid));\""""}, {""name"": ""kafka"", ""image_name"": ""apache/kafka:3.8.1"", ""tmp_fs"": """", ""environment"": ""KAFKA_NODE_ID: 1;KAFKA_PROCESS_ROLES: broker,controller;KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093;KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092;KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER;KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT;KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093;KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1;KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1;KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1;KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0"", ""volume"": """", ""health_check_command"": """"}]" +komga,TRUE,,--server.port=8080 --komga.config-dir=/tmp/komga --komga.database.file=/komga-database.sqlite,http://localhost:8080/v3/api-docs,http://localhost:8080,TRUE,, diff --git a/statistics/data.csv b/statistics/data.csv index d1a734e3b..b34ad7374 100644 --- a/statistics/data.csv +++ b/statistics/data.csv @@ -53,6 +53,7 @@ TRUE,adoptme,REST,Java,JDK 21,Maven,41,6158,Neo4j,UNDEFINED,14,FALSE,https://git TRUE,arimaa,REST,Java,JDK 21,Maven,141,9460,MySQL;MongoDB;Neo4j,UNDEFINED,38,TRUE,https://github.com/KEAArimaaProject/arimaa-backend TRUE,lovemining,REST,Java,JDK 21,Maven,25,1793,MongoDB;Neo4j,UNDEFINED,18,TRUE,https://github.com/Andryd22/LoveMining TRUE,digitalbanking,REST,Java,JDK 17,Maven,27,2835,Redis;Cassandra,UNDEFINED,55,FALSE,https://github.com/jphaugla/Redisearch-Digital-Banking-redisTemplate +TRUE,komga,REST,Kotlin,JDK 17,Gradle,543,62303,SQLite,MIT,174,TRUE,https://github.com/gotson/komga FALSE,ind0,REST,Java,JDK 8,Gradle,103,17039,PostgreSQL,Proprietary,20,FALSE,UNDEFINED FALSE,ind1,REST,Java;Kotlin,JDK 11,Gradle,163,15240,PostgreSQL,Proprietary,53,FALSE,UNDEFINED diff --git a/statistics/table_emb.md b/statistics/table_emb.md index 9bbdc5c8d..96943940b 100644 --- a/statistics/table_emb.md +++ b/statistics/table_emb.md @@ -24,6 +24,7 @@ |REST|__http-patch-spring__|1450|30|6|Java|JDK 11|Maven||| |REST|__jasper__|46791|337|61|Java|JDK 25|Maven|PostgreSQL|✓| |REST|__joinus__|7906|101|37|Java|JDK 21|Maven|MongoDB, Neo4j|✓| +|REST|__komga__|62303|543|174|Kotlin|JDK 17|Gradle|SQLite|✓| |REST|__languagetool__|174781|1385|2|Java|JDK 8|Maven||| |REST|__lovemining__|1793|25|18|Java|JDK 21|Maven|MongoDB, Neo4j|✓| |REST|__market__|9861|124|13|Java|JDK 11|Maven|H2|✓|