mirror of
https://github.com/simon-ding/polaris.git
synced 2026-03-20 19:17:36 +08:00
WIP: qbittorrent support
This commit is contained in:
32
pkg/go-qbittorrent/.dockerignore
Normal file
32
pkg/go-qbittorrent/.dockerignore
Normal file
@@ -0,0 +1,32 @@
|
||||
# Include any files or directories that you don't want to be copied to your
|
||||
# container here (e.g., local build artifacts, temporary files, etc.).
|
||||
#
|
||||
# For more help, visit the .dockerignore file reference guide at
|
||||
# https://docs.docker.com/engine/reference/builder/#dockerignore-file
|
||||
|
||||
**/.DS_Store
|
||||
**/.classpath
|
||||
**/.dockerignore
|
||||
**/.env
|
||||
**/.git
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
||||
1
pkg/go-qbittorrent/.gitignore
vendored
Normal file
1
pkg/go-qbittorrent/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
./main.go
|
||||
19
pkg/go-qbittorrent/README.md
Normal file
19
pkg/go-qbittorrent/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
go-qbittorrent
|
||||
==================
|
||||
|
||||
Golang wrapper for qBittorrent Web API (for versions above v4.1) forked from [superturkey650](https://github.com/superturkey650/go-qbittorrent) version (only supporting older API version)
|
||||
|
||||
This wrapper is based on the methods described in [qBittorrent's Official Web API](https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)>)
|
||||
|
||||
Some methods are only supported in qBittorent's latest version (v4.5 when writing).
|
||||
|
||||
It'll be best if you upgrade your client to a latest version.
|
||||
|
||||
An example can be found in main.go
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
The best way is to install with go get::
|
||||
|
||||
$ go get github.com/simon-ding/go-qbittorrent/qbt
|
||||
260
pkg/go-qbittorrent/docs.txt
Normal file
260
pkg/go-qbittorrent/docs.txt
Normal file
@@ -0,0 +1,260 @@
|
||||
PACKAGE DOCUMENTATION
|
||||
|
||||
package qbt
|
||||
import "/Users/me/Repos/go/src/go-qbittorrent/qbt"
|
||||
|
||||
|
||||
TYPES
|
||||
|
||||
type BasicTorrent struct {
|
||||
AddedOn int `json:"added_on"`
|
||||
Category string `json:"category"`
|
||||
CompletionOn int64 `json:"completion_on"`
|
||||
Dlspeed int `json:"dlspeed"`
|
||||
Eta int `json:"eta"`
|
||||
ForceStart bool `json:"force_start"`
|
||||
Hash string `json:"hash"`
|
||||
Name string `json:"name"`
|
||||
NumComplete int `json:"num_complete"`
|
||||
NumIncomplete int `json:"num_incomplete"`
|
||||
NumLeechs int `json:"num_leechs"`
|
||||
NumSeeds int `json:"num_seeds"`
|
||||
Priority int `json:"priority"`
|
||||
Progress int `json:"progress"`
|
||||
Ratio int `json:"ratio"`
|
||||
SavePath string `json:"save_path"`
|
||||
SeqDl bool `json:"seq_dl"`
|
||||
Size int `json:"size"`
|
||||
State string `json:"state"`
|
||||
SuperSeeding bool `json:"super_seeding"`
|
||||
Upspeed int `json:"upspeed"`
|
||||
}
|
||||
BasicTorrent holds a basic torrent object from qbittorrent
|
||||
|
||||
type Client struct {
|
||||
URL string
|
||||
Authenticated bool
|
||||
Session string //replace with session type
|
||||
Jar http.CookieJar
|
||||
// contains filtered or unexported fields
|
||||
}
|
||||
Client creates a connection to qbittorrent and performs requests
|
||||
|
||||
func NewClient(url string) *Client
|
||||
NewClient creates a new client connection to qbittorrent
|
||||
|
||||
func (c *Client) AddTrackers(infoHash string, trackers string) (*http.Response, error)
|
||||
AddTrackers adds trackers to a specific torrent
|
||||
|
||||
func (c *Client) DecreasePriority(infoHashList []string) (*http.Response, error)
|
||||
DecreasePriority decreases the priority of a list of torrents
|
||||
|
||||
func (c *Client) DeletePermanently(infoHashList []string) (*http.Response, error)
|
||||
DeletePermanently deletes all files for a list of torrents
|
||||
|
||||
func (c *Client) DeleteTemp(infoHashList []string) (*http.Response, error)
|
||||
DeleteTemp deletes the temporary files for a list of torrents
|
||||
|
||||
func (c *Client) DownloadFromFile(file string, options map[string]string) (*http.Response, error)
|
||||
DownloadFromFile downloads a torrent from a file
|
||||
|
||||
func (c *Client) DownloadFromLink(link string, options map[string]string) (*http.Response, error)
|
||||
DownloadFromLink starts downloading a torrent from a link
|
||||
|
||||
func (c *Client) ForceStart(infoHashList []string, value bool) (*http.Response, error)
|
||||
ForceStart force starts a list of torrents
|
||||
|
||||
func (c *Client) GetAlternativeSpeedStatus() (status bool, err error)
|
||||
GetAlternativeSpeedStatus gets the alternative speed status of your
|
||||
qbittorrent client
|
||||
|
||||
func (c *Client) GetGlobalDownloadLimit() (limit int, err error)
|
||||
GetGlobalDownloadLimit gets the global download limit of your
|
||||
qbittorrent client
|
||||
|
||||
func (c *Client) GetGlobalUploadLimit() (limit int, err error)
|
||||
GetGlobalUploadLimit gets the global upload limit of your qbittorrent
|
||||
client
|
||||
|
||||
func (c *Client) GetTorrentDownloadLimit(infoHashList []string) (limits map[string]string, err error)
|
||||
GetTorrentDownloadLimit gets the download limit for a list of torrents
|
||||
|
||||
func (c *Client) GetTorrentUploadLimit(infoHashList []string) (limits map[string]string, err error)
|
||||
GetTorrentUploadLimit gets the upload limit for a list of torrents
|
||||
|
||||
func (c *Client) IncreasePriority(infoHashList []string) (*http.Response, error)
|
||||
IncreasePriority increases the priority of a list of torrents
|
||||
|
||||
func (c *Client) Login(username string, password string) (loggedIn bool, err error)
|
||||
Login logs you in to the qbittorrent client
|
||||
|
||||
func (c *Client) Logout() (loggedOut bool, err error)
|
||||
Logout logs you out of the qbittorrent client
|
||||
|
||||
func (c *Client) Pause(infoHash string) (*http.Response, error)
|
||||
Pause pauses a specific torrent
|
||||
|
||||
func (c *Client) PauseAll() (*http.Response, error)
|
||||
PauseAll pauses all torrents
|
||||
|
||||
func (c *Client) PauseMultiple(infoHashList []string) (*http.Response, error)
|
||||
PauseMultiple pauses a list of torrents
|
||||
|
||||
func (c *Client) Recheck(infoHashList []string) (*http.Response, error)
|
||||
Recheck rechecks a list of torrents
|
||||
|
||||
func (c *Client) Resume(infoHash string) (*http.Response, error)
|
||||
Resume resumes a specific torrent
|
||||
|
||||
func (c *Client) ResumeAll(infoHashList []string) (*http.Response, error)
|
||||
ResumeAll resumes all torrents
|
||||
|
||||
func (c *Client) ResumeMultiple(infoHashList []string) (*http.Response, error)
|
||||
ResumeMultiple resumes a list of torrents
|
||||
|
||||
func (c *Client) SetCategory(infoHashList []string, category string) (*http.Response, error)
|
||||
SetCategory sets the category for a list of torrents
|
||||
|
||||
func (c *Client) SetFilePriority(infoHash string, fileID string, priority string) (*http.Response, error)
|
||||
SetFilePriority sets the priority for a specific torrent file
|
||||
|
||||
func (c *Client) SetGlobalDownloadLimit(limit string) (*http.Response, error)
|
||||
SetGlobalDownloadLimit sets the global download limit of your
|
||||
qbittorrent client
|
||||
|
||||
func (c *Client) SetGlobalUploadLimit(limit string) (*http.Response, error)
|
||||
SetGlobalUploadLimit sets the global upload limit of your qbittorrent
|
||||
client
|
||||
|
||||
func (c *Client) SetLabel(infoHashList []string, label string) (*http.Response, error)
|
||||
SetLabel sets the labels for a list of torrents
|
||||
|
||||
func (c *Client) SetMaxPriority(infoHashList []string) (*http.Response, error)
|
||||
SetMaxPriority sets the max priority for a list of torrents
|
||||
|
||||
func (c *Client) SetMinPriority(infoHashList []string) (*http.Response, error)
|
||||
SetMinPriority sets the min priority for a list of torrents
|
||||
|
||||
func (c *Client) SetPreferences(params map[string]string) (*http.Response, error)
|
||||
SetPreferences sets the preferences of your qbittorrent client
|
||||
|
||||
func (c *Client) SetTorrentDownloadLimit(infoHashList []string, limit string) (*http.Response, error)
|
||||
SetTorrentDownloadLimit sets the download limit for a list of torrents
|
||||
|
||||
func (c *Client) SetTorrentUploadLimit(infoHashList []string, limit string) (*http.Response, error)
|
||||
SetTorrentUploadLimit sets the upload limit of a list of torrents
|
||||
|
||||
func (c *Client) Shutdown() (shuttingDown bool, err error)
|
||||
Shutdown shuts down the qbittorrent client
|
||||
|
||||
func (c *Client) Sync(rid string) (Sync, error)
|
||||
Sync syncs main data of qbittorrent
|
||||
|
||||
func (c *Client) ToggleAlternativeSpeed() (*http.Response, error)
|
||||
ToggleAlternativeSpeed toggles the alternative speed of your qbittorrent
|
||||
client
|
||||
|
||||
func (c *Client) ToggleFirstLastPiecePriority(infoHashList []string) (*http.Response, error)
|
||||
ToggleFirstLastPiecePriority toggles first last piece priority of a list
|
||||
of torrents
|
||||
|
||||
func (c *Client) ToggleSequentialDownload(infoHashList []string) (*http.Response, error)
|
||||
ToggleSequentialDownload toggles the download sequence of a list of
|
||||
torrents
|
||||
|
||||
func (c *Client) Torrent(infoHash string) (Torrent, error)
|
||||
Torrent gets a specific torrent
|
||||
|
||||
func (c *Client) TorrentFiles(infoHash string) ([]TorrentFile, error)
|
||||
TorrentFiles gets the files of a specifc torrent
|
||||
|
||||
func (c *Client) TorrentTrackers(infoHash string) ([]Tracker, error)
|
||||
TorrentTrackers gets all trackers for a specific torrent
|
||||
|
||||
func (c *Client) TorrentWebSeeds(infoHash string) ([]WebSeed, error)
|
||||
TorrentWebSeeds gets seeders for a specific torrent
|
||||
|
||||
func (c *Client) Torrents(filters map[string]string) (torrentList []BasicTorrent, err error)
|
||||
Torrents gets a list of all torrents in qbittorrent matching your filter
|
||||
|
||||
type Sync struct {
|
||||
Categories []string `json:"categories"`
|
||||
FullUpdate bool `json:"full_update"`
|
||||
Rid int `json:"rid"`
|
||||
ServerState struct {
|
||||
ConnectionStatus string `json:"connection_status"`
|
||||
DhtNodes int `json:"dht_nodes"`
|
||||
DlInfoData int `json:"dl_info_data"`
|
||||
DlInfoSpeed int `json:"dl_info_speed"`
|
||||
DlRateLimit int `json:"dl_rate_limit"`
|
||||
Queueing bool `json:"queueing"`
|
||||
RefreshInterval int `json:"refresh_interval"`
|
||||
UpInfoData int `json:"up_info_data"`
|
||||
UpInfoSpeed int `json:"up_info_speed"`
|
||||
UpRateLimit int `json:"up_rate_limit"`
|
||||
UseAltSpeedLimits bool `json:"use_alt_speed_limits"`
|
||||
} `json:"server_state"`
|
||||
Torrents map[string]Torrent `json:"torrents"`
|
||||
}
|
||||
Sync holds the sync response struct
|
||||
|
||||
type Torrent struct {
|
||||
AdditionDate int `json:"addition_date"`
|
||||
Comment string `json:"comment"`
|
||||
CompletionDate int `json:"completion_date"`
|
||||
CreatedBy string `json:"created_by"`
|
||||
CreationDate int `json:"creation_date"`
|
||||
DlLimit int `json:"dl_limit"`
|
||||
DlSpeed int `json:"dl_speed"`
|
||||
DlSpeedAvg int `json:"dl_speed_avg"`
|
||||
Eta int `json:"eta"`
|
||||
LastSeen int `json:"last_seen"`
|
||||
NbConnections int `json:"nb_connections"`
|
||||
NbConnectionsLimit int `json:"nb_connections_limit"`
|
||||
Peers int `json:"peers"`
|
||||
PeersTotal int `json:"peers_total"`
|
||||
PieceSize int `json:"piece_size"`
|
||||
PiecesHave int `json:"pieces_have"`
|
||||
PiecesNum int `json:"pieces_num"`
|
||||
Reannounce int `json:"reannounce"`
|
||||
SavePath string `json:"save_path"`
|
||||
SeedingTime int `json:"seeding_time"`
|
||||
Seeds int `json:"seeds"`
|
||||
SeedsTotal int `json:"seeds_total"`
|
||||
ShareRatio float64 `json:"share_ratio"`
|
||||
TimeElapsed int `json:"time_elapsed"`
|
||||
TotalDownloaded int `json:"total_downloaded"`
|
||||
TotalDownloadedSession int `json:"total_downloaded_session"`
|
||||
TotalSize int `json:"total_size"`
|
||||
TotalUploaded int `json:"total_uploaded"`
|
||||
TotalUploadedSession int `json:"total_uploaded_session"`
|
||||
TotalWasted int `json:"total_wasted"`
|
||||
UpLimit int `json:"up_limit"`
|
||||
UpSpeed int `json:"up_speed"`
|
||||
UpSpeedAvg int `json:"up_speed_avg"`
|
||||
}
|
||||
Torrent holds a torrent object from qbittorrent
|
||||
|
||||
type TorrentFile struct {
|
||||
IsSeed bool `json:"is_seed"`
|
||||
Name string `json:"name"`
|
||||
Priority int `json:"priority"`
|
||||
Progress int `json:"progress"`
|
||||
Size int `json:"size"`
|
||||
}
|
||||
TorrentFile holds a torrent file object from qbittorrent
|
||||
|
||||
type Tracker struct {
|
||||
Msg string `json:"msg"`
|
||||
NumPeers int `json:"num_peers"`
|
||||
Status string `json:"status"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
Tracker holds a tracker object from qbittorrent
|
||||
|
||||
type WebSeed struct {
|
||||
URL string `json:"url"`
|
||||
}
|
||||
WebSeed holds a webseed object from qbittorrent
|
||||
|
||||
|
||||
66
pkg/go-qbittorrent/go-qbittorrent.go
Normal file
66
pkg/go-qbittorrent/go-qbittorrent.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package qbittorrent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"polaris/pkg/go-qbittorrent/qbt"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// connect to qbittorrent client
|
||||
qb := qbt.NewClient("http://localhost:8181")
|
||||
|
||||
// login to the client
|
||||
loginOpts := qbt.LoginOptions{
|
||||
Username: "username",
|
||||
Password: "password",
|
||||
}
|
||||
err := qb.Login(loginOpts)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// ********************
|
||||
// DOWNLOAD A TORRENT *
|
||||
// ********************
|
||||
|
||||
// were not using any filters so the options map is empty
|
||||
downloadOpts := qbt.DownloadOptions{}
|
||||
// set the path to the file
|
||||
//path := "/Users/me/Downloads/Source.Code.2011.1080p.BluRay.H264.AAC-RARBG-[rarbg.to].torrent"
|
||||
links := []string{"http://rarbg.to/download.php?id=9buc5hp&h=d73&f=Courage.the.Cowardly.Dog.1999.S01.1080p.AMZN.WEBRip.DD2.0.x264-NOGRP%5Brartv%5D-[rarbg.to].torrent"}
|
||||
// download the torrent using the file
|
||||
// the wrapper will handle opening and closing the file for you
|
||||
err = qb.DownloadLinks(links, downloadOpts)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("[-] Download torrent from link")
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println("[+] Download torrent from link")
|
||||
}
|
||||
|
||||
// ******************
|
||||
// GET ALL TORRENTS *
|
||||
// ******************
|
||||
torrentsOpts := qbt.TorrentsOptions{}
|
||||
filter := "inactive"
|
||||
sort := "name"
|
||||
hash := "d739f78a12b241ba62719b1064701ffbb45498a8"
|
||||
torrentsOpts.Filter = &filter
|
||||
torrentsOpts.Sort = &sort
|
||||
torrentsOpts.Hashes = []string{hash}
|
||||
torrents, err := qb.Torrents(torrentsOpts)
|
||||
if err != nil {
|
||||
fmt.Println("[-] Get torrent list")
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println("[+] Get torrent list")
|
||||
if len(torrents) > 0 {
|
||||
spew.Dump(torrents[0])
|
||||
} else {
|
||||
fmt.Println("No torrents found")
|
||||
}
|
||||
}
|
||||
}
|
||||
1139
pkg/go-qbittorrent/qbt/api.go
Normal file
1139
pkg/go-qbittorrent/qbt/api.go
Normal file
File diff suppressed because it is too large
Load Diff
387
pkg/go-qbittorrent/qbt/models.go
Normal file
387
pkg/go-qbittorrent/qbt/models.go
Normal file
@@ -0,0 +1,387 @@
|
||||
package qbt
|
||||
|
||||
//BasicTorrent holds a basic torrent object from qbittorrent
|
||||
type BasicTorrent struct {
|
||||
Category string `json:"category"`
|
||||
CompletionOn int64 `json:"completion_on"`
|
||||
Dlspeed int `json:"dlspeed"`
|
||||
Eta int `json:"eta"`
|
||||
ForceStart bool `json:"force_start"`
|
||||
Hash string `json:"hash"`
|
||||
Name string `json:"name"`
|
||||
NumComplete int `json:"num_complete"`
|
||||
NumIncomplete int `json:"num_incomplete"`
|
||||
NumLeechs int `json:"num_leechs"`
|
||||
NumSeeds int `json:"num_seeds"`
|
||||
Priority int `json:"priority"`
|
||||
Progress int `json:"progress"`
|
||||
Ratio int `json:"ratio"`
|
||||
SavePath string `json:"save_path"`
|
||||
SeqDl bool `json:"seq_dl"`
|
||||
Size int `json:"size"`
|
||||
State string `json:"state"`
|
||||
SuperSeeding bool `json:"super_seeding"`
|
||||
Upspeed int `json:"upspeed"`
|
||||
FirstLastPiecePriority bool `json:"f_l_piece_prio"`
|
||||
}
|
||||
|
||||
//Torrent holds a torrent object from qbittorrent
|
||||
//with more information than BasicTorrent
|
||||
type Torrent struct {
|
||||
AdditionDate int `json:"addition_date"`
|
||||
Comment string `json:"comment"`
|
||||
CompletionDate int `json:"completion_date"`
|
||||
CreatedBy string `json:"created_by"`
|
||||
CreationDate int `json:"creation_date"`
|
||||
DlLimit int `json:"dl_limit"`
|
||||
DlSpeed int `json:"dl_speed"`
|
||||
DlSpeedAvg int `json:"dl_speed_avg"`
|
||||
Eta int `json:"eta"`
|
||||
LastSeen int `json:"last_seen"`
|
||||
NbConnections int `json:"nb_connections"`
|
||||
NbConnectionsLimit int `json:"nb_connections_limit"`
|
||||
Peers int `json:"peers"`
|
||||
PeersTotal int `json:"peers_total"`
|
||||
PieceSize int `json:"piece_size"`
|
||||
PiecesHave int `json:"pieces_have"`
|
||||
PiecesNum int `json:"pieces_num"`
|
||||
Reannounce int `json:"reannounce"`
|
||||
SavePath string `json:"save_path"`
|
||||
SeedingTime int `json:"seeding_time"`
|
||||
Seeds int `json:"seeds"`
|
||||
SeedsTotal int `json:"seeds_total"`
|
||||
ShareRatio float64 `json:"share_ratio"`
|
||||
TimeElapsed int `json:"time_elapsed"`
|
||||
TotalDl int `json:"total_downloaded"`
|
||||
TotalDlSession int `json:"total_downloaded_session"`
|
||||
TotalSize int `json:"total_size"`
|
||||
TotalUl int `json:"total_uploaded"`
|
||||
TotalUlSession int `json:"total_uploaded_session"`
|
||||
TotalWasted int `json:"total_wasted"`
|
||||
UpLimit int `json:"up_limit"`
|
||||
UpSpeed int `json:"up_speed"`
|
||||
UpSpeedAvg int `json:"up_speed_avg"`
|
||||
}
|
||||
|
||||
type TorrentInfo struct {
|
||||
AddedOn int64 `json:"added_on"`
|
||||
AmountLeft int64 `json:"amount_left"`
|
||||
AutoTmm bool `json:"auto_tmm"`
|
||||
Availability int64 `json:"availability"`
|
||||
Category string `json:"category"`
|
||||
Completed int64 `json:"completed"`
|
||||
CompletionOn int64 `json:"completion_on"`
|
||||
ContentPath string `json:"content_path"`
|
||||
DlLimit int64 `json:"dl_limit"`
|
||||
Dlspeed int64 `json:"dlspeed"`
|
||||
Downloaded int64 `json:"downloaded"`
|
||||
DownloadedSession int64 `json:"downloaded_session"`
|
||||
Eta int64 `json:"eta"`
|
||||
FLPiecePrio bool `json:"f_l_piece_prio"`
|
||||
ForceStart bool `json:"force_start"`
|
||||
Hash string `json:"hash"`
|
||||
LastActivity int64 `json:"last_activity"`
|
||||
MagnetURI string `json:"magnet_uri"`
|
||||
MaxRatio float64 `json:"max_ratio"`
|
||||
MaxSeedingTime int64 `json:"max_seeding_time"`
|
||||
Name string `json:"name"`
|
||||
NumComplete int64 `json:"num_complete"`
|
||||
NumIncomplete int64 `json:"num_incomplete"`
|
||||
NumLeechs int64 `json:"num_leechs"`
|
||||
NumSeeds int64 `json:"num_seeds"`
|
||||
Priority int64 `json:"priority"`
|
||||
Progress int64 `json:"progress"`
|
||||
Ratio float64 `json:"ratio"`
|
||||
RatioLimit int64 `json:"ratio_limit"`
|
||||
SavePath string `json:"save_path"`
|
||||
SeedingTimeLimit int64 `json:"seeding_time_limit"`
|
||||
SeenComplete int64 `json:"seen_complete"`
|
||||
SeqDl bool `json:"seq_dl"`
|
||||
Size int64 `json:"size"`
|
||||
State string `json:"state"`
|
||||
SuperSeeding bool `json:"super_seeding"`
|
||||
Tags string `json:"tags"`
|
||||
TimeActive int64 `json:"time_active"`
|
||||
TotalSize int64 `json:"total_size"`
|
||||
Tracker string `json:"tracker"`
|
||||
TrackersCount int64 `json:"trackers_count"`
|
||||
UpLimit int64 `json:"up_limit"`
|
||||
Uploaded int64 `json:"uploaded"`
|
||||
UploadedSession int64 `json:"uploaded_session"`
|
||||
Upspeed int64 `json:"upspeed"`
|
||||
}
|
||||
|
||||
//Tracker holds a tracker object from qbittorrent
|
||||
type Tracker struct {
|
||||
Msg string `json:"msg"`
|
||||
NumPeers int `json:"num_peers"`
|
||||
NumSeeds int `json:"num_seeds"`
|
||||
NumLeeches int `json:"num_leeches"`
|
||||
NumDownloaded int `json:"num_downloaded"`
|
||||
Tier int `json:"tier"`
|
||||
Status int `json:"status"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
//WebSeed holds a webseed object from qbittorrent
|
||||
type WebSeed struct {
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
//TorrentFile holds a torrent file object from qbittorrent
|
||||
type TorrentFile struct {
|
||||
Index int `json:"index"`
|
||||
IsSeed bool `json:"is_seed"`
|
||||
Name string `json:"name"`
|
||||
Availability float32 `json:"availability"`
|
||||
Priority int `json:"priority"`
|
||||
Progress int `json:"progress"`
|
||||
Size int `json:"size"`
|
||||
PieceRange []int `json:"piece_range"`
|
||||
}
|
||||
|
||||
//Sync holds the sync response struct which contains
|
||||
//the server state and a map of infohashes to Torrents
|
||||
type Sync struct {
|
||||
Categories []string `json:"categories"`
|
||||
FullUpdate bool `json:"full_update"`
|
||||
Rid int `json:"rid"`
|
||||
ServerState struct {
|
||||
ConnectionStatus string `json:"connection_status"`
|
||||
DhtNodes int `json:"dht_nodes"`
|
||||
DlInfoData int `json:"dl_info_data"`
|
||||
DlInfoSpeed int `json:"dl_info_speed"`
|
||||
DlRateLimit int `json:"dl_rate_limit"`
|
||||
Queueing bool `json:"queueing"`
|
||||
RefreshInterval int `json:"refresh_interval"`
|
||||
UpInfoData int `json:"up_info_data"`
|
||||
UpInfoSpeed int `json:"up_info_speed"`
|
||||
UpRateLimit int `json:"up_rate_limit"`
|
||||
UseAltSpeedLimits bool `json:"use_alt_speed_limits"`
|
||||
} `json:"server_state"`
|
||||
Torrents map[string]Torrent `json:"torrents"`
|
||||
}
|
||||
|
||||
type BuildInfo struct {
|
||||
QTVersion string `json:"qt"`
|
||||
LibtorrentVersion string `json:"libtorrent"`
|
||||
BoostVersion string `json:"boost"`
|
||||
OpenSSLVersion string `json:"openssl"`
|
||||
AppBitness string `json:"bitness"`
|
||||
}
|
||||
|
||||
type Preferences struct {
|
||||
Locale string `json:"locale"`
|
||||
CreateSubfolderEnabled bool `json:"create_subfolder_enabled"`
|
||||
StartPausedEnabled bool `json:"start_paused_enabled"`
|
||||
AutoDeleteMode int `json:"auto_delete_mode"`
|
||||
PreallocateAll bool `json:"preallocate_all"`
|
||||
IncompleteFilesExt bool `json:"incomplete_files_ext"`
|
||||
AutoTMMEnabled bool `json:"auto_tmm_enabled"`
|
||||
TorrentChangedTMMEnabled bool `json:"torrent_changed_tmm_enabled"`
|
||||
SavePathChangedTMMEnabled bool `json:"save_path_changed_tmm_enabled"`
|
||||
CategoryChangedTMMEnabled bool `json:"category_changed_tmm_enabled"`
|
||||
SavePath string `json:"save_path"`
|
||||
TempPathEnabled bool `json:"temp_path_enabled"`
|
||||
TempPath string `json:"temp_path"`
|
||||
ScanDirs map[string]interface{} `json:"scan_dirs"`
|
||||
ExportDir string `json:"export_dir"`
|
||||
ExportDirFin string `json:"export_dir_fin"`
|
||||
MailNotificationEnabled string `json:"mail_notification_enabled"`
|
||||
MailNotificationSender string `json:"mail_notification_sender"`
|
||||
MailNotificationEmail string `json:"mail_notification_email"`
|
||||
MailNotificationSMPTP string `json:"mail_notification_smtp"`
|
||||
MailNotificationSSLEnabled bool `json:"mail_notification_ssl_enabled"`
|
||||
MailNotificationAuthEnabled bool `json:"mail_notification_auth_enabled"`
|
||||
MailNotificationUsername string `json:"mail_notification_username"`
|
||||
MailNotificationPassword string `json:"mail_notification_password"`
|
||||
AutorunEnabled bool `json:"autorun_enabled"`
|
||||
AutorunProgram string `json:"autorun_program"`
|
||||
QueueingEnabled bool `json:"queueing_enabled"`
|
||||
MaxActiveDls int `json:"max_active_downloads"`
|
||||
MaxActiveTorrents int `json:"max_active_torrents"`
|
||||
MaxActiveUls int `json:"max_active_uploads"`
|
||||
DontCountSlowTorrents bool `json:"dont_count_slow_torrents"`
|
||||
SlowTorrentDlRateThreshold int `json:"slow_torrent_dl_rate_threshold"`
|
||||
SlowTorrentUlRateThreshold int `json:"slow_torrent_ul_rate_threshold"`
|
||||
SlowTorrentInactiveTimer int `json:"slow_torrent_inactive_timer"`
|
||||
MaxRatioEnabled bool `json:"max_ratio_enabled"`
|
||||
MaxRatio float64 `json:"max_ratio"`
|
||||
MaxRatioAct bool `json:"max_ratio_act"`
|
||||
ListenPort int `json:"listen_port"`
|
||||
UPNP bool `json:"upnp"`
|
||||
RandomPort bool `json:"random_port"`
|
||||
DlLimit int `json:"dl_limit"`
|
||||
UlLimit int `json:"up_limit"`
|
||||
MaxConnections int `json:"max_connec"`
|
||||
MaxConnectionsPerTorrent int `json:"max_connec_per_torrent"`
|
||||
MaxUls int `json:"max_uploads"`
|
||||
MaxUlsPerTorrent int `json:"max_uploads_per_torrent"`
|
||||
UTPEnabled bool `json:"enable_utp"`
|
||||
LimitUTPRate bool `json:"limit_utp_rate"`
|
||||
LimitTCPOverhead bool `json:"limit_tcp_overhead"`
|
||||
LimitLANPeers bool `json:"limit_lan_peers"`
|
||||
AltDlLimit int `json:"alt_dl_limit"`
|
||||
AltUlLimit int `json:"alt_up_limit"`
|
||||
SchedulerEnabled bool `json:"scheduler_enabled"`
|
||||
ScheduleFromHour int `json:"schedule_from_hour"`
|
||||
ScheduleFromMin int `json:"schedule_from_min"`
|
||||
ScheduleToHour int `json:"schedule_to_hour"`
|
||||
ScheduleToMin int `json:"schedule_to_min"`
|
||||
SchedulerDays int `json:"scheduler_days"`
|
||||
DHTEnabled bool `json:"dht"`
|
||||
DHTSameAsBT bool `json:"dhtSameAsBT"`
|
||||
DHTPort int `json:"dht_port"`
|
||||
PexEnabled bool `json:"pex"`
|
||||
LSDEnabled bool `json:"lsd"`
|
||||
Encryption int `json:"encryption"`
|
||||
AnonymousMode bool `json:"anonymous_mode"`
|
||||
ProxyType int `json:"proxy_type"`
|
||||
ProxyIP string `json:"proxy_ip"`
|
||||
ProxyPort int `json:"proxy_port"`
|
||||
ProxyPeerConnections bool `json:"proxy_peer_connections"`
|
||||
ForceProxy bool `json:"force_proxy"`
|
||||
ProxyAuthEnabled bool `json:"proxy_auth_enabled"`
|
||||
ProxyUsername string `json:"proxy_username"`
|
||||
ProxyPassword string `json:"proxy_password"`
|
||||
IPFilterEnabled bool `json:"ip_filter_enabled"`
|
||||
IPFilterPath string `json:"ip_filter_path"`
|
||||
IPFilterTrackers string `json:"ip_filter_trackers"`
|
||||
WebUIDomainList string `json:"web_ui_domain_list"`
|
||||
WebUIAddress string `json:"web_ui_address"`
|
||||
WebUIPort int `json:"web_ui_port"`
|
||||
WebUIUPNPEnabled bool `json:"web_ui_upnp"`
|
||||
WebUIUsername string `json:"web_ui_username"`
|
||||
WebUIPassword string `json:"web_ui_password"`
|
||||
WebUICSRFProtectionEnabled bool `json:"web_ui_csrf_protection_enabled"`
|
||||
WebUIClickjackingProtectionEnabled bool `json:"web_ui_clickjacking_protection_enabled"`
|
||||
BypassLocalAuth bool `json:"bypass_local_auth"`
|
||||
BypassAuthSubnetWhitelistEnabled bool `json:"bypass_auth_subnet_whitelist_enabled"`
|
||||
BypassAuthSubnetWhitelist string `json:"bypass_auth_subnet_whitelist"`
|
||||
AltWebUIEnabled bool `json:"alternative_webui_enabled"`
|
||||
AltWebUIPath string `json:"alternative_webui_path"`
|
||||
UseHTTPS bool `json:"use_https"`
|
||||
SSLKey string `json:"ssl_key"`
|
||||
SSLCert string `json:"ssl_cert"`
|
||||
DynDNSEnabled bool `json:"dyndns_enabled"`
|
||||
DynDNSService int `json:"dyndns_service"`
|
||||
DynDNSUsername string `json:"dyndns_username"`
|
||||
DynDNSPassword string `json:"dyndns_password"`
|
||||
DynDNSDomain string `json:"dyndns_domain"`
|
||||
RSSRefreshInterval int `json:"rss_refresh_interval"`
|
||||
RSSMaxArtPerFeed int `json:"rss_max_articles_per_feed"`
|
||||
RSSProcessingEnabled bool `json:"rss_processing_enabled"`
|
||||
RSSAutoDlEnabled bool `json:"rss_auto_downloading_enabled"`
|
||||
}
|
||||
|
||||
//Log
|
||||
type Log struct {
|
||||
ID int `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Timestamp int `json:"timestamp"`
|
||||
Type int `json:"type"`
|
||||
}
|
||||
|
||||
//PeerLog
|
||||
type PeerLog struct {
|
||||
ID int `json:"id"`
|
||||
IP string `json:"ip"`
|
||||
Blocked bool `json:"blocked"`
|
||||
Timestamp int `json:"timestamp"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
//Info
|
||||
type Info struct {
|
||||
ConnectionStatus string `json:"connection_status"`
|
||||
DHTNodes int `json:"dht_nodes"`
|
||||
DlInfoData int `json:"dl_info_data"`
|
||||
DlInfoSpeed int `json:"dl_info_speed"`
|
||||
DlRateLimit int `json:"dl_rate_limit"`
|
||||
UlInfoData int `json:"up_info_data"`
|
||||
UlInfoSpeed int `json:"up_info_speed"`
|
||||
UlRateLimit int `json:"up_rate_limit"`
|
||||
Queueing bool `json:"queueing"`
|
||||
UseAltSpeedLimits bool `json:"use_alt_speed_limits"`
|
||||
RefreshInterval int `json:"refresh_interval"`
|
||||
}
|
||||
|
||||
type TorrentsOptions struct {
|
||||
Filter *string // all, downloading, completed, paused, active, inactive => optional
|
||||
Category *string // => optional
|
||||
Sort *string // => optional
|
||||
Reverse *bool // => optional
|
||||
Limit *int // => optional (no negatives)
|
||||
Offset *int // => optional (negatives allowed)
|
||||
Hashes []string // separated by | => optional
|
||||
}
|
||||
|
||||
//Category of torrent
|
||||
type Category struct {
|
||||
Name string `json:"name"`
|
||||
SavePath string `json:"savePath"`
|
||||
}
|
||||
|
||||
//Categories mapping
|
||||
type Categories struct {
|
||||
Category map[string]Category
|
||||
}
|
||||
|
||||
//LoginOptions contains all options for /login endpoint
|
||||
type LoginOptions struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
//AddTrackersOptions contains all options for /addTrackers endpoint
|
||||
type AddTrackersOptions struct {
|
||||
Hash string
|
||||
Trackers []string
|
||||
}
|
||||
|
||||
//EditTrackerOptions contains all options for /editTracker endpoint
|
||||
type EditTrackerOptions struct {
|
||||
Hash string
|
||||
OrigURL string
|
||||
NewURL string
|
||||
}
|
||||
|
||||
//RemoveTrackersOptions contains all options for /removeTrackers endpoint
|
||||
type RemoveTrackersOptions struct {
|
||||
Hash string
|
||||
Trackers []string
|
||||
}
|
||||
|
||||
type DownloadOptions struct {
|
||||
Savepath *string
|
||||
Cookie *string
|
||||
Category *string
|
||||
SkipHashChecking *bool
|
||||
Paused *bool
|
||||
RootFolder *bool
|
||||
Rename *string
|
||||
UploadSpeedLimit *int
|
||||
DownloadSpeedLimit *int
|
||||
SequentialDownload *bool
|
||||
AutomaticTorrentManagement *bool
|
||||
FirstLastPiecePriority *bool
|
||||
}
|
||||
|
||||
type InfoOptions struct {
|
||||
Filter *string
|
||||
Category *string
|
||||
Sort *string
|
||||
Reverse *bool
|
||||
Limit *int
|
||||
Offset *int
|
||||
Hashes []string
|
||||
}
|
||||
|
||||
type PriorityValues int
|
||||
|
||||
const (
|
||||
Do_not_download PriorityValues = 0
|
||||
Normal_priority PriorityValues = 1
|
||||
High_priority PriorityValues = 6
|
||||
Maximal_priority PriorityValues = 7
|
||||
)
|
||||
24
pkg/go-qbittorrent/tools/tools.go
Normal file
24
pkg/go-qbittorrent/tools/tools.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package tools
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
)
|
||||
|
||||
// PrintResponse prints the body of a response
|
||||
func PrintResponse(body io.ReadCloser) {
|
||||
r, _ := io.ReadAll(body)
|
||||
fmt.Println("response: " + string(r))
|
||||
}
|
||||
|
||||
// PrintRequest prints a request
|
||||
func PrintRequest(req *http.Request) error {
|
||||
r, err := httputil.DumpRequest(req, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("request: " + string(r))
|
||||
return nil
|
||||
}
|
||||
133
pkg/qbittorrent/qbittorrent.go
Normal file
133
pkg/qbittorrent/qbittorrent.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package qbittorrent
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"polaris/pkg"
|
||||
"polaris/pkg/go-qbittorrent/qbt"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
c *qbt.Client
|
||||
}
|
||||
|
||||
func (c *Client) Download(link, dir string) (pkg.Torrent, error) {
|
||||
all, err := c.c.Torrents(qbt.TorrentsOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get old torrents")
|
||||
}
|
||||
allHash := make(map[string]bool, len(all))
|
||||
for _, t := range all {
|
||||
allHash[t.Hash] = true
|
||||
}
|
||||
err = c.c.DownloadLinks([]string{link}, qbt.DownloadOptions{Savepath: &dir})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "qbt download")
|
||||
}
|
||||
var newHash string
|
||||
|
||||
loop:
|
||||
for i := 0; i < 10; i++ {
|
||||
time.Sleep(1 * time.Second)
|
||||
all, err = c.c.Torrents(qbt.TorrentsOptions{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "get new torrents")
|
||||
}
|
||||
|
||||
for _, t := range all {
|
||||
if !allHash[t.Hash] {
|
||||
newHash = t.Hash
|
||||
break loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if newHash == "" {
|
||||
return nil, fmt.Errorf("download torrent fail: timeout")
|
||||
}
|
||||
return &Torrent{Hash: newHash, c: c.c}, nil
|
||||
|
||||
}
|
||||
|
||||
type Torrent struct {
|
||||
c *qbt.Client
|
||||
Hash string
|
||||
URL string
|
||||
User string
|
||||
Password string
|
||||
}
|
||||
|
||||
func (t *Torrent) getTorrent() (*qbt.TorrentInfo, error) {
|
||||
all, err := t.c.Torrents(qbt.TorrentsOptions{Hashes: []string{t.Hash}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(all) == 0 {
|
||||
return nil, fmt.Errorf("no such torrent: %v", t.Hash)
|
||||
}
|
||||
return &all[0], nil
|
||||
}
|
||||
|
||||
func (t *Torrent) Name() (string, error) {
|
||||
qb, err := t.getTorrent()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return qb.Name, nil
|
||||
}
|
||||
|
||||
func (t *Torrent) Progress() (int, error) {
|
||||
qb, err := t.getTorrent()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return int(qb.Progress), nil
|
||||
}
|
||||
|
||||
func (t *Torrent) Stop() error {
|
||||
return t.c.Pause([]string{t.Hash})
|
||||
}
|
||||
|
||||
func (t *Torrent) Start() error {
|
||||
ok, err := t.c.Resume([]string{t.Hash})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("status not 200")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Torrent) Remove() error {
|
||||
ok, err := t.c.Delete([]string{t.Hash}, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !ok {
|
||||
return fmt.Errorf("status not 200")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Torrent) Save() string {
|
||||
data, _ := json.Marshal(t)
|
||||
return string(data)
|
||||
}
|
||||
|
||||
func (t *Torrent) Exists() bool {
|
||||
_, err := t.getTorrent()
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func (t *Torrent) SeedRatio() (float64, error) {
|
||||
qb, err := t.getTorrent()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return qb.Ratio, nil
|
||||
}
|
||||
1
pkg/thirdparty/doc.go
vendored
Normal file
1
pkg/thirdparty/doc.go
vendored
Normal file
@@ -0,0 +1 @@
|
||||
package thirdparty
|
||||
Reference in New Issue
Block a user