Skip to content

Commit

Permalink
Spring cleaning (#2)
Browse files Browse the repository at this point in the history
* updated dependencies

* Fix okhttp logger error

* fix random warning

* removed markdown to avoid compatibility issues

* split messages if they are too long

* changed /download command to /get

* updated dockerfile

* changed base to azul alpine jre

* changed version to semVer

* only print wget errors

* bumped version for release
  • Loading branch information
LivingWithHippos authored Jun 2, 2022
1 parent 71fe3c8 commit fef1325
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 55 deletions.
13 changes: 2 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,11 @@ COPY --chown=gradle:gradle app /home/gradle/src
WORKDIR /home/gradle/src
RUN ./gradlew Jar

# Openjdk alpine support is not ready atm
# this image does not throw errors but final image size is ~ 420 MB probably because it's a jdk and not a jre
# FROM openjdk:16-slim

# final image size ~ 230 MB
# When built shows a warning due to a bug in java 11 fixed in 14.
# Lates jre available atm https://hub.docker.com/_/openjdk?tab=tags&page=1&ordering=last_updated&name=jre
FROM openjdk:11-jre-slim
FROM azul/zulu-openjdk-alpine:18-jre

RUN \
echo "**** install runtime packages ****" && \
apt-get update && \
apt-get install -y --no-install-recommends \
wget
apk add --no-cache wget

RUN mkdir /app
COPY --from=build /home/gradle/src/build/libs/ /app/
Expand Down
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ services:
# optional
# only let this user use the bot
# - WHITELISTED_USER=your telegram user id
# add arguments for wget, userd for /download
# add arguments for wget, userd for /get
# - WGET_ARGUMENTS=see https://www.gnu.org/software/wget/manual/wget.html, default is "--no-verbose"
# OkHttp log level
# - LOG_LEVEL=availabel options are error, body, basic, headers, none. Default is error
Expand Down Expand Up @@ -81,7 +81,7 @@ java \
-jar unchained-bot-kotlin.jar
```

To use the `/download` command you need wget installed.
To use the `/get` command you need wget installed.

If you don't use docker or already have java installed, this file is just ~ 9 MB. The docker image is around 230 MB.

Expand All @@ -97,20 +97,20 @@ If you don't use docker or already have java installed, this file is just ~ 9 MB
| WGET_ARGUMENTS | wget is used to download files locally. Pass arguments to it with this |
| LOG_LEVEL | default is error, if you have issues you can set this to another level like body, basic, headers, none (currently bugged, do not use) |
| TEMP_PATH | path where temporary files, such are `.torrent` files, are being downloaded. You probably won't change this. |
| DOWNLOADS_PATH | the folder where files are downloaded with `/download`. If you're using docker just change the mounted folder instead: `/new/path:/downloads` |
| DOWNLOADS_PATH | the folder where files are downloaded with `/get`. If you're using docker just change the mounted folder instead: `/new/path:/downloads` |

## Available Commands

Parameters between [square brackets] are optional.

| Parameter | Function |
|---|---|
| /help | display the list of available commands |
| /user | get Real Debrid user's information |
| /torrents [number, default 5] | list the last torrents |
| Parameter | Function |
|--------------------------------|---|
| /help | display the list of available commands |
| /user | get Real Debrid user's information |
| /torrents [number, default 5] | list the last torrents |
| /downloads [number, default 5] | list the last downloads |
| /download unrestricted_link | downloads the link on the directory of the server running the bot |
| /unrestrict url|magnet|torrent file link | generate a download link. Magnet/Torrents will be queued, check their status with /torrents |
| /get unrestricted_link | downloads the link on the directory of the server running the bot |
| /unrestrict url |magnet|torrent file link | generate a download link. Magnet/Torrents will be queued, check their status with /torrents |
| /transcode real_debrid_file_id | transcode streaming links to various quality levels. Get the file id using /unrestrict |

## Thanks, Mr. Unchained
Expand Down
2 changes: 1 addition & 1 deletion app/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ plugins {
kotlin("jvm") version "1.6.10"
kotlin("kapt") version "1.6.10"
application
id("com.github.ben-manes.versions") version "0.42.0"
}

group = "com.github.livingwithhippos"
version = "0.52"
version = "0.6.3"

repositories {
mavenCentral()
Expand All @@ -19,13 +20,13 @@ val ktlint: Configuration by configurations.creating
dependencies {

val kotlinVersion = "1.6.10"
val coroutinesVersion = "1.6.0"
val telegramVersion = "6.0.6"
val coroutinesVersion = "1.6.2"
val telegramVersion = "6.0.7"
val moshiVersion = "1.13.0"
val retrofitVersion = "2.9.0"
val okhttpVersion = "4.9.3"
val koinVersion = "3.1.5"
val ktLintVersion = "0.43.2"
val koinVersion = "3.2.0"
val ktLintVersion = "0.45.2"

// kotlin stdlib
implementation ("org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion")
Expand All @@ -51,7 +52,7 @@ dependencies {
//okhttp
implementation ("com.squareup.okhttp3:okhttp:$okhttpVersion")
//okhttp logging. It's already used by the telegram bot library and can be set with Loglevel.Network
// implementation ("com.squareup.okhttp3:logging-interceptor:$okhttpVersion")
implementation ("com.squareup.okhttp3:logging-interceptor:$okhttpVersion")

ktlint("com.pinterest:ktlint:$ktLintVersion")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,22 @@ import com.github.livingwithhippos.unchained_bot.localization.localeMapping
import com.github.livingwithhippos.unchained_bot.utilities.isMagnet
import com.github.livingwithhippos.unchained_bot.utilities.isTorrent
import com.github.livingwithhippos.unchained_bot.utilities.isWebUrl
import com.github.livingwithhippos.unchained_bot.utilities.runCommand
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import okhttp3.Request
import okio.buffer
import okio.sink
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import java.nio.charset.Charset
import kotlin.system.exitProcess

class BotApplication : KoinComponent {
Expand All @@ -51,7 +54,7 @@ class BotApplication : KoinComponent {
private val enableQuery: String = getKoin().getProperty("ENABLE_QUERIES") ?: "false"
private val enableQueriesArgument: Boolean = enableQuery.equals("true", true) || enableQuery == "1"
private val whitelistedUser: Long = getKoin().getProperty<String>("WHITELISTED_USER")?.toLongOrNull() ?: 0
private val localeArgument: String = getKoin().getProperty("LOCALE") ?: "en"
private val localeArgument: String = getKoin().getProperty<String>("LOCALE") ?: "en"

private val localization: Localization = localeMapping.getOrDefault(localeArgument, EN)

Expand All @@ -72,6 +75,9 @@ class BotApplication : KoinComponent {
private val job = Job()
private val scope = CoroutineScope(Dispatchers.Default + job)

private val download = Job()
private val downloadScope = CoroutineScope(Dispatchers.IO + download)

// Filters
// Filter the whitelisted user, if any
private val userFilter = if (whitelistedUser > 10000) Filter.User(whitelistedUser) else Filter.All
Expand All @@ -83,9 +89,7 @@ class BotApplication : KoinComponent {
private val unrestrictCommandFilter = Filter.Custom { text?.startsWith("/unrestrict") ?: false }
private val transcodeCommandFilter = Filter.Custom { text?.startsWith("/transcode ") ?: false }

// more complete check, otherwise text?.startsWith("/download") will also match /downloads
// necessary only for commands that have another commands starting with the same characters
private val downloadCommandFilter = Filter.Custom { (text?.split("\\s")?.firstOrNull() ?: "") == "/download" }
private val getCommandFilter = Filter.Custom { (text?.startsWith("/get") ?: false) }
private val torrentsCommandFilter = Filter.Custom { text?.startsWith("/torrents") ?: false }
private val downloadsCommandFilter = Filter.Custom { (text?.startsWith("/downloads") ?: false) }

Expand All @@ -111,7 +115,6 @@ class BotApplication : KoinComponent {
checkAndMakeDirectories(tempPath, downloadsPath)

println("Starting bot...")
println("Ignore the retrofit warning")

val bot = bot {

Expand Down Expand Up @@ -269,15 +272,39 @@ class BotApplication : KoinComponent {
)
}

message(downloadCommandFilter and userFilter) {
message(getCommandFilter and userFilter) {
val args = getArgAsString(message.text)
// todo: restrict link to real debrid urls?
if (!args.isNullOrBlank() && args.isWebUrl()) {
bot.sendMessage(
chatId = ChatId.fromId(message.chat.id),
text = localization.startingDownload
)
"wget -P $downloadsPath $wgetArguments $args".runCommand()
downloadScope.launch {
withContext(Dispatchers.IO) {
val process = ProcessBuilder(
"wget",
"-P", downloadsPath,
wgetArguments,
args
).redirectOutput(ProcessBuilder.Redirect.PIPE)
.start()
val reader = process.errorStream.bufferedReader(Charset.defaultCharset())
reader.use {
var line = it.readLine()
while (line != null) {
println(line)
line = it.readLine()
if (line != null)
bot.sendMessage(
chatId = ChatId.fromId(message.chat.id),
text = line
)
}
}
process.waitFor()
}
}
} else
bot.sendMessage(
chatId = ChatId.fromId(message.chat.id),
Expand All @@ -294,32 +321,46 @@ class BotApplication : KoinComponent {
val stringBuilder = StringBuilder()
torrents.forEach {

stringBuilder.append(
val tempBuffer = StringBuffer()

tempBuffer.append(
"""
*${localization.name}:* ${it.filename}
*${localization.size}:* ${it.bytes / 1024 / 1024} MB
*${localization.status}:* ${it.status}
*${localization.progress}:* ${it.progress}%
${localization.name}: ${it.filename}
${localization.size}: ${it.bytes / 1024 / 1024} MB
${localization.status}: ${it.status}
${localization.progress}: ${it.progress}%
""".trimIndent()
)
stringBuilder.append("\n")
tempBuffer.appendLine()
if (it.links.isNotEmpty()) {
if (it.links.size == 1) {
stringBuilder.append("${localization.getDownloadLink} /unrestrict ${it.links.first()}\n")
tempBuffer.append("${localization.getDownloadLink}\n/unrestrict ${it.links.first()}\n")
} else {
stringBuilder.append("${localization.getDownloadLink} /unrestrict +\n")
tempBuffer.append("${localization.getDownloadLink}\n")
it.links.forEach { link ->
stringBuilder.append(link)
stringBuilder.append("\n")
tempBuffer.append("/unrestrict ")
tempBuffer.append(link)
tempBuffer.appendLine()
}
}
}
stringBuilder.append("\n")
tempBuffer.appendLine()

// if the size of the message is too big send a message and clear the main builder
if (stringBuilder.length + tempBuffer.length > 4000) {
bot.sendMessage(
chatId = ChatId.fromId(message.chat.id),
text = stringBuilder.toString(),
disableWebPagePreview = true
)
stringBuilder.clear()
}
// add the current message to the main builder
stringBuilder.append(tempBuffer)
}
bot.sendMessage(
chatId = ChatId.fromId(message.chat.id),
text = stringBuilder.toString(),
parseMode = ParseMode.MARKDOWN,
disableWebPagePreview = true
)
}
Expand All @@ -333,9 +374,20 @@ class BotApplication : KoinComponent {
downloadRepository.getDownloads(privateApiKey, limit = retrievedDownloads)
val stringBuilder = StringBuilder()
downloads.forEach {
stringBuilder.append(formatDownloadItem(it))
stringBuilder.appendLine()
stringBuilder.appendLine()
val tempBuffer = StringBuilder()
tempBuffer.append(formatDownloadItem(it))
tempBuffer.appendLine()
tempBuffer.appendLine()

if (stringBuilder.length + tempBuffer.length > 4000) {
bot.sendMessage(
chatId = ChatId.fromId(message.chat.id),
text = stringBuilder.toString(),
parseMode = ParseMode.MARKDOWN
)
stringBuilder.clear()
}
stringBuilder.append(tempBuffer)
}
bot.sendMessage(
chatId = ChatId.fromId(message.chat.id),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object EN : Localization {
/user - get Real Debrid user's information
/torrents [number, default 5] - list the last torrents
/downloads [number, default 5] - list the last downloads
/download [unrestricted link] - downloads the link on the directory of the server running the bot
/get [unrestricted link] - downloads the link on the directory of the server running the bot
/unrestrict [url|magnet|torrent file link] - generate a download link. Magnet/Torrents will be queued, check their status with /torrents
/transcode [real debrid file id] - transcode streaming links to various quality levels. Get the file id using /unrestrict
""".trimIndent()
Expand Down Expand Up @@ -57,7 +57,7 @@ object EN : Localization {
override val getDownloadLink: String
get() = "Get the download link with"
override val wrongDownloadSyntax: String
get() = "Wrong or missing argument.\nSyntax: /download [unrestricted link]"
get() = "Wrong or missing argument.\nSyntax: /get [unrestricted link]"
override val wrongStreamSyntax: String
get() = "Wrong or missing argument.\nSyntax: /stream [real debrid file id]"
override val wrongUnrestrictSyntax: String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object IT : Localization {
/user - mostra le informazioni utente
/torrents \[numero, default 5] - mostra la lista degli ultimi n torrent
/downloads \[numero, default 5] - mostra la lista degli ultimi n download
/download \[url] - scarica un url nel server in cui sta girando il bot
/get \[url] - scarica un link nel server in cui sta girando il bot
/unrestrict \[url|magnet|link file torrent] - genera un link di download. Magnet/Torrents verranno messi in coda, controlla il loro status con /torrents
/transcode \[id file real debrid] - offre codifiche per streaming di varie qualità. Ottieni l'id con /unrestrict
""".trimIndent()
Expand Down Expand Up @@ -57,7 +57,7 @@ object IT : Localization {
override val getDownloadLink: String
get() = "Ottieni link per download con"
override val wrongDownloadSyntax: String
get() = "Parametro errato o mancante.\nSintassi: /download [link sbloccato]"
get() = "Parametro errato o mancante.\nSintassi: /get [link sbloccato]"
override val wrongStreamSyntax: String
get() = "Parametro errato o mancante.\nSintassi: /stream [id file real debrid]"
override val wrongUnrestrictSyntax: String
Expand Down

0 comments on commit fef1325

Please sign in to comment.