Initial commit: docker compose config
Release Docker multi arch / docker (push) Has been cancelled
Test Install Script / Test Script Syntax (push) Has been cancelled
Test Install Script / Test on almalinux-10 (default) (push) Has been cancelled
Test Install Script / Test on almalinux-10 (root) (push) Has been cancelled
Test Install Script / Test on almalinux-8 (default) (push) Has been cancelled
Test Install Script / Test on almalinux-8 (root) (push) Has been cancelled
Test Install Script / Test on almalinux-9 (default) (push) Has been cancelled
Test Install Script / Test on almalinux-9 (root) (push) Has been cancelled
Test Install Script / Test on amazonlinux-2 (default) (push) Has been cancelled
Test Install Script / Test on amazonlinux-2 (root) (push) Has been cancelled
Test Install Script / Test on debian-11 (default) (push) Has been cancelled
Test Install Script / Test on debian-11 (root) (push) Has been cancelled
Test Install Script / Test on debian-12 (default) (push) Has been cancelled
Test Install Script / Test on debian-12 (root) (push) Has been cancelled
Test Install Script / Test on debian-13 (default) (push) Has been cancelled
Test Install Script / Test on debian-13 (root) (push) Has been cancelled
Test Install Script / Test on fedora-latest (default) (push) Has been cancelled
Test Install Script / Test on fedora-latest (root) (push) Has been cancelled
Test Install Script / Test on rocky-10 (default) (push) Has been cancelled
Test Install Script / Test on rocky-10 (root) (push) Has been cancelled
Test Install Script / Test on rocky-8 (default) (push) Has been cancelled
Test Install Script / Test on rocky-8 (root) (push) Has been cancelled
Test Install Script / Test on rocky-9 (default) (push) Has been cancelled
Test Install Script / Test on rocky-9 (root) (push) Has been cancelled
Test Install Script / Test on ubuntu-22.04 (default) (push) Has been cancelled
Test Install Script / Test on ubuntu-22.04 (root) (push) Has been cancelled
Test Install Script / Test on ubuntu-24.04 (default) (push) Has been cancelled
Test Install Script / Test on ubuntu-24.04 (root) (push) Has been cancelled

This commit is contained in:
2026-05-30 12:07:11 +00:00
commit 616c6b1c62
381 changed files with 55145 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
package torrshash
import (
"bytes"
"math/big"
"regexp"
"strings"
)
const base62Alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
var base62Regex = regexp.MustCompile(`^[a-zA-Z0-9]+$`)
func IsBase62(s string) bool {
return base62Regex.MatchString(strings.TrimSpace(s))
}
func Encode62(b []byte) string {
x := new(big.Int).SetBytes(b)
base := big.NewInt(62)
zero := big.NewInt(0)
mod := new(big.Int)
var res []byte
for x.Cmp(zero) > 0 {
x.QuoRem(x, base, mod)
res = append(res, base62Alphabet[mod.Int64()])
}
for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
res[i], res[j] = res[j], res[i]
}
return string(res)
}
func Decode62(s string) []byte {
res := new(big.Int)
base := big.NewInt(62)
for _, char := range s {
val := bytes.IndexByte([]byte(base62Alphabet), byte(char))
res.Mul(res, base)
res.Add(res, big.NewInt(int64(val)))
}
return res.Bytes()
}
+130
View File
@@ -0,0 +1,130 @@
package torrshash
import (
"encoding/binary"
"fmt"
"io"
"strconv"
"strings"
)
type Field struct {
Tag Tag `json:"tag"`
Value string `json:"value"`
}
type Tag int
const (
TagTitle = iota // string
TagPoster // string
TagTracker // string
TagCategory // string
TagSize // binary
)
func (tag Tag) String() string {
switch tag {
case TagTitle:
return "Title"
case TagPoster:
return "Poster"
case TagTracker:
return "Tracker"
case TagCategory:
return "Category"
case TagSize:
return "Size"
default:
return "Unknown"
}
}
func NewField(tag Tag, value string) *Field {
return &Field{Tag: tag, Value: value}
}
func ReadField(reader io.Reader) (*Field, error) {
tagb := make([]byte, 1)
if _, err := reader.Read(tagb); err == io.EOF {
return nil, nil
}
tag := Tag(tagb[0])
if isBinary(tag) {
var value int64
err := binary.Read(reader, binary.LittleEndian, &value)
if err != nil {
return nil, err
}
return NewField(tag, strconv.FormatInt(value, 10)), nil
}
var length uint16
err := binary.Read(reader, binary.LittleEndian, &length)
if err != nil {
return nil, err
}
valBytes := make([]byte, length)
n, err := io.ReadFull(reader, valBytes)
if err != nil {
return nil, err
}
if n != int(length) {
return nil, fmt.Errorf("expected to read %v bytes, read %v", length, n)
}
return NewField(tag, string(valBytes)), nil
}
func (f *Field) write(writer io.Writer) error {
value := strings.TrimSpace(f.Value)
if len(value) == 0 {
return nil
}
if isBinary(f.Tag) && value == "0" {
return nil
}
_, err := writer.Write([]byte{byte(f.Tag)})
if err != nil {
return err
}
if isBinary(f.Tag) {
ii, err := strconv.ParseInt(value, 10, 64)
if err != nil {
return err
}
if ii == 0 {
return nil
}
return binary.Write(writer, binary.LittleEndian, ii)
}
strBytes := []byte(value)
err = binary.Write(writer, binary.LittleEndian, uint16(len(strBytes)))
if err != nil {
return err
}
_, err = writer.Write(strBytes)
return err
}
func isBinary(t Tag) bool {
switch t {
case TagTitle:
case TagPoster:
case TagTracker:
case TagCategory:
return false
case TagSize:
return true
default:
return false
}
return false
}
+83
View File
@@ -0,0 +1,83 @@
package torrshash
import (
"bytes"
"compress/zlib"
"encoding/hex"
"io"
"strings"
)
func Pack(hash *TorrsHash) (string, error) {
data, err := pack(hash)
if err != nil {
return "", err
}
return Encode62(data), nil
}
func PackBytes(hash *TorrsHash) ([]byte, error) {
return pack(hash)
}
func Unpack(token string) (*TorrsHash, error) {
data := Decode62(strings.TrimSpace(token))
return UnpackBytes(data)
}
func UnpackBytes(data []byte) (*TorrsHash, error) {
return unpack(data)
}
func pack(t *TorrsHash) ([]byte, error) {
buf := new(bytes.Buffer)
zw, err := zlib.NewWriterLevel(buf, zlib.BestCompression)
if err != nil {
return nil, err
}
hashBytes, _ := hex.DecodeString(strings.TrimSpace(t.Hash))
_, err = zw.Write(hashBytes)
if err != nil {
return nil, err
}
for _, f := range t.Fields {
err = f.write(zw)
if err != nil {
return nil, err
}
}
err = zw.Close()
return buf.Bytes(), err
}
func unpack(data []byte) (*TorrsHash, error) {
zr, err := zlib.NewReader(bytes.NewReader(data))
if err != nil {
return nil, err
}
defer zr.Close()
hashBuf := make([]byte, 20)
if _, err = io.ReadFull(zr, hashBuf); err != nil {
return nil, err
}
th := &TorrsHash{}
th.Hash = hex.EncodeToString(hashBuf)
for {
field, err := ReadField(zr)
if err == nil && field == nil {
//End on read
return th, nil
}
if err != nil {
return th, err
}
th.Fields = append(th.Fields, field)
}
}
+62
View File
@@ -0,0 +1,62 @@
package torrshash
type TorrsHash struct {
Hash string `json:"hash"`
Fields []*Field `json:"fields"`
}
func New(hash string) *TorrsHash {
th := &TorrsHash{}
th.Hash = hash
return th
}
func (th *TorrsHash) AddField(tag Tag, value string) {
th.Fields = append(th.Fields, &Field{tag, value})
}
func (h *TorrsHash) Title() string {
for _, f := range h.Fields {
if f.Tag == TagTitle {
return f.Value
}
}
return ""
}
func (h *TorrsHash) Poster() string {
for _, f := range h.Fields {
if f.Tag == TagPoster {
return f.Value
}
}
return ""
}
func (h *TorrsHash) Category() string {
for _, f := range h.Fields {
if f.Tag == TagCategory {
return f.Value
}
}
return ""
}
func (h *TorrsHash) Trackers() []string {
var list []string
for _, f := range h.Fields {
if f.Tag == TagTracker {
list = append(list, f.Value)
}
}
return list
}
func (h *TorrsHash) String() string {
str := "Hash: " + h.Hash
for _, f := range h.Fields {
str += " " + f.Tag.String() + ": " + f.Value
}
return str
}