Files
zurg/pkg/realdebrid/types.go
2024-06-28 22:40:39 +02:00

216 lines
5.2 KiB
Go

package realdebrid
import (
"errors"
"math"
"strings"
jsoniter "github.com/json-iterator/go"
)
var json = jsoniter.ConfigCompatibleWithStandardLibrary
type FileJSON struct {
FileSize int `json:"filesize"`
Link string `json:"link"`
}
type Download struct {
ID string `json:"id"`
Filename string `json:"filename"`
Filesize int64 `json:"filesize"` // bytes, 0 if unknown
Link string `json:"link"` // Original link
Host string `json:"host"` // Host main domain
Download string `json:"download"` // Generated link
Streamable int `json:"streamable"`
Generated string `json:"-"` // jsonDate
Token string `json:"-"`
Type string `json:"type"`
}
func (d *Download) UnmarshalJSON(data []byte) error {
type Alias Download
aux := &struct {
Generated string `json:"generated"`
*Alias
}{
Alias: (*Alias)(d),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
d.Generated = strings.Replace(aux.Generated, "Z", "+01:00", 1)
return nil
}
type Torrent struct {
ID string `json:"id"`
Name string `json:"filename"`
Hash string `json:"hash"`
Progress int `json:"-"`
Status string `json:"status"`
Links []string `json:"links"`
Added string `json:"-"`
}
func (i *Torrent) UnmarshalJSON(data []byte) error {
type Alias Torrent
aux := &struct {
Progress float64 `json:"progress"`
Added string `json:"added"`
*Alias
}{
Alias: (*Alias)(i),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
i.Progress = int(math.Floor(aux.Progress))
i.Added = strings.Replace(aux.Added, "Z", "+01:00", 1)
return nil
}
func (i *Torrent) MarshalJSON() ([]byte, error) {
type Alias Torrent
aux := &struct {
Progress float64 `json:"progress"`
Added string `json:"added"`
*Alias
}{
Alias: (*Alias)(i),
Progress: float64(i.Progress), // Convert int to float64 for JSON representation
Added: i.Added,
}
return json.Marshal(aux)
}
type TorrentInfo struct {
ID string `json:"id"`
Name string `json:"filename"`
Hash string `json:"hash"`
Progress int `json:"-"`
Status string `json:"status"`
Added string `json:"-"`
Ended string `json:"-"`
Bytes int64 `json:"bytes"`
Links []string `json:"links"`
OriginalName string `json:"original_filename"`
OriginalBytes int64 `json:"original_bytes"`
Files []File `json:"files"`
}
func (i *TorrentInfo) IsComplete() bool {
selectedCount := 0
for _, file := range i.Files {
if file.Selected == 1 {
selectedCount++
}
}
if i.Progress != 100 {
return false
}
return selectedCount == len(i.Links) && len(i.Links) > 0
}
func (i *TorrentInfo) MarshalJSON() ([]byte, error) {
type Alias TorrentInfo
aux := &struct {
Progress float64 `json:"progress"`
Added string `json:"added"`
Ended string `json:"ended"`
*Alias
}{
Alias: (*Alias)(i),
Progress: float64(i.Progress), // Convert int to float64 for JSON representation
Added: i.Added,
}
if i.Ended != "" {
aux.Ended = i.Ended
}
return json.Marshal(aux)
}
func (i *TorrentInfo) UnmarshalJSON(data []byte) error {
type Alias TorrentInfo
aux := &struct {
Progress float64 `json:"progress"`
Added string `json:"added"`
Ended string `json:"ended"`
*Alias
}{
Alias: (*Alias)(i),
}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
i.Progress = int(math.Floor(aux.Progress))
i.Added = strings.Replace(aux.Added, "Z", "+01:00", 1)
if aux.Ended != "" {
i.Ended = strings.Replace(aux.Ended, "Z", "+01:00", 1)
}
return nil
}
type File struct {
ID int `json:"id"`
Path string `json:"path"`
Bytes int64 `json:"bytes"`
Selected int `json:"selected"`
}
type MagnetResponse struct {
ID string `json:"id"`
URI string `json:"uri"`
}
type ActiveTorrentCountResponse struct {
DownloadingCount int `json:"nb"`
MaxNumberOfTorrents int `json:"limit"`
}
type User struct {
ID int `json:"id"`
Username string `json:"username"`
Email string `json:"email"`
Points int `json:"points"` // Fidelity points
Locale string `json:"locale"` // User language
Type string `json:"type"` // "premium" or "free"
Premium int `json:"premium"` // seconds left as a Premium user
Expiration string `json:"expiration"` // jsonDate
}
// key: torrent hash
type AvailabilityResponse map[string]HosterHash
type HosterHash struct {
// key: "rd"
Variants map[string][]SelectionVariant
Strings []string
}
// key: file id
type SelectionVariant map[int]FileData
type FileData struct {
Filename string `json:"filename"`
Filesize int `json:"filesize"`
}
func (h *HosterHash) UnmarshalJSON(data []byte) error {
// First, try unmarshaling as map[string][]SelectionVariant
var variants map[string][]SelectionVariant
if err := json.Unmarshal(data, &variants); err == nil {
h.Variants = variants
return nil
}
// If that fails, try unmarshaling as []string
var strings []string
if err := json.Unmarshal(data, &strings); err == nil {
h.Strings = strings
return nil
}
return errors.New("availability json data did not match expected formats (map or array)")
}