Initial commit

This commit is contained in:
Jeffrey Serio 2023-06-23 21:33:24 -05:00
commit 11c68f21c7
12 changed files with 616 additions and 0 deletions

48
almalinux/main.go Normal file
View File

@ -0,0 +1,48 @@
package almalinux
import (
"fmt"
"log"
"codeberg.org/hyperreal/go-torrent-helper/common"
"github.com/hekmon/transmissionrpc"
)
type AlmaLinux struct {
NameSubstr string
Relver string
URL string
}
func (a AlmaLinux) AddNewTorrents(transmissionbt *transmissionrpc.Client) error {
// Set torrentURLs for AlmaLinux mirror
a.URL = "https://almalinux-mirror.dal1.hivelocity.net/"
torrentURLs := []string{
fmt.Sprintf("%s/%s/isos/aarch64/AlmaLinux-%s-aarch64.torrent", a.URL, a.Relver, a.Relver),
fmt.Sprintf("%s/%s/isos/ppc64le/AlmaLinux-%s-ppc64le.torrent", a.URL, a.Relver, a.Relver),
fmt.Sprintf("%s/%s/isos/s390x/AlmaLinux-%s-s390x.torrent", a.URL, a.Relver, a.Relver),
fmt.Sprintf("%s/%s/isos/x86_64/AlmaLinux-%s-x86_64.torrent", a.URL, a.Relver, a.Relver),
}
// Add torrents to Transmission instance
for _, torrentURL := range torrentURLs {
torrent, err := transmissionbt.TorrentAdd(&transmissionrpc.TorrentAddPayload{
Filename: &torrentURL,
})
if err != nil {
return err
}
log.Printf("%s added\n", *torrent.Name)
}
return nil
}
func (a AlmaLinux) RemoveOldTorrents(transmissionbt *transmissionrpc.Client) error {
if err := common.RemoveTorrents(a.NameSubstr, a.Relver, transmissionbt); err != nil {
return err
}
return nil
}

163
command/main.go Normal file
View File

@ -0,0 +1,163 @@
package command
import (
"errors"
"flag"
"fmt"
"os"
"codeberg.org/hyperreal/go-torrent-helper/almalinux"
"codeberg.org/hyperreal/go-torrent-helper/debian"
"codeberg.org/hyperreal/go-torrent-helper/fedora"
"codeberg.org/hyperreal/go-torrent-helper/nixos"
"codeberg.org/hyperreal/go-torrent-helper/parrot"
"codeberg.org/hyperreal/go-torrent-helper/qubes"
"codeberg.org/hyperreal/go-torrent-helper/rocky"
"github.com/hekmon/transmissionrpc"
)
type Distro interface {
AddNewTorrents(client *transmissionrpc.Client) error
RemoveOldTorrents(client *transmissionrpc.Client) error
}
func NewAddCmd() *AddCmd {
addCmd := &AddCmd{
fs: flag.NewFlagSet("add", flag.ExitOnError),
}
addCmd.fs.StringVar(&addCmd.distro, "distro", "", "Distro to add torrents for")
addCmd.fs.StringVar(&addCmd.relver, "relver", "", "Release version to add")
return addCmd
}
func NewRemoveCmd() *RemoveCmd {
removeCmd := &RemoveCmd{
fs: flag.NewFlagSet("remove", flag.ExitOnError),
}
removeCmd.fs.StringVar(&removeCmd.distro, "distro", "", "Distro to remove torrents for")
removeCmd.fs.StringVar(&removeCmd.relver, "relver", "", "Release version to remove")
return removeCmd
}
type AddCmd struct {
fs *flag.FlagSet
distro string
relver string
}
type RemoveCmd struct {
fs *flag.FlagSet
distro string
relver string
}
func (a *AddCmd) Name() string {
return a.fs.Name()
}
func (r *RemoveCmd) Name() string {
return r.fs.Name()
}
func (a *AddCmd) Init(args []string) error {
return a.fs.Parse(args)
}
func (r *RemoveCmd) Init(args []string) error {
return r.fs.Parse(args)
}
func (a *AddCmd) Run(d Distro) error {
client, err := transmissionrpc.New(os.Getenv("TRANSMISSION_RPC_URL"), "", "", nil)
if err != nil {
return err
}
if err := d.AddNewTorrents(client); err != nil {
return err
}
return nil
}
func (r *RemoveCmd) Run(d Distro) error {
client, err := transmissionrpc.New(os.Getenv("TRANSMISSION_RPC_URL"), "", "", nil)
if err != nil {
return err
}
if err := d.RemoveOldTorrents(client); err != nil {
return err
}
return nil
}
type Runner interface {
Init([]string) error
Run(d Distro) error
Name() string
}
func Root(args []string) error {
if len(args) < 1 {
return errors.New("You must pass a sub-command")
}
cmds := []Runner{
NewAddCmd(),
NewRemoveCmd(),
}
subcmd := os.Args[1]
for _, cmd := range cmds {
if cmd.Name() == subcmd {
cmd.Init(os.Args[2:])
distro := os.Args[3]
relver := os.Args[5]
switch distro {
case "almalinux":
a := &almalinux.AlmaLinux{NameSubstr: "AlmaLinux", Relver: relver}
return cmd.Run(a)
case "debian":
d := &debian.Debian{NameSubstr: "debian", Relver: relver}
return cmd.Run(d)
case "fedora":
f := &fedora.Fedora{NameSubstr: "Fedora", Relver: relver}
return cmd.Run(f)
case "nixos":
n := &nixos.Nixos{NameSubstr: "nixos"}
return cmd.Run(n)
case "parrot":
p := &parrot.Parrot{NameSubstr: "Parrot", Relver: relver}
return cmd.Run(p)
case "qubes":
q := &qubes.Qubes{NameSubstr: "Qubes", Relver: relver}
return cmd.Run(q)
case "rocky":
r := &rocky.Rocky{NameSubstr: "Rocky", Relver: relver}
return cmd.Run(r)
default:
return fmt.Errorf("Unknown distro: %s", distro)
}
}
}
return fmt.Errorf("Unknown subcommand: %s", subcmd)
}

67
common/main.go Normal file
View File

@ -0,0 +1,67 @@
package common
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
"github.com/hekmon/transmissionrpc"
)
func GetResponse(url string) ([]byte, error) {
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("User-Agent", "go-torrent-helper")
// Add required headers for GitHub API
if strings.Contains(url, "github") {
req.Header.Add("Accept", "application/vnd.github.v3.text-match+json")
req.Header.Add("Accept", "application/vnd.github.moondragon+json")
}
// Carry out the request and receive response
client := http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("Error while making request: %s\n", err)
}
// Status in <200 or >299
if resp.StatusCode < 200 || resp.StatusCode > 299 {
return nil, fmt.Errorf("Error: %d %s\n", resp.StatusCode, resp.Status)
}
// Return response as bytes
dataInBytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("Error reading response: %s\n", err)
}
return dataInBytes, nil
}
func RemoveTorrents(nameSubstr string, relver string, transmissionbt *transmissionrpc.Client) error {
var oldTorrents []int64
torrents, err := transmissionbt.TorrentGet([]string{"id", "name"}, nil)
if err != nil {
return err
} else {
for _, torrent := range torrents {
if strings.Contains(*torrent.Name, nameSubstr) && strings.Contains(*torrent.Name, relver) {
oldTorrents = append(oldTorrents, *torrent.ID)
}
}
}
rmPayload := &transmissionrpc.TorrentRemovePayload{
IDs: oldTorrents,
DeleteLocalData: false,
}
if err := transmissionbt.TorrentRemove(rmPayload); err != nil {
return err
}
return nil
}

48
debian/main.go vendored Normal file
View File

@ -0,0 +1,48 @@
package debian
import (
"fmt"
"log"
thelper "codeberg.org/hyperreal/go-torrent-helper/common"
"github.com/hekmon/transmissionrpc"
)
type Debian struct {
NameSubstr string
Relver string
URL string
}
func (d Debian) AddNewTorrents(transmissionbt *transmissionrpc.Client) error {
// Set torrentURLs for Debian GNU/Linux mirror
d.URL = "https://cdimage.debian.org/debian-cd/current/"
torrentURLs := []string{
fmt.Sprintf("%s/amd64/bt-dvd/debian-%s-amd64-DVD-1.iso.torrent", d.URL, d.Relver),
fmt.Sprintf("%s/arm64/bt-dvd/debian-%s-arm64-DVD-1.iso.torrent", d.URL, d.Relver),
fmt.Sprintf("%s/ppc64el/bt-dvd/debian-%s-ppc64el-DVD-1.iso.torrent", d.URL, d.Relver),
fmt.Sprintf("%s/s390x/bt-dvd/debian-%s-s390x-DVD-1.iso.torrent", d.URL, d.Relver),
}
// Add torrents to Transmission instance
for _, torrentURL := range torrentURLs {
torrent, err := transmissionbt.TorrentAdd(&transmissionrpc.TorrentAddPayload{
Filename: &torrentURL,
})
if err != nil {
return err
}
log.Printf("%s added\n", *torrent.Name)
}
return nil
}
func (d Debian) RemoveOldTorrents(transmissionbt *transmissionrpc.Client) error {
if err := thelper.RemoveTorrents(d.NameSubstr, d.Relver, transmissionbt); err != nil {
return err
}
return nil
}

61
fedora/main.go Normal file
View File

@ -0,0 +1,61 @@
package fedora
import (
"fmt"
"log"
"regexp"
"strings"
"codeberg.org/hyperreal/go-torrent-helper/common"
"github.com/hekmon/transmissionrpc"
)
type Fedora struct {
NameSubstr string
Relver string
URL string
}
func (f Fedora) AddNewTorrents(transmissionbt *transmissionrpc.Client) error {
// Send HTTP GET request and receive response
f.URL = "https://torrent.fedoraproject.org/"
torrentSubstr := fmt.Sprintf("%s.torrent", f.Relver)
dataInBytes, err := common.GetResponse(f.URL)
if err != nil {
return err
}
bodyText := string(dataInBytes)
// Extract torrent URLs from web page contents
var torrentURLs []string
re := regexp.MustCompile(`(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])`)
match := re.FindAllString(bodyText, 1000)
for _, v := range match {
if strings.Contains(v, torrentSubstr) {
torrentURLs = append(torrentURLs, v)
}
}
// Add torrents to Transmission instance
for _, torrentURL := range torrentURLs {
torrent, err := transmissionbt.TorrentAdd(&transmissionrpc.TorrentAddPayload{
Filename: &torrentURL,
})
if err != nil {
return err
}
log.Printf("%s added\n", *torrent.Name)
}
return nil
}
func (f Fedora) RemoveOldTorrents(transmissionbt *transmissionrpc.Client) error {
if err := common.RemoveTorrents(f.NameSubstr, f.Relver, transmissionbt); err != nil {
return err
}
return nil
}

10
go.mod Normal file
View File

@ -0,0 +1,10 @@
module codeberg.org/hyperreal/go-torrent-helper
go 1.20
require github.com/hekmon/transmissionrpc v1.1.0
require (
github.com/hashicorp/go-cleanhttp v0.5.1 // indirect
github.com/hekmon/cunits/v2 v2.0.2 // indirect
)

6
go.sum Normal file
View File

@ -0,0 +1,6 @@
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hekmon/cunits/v2 v2.0.2 h1:qnZMfVxBiTgtAXVSMLKxzV1nihS6KzdjDHgh+nS4RgI=
github.com/hekmon/cunits/v2 v2.0.2/go.mod h1:9r1TycXYXaTmEWlAIfFV8JT+Xo59U96yUJAYHxzii2M=
github.com/hekmon/transmissionrpc v1.1.0 h1:58xY27x2JYxaMlIj7ycKnxqgCm3IjvTxfB7cHPLxOfs=
github.com/hekmon/transmissionrpc v1.1.0/go.mod h1:qkwhsyD/MQSlWvOE1AC92xajwEveAuGsOvTuOBZEuHc=

14
main.go Normal file
View File

@ -0,0 +1,14 @@
package main
import (
"log"
"os"
"codeberg.org/hyperreal/go-torrent-helper/command"
)
func main() {
if err := command.Root(os.Args[1:]); err != nil {
log.Fatalln(err)
}
}

57
nixos/main.go Normal file
View File

@ -0,0 +1,57 @@
package nixos
import (
"encoding/json"
"log"
"codeberg.org/hyperreal/go-torrent-helper/common"
"github.com/hekmon/transmissionrpc"
)
type Nixos struct {
NameSubstr string
URL string
}
func (n Nixos) AddNewTorrents(transmissionbt *transmissionrpc.Client) error {
// Send GET request and receive HTTP response
n.URL = "https://api.github.com/repos/AnimMouse/NixOS-ISO-Torrents/releases/latest"
dataInBytes, err := common.GetResponse(n.URL)
if err != nil {
return err
}
result := make(map[string]interface{})
if err := json.Unmarshal(dataInBytes, &result); err != nil {
return err
}
// Get torrent URLs from HTTP response result
var torrentURLs []interface{}
for _, asset := range result["assets"].([]interface{}) {
torrentURLs = append(torrentURLs, asset.(map[string]interface{})["browser_download_url"])
}
// Add URLs to Transmission
for _, torrentURL := range torrentURLs {
strTorrentURL := torrentURL.(string)
torrent, err := transmissionbt.TorrentAdd(&transmissionrpc.TorrentAddPayload{
Filename: &strTorrentURL,
})
if err != nil {
return err
}
log.Printf("%s added\n", *torrent.Name)
}
return nil
}
func (n Nixos) RemoveOldTorrents(transmissionbt *transmissionrpc.Client) error {
if err := common.RemoveTorrents(n.NameSubstr, "", transmissionbt); err != nil {
return err
}
return nil
}

53
parrot/main.go Normal file
View File

@ -0,0 +1,53 @@
package parrot
import (
"fmt"
"log"
"codeberg.org/hyperreal/go-torrent-helper/common"
"github.com/hekmon/transmissionrpc"
)
type Parrot struct {
NameSubstr string
Relver string
URL string
}
func (p Parrot) AddNewTorrents(transmissionbt *transmissionrpc.Client) error {
// Set torrentURLs for Parrot Security
p.URL = "https://deb.parrot.sh/parrot/"
torrentURLs := []string{
fmt.Sprintf("%s/iso/%s/Parrot-security-%s_amd64.iso.torrent", p.URL, p.Relver, p.Relver),
fmt.Sprintf("%s/iso/%s/Parrot-security-%s_amd64.ova.torrent", p.URL, p.Relver, p.Relver),
fmt.Sprintf("%s/iso/%s/Parrot-security-%s_arm64.utm.torrent", p.URL, p.Relver, p.Relver),
fmt.Sprintf("%s/iso/%s/Parrot-home-%s_amd64.iso.torrent", p.URL, p.Relver, p.Relver),
fmt.Sprintf("%s/iso/%s/Parrot-home-%s_amd64.ova.torrent", p.URL, p.Relver, p.Relver),
fmt.Sprintf("%s/iso/%s/Parrot-home-%s_arm64.utm.torrent", p.URL, p.Relver, p.Relver),
fmt.Sprintf("%s/iso/%s/Parrot-htb-%s_amd64.iso.torrent", p.URL, p.Relver, p.Relver),
fmt.Sprintf("%s/iso/%s/Parrot-architect-%s_arm64.iso.torrent", p.URL, p.Relver, p.Relver),
fmt.Sprintf("%s/iso/%s/Parrot-architect-%s_amd64.iso.torrent", p.URL, p.Relver, p.Relver),
}
// Add torrents to Transmission instance
for _, torrentURL := range torrentURLs {
torrent, err := transmissionbt.TorrentAdd(&transmissionrpc.TorrentAddPayload{
Filename: &torrentURL,
})
if err != nil {
return err
}
log.Printf("%s added\n", *torrent.Name)
}
return nil
}
func (p Parrot) RemoveOldTorrents(transmissionbt *transmissionrpc.Client) error {
if err := common.RemoveTorrents(p.NameSubstr, p.Relver, transmissionbt); err != nil {
return err
}
return nil
}

41
qubes/main.go Normal file
View File

@ -0,0 +1,41 @@
package qubes
import (
"fmt"
"log"
"codeberg.org/hyperreal/go-torrent-helper/common"
"github.com/hekmon/transmissionrpc"
)
type Qubes struct {
NameSubstr string
Relver string
URL string
}
func (q Qubes) AddNewTorrents(transmissionbt *transmissionrpc.Client) error {
// Set torrentURLs for Qubes OS
q.URL = "https://mirrors.edge.kernel.org/qubes/iso/Qubes"
torrentURL := fmt.Sprintf("%s-%s-x86_64.torrent", q.URL, q.Relver)
// Add torrent to Transmission instance
torrent, err := transmissionbt.TorrentAdd(&transmissionrpc.TorrentAddPayload{
Filename: &torrentURL,
})
if err != nil {
return err
}
log.Printf("%s added\n", *torrent.Name)
return nil
}
func (q Qubes) RemoveOldTorrents(transmissionbt *transmissionrpc.Client) error {
if err := common.RemoveTorrents(q.NameSubstr, q.Relver, transmissionbt); err != nil {
return err
}
return nil
}

48
rocky/main.go Normal file
View File

@ -0,0 +1,48 @@
package rocky
import (
"fmt"
"log"
"codeberg.org/hyperreal/go-torrent-helper/common"
"github.com/hekmon/transmissionrpc"
)
type Rocky struct {
NameSubstr string
Relver string
URL string
}
func (r Rocky) AddNewTorrents(transmissionbt *transmissionrpc.Client) error {
// Set torrentURLs for Rocky Linux mirror
r.URL = "https://download.rockylinux.org/pub/rocky/"
torrentURLs := []string{
fmt.Sprintf("%s/%s/isos/x86_64/Rocky-%s-x86_64-dvd.torrent", r.URL, r.Relver, r.Relver),
fmt.Sprintf("%s/%s/isos/aarch64/Rocky-%s-aarch64-dvd.torrent", r.URL, r.Relver, r.Relver),
fmt.Sprintf("%s/%s/isos/ppc64le/Rocky-%s-ppc64le-dvd.torrent", r.URL, r.Relver, r.Relver),
fmt.Sprintf("%s/%s/isos/s390x/Rocky-%s-s390x-dvd.torrent", r.URL, r.Relver, r.Relver),
}
// Add torrents to Transmission instance
for _, torrentURL := range torrentURLs {
torrent, err := transmissionbt.TorrentAdd(&transmissionrpc.TorrentAddPayload{
Filename: &torrentURL,
})
if err != nil {
return err
}
log.Printf("%s added\n", *torrent.Name)
}
return nil
}
func (r Rocky) RemoveOldTorrents(transmissionbt *transmissionrpc.Client) error {
if err := common.RemoveTorrents(r.NameSubstr, r.Relver, transmissionbt); err != nil {
return err
}
return nil
}