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

@ -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
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~

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