initial push
This commit is contained in:
commit
6470a6882b
6 changed files with 199 additions and 0 deletions
25
.gitignore
vendored
Normal file
25
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# If you prefer the allow list template instead of the deny list, see community template:
|
||||||
|
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||||
|
#
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, built with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Dependency directories (remove the comment below to include it)
|
||||||
|
# vendor/
|
||||||
|
|
||||||
|
# Go workspace file
|
||||||
|
go.work
|
||||||
|
go.work.sum
|
||||||
|
|
||||||
|
# env file
|
||||||
|
.env
|
||||||
18
Dockerfile
Normal file
18
Dockerfile
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
FROM golang:alpine as builder
|
||||||
|
|
||||||
|
# build app
|
||||||
|
WORKDIR /opt/torrentchecker/src
|
||||||
|
COPY . /opt/torrentchecker/src
|
||||||
|
|
||||||
|
RUN go build -o /opt/torrentchecker/torrentchecker main.go
|
||||||
|
RUN chmod a+x /opt/torrentchecker/torrentchecker
|
||||||
|
|
||||||
|
# target image
|
||||||
|
FROM golang:alpine
|
||||||
|
RUN mkdir -p /opt/torrentchecker
|
||||||
|
|
||||||
|
COPY --from=builder /opt/torrentchecker/torrentchecker /opt/torrentchecker/torrentchecker
|
||||||
|
RUN crontab -l | { cat; echo "0 * * * * /opt/torrentchecker/torrentchecker"; } | crontab -
|
||||||
|
|
||||||
|
|
||||||
|
CMD ["crond", "-f", "-l", "2"]
|
||||||
10
docker-compose.yaml
Normal file
10
docker-compose.yaml
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
image: registry.domandoman.xyz/utils/torrentchecker
|
||||||
|
restart: unless-stopped
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
platform: "linux/amd64"
|
||||||
3
env.template
Normal file
3
env.template
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
TORRENT_BASEPATH=""
|
||||||
|
TORRENT_USERNAME=""
|
||||||
|
TORRENT_PASSWORD=""
|
||||||
3
go.mod
Normal file
3
go.mod
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
module git.domandoman.xyz/doman/tchecker
|
||||||
|
|
||||||
|
go 1.24.1
|
||||||
140
main.go
Normal file
140
main.go
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/http/cookiejar"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type HTTPClient struct {
|
||||||
|
client *http.Client
|
||||||
|
basePath string
|
||||||
|
jar *cookiejar.Jar
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHTTPClient(basePath string) *HTTPClient {
|
||||||
|
jar, err := cookiejar.New(nil)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &HTTPClient{
|
||||||
|
client: &http.Client{Jar: jar},
|
||||||
|
basePath: basePath,
|
||||||
|
jar: jar,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HTTPClient) Get(subPath string, query map[string]string) (*http.Response, error) {
|
||||||
|
combined, err := url.JoinPath(c.basePath, subPath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed, err := url.Parse(combined)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if query != nil {
|
||||||
|
q := parsed.Query()
|
||||||
|
|
||||||
|
for k, v := range query {
|
||||||
|
q.Set(k, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed.RawQuery = q.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.client.Get(parsed.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HTTPClient) PostForm(subPath string, data map[string][]string) (*http.Response, error) {
|
||||||
|
url, err := url.JoinPath(c.basePath, subPath)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.client.PostForm(url, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *HTTPClient) Login(username string, password string) error {
|
||||||
|
resp, err := c.PostForm("/api/v2/auth/login", map[string][]string{"username": {username}, "password": {password}})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
setCookie := resp.Header.Get("Set-Cookie")
|
||||||
|
|
||||||
|
if setCookie == "" {
|
||||||
|
return fmt.Errorf("no Set-Cookie in response header")
|
||||||
|
}
|
||||||
|
|
||||||
|
jarCookie := c.jar.Cookies(resp.Request.URL)
|
||||||
|
|
||||||
|
if len(jarCookie) == 0 {
|
||||||
|
return fmt.Errorf("no cookie saved to cookiejar")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
basePath := os.Getenv("TORRENT_BASEPATH")
|
||||||
|
username := os.Getenv("TORRENT_USERNAME")
|
||||||
|
password := os.Getenv("TORRENT_PASSWORD")
|
||||||
|
|
||||||
|
client := NewHTTPClient(basePath)
|
||||||
|
|
||||||
|
err := client.Login(username, password)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := client.Get("/api/v2/torrents/info", map[string]string{"filter": "seeding"})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
panic(fmt.Errorf("unexpected status code: %d", resp.StatusCode))
|
||||||
|
}
|
||||||
|
|
||||||
|
decoder := json.NewDecoder(resp.Body)
|
||||||
|
|
||||||
|
var torrents []map[string]interface{}
|
||||||
|
|
||||||
|
err = decoder.Decode(&torrents)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, torrent := range torrents {
|
||||||
|
resp, err := client.PostForm("/api/v2/torrents/stop", map[string][]string{"hashes": {torrent["hash"].(string)}})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
panic(fmt.Errorf("unexpected status code: %d", resp.StatusCode))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("done")
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue