216 lines
5.2 KiB
Go
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)")
|
|
}
|