Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jobs:
strategy:
matrix:
include:
- os: ubuntu-20.04
- os: ubuntu-latest
- os: windows-2022
runs-on: ${{ matrix.os }}
steps:
Expand Down
65 changes: 63 additions & 2 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (
"net/http"
"os"

"github.com/cenkalti/rpc2"
"github.com/cenkalti/rpc2/jsonrpc"
"github.com/gorilla/websocket"
"github.com/nubuki-all/rpc2"
"github.com/siku2/arigo/internal/pkg/jsonrpc"
"github.com/siku2/arigo/internal/pkg/wsrpc"
"github.com/siku2/arigo/pkg/aria2proto"
)
Expand Down Expand Up @@ -109,22 +109,27 @@ func (c *Client) onDownloadStart(_ *rpc2.Client, event *DownloadEvent, _ *interf
c.evtTarget.Dispatch(StartEvent, event)
return nil
}

func (c *Client) onDownloadPause(_ *rpc2.Client, event *DownloadEvent, _ *interface{}) error {
c.evtTarget.Dispatch(PauseEvent, event)
return nil
}

func (c *Client) onDownloadStop(_ *rpc2.Client, event *DownloadEvent, _ *interface{}) error {
c.evtTarget.Dispatch(StopEvent, event)
return nil
}

func (c *Client) onDownloadComplete(_ *rpc2.Client, event *DownloadEvent, _ *interface{}) error {
c.evtTarget.Dispatch(CompleteEvent, event)
return nil
}

func (c *Client) onDownloadError(_ *rpc2.Client, event *DownloadEvent, _ *interface{}) error {
c.evtTarget.Dispatch(ErrorEvent, event)
return nil
}

func (c *Client) onBTDownloadComplete(_ *rpc2.Client, event *DownloadEvent, _ *interface{}) error {
c.evtTarget.Dispatch(BTCompleteEvent, event)
return nil
Expand Down Expand Up @@ -196,6 +201,52 @@ func (c *Client) DownloadWithContext(ctx context.Context, uris []string, options
return
}

// GetDownloads retrieves a list of statuses for the given gids
// if no gid is given, return all active downloads and a thousand (1000)
// of each of most recent waiting and stopped downloads.
func (c *Client) GetDownloads(gids ...string) []Status {
var statuses []Status
if len(gids) != 0 {
for _, gid := range gids {
s, _ := c.TellStatus(gid)
statuses = append(statuses, s)
}
} else {
s, _ := c.TellActive()
statuses = append(statuses, s...)
s, _ = c.TellWaiting(0, 1000)
statuses = append(statuses, s...)
s, _ = c.TellStopped(0, 1000)
statuses = append(statuses, s...)
}
return statuses
}

// DeleteDownloads removes the downloads denoted by status and deletes all corresponding files.
// This is not an aria2 method.
func (c *Client) DeleteDownloads(statuses []Status, force, files, clean bool) {
for _, status := range statuses {
switch status.Status {
case StatusCompleted, StatusRemoved, StatusError:
_ = c.RemoveDownloadResult(status.GID)
default:
if force {
_ = c.ForceRemove(status.GID)
} else {
_ = c.Remove(status.GID)
}
_ = c.RemoveDownloadResult(status.GID)
}
if files {
RemoveFiles(status.Files)
removeRootDir(status)
}
if clean {
_ = DeleteControlFile(status)
}
}
}

// Delete removes the download denoted by gid and deletes all corresponding files.
// This is not an aria2 method.
func (c *Client) Delete(gid string) (err error) {
Expand Down Expand Up @@ -471,6 +522,10 @@ func (c *Client) GetServers(gid string) ([]FileServers, error) {
// keys does the same as in the TellStatus() method.
func (c *Client) TellActive(keys ...string) ([]Status, error) {
var reply []Status

if len(keys) == 0 {
keys = make([]string, 0)
}
err := c.rpcClient.Call(aria2proto.TellActive, c.getArgs(keys), &reply)

return reply, err
Expand All @@ -488,6 +543,9 @@ func (c *Client) TellActive(keys ...string) ([]Status, error) {
// If specified, the returned Statuses only contain the keys passed to the method.
func (c *Client) TellWaiting(offset int, num uint, keys ...string) ([]Status, error) {
var reply []Status
if len(keys) == 0 {
keys = make([]string, 0)
}
err := c.rpcClient.Call(aria2proto.TellWaiting, c.getArgs(offset, num, keys), &reply)

return reply, err
Expand All @@ -505,6 +563,9 @@ func (c *Client) TellWaiting(offset int, num uint, keys ...string) ([]Status, er
// If specified, the returned Statuses only contain the keys passed to the method.
func (c *Client) TellStopped(offset int, num uint, keys ...string) ([]Status, error) {
var reply []Status
if len(keys) == 0 {
keys = make([]string, 0)
}
err := c.rpcClient.Call(aria2proto.TellStopped, c.getArgs(offset, num, keys), &reply)

return reply, err
Expand Down
112 changes: 112 additions & 0 deletions errors/exitstatus.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package errors

//go:generate stringer -type=ExitStatus

// ExitStatus is an integer returned by aria2 for downloads which describes why a download exited.
// Please see https://aria2.github.io/manual/en/html/aria2c.html#exit-status
type ExitStatus uint8

const (
// Success indicates that all downloads were successful.
Success ExitStatus = iota

// UnknownError indicates that an unknown error occurred.
UnknownError

// Timeout indicates that a timeout occurred.
Timeout

// ResourceNotFound indicates that a resource was not found.
ResourceNotFound

// ResourceNotFoundReached indicates that aria2 saw the specified number of “resource not found” error.
// See the --max-file-not-found option.
ResourceNotFoundReached

// DownloadSpeedTooSlow indicates that a download aborted because download speed was too slow.
// See --lowest-speed-limit option.
DownloadSpeedTooSlow

// NetworkError indicates that a network problem occurred.
NetworkError

// UnfinishedDownloads indicates that there were unfinished downloads.
// This error is only reported if all finished downloads were successful and there were unfinished
// downloads in a queue when aria2 exited by pressing Ctrl-C by an user or sending TERM or INT signal.
UnfinishedDownloads

// RemoteNoResume indicates that the remote server did not support resume when resume was required to complete download.
RemoteNoResume

// NotEnoughDiskSpace indicates that there was not enough disk space available.
NotEnoughDiskSpace

// PieceLengthMismatch indicates that the piece length was different from one in .aria2 control file.
// See --allow-piece-length-change option.
PieceLengthMismatch

// SameFileBeingDownloaded indicates that aria2 was downloading same file at that moment.
SameFileBeingDownloaded

// SameInfoHashBeingDownloaded indicates that aria2 was downloading same info hash torrent at that moment.
SameInfoHashBeingDownloaded

// FileAlreadyExists indicates that the file already existed. See --allow-overwrite option.
FileAlreadyExists

//RenamingFailed indicates that renaming the file failed. See --auto-file-renaming option.
RenamingFailed

// CouldNotOpenExistingFile indicates that aria2 could not open existing file.
CouldNotOpenExistingFile

// CouldNotCreateNewFile indicates that aria2 could not create new file or truncate existing file.
CouldNotCreateNewFile

// FileIOError indicates that a file I/O error occurred.
FileIOError

// CouldNotCreateDirectory indicates that aria2 could not create directory.
CouldNotCreateDirectory

// NameResolutionFailed indicates that the name resolution failed.
NameResolutionFailed

// MetalinkParsingFailed indicates that aria2 could not parse Metalink document.
MetalinkParsingFailed

// FTPCommandFailed indicates that the FTP command failed.
FTPCommandFailed

// HTTPResponseHeaderBad indicates that the HTTP response header was bad or unexpected.
HTTPResponseHeaderBad

// TooManyRedirects indicates that too many redirects occurred.
TooManyRedirects

// HTTPAuthorizationFailed indicates that HTTP authorization failed.
HTTPAuthorizationFailed

// BencodedFileParseError indicates that aria2 could not parse bencoded file (usually “.torrent” file).
BencodedFileParseError

// TorrentFileCorrupt indicates that the “.torrent” file was corrupted or missing information that aria2 needed.
TorrentFileCorrupt

// MagnetURIBad indicates that the magnet URI was bad.
MagnetURIBad

// RemoteServerHandleRequestError indicates that the remote server was unable to handle the request due to a
// temporary overloading or maintenance.
RemoteServerHandleRequestError

// JSONRPCParseError indicates that aria2 could not parse JSON-RPC request.
JSONRPCParseError

// Reserved is a reserved value. If you get this exit status then the library is probably out-of-date,
// or the universe is breaking down.
Reserved

// ChecksumValidationFailed indicates that the checksum validation failed.
ChecksumValidationFailed
)
2 changes: 1 addition & 1 deletion exitstatus_string.go → errors/exitstatus_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions errors/json.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package errors

import "fmt"

type JSONRPCError struct {
Code ExitStatus `json:"code"` // error code
Message string `json:"message"` // The human readable error message associated to Code
}

func (e *JSONRPCError) Error() string {
return fmt.Sprintf("code=%d, message=%s", e.Code, e.Message)
}

Loading