Changelog: 0.1.3
This commit is contained in:
88
common/cache.go
Normal file
88
common/cache.go
Normal 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)
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user