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.
downkyi/DownKyi.Core/Aria2cNet/Client/AriaClient.cs

1160 lines
46 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using DownKyi.Core.Aria2cNet.Client.Entity;
using DownKyi.Core.Logging;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace DownKyi.Core.Aria2cNet.Client
{
/// <summary>
/// http://aria2.github.io/manual/en/html/aria2c.html#methods
/// </summary>
public static class AriaClient
{
private static readonly string JSONRPC = "2.0";
private const string LOCAL_HOST = "http://localhost";
private const string TOKEN = "downkyi";
private const int LISTEN_PORT = 6800;
private static string host = LOCAL_HOST;
private static string token = TOKEN;
private static int listenPort = LISTEN_PORT;
/// <summary>
/// This method adds a new download.
/// uris is an array of HTTP/FTP/SFTP/BitTorrent URIs (strings) pointing to the same resource.
/// If you mix URIs pointing to different resources,
/// then the download may fail or be corrupted without aria2 complaining.
/// When adding BitTorrent Magnet URIs,
/// uris must have only one element and it should be BitTorrent Magnet URI.
/// options is a struct and its members are pairs of option name and value.
/// See Options below for more details.
/// If position is given, it must be an integer starting from 0.
/// The new download will be inserted at position in the waiting queue.
/// If position is omitted or position is larger than the current size of the queue,
/// the new download is appended to the end of the queue.
/// This method returns the GID of the newly registered download.
/// </summary>
/// <param name="uris"></param>
/// <param name="dir"></param>
/// <param name="outFile"></param>
/// <returns></returns>
public static async Task<AriaAddUri> AddUriAsync(List<string> uris, AriaSendOption option, int position = -1)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
uris,
option
};
if (position > -1)
{
ariaParams.Add(position);
}
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.addUri",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaAddUri>(ariaSend);
}
/// <summary>
/// This method adds a BitTorrent download by uploading a ".torrent" file.
/// If you want to add a BitTorrent Magnet URI, use the aria2.addUri() method instead.
/// torrent must be a base64-encoded string containing the contents of the ".torrent" file.
/// uris is an array of URIs (string).
/// uris is used for Web-seeding.
/// For single file torrents, the URI can be a complete URI pointing to the resource;
/// if URI ends with /, name in torrent file is added.
/// For multi-file torrents, name and path in torrent are added to form a URI for each file.
/// options is a struct and its members are pairs of option name and value.
/// See Options below for more details.
/// If position is given, it must be an integer starting from 0.
/// The new download will be inserted at position in the waiting queue.
/// If position is omitted or position is larger than the current size of the queue,
/// the new download is appended to the end of the queue.
/// This method returns the GID of the newly registered download.
/// If --rpc-save-upload-metadata is true,
/// the uploaded data is saved as a file named as the hex string of SHA-1 hash of data plus ".torrent" in the directory specified by --dir option.
/// E.g. a file name might be 0a3893293e27ac0490424c06de4d09242215f0a6.torrent.
/// If a file with the same name already exists, it is overwritten!
/// If the file cannot be saved successfully or --rpc-save-upload-metadata is false,
/// the downloads added by this method are not saved by --save-session.
/// </summary>
/// <param name="torrent"></param>
/// <param name="uris"></param>
/// <param name="option"></param>
/// <returns></returns>
public static async Task<AriaAddTorrent> AddTorrentAsync(string torrent, List<string> uris, AriaSendOption option, int position = -1)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
torrent,
uris,
option
};
if (position > -1)
{
ariaParams.Add(position);
}
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.addTorrent",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaAddTorrent>(ariaSend);
}
/// <summary>
/// This method adds a Metalink download by uploading a ".metalink" file.
/// metalink is a base64-encoded string which contains the contents of the ".metalink" file.
/// options is a struct and its members are pairs of option name and value.
/// See Options below for more details.
/// If position is given, it must be an integer starting from 0.
/// The new download will be inserted at position in the waiting queue.
/// If position is omitted or position is larger than the current size of the queue,
/// the new download is appended to the end of the queue.
/// This method returns an array of GIDs of newly registered downloads.
/// If --rpc-save-upload-metadata is true,
/// the uploaded data is saved as a file named hex string of SHA-1 hash of data plus ".metalink" in the directory specified by --dir option.
/// E.g. a file name might be 0a3893293e27ac0490424c06de4d09242215f0a6.metalink.
/// If a file with the same name already exists, it is overwritten!
/// If the file cannot be saved successfully or --rpc-save-upload-metadata is false,
/// the downloads added by this method are not saved by --save-session.
/// </summary>
/// <param name="metalink"></param>
/// <param name="uris"></param>
/// <param name="option"></param>
/// <returns></returns>
public static async Task<AriaAddMetalink> AddMetalinkAsync(string metalink, List<string> uris, AriaSendOption option, int position = -1)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
metalink,
uris,
option
};
if (position > -1)
{
ariaParams.Add(position);
}
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.addMetalink",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaAddMetalink>(ariaSend);
}
/// <summary>
/// This method removes the download denoted by gid (string).
/// If the specified download is in progress, it is first stopped.
/// The status of the removed download becomes removed.
/// This method returns GID of removed download.
/// </summary>
/// <param name="gid"></param>
/// <returns></returns>
public static async Task<AriaRemove> RemoveAsync(string gid)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.remove",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaRemove>(ariaSend);
}
/// <summary>
/// This method removes the download denoted by gid.
/// This method behaves just like aria2.remove()
/// except that this method removes the download without performing any actions which take time,
/// such as contacting BitTorrent trackers to unregister the download first.
/// </summary>
/// <param name="gid"></param>
/// <returns></returns>
public static async Task<AriaRemove> ForceRemoveAsync(string gid)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.forceRemove",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaRemove>(ariaSend);
}
/// <summary>
/// This method pauses the download denoted by gid (string).
/// The status of paused download becomes paused.
/// If the download was active, the download is placed in the front of waiting queue.
/// While the status is paused, the download is not started.
/// To change status to waiting, use the aria2.unpause() method.
/// This method returns GID of paused download.
/// </summary>
/// <param name="gid"></param>
/// <returns></returns>
public static async Task<AriaPause> PauseAsync(string gid)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.pause",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaPause>(ariaSend);
}
/// <summary>
/// This method is equal to calling aria2.pause() for every active/waiting download.
/// This methods returns OK.
/// </summary>
/// <returns></returns>
public static async Task<AriaPause> PauseAllAsync()
{
List<object> ariaParams = new List<object>
{
"token:" + token,
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.pauseAll",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaPause>(ariaSend);
}
/// <summary>
/// This method pauses the download denoted by gid.
/// This method behaves just like aria2.pause()
/// except that this method pauses downloads without performing any actions which take time,
/// such as contacting BitTorrent trackers to unregister the download first.
/// </summary>
/// <param name="gid"></param>
/// <returns></returns>
public static async Task<AriaPause> ForcePauseAsync(string gid)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.forcePause",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaPause>(ariaSend);
}
/// <summary>
/// This method is equal to calling aria2.forcePause() for every active/waiting download.
/// This methods returns OK.
/// </summary>
/// <returns></returns>
public static async Task<AriaPause> ForcePauseAllAsync()
{
List<object> ariaParams = new List<object>
{
"token:" + token,
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.forcePauseAll",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaPause>(ariaSend);
}
/// <summary>
/// This method changes the status of the download denoted by gid (string) from paused to waiting,
/// making the download eligible to be restarted.
/// This method returns the GID of the unpaused download.
/// </summary>
/// <param name="gid"></param>
/// <returns></returns>
public static async Task<AriaPause> UnpauseAsync(string gid)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.unpause",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaPause>(ariaSend);
}
/// <summary>
/// This method is equal to calling aria2.unpause() for every paused download.
/// This methods returns OK.
/// </summary>
/// <returns></returns>
public static async Task<AriaPause> UnpauseAllAsync()
{
List<object> ariaParams = new List<object>
{
"token:" + token,
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.unpauseAll",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaPause>(ariaSend);
}
/// <summary>
/// This method returns the progress of the download denoted by gid (string).
/// keys is an array of strings.
/// If specified, the response contains only keys in the keys array.
/// If keys is empty or omitted, the response contains all keys.
/// This is useful when you just want specific keys and avoid unnecessary transfers.
/// For example, aria2.tellStatus("2089b05ecca3d829", ["gid", "status"]) returns the gid and status keys only.
/// The response is a struct and contains following keys. Values are strings.
/// </summary>
/// <param name="gid"></param>
/// <returns></returns>
public static async Task<AriaTellStatus> TellStatus(string gid)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.tellStatus",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaTellStatus>(ariaSend);
}
/// <summary>
/// This method returns the URIs used in the download denoted by gid (string).
/// The response is an array of structs and it contains following keys.
/// Values are string.
/// </summary>
/// <param name="gid"></param>
/// <returns></returns>
public static async Task<AriaGetUris> GetUrisAsync(string gid)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.getUris",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaGetUris>(ariaSend);
}
/// <summary>
/// This method returns the file list of the download denoted by gid (string).
/// The response is an array of structs which contain following keys.
/// Values are strings.
/// </summary>
/// <param name="gid"></param>
/// <returns></returns>
public static async Task<AriaGetFiles> GetFilesAsync(string gid)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.getFiles",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaGetFiles>(ariaSend);
}
/// <summary>
/// This method returns a list peers of the download denoted by gid (string).
/// This method is for BitTorrent only.
/// The response is an array of structs and contains the following keys.
/// Values are strings.
/// </summary>
/// <param name="gid"></param>
/// <returns></returns>
public static async Task<AriaGetPeers> GetPeersAsync(string gid)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.getPeers",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaGetPeers>(ariaSend);
}
/// <summary>
/// This method returns currently connected HTTP(S)/FTP/SFTP servers of the download denoted by gid (string).
/// The response is an array of structs and contains the following keys.
/// Values are strings.
/// </summary>
/// <param name="gid"></param>
/// <returns></returns>
public static async Task<AriaGetServers> GetServersAsync(string gid)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.getServers",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaGetServers>(ariaSend);
}
/// <summary>
/// This method returns a list of active downloads.
/// The response is an array of the same structs as returned by the aria2.tellStatus() method.
/// For the keys parameter, please refer to the aria2.tellStatus() method.
/// </summary>
/// <returns></returns>
public static async Task<AriaTellStatusList> TellActiveAsync()
{
List<object> ariaParams = new List<object>
{
"token:" + token,
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.tellActive",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaTellStatusList>(ariaSend);
}
/// <summary>
/// This method returns a list of waiting downloads, including paused ones.
/// offset is an integer and specifies the offset from the download waiting at the front.
/// num is an integer and specifies the max.
/// number of downloads to be returned.
/// For the keys parameter, please refer to the aria2.tellStatus() method.
/// <br/><br/>
/// If offset is a positive integer,
/// this method returns downloads in the range of [offset, offset + num).
/// <br/><br/>
/// offset can be a negative integer.
/// offset == -1 points last download in the waiting queue and offset == -2 points the download before the last download, and so on.
/// Downloads in the response are in reversed order then.
/// <br/><br/>
/// For example, imagine three downloads "A","B" and "C" are waiting in this order.
/// aria2.tellWaiting(0, 1) returns ["A"].
/// aria2.tellWaiting(1, 2) returns ["B", "C"].
/// aria2.tellWaiting(-1, 2) returns ["C", "B"].
/// <br/><br/>
/// The response is an array of the same structs as returned by aria2.tellStatus() method.
/// </summary>
/// <param name="offset"></param>
/// <param name="num"></param>
/// <returns></returns>
public static async Task<AriaTellStatusList> TellWaitingAsync(int offset, int num)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
offset,
num
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.tellWaiting",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaTellStatusList>(ariaSend);
}
/// <summary>
/// This method returns a list of stopped downloads.
/// offset is an integer and specifies the offset from the least recently stopped download.
/// num is an integer and specifies the max.
/// number of downloads to be returned.
/// For the keys parameter, please refer to the aria2.tellStatus() method.
/// <br/><br/>
/// offset and num have the same semantics as described in the aria2.tellWaiting() method.
/// <br/><br/>
/// The response is an array of the same structs as returned by the aria2.tellStatus() method.
/// </summary>
/// <param name="offset"></param>
/// <param name="num"></param>
/// <returns></returns>
public static async Task<AriaTellStatusList> TellStoppedAsync(int offset, int num)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
offset,
num
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.tellStopped",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaTellStatusList>(ariaSend);
}
/// <summary>
/// This method changes the position of the download denoted by gid in the queue.
/// pos is an integer.
/// how is a string.
/// If how is POS_SET, it moves the download to a position relative to the beginning of the queue.
/// If how is POS_CUR, it moves the download to a position relative to the current position.
/// If how is POS_END, it moves the download to a position relative to the end of the queue.
/// If the destination position is less than 0 or beyond the end of the queue,
/// it moves the download to the beginning or the end of the queue respectively.
/// The response is an integer denoting the resulting position.
///
/// For example, if GID#2089b05ecca3d829 is currently in position 3,
/// aria2.changePosition('2089b05ecca3d829', -1, 'POS_CUR') will change its position to 2.
/// Additionally aria2.changePosition('2089b05ecca3d829', 0, 'POS_SET') will change its position to 0 (the beginning of the queue).
///
/// The following examples move the download GID#2089b05ecca3d829 to the front of the queue.
/// </summary>
/// <param name="gid"></param>
/// <param name="pos"></param>
/// <param name="how"></param>
/// <returns></returns>
public static async Task<AriaChangePosition> ChangePositionAsync(string gid, int pos, HowChangePosition how)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid,
pos,
how.ToString("G")
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.changePosition",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaChangePosition>(ariaSend);
}
/// <summary>
/// This method removes the URIs in delUris from and appends the URIs in addUris to download denoted by gid.
/// delUris and addUris are lists of strings.
/// A download can contain multiple files and URIs are attached to each file.
/// fileIndex is used to select which file to remove/attach given URIs.
/// fileIndex is 1-based.
/// position is used to specify where URIs are inserted in the existing waiting URI list.
/// position is 0-based.
/// When position is omitted, URIs are appended to the back of the list.
/// This method first executes the removal and then the addition.
/// position is the position after URIs are removed, not the position when this method is called.
/// When removing an URI, if the same URIs exist in download,
/// only one of them is removed for each URI in delUris.
/// In other words,
/// if there are three URIs http://example.org/aria2 and you want remove them all,
/// you have to specify (at least) 3 http://example.org/aria2 in delUris.
/// This method returns a list which contains two integers.
/// The first integer is the number of URIs deleted. The second integer is the number of URIs added.
/// </summary>
/// <param name="gid"></param>
/// <param name="fileIndex"></param>
/// <param name="delUris"></param>
/// <param name="addUris"></param>
/// <param name="position"></param>
/// <returns></returns>
public static async Task<AriaChangeUri> ChangeUriAsync(string gid, int fileIndex, List<string> delUris, List<string> addUris, int position = -1)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid,
fileIndex,
delUris,
addUris
};
if (position > -1)
{
ariaParams.Add(position);
}
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.changePosition",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaChangeUri>(ariaSend);
}
/// <summary>
/// This method returns options of the download denoted by gid.
/// The response is a struct where keys are the names of options.
/// The values are strings.
/// Note that this method does not return options which have no default value and have not been set on the command-line,
/// in configuration files or RPC methods.
/// </summary>
/// <param name="gid"></param>
/// <returns></returns>
public static async Task<AriaGetOption> GetOptionAsync(string gid)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.getOption",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaGetOption>(ariaSend);
}
/// <summary>
/// This method changes options of the download denoted by gid (string) dynamically.
/// options is a struct.
/// The options listed in Input File subsection are available, except for following options:
/// <br/>
/// dry-run metalink-base-uri parameterized-uri pause piece-length rpc-save-upload-metadata
/// <br/>
/// Except for the following options,
/// changing the other options of active download makes it restart
/// (restart itself is managed by aria2, and no user intervention is required):
/// <br/>
/// bt-max-peers bt-request-peer-speed-limit bt-remove-unselected-file force-save max-download-limit max-upload-limit
/// <br/>
/// This method returns OK for success.
/// </summary>
/// <param name="gid"></param>
/// <param name="option"></param>
/// <returns></returns>
public static async Task<AriaChangeOption> ChangeOptionAsync(string gid, object option)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid,
option
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.changeOption",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaChangeOption>(ariaSend);
}
/// <summary>
/// This method returns the global options.
/// The response is a struct.
/// Its keys are the names of options.
/// Values are strings.
/// Note that this method does not return options which have no default value and have not been set on the command-line,
/// in configuration files or RPC methods.
/// Because global options are used as a template for the options of newly added downloads,
/// the response contains keys returned by the aria2.getOption() method.
/// </summary>
/// <returns></returns>
public static async Task<AriaGetOption> GetGlobalOptionAsync()
{
List<object> ariaParams = new List<object>
{
"token:" + token,
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.getGlobalOption",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaGetOption>(ariaSend);
}
/// <summary>
/// This method changes global options dynamically.
/// options is a struct.
/// The following options are available:
/// <br/>
/// bt-max-open-files download-result keep-unfinished-download-result log log-level
/// max-concurrent-downloads max-download-result max-overall-download-limit max-overall-upload-limit
/// optimize-concurrent-downloads save-cookies save-session server-stat-of
/// <br/>
/// In addition, options listed in the Input File subsection are available,
/// except for following options: checksum, index-out, out, pause and select-file.
/// With the log option, you can dynamically start logging or change log file.
/// To stop logging, specify an empty string("") as the parameter value.
/// Note that log file is always opened in append mode.
/// This method returns OK for success.
/// </summary>
/// <param name="option"></param>
/// <returns></returns>
public static async Task<AriaChangeOption> ChangeGlobalOptionAsync(object option)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
option
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.changeGlobalOption",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaChangeOption>(ariaSend);
}
/// <summary>
/// This method returns global statistics such as the overall download and upload speeds.
/// The response is a struct and contains the following keys. Values are strings.
/// </summary>
/// <returns></returns>
public static async Task<AriaGetGlobalStat> GetGlobalStatAsync()
{
List<object> ariaParams = new List<object>
{
"token:" + token,
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.getGlobalStat",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaGetGlobalStat>(ariaSend);
}
/// <summary>
/// This method purges completed/error/removed downloads to free memory.
/// This method returns OK.
/// </summary>
/// <returns></returns>
public static async Task<AriaRemove> PurgeDownloadResultAsync()
{
List<object> ariaParams = new List<object>
{
"token:" + token,
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.purgeDownloadResult",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaRemove>(ariaSend);
}
/// <summary>
/// This method removes a completed/error/removed download denoted by gid from memory.
/// This method returns OK for success.
/// </summary>
/// <param name="gid"></param>
/// <returns></returns>
public static async Task<AriaRemove> RemoveDownloadResultAsync(string gid)
{
List<object> ariaParams = new List<object>
{
"token:" + token,
gid
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.removeDownloadResult",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaRemove>(ariaSend);
}
/// <summary>
/// This method returns the version of aria2 and the list of enabled features.
/// The response is a struct and contains following keys.
/// </summary>
/// <returns></returns>
public static async Task<AriaVersion> GetAriaVersionAsync()
{
List<object> ariaParams = new List<object>
{
"token:" + token,
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.getVersion",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaVersion>(ariaSend);
}
/// <summary>
/// This method returns session information.
/// The response is a struct and contains following key.
/// <br/><br/>
/// Session ID, which is generated each time when aria2 is invoked.
/// </summary>
/// <returns></returns>
public static async Task<AriaGetSessionInfo> GetSessionInfoAsync()
{
List<object> ariaParams = new List<object>
{
"token:" + token,
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.getSessionInfo",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaGetSessionInfo>(ariaSend);
}
/// <summary>
/// This method shuts down aria2.
/// This method returns OK.
/// </summary>
/// <returns></returns>
public static async Task<AriaShutdown> ShutdownAsync()
{
List<object> ariaParams = new List<object>
{
"token:" + token,
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.shutdown",
Params = ariaParams
};
var re = await GetRpcResponseAsync<AriaShutdown>(ariaSend);
return re;
}
/// <summary>
/// This method shuts down aria2().
/// This method behaves like :func:'aria2.shutdown` without performing any actions which take time,
/// such as contacting BitTorrent trackers to unregister downloads first.
/// This method returns OK.
/// </summary>
/// <returns></returns>
public static async Task<AriaShutdown> ForceShutdownAsync()
{
List<object> ariaParams = new List<object>
{
"token:" + token,
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.forceShutdown",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaShutdown>(ariaSend);
}
/// <summary>
/// This method saves the current session to a file specified by the --save-session option.
/// This method returns OK if it succeeds.
/// </summary>
/// <returns></returns>
public static async Task<AriaSaveSession> SaveSessionAsync()
{
List<object> ariaParams = new List<object>
{
"token:" + token,
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "aria2.saveSession",
Params = ariaParams
};
return await GetRpcResponseAsync<AriaSaveSession>(ariaSend);
}
/// <summary>
/// This methods encapsulates multiple method calls in a single request.
/// methods is an array of structs. The structs contain two keys: methodName and params.
/// methodName is the method name to call and params is array containing parameters to the method call.
/// This method returns an array of responses.
/// The elements will be either a one-item array containing the return value of the method call or a struct of fault element if an encapsulated method call fails.
/// </summary>
/// <param name="systemMulticallMathods"></param>
/// <returns></returns>
public static async Task<List<SystemMulticall>> MulticallAsync(List<SystemMulticallMathod> systemMulticallMathods)
{
List<object> ariaParams = new List<object>
{
systemMulticallMathods
};
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "system.multicall",
Params = ariaParams
};
return await GetRpcResponseAsync<List<SystemMulticall>>(ariaSend);
}
/// <summary>
/// This method returns all the available RPC methods in an array of string.
/// Unlike other methods, this method does not require secret token.
/// This is safe because this method just returns the available method names.
/// </summary>
/// <returns></returns>
public static async Task<SystemListMethods> ListMethodsAsync()
{
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "system.listMethods"
};
return await GetRpcResponseAsync<SystemListMethods>(ariaSend);
}
/// <summary>
/// This method returns all the available RPC notifications in an array of string.
/// Unlike other methods, this method does not require secret token.
/// This is safe because this method just returns the available notifications names.
/// </summary>
/// <returns></returns>
public static async Task<SystemListNotifications> ListNotificationsAsync()
{
AriaSendData ariaSend = new AriaSendData
{
Id = Guid.NewGuid().ToString("N"),
Jsonrpc = JSONRPC,
Method = "system.listNotifications"
};
return await GetRpcResponseAsync<SystemListNotifications>(ariaSend);
}
/// <summary>
/// 设置aria token
/// </summary>
/// <param name="token"></param>
public static void SetToken(string token = TOKEN)
{
AriaClient.token = token;
}
/// <summary>
/// 设置aria host
/// </summary>
/// <param name="host"></param>
public static void SetHost(string host = LOCAL_HOST)
{
AriaClient.host = host;
}
public static void SetListenPort(int listenPort = LISTEN_PORT)
{
AriaClient.listenPort = listenPort;
}
/// <summary>
/// 获取jsonrpc的地址
/// </summary>
/// <returns></returns>
private static string GetRpcUri()
{
return $"{host}:{AriaClient.listenPort}/jsonrpc";
}
/// <summary>
/// 发送http请求并将返回的json反序列化
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="ariaSend"></param>
/// <returns></returns>
private async static Task<T> GetRpcResponseAsync<T>(AriaSendData ariaSend)
{
// 去掉null
var jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore };
// 转换为json字符串
string sendJson = JsonConvert.SerializeObject(ariaSend, Formatting.Indented, jsonSetting);
// 向服务器请求数据
string result = string.Empty;
await Task.Run(() =>
{
result = Request(GetRpcUri(), sendJson);
});
if (result == null) { return default; }
// 反序列化
var aria = JsonConvert.DeserializeObject<T>(result);
return aria;
}
/// <summary>
/// http请求
/// </summary>
/// <param name="url"></param>
/// <param name="parameters"></param>
/// <param name="retry"></param>
/// <returns></returns>
private static string Request(string url, string parameters, int retry = 3)
{
// 重试次数
if (retry <= 0) { return null; }
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.Timeout = 5 * 1000;
request.ContentType = "application/json";
byte[] postData = Encoding.UTF8.GetBytes(parameters);
request.ContentLength = postData.Length;
using (Stream reqStream = request.GetRequestStream())
{
reqStream.Write(postData, 0, postData.Length);
reqStream.Close();
}
string html = string.Empty;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
html = reader.ReadToEnd();
}
}
}
return html;
}
catch (WebException e)
{
//Utils.Debugging.Console.PrintLine("Request()发生Web异常: {0}", e);
//LogManager.Error("AriaClient", e);
//return Request(url, parameters, retry - 1);
string html = string.Empty;
var response = (HttpWebResponse)e.Response;
if (response == null) { return null; }
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
html = reader.ReadToEnd();
}
}
//Console.WriteLine($"本次请求使用的参数:{parameters}");
//Console.WriteLine($"返回的web数据{html}");
return html;
}
catch (IOException e)
{
Utils.Debugging.Console.PrintLine("Request()发生IO异常: {0}", e);
LogManager.Error("AriaClient", e);
return Request(url, parameters, retry - 1);
}
catch (Exception e)
{
Utils.Debugging.Console.PrintLine("Request()发生其他异常: {0}", e);
LogManager.Error("AriaClient", e);
return Request(url, parameters, retry - 1);
}
}
}
}