You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
99 lines
2.1 KiB
99 lines
2.1 KiB
3 years ago
|
package magnetinfo
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"net/url"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// Contains all magnet link parameters
|
||
|
type MagnetInfo struct {
|
||
|
DisplayNames []string // DN
|
||
|
ExactLength uint64 // XL
|
||
|
ExactTopics []string // XT
|
||
|
WebSeeds []string // WS
|
||
|
AcceptableSources []string // AS
|
||
|
ExactSources []string // XS
|
||
|
KeywordTopics []string // KT
|
||
|
ManifestTopics []string // MT
|
||
|
AddressTrackers []string // TR
|
||
|
}
|
||
|
|
||
|
// Parses a magnet link and returns its info
|
||
|
func Parse(magnetLink string) (*MagnetInfo, error) {
|
||
|
// split a magnet link identifier and key-value pairs
|
||
|
parts := strings.Split(magnetLink, ":?")
|
||
|
|
||
|
if len(parts) == 1 || parts[0] != "magnet" {
|
||
|
return nil, fmt.Errorf("given string does not contain a \"magnet\" identifier")
|
||
|
}
|
||
|
|
||
|
// get all key-value pairs
|
||
|
pairs := strings.Split(parts[1], "&")
|
||
|
|
||
|
var info MagnetInfo
|
||
|
for _, pair := range pairs {
|
||
|
// get key and its value
|
||
|
keyval := strings.Split(pair, "=")
|
||
|
|
||
|
key := keyval[0]
|
||
|
value := keyval[1]
|
||
|
|
||
|
switch strings.ToLower(key) {
|
||
|
case "dn":
|
||
|
value, err := url.QueryUnescape(value)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
info.DisplayNames = append(info.DisplayNames, value)
|
||
|
|
||
|
case "xl":
|
||
|
length, err := strconv.ParseUint(value, 10, 64)
|
||
|
if err != nil {
|
||
|
fmt.Println(err)
|
||
|
}
|
||
|
info.ExactLength = length
|
||
|
|
||
|
case "xt":
|
||
|
info.ExactTopics = append(info.ExactTopics, value)
|
||
|
|
||
|
case "ws":
|
||
|
info.WebSeeds = append(info.WebSeeds, value)
|
||
|
|
||
|
case "as":
|
||
|
value, err := url.QueryUnescape(value)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
info.AcceptableSources = append(info.AcceptableSources, value)
|
||
|
|
||
|
case "xs":
|
||
|
info.ExactSources = append(info.ExactSources, value)
|
||
|
|
||
|
case "kt":
|
||
|
value, err := url.QueryUnescape(value)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
info.KeywordTopics = append(info.KeywordTopics, value)
|
||
|
|
||
|
case "mt":
|
||
|
value, err := url.QueryUnescape(value)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
info.ManifestTopics = append(info.ManifestTopics, value)
|
||
|
|
||
|
case "tr":
|
||
|
value, err := url.QueryUnescape(value)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
info.AddressTrackers = append(info.AddressTrackers, value)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return &info, nil
|
||
|
}
|