Changelog: 0.1.3

This commit is contained in:
Mukhtar Akere
2024-09-01 13:17:15 +01:00
parent 74791d6e62
commit d405e0d8e0
11 changed files with 398 additions and 111 deletions

88
common/cache.go Normal file
View File

@@ -0,0 +1,88 @@
package common
import (
"sync"
)
type Cache struct {
data map[string]struct{}
order []string
maxItems int
mu sync.RWMutex
}
func NewCache(maxItems int) *Cache {
if maxItems <= 0 {
maxItems = 1000
}
return &Cache{
data: make(map[string]struct{}, maxItems),
order: make([]string, 0, maxItems),
maxItems: maxItems,
}
}
func (c *Cache) Add(value string) {
c.mu.Lock()
defer c.mu.Unlock()
if _, exists := c.data[value]; !exists {
if len(c.order) >= c.maxItems {
delete(c.data, c.order[0])
c.order = c.order[1:]
}
c.data[value] = struct{}{}
c.order = append(c.order, value)
}
}
func (c *Cache) AddMultiple(values map[string]bool) {
c.mu.Lock()
defer c.mu.Unlock()
for value := range values {
if _, exists := c.data[value]; !exists {
if len(c.order) >= c.maxItems {
delete(c.data, c.order[0])
c.order = c.order[1:]
}
c.data[value] = struct{}{}
c.order = append(c.order, value)
}
}
}
func (c *Cache) Get(index int) (string, bool) {
c.mu.RLock()
defer c.mu.RUnlock()
if index < 0 || index >= len(c.order) {
return "", false
}
return c.order[index], true
}
func (c *Cache) GetMultiple(values []string) map[string]bool {
c.mu.RLock()
defer c.mu.RUnlock()
result := make(map[string]bool, len(values))
for _, value := range values {
if _, exists := c.data[value]; exists {
result[value] = true
}
}
return result
}
func (c *Cache) Exists(value string) bool {
c.mu.RLock()
defer c.mu.RUnlock()
_, exists := c.data[value]
return exists
}
func (c *Cache) Len() int {
c.mu.RLock()
defer c.mu.RUnlock()
return len(c.order)
}

View File

@@ -16,7 +16,6 @@ type DebridConfig struct {
}
type Config struct {
DbDSN string `json:"db_dsn"`
Debrid DebridConfig `json:"debrid"`
Arrs []struct {
WatchFolder string `json:"watch_folder"`
@@ -32,6 +31,7 @@ type Config struct {
Password string `json:"password"`
CachedOnly bool `json:"cached_only"`
}
MaxCacheSize int `json:"max_cache_size"`
}
func LoadConfig(path string) (*Config, error) {

View File

@@ -2,11 +2,16 @@ package common
import (
"bufio"
"encoding/base32"
"encoding/hex"
"fmt"
"github.com/anacrolix/torrent/metainfo"
"log"
"math/rand"
"net/http"
"net/url"
"os"
"regexp"
"strings"
)
@@ -46,14 +51,51 @@ func OpenMagnetFile(filePath string) string {
return ""
}
func OpenMagnetHttpURL(magnetLink string) (*Magnet, error) {
resp, err := http.Get(magnetLink)
if err != nil {
return nil, fmt.Errorf("error making GET request: %v", err)
}
defer func(resp *http.Response) {
err := resp.Body.Close()
if err != nil {
return
}
}(resp) // Ensure the response is closed after the function ends
// Create a scanner to read the file line by line
mi, err := metainfo.Load(resp.Body)
if err != nil {
return nil, err
}
hash := mi.HashInfoBytes()
infoHash := hash.HexString()
info, err := mi.UnmarshalInfo()
if err != nil {
return nil, err
}
log.Println("InfoHash: ", infoHash)
magnet := &Magnet{
InfoHash: infoHash,
Name: info.Name,
Size: info.Length,
Link: mi.Magnet(&hash, &info).String(),
}
return magnet, nil
}
func GetMagnetInfo(magnetLink string) (*Magnet, error) {
if magnetLink == "" {
return nil, fmt.Errorf("error getting magnet from file")
}
magnetURI, err := url.Parse(magnetLink)
if err != nil {
return nil, fmt.Errorf("error parsing magnet link")
}
query := magnetURI.Query()
xt := query.Get("xt")
dn := query.Get("dn")
@@ -81,3 +123,47 @@ func RandomString(length int) string {
}
return string(b)
}
func ExtractInfoHash(magnetDesc string) string {
const prefix = "xt=urn:btih:"
start := strings.Index(magnetDesc, prefix)
if start == -1 {
return ""
}
hash := ""
start += len(prefix)
end := strings.IndexAny(magnetDesc[start:], "&#")
if end == -1 {
hash = magnetDesc[start:]
} else {
hash = magnetDesc[start : start+end]
}
hash, _ = processInfoHash(hash) // Convert to hex if needed
return hash
}
func processInfoHash(input string) (string, error) {
// Regular expression for a valid 40-character hex infohash
hexRegex := regexp.MustCompile("^[0-9a-fA-F]{40}$")
// If it's already a valid hex infohash, return it as is
if hexRegex.MatchString(input) {
return strings.ToLower(input), nil
}
// If it's 32 characters long, it might be Base32 encoded
if len(input) == 32 {
// Ensure the input is uppercase and remove any padding
input = strings.ToUpper(strings.TrimRight(input, "="))
// Try to decode from Base32
decoded, err := base32.StdEncoding.DecodeString(input)
if err == nil && len(decoded) == 20 {
// If successful and the result is 20 bytes, encode to hex
return hex.EncodeToString(decoded), nil
}
}
// If we get here, it's not a valid infohash and we couldn't convert it
return "", fmt.Errorf("invalid infohash: %s", input)
}