Push first proper version
This commit is contained in:
parent
7cad13248a
commit
fff2f8698f
9
.dockerignore
Normal file
9
.dockerignore
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
.idea/
|
||||||
|
.gradle/
|
||||||
|
build/
|
||||||
|
out/
|
||||||
|
test.db
|
||||||
|
gradle/
|
||||||
|
gradlew
|
||||||
|
gradlew.bat
|
||||||
|
.gitignore
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
||||||
.gradle/
|
.gradle/
|
||||||
build/
|
build/
|
||||||
out/
|
out/
|
||||||
|
test.db
|
27
.gitlab-ci.yml
Normal file
27
.gitlab-ci.yml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
image: docker:latest
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- build
|
||||||
|
|
||||||
|
variables:
|
||||||
|
IMAGE_TAG: $CI_REGISTRY_IMAGE:latest
|
||||||
|
NAME: $CI_PROJECT_NAME
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
|
|
||||||
|
build_and_push:
|
||||||
|
stage: build
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
script:
|
||||||
|
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.voidcorp.nl
|
||||||
|
- docker build -t $IMAGE_TAG .
|
||||||
|
- docker push $IMAGE_TAG
|
||||||
|
|
||||||
|
only_build:
|
||||||
|
stage: build
|
||||||
|
except:
|
||||||
|
- master
|
||||||
|
script:
|
||||||
|
- docker build -t $IMAGE_TAG .
|
12
Dockerfile
Normal file
12
Dockerfile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
FROM gradle:jdk11 as builder
|
||||||
|
|
||||||
|
COPY --chown=gradle:gradle . /home/gradle/src
|
||||||
|
WORKDIR /home/gradle/src
|
||||||
|
RUN gradle build
|
||||||
|
|
||||||
|
FROM openjdk:11-jre-slim
|
||||||
|
COPY --from=builder /home/gradle/src/build/distributions/watchtower.tar /app/watchtower.tar
|
||||||
|
WORKDIR /app
|
||||||
|
RUN tar -xvf watchtower.tar
|
||||||
|
WORKDIR /app/watchtower
|
||||||
|
CMD bin/watchtower
|
|
@ -1,6 +1,7 @@
|
||||||
plugins {
|
plugins {
|
||||||
java
|
java
|
||||||
kotlin("jvm") version "1.3.61"
|
application
|
||||||
|
kotlin("jvm") version "1.3.70"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "nl.voidcorp"
|
group = "nl.voidcorp"
|
||||||
|
@ -10,11 +11,21 @@ repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun DependencyHandlerScope.exposed(part: String) = implementation("org.jetbrains.exposed", part, "0.22.1")
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("stdlib-jdk8"))
|
implementation(kotlin("stdlib-jdk8"))
|
||||||
implementation("net.dv8tion:JDA:4.1.1_108")
|
implementation("net.dv8tion:JDA:4.1.1_108") {
|
||||||
|
exclude(module = "opus-java")
|
||||||
|
}
|
||||||
testImplementation("junit", "junit", "4.12")
|
testImplementation("junit", "junit", "4.12")
|
||||||
implementation("ch.qos.logback:logback-classic:1.2.3")
|
implementation("ch.qos.logback:logback-classic:1.2.3")
|
||||||
|
exposed("exposed-core")
|
||||||
|
exposed("exposed-dao")
|
||||||
|
exposed("exposed-jdbc")
|
||||||
|
implementation("org.xerial:sqlite-jdbc:3.30.1")
|
||||||
|
implementation("com.impossibl.pgjdbc-ng:pgjdbc-ng:0.8.3")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
configure<JavaPluginConvention> {
|
configure<JavaPluginConvention> {
|
||||||
|
@ -27,4 +38,14 @@ tasks {
|
||||||
compileTestKotlin {
|
compileTestKotlin {
|
||||||
kotlinOptions.jvmTarget = "1.8"
|
kotlinOptions.jvmTarget = "1.8"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
distTar {
|
||||||
|
archiveName = "watchtower.tar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
applicationName = "watchtower"
|
||||||
|
mainClassName = "nl.voidcorp.watchtower.MainKt"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
rootProject.name = "OttoLogs"
|
rootProject.name = "WatchTower"
|
||||||
|
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
package nl.voidcorp.ottologs
|
|
||||||
|
|
||||||
import net.dv8tion.jda.api.EmbedBuilder
|
|
||||||
import net.dv8tion.jda.api.JDABuilder
|
|
||||||
import net.dv8tion.jda.api.entities.Activity
|
|
||||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageDeleteEvent
|
|
||||||
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent
|
|
||||||
import net.dv8tion.jda.api.hooks.ListenerAdapter
|
|
||||||
import java.awt.Color
|
|
||||||
|
|
||||||
fun main() {
|
|
||||||
val token: String = System.getenv("DISCORD_TOKEN") ?: throw RuntimeException("Missing DISCORD_TOKEN in env!")
|
|
||||||
val jda = JDABuilder().setToken(token).setActivity(Activity.watching("you")).addEventListeners(LogListener).build()
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Message(val user: Long, val content: String, val channel: Long, val guild: Long, val message: Long)
|
|
||||||
|
|
||||||
val messages = mutableListOf<Message>()
|
|
||||||
|
|
||||||
object LogListener : ListenerAdapter() {
|
|
||||||
override fun onGuildMessageReceived(event: GuildMessageReceivedEvent) {
|
|
||||||
if (!event.isWebhookMessage && !event.author.isBot) {
|
|
||||||
val m = Message(
|
|
||||||
event.author.idLong,
|
|
||||||
event.message.contentRaw,
|
|
||||||
event.message.channel.idLong,
|
|
||||||
event.guild.idLong,
|
|
||||||
event.message.idLong
|
|
||||||
)
|
|
||||||
messages += m
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onGuildMessageDelete(event: GuildMessageDeleteEvent) {
|
|
||||||
val m = messages.firstOrNull { it.message == event.messageIdLong } ?: return
|
|
||||||
val logs = event.guild.textChannels.find { it.name == "logs" }
|
|
||||||
logs?.sendMessage(
|
|
||||||
EmbedBuilder().setDescription(m.content).setTitle("Message Deleted!")
|
|
||||||
.addField("Channel", event.channel.asMention, true).addField(
|
|
||||||
"User",
|
|
||||||
event.jda.getUserById(m.user)?.asTag ?: "No Idea...",
|
|
||||||
true
|
|
||||||
).setColor(Color.RED)
|
|
||||||
.build()
|
|
||||||
)?.queue {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
37
src/main/kotlin/nl/voidcorp/watchtower/DAO.kt
Normal file
37
src/main/kotlin/nl/voidcorp/watchtower/DAO.kt
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
package nl.voidcorp.watchtower
|
||||||
|
|
||||||
|
import org.jetbrains.exposed.dao.IntEntity
|
||||||
|
import org.jetbrains.exposed.dao.IntEntityClass
|
||||||
|
import org.jetbrains.exposed.dao.id.EntityID
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
|
||||||
|
class Message(id: EntityID<Int>) : IntEntity(id) {
|
||||||
|
companion object : IntEntityClass<Message>(Messages)
|
||||||
|
|
||||||
|
var user by Messages.user
|
||||||
|
var channel by Messages.channel
|
||||||
|
var guild by Messages.guild
|
||||||
|
var message by Messages.message
|
||||||
|
val history by MessageHistory referrersOn MessageHistories.original
|
||||||
|
|
||||||
|
|
||||||
|
fun update(new: String) {
|
||||||
|
transaction {
|
||||||
|
MessageHistory.new {
|
||||||
|
content = new
|
||||||
|
original = this@Message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val lastVersion
|
||||||
|
get() = history.maxBy { it.updated }!!
|
||||||
|
}
|
||||||
|
|
||||||
|
class MessageHistory(id: EntityID<Int>) : IntEntity(id) {
|
||||||
|
companion object : IntEntityClass<MessageHistory>(MessageHistories)
|
||||||
|
|
||||||
|
var content by MessageHistories.content
|
||||||
|
var updated by MessageHistories.updated
|
||||||
|
var original by Message referencedOn MessageHistories.original
|
||||||
|
}
|
92
src/main/kotlin/nl/voidcorp/watchtower/Main.kt
Normal file
92
src/main/kotlin/nl/voidcorp/watchtower/Main.kt
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
package nl.voidcorp.watchtower
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.EmbedBuilder
|
||||||
|
import net.dv8tion.jda.api.JDABuilder
|
||||||
|
import net.dv8tion.jda.api.entities.Activity
|
||||||
|
import net.dv8tion.jda.api.events.message.guild.GenericGuildMessageEvent
|
||||||
|
import net.dv8tion.jda.api.events.message.guild.GuildMessageDeleteEvent
|
||||||
|
import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent
|
||||||
|
import net.dv8tion.jda.api.events.message.guild.GuildMessageUpdateEvent
|
||||||
|
import net.dv8tion.jda.api.hooks.ListenerAdapter
|
||||||
|
import org.jetbrains.exposed.sql.Database
|
||||||
|
import org.jetbrains.exposed.sql.SchemaUtils
|
||||||
|
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
import java.awt.Color
|
||||||
|
import java.sql.Connection
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
val token: String = System.getenv("DISCORD_TOKEN") ?: throw RuntimeException("Missing DISCORD_TOKEN in env!")
|
||||||
|
Database.connect(
|
||||||
|
System.getenv("JDBC_URl") ?: "jdbc:sqlite:test.db",
|
||||||
|
System.getenv("JDBC_DRIVER") ?: "org.sqlite.JDBC"
|
||||||
|
)
|
||||||
|
TransactionManager.manager.defaultIsolationLevel = Connection.TRANSACTION_SERIALIZABLE
|
||||||
|
transaction {
|
||||||
|
SchemaUtils.createMissingTablesAndColumns(Messages, MessageHistories)
|
||||||
|
}
|
||||||
|
JDABuilder().setToken(token).setActivity(Activity.watching("you")).addEventListeners(LogListener).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun GuildMessageReceivedEvent.log() {
|
||||||
|
transaction {
|
||||||
|
Message.new {
|
||||||
|
channel = this@log.channel.idLong
|
||||||
|
user = this@log.author.idLong
|
||||||
|
guild = this@log.guild.idLong
|
||||||
|
message = this@log.messageIdLong
|
||||||
|
}.update(this@log.message.contentRaw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object LogListener : ListenerAdapter() {
|
||||||
|
override fun onGuildMessageReceived(event: GuildMessageReceivedEvent) {
|
||||||
|
if (!event.isWebhookMessage && !event.author.isBot) {
|
||||||
|
event.log()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onGuildMessageUpdate(event: GuildMessageUpdateEvent) {
|
||||||
|
if (!event.author.isBot) {
|
||||||
|
val m = transaction { Message.find { Messages.message eq event.messageIdLong }.firstOrNull() } ?: return
|
||||||
|
m.update(event.message.contentRaw)
|
||||||
|
messageEdit(event, "Message Edited!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onGuildMessageDelete(event: GuildMessageDeleteEvent) {
|
||||||
|
messageEdit(event, "Message Deleted!")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun messageEdit(event: GenericGuildMessageEvent, what: String) {
|
||||||
|
val m = transaction { Message.find { Messages.message eq event.messageIdLong }.firstOrNull() } ?: return
|
||||||
|
val logs = event.guild.textChannels.find { it.name == "logs" }
|
||||||
|
logs?.sendMessage(
|
||||||
|
EmbedBuilder().setDescription(transaction { m.lastVersion.content }).setTitle(what)
|
||||||
|
.addField("Channel", event.channel.asMention, true).addField(
|
||||||
|
"User",
|
||||||
|
event.jda.getUserById(m.user)?.asTag ?: "No Idea...",
|
||||||
|
true
|
||||||
|
).setColor(Color.ORANGE.let {
|
||||||
|
if (what.contains("delete", true)) Color.RED.darker() else it
|
||||||
|
}).apply {
|
||||||
|
this.addField(
|
||||||
|
"History",
|
||||||
|
transaction {
|
||||||
|
m.history.sortedBy { it.updated }.dropLast(1).joinToString("\n") { it.content }
|
||||||
|
}, false
|
||||||
|
)
|
||||||
|
}.setTimestamp(Instant.ofEpochMilli(transaction { m.lastVersion.updated })).setFooter("Last changed at")
|
||||||
|
.build()
|
||||||
|
)?.queue {
|
||||||
|
if (event is GuildMessageDeleteEvent) {
|
||||||
|
transaction {
|
||||||
|
MessageHistory.find { MessageHistories.original eq m.id }.forEach { it.delete() }
|
||||||
|
m.delete()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
src/main/kotlin/nl/voidcorp/watchtower/Tables.kt
Normal file
16
src/main/kotlin/nl/voidcorp/watchtower/Tables.kt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package nl.voidcorp.watchtower
|
||||||
|
|
||||||
|
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||||
|
|
||||||
|
object Messages : IntIdTable() {
|
||||||
|
val user = long("user")
|
||||||
|
val channel = long("channel")
|
||||||
|
val guild = long("guild")
|
||||||
|
val message = long("message")
|
||||||
|
}
|
||||||
|
|
||||||
|
object MessageHistories : IntIdTable() {
|
||||||
|
val original = reference("original", Messages)
|
||||||
|
val content = text("content")
|
||||||
|
val updated = long("updated").clientDefault { System.currentTimeMillis() }
|
||||||
|
}
|
Loading…
Reference in a new issue