Compare commits

...

14 Commits

Author SHA1 Message Date
cf149f7a89
update
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-11 20:36:17 +03:00
48c2190ea4
Merge remote-tracking branch 'origin/master' into drone 2024-10-11 20:34:57 +03:00
Kirill Alekseev
05fe601479
Implemented commands to set download/upload limit and download directory (#47)
* implemented downloaddir command

* implemented uplimit and downlimit commands

* moved command-related code to transmission lib
2024-08-21 09:14:16 +03:00
16cb1dfbe7
fixed Dockerfile
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone Build is passing
2024-08-18 20:47:28 +03:00
efa8ded7c5
Merge remote-tracking branch 'origin/master' into drone
Some checks failed
continuous-integration/drone/push Build is failing
2024-08-18 09:32:54 +03:00
3df77e1121
update .drone.yml
Some checks reported errors
continuous-integration/drone/push Build was killed
continuous-integration/drone Build was killed
2024-08-13 08:46:46 +03:00
c260db6480
update .drone.yml
Some checks failed
continuous-integration/drone/push Build is failing
2024-08-13 08:43:14 +03:00
jensaymoo
dd216f3de6
Update main.go (#45)
fixed *downs* command in help message
2024-03-21 02:02:58 +03:00
Struchkov Mark
3fb5339ef5
Update Dockerfile (#44) 2024-01-28 11:49:29 +03:00
46d252c3f6
fix Dockerfile
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-28 11:32:45 +03:00
f793658f1d
fix Dockerfile
All checks were successful
continuous-integration/drone/push Build is passing
2024-01-28 11:18:17 +03:00
1833681eed
fix Dockerfile
Some checks failed
continuous-integration/drone/push Build is failing
2024-01-28 11:12:13 +03:00
f37966fdf7
drone 2024-01-28 11:01:46 +03:00
2af81315bc
drone
Some checks failed
continuous-integration/drone/push Build is failing
2024-01-28 10:50:13 +03:00
4 changed files with 220 additions and 16 deletions

50
.drone.yml Normal file
View File

@ -0,0 +1,50 @@
---
kind: pipeline
type: docker
name: build-and-push-develop
steps:
- name: docker build an publish
image: docker.struchkov.dev/docker-buildx:latest
environment:
DOCKER_REGISTRY_TOKEN:
from_secret: DOCKER_REGISTRY_TOKEN
DOCKER_REGISTRY_USER:
from_secret: DOCKER_REGISTRY_USER
volumes:
- name: dockersock
path: /var/run
commands:
- sleep 30
- echo "$DOCKER_REGISTRY_TOKEN" | docker login docker.struchkov.dev --username $DOCKER_REGISTRY_USER --password-stdin
- echo "$DOCKER_REGISTRY_TOKEN" | docker login hub.docker.struchkov.dev --username $DOCKER_REGISTRY_USER --password-stdin
- docker buildx create --use
- docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 -t "docker.struchkov.dev/transmission-telegram:latest" .
trigger:
branch:
- drone
services:
- name: docker
# https://hub.docker.com/r/library/docker
image: hub.docker.struchkov.dev/docker:27.3.1-dind-alpine3.20
privileged: true
volumes:
- name: dockersock
path: /var/run
volumes:
- name: dockersock
temp: {}
image_pull_secrets:
- DOCKER_AUTH
# drone sign --save DockerFiles/transmission-telegram
---
kind: signature
hmac: 5af7a78fc831318a31863c4f713b3c6e10d752e80f2208344a91e503ecc300c6
...

65
.gitignore vendored Normal file
View File

@ -0,0 +1,65 @@
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
.idea/**/aws.xml
.idea/**/contentModel.xml
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
.idea/**/gradle.xml
.idea/**/libraries
cmake-build-*/
.idea/**/mongoSettings.xml
*.iws
out/
.idea_modules/
atlassian-ide-plugin.xml
.idea/replstate.xml
.idea/sonarlint/
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
.idea/httpRequests
.idea/caches/build_file_checksums.ser
*~
.fuse_hidden*
.directory
.Trash-*
.nfs*
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
*.stackdump
[Dd]esktop.ini
$RECYCLE.BIN/
*.cab
*.msi
*.msix
*.msm
*.msp
*.lnk
.DS_Store
.AppleDouble
.LSOverride
Icon
._*
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

View File

@ -1,7 +1,4 @@
FROM golang:alpine as build FROM golang:alpine AS build
ENV GOOS=linux \
GOARCH=amd64
RUN apk add --no-cache git RUN apk add --no-cache git
@ -15,12 +12,12 @@ RUN go install -v ./...
RUN go build -o main . RUN go build -o main .
FROM alpine:latest as certs FROM alpine:latest AS certs
RUN apk --update add ca-certificates RUN apk --no-cache add ca-certificates
FROM bash:latest FROM bash:latest
COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=build /go/bin/transmission-telegram / COPY --from=build /go/src/transmission-telegram/main /transmission-telegram
RUN chmod 777 transmission-telegram RUN chmod 777 transmission-telegram
ENTRYPOINT ["/transmission-telegram"] ENTRYPOINT ["/transmission-telegram"]

98
main.go
View File

@ -15,7 +15,7 @@ import (
"github.com/dustin/go-humanize" "github.com/dustin/go-humanize"
"github.com/pyed/tailer" "github.com/pyed/tailer"
"github.com/pyed/transmission" "github.com/pyed/transmission"
"gopkg.in/telegram-bot-api.v4" tgbotapi "gopkg.in/telegram-bot-api.v4"
) )
const ( const (
@ -31,7 +31,7 @@ const (
*tail* or *ta* *tail* or *ta*
Lists the last n number of torrents, n defaults to 5 if no argument is provided. Lists the last n number of torrents, n defaults to 5 if no argument is provided.
*down* or *dl* *downs* or *dg*
Lists torrents with the status of _Downloading_ or in the queue to download. Lists torrents with the status of _Downloading_ or in the queue to download.
*seeding* or *sd* *seeding* or *sd*
@ -55,6 +55,10 @@ const (
*trackers* or *tr* *trackers* or *tr*
Lists all the trackers along with the number of torrents. Lists all the trackers along with the number of torrents.
*downloaddir* or *dd*
Set download directory to the specified path. Transmission will automatically create a
directory in case you provided an inexistent one.
*add* or *ad* *add* or *ad*
Takes one or many URLs or magnets to add them. You can send a ".torrent" file via Telegram to add it. Takes one or many URLs or magnets to add them. You can send a ".torrent" file via Telegram to add it.
@ -85,6 +89,12 @@ const (
*stats* or *sa* *stats* or *sa*
Shows Transmission's stats. Shows Transmission's stats.
*downlimit* or *dl*
Set global limit for download speed in kilobytes.
*uplimit* or *ul*
Set global limit for upload speed in kilobytes.
*speed* or *ss* *speed* or *ss*
Shows the upload and download speeds. Shows the upload and download speeds.
@ -332,7 +342,7 @@ func main() {
case "tail", "/tail", "ta", "/ta": case "tail", "/tail", "ta", "/ta":
go tail(update, tokens[1:]) go tail(update, tokens[1:])
case "downs", "/downs", "dl", "/dl": case "downs", "/downs", "dg", "/dg":
go downs(update) go downs(update)
case "seeding", "/seeding", "sd", "/sd": case "seeding", "/seeding", "sd", "/sd":
@ -356,6 +366,9 @@ func main() {
case "trackers", "/trackers", "tr", "/tr": case "trackers", "/trackers", "tr", "/tr":
go trackers(update) go trackers(update)
case "downloaddir", "dd":
go downloaddir(update, tokens[1:])
case "add", "/add", "ad", "/ad": case "add", "/add", "ad", "/ad":
go add(update, tokens[1:]) go add(update, tokens[1:])
@ -380,6 +393,12 @@ func main() {
case "stats", "/stats", "sa", "/sa": case "stats", "/stats", "sa", "/sa":
go stats(update) go stats(update)
case "downlimit", "dl":
go downlimit(update, tokens[1:])
case "uplimit", "ul":
go uplimit(update, tokens[1:])
case "speed", "/speed", "ss", "/ss": case "speed", "/speed", "ss", "/ss":
go speed(update) go speed(update)
@ -950,6 +969,34 @@ func trackers(ud tgbotapi.Update) {
send(buf.String(), ud.Message.Chat.ID, false) send(buf.String(), ud.Message.Chat.ID, false)
} }
// downloaddir takes a path and sets it as the download directory
func downloaddir(ud tgbotapi.Update, tokens []string) {
if len(tokens) < 1 {
send("Please, specify a path for downloaddir", ud.Message.Chat.ID, false)
return
}
downloadDir := tokens[0]
cmd := transmission.NewSessionSetCommand()
cmd.SetDownloadDir(downloadDir)
out, err := Client.ExecuteCommand(cmd)
if err != nil {
send("*downloaddir:* "+err.Error(), ud.Message.Chat.ID, false)
return
}
if out.Result != "success" {
send("*downloaddir:* "+out.Result, ud.Message.Chat.ID, false)
return
}
send(
"*downloaddir:* downloaddir has been successfully changed to"+downloadDir,
ud.Message.Chat.ID, false,
)
}
// add takes an URL to a .torrent file to add it to transmission // add takes an URL to a .torrent file to add it to transmission
func add(ud tgbotapi.Update, tokens []string) { func add(ud tgbotapi.Update, tokens []string) {
if len(tokens) == 0 { if len(tokens) == 0 {
@ -1316,6 +1363,51 @@ func stats(ud tgbotapi.Update) {
send(msg, ud.Message.Chat.ID, true) send(msg, ud.Message.Chat.ID, true)
} }
// downlimit sets the global downlimit to a provided value in kilobytes
func downlimit(ud tgbotapi.Update, tokens []string) {
speedLimit(ud, tokens, transmission.DownloadLimitType)
}
// uplimit sets the global uplimit to a provided value in kilobytes
func uplimit(ud tgbotapi.Update, tokens []string) {
speedLimit(ud, tokens, transmission.UploadLimitType)
}
// speedLimit sets either a donwload or upload limit
func speedLimit(ud tgbotapi.Update, tokens []string, limitType transmission.SpeedLimitType) {
if len(tokens) < 1 {
send("Please, specify the limit", ud.Message.Chat.ID, false)
return
}
limit, err := strconv.ParseUint(tokens[0], 10, 32)
if err != nil {
send("Please, specify the limit as number of kilobytes", ud.Message.Chat.ID, false)
return
}
speedLimitCmd := transmission.NewSpeedLimitCommand(limitType, uint(limit))
if speedLimitCmd == nil {
send(fmt.Sprintf("*%s:* internal error", limitType), ud.Message.Chat.ID, false)
return
}
out, err := Client.ExecuteCommand(speedLimitCmd)
if err != nil {
send(fmt.Sprintf("*%s:* %v", limitType, err.Error()), ud.Message.Chat.ID, false)
return
}
if out.Result != "success" {
send(fmt.Sprintf("*%s:* %v", limitType, out.Result), ud.Message.Chat.ID, false)
return
}
send(
fmt.Sprintf("*%s:* limit has been successfully changed to %d KB/s", limitType, limit),
ud.Message.Chat.ID, false,
)
}
// speed will echo back the current download and upload speeds // speed will echo back the current download and upload speeds
func speed(ud tgbotapi.Update) { func speed(ud tgbotapi.Update) {
stats, err := Client.GetStats() stats, err := Client.GetStats()