Got 3rd party dependencies working in development mode

This commit is contained in:
grimsi
2024-10-30 14:10:51 +01:00
parent 0563f2b366
commit 1bb46e3a71
15 changed files with 104 additions and 71 deletions
+1
View File
@@ -45,5 +45,6 @@ docker-compose.yml
generated
db
data
packaged_plugins
logs
templates
-4
View File
@@ -32,8 +32,4 @@ subprojects {
}
}
tasks.named("build") {
dependsOn(":gameyfin:uberJar")
}
extra.set("pluginDir", rootProject.layout.buildDirectory.get().asFile.resolve("plugins"))
-26
View File
@@ -1,5 +1,4 @@
group = "de.grimsi"
val pluginDir: File by rootProject.extra
val appMainClass = "de.grimsi.gameyfin.GameyfinApplication"
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> {
useJUnitPlatform()
}
@@ -10,10 +10,10 @@ import java.nio.file.Path
@Configuration
class PluginManagerConfig {
private val log = KotlinLogging.logger {}
private val pluginPath = Path.of("plugins")
private val pluginPath = System.getProperty("pf4j.pluginsDir", "plugins")
@Bean
fun pluginManager() = SpringDevtoolsPluginManager(pluginPath)
fun pluginManager() = SpringDevtoolsPluginManager(Path.of(pluginPath))
@EventListener(ApplicationReadyEvent::class)
fun loadedPlugins() {
@@ -48,7 +48,7 @@ class AsyncFileTailer(
tailer.run()
}
log.info { "Started tailing the file: ${file.name}" }
log.debug { "Started tailing the file: ${file.name}" }
} else {
log.error { "File tailing for file ${file.name} is already running!" }
}
@@ -58,7 +58,7 @@ class AsyncFileTailer(
tailerJob?.let {
it.cancel()
tailerJob = null
log.info { "Stopped tailing the file: ${file.name}" }
log.debug { "Stopped tailing the file: ${file.name}" }
}
}
}
+3 -1
View File
@@ -10,7 +10,9 @@ repositories {
dependencies {
// PF4J (shared)
api("org.pf4j:pf4j:${rootProject.extra["pf4jVersion"]}")
api("org.pf4j:pf4j:${rootProject.extra["pf4jVersion"]}") {
exclude(group = "org.slf4j")
}
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
}
}
@@ -3,7 +3,5 @@ package de.grimsi.gameyfin.pluginapi.gamemetadata
import org.pf4j.ExtensionPoint
interface GameMetadataFetcher : ExtensionPoint {
fun getConfig(): Map<String, String>
fun setConfig(config: Map<String, String>)
fun fetchMetadata(gameId: String): GameMetadata
}
+14 -24
View File
@@ -11,36 +11,26 @@ subprojects {
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 {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
isZip64 = true
archiveBaseName.set("plugin-${project.name}")
manifest {
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") {
dependsOn(tasks.named("plugin"))
tasks.register<Copy>("assemblePlugin") {
from(project.tasks.jar)
into(pluginDir)
}
}
+24
View File
@@ -3,5 +3,29 @@ plugins {
}
dependencies {
// Kotlin annotation processor
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
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.GameMetadataFetcher
import org.pf4j.Extension
@@ -9,24 +12,39 @@ import java.time.Instant
class IgdbPlugin(wrapper: PluginWrapper) : Plugin(wrapper) {
companion object {
val config: IgdbPluginConfig = IgdbPluginConfig(null, null)
}
override fun start() {
println("IgdbPlugin.start()")
authenticate()
}
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
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 {
return GameMetadata(
title = "Test Game",
@@ -0,0 +1,6 @@
package de.grimsi.gameyfin.plugins.igdb
data class IgdbPluginConfig(
val clientId: String?,
val clientSecret: String?
)
@@ -0,0 +1,7 @@
package de.grimsi.gameyfin.plugins.igdb.dto
data class TwitchOAuthTokenDto(
val accessToken: String,
val expiresIn: Int,
val tokenType: String
)