Merge branch 'system.listNotifications' of https://github.com/sonnyp/aria2 into sonnyp-system.listNotifications

pull/629/head
Tatsuhiro Tsujikawa 2016-04-15 23:26:38 +09:00
commit cf1dd06d03
7 changed files with 135 additions and 35 deletions

View File

@ -36,5 +36,6 @@ luokar
mozillazg mozillazg
multisnow multisnow
oliviercommelarbre oliviercommelarbre
Sonny Piers
[1] https://gist.github.com/tatsuhiro-t/deaffeb064652104ad11 [1] https://gist.github.com/tatsuhiro-t/deaffeb064652104ad11

View File

@ -103,7 +103,7 @@ HTTP/FTP/SFTP Options
See also `ENVIRONMENT`_ section. See also `ENVIRONMENT`_ section.
.. note:: .. note::
If user and password are embedded in proxy URI and they are also If user and password are embedded in proxy URI and they are also
specified by *--{http,https,ftp,all}-proxy-{user,passwd}* options, specified by *--{http,https,ftp,all}-proxy-{user,passwd}* options,
those specified later override prior options. For example, if you specified those specified later override prior options. For example, if you specified
@ -209,7 +209,7 @@ HTTP/FTP/SFTP Options
Disables netrc support. netrc support is enabled by default. Disables netrc support. netrc support is enabled by default.
.. note:: .. note::
netrc file is only read at the startup if netrc file is only read at the startup if
:option:`--no-netrc <-n>` is ``false``. :option:`--no-netrc <-n>` is ``false``.
So if :option:`--no-netrc <-n>` is ``true`` at the startup, So if :option:`--no-netrc <-n>` is ``true`` at the startup,
@ -305,7 +305,7 @@ HTTP/FTP/SFTP Options
Default: ``5`` Default: ``5``
.. note:: .. note::
Some Metalinks regulate the number of servers to connect. aria2 Some Metalinks regulate the number of servers to connect. aria2
strictly respects them. This means that if Metalink defines the strictly respects them. This means that if Metalink defines the
``maxconnections`` attribute lower than N, then aria2 uses the ``maxconnections`` attribute lower than N, then aria2 uses the
@ -417,7 +417,7 @@ HTTP Specific Options
``Content-Encoding: deflate``. Default: ``false`` ``Content-Encoding: deflate``. Default: ``false``
.. note:: .. note::
Some server responds with ``Content-Encoding: gzip`` for files which Some server responds with ``Content-Encoding: gzip`` for files which
itself is gzipped file. aria2 inflates them anyway because of the itself is gzipped file. aria2 inflates them anyway because of the
response header. response header.
@ -500,7 +500,7 @@ HTTP Specific Options
Default: ``false`` Default: ``false``
.. note:: .. note::
In performance perspective, there is usually no advantage to enable In performance perspective, there is usually no advantage to enable
this option. this option.
@ -747,7 +747,7 @@ BitTorrent Specific Options
If ``true`` is given, aria2 doesn't accept and establish connection with legacy If ``true`` is given, aria2 doesn't accept and establish connection with legacy
BitTorrent handshake(\\19BitTorrent protocol). BitTorrent handshake(\\19BitTorrent protocol).
Thus aria2 always uses Obfuscation handshake. Thus aria2 always uses Obfuscation handshake.
Default: ``false`` Default: ``false``
.. option:: --bt-request-peer-speed-limit=<SPEED> .. option:: --bt-request-peer-speed-limit=<SPEED>
@ -937,7 +937,7 @@ BitTorrent Specific Options
Specify seeding time in minutes. Also see the :option:`--seed-ratio` option. Specify seeding time in minutes. Also see the :option:`--seed-ratio` option.
.. note:: .. note::
Specifying :option:`--seed-time=0 <--seed-time>` disables seeding after download completed. Specifying :option:`--seed-time=0 <--seed-time>` disables seeding after download completed.
.. option:: -T, --torrent-file=<TORRENT_FILE> .. option:: -T, --torrent-file=<TORRENT_FILE>
@ -994,7 +994,7 @@ Metalink Specific Options
The possible values are ``http``, ``https``, ``ftp`` and ``none``. The possible values are ``http``, ``https``, ``ftp`` and ``none``.
Specify ``none`` to disable this feature. Specify ``none`` to disable this feature.
Default: ``none`` Default: ``none``
.. option:: --metalink-enable-unique-protocol[=true|false] .. option:: --metalink-enable-unique-protocol[=true|false]
If ``true`` is given and several protocols are available for a mirror in a If ``true`` is given and several protocols are available for a mirror in a
@ -1489,7 +1489,7 @@ Advanced Options
Default: ``1M`` Default: ``1M``
.. note:: .. note::
The possible use case of :option:`--piece-length` The possible use case of :option:`--piece-length`
option is change the request range in one HTTP pipelined request. option is change the request range in one HTTP pipelined request.
To enable HTTP pipelining use To enable HTTP pipelining use
@ -1631,7 +1631,7 @@ Advanced Options
Truncate console readout to fit in a single line. Truncate console readout to fit in a single line.
Default: ``true`` Default: ``true``
.. option:: -v, --version .. option:: -v, --version
Print the version number, copyright and the configuration information and Print the version number, copyright and the configuration information and
@ -1883,7 +1883,7 @@ aria2 recognizes the following environment variables.
The command-line option :option:`--all-proxy` overrides this value. The command-line option :option:`--all-proxy` overrides this value.
.. note:: .. note::
Although aria2 accepts ``ftp://`` and ``https://`` scheme in proxy URI, it Although aria2 accepts ``ftp://`` and ``https://`` scheme in proxy URI, it
simply assumes that ``http://`` is specified and does not change its simply assumes that ``http://`` is specified and does not change its
behavior based on the specified scheme. behavior based on the specified scheme.
@ -2111,7 +2111,7 @@ of URIs. These optional lines must start with white space(s).
* :option:`uri-selector <--uri-selector>` * :option:`uri-selector <--uri-selector>`
* :option:`use-head <--use-head>` * :option:`use-head <--use-head>`
* :option:`user-agent <-U>` * :option:`user-agent <-U>`
These options have exactly same meaning of the ones in the These options have exactly same meaning of the ones in the
command-line options, but it just applies to the URIs it belongs to. command-line options, but it just applies to the URIs it belongs to.
Please note that for options in input file ``--`` prefix must be Please note that for options in input file ``--`` prefix must be
@ -2262,9 +2262,8 @@ to provide the token as the first parameter as described above.
interface. Therefore it is recommended to prefer Batch or `system.multicall` interface. Therefore it is recommended to prefer Batch or `system.multicall`
requests when appropriate. requests when appropriate.
`system.listMethods` can be executed without token. Since it just `system.listMethods` and `system.listNotifications` can be executed without token. Since they just
returns the all available methods, and does not alter anything, it return available methods/notifications, they do not alter anything, they're safe without secret token.
is safe without secret token.
Methods Methods
~~~~~~~ ~~~~~~~
@ -3478,9 +3477,9 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
.. function:: system.listMethods() .. function:: system.listMethods()
This method returns the all available RPC methods in an array of This method returns all the available RPC methods in an array of
string. Unlike other methods, this method does not require secret string. Unlike other methods, this method does not require secret
token. This is safe because this method jsut returns the available token. This is safe because this method just returns the available
method names. method names.
**JSON-RPC Example** **JSON-RPC Example**
@ -3506,6 +3505,36 @@ For information on the *secret* parameter, see :ref:`rpc_auth`.
>>> s.system.listMethods() >>> s.system.listMethods()
['aria2.addUri', 'aria2.addTorrent', ... ['aria2.addUri', 'aria2.addTorrent', ...
.. function:: system.listNotifications()
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.
**JSON-RPC Example**
::
>>> import urllib2, json
>>> from pprint import pprint
>>> jsonreq = json.dumps({'jsonrpc':'2.0', 'id':'qwer',
... 'method':'system.listNotifications'})
>>> c = urllib2.urlopen('http://localhost:6800/jsonrpc', jsonreq)
>>> pprint(json.loads(c.read()))
{u'id': u'qwer',
u'jsonrpc': u'2.0',
u'result': [u'aria2.onDownloadStart',
u'aria2.onDownloadPause',
...
**XML-RPC Example**
::
>>> import xmlrpclib
>>> s = xmlrpclib.ServerProxy('http://localhost:6800/rpc')
>>> s.system.listNotifications()
['aria2.onDownloadStart', 'aria2.onDownloadPause', ...
Error Handling Error Handling
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
@ -3665,50 +3694,50 @@ notification method. Following notification methods are defined.
This notification will be sent when a download is started. This notification will be sent when a download is started.
The *event* is of type struct and it contains following keys. The *event* is of type struct and it contains following keys.
The value type is string. The value type is string.
``gid`` ``gid``
GID of the download. GID of the download.
.. function:: aria2.onDownloadPause(event) .. function:: aria2.onDownloadPause(event)
This notification will be sent when a download is paused. The *event* This notification will be sent when a download is paused. The *event*
is the same struct as the *event* argument of is the same struct as the *event* argument of
:func:`aria2.onDownloadStart` method. :func:`aria2.onDownloadStart` method.
.. function:: aria2.onDownloadStop(event) .. function:: aria2.onDownloadStop(event)
This notification will be sent when a download is stopped by the user. This notification will be sent when a download is stopped by the user.
The *event* is the same struct as the *event* argument of The *event* is the same struct as the *event* argument of
:func:`aria2.onDownloadStart` method. :func:`aria2.onDownloadStart` method.
.. function:: aria2.onDownloadComplete(event) .. function:: aria2.onDownloadComplete(event)
This notification will be sent when a download is complete. For This notification will be sent when a download is complete. For
BitTorrent downloads, this notification is sent when the download is BitTorrent downloads, this notification is sent when the download is
complete and seeding is over. The *event* is the same struct of the complete and seeding is over. The *event* is the same struct of the
*event* argument of *event* argument of
:func:`aria2.onDownloadStart` method. :func:`aria2.onDownloadStart` method.
.. function:: aria2.onDownloadError(event) .. function:: aria2.onDownloadError(event)
This notification will be sent when a download is stopped due to an error. This notification will be sent when a download is stopped due to an error.
The *event* is the same struct as the *event* argument of The *event* is the same struct as the *event* argument of
:func:`aria2.onDownloadStart` method. :func:`aria2.onDownloadStart` method.
.. function:: aria2.onBtDownloadComplete(event) .. function:: aria2.onBtDownloadComplete(event)
This notification will be sent when a torrent download is complete but seeding This notification will be sent when a torrent download is complete but seeding
is still going on. The *event* is the same struct as the *event* argument of is still going on. The *event* is the same struct as the *event* argument of
:func:`aria2.onDownloadStart` method. :func:`aria2.onDownloadStart` method.
Sample XML-RPC Client Code Sample XML-RPC Client Code
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -3719,15 +3748,15 @@ prints the RPC response:
.. code-block:: ruby .. code-block:: ruby
#!/usr/bin/env ruby #!/usr/bin/env ruby
require 'xmlrpc/client' require 'xmlrpc/client'
require 'pp' require 'pp'
client=XMLRPC::Client.new2("http://localhost:6800/rpc") client=XMLRPC::Client.new2("http://localhost:6800/rpc")
options={ "dir" => "/downloads" } options={ "dir" => "/downloads" }
result=client.call("aria2.addUri", [ "http://localhost/aria2.tar.bz2" ], options) result=client.call("aria2.addUri", [ "http://localhost/aria2.tar.bz2" ], options)
pp result pp result
@ -3736,7 +3765,7 @@ xmlrpc.client instead) to interact with aria2::
import xmlrpclib import xmlrpclib
from pprint import pprint from pprint import pprint
s = xmlrpclib.ServerProxy("http://localhost:6800/rpc") s = xmlrpclib.ServerProxy("http://localhost:6800/rpc")
r = s.aria2.addUri(["http://localhost/aria2.tar.bz2"], {"dir":"/downloads"}) r = s.aria2.addUri(["http://localhost/aria2.tar.bz2"], {"dir":"/downloads"})
pprint(r) pprint(r)
@ -3870,7 +3899,7 @@ For FTP:
$ aria2c --ftp-proxy="http://proxy:8080" "ftp://host/file" $ aria2c --ftp-proxy="http://proxy:8080" "ftp://host/file"
.. note:: .. note::
See :option:`--http-proxy`, :option:`--https-proxy`, :option:`--ftp-proxy`, See :option:`--http-proxy`, :option:`--https-proxy`, :option:`--ftp-proxy`,
:option:`--all-proxy` and :option:`--no-proxy` for details. You can specify :option:`--all-proxy` and :option:`--no-proxy` for details. You can specify
proxy in the environment variables. See `ENVIRONMENT`_ section. proxy in the environment variables. See `ENVIRONMENT`_ section.
@ -4196,7 +4225,7 @@ Repair a damaged download
$ aria2c -V file.metalink $ aria2c -V file.metalink
.. note:: .. note::
Repairing damaged downloads can be done efficiently when used with Repairing damaged downloads can be done efficiently when used with
BitTorrent or Metalink with chunk checksums. BitTorrent or Metalink with chunk checksums.

View File

@ -68,11 +68,24 @@ std::vector<std::string> rpcMethodNames = {
"aria2.removeDownloadResult", "aria2.getVersion", "aria2.getSessionInfo", "aria2.removeDownloadResult", "aria2.getVersion", "aria2.getSessionInfo",
"aria2.shutdown", "aria2.forceShutdown", "aria2.getGlobalStat", "aria2.shutdown", "aria2.forceShutdown", "aria2.getGlobalStat",
"aria2.saveSession", "system.multicall", "system.listMethods", "aria2.saveSession", "system.multicall", "system.listMethods",
"system.listNotifications",
}; };
} // namespace } // namespace
const std::vector<std::string>& allMethodNames() { return rpcMethodNames; } const std::vector<std::string>& allMethodNames() { return rpcMethodNames; }
namespace {
std::vector<std::string> rpcNotificationsNames = {
"aria2.onDownloadStart", "aria2.onDownloadPause", "aria2.onDownloadStop",
"aria2.onDownloadComplete", "aria2.onDownloadError",
#ifdef ENABLE_BITTORRENT
"aria2.onBtDownloadComplete",
#endif // ENABLE_BITTORRENT
};
} // namespace
const std::vector<std::string>& allNotificationsNames() { return rpcNotificationsNames; }
namespace { namespace {
std::unique_ptr<RpcMethod> createMethod(const std::string& methodName) std::unique_ptr<RpcMethod> createMethod(const std::string& methodName)
{ {
@ -220,6 +233,10 @@ std::unique_ptr<RpcMethod> createMethod(const std::string& methodName)
return make_unique<SystemListMethodsRpcMethod>(); return make_unique<SystemListMethodsRpcMethod>();
} }
if (methodName == SystemListNotificationsRpcMethod::getMethodName()) {
return make_unique<SystemListNotificationsRpcMethod>();
}
return nullptr; return nullptr;
} }
} // namespace } // namespace

View File

@ -49,6 +49,8 @@ class RpcMethod;
const std::vector<std::string>& allMethodNames(); const std::vector<std::string>& allMethodNames();
const std::vector<std::string>& allNotificationsNames();
RpcMethod* getMethod(const std::string& methodName); RpcMethod* getMethod(const std::string& methodName);
} // namespace rpc } // namespace rpc

View File

@ -1451,6 +1451,26 @@ RpcResponse SystemListMethodsRpcMethod::execute(RpcRequest req,
std::move(req.id)); std::move(req.id));
} }
std::unique_ptr<ValueBase>
SystemListNotificationsRpcMethod::process(const RpcRequest& req,
DownloadEngine* e)
{
auto list = List::g();
for (auto& s : allNotificationsNames()) {
list->append(s);
}
return std::move(list);
}
RpcResponse SystemListNotificationsRpcMethod::execute(RpcRequest req,
DownloadEngine* e)
{
auto r = process(req, e);
return RpcResponse(0, RpcResponse::AUTHORIZED, std::move(r),
std::move(req.id));
}
std::unique_ptr<ValueBase> NoSuchMethodRpcMethod::process(const RpcRequest& req, std::unique_ptr<ValueBase> NoSuchMethodRpcMethod::process(const RpcRequest& req,
DownloadEngine* e) DownloadEngine* e)
{ {

View File

@ -537,6 +537,17 @@ public:
static const char* getMethodName() { return "system.listMethods"; } static const char* getMethodName() { return "system.listMethods"; }
}; };
class SystemListNotificationsRpcMethod : public RpcMethod {
protected:
virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,
DownloadEngine* e) CXX11_OVERRIDE;
public:
virtual RpcResponse execute(RpcRequest req, DownloadEngine* e) CXX11_OVERRIDE;
static const char* getMethodName() { return "system.listNotifications"; }
};
class NoSuchMethodRpcMethod : public RpcMethod { class NoSuchMethodRpcMethod : public RpcMethod {
protected: protected:
virtual std::unique_ptr<ValueBase> process(const RpcRequest& req, virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,

View File

@ -80,6 +80,7 @@ class RpcMethodTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testSystemMulticall); CPPUNIT_TEST(testSystemMulticall);
CPPUNIT_TEST(testSystemMulticall_fail); CPPUNIT_TEST(testSystemMulticall_fail);
CPPUNIT_TEST(testSystemListMethods); CPPUNIT_TEST(testSystemListMethods);
CPPUNIT_TEST(testSystemListNotifications);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
@ -146,6 +147,7 @@ public:
void testSystemMulticall(); void testSystemMulticall();
void testSystemMulticall_fail(); void testSystemMulticall_fail();
void testSystemListMethods(); void testSystemListMethods();
void testSystemListNotifications();
}; };
CPPUNIT_TEST_SUITE_REGISTRATION(RpcMethodTest); CPPUNIT_TEST_SUITE_REGISTRATION(RpcMethodTest);
@ -1396,6 +1398,24 @@ void RpcMethodTest::testSystemListMethods()
} }
} }
void RpcMethodTest::testSystemListNotifications()
{
SystemListNotificationsRpcMethod m;
auto res = m.execute(createReq("system.listNotifications"), e_.get());
CPPUNIT_ASSERT_EQUAL(0, res.code);
const auto resParams = downcast<List>(res.param);
auto& allNames = allNotificationsNames();
CPPUNIT_ASSERT_EQUAL(allNames.size(), resParams->size());
for (size_t i = 0; i < allNames.size(); ++i) {
const auto s = downcast<String>(resParams->get(i));
CPPUNIT_ASSERT(s);
CPPUNIT_ASSERT_EQUAL(allNames[i], s->s());
}
}
} // namespace rpc } // namespace rpc
} // namespace aria2 } // namespace aria2