Compare commits
46 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a325440f24 | |||
| 14072bb5a0 | |||
| 7fc33ba8db | |||
| 47e51b6615 | |||
| 857562eaff | |||
| bace854b50 | |||
| e4a404472d | |||
| 7bfa215b4c | |||
| ab7af4b80b | |||
| 2c7ebd8ece | |||
| c96da79058 | |||
| 8f09ebacf5 | |||
| e21f3b9c75 | |||
| 37eeef06e2 | |||
| b7fe56687c | |||
| 60565729ca | |||
| 36f4e1c340 | |||
| abc2a5214b | |||
| a29010e0d7 | |||
| db99ab66ae | |||
| 84cc73c149 | |||
| 10a29cab33 | |||
| 849e2f103a | |||
| 6c22fe193a | |||
| e69dbbf418 | |||
| dfa59a1691 | |||
| 5023e96301 | |||
| 224c24ee9f | |||
| e3b154cf9e | |||
| d249867c4c | |||
| b56045e984 | |||
| 3777cc646e | |||
| aa5a1083d0 | |||
| 2ae5e0742e | |||
| e5e875c54a | |||
| 1a99ec76e4 | |||
| 1b122d1157 | |||
| 77f2f8cc18 | |||
| f0a99980b6 | |||
| b0d43ffe69 | |||
| 16cb0184a4 | |||
| f211a33ea3 | |||
| 440c815189 | |||
| 25829aacfd | |||
| 700a739f95 | |||
| d9620bec05 |
@@ -23,7 +23,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Cancel previous runs
|
- name: Cancel previous runs
|
||||||
uses: styfle/cancel-workflow-action@0.5.0
|
uses: styfle/cancel-workflow-action@0.9.0
|
||||||
with:
|
with:
|
||||||
access_token: ${{ github.token }}
|
access_token: ${{ github.token }}
|
||||||
|
|
||||||
@@ -48,14 +48,14 @@ jobs:
|
|||||||
- name: Download android.jar
|
- name: Download android.jar
|
||||||
run: |
|
run: |
|
||||||
cd master
|
cd master
|
||||||
curl https://raw.githubusercontent.com/AriaMoradi/Tachidesk/android-jar/android.jar -o AndroidCompat/lib/android.jar
|
curl https://raw.githubusercontent.com/Suwayomi/Tachidesk/android-jar/android.jar -o AndroidCompat/lib/android.jar
|
||||||
|
|
||||||
- name: Cache node_modules
|
- name: Cache node_modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
**/react/node_modules
|
**/webUI/node_modules
|
||||||
key: ${{ runner.os }}-${{ hashFiles('**/react/yarn.lock') }}
|
key: ${{ runner.os }}-${{ hashFiles('**/webUI/yarn.lock') }}
|
||||||
|
|
||||||
- name: Build and copy webUI, Build Jar
|
- name: Build and copy webUI, Build Jar
|
||||||
uses: eskatos/gradle-command-action@v1
|
uses: eskatos/gradle-command-action@v1
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Cancel previous runs
|
- name: Cancel previous runs
|
||||||
uses: styfle/cancel-workflow-action@0.5.0
|
uses: styfle/cancel-workflow-action@0.9.0
|
||||||
with:
|
with:
|
||||||
access_token: ${{ github.token }}
|
access_token: ${{ github.token }}
|
||||||
|
|
||||||
@@ -50,19 +50,19 @@ jobs:
|
|||||||
- name: Download android.jar
|
- name: Download android.jar
|
||||||
run: |
|
run: |
|
||||||
cd master
|
cd master
|
||||||
curl https://raw.githubusercontent.com/AriaMoradi/Tachidesk/android-jar/android.jar -o AndroidCompat/lib/android.jar
|
curl https://raw.githubusercontent.com/Suwayomi/Tachidesk/android-jar/android.jar -o AndroidCompat/lib/android.jar
|
||||||
|
|
||||||
- name: Cache node_modules
|
- name: Cache node_modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
**/react/node_modules
|
**/webUI/node_modules
|
||||||
key: ${{ runner.os }}-${{ hashFiles('**/react/yarn.lock') }}
|
key: ${{ runner.os }}-${{ hashFiles('**/webUI/yarn.lock') }}
|
||||||
|
|
||||||
- name: Build and copy webUI, Build Jar
|
- name: Build and copy webUI, Build Jar
|
||||||
uses: eskatos/gradle-command-action@v1
|
uses: eskatos/gradle-command-action@v1
|
||||||
env:
|
env:
|
||||||
TachideskBuildType: "Preview"
|
ProductBuildType: "Preview"
|
||||||
with:
|
with:
|
||||||
build-root-directory: master
|
build-root-directory: master
|
||||||
wrapper-directory: master
|
wrapper-directory: master
|
||||||
@@ -127,3 +127,7 @@ jobs:
|
|||||||
owner: "Suwayomi"
|
owner: "Suwayomi"
|
||||||
repo: "Tachidesk-preview"
|
repo: "Tachidesk-preview"
|
||||||
tag: ${{ steps.GenTagName.outputs.value }}
|
tag: ${{ steps.GenTagName.outputs.value }}
|
||||||
|
|
||||||
|
- name: Run Docker build workflow
|
||||||
|
run: |
|
||||||
|
curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.DEPLOY_PREVIEW_TOKEN }}" -d '{"ref":"main", "inputs":{"tachidesk_release_type": "preview"}}' https://api.github.com/repos/suwayomi/docker-tachidesk/actions/workflows/build_container_images.yml/dispatches
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Cancel previous runs
|
- name: Cancel previous runs
|
||||||
uses: styfle/cancel-workflow-action@0.5.0
|
uses: styfle/cancel-workflow-action@0.9.0
|
||||||
with:
|
with:
|
||||||
access_token: ${{ github.token }}
|
access_token: ${{ github.token }}
|
||||||
|
|
||||||
@@ -49,19 +49,19 @@ jobs:
|
|||||||
- name: Download android.jar
|
- name: Download android.jar
|
||||||
run: |
|
run: |
|
||||||
cd master
|
cd master
|
||||||
curl https://raw.githubusercontent.com/AriaMoradi/Tachidesk/android-jar/android.jar -o AndroidCompat/lib/android.jar
|
curl https://raw.githubusercontent.com/Suwayomi/Tachidesk/android-jar/android.jar -o AndroidCompat/lib/android.jar
|
||||||
|
|
||||||
- name: Cache node_modules
|
- name: Cache node_modules
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
**/react/node_modules
|
**/webUI/node_modules
|
||||||
key: ${{ runner.os }}-${{ hashFiles('**/react/yarn.lock') }}
|
key: ${{ runner.os }}-${{ hashFiles('**/webUI/yarn.lock') }}
|
||||||
|
|
||||||
- name: Build and copy webUI, Build Jar
|
- name: Build and copy webUI, Build Jar
|
||||||
uses: eskatos/gradle-command-action@v1
|
uses: eskatos/gradle-command-action@v1
|
||||||
env:
|
env:
|
||||||
TachideskBuildType: "Stable"
|
ProductBuildType: "Stable"
|
||||||
with:
|
with:
|
||||||
build-root-directory: master
|
build-root-directory: master
|
||||||
wrapper-directory: master
|
wrapper-directory: master
|
||||||
@@ -85,3 +85,8 @@ jobs:
|
|||||||
tags: true
|
tags: true
|
||||||
draft: true
|
draft: true
|
||||||
verbose: true
|
verbose: true
|
||||||
|
|
||||||
|
- name: Run Docker build workflow
|
||||||
|
run: |
|
||||||
|
curl -X POST -H "Accept: application/vnd.github.v3+json" -H "Authorization: token ${{ secrets.DEPLOY_PREVIEW_TOKEN }}" -d '{"ref":"main", "inputs":{"tachidesk_release_type": "stable"}}' https://api.github.com/repos/suwayomi/docker-tachidesk/actions/workflows/build_container_images.yml/dispatches
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ gradle.properties
|
|||||||
# Ignore Gradle build output directory
|
# Ignore Gradle build output directory
|
||||||
build
|
build
|
||||||
|
|
||||||
server/src/main/resources/react
|
server/src/main/resources/webUI
|
||||||
server/tmp/
|
server/tmp/
|
||||||
server/tachiserver-data/
|
server/tachiserver-data/
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import net.harawata.appdirs.AppDirsFactory
|
|||||||
val ApplicationRootDir: String
|
val ApplicationRootDir: String
|
||||||
get(): String {
|
get(): String {
|
||||||
return System.getProperty(
|
return System.getProperty(
|
||||||
"suwayomi.server.rootDir",
|
"suwayomi.tachidesk.server.rootDir",
|
||||||
AppDirsFactory.getInstance().getUserDataDir("Tachidesk", null, null)
|
AppDirsFactory.getInstance().getUserDataDir("Tachidesk", null, null)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -17,4 +17,4 @@ fun setLogLevel(level: Level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun debugLogsEnabled(config: Config)
|
fun debugLogsEnabled(config: Config)
|
||||||
= System.getProperty("suwayomi.server.debugLogsEnabled", config.getString("server.debugLogsEnabled")).toBoolean()
|
= System.getProperty("suwayomi.tachidesk.server.debugLogsEnabled", config.getString("server.debugLogsEnabled")).toBoolean()
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
application
|
application
|
||||||
|
kotlin("plugin.serialization")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -46,6 +47,17 @@ dependencies {
|
|||||||
implementation("org.mozilla:rhino-runtime:1.7.13")
|
implementation("org.mozilla:rhino-runtime:1.7.13")
|
||||||
// 'org.mozilla:rhino-engine' provides the same interface as 'javax.script' a.k.a Nashorn
|
// 'org.mozilla:rhino-engine' provides the same interface as 'javax.script' a.k.a Nashorn
|
||||||
implementation("org.mozilla:rhino-engine:1.7.13")
|
implementation("org.mozilla:rhino-engine:1.7.13")
|
||||||
|
|
||||||
|
// Kotlin wrapper around Java Preferences, makes certain things easier
|
||||||
|
val multiplatformSettingsVersion = "0.7.7"
|
||||||
|
implementation("com.russhwolf:multiplatform-settings-jvm:$multiplatformSettingsVersion")
|
||||||
|
implementation("com.russhwolf:multiplatform-settings-serialization-jvm:$multiplatformSettingsVersion")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||||
|
kotlinOptions.freeCompilerArgs = listOf("-Xopt-in=kotlin.RequiresOptIn")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//def fatJarTask = tasks.getByPath(':AndroidCompat:JVMPatch:fatJar')
|
//def fatJarTask = tasks.getByPath(':AndroidCompat:JVMPatch:fatJar')
|
||||||
|
|||||||
+9
-10
@@ -38,7 +38,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import xyz.nulldev.androidcompat.info.ApplicationInfoImpl;
|
import xyz.nulldev.androidcompat.info.ApplicationInfoImpl;
|
||||||
import xyz.nulldev.androidcompat.io.AndroidFiles;
|
import xyz.nulldev.androidcompat.io.AndroidFiles;
|
||||||
import xyz.nulldev.androidcompat.io.sharedprefs.JsonSharedPreferences;
|
import xyz.nulldev.androidcompat.io.sharedprefs.JavaSharedPreferences;
|
||||||
import xyz.nulldev.androidcompat.service.ServiceSupport;
|
import xyz.nulldev.androidcompat.service.ServiceSupport;
|
||||||
import xyz.nulldev.androidcompat.util.KodeinGlobalHelper;
|
import xyz.nulldev.androidcompat.util.KodeinGlobalHelper;
|
||||||
|
|
||||||
@@ -165,23 +165,22 @@ public class CustomContext extends Context implements DIAware {
|
|||||||
/** Fake shared prefs! **/
|
/** Fake shared prefs! **/
|
||||||
private Map<String, SharedPreferences> prefs = new HashMap<>(); //Cache
|
private Map<String, SharedPreferences> prefs = new HashMap<>(); //Cache
|
||||||
|
|
||||||
private File sharedPrefsFileFromString(String s) {
|
|
||||||
return new File(androidFiles.getPrefsDir(), s + ".json");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized SharedPreferences getSharedPreferences(String s, int i) {
|
public synchronized SharedPreferences getSharedPreferences(String s, int i) {
|
||||||
SharedPreferences preferences = prefs.get(s);
|
SharedPreferences preferences = prefs.get(s);
|
||||||
//Create new shared preferences if one does not exist
|
//Create new shared preferences if one does not exist
|
||||||
if(preferences == null) {
|
if(preferences == null) {
|
||||||
preferences = getSharedPreferences(sharedPrefsFileFromString(s), i);
|
preferences = new JavaSharedPreferences(s);
|
||||||
prefs.put(s, preferences);
|
prefs.put(s, preferences);
|
||||||
}
|
}
|
||||||
return preferences;
|
return preferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SharedPreferences getSharedPreferences(File file, int mode) {
|
@Override
|
||||||
return new JsonSharedPreferences(file);
|
public SharedPreferences getSharedPreferences(@NotNull File file, int mode) {
|
||||||
|
String path = file.getAbsolutePath().replace('\\', '/');
|
||||||
|
int firstSlash = path.indexOf("/");
|
||||||
|
return new JavaSharedPreferences(path.substring(firstSlash));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -191,8 +190,8 @@ public class CustomContext extends Context implements DIAware {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean deleteSharedPreferences(String name) {
|
public boolean deleteSharedPreferences(String name) {
|
||||||
prefs.remove(name);
|
JavaSharedPreferences item = (JavaSharedPreferences) prefs.remove(name);
|
||||||
return sharedPrefsFileFromString(name).delete();
|
return item.deleteAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -26,8 +26,6 @@ class AndroidFiles(val configManager: ConfigManager = GlobalConfigManager) {
|
|||||||
val downloadCacheDir: File get() = registerFile(filesConfig.downloadCacheDir)
|
val downloadCacheDir: File get() = registerFile(filesConfig.downloadCacheDir)
|
||||||
val databasesDir: File get() = registerFile(filesConfig.databasesDir)
|
val databasesDir: File get() = registerFile(filesConfig.databasesDir)
|
||||||
|
|
||||||
val prefsDir: File get() = registerFile(filesConfig.prefsDir)
|
|
||||||
|
|
||||||
val packagesDir: File get() = registerFile(filesConfig.packageDir)
|
val packagesDir: File get() = registerFile(filesConfig.packageDir)
|
||||||
|
|
||||||
fun registerFile(file: String): File {
|
fun registerFile(file: String): File {
|
||||||
|
|||||||
+168
@@ -0,0 +1,168 @@
|
|||||||
|
package xyz.nulldev.androidcompat.io.sharedprefs
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
|
import com.russhwolf.settings.ExperimentalSettingsApi
|
||||||
|
import com.russhwolf.settings.ExperimentalSettingsImplementation
|
||||||
|
import com.russhwolf.settings.JvmPreferencesSettings
|
||||||
|
import com.russhwolf.settings.serialization.decodeValue
|
||||||
|
import com.russhwolf.settings.serialization.encodeValue
|
||||||
|
import com.russhwolf.settings.set
|
||||||
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
|
import kotlinx.serialization.SerializationException
|
||||||
|
import kotlinx.serialization.builtins.SetSerializer
|
||||||
|
import kotlinx.serialization.builtins.nullable
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
import java.util.prefs.PreferenceChangeListener
|
||||||
|
import java.util.prefs.Preferences
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSettingsImplementation::class, ExperimentalSerializationApi::class, ExperimentalSettingsApi::class)
|
||||||
|
class JavaSharedPreferences(key: String) : SharedPreferences {
|
||||||
|
private val javaPreferences = Preferences.userRoot().node("suwayomi/tachidesk/$key")
|
||||||
|
private val preferences = JvmPreferencesSettings(javaPreferences)
|
||||||
|
private val listeners = mutableMapOf<SharedPreferences.OnSharedPreferenceChangeListener, PreferenceChangeListener>()
|
||||||
|
|
||||||
|
// TODO: 2021-05-29 Need to find a way to get this working with all pref types
|
||||||
|
override fun getAll(): MutableMap<String, *> {
|
||||||
|
return preferences.keys.associateWith { preferences.getStringOrNull(it) }.toMutableMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getString(key: String, defValue: String?): String? {
|
||||||
|
return if (defValue != null) {
|
||||||
|
preferences.getString(key, defValue)
|
||||||
|
} else {
|
||||||
|
preferences.getStringOrNull(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getStringSet(key: String, defValues: MutableSet<String>?): MutableSet<String>? {
|
||||||
|
try {
|
||||||
|
return if (defValues != null) {
|
||||||
|
preferences.decodeValue(SetSerializer(String.serializer()).nullable, key, defValues)
|
||||||
|
} else {
|
||||||
|
preferences.decodeValue(SetSerializer(String.serializer()).nullable, key, null)
|
||||||
|
}?.toMutableSet()
|
||||||
|
} catch (e: SerializationException) {
|
||||||
|
throw ClassCastException("$key was not a StringSet")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInt(key: String, defValue: Int): Int {
|
||||||
|
return preferences.getInt(key, defValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLong(key: String, defValue: Long): Long {
|
||||||
|
return preferences.getLong(key, defValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFloat(key: String, defValue: Float): Float {
|
||||||
|
return preferences.getFloat(key, defValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBoolean(key: String, defValue: Boolean): Boolean {
|
||||||
|
return preferences.getBoolean(key, defValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun contains(key: String): Boolean {
|
||||||
|
return key in preferences.keys
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun edit(): SharedPreferences.Editor {
|
||||||
|
return Editor(preferences)
|
||||||
|
}
|
||||||
|
|
||||||
|
class Editor(private val preferences: JvmPreferencesSettings) : SharedPreferences.Editor {
|
||||||
|
val itemsToAdd = mutableMapOf<String, Any>()
|
||||||
|
|
||||||
|
override fun putString(key: String, value: String?): SharedPreferences.Editor {
|
||||||
|
if (value != null) {
|
||||||
|
itemsToAdd[key] = value
|
||||||
|
} else {
|
||||||
|
remove(key)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putStringSet(
|
||||||
|
key: String,
|
||||||
|
values: MutableSet<String>?
|
||||||
|
): SharedPreferences.Editor {
|
||||||
|
if (values != null) {
|
||||||
|
itemsToAdd[key] = values
|
||||||
|
} else {
|
||||||
|
remove(key)
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putInt(key: String, value: Int): SharedPreferences.Editor {
|
||||||
|
itemsToAdd[key] = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putLong(key: String, value: Long): SharedPreferences.Editor {
|
||||||
|
itemsToAdd[key] = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putFloat(key: String, value: Float): SharedPreferences.Editor {
|
||||||
|
itemsToAdd[key] = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun putBoolean(key: String, value: Boolean): SharedPreferences.Editor {
|
||||||
|
itemsToAdd[key] = value
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove(key: String): SharedPreferences.Editor {
|
||||||
|
itemsToAdd.remove(key)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun clear(): SharedPreferences.Editor {
|
||||||
|
itemsToAdd.clear()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun commit(): Boolean {
|
||||||
|
addToPreferences()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun apply() {
|
||||||
|
addToPreferences()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addToPreferences() {
|
||||||
|
itemsToAdd.forEach { (key, value) ->
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
when (value) {
|
||||||
|
is Set<*> -> preferences.encodeValue(SetSerializer(String.serializer()), key, value as Set<String>)
|
||||||
|
else -> {
|
||||||
|
preferences[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun registerOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener) {
|
||||||
|
val javaListener = PreferenceChangeListener {
|
||||||
|
listener.onSharedPreferenceChanged(this, it.key)
|
||||||
|
}
|
||||||
|
listeners[listener] = javaListener
|
||||||
|
javaPreferences.addPreferenceChangeListener(javaListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregisterOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener) {
|
||||||
|
val registeredListener = listeners.remove(listener)
|
||||||
|
if (registeredListener != null) {
|
||||||
|
javaPreferences.removePreferenceChangeListener(registeredListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteAll(): Boolean {
|
||||||
|
javaPreferences.removeNode()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ Here is a list of current features:
|
|||||||
- A library to save your mangas and categories to put them into.
|
- A library to save your mangas and categories to put them into.
|
||||||
- Searching and browsing installed sources.
|
- Searching and browsing installed sources.
|
||||||
- A decent chapter reader.
|
- A decent chapter reader.
|
||||||
- Ability to download Mangas for offline read(This partially works)
|
- Ability to download Mangas for offline read
|
||||||
- Backup and restore support powered by Tachiyomi Legacy Backups
|
- Backup and restore support powered by Tachiyomi Legacy Backups
|
||||||
|
|
||||||
**Note:** Keep in mind that Tachidesk is alpha software and can break rarely and/or with each update. See [Troubleshooting](https://github.com/Suwayomi/Tachidesk/wiki/Troubleshooting) if it happens.
|
**Note:** Keep in mind that Tachidesk is alpha software and can break rarely and/or with each update. See [Troubleshooting](https://github.com/Suwayomi/Tachidesk/wiki/Troubleshooting) if it happens.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.4.32"
|
kotlin("jvm") version "1.4.32"
|
||||||
|
kotlin("plugin.serialization") version "1.4.32" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
@@ -50,6 +51,10 @@ configure(projects) {
|
|||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$coroutinesVersion")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$coroutinesVersion")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutinesVersion")
|
||||||
|
|
||||||
|
val kotlinSerializationVersion = "1.1.0"
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinSerializationVersion")
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-serialization-protobuf:$kotlinSerializationVersion")
|
||||||
|
|
||||||
|
|
||||||
// Dependency Injection
|
// Dependency Injection
|
||||||
implementation("org.kodein.di:kodein-di-conf-jvm:7.5.0")
|
implementation("org.kodein.di:kodein-di-conf-jvm:7.5.0")
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
jre\bin\java -Dsuwayomi.server.debugLogsEnabled=true -jar Tachidesk.jar
|
jre\bin\java -Dsuwayomi.tachidesk.server.debugLogsEnabled=true -jar Tachidesk.jar
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
jre\bin\javaw "-Dsuwayomi.server.webInterface=electron" "-Dsuwayomi.server.electronPath=electron/electron.exe" -jar Tachidesk.jar
|
jre\bin\javaw "-Dsuwayomi.tachidesk.server.webInterface=electron" "-Dsuwayomi.tachidesk.server.electronPath=electron/electron.exe" -jar Tachidesk.jar
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ jre_dir="jdk8u292-b10-jre"
|
|||||||
|
|
||||||
echo "creating windows bundle"
|
echo "creating windows bundle"
|
||||||
|
|
||||||
jar=$(ls ../server/build/Tachidesk-*.jar)
|
jar=$(ls ../server/build/*.jar | tail -n1)
|
||||||
jar_name=$(echo $jar | cut -d'/' -f4)
|
jar_name=$(echo $jar | cut -d'/' -f4)
|
||||||
release_name=$(echo $jar_name | cut -d'.' -f4 --complement)-$arch
|
release_name=$(echo $jar_name | sed 's/.jar//')-$arch
|
||||||
|
|
||||||
|
|
||||||
# make release dir
|
# make release dir
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ dependencies {
|
|||||||
testImplementation(kotlin("test-junit5"))
|
testImplementation(kotlin("test-junit5"))
|
||||||
}
|
}
|
||||||
|
|
||||||
val MainClass = "suwayomi.MainKt"
|
val MainClass = "suwayomi.tachidesk.MainKt"
|
||||||
application {
|
application {
|
||||||
mainClass.set(MainClass)
|
mainClass.set(MainClass)
|
||||||
|
|
||||||
@@ -93,11 +93,11 @@ sourceSets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// should be bumped with each stable release
|
// should be bumped with each stable release
|
||||||
val tachideskVersion = "v0.4.0"
|
val tachideskVersion = System.getenv("ProductVersion") ?: "v0.4.3"
|
||||||
|
|
||||||
// counts commit count on master
|
// counts commit count on master
|
||||||
val tachideskRevision = runCatching {
|
val tachideskRevision = runCatching {
|
||||||
Runtime
|
System.getenv("ProductRevision") ?: Runtime
|
||||||
.getRuntime()
|
.getRuntime()
|
||||||
.exec("git rev-list HEAD --count")
|
.exec("git rev-list HEAD --count")
|
||||||
.let { process ->
|
.let { process ->
|
||||||
@@ -107,7 +107,6 @@ val tachideskRevision = runCatching {
|
|||||||
}
|
}
|
||||||
process.destroy()
|
process.destroy()
|
||||||
"r" + output.trim()
|
"r" + output.trim()
|
||||||
|
|
||||||
}
|
}
|
||||||
}.getOrDefault("r0")
|
}.getOrDefault("r0")
|
||||||
|
|
||||||
@@ -119,7 +118,7 @@ buildConfig {
|
|||||||
buildConfigField("String", "NAME", rootProject.name)
|
buildConfigField("String", "NAME", rootProject.name)
|
||||||
buildConfigField("String", "VERSION", tachideskVersion)
|
buildConfigField("String", "VERSION", tachideskVersion)
|
||||||
buildConfigField("String", "REVISION", tachideskRevision)
|
buildConfigField("String", "REVISION", tachideskRevision)
|
||||||
buildConfigField("String", "BUILD_TYPE", if (System.getenv("TachideskBuildType") == "Stable") "Stable" else "Preview")
|
buildConfigField("String", "BUILD_TYPE", if (System.getenv("ProductBuildType") == "Stable") "Stable" else "Preview")
|
||||||
buildConfigField("long", "BUILD_TIME", Instant.now().epochSecond.toString())
|
buildConfigField("long", "BUILD_TIME", Instant.now().epochSecond.toString())
|
||||||
|
|
||||||
buildConfigField("String", "GITHUB", "https://github.com/Suwayomi/Tachidesk")
|
buildConfigField("String", "GITHUB", "https://github.com/Suwayomi/Tachidesk")
|
||||||
|
|||||||
+5
-5
@@ -1,7 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.source
|
package eu.kanade.tachiyomi.animesource
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.source.model.AnimesPage
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
|
||||||
interface AnimeCatalogueSource : AnimeSource {
|
interface AnimeCatalogueSource : AnimeSource {
|
||||||
@@ -30,7 +30,7 @@ interface AnimeCatalogueSource : AnimeSource {
|
|||||||
* @param query the search query.
|
* @param query the search query.
|
||||||
* @param filters the list of filters to apply.
|
* @param filters the list of filters to apply.
|
||||||
*/
|
*/
|
||||||
fun fetchSearchAnime(page: Int, query: String, filters: FilterList): Observable<AnimesPage>
|
fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable<AnimesPage>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an observable containing a page with a list of latest anime updates.
|
* Returns an observable containing a page with a list of latest anime updates.
|
||||||
@@ -42,5 +42,5 @@ interface AnimeCatalogueSource : AnimeSource {
|
|||||||
/**
|
/**
|
||||||
* Returns the list of filters for the source.
|
* Returns the list of filters for the source.
|
||||||
*/
|
*/
|
||||||
fun getFilterList(): FilterList
|
fun getFilterList(): AnimeFilterList
|
||||||
}
|
}
|
||||||
+3
-3
@@ -1,7 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.source
|
package eu.kanade.tachiyomi.animesource
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.source.model.SAnime
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package eu.kanade.tachiyomi.source
|
package eu.kanade.tachiyomi.animesource
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A factory for creating sources at runtime.
|
* A factory for creating sources at runtime.
|
||||||
+4
-4
@@ -1,9 +1,9 @@
|
|||||||
package eu.kanade.tachiyomi.source
|
package eu.kanade.tachiyomi.animesource
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import eu.kanade.tachiyomi.source.model.SAnime
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||||
import eu.kanade.tachiyomi.source.online.AnimeHttpSource
|
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
|
||||||
open class AnimeSourceManager(private val context: Context) {
|
open class AnimeSourceManager(private val context: Context) {
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package eu.kanade.tachiyomi.source
|
package eu.kanade.tachiyomi.animesource
|
||||||
|
|
||||||
import android.support.v7.preference.PreferenceScreen
|
import android.support.v7.preference.PreferenceScreen
|
||||||
|
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package eu.kanade.tachiyomi.animesource.model
|
||||||
|
|
||||||
|
sealed class AnimeFilter<T>(val name: String, var state: T) {
|
||||||
|
open class Header(name: String) : AnimeFilter<Any>(name, 0)
|
||||||
|
open class Separator(name: String = "") : AnimeFilter<Any>(name, 0)
|
||||||
|
abstract class Select<V>(name: String, val values: Array<V>, state: Int = 0) : AnimeFilter<Int>(name, state)
|
||||||
|
abstract class Text(name: String, state: String = "") : AnimeFilter<String>(name, state)
|
||||||
|
abstract class CheckBox(name: String, state: Boolean = false) : AnimeFilter<Boolean>(name, state)
|
||||||
|
abstract class TriState(name: String, state: Int = STATE_IGNORE) : AnimeFilter<Int>(name, state) {
|
||||||
|
fun isIgnored() = state == STATE_IGNORE
|
||||||
|
fun isIncluded() = state == STATE_INCLUDE
|
||||||
|
fun isExcluded() = state == STATE_EXCLUDE
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val STATE_IGNORE = 0
|
||||||
|
const val STATE_INCLUDE = 1
|
||||||
|
const val STATE_EXCLUDE = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Group<V>(name: String, state: List<V>) : AnimeFilter<List<V>>(name, state)
|
||||||
|
|
||||||
|
abstract class Sort(name: String, val values: Array<String>, state: Selection? = null) :
|
||||||
|
AnimeFilter<Sort.Selection?>(name, state) {
|
||||||
|
data class Selection(val index: Int, val ascending: Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is AnimeFilter<*>) return false
|
||||||
|
|
||||||
|
return name == other.name && state == other.state
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = name.hashCode()
|
||||||
|
result = 31 * result + (state?.hashCode() ?: 0)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package eu.kanade.tachiyomi.animesource.model
|
||||||
|
|
||||||
|
data class AnimeFilterList(val list: List<AnimeFilter<*>>) : List<AnimeFilter<*>> by list {
|
||||||
|
|
||||||
|
constructor(vararg fs: AnimeFilter<*>) : this(if (fs.isNotEmpty()) fs.asList() else emptyList())
|
||||||
|
}
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
package eu.kanade.tachiyomi.source.model
|
package eu.kanade.tachiyomi.animesource.model
|
||||||
|
|
||||||
data class AnimesPage(val animes: List<SAnime>, val hasNextPage: Boolean)
|
data class AnimesPage(val animes: List<SAnime>, val hasNextPage: Boolean)
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package eu.kanade.tachiyomi.source.model
|
package eu.kanade.tachiyomi.animesource.model
|
||||||
|
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package eu.kanade.tachiyomi.source.model
|
package eu.kanade.tachiyomi.animesource.model
|
||||||
|
|
||||||
class SAnimeImpl : SAnime {
|
class SAnimeImpl : SAnime {
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package eu.kanade.tachiyomi.source.model
|
package eu.kanade.tachiyomi.animesource.model
|
||||||
|
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package eu.kanade.tachiyomi.source.model
|
package eu.kanade.tachiyomi.animesource.model
|
||||||
|
|
||||||
class SEpisodeImpl : SEpisode {
|
class SEpisodeImpl : SEpisode {
|
||||||
|
|
||||||
+9
-9
@@ -1,15 +1,15 @@
|
|||||||
package eu.kanade.tachiyomi.source.online
|
package eu.kanade.tachiyomi.animesource.online
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.AnimeFilterList
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||||
import eu.kanade.tachiyomi.network.newCallWithProgress
|
import eu.kanade.tachiyomi.network.newCallWithProgress
|
||||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
|
||||||
import eu.kanade.tachiyomi.source.model.AnimesPage
|
|
||||||
import eu.kanade.tachiyomi.source.model.FilterList
|
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.source.model.SAnime
|
|
||||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
@@ -118,7 +118,7 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||||||
* @param query the search query.
|
* @param query the search query.
|
||||||
* @param filters the list of filters to apply.
|
* @param filters the list of filters to apply.
|
||||||
*/
|
*/
|
||||||
override fun fetchSearchAnime(page: Int, query: String, filters: FilterList): Observable<AnimesPage> {
|
override fun fetchSearchAnime(page: Int, query: String, filters: AnimeFilterList): Observable<AnimesPage> {
|
||||||
return client.newCall(searchAnimeRequest(page, query, filters))
|
return client.newCall(searchAnimeRequest(page, query, filters))
|
||||||
.asObservableSuccess()
|
.asObservableSuccess()
|
||||||
.map { response ->
|
.map { response ->
|
||||||
@@ -133,7 +133,7 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||||||
* @param query the search query.
|
* @param query the search query.
|
||||||
* @param filters the list of filters to apply.
|
* @param filters the list of filters to apply.
|
||||||
*/
|
*/
|
||||||
protected abstract fun searchAnimeRequest(page: Int, query: String, filters: FilterList): Request
|
protected abstract fun searchAnimeRequest(page: Int, query: String, filters: AnimeFilterList): Request
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the response from the site and returns a [AnimesPage] object.
|
* Parses the response from the site and returns a [AnimesPage] object.
|
||||||
@@ -380,7 +380,7 @@ abstract class AnimeHttpSource : AnimeCatalogueSource {
|
|||||||
/**
|
/**
|
||||||
* Returns the list of filters for the source.
|
* Returns the list of filters for the source.
|
||||||
*/
|
*/
|
||||||
override fun getFilterList() = FilterList()
|
override fun getFilterList() = AnimeFilterList()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63"
|
const val DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36 Edg/88.0.705.63"
|
||||||
+1
@@ -1,5 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.source.online
|
package eu.kanade.tachiyomi.source.online
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
|
|
||||||
+4
-4
@@ -1,9 +1,9 @@
|
|||||||
package eu.kanade.tachiyomi.source.online
|
package eu.kanade.tachiyomi.animesource.online
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.source.model.AnimesPage
|
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||||
import eu.kanade.tachiyomi.source.model.Page
|
import eu.kanade.tachiyomi.source.model.Page
|
||||||
import eu.kanade.tachiyomi.source.model.SAnime
|
|
||||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package suwayomi.anime.impl.extension.github
|
|
||||||
|
|
||||||
data class OnlineExtension(
|
|
||||||
val name: String,
|
|
||||||
val pkgName: String,
|
|
||||||
val versionName: String,
|
|
||||||
val versionCode: Int,
|
|
||||||
val lang: String,
|
|
||||||
val isNsfw: Boolean,
|
|
||||||
val apkName: String,
|
|
||||||
val iconUrl: String
|
|
||||||
)
|
|
||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi
|
package suwayomi.tachidesk
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -7,8 +7,8 @@ package suwayomi
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import suwayomi.server.JavalinSetup.javalinSetup
|
import suwayomi.tachidesk.server.JavalinSetup.javalinSetup
|
||||||
import suwayomi.server.applicationSetup
|
import suwayomi.tachidesk.server.applicationSetup
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
applicationSetup()
|
applicationSetup()
|
||||||
+15
-15
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime
|
package suwayomi.tachidesk.anime
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -8,20 +8,20 @@ package suwayomi.anime
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import io.javalin.Javalin
|
import io.javalin.Javalin
|
||||||
import suwayomi.anime.impl.Anime.getAnime
|
import suwayomi.tachidesk.anime.impl.Anime.getAnime
|
||||||
import suwayomi.anime.impl.Anime.getAnimeThumbnail
|
import suwayomi.tachidesk.anime.impl.Anime.getAnimeThumbnail
|
||||||
import suwayomi.anime.impl.AnimeList.getAnimeList
|
import suwayomi.tachidesk.anime.impl.AnimeList.getAnimeList
|
||||||
import suwayomi.anime.impl.Episode.getEpisode
|
import suwayomi.tachidesk.anime.impl.Episode.getEpisode
|
||||||
import suwayomi.anime.impl.Episode.getEpisodeList
|
import suwayomi.tachidesk.anime.impl.Episode.getEpisodeList
|
||||||
import suwayomi.anime.impl.Episode.modifyEpisode
|
import suwayomi.tachidesk.anime.impl.Episode.modifyEpisode
|
||||||
import suwayomi.anime.impl.Source.getAnimeSource
|
import suwayomi.tachidesk.anime.impl.Source.getAnimeSource
|
||||||
import suwayomi.anime.impl.Source.getSourceList
|
import suwayomi.tachidesk.anime.impl.Source.getSourceList
|
||||||
import suwayomi.anime.impl.extension.Extension.getExtensionIcon
|
import suwayomi.tachidesk.anime.impl.extension.Extension.getExtensionIcon
|
||||||
import suwayomi.anime.impl.extension.Extension.installExtension
|
import suwayomi.tachidesk.anime.impl.extension.Extension.installExtension
|
||||||
import suwayomi.anime.impl.extension.Extension.uninstallExtension
|
import suwayomi.tachidesk.anime.impl.extension.Extension.uninstallExtension
|
||||||
import suwayomi.anime.impl.extension.Extension.updateExtension
|
import suwayomi.tachidesk.anime.impl.extension.Extension.updateExtension
|
||||||
import suwayomi.anime.impl.extension.ExtensionsList.getExtensionList
|
import suwayomi.tachidesk.anime.impl.extension.ExtensionsList.getExtensionList
|
||||||
import suwayomi.server.JavalinSetup.future
|
import suwayomi.tachidesk.server.JavalinSetup.future
|
||||||
|
|
||||||
object AnimeAPI {
|
object AnimeAPI {
|
||||||
fun defineEndpoints(app: Javalin) {
|
fun defineEndpoints(app: Javalin) {
|
||||||
+14
-14
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.impl
|
package suwayomi.tachidesk.anime.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -7,25 +7,25 @@ package suwayomi.anime.impl
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.source.model.SAnime
|
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.jetbrains.exposed.sql.update
|
import org.jetbrains.exposed.sql.update
|
||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
import org.kodein.di.conf.global
|
import org.kodein.di.conf.global
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import suwayomi.anime.impl.AnimeList.proxyThumbnailUrl
|
import suwayomi.tachidesk.anime.impl.AnimeList.proxyThumbnailUrl
|
||||||
import suwayomi.anime.impl.Source.getAnimeSource
|
import suwayomi.tachidesk.anime.impl.Source.getAnimeSource
|
||||||
import suwayomi.anime.impl.util.GetAnimeHttpSource.getAnimeHttpSource
|
import suwayomi.tachidesk.anime.impl.util.GetAnimeHttpSource.getAnimeHttpSource
|
||||||
import suwayomi.anime.model.dataclass.AnimeDataClass
|
import suwayomi.tachidesk.anime.model.dataclass.AnimeDataClass
|
||||||
import suwayomi.anime.model.table.AnimeStatus
|
import suwayomi.tachidesk.anime.model.table.AnimeStatus
|
||||||
import suwayomi.anime.model.table.AnimeTable
|
import suwayomi.tachidesk.anime.model.table.AnimeTable
|
||||||
import suwayomi.server.ApplicationDirs
|
import suwayomi.tachidesk.manga.impl.util.lang.awaitSingle
|
||||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
import suwayomi.tachidesk.manga.impl.util.network.await
|
||||||
import suwayomi.tachidesk.impl.util.network.await
|
import suwayomi.tachidesk.manga.impl.util.storage.CachedImageResponse.clearCachedImage
|
||||||
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.clearCachedImage
|
import suwayomi.tachidesk.manga.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
||||||
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
import suwayomi.tachidesk.server.ApplicationDirs
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
|
||||||
object Anime {
|
object Anime {
|
||||||
@@ -102,7 +102,7 @@ object Anime {
|
|||||||
fetchedAnime.description,
|
fetchedAnime.description,
|
||||||
fetchedAnime.genre,
|
fetchedAnime.genre,
|
||||||
AnimeStatus.valueOf(fetchedAnime.status).name,
|
AnimeStatus.valueOf(fetchedAnime.status).name,
|
||||||
false,
|
animeEntry[AnimeTable.inLibrary],
|
||||||
getAnimeSource(animeEntry[AnimeTable.sourceReference]),
|
getAnimeSource(animeEntry[AnimeTable.sourceReference]),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
+8
-8
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.impl
|
package suwayomi.tachidesk.anime.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -7,16 +7,16 @@ package suwayomi.anime.impl
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.source.model.AnimesPage
|
import eu.kanade.tachiyomi.animesource.model.AnimesPage
|
||||||
import org.jetbrains.exposed.sql.insertAndGetId
|
import org.jetbrains.exposed.sql.insertAndGetId
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import suwayomi.anime.impl.util.GetAnimeHttpSource.getAnimeHttpSource
|
import suwayomi.tachidesk.anime.impl.util.GetAnimeHttpSource.getAnimeHttpSource
|
||||||
import suwayomi.anime.model.dataclass.AnimeDataClass
|
import suwayomi.tachidesk.anime.model.dataclass.AnimeDataClass
|
||||||
import suwayomi.anime.model.dataclass.PagedAnimeListDataClass
|
import suwayomi.tachidesk.anime.model.dataclass.PagedAnimeListDataClass
|
||||||
import suwayomi.anime.model.table.AnimeStatus
|
import suwayomi.tachidesk.anime.model.table.AnimeStatus
|
||||||
import suwayomi.anime.model.table.AnimeTable
|
import suwayomi.tachidesk.anime.model.table.AnimeTable
|
||||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
import suwayomi.tachidesk.manga.impl.util.lang.awaitSingle
|
||||||
|
|
||||||
object AnimeList {
|
object AnimeList {
|
||||||
fun proxyThumbnailUrl(animeId: Int): String {
|
fun proxyThumbnailUrl(animeId: Int): String {
|
||||||
+10
-10
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.impl
|
package suwayomi.tachidesk.anime.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -7,8 +7,8 @@ package suwayomi.anime.impl
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.source.model.SAnime
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||||
import eu.kanade.tachiyomi.source.model.SEpisode
|
import eu.kanade.tachiyomi.animesource.model.SEpisode
|
||||||
import org.jetbrains.exposed.sql.SortOrder.DESC
|
import org.jetbrains.exposed.sql.SortOrder.DESC
|
||||||
import org.jetbrains.exposed.sql.and
|
import org.jetbrains.exposed.sql.and
|
||||||
import org.jetbrains.exposed.sql.deleteWhere
|
import org.jetbrains.exposed.sql.deleteWhere
|
||||||
@@ -16,13 +16,13 @@ import org.jetbrains.exposed.sql.insert
|
|||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.jetbrains.exposed.sql.update
|
import org.jetbrains.exposed.sql.update
|
||||||
import suwayomi.anime.impl.Anime.getAnime
|
import suwayomi.tachidesk.anime.impl.Anime.getAnime
|
||||||
import suwayomi.anime.impl.util.GetAnimeHttpSource.getAnimeHttpSource
|
import suwayomi.tachidesk.anime.impl.util.GetAnimeHttpSource.getAnimeHttpSource
|
||||||
import suwayomi.anime.model.dataclass.EpisodeDataClass
|
import suwayomi.tachidesk.anime.model.dataclass.EpisodeDataClass
|
||||||
import suwayomi.anime.model.table.AnimeTable
|
import suwayomi.tachidesk.anime.model.table.AnimeTable
|
||||||
import suwayomi.anime.model.table.EpisodeTable
|
import suwayomi.tachidesk.anime.model.table.EpisodeTable
|
||||||
import suwayomi.anime.model.table.toDataClass
|
import suwayomi.tachidesk.anime.model.table.toDataClass
|
||||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
import suwayomi.tachidesk.manga.impl.util.lang.awaitSingle
|
||||||
|
|
||||||
object Episode {
|
object Episode {
|
||||||
/** get episode list when showing an anime */
|
/** get episode list when showing an anime */
|
||||||
+6
-6
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.impl
|
package suwayomi.tachidesk.anime.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -11,11 +11,11 @@ import mu.KotlinLogging
|
|||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.selectAll
|
import org.jetbrains.exposed.sql.selectAll
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import suwayomi.anime.impl.extension.Extension.getExtensionIconUrl
|
import suwayomi.tachidesk.anime.impl.extension.Extension.getExtensionIconUrl
|
||||||
import suwayomi.anime.impl.util.GetAnimeHttpSource.getAnimeHttpSource
|
import suwayomi.tachidesk.anime.impl.util.GetAnimeHttpSource.getAnimeHttpSource
|
||||||
import suwayomi.anime.model.dataclass.AnimeSourceDataClass
|
import suwayomi.tachidesk.anime.model.dataclass.AnimeSourceDataClass
|
||||||
import suwayomi.anime.model.table.AnimeExtensionTable
|
import suwayomi.tachidesk.anime.model.table.AnimeExtensionTable
|
||||||
import suwayomi.anime.model.table.AnimeSourceTable
|
import suwayomi.tachidesk.anime.model.table.AnimeSourceTable
|
||||||
|
|
||||||
object Source {
|
object Source {
|
||||||
private val logger = KotlinLogging.logger {}
|
private val logger = KotlinLogging.logger {}
|
||||||
+21
-21
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.impl.extension
|
package suwayomi.tachidesk.anime.impl.extension
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -8,11 +8,11 @@ package suwayomi.anime.impl.extension
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import eu.kanade.tachiyomi.animesource.AnimeCatalogueSource
|
||||||
|
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||||
|
import eu.kanade.tachiyomi.animesource.AnimeSourceFactory
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.source.AnimeCatalogueSource
|
|
||||||
import eu.kanade.tachiyomi.source.AnimeSource
|
|
||||||
import eu.kanade.tachiyomi.source.AnimeSourceFactory
|
|
||||||
import mu.KotlinLogging
|
import mu.KotlinLogging
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
@@ -25,23 +25,23 @@ import org.jetbrains.exposed.sql.update
|
|||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
import org.kodein.di.conf.global
|
import org.kodein.di.conf.global
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import suwayomi.anime.impl.extension.ExtensionsList.extensionTableAsDataClass
|
import suwayomi.tachidesk.anime.impl.extension.ExtensionsList.extensionTableAsDataClass
|
||||||
import suwayomi.anime.impl.extension.github.ExtensionGithubApi
|
import suwayomi.tachidesk.anime.impl.extension.github.ExtensionGithubApi
|
||||||
import suwayomi.anime.impl.util.PackageTools.EXTENSION_FEATURE
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.EXTENSION_FEATURE
|
||||||
import suwayomi.anime.impl.util.PackageTools.LIB_VERSION_MAX
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.LIB_VERSION_MAX
|
||||||
import suwayomi.anime.impl.util.PackageTools.LIB_VERSION_MIN
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.LIB_VERSION_MIN
|
||||||
import suwayomi.anime.impl.util.PackageTools.METADATA_NSFW
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.METADATA_NSFW
|
||||||
import suwayomi.anime.impl.util.PackageTools.METADATA_SOURCE_CLASS
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.METADATA_SOURCE_CLASS
|
||||||
import suwayomi.anime.impl.util.PackageTools.dex2jar
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.dex2jar
|
||||||
import suwayomi.anime.impl.util.PackageTools.getPackageInfo
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.getPackageInfo
|
||||||
import suwayomi.anime.impl.util.PackageTools.getSignatureHash
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.getSignatureHash
|
||||||
import suwayomi.anime.impl.util.PackageTools.loadExtensionSources
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.loadExtensionSources
|
||||||
import suwayomi.anime.impl.util.PackageTools.trustedSignatures
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.trustedSignatures
|
||||||
import suwayomi.anime.model.table.AnimeExtensionTable
|
import suwayomi.tachidesk.anime.model.table.AnimeExtensionTable
|
||||||
import suwayomi.anime.model.table.AnimeSourceTable
|
import suwayomi.tachidesk.anime.model.table.AnimeSourceTable
|
||||||
import suwayomi.server.ApplicationDirs
|
import suwayomi.tachidesk.manga.impl.util.network.await
|
||||||
import suwayomi.tachidesk.impl.util.network.await
|
import suwayomi.tachidesk.manga.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
||||||
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
import suwayomi.tachidesk.server.ApplicationDirs
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
+6
-6
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.impl.extension
|
package suwayomi.tachidesk.anime.impl.extension
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -14,11 +14,11 @@ import org.jetbrains.exposed.sql.select
|
|||||||
import org.jetbrains.exposed.sql.selectAll
|
import org.jetbrains.exposed.sql.selectAll
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.jetbrains.exposed.sql.update
|
import org.jetbrains.exposed.sql.update
|
||||||
import suwayomi.anime.impl.extension.Extension.getExtensionIconUrl
|
import suwayomi.tachidesk.anime.impl.extension.Extension.getExtensionIconUrl
|
||||||
import suwayomi.anime.impl.extension.github.ExtensionGithubApi
|
import suwayomi.tachidesk.anime.impl.extension.github.ExtensionGithubApi
|
||||||
import suwayomi.anime.impl.extension.github.OnlineExtension
|
import suwayomi.tachidesk.anime.impl.extension.github.OnlineExtension
|
||||||
import suwayomi.anime.model.dataclass.AnimeExtensionDataClass
|
import suwayomi.tachidesk.anime.model.dataclass.AnimeExtensionDataClass
|
||||||
import suwayomi.anime.model.table.AnimeExtensionTable
|
import suwayomi.tachidesk.anime.model.table.AnimeExtensionTable
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
object ExtensionsList {
|
object ExtensionsList {
|
||||||
+9
-10
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.impl.extension.github
|
package suwayomi.tachidesk.anime.impl.extension.github
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -13,23 +13,22 @@ import com.google.gson.JsonArray
|
|||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import suwayomi.anime.model.dataclass.AnimeExtensionDataClass
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.LIB_VERSION_MAX
|
||||||
import suwayomi.tachidesk.impl.util.network.UnzippingInterceptor
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.LIB_VERSION_MIN
|
||||||
|
import suwayomi.tachidesk.anime.model.dataclass.AnimeExtensionDataClass
|
||||||
|
import suwayomi.tachidesk.manga.impl.util.network.UnzippingInterceptor
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
object ExtensionGithubApi {
|
object ExtensionGithubApi {
|
||||||
const val BASE_URL = "https://raw.githubusercontent.com"
|
private const val BASE_URL = "https://raw.githubusercontent.com"
|
||||||
const val REPO_URL_PREFIX = "$BASE_URL/jmir1/tachiyomi-extensions/repo"
|
private const val REPO_URL_PREFIX = "$BASE_URL/jmir1/tachiyomi-extensions/repo"
|
||||||
|
|
||||||
private const val LIB_VERSION_MIN = 1.3
|
|
||||||
private const val LIB_VERSION_MAX = 1.3
|
|
||||||
|
|
||||||
private fun parseResponse(json: JsonArray): List<OnlineExtension> {
|
private fun parseResponse(json: JsonArray): List<OnlineExtension> {
|
||||||
return json
|
return json
|
||||||
.map { it.asJsonObject }
|
.map { it.asJsonObject }
|
||||||
.filter { element ->
|
.filter { element ->
|
||||||
val versionName = element["version"].string
|
val versionName = element["version"].string
|
||||||
val libVersion = versionName.substringBeforeLast('.').toDouble()
|
val libVersion = versionName.substringBeforeLast('.').toInt()
|
||||||
libVersion in LIB_VERSION_MIN..LIB_VERSION_MAX
|
libVersion in LIB_VERSION_MIN..LIB_VERSION_MAX
|
||||||
}
|
}
|
||||||
.map { element ->
|
.map { element ->
|
||||||
@@ -69,7 +68,7 @@ object ExtensionGithubApi {
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getRepo(): com.google.gson.JsonArray {
|
private fun getRepo(): JsonArray {
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url("$REPO_URL_PREFIX/index.json.gz")
|
.url("$REPO_URL_PREFIX/index.json.gz")
|
||||||
.build()
|
.build()
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package suwayomi.tachidesk.anime.impl.extension.github
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
data class OnlineExtension(
|
||||||
|
val name: String,
|
||||||
|
val pkgName: String,
|
||||||
|
val versionName: String,
|
||||||
|
val versionCode: Int,
|
||||||
|
val lang: String,
|
||||||
|
val isNsfw: Boolean,
|
||||||
|
val apkName: String,
|
||||||
|
val iconUrl: String
|
||||||
|
)
|
||||||
+8
-8
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.impl.util
|
package suwayomi.tachidesk.anime.impl.util
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -7,18 +7,18 @@ package suwayomi.anime.impl.util
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.source.AnimeSource
|
import eu.kanade.tachiyomi.animesource.AnimeSource
|
||||||
import eu.kanade.tachiyomi.source.AnimeSourceFactory
|
import eu.kanade.tachiyomi.animesource.AnimeSourceFactory
|
||||||
import eu.kanade.tachiyomi.source.online.AnimeHttpSource
|
import eu.kanade.tachiyomi.animesource.online.AnimeHttpSource
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
import org.kodein.di.conf.global
|
import org.kodein.di.conf.global
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import suwayomi.anime.impl.util.PackageTools.loadExtensionSources
|
import suwayomi.tachidesk.anime.impl.util.PackageTools.loadExtensionSources
|
||||||
import suwayomi.anime.model.table.AnimeExtensionTable
|
import suwayomi.tachidesk.anime.model.table.AnimeExtensionTable
|
||||||
import suwayomi.anime.model.table.AnimeSourceTable
|
import suwayomi.tachidesk.anime.model.table.AnimeSourceTable
|
||||||
import suwayomi.server.ApplicationDirs
|
import suwayomi.tachidesk.server.ApplicationDirs
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
object GetAnimeHttpSource {
|
object GetAnimeHttpSource {
|
||||||
+4
-4
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.impl.util
|
package suwayomi.tachidesk.anime.impl.util
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -22,7 +22,7 @@ import org.kodein.di.conf.global
|
|||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
import suwayomi.server.ApplicationDirs
|
import suwayomi.tachidesk.server.ApplicationDirs
|
||||||
import xyz.nulldev.androidcompat.pm.InstalledPackage.Companion.toList
|
import xyz.nulldev.androidcompat.pm.InstalledPackage.Companion.toList
|
||||||
import xyz.nulldev.androidcompat.pm.toPackageInfo
|
import xyz.nulldev.androidcompat.pm.toPackageInfo
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -40,8 +40,8 @@ object PackageTools {
|
|||||||
const val METADATA_SOURCE_CLASS = "tachiyomi.animeextension.class"
|
const val METADATA_SOURCE_CLASS = "tachiyomi.animeextension.class"
|
||||||
const val METADATA_SOURCE_FACTORY = "tachiyomi.animeextension.factory"
|
const val METADATA_SOURCE_FACTORY = "tachiyomi.animeextension.factory"
|
||||||
const val METADATA_NSFW = "tachiyomi.animeextension.nsfw"
|
const val METADATA_NSFW = "tachiyomi.animeextension.nsfw"
|
||||||
const val LIB_VERSION_MIN = 1.3
|
const val LIB_VERSION_MIN = 10
|
||||||
const val LIB_VERSION_MAX = 1.3
|
const val LIB_VERSION_MAX = 10
|
||||||
|
|
||||||
private const val officialSignature = "50ab1d1e3a20d204d0ad6d334c7691c632e41b98dfa132bf385695fdfa63839c" // jmir1's key
|
private const val officialSignature = "50ab1d1e3a20d204d0ad6d334c7691c632e41b98dfa132bf385695fdfa63839c" // jmir1's key
|
||||||
var trustedSignatures = mutableSetOf<String>() + officialSignature
|
var trustedSignatures = mutableSetOf<String>() + officialSignature
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.model.dataclass
|
package suwayomi.tachidesk.anime.model.dataclass
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -7,7 +7,7 @@ package suwayomi.anime.model.dataclass
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import suwayomi.anime.model.table.AnimeStatus
|
import suwayomi.tachidesk.anime.model.table.AnimeStatus
|
||||||
|
|
||||||
data class AnimeDataClass(
|
data class AnimeDataClass(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.model.dataclass
|
package suwayomi.tachidesk.anime.model.dataclass
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.model.dataclass
|
package suwayomi.tachidesk.anime.model.dataclass
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.model.dataclass
|
package suwayomi.tachidesk.anime.model.dataclass
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.model.table
|
package suwayomi.tachidesk.anime.model.table
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.model.table
|
package suwayomi.tachidesk.anime.model.table
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
+5
-5
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.model.table
|
package suwayomi.tachidesk.anime.model.table
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -7,12 +7,12 @@ package suwayomi.anime.model.table
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.source.model.SAnime
|
import eu.kanade.tachiyomi.animesource.model.SAnime
|
||||||
import org.jetbrains.exposed.dao.id.IntIdTable
|
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||||
import org.jetbrains.exposed.sql.ResultRow
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
import suwayomi.tachidesk.impl.MangaList.proxyThumbnailUrl
|
import suwayomi.tachidesk.manga.impl.MangaList.proxyThumbnailUrl
|
||||||
import suwayomi.tachidesk.model.dataclass.MangaDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.MangaDataClass
|
||||||
import suwayomi.tachidesk.model.table.MangaStatus.Companion
|
import suwayomi.tachidesk.manga.model.table.MangaStatus.Companion
|
||||||
|
|
||||||
object AnimeTable : IntIdTable() {
|
object AnimeTable : IntIdTable() {
|
||||||
val url = varchar("url", 2048)
|
val url = varchar("url", 2048)
|
||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.anime.model.table
|
package suwayomi.tachidesk.anime.model.table
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -11,7 +11,7 @@ import org.jetbrains.exposed.dao.id.IntIdTable
|
|||||||
import org.jetbrains.exposed.sql.ResultRow
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import suwayomi.anime.model.dataclass.EpisodeDataClass
|
import suwayomi.tachidesk.anime.model.dataclass.EpisodeDataClass
|
||||||
|
|
||||||
object EpisodeTable : IntIdTable() {
|
object EpisodeTable : IntIdTable() {
|
||||||
val url = varchar("url", 2048)
|
val url = varchar("url", 2048)
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.legacy.models
|
|
||||||
|
|
||||||
data class DHistory(val url: String, val lastRead: Long)
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package suwayomi.tachidesk.impl.download
|
|
||||||
|
|
||||||
import org.jetbrains.exposed.sql.ResultRow
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
data class Download(
|
|
||||||
val chapter: ResultRow,
|
|
||||||
)
|
|
||||||
|
|
||||||
private val downloadQueue = LinkedBlockingQueue<Download>()
|
|
||||||
|
|
||||||
class Downloader {
|
|
||||||
|
|
||||||
fun start() {
|
|
||||||
TODO()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun stop() {
|
|
||||||
TODO()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package suwayomi.tachidesk.impl.extension.github
|
|
||||||
|
|
||||||
data class OnlineExtension(
|
|
||||||
val name: String,
|
|
||||||
val pkgName: String,
|
|
||||||
val versionName: String,
|
|
||||||
val versionCode: Int,
|
|
||||||
val lang: String,
|
|
||||||
val isNsfw: Boolean,
|
|
||||||
val apkName: String,
|
|
||||||
val iconUrl: String
|
|
||||||
)
|
|
||||||
+105
-36
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk
|
package suwayomi.tachidesk.manga
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -8,36 +8,39 @@ package suwayomi.tachidesk
|
|||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import io.javalin.Javalin
|
import io.javalin.Javalin
|
||||||
import suwayomi.server.JavalinSetup.future
|
import suwayomi.tachidesk.manga.impl.Category
|
||||||
import suwayomi.server.impl.About
|
import suwayomi.tachidesk.manga.impl.CategoryManga.addMangaToCategory
|
||||||
import suwayomi.tachidesk.impl.Category
|
import suwayomi.tachidesk.manga.impl.CategoryManga.getCategoryMangaList
|
||||||
import suwayomi.tachidesk.impl.CategoryManga.addMangaToCategory
|
import suwayomi.tachidesk.manga.impl.CategoryManga.getMangaCategories
|
||||||
import suwayomi.tachidesk.impl.CategoryManga.getCategoryMangaList
|
import suwayomi.tachidesk.manga.impl.CategoryManga.removeMangaFromCategory
|
||||||
import suwayomi.tachidesk.impl.CategoryManga.getMangaCategories
|
import suwayomi.tachidesk.manga.impl.Chapter.getChapter
|
||||||
import suwayomi.tachidesk.impl.CategoryManga.removeMangaFromCategory
|
import suwayomi.tachidesk.manga.impl.Chapter.getChapterList
|
||||||
import suwayomi.tachidesk.impl.Chapter.getChapter
|
import suwayomi.tachidesk.manga.impl.Chapter.modifyChapter
|
||||||
import suwayomi.tachidesk.impl.Chapter.getChapterList
|
import suwayomi.tachidesk.manga.impl.Chapter.modifyChapterMeta
|
||||||
import suwayomi.tachidesk.impl.Chapter.modifyChapter
|
import suwayomi.tachidesk.manga.impl.Library.addMangaToLibrary
|
||||||
import suwayomi.tachidesk.impl.Library.addMangaToLibrary
|
import suwayomi.tachidesk.manga.impl.Library.getLibraryMangas
|
||||||
import suwayomi.tachidesk.impl.Library.getLibraryMangas
|
import suwayomi.tachidesk.manga.impl.Library.removeMangaFromLibrary
|
||||||
import suwayomi.tachidesk.impl.Library.removeMangaFromLibrary
|
import suwayomi.tachidesk.manga.impl.Manga.getManga
|
||||||
import suwayomi.tachidesk.impl.Manga.getManga
|
import suwayomi.tachidesk.manga.impl.Manga.getMangaThumbnail
|
||||||
import suwayomi.tachidesk.impl.Manga.getMangaThumbnail
|
import suwayomi.tachidesk.manga.impl.Manga.modifyMangaMeta
|
||||||
import suwayomi.tachidesk.impl.MangaList.getMangaList
|
import suwayomi.tachidesk.manga.impl.MangaList.getMangaList
|
||||||
import suwayomi.tachidesk.impl.Page.getPageImage
|
import suwayomi.tachidesk.manga.impl.Page.getPageImage
|
||||||
import suwayomi.tachidesk.impl.Search.sourceFilters
|
import suwayomi.tachidesk.manga.impl.Search.sourceFilters
|
||||||
import suwayomi.tachidesk.impl.Search.sourceGlobalSearch
|
import suwayomi.tachidesk.manga.impl.Search.sourceGlobalSearch
|
||||||
import suwayomi.tachidesk.impl.Search.sourceSearch
|
import suwayomi.tachidesk.manga.impl.Search.sourceSearch
|
||||||
import suwayomi.tachidesk.impl.Source.getSource
|
import suwayomi.tachidesk.manga.impl.Source.getSource
|
||||||
import suwayomi.tachidesk.impl.Source.getSourceList
|
import suwayomi.tachidesk.manga.impl.Source.getSourceList
|
||||||
import suwayomi.tachidesk.impl.backup.BackupFlags
|
import suwayomi.tachidesk.manga.impl.backup.BackupFlags
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.LegacyBackupExport.createLegacyBackup
|
import suwayomi.tachidesk.manga.impl.backup.legacy.LegacyBackupExport.createLegacyBackup
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.LegacyBackupImport.restoreLegacyBackup
|
import suwayomi.tachidesk.manga.impl.backup.legacy.LegacyBackupImport.restoreLegacyBackup
|
||||||
import suwayomi.tachidesk.impl.extension.Extension.getExtensionIcon
|
import suwayomi.tachidesk.manga.impl.download.DownloadManager
|
||||||
import suwayomi.tachidesk.impl.extension.Extension.installExtension
|
import suwayomi.tachidesk.manga.impl.extension.Extension.getExtensionIcon
|
||||||
import suwayomi.tachidesk.impl.extension.Extension.uninstallExtension
|
import suwayomi.tachidesk.manga.impl.extension.Extension.installExtension
|
||||||
import suwayomi.tachidesk.impl.extension.Extension.updateExtension
|
import suwayomi.tachidesk.manga.impl.extension.Extension.uninstallExtension
|
||||||
import suwayomi.tachidesk.impl.extension.ExtensionsList.getExtensionList
|
import suwayomi.tachidesk.manga.impl.extension.Extension.updateExtension
|
||||||
|
import suwayomi.tachidesk.manga.impl.extension.ExtensionsList.getExtensionList
|
||||||
|
import suwayomi.tachidesk.server.JavalinSetup.future
|
||||||
|
import suwayomi.tachidesk.server.impl.About
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
@@ -184,6 +187,18 @@ object TachideskAPI {
|
|||||||
ctx.json(future { getChapterList(mangaId, onlineFetch) })
|
ctx.json(future { getChapterList(mangaId, onlineFetch) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// used to modify a manga's meta paramaters
|
||||||
|
app.patch("/api/v1/manga/:mangaId/meta") { ctx ->
|
||||||
|
val mangaId = ctx.pathParam("mangaId").toInt()
|
||||||
|
|
||||||
|
val key = ctx.formParam("key")!!
|
||||||
|
val value = ctx.formParam("value")!!
|
||||||
|
|
||||||
|
modifyMangaMeta(mangaId, key, value)
|
||||||
|
|
||||||
|
ctx.status(200)
|
||||||
|
}
|
||||||
|
|
||||||
// used to display a chapter, get a chapter in order to show it's pages
|
// used to display a chapter, get a chapter in order to show it's pages
|
||||||
app.get("/api/v1/manga/:mangaId/chapter/:chapterIndex") { ctx ->
|
app.get("/api/v1/manga/:mangaId/chapter/:chapterIndex") { ctx ->
|
||||||
val chapterIndex = ctx.pathParam("chapterIndex").toInt()
|
val chapterIndex = ctx.pathParam("chapterIndex").toInt()
|
||||||
@@ -206,6 +221,19 @@ object TachideskAPI {
|
|||||||
ctx.status(200)
|
ctx.status(200)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// used to modify a chapter's meta paramaters
|
||||||
|
app.patch("/api/v1/manga/:mangaId/chapter/:chapterIndex/meta") { ctx ->
|
||||||
|
val chapterIndex = ctx.pathParam("chapterIndex").toInt()
|
||||||
|
val mangaId = ctx.pathParam("mangaId").toInt()
|
||||||
|
|
||||||
|
val key = ctx.formParam("key")!!
|
||||||
|
val value = ctx.formParam("value")!!
|
||||||
|
|
||||||
|
modifyChapterMeta(mangaId, chapterIndex, key, value)
|
||||||
|
|
||||||
|
ctx.status(200)
|
||||||
|
}
|
||||||
|
|
||||||
// get page at index "index"
|
// get page at index "index"
|
||||||
app.get("/api/v1/manga/:mangaId/chapter/:chapterIndex/page/:index") { ctx ->
|
app.get("/api/v1/manga/:mangaId/chapter/:chapterIndex/page/:index") { ctx ->
|
||||||
val mangaId = ctx.pathParam("mangaId").toInt()
|
val mangaId = ctx.pathParam("mangaId").toInt()
|
||||||
@@ -383,15 +411,56 @@ object TachideskAPI {
|
|||||||
// Download queue stats
|
// Download queue stats
|
||||||
app.ws("/api/v1/downloads") { ws ->
|
app.ws("/api/v1/downloads") { ws ->
|
||||||
ws.onConnect { ctx ->
|
ws.onConnect { ctx ->
|
||||||
// TODO: send current stat
|
DownloadManager.addClient(ctx)
|
||||||
// TODO: add to downlad subscribers
|
DownloadManager.notifyClient(ctx)
|
||||||
}
|
}
|
||||||
ws.onMessage {
|
ws.onMessage { ctx ->
|
||||||
// TODO: send current stat
|
DownloadManager.handleRequest(ctx)
|
||||||
}
|
}
|
||||||
ws.onClose { ctx ->
|
ws.onClose { ctx ->
|
||||||
// TODO: remove from subscribers
|
DownloadManager.removeClient(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start the downloader
|
||||||
|
app.get("/api/v1/downloads/start") { ctx ->
|
||||||
|
DownloadManager.start()
|
||||||
|
|
||||||
|
ctx.status(200)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop the downloader
|
||||||
|
app.get("/api/v1/downloads/stop") { ctx ->
|
||||||
|
DownloadManager.stop()
|
||||||
|
|
||||||
|
ctx.status(200)
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear download queue
|
||||||
|
app.get("/api/v1/downloads/clear") { ctx ->
|
||||||
|
DownloadManager.clear()
|
||||||
|
|
||||||
|
ctx.status(200)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queue chapter for download
|
||||||
|
app.get("/api/v1/download/:mangaId/chapter/:chapterIndex") { ctx ->
|
||||||
|
val chapterIndex = ctx.pathParam("chapterIndex").toInt()
|
||||||
|
val mangaId = ctx.pathParam("mangaId").toInt()
|
||||||
|
|
||||||
|
DownloadManager.enqueue(chapterIndex, mangaId)
|
||||||
|
|
||||||
|
ctx.status(200)
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete chapter from download queue
|
||||||
|
app.delete("/api/v1/download/:mangaId/chapter/:chapterIndex") { ctx ->
|
||||||
|
val chapterIndex = ctx.pathParam("chapterIndex").toInt()
|
||||||
|
val mangaId = ctx.pathParam("mangaId").toInt()
|
||||||
|
|
||||||
|
DownloadManager.unqueue(chapterIndex, mangaId)
|
||||||
|
|
||||||
|
ctx.status(200)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
-6
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl
|
package suwayomi.tachidesk.manga.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -14,11 +14,11 @@ import org.jetbrains.exposed.sql.select
|
|||||||
import org.jetbrains.exposed.sql.selectAll
|
import org.jetbrains.exposed.sql.selectAll
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.jetbrains.exposed.sql.update
|
import org.jetbrains.exposed.sql.update
|
||||||
import suwayomi.tachidesk.impl.CategoryManga.removeMangaFromCategory
|
import suwayomi.tachidesk.manga.impl.CategoryManga.removeMangaFromCategory
|
||||||
import suwayomi.tachidesk.model.dataclass.CategoryDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.CategoryDataClass
|
||||||
import suwayomi.tachidesk.model.table.CategoryMangaTable
|
import suwayomi.tachidesk.manga.model.table.CategoryMangaTable
|
||||||
import suwayomi.tachidesk.model.table.CategoryTable
|
import suwayomi.tachidesk.manga.model.table.CategoryTable
|
||||||
import suwayomi.tachidesk.model.table.toDataClass
|
import suwayomi.tachidesk.manga.model.table.toDataClass
|
||||||
|
|
||||||
object Category {
|
object Category {
|
||||||
/**
|
/**
|
||||||
+7
-7
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl
|
package suwayomi.tachidesk.manga.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -14,12 +14,12 @@ import org.jetbrains.exposed.sql.insert
|
|||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.jetbrains.exposed.sql.update
|
import org.jetbrains.exposed.sql.update
|
||||||
import suwayomi.tachidesk.model.dataclass.CategoryDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.CategoryDataClass
|
||||||
import suwayomi.tachidesk.model.dataclass.MangaDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.MangaDataClass
|
||||||
import suwayomi.tachidesk.model.table.CategoryMangaTable
|
import suwayomi.tachidesk.manga.model.table.CategoryMangaTable
|
||||||
import suwayomi.tachidesk.model.table.CategoryTable
|
import suwayomi.tachidesk.manga.model.table.CategoryTable
|
||||||
import suwayomi.tachidesk.model.table.MangaTable
|
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||||
import suwayomi.tachidesk.model.table.toDataClass
|
import suwayomi.tachidesk.manga.model.table.toDataClass
|
||||||
|
|
||||||
object CategoryManga {
|
object CategoryManga {
|
||||||
fun addMangaToCategory(mangaId: Int, categoryId: Int) {
|
fun addMangaToCategory(mangaId: Int, categoryId: Int) {
|
||||||
+103
-52
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl
|
package suwayomi.tachidesk.manga.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -9,6 +9,7 @@ package suwayomi.tachidesk.impl
|
|||||||
|
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import org.jetbrains.exposed.dao.id.EntityID
|
||||||
import org.jetbrains.exposed.sql.SortOrder.DESC
|
import org.jetbrains.exposed.sql.SortOrder.DESC
|
||||||
import org.jetbrains.exposed.sql.and
|
import org.jetbrains.exposed.sql.and
|
||||||
import org.jetbrains.exposed.sql.deleteWhere
|
import org.jetbrains.exposed.sql.deleteWhere
|
||||||
@@ -16,14 +17,16 @@ import org.jetbrains.exposed.sql.insert
|
|||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.jetbrains.exposed.sql.update
|
import org.jetbrains.exposed.sql.update
|
||||||
import suwayomi.tachidesk.impl.Manga.getManga
|
import suwayomi.tachidesk.manga.impl.Manga.getManga
|
||||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import suwayomi.tachidesk.manga.impl.util.GetHttpSource.getHttpSource
|
||||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
import suwayomi.tachidesk.manga.impl.util.lang.awaitSingle
|
||||||
import suwayomi.tachidesk.model.dataclass.ChapterDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.ChapterDataClass
|
||||||
import suwayomi.tachidesk.model.table.ChapterTable
|
import suwayomi.tachidesk.manga.model.table.ChapterMetaTable
|
||||||
import suwayomi.tachidesk.model.table.MangaTable
|
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||||
import suwayomi.tachidesk.model.table.PageTable
|
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||||
import suwayomi.tachidesk.model.table.toDataClass
|
import suwayomi.tachidesk.manga.model.table.PageTable
|
||||||
|
import suwayomi.tachidesk.manga.model.table.toDataClass
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
object Chapter {
|
object Chapter {
|
||||||
/** get chapter list when showing a manga */
|
/** get chapter list when showing a manga */
|
||||||
@@ -88,7 +91,7 @@ object Chapter {
|
|||||||
// clear any orphaned chapters that are in the db but not in `chapterList`
|
// clear any orphaned chapters that are in the db but not in `chapterList`
|
||||||
val dbChapterCount = transaction { ChapterTable.select { ChapterTable.manga eq mangaId }.count() }
|
val dbChapterCount = transaction { ChapterTable.select { ChapterTable.manga eq mangaId }.count() }
|
||||||
if (dbChapterCount > chapterCount) { // we got some clean up due
|
if (dbChapterCount > chapterCount) { // we got some clean up due
|
||||||
val dbChapterList = transaction { ChapterTable.select { ChapterTable.manga eq mangaId } }
|
val dbChapterList = transaction { ChapterTable.select { ChapterTable.manga eq mangaId }.toList() }
|
||||||
|
|
||||||
dbChapterList.forEach {
|
dbChapterList.forEach {
|
||||||
if (it[ChapterTable.chapterIndex] >= chapterList.size ||
|
if (it[ChapterTable.chapterIndex] >= chapterList.size ||
|
||||||
@@ -122,9 +125,15 @@ object Chapter {
|
|||||||
dbChapter[ChapterTable.isRead],
|
dbChapter[ChapterTable.isRead],
|
||||||
dbChapter[ChapterTable.isBookmarked],
|
dbChapter[ChapterTable.isBookmarked],
|
||||||
dbChapter[ChapterTable.lastPageRead],
|
dbChapter[ChapterTable.lastPageRead],
|
||||||
|
dbChapter[ChapterTable.lastReadAt],
|
||||||
|
|
||||||
chapterCount - index,
|
chapterCount - index,
|
||||||
chapterList.size
|
dbChapter[ChapterTable.isDownloaded],
|
||||||
|
|
||||||
|
dbChapter[ChapterTable.pageCount],
|
||||||
|
|
||||||
|
chapterList.size,
|
||||||
|
meta = getChapterMetaMap(dbChapter[ChapterTable.id])
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -136,54 +145,69 @@ object Chapter {
|
|||||||
(ChapterTable.chapterIndex eq chapterIndex) and (ChapterTable.manga eq mangaId)
|
(ChapterTable.chapterIndex eq chapterIndex) and (ChapterTable.manga eq mangaId)
|
||||||
}.first()
|
}.first()
|
||||||
}
|
}
|
||||||
val mangaEntry = transaction { MangaTable.select { MangaTable.id eq mangaId }.first() }
|
|
||||||
val source = getHttpSource(mangaEntry[MangaTable.sourceReference])
|
|
||||||
|
|
||||||
val pageList = source.fetchPageList(
|
return if (!chapterEntry[ChapterTable.isDownloaded]) {
|
||||||
SChapter.create().apply {
|
val mangaEntry = transaction { MangaTable.select { MangaTable.id eq mangaId }.first() }
|
||||||
url = chapterEntry[ChapterTable.url]
|
val source = getHttpSource(mangaEntry[MangaTable.sourceReference])
|
||||||
name = chapterEntry[ChapterTable.name]
|
|
||||||
}
|
|
||||||
).awaitSingle()
|
|
||||||
|
|
||||||
val chapterId = chapterEntry[ChapterTable.id].value
|
val pageList = source.fetchPageList(
|
||||||
val chapterCount = transaction { ChapterTable.select { ChapterTable.manga eq mangaId }.count() }
|
SChapter.create().apply {
|
||||||
|
url = chapterEntry[ChapterTable.url]
|
||||||
|
name = chapterEntry[ChapterTable.name]
|
||||||
|
}
|
||||||
|
).awaitSingle()
|
||||||
|
|
||||||
// update page list for this chapter
|
val chapterId = chapterEntry[ChapterTable.id].value
|
||||||
transaction {
|
val chapterCount = transaction { ChapterTable.select { ChapterTable.manga eq mangaId }.count() }
|
||||||
pageList.forEach { page ->
|
|
||||||
val pageEntry = transaction { PageTable.select { (PageTable.chapter eq chapterId) and (PageTable.index eq page.index) }.firstOrNull() }
|
// update page list for this chapter
|
||||||
if (pageEntry == null) {
|
transaction {
|
||||||
PageTable.insert {
|
pageList.forEach { page ->
|
||||||
it[index] = page.index
|
val pageEntry = transaction { PageTable.select { (PageTable.chapter eq chapterId) and (PageTable.index eq page.index) }.firstOrNull() }
|
||||||
it[url] = page.url
|
if (pageEntry == null) {
|
||||||
it[imageUrl] = page.imageUrl
|
PageTable.insert {
|
||||||
it[chapter] = chapterId
|
it[index] = page.index
|
||||||
}
|
it[url] = page.url
|
||||||
} else {
|
it[imageUrl] = page.imageUrl
|
||||||
PageTable.update({ (PageTable.chapter eq chapterId) and (PageTable.index eq page.index) }) {
|
it[chapter] = chapterId
|
||||||
it[url] = page.url
|
}
|
||||||
it[imageUrl] = page.imageUrl
|
} else {
|
||||||
|
PageTable.update({ (PageTable.chapter eq chapterId) and (PageTable.index eq page.index) }) {
|
||||||
|
it[url] = page.url
|
||||||
|
it[imageUrl] = page.imageUrl
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val pageCount = pageList.count()
|
||||||
|
|
||||||
|
transaction {
|
||||||
|
ChapterTable.update({ (ChapterTable.manga eq mangaId) and (ChapterTable.chapterIndex eq chapterIndex) }) {
|
||||||
|
it[ChapterTable.pageCount] = pageCount
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ChapterDataClass(
|
||||||
|
chapterEntry[ChapterTable.url],
|
||||||
|
chapterEntry[ChapterTable.name],
|
||||||
|
chapterEntry[ChapterTable.date_upload],
|
||||||
|
chapterEntry[ChapterTable.chapter_number],
|
||||||
|
chapterEntry[ChapterTable.scanlator],
|
||||||
|
mangaId,
|
||||||
|
chapterEntry[ChapterTable.isRead],
|
||||||
|
chapterEntry[ChapterTable.isBookmarked],
|
||||||
|
chapterEntry[ChapterTable.lastPageRead],
|
||||||
|
chapterEntry[ChapterTable.lastReadAt],
|
||||||
|
|
||||||
|
chapterEntry[ChapterTable.chapterIndex],
|
||||||
|
chapterEntry[ChapterTable.isDownloaded],
|
||||||
|
pageCount,
|
||||||
|
chapterCount.toInt(),
|
||||||
|
getChapterMetaMap(chapterEntry[ChapterTable.id])
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ChapterTable.toDataClass(chapterEntry)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ChapterDataClass(
|
|
||||||
chapterEntry[ChapterTable.url],
|
|
||||||
chapterEntry[ChapterTable.name],
|
|
||||||
chapterEntry[ChapterTable.date_upload],
|
|
||||||
chapterEntry[ChapterTable.chapter_number],
|
|
||||||
chapterEntry[ChapterTable.scanlator],
|
|
||||||
mangaId,
|
|
||||||
chapterEntry[ChapterTable.isRead],
|
|
||||||
chapterEntry[ChapterTable.isBookmarked],
|
|
||||||
chapterEntry[ChapterTable.lastPageRead],
|
|
||||||
|
|
||||||
chapterEntry[ChapterTable.chapterIndex],
|
|
||||||
chapterCount.toInt(),
|
|
||||||
pageList.count()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun modifyChapter(mangaId: Int, chapterIndex: Int, isRead: Boolean?, isBookmarked: Boolean?, markPrevRead: Boolean?, lastPageRead: Int?) {
|
fun modifyChapter(mangaId: Int, chapterIndex: Int, isRead: Boolean?, isBookmarked: Boolean?, markPrevRead: Boolean?, lastPageRead: Int?) {
|
||||||
@@ -198,6 +222,7 @@ object Chapter {
|
|||||||
}
|
}
|
||||||
lastPageRead?.also {
|
lastPageRead?.also {
|
||||||
update[ChapterTable.lastPageRead] = it
|
update[ChapterTable.lastPageRead] = it
|
||||||
|
update[ChapterTable.lastReadAt] = Instant.now().epochSecond
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,4 +234,30 @@ object Chapter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getChapterMetaMap(chapter: EntityID<Int>): Map<String, String> {
|
||||||
|
return transaction {
|
||||||
|
ChapterMetaTable.select { ChapterMetaTable.ref eq chapter }
|
||||||
|
.associate { it[ChapterMetaTable.key] to it[ChapterMetaTable.value] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun modifyChapterMeta(mangaId: Int, chapterIndex: Int, key: String, value: String) {
|
||||||
|
transaction {
|
||||||
|
val chapter = ChapterTable.select { (ChapterTable.manga eq mangaId) and (ChapterTable.chapterIndex eq chapterIndex) }
|
||||||
|
.first()[ChapterTable.id]
|
||||||
|
val meta = transaction { ChapterMetaTable.select { (ChapterMetaTable.ref eq chapter) and (ChapterMetaTable.key eq key) } }.firstOrNull()
|
||||||
|
if (meta == null) {
|
||||||
|
ChapterMetaTable.insert {
|
||||||
|
it[ChapterMetaTable.key] = key
|
||||||
|
it[ChapterMetaTable.value] = value
|
||||||
|
it[ChapterMetaTable.ref] = chapter
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ChapterMetaTable.update {
|
||||||
|
it[ChapterMetaTable.value] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+7
-7
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl
|
package suwayomi.tachidesk.manga.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -13,12 +13,12 @@ import org.jetbrains.exposed.sql.insert
|
|||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.jetbrains.exposed.sql.update
|
import org.jetbrains.exposed.sql.update
|
||||||
import suwayomi.tachidesk.impl.Manga.getManga
|
import suwayomi.tachidesk.manga.impl.Manga.getManga
|
||||||
import suwayomi.tachidesk.model.dataclass.MangaDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.MangaDataClass
|
||||||
import suwayomi.tachidesk.model.table.CategoryMangaTable
|
import suwayomi.tachidesk.manga.model.table.CategoryMangaTable
|
||||||
import suwayomi.tachidesk.model.table.CategoryTable
|
import suwayomi.tachidesk.manga.model.table.CategoryTable
|
||||||
import suwayomi.tachidesk.model.table.MangaTable
|
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||||
import suwayomi.tachidesk.model.table.toDataClass
|
import suwayomi.tachidesk.manga.model.table.toDataClass
|
||||||
|
|
||||||
object Library {
|
object Library {
|
||||||
// TODO: `Category.isLanding` is to handle the default categories a new library manga gets,
|
// TODO: `Category.isLanding` is to handle the default categories a new library manga gets,
|
||||||
+45
-13
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl
|
package suwayomi.tachidesk.manga.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -9,23 +9,27 @@ package suwayomi.tachidesk.impl
|
|||||||
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
import org.jetbrains.exposed.dao.id.EntityID
|
||||||
|
import org.jetbrains.exposed.sql.and
|
||||||
|
import org.jetbrains.exposed.sql.insert
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.jetbrains.exposed.sql.update
|
import org.jetbrains.exposed.sql.update
|
||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
import org.kodein.di.conf.global
|
import org.kodein.di.conf.global
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import suwayomi.server.ApplicationDirs
|
import suwayomi.tachidesk.manga.impl.MangaList.proxyThumbnailUrl
|
||||||
import suwayomi.tachidesk.impl.MangaList.proxyThumbnailUrl
|
import suwayomi.tachidesk.manga.impl.Source.getSource
|
||||||
import suwayomi.tachidesk.impl.Source.getSource
|
import suwayomi.tachidesk.manga.impl.util.GetHttpSource.getHttpSource
|
||||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import suwayomi.tachidesk.manga.impl.util.lang.awaitSingle
|
||||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
import suwayomi.tachidesk.manga.impl.util.network.await
|
||||||
import suwayomi.tachidesk.impl.util.network.await
|
import suwayomi.tachidesk.manga.impl.util.storage.CachedImageResponse.clearCachedImage
|
||||||
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.clearCachedImage
|
import suwayomi.tachidesk.manga.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
||||||
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
import suwayomi.tachidesk.manga.model.dataclass.MangaDataClass
|
||||||
import suwayomi.tachidesk.model.dataclass.MangaDataClass
|
import suwayomi.tachidesk.manga.model.table.MangaMetaTable
|
||||||
import suwayomi.tachidesk.model.table.MangaStatus
|
import suwayomi.tachidesk.manga.model.table.MangaStatus
|
||||||
import suwayomi.tachidesk.model.table.MangaTable
|
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||||
|
import suwayomi.tachidesk.server.ApplicationDirs
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
|
||||||
object Manga {
|
object Manga {
|
||||||
@@ -57,6 +61,7 @@ object Manga {
|
|||||||
MangaStatus.valueOf(mangaEntry[MangaTable.status]).name,
|
MangaStatus.valueOf(mangaEntry[MangaTable.status]).name,
|
||||||
mangaEntry[MangaTable.inLibrary],
|
mangaEntry[MangaTable.inLibrary],
|
||||||
getSource(mangaEntry[MangaTable.sourceReference]),
|
getSource(mangaEntry[MangaTable.sourceReference]),
|
||||||
|
getMangaMetaMap(mangaEntry[MangaTable.id]),
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
} else { // initialize manga
|
} else { // initialize manga
|
||||||
@@ -102,13 +107,40 @@ object Manga {
|
|||||||
fetchedManga.description,
|
fetchedManga.description,
|
||||||
fetchedManga.genre,
|
fetchedManga.genre,
|
||||||
MangaStatus.valueOf(fetchedManga.status).name,
|
MangaStatus.valueOf(fetchedManga.status).name,
|
||||||
false,
|
mangaEntry[MangaTable.inLibrary],
|
||||||
getSource(mangaEntry[MangaTable.sourceReference]),
|
getSource(mangaEntry[MangaTable.sourceReference]),
|
||||||
|
getMangaMetaMap(mangaEntry[MangaTable.id]),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getMangaMetaMap(manga: EntityID<Int>): Map<String, String> {
|
||||||
|
return transaction {
|
||||||
|
MangaMetaTable.select { MangaMetaTable.ref eq manga }
|
||||||
|
.associate { it[MangaMetaTable.key] to it[MangaMetaTable.value] }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun modifyMangaMeta(mangaId: Int, key: String, value: String) {
|
||||||
|
transaction {
|
||||||
|
val manga = MangaMetaTable.select { (MangaTable.id eq mangaId) }
|
||||||
|
.first()[MangaTable.id]
|
||||||
|
val meta = transaction { MangaMetaTable.select { (MangaMetaTable.ref eq manga) and (MangaMetaTable.key eq key) } }.firstOrNull()
|
||||||
|
if (meta == null) {
|
||||||
|
MangaMetaTable.insert {
|
||||||
|
it[MangaMetaTable.key] = key
|
||||||
|
it[MangaMetaTable.value] = value
|
||||||
|
it[MangaMetaTable.ref] = manga
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MangaMetaTable.update {
|
||||||
|
it[MangaMetaTable.value] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val applicationDirs by DI.global.instance<ApplicationDirs>()
|
private val applicationDirs by DI.global.instance<ApplicationDirs>()
|
||||||
suspend fun getMangaThumbnail(mangaId: Int): Pair<InputStream, String> {
|
suspend fun getMangaThumbnail(mangaId: Int): Pair<InputStream, String> {
|
||||||
val saveDir = applicationDirs.mangaThumbnailsRoot
|
val saveDir = applicationDirs.mangaThumbnailsRoot
|
||||||
+10
-8
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl
|
package suwayomi.tachidesk.manga.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -11,12 +11,13 @@ import eu.kanade.tachiyomi.source.model.MangasPage
|
|||||||
import org.jetbrains.exposed.sql.insertAndGetId
|
import org.jetbrains.exposed.sql.insertAndGetId
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import suwayomi.tachidesk.manga.impl.Manga.getMangaMetaMap
|
||||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
import suwayomi.tachidesk.manga.impl.util.GetHttpSource.getHttpSource
|
||||||
import suwayomi.tachidesk.model.dataclass.MangaDataClass
|
import suwayomi.tachidesk.manga.impl.util.lang.awaitSingle
|
||||||
import suwayomi.tachidesk.model.dataclass.PagedMangaListDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.MangaDataClass
|
||||||
import suwayomi.tachidesk.model.table.MangaStatus
|
import suwayomi.tachidesk.manga.model.dataclass.PagedMangaListDataClass
|
||||||
import suwayomi.tachidesk.model.table.MangaTable
|
import suwayomi.tachidesk.manga.model.table.MangaStatus
|
||||||
|
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||||
|
|
||||||
object MangaList {
|
object MangaList {
|
||||||
fun proxyThumbnailUrl(mangaId: Int): String {
|
fun proxyThumbnailUrl(mangaId: Int): String {
|
||||||
@@ -89,7 +90,8 @@ object MangaList {
|
|||||||
mangaEntry[MangaTable.description],
|
mangaEntry[MangaTable.description],
|
||||||
mangaEntry[MangaTable.genre],
|
mangaEntry[MangaTable.genre],
|
||||||
MangaStatus.valueOf(mangaEntry[MangaTable.status]).name,
|
MangaStatus.valueOf(mangaEntry[MangaTable.status]).name,
|
||||||
mangaEntry[MangaTable.inLibrary]
|
mangaEntry[MangaTable.inLibrary],
|
||||||
|
meta = getMangaMetaMap(mangaEntry[MangaTable.id])
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+9
-9
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl
|
package suwayomi.tachidesk.manga.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -16,14 +16,14 @@ import org.jetbrains.exposed.sql.update
|
|||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
import org.kodein.di.conf.global
|
import org.kodein.di.conf.global
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import suwayomi.server.ApplicationDirs
|
import suwayomi.tachidesk.manga.impl.util.GetHttpSource.getHttpSource
|
||||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import suwayomi.tachidesk.manga.impl.util.lang.awaitSingle
|
||||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
import suwayomi.tachidesk.manga.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
||||||
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
import suwayomi.tachidesk.manga.impl.util.storage.SafePath
|
||||||
import suwayomi.tachidesk.impl.util.storage.SafePath
|
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||||
import suwayomi.tachidesk.model.table.ChapterTable
|
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||||
import suwayomi.tachidesk.model.table.MangaTable
|
import suwayomi.tachidesk.manga.model.table.PageTable
|
||||||
import suwayomi.tachidesk.model.table.PageTable
|
import suwayomi.tachidesk.server.ApplicationDirs
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
|
||||||
+5
-5
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl
|
package suwayomi.tachidesk.manga.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -7,10 +7,10 @@ package suwayomi.tachidesk.impl
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
import suwayomi.tachidesk.impl.MangaList.processEntries
|
import suwayomi.tachidesk.manga.impl.MangaList.processEntries
|
||||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import suwayomi.tachidesk.manga.impl.util.GetHttpSource.getHttpSource
|
||||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
import suwayomi.tachidesk.manga.impl.util.lang.awaitSingle
|
||||||
import suwayomi.tachidesk.model.dataclass.PagedMangaListDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.PagedMangaListDataClass
|
||||||
|
|
||||||
object Search {
|
object Search {
|
||||||
// TODO
|
// TODO
|
||||||
+6
-6
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl
|
package suwayomi.tachidesk.manga.impl
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -11,11 +11,11 @@ import mu.KotlinLogging
|
|||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.selectAll
|
import org.jetbrains.exposed.sql.selectAll
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import suwayomi.tachidesk.impl.extension.Extension.getExtensionIconUrl
|
import suwayomi.tachidesk.manga.impl.extension.Extension.getExtensionIconUrl
|
||||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import suwayomi.tachidesk.manga.impl.util.GetHttpSource.getHttpSource
|
||||||
import suwayomi.tachidesk.model.dataclass.SourceDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.SourceDataClass
|
||||||
import suwayomi.tachidesk.model.table.ExtensionTable
|
import suwayomi.tachidesk.manga.model.table.ExtensionTable
|
||||||
import suwayomi.tachidesk.model.table.SourceTable
|
import suwayomi.tachidesk.manga.model.table.SourceTable
|
||||||
|
|
||||||
object Source {
|
object Source {
|
||||||
private val logger = KotlinLogging.logger {}
|
private val logger = KotlinLogging.logger {}
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup
|
package suwayomi.tachidesk.manga.impl.backup
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
+11
-11
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.legacy
|
package suwayomi.tachidesk.manga.impl.backup.legacy
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -11,16 +11,16 @@ import com.github.salomonbrys.kotson.registerTypeAdapter
|
|||||||
import com.github.salomonbrys.kotson.registerTypeHierarchyAdapter
|
import com.github.salomonbrys.kotson.registerTypeHierarchyAdapter
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.GsonBuilder
|
import com.google.gson.GsonBuilder
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.models.DHistory
|
import suwayomi.tachidesk.manga.impl.backup.legacy.models.DHistory
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.serializer.CategoryTypeAdapter
|
import suwayomi.tachidesk.manga.impl.backup.legacy.serializer.CategoryTypeAdapter
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.serializer.ChapterTypeAdapter
|
import suwayomi.tachidesk.manga.impl.backup.legacy.serializer.ChapterTypeAdapter
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.serializer.HistoryTypeAdapter
|
import suwayomi.tachidesk.manga.impl.backup.legacy.serializer.HistoryTypeAdapter
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.serializer.MangaTypeAdapter
|
import suwayomi.tachidesk.manga.impl.backup.legacy.serializer.MangaTypeAdapter
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.serializer.TrackTypeAdapter
|
import suwayomi.tachidesk.manga.impl.backup.legacy.serializer.TrackTypeAdapter
|
||||||
import suwayomi.tachidesk.impl.backup.models.CategoryImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.CategoryImpl
|
||||||
import suwayomi.tachidesk.impl.backup.models.ChapterImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.ChapterImpl
|
||||||
import suwayomi.tachidesk.impl.backup.models.MangaImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.MangaImpl
|
||||||
import suwayomi.tachidesk.impl.backup.models.TrackImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.TrackImpl
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
open class LegacyBackupBase {
|
open class LegacyBackupBase {
|
||||||
+13
-13
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.legacy
|
package suwayomi.tachidesk.manga.impl.backup.legacy
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -14,18 +14,18 @@ import com.google.gson.JsonObject
|
|||||||
import eu.kanade.tachiyomi.source.LocalSource
|
import eu.kanade.tachiyomi.source.LocalSource
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import suwayomi.tachidesk.impl.Category.getCategoryList
|
import suwayomi.tachidesk.manga.impl.Category.getCategoryList
|
||||||
import suwayomi.tachidesk.impl.CategoryManga.getMangaCategories
|
import suwayomi.tachidesk.manga.impl.CategoryManga.getMangaCategories
|
||||||
import suwayomi.tachidesk.impl.backup.BackupFlags
|
import suwayomi.tachidesk.manga.impl.backup.BackupFlags
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.models.Backup
|
import suwayomi.tachidesk.manga.impl.backup.legacy.models.Backup
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.models.Backup.CURRENT_VERSION
|
import suwayomi.tachidesk.manga.impl.backup.legacy.models.Backup.CURRENT_VERSION
|
||||||
import suwayomi.tachidesk.impl.backup.models.CategoryImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.CategoryImpl
|
||||||
import suwayomi.tachidesk.impl.backup.models.ChapterImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.ChapterImpl
|
||||||
import suwayomi.tachidesk.impl.backup.models.Manga
|
import suwayomi.tachidesk.manga.impl.backup.models.Manga
|
||||||
import suwayomi.tachidesk.impl.backup.models.MangaImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.MangaImpl
|
||||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import suwayomi.tachidesk.manga.impl.util.GetHttpSource.getHttpSource
|
||||||
import suwayomi.tachidesk.model.table.ChapterTable
|
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||||
import suwayomi.tachidesk.model.table.MangaTable
|
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||||
|
|
||||||
object LegacyBackupExport : LegacyBackupBase() {
|
object LegacyBackupExport : LegacyBackupBase() {
|
||||||
|
|
||||||
+17
-17
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.legacy
|
package suwayomi.tachidesk.manga.impl.backup.legacy
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.fromJson
|
import com.github.salomonbrys.kotson.fromJson
|
||||||
import com.google.gson.JsonArray
|
import com.google.gson.JsonArray
|
||||||
@@ -13,22 +13,22 @@ import org.jetbrains.exposed.sql.insert
|
|||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.jetbrains.exposed.sql.update
|
import org.jetbrains.exposed.sql.update
|
||||||
import suwayomi.tachidesk.impl.Category.createCategory
|
import suwayomi.tachidesk.manga.impl.Category.createCategory
|
||||||
import suwayomi.tachidesk.impl.Category.getCategoryList
|
import suwayomi.tachidesk.manga.impl.Category.getCategoryList
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.LegacyBackupValidator.ValidationResult
|
import suwayomi.tachidesk.manga.impl.backup.legacy.LegacyBackupValidator.ValidationResult
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.LegacyBackupValidator.validate
|
import suwayomi.tachidesk.manga.impl.backup.legacy.LegacyBackupValidator.validate
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.models.Backup
|
import suwayomi.tachidesk.manga.impl.backup.legacy.models.Backup
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.models.DHistory
|
import suwayomi.tachidesk.manga.impl.backup.legacy.models.DHistory
|
||||||
import suwayomi.tachidesk.impl.backup.models.CategoryImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.CategoryImpl
|
||||||
import suwayomi.tachidesk.impl.backup.models.Chapter
|
import suwayomi.tachidesk.manga.impl.backup.models.Chapter
|
||||||
import suwayomi.tachidesk.impl.backup.models.ChapterImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.ChapterImpl
|
||||||
import suwayomi.tachidesk.impl.backup.models.Manga
|
import suwayomi.tachidesk.manga.impl.backup.models.Manga
|
||||||
import suwayomi.tachidesk.impl.backup.models.MangaImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.MangaImpl
|
||||||
import suwayomi.tachidesk.impl.backup.models.Track
|
import suwayomi.tachidesk.manga.impl.backup.models.Track
|
||||||
import suwayomi.tachidesk.impl.backup.models.TrackImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.TrackImpl
|
||||||
import suwayomi.tachidesk.impl.util.GetHttpSource.getHttpSource
|
import suwayomi.tachidesk.manga.impl.util.GetHttpSource.getHttpSource
|
||||||
import suwayomi.tachidesk.impl.util.lang.awaitSingle
|
import suwayomi.tachidesk.manga.impl.util.lang.awaitSingle
|
||||||
import suwayomi.tachidesk.model.table.MangaTable
|
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
||||||
+3
-3
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.legacy
|
package suwayomi.tachidesk.manga.impl.backup.legacy
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -10,8 +10,8 @@ package suwayomi.tachidesk.impl.backup.legacy
|
|||||||
import com.google.gson.JsonObject
|
import com.google.gson.JsonObject
|
||||||
import org.jetbrains.exposed.sql.select
|
import org.jetbrains.exposed.sql.select
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.models.Backup
|
import suwayomi.tachidesk.manga.impl.backup.legacy.models.Backup
|
||||||
import suwayomi.tachidesk.model.table.SourceTable
|
import suwayomi.tachidesk.manga.model.table.SourceTable
|
||||||
|
|
||||||
object LegacyBackupValidator {
|
object LegacyBackupValidator {
|
||||||
data class ValidationResult(val missingSources: List<String>, val missingTrackers: List<String>)
|
data class ValidationResult(val missingSources: List<String>, val missingTrackers: List<String>)
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.legacy.models
|
package suwayomi.tachidesk.manga.impl.backup.legacy.models
|
||||||
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package suwayomi.tachidesk.manga.impl.backup.legacy.models
|
||||||
|
|
||||||
|
data class DHistory(val url: String, val lastRead: Long)
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.legacy.serializer
|
package suwayomi.tachidesk.manga.impl.backup.legacy.serializer
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.typeAdapter
|
import com.github.salomonbrys.kotson.typeAdapter
|
||||||
import com.google.gson.TypeAdapter
|
import com.google.gson.TypeAdapter
|
||||||
import suwayomi.tachidesk.impl.backup.models.CategoryImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.CategoryImpl
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON Serializer used to write / read [CategoryImpl] to / from json
|
* JSON Serializer used to write / read [CategoryImpl] to / from json
|
||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.legacy.serializer
|
package suwayomi.tachidesk.manga.impl.backup.legacy.serializer
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.typeAdapter
|
import com.github.salomonbrys.kotson.typeAdapter
|
||||||
import com.google.gson.TypeAdapter
|
import com.google.gson.TypeAdapter
|
||||||
import com.google.gson.stream.JsonToken
|
import com.google.gson.stream.JsonToken
|
||||||
import suwayomi.tachidesk.impl.backup.models.ChapterImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.ChapterImpl
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON Serializer used to write / read [ChapterImpl] to / from json
|
* JSON Serializer used to write / read [ChapterImpl] to / from json
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.legacy.serializer
|
package suwayomi.tachidesk.manga.impl.backup.legacy.serializer
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.typeAdapter
|
import com.github.salomonbrys.kotson.typeAdapter
|
||||||
import com.google.gson.TypeAdapter
|
import com.google.gson.TypeAdapter
|
||||||
import suwayomi.tachidesk.impl.backup.legacy.models.DHistory
|
import suwayomi.tachidesk.manga.impl.backup.legacy.models.DHistory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON Serializer used to write / read [DHistory] to / from json
|
* JSON Serializer used to write / read [DHistory] to / from json
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.legacy.serializer
|
package suwayomi.tachidesk.manga.impl.backup.legacy.serializer
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.typeAdapter
|
import com.github.salomonbrys.kotson.typeAdapter
|
||||||
import com.google.gson.TypeAdapter
|
import com.google.gson.TypeAdapter
|
||||||
import suwayomi.tachidesk.impl.backup.models.MangaImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.MangaImpl
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON Serializer used to write / read [MangaImpl] to / from json
|
* JSON Serializer used to write / read [MangaImpl] to / from json
|
||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.legacy.serializer
|
package suwayomi.tachidesk.manga.impl.backup.legacy.serializer
|
||||||
|
|
||||||
import com.github.salomonbrys.kotson.typeAdapter
|
import com.github.salomonbrys.kotson.typeAdapter
|
||||||
import com.google.gson.TypeAdapter
|
import com.google.gson.TypeAdapter
|
||||||
import com.google.gson.stream.JsonToken
|
import com.google.gson.stream.JsonToken
|
||||||
import suwayomi.tachidesk.impl.backup.models.TrackImpl
|
import suwayomi.tachidesk.manga.impl.backup.models.TrackImpl
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON Serializer used to write / read [TrackImpl] to / from json
|
* JSON Serializer used to write / read [TrackImpl] to / from json
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
class CategoryImpl : Category {
|
class CategoryImpl : Category {
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
import org.jetbrains.exposed.sql.ResultRow
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
import suwayomi.tachidesk.model.table.ChapterTable
|
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||||
|
|
||||||
class ChapterImpl : Chapter {
|
class ChapterImpl : Chapter {
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object containing the history statistics of a chapter
|
* Object containing the history statistics of a chapter
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
class LibraryManga : MangaImpl() {
|
class LibraryManga : MangaImpl() {
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
class MangaCategory {
|
class MangaCategory {
|
||||||
|
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
class MangaChapter(val manga: Manga, val chapter: Chapter)
|
class MangaChapter(val manga: Manga, val chapter: Chapter)
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object containing manga, chapter and history
|
* Object containing manga, chapter and history
|
||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
import org.jetbrains.exposed.sql.ResultRow
|
import org.jetbrains.exposed.sql.ResultRow
|
||||||
import suwayomi.tachidesk.model.table.MangaTable
|
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||||
|
|
||||||
open class MangaImpl : Manga {
|
open class MangaImpl : Manga {
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.backup.models
|
package suwayomi.tachidesk.manga.impl.backup.models
|
||||||
|
|
||||||
class TrackImpl : Track {
|
class TrackImpl : Track {
|
||||||
|
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
package suwayomi.tachidesk.manga.impl.download
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import io.javalin.websocket.WsContext
|
||||||
|
import io.javalin.websocket.WsMessageContext
|
||||||
|
import org.jetbrains.exposed.sql.and
|
||||||
|
import org.jetbrains.exposed.sql.select
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
import suwayomi.tachidesk.manga.impl.download.model.DownloadChapter
|
||||||
|
import suwayomi.tachidesk.manga.impl.download.model.DownloadState.Downloading
|
||||||
|
import suwayomi.tachidesk.manga.impl.download.model.DownloadStatus
|
||||||
|
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||||
|
import suwayomi.tachidesk.manga.model.table.toDataClass
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
|
|
||||||
|
object DownloadManager {
|
||||||
|
private val clients = ConcurrentHashMap<String, WsContext>()
|
||||||
|
private val downloadQueue = CopyOnWriteArrayList<DownloadChapter>()
|
||||||
|
private var downloader: Downloader? = null
|
||||||
|
|
||||||
|
fun addClient(ctx: WsContext) {
|
||||||
|
clients[ctx.sessionId] = ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeClient(ctx: WsContext) {
|
||||||
|
clients.remove(ctx.sessionId)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun notifyClient(ctx: WsContext) {
|
||||||
|
ctx.send(
|
||||||
|
getStatus()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleRequest(ctx: WsMessageContext) {
|
||||||
|
when (ctx.message()) {
|
||||||
|
"STATUS" -> notifyClient(ctx)
|
||||||
|
else -> ctx.send(
|
||||||
|
"""
|
||||||
|
|Invalid command.
|
||||||
|
|Supported commands are:
|
||||||
|
| - STATUS
|
||||||
|
| sends the current download status
|
||||||
|
|""".trimMargin()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notifyAllClients() {
|
||||||
|
val status = getStatus()
|
||||||
|
clients.forEach {
|
||||||
|
it.value.send(status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getStatus(): DownloadStatus {
|
||||||
|
return DownloadStatus(
|
||||||
|
if (downloader == null ||
|
||||||
|
downloadQueue.none { it.state == Downloading }
|
||||||
|
) "Stopped" else "Started",
|
||||||
|
downloadQueue
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enqueue(chapterIndex: Int, mangaId: Int) {
|
||||||
|
if (downloadQueue.none { it.mangaId == mangaId && it.chapterIndex == chapterIndex }) {
|
||||||
|
downloadQueue.add(
|
||||||
|
DownloadChapter(
|
||||||
|
chapterIndex,
|
||||||
|
mangaId,
|
||||||
|
chapter = ChapterTable.toDataClass(
|
||||||
|
transaction {
|
||||||
|
ChapterTable.select { (ChapterTable.manga eq mangaId) and (ChapterTable.chapterIndex eq chapterIndex) }
|
||||||
|
.first()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
start()
|
||||||
|
}
|
||||||
|
notifyAllClients()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unqueue(chapterIndex: Int, mangaId: Int) {
|
||||||
|
downloadQueue.removeIf { it.mangaId == mangaId && it.chapterIndex == chapterIndex }
|
||||||
|
notifyAllClients()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun start() {
|
||||||
|
if (downloader != null && !downloader?.isAlive!!) // doesn't exist or is dead
|
||||||
|
downloader = null
|
||||||
|
|
||||||
|
if (downloader == null) {
|
||||||
|
downloader = Downloader(downloadQueue) { notifyAllClients() }
|
||||||
|
downloader!!.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyAllClients()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stop() {
|
||||||
|
downloader?.let {
|
||||||
|
synchronized(it.shouldStop) {
|
||||||
|
it.shouldStop = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
downloader = null
|
||||||
|
notifyAllClients()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clear() {
|
||||||
|
stop()
|
||||||
|
downloadQueue.clear()
|
||||||
|
notifyAllClients()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class DownloaderState(val state: Int) {
|
||||||
|
Stopped(0),
|
||||||
|
Running(1),
|
||||||
|
Paused(2),
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package suwayomi.tachidesk.manga.impl.download
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.jetbrains.exposed.sql.and
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
import org.jetbrains.exposed.sql.update
|
||||||
|
import suwayomi.tachidesk.manga.impl.Chapter.getChapter
|
||||||
|
import suwayomi.tachidesk.manga.impl.Page.getPageImage
|
||||||
|
import suwayomi.tachidesk.manga.impl.download.model.DownloadChapter
|
||||||
|
import suwayomi.tachidesk.manga.impl.download.model.DownloadState.Downloading
|
||||||
|
import suwayomi.tachidesk.manga.impl.download.model.DownloadState.Error
|
||||||
|
import suwayomi.tachidesk.manga.impl.download.model.DownloadState.Finished
|
||||||
|
import suwayomi.tachidesk.manga.impl.download.model.DownloadState.Queued
|
||||||
|
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
|
|
||||||
|
class Downloader(private val downloadQueue: CopyOnWriteArrayList<DownloadChapter>, val notifier: () -> Unit) : Thread() {
|
||||||
|
var shouldStop: Boolean = false
|
||||||
|
|
||||||
|
class DownloadShouldStopException : Exception()
|
||||||
|
|
||||||
|
fun step() {
|
||||||
|
notifier()
|
||||||
|
synchronized(shouldStop) {
|
||||||
|
if (shouldStop) throw DownloadShouldStopException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun run() {
|
||||||
|
do {
|
||||||
|
val download = downloadQueue.firstOrNull {
|
||||||
|
it.state == Queued ||
|
||||||
|
(it.state == Error && it.tries < 3) // 3 re-tries per download
|
||||||
|
} ?: break
|
||||||
|
|
||||||
|
try {
|
||||||
|
download.state = Downloading
|
||||||
|
step()
|
||||||
|
|
||||||
|
download.chapter = runBlocking { getChapter(download.chapterIndex, download.mangaId) }
|
||||||
|
step()
|
||||||
|
|
||||||
|
val pageCount = download.chapter!!.pageCount
|
||||||
|
for (pageNum in 0 until pageCount) {
|
||||||
|
runBlocking { getPageImage(download.mangaId, download.chapterIndex, pageNum) }
|
||||||
|
// TODO: retry on error with 2,4,8 seconds of wait
|
||||||
|
// TODO: download multiple pages at once, possible solution: rx observer's strategy is used in Tachiyomi
|
||||||
|
// TODO: fine grained download percentage
|
||||||
|
download.progress = (pageNum + 1).toFloat() / pageCount
|
||||||
|
step()
|
||||||
|
}
|
||||||
|
download.state = Finished
|
||||||
|
transaction {
|
||||||
|
ChapterTable.update({ (ChapterTable.manga eq download.mangaId) and (ChapterTable.chapterIndex eq download.chapterIndex) }) {
|
||||||
|
it[isDownloaded] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
step()
|
||||||
|
|
||||||
|
downloadQueue.removeIf { it.mangaId == download.mangaId && it.chapterIndex == download.chapterIndex }
|
||||||
|
step()
|
||||||
|
} catch (e: DownloadShouldStopException) {
|
||||||
|
println("Downloader was stopped")
|
||||||
|
downloadQueue.filter { it.state == Downloading }.forEach { it.state = Queued }
|
||||||
|
} catch (e: Exception) {
|
||||||
|
println("Downloader faced an exception")
|
||||||
|
downloadQueue.filter { it.state == Downloading }.forEach { it.state = Error; it.tries++ }
|
||||||
|
e.printStackTrace()
|
||||||
|
} finally {
|
||||||
|
notifier()
|
||||||
|
}
|
||||||
|
} while (!shouldStop)
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
package suwayomi.tachidesk.manga.impl.download.model
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import suwayomi.tachidesk.manga.impl.download.model.DownloadState.Queued
|
||||||
|
import suwayomi.tachidesk.manga.model.dataclass.ChapterDataClass
|
||||||
|
|
||||||
|
class DownloadChapter(
|
||||||
|
val chapterIndex: Int,
|
||||||
|
val mangaId: Int,
|
||||||
|
var state: DownloadState = Queued,
|
||||||
|
var progress: Float = 0f,
|
||||||
|
var tries: Int = 0,
|
||||||
|
var chapter: ChapterDataClass? = null,
|
||||||
|
)
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package suwayomi.tachidesk.manga.impl.download.model
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
enum class DownloadState(val state: Int) {
|
||||||
|
Queued(0),
|
||||||
|
Downloading(1),
|
||||||
|
Finished(2),
|
||||||
|
Error(3),
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package suwayomi.tachidesk.manga.impl.download.model
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
data class DownloadStatus(
|
||||||
|
val status: String,
|
||||||
|
val queue: List<DownloadChapter>,
|
||||||
|
)
|
||||||
+18
-18
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.extension
|
package suwayomi.tachidesk.manga.impl.extension
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -25,23 +25,23 @@ import org.jetbrains.exposed.sql.update
|
|||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
import org.kodein.di.conf.global
|
import org.kodein.di.conf.global
|
||||||
import org.kodein.di.instance
|
import org.kodein.di.instance
|
||||||
import suwayomi.server.ApplicationDirs
|
import suwayomi.tachidesk.manga.impl.extension.ExtensionsList.extensionTableAsDataClass
|
||||||
import suwayomi.tachidesk.impl.extension.ExtensionsList.extensionTableAsDataClass
|
import suwayomi.tachidesk.manga.impl.extension.github.ExtensionGithubApi
|
||||||
import suwayomi.tachidesk.impl.extension.github.ExtensionGithubApi
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.EXTENSION_FEATURE
|
||||||
import suwayomi.tachidesk.impl.util.PackageTools.EXTENSION_FEATURE
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.LIB_VERSION_MAX
|
||||||
import suwayomi.tachidesk.impl.util.PackageTools.LIB_VERSION_MAX
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.LIB_VERSION_MIN
|
||||||
import suwayomi.tachidesk.impl.util.PackageTools.LIB_VERSION_MIN
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.METADATA_NSFW
|
||||||
import suwayomi.tachidesk.impl.util.PackageTools.METADATA_NSFW
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.METADATA_SOURCE_CLASS
|
||||||
import suwayomi.tachidesk.impl.util.PackageTools.METADATA_SOURCE_CLASS
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.dex2jar
|
||||||
import suwayomi.tachidesk.impl.util.PackageTools.dex2jar
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.getPackageInfo
|
||||||
import suwayomi.tachidesk.impl.util.PackageTools.getPackageInfo
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.getSignatureHash
|
||||||
import suwayomi.tachidesk.impl.util.PackageTools.getSignatureHash
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.loadExtensionSources
|
||||||
import suwayomi.tachidesk.impl.util.PackageTools.loadExtensionSources
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.trustedSignatures
|
||||||
import suwayomi.tachidesk.impl.util.PackageTools.trustedSignatures
|
import suwayomi.tachidesk.manga.impl.util.network.await
|
||||||
import suwayomi.tachidesk.impl.util.network.await
|
import suwayomi.tachidesk.manga.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
||||||
import suwayomi.tachidesk.impl.util.storage.CachedImageResponse.getCachedImageResponse
|
import suwayomi.tachidesk.manga.model.table.ExtensionTable
|
||||||
import suwayomi.tachidesk.model.table.ExtensionTable
|
import suwayomi.tachidesk.manga.model.table.SourceTable
|
||||||
import suwayomi.tachidesk.model.table.SourceTable
|
import suwayomi.tachidesk.server.ApplicationDirs
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
+6
-6
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.extension
|
package suwayomi.tachidesk.manga.impl.extension
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -14,11 +14,11 @@ import org.jetbrains.exposed.sql.select
|
|||||||
import org.jetbrains.exposed.sql.selectAll
|
import org.jetbrains.exposed.sql.selectAll
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.jetbrains.exposed.sql.update
|
import org.jetbrains.exposed.sql.update
|
||||||
import suwayomi.tachidesk.impl.extension.Extension.getExtensionIconUrl
|
import suwayomi.tachidesk.manga.impl.extension.Extension.getExtensionIconUrl
|
||||||
import suwayomi.tachidesk.impl.extension.github.ExtensionGithubApi
|
import suwayomi.tachidesk.manga.impl.extension.github.ExtensionGithubApi
|
||||||
import suwayomi.tachidesk.impl.extension.github.OnlineExtension
|
import suwayomi.tachidesk.manga.impl.extension.github.OnlineExtension
|
||||||
import suwayomi.tachidesk.model.dataclass.ExtensionDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.ExtensionDataClass
|
||||||
import suwayomi.tachidesk.model.table.ExtensionTable
|
import suwayomi.tachidesk.manga.model.table.ExtensionTable
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
object ExtensionsList {
|
object ExtensionsList {
|
||||||
+8
-12
@@ -1,4 +1,4 @@
|
|||||||
package suwayomi.tachidesk.impl.extension.github
|
package suwayomi.tachidesk.manga.impl.extension.github
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (C) Contributors to the Suwayomi project
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
@@ -13,16 +13,14 @@ import com.google.gson.JsonArray
|
|||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import suwayomi.tachidesk.impl.util.network.UnzippingInterceptor
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.LIB_VERSION_MAX
|
||||||
import suwayomi.tachidesk.model.dataclass.ExtensionDataClass
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.LIB_VERSION_MIN
|
||||||
|
import suwayomi.tachidesk.manga.model.dataclass.ExtensionDataClass
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
object ExtensionGithubApi {
|
object ExtensionGithubApi {
|
||||||
const val BASE_URL = "https://raw.githubusercontent.com"
|
private const val BASE_URL = "https://raw.githubusercontent.com"
|
||||||
const val REPO_URL_PREFIX = "$BASE_URL/tachiyomiorg/tachiyomi-extensions/repo"
|
private const val REPO_URL_PREFIX = "$BASE_URL/tachiyomiorg/tachiyomi-extensions/repo"
|
||||||
|
|
||||||
private const val LIB_VERSION_MIN = 1.2
|
|
||||||
private const val LIB_VERSION_MAX = 1.2
|
|
||||||
|
|
||||||
private fun parseResponse(json: JsonArray): List<OnlineExtension> {
|
private fun parseResponse(json: JsonArray): List<OnlineExtension> {
|
||||||
return json
|
return json
|
||||||
@@ -61,17 +59,15 @@ object ExtensionGithubApi {
|
|||||||
.addNetworkInterceptor { chain ->
|
.addNetworkInterceptor { chain ->
|
||||||
val originalResponse = chain.proceed(chain.request())
|
val originalResponse = chain.proceed(chain.request())
|
||||||
originalResponse.newBuilder()
|
originalResponse.newBuilder()
|
||||||
.header("Content-Encoding", "gzip")
|
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
.addInterceptor(UnzippingInterceptor())
|
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getRepo(): com.google.gson.JsonArray {
|
private fun getRepo(): JsonArray {
|
||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url("$REPO_URL_PREFIX/index.json.gz")
|
.url("$REPO_URL_PREFIX/index.min.json")
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val response = client.newCall(request).execute().use { response -> response.body!!.string() }
|
val response = client.newCall(request).execute().use { response -> response.body!!.string() }
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package suwayomi.tachidesk.manga.impl.extension.github
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) Contributors to the Suwayomi project
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
data class OnlineExtension(
|
||||||
|
val name: String,
|
||||||
|
val pkgName: String,
|
||||||
|
val versionName: String,
|
||||||
|
val versionCode: Int,
|
||||||
|
val lang: String,
|
||||||
|
val isNsfw: Boolean,
|
||||||
|
val apkName: String,
|
||||||
|
val iconUrl: String
|
||||||
|
)
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user