mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-16 16:20:04 +00:00
Got 3rd party dependencies working in development mode
This commit is contained in:
@@ -45,5 +45,6 @@ docker-compose.yml
|
|||||||
generated
|
generated
|
||||||
db
|
db
|
||||||
data
|
data
|
||||||
|
packaged_plugins
|
||||||
logs
|
logs
|
||||||
templates
|
templates
|
||||||
|
|||||||
@@ -32,8 +32,4 @@ subprojects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named("build") {
|
|
||||||
dependsOn(":gameyfin:uberJar")
|
|
||||||
}
|
|
||||||
|
|
||||||
extra.set("pluginDir", rootProject.layout.buildDirectory.get().asFile.resolve("plugins"))
|
extra.set("pluginDir", rootProject.layout.buildDirectory.get().asFile.resolve("plugins"))
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
group = "de.grimsi"
|
group = "de.grimsi"
|
||||||
val pluginDir: File by rootProject.extra
|
|
||||||
val appMainClass = "de.grimsi.gameyfin.GameyfinApplication"
|
val appMainClass = "de.grimsi.gameyfin.GameyfinApplication"
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
@@ -86,31 +85,6 @@ dependencyManagement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named<JavaExec>("run") {
|
|
||||||
systemProperty("pf4j.pluginsDir", pluginDir.absolutePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.register<Jar>("uberJar") {
|
|
||||||
dependsOn(tasks.named("compileKotlin"))
|
|
||||||
archiveClassifier.set("uber")
|
|
||||||
|
|
||||||
from(sourceSets.main.get().output)
|
|
||||||
|
|
||||||
dependsOn(configurations.runtimeClasspath)
|
|
||||||
from({
|
|
||||||
configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) }
|
|
||||||
})
|
|
||||||
|
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
|
||||||
isZip64 = true
|
|
||||||
|
|
||||||
manifest {
|
|
||||||
attributes["Main-Class"] = appMainClass
|
|
||||||
}
|
|
||||||
|
|
||||||
archiveBaseName.set(project.name)
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.withType<Test> {
|
tasks.withType<Test> {
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
@@ -10,10 +10,10 @@ import java.nio.file.Path
|
|||||||
@Configuration
|
@Configuration
|
||||||
class PluginManagerConfig {
|
class PluginManagerConfig {
|
||||||
private val log = KotlinLogging.logger {}
|
private val log = KotlinLogging.logger {}
|
||||||
private val pluginPath = Path.of("plugins")
|
private val pluginPath = System.getProperty("pf4j.pluginsDir", "plugins")
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
fun pluginManager() = SpringDevtoolsPluginManager(pluginPath)
|
fun pluginManager() = SpringDevtoolsPluginManager(Path.of(pluginPath))
|
||||||
|
|
||||||
@EventListener(ApplicationReadyEvent::class)
|
@EventListener(ApplicationReadyEvent::class)
|
||||||
fun loadedPlugins() {
|
fun loadedPlugins() {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class AsyncFileTailer(
|
|||||||
tailer.run()
|
tailer.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info { "Started tailing the file: ${file.name}" }
|
log.debug { "Started tailing the file: ${file.name}" }
|
||||||
} else {
|
} else {
|
||||||
log.error { "File tailing for file ${file.name} is already running!" }
|
log.error { "File tailing for file ${file.name} is already running!" }
|
||||||
}
|
}
|
||||||
@@ -58,7 +58,7 @@ class AsyncFileTailer(
|
|||||||
tailerJob?.let {
|
tailerJob?.let {
|
||||||
it.cancel()
|
it.cancel()
|
||||||
tailerJob = null
|
tailerJob = null
|
||||||
log.info { "Stopped tailing the file: ${file.name}" }
|
log.debug { "Stopped tailing the file: ${file.name}" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,9 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// PF4J (shared)
|
// PF4J (shared)
|
||||||
api("org.pf4j:pf4j:${rootProject.extra["pf4jVersion"]}")
|
api("org.pf4j:pf4j:${rootProject.extra["pf4jVersion"]}") {
|
||||||
|
exclude(group = "org.slf4j")
|
||||||
|
}
|
||||||
|
|
||||||
implementation(kotlin("stdlib"))
|
implementation(kotlin("stdlib"))
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package de.grimsi.gameyfin.pluginapi.core
|
||||||
|
|
||||||
|
import org.pf4j.Plugin
|
||||||
|
|
||||||
|
abstract class GameyfinPlugin(protected val context: PluginContext) : Plugin()
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
package de.grimsi.gameyfin.pluginapi.core
|
||||||
|
|
||||||
|
class PluginConfigError(message: String) : RuntimeException(message)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package de.grimsi.gameyfin.pluginapi.core
|
||||||
|
|
||||||
|
import org.pf4j.RuntimeMode
|
||||||
|
|
||||||
|
class PluginContext(private val runtimeMode: RuntimeMode) {
|
||||||
|
fun getRuntimeMode(): RuntimeMode {
|
||||||
|
return runtimeMode
|
||||||
|
}
|
||||||
|
}
|
||||||
-2
@@ -3,7 +3,5 @@ package de.grimsi.gameyfin.pluginapi.gamemetadata
|
|||||||
import org.pf4j.ExtensionPoint
|
import org.pf4j.ExtensionPoint
|
||||||
|
|
||||||
interface GameMetadataFetcher : ExtensionPoint {
|
interface GameMetadataFetcher : ExtensionPoint {
|
||||||
fun getConfig(): Map<String, String>
|
|
||||||
fun setConfig(config: Map<String, String>)
|
|
||||||
fun fetchMetadata(gameId: String): GameMetadata
|
fun fetchMetadata(gameId: String): GameMetadata
|
||||||
}
|
}
|
||||||
+14
-24
@@ -11,36 +11,26 @@ subprojects {
|
|||||||
implementation(project(":plugin-api"))
|
implementation(project(":plugin-api"))
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.register<Jar>("plugin") {
|
|
||||||
archiveBaseName.set("plugin-${project.name}")
|
|
||||||
|
|
||||||
// first taking the classes generated by the jar task
|
|
||||||
into("classes") {
|
|
||||||
with(tasks.named<Jar>("jar").get())
|
|
||||||
}
|
|
||||||
// and then we also need to include any libraries that are needed by the plugin
|
|
||||||
dependsOn(configurations.runtimeClasspath)
|
|
||||||
into("lib") {
|
|
||||||
from({
|
|
||||||
configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
archiveExtension.set("jar")
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.register<Copy>("assemblePlugin") {
|
|
||||||
from(project.tasks.named("plugin"))
|
|
||||||
into(pluginDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.jar {
|
tasks.jar {
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
isZip64 = true
|
||||||
|
archiveBaseName.set("plugin-${project.name}")
|
||||||
manifest {
|
manifest {
|
||||||
from("./src/main/resources/MANIFEST.MF")
|
from("./src/main/resources/MANIFEST.MF")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
from(configurations.runtimeClasspath.get().map { project.zipTree(it) }) {
|
||||||
|
exclude("META-INF/*.SF")
|
||||||
|
exclude("META-INF/*.DSA")
|
||||||
|
exclude("META-INF/*.RSA")
|
||||||
|
}
|
||||||
|
from(sourceSets["main"].output.classesDirs)
|
||||||
|
from(sourceSets["main"].resources)
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named("build") {
|
tasks.register<Copy>("assemblePlugin") {
|
||||||
dependsOn(tasks.named("plugin"))
|
from(project.tasks.jar)
|
||||||
|
into(pluginDir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,29 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
// Kotlin annotation processor
|
||||||
ksp("care.better.pf4j:pf4j-kotlin-symbol-processing:2.0.20-1.0.1")
|
ksp("care.better.pf4j:pf4j-kotlin-symbol-processing:2.0.20-1.0.1")
|
||||||
|
|
||||||
|
// IGDB API client
|
||||||
|
implementation("io.github.husnjak:igdb-api-jvm:1.2.0")
|
||||||
|
|
||||||
|
compileOnly("org.slf4j:slf4j-api:2.0.16")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.register<Copy>("copyDependencyClasses") {
|
||||||
|
dependsOn(tasks.jar)
|
||||||
|
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
|
||||||
|
from(configurations.runtimeClasspath.get().map { project.zipTree(it) }) {
|
||||||
|
include("**/*.class")
|
||||||
|
}
|
||||||
|
from("src/main/resources/MANIFEST.MF") {
|
||||||
|
into("META-INF")
|
||||||
|
}
|
||||||
|
into(layout.buildDirectory.get().asFile.resolve("classes/kotlin/main"))
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.build {
|
||||||
|
dependsOn("copyDependencyClasses")
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
package de.grimsi.gameyfin.plugins.igdb
|
package de.grimsi.gameyfin.plugins.igdb
|
||||||
|
|
||||||
|
import com.api.igdb.request.IGDBWrapper
|
||||||
|
import com.api.igdb.request.TwitchAuthenticator
|
||||||
|
import de.grimsi.gameyfin.pluginapi.core.PluginConfigError
|
||||||
import de.grimsi.gameyfin.pluginapi.gamemetadata.GameMetadata
|
import de.grimsi.gameyfin.pluginapi.gamemetadata.GameMetadata
|
||||||
import de.grimsi.gameyfin.pluginapi.gamemetadata.GameMetadataFetcher
|
import de.grimsi.gameyfin.pluginapi.gamemetadata.GameMetadataFetcher
|
||||||
import org.pf4j.Extension
|
import org.pf4j.Extension
|
||||||
@@ -9,24 +12,39 @@ import java.time.Instant
|
|||||||
|
|
||||||
class IgdbPlugin(wrapper: PluginWrapper) : Plugin(wrapper) {
|
class IgdbPlugin(wrapper: PluginWrapper) : Plugin(wrapper) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val config: IgdbPluginConfig = IgdbPluginConfig(null, null)
|
||||||
|
}
|
||||||
|
|
||||||
override fun start() {
|
override fun start() {
|
||||||
println("IgdbPlugin.start()")
|
authenticate()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun stop() {
|
override fun stop() {
|
||||||
println("IgdbPlugin.stop()")
|
log.debug("IgdbPlugin.stop()")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun authenticate() {
|
||||||
|
log.debug("Authenticating on Twitch API...")
|
||||||
|
|
||||||
|
// FIXME: This should be read from the config
|
||||||
|
val clientId = "8nrnjn74x1oa7of2g8sg4voy2lapml"
|
||||||
|
// FIXME: This should be read from the config
|
||||||
|
val clientSecret = "pyrvg3sdduxjg4qxidra9237xj17yn"
|
||||||
|
|
||||||
|
// val clientId: String = config.clientId ?: throw PluginConfigError("Twitch Client ID not set")
|
||||||
|
// val clientSecret: String = config.clientSecret ?: throw PluginConfigError("Twitch Client Secret not set")
|
||||||
|
|
||||||
|
val token = TwitchAuthenticator.requestTwitchToken(clientId, clientSecret)
|
||||||
|
?: throw PluginConfigError("Failed to authenticate on Twitch API")
|
||||||
|
|
||||||
|
IGDBWrapper.setCredentials(clientId, token.access_token)
|
||||||
|
|
||||||
|
log.debug("Authentication successful")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Extension
|
@Extension
|
||||||
class IgdbMetadataFetcher : GameMetadataFetcher {
|
class IgdbMetadataFetcher : GameMetadataFetcher {
|
||||||
override fun getConfig(): Map<String, String> {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setConfig(config: Map<String, String>) {
|
|
||||||
TODO("Not yet implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun fetchMetadata(gameId: String): GameMetadata {
|
override fun fetchMetadata(gameId: String): GameMetadata {
|
||||||
return GameMetadata(
|
return GameMetadata(
|
||||||
title = "Test Game",
|
title = "Test Game",
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package de.grimsi.gameyfin.plugins.igdb
|
||||||
|
|
||||||
|
data class IgdbPluginConfig(
|
||||||
|
val clientId: String?,
|
||||||
|
val clientSecret: String?
|
||||||
|
)
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package de.grimsi.gameyfin.plugins.igdb.dto
|
||||||
|
|
||||||
|
data class TwitchOAuthTokenDto(
|
||||||
|
val accessToken: String,
|
||||||
|
val expiresIn: Int,
|
||||||
|
val tokenType: String
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user