瀏覽代碼

system.listNotifications RPC method

Sonny Piers 9 年之前
父節點
當前提交
d3f16a5711
共有 7 個文件被更改,包括 135 次插入35 次删除
  1. 1 0
      AUTHORS
  2. 64 35
      doc/manual-src/en/aria2c.rst
  3. 17 0
      src/RpcMethodFactory.cc
  4. 2 0
      src/RpcMethodFactory.h
  5. 20 0
      src/RpcMethodImpl.cc
  6. 11 0
      src/RpcMethodImpl.h
  7. 20 0
      test/RpcMethodTest.cc

+ 1 - 0
AUTHORS

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

+ 64 - 35
doc/manual-src/en/aria2c.rst

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

+ 17 - 0
src/RpcMethodFactory.cc

@@ -68,11 +68,24 @@ std::vector<std::string> rpcMethodNames = {
     "aria2.removeDownloadResult", "aria2.getVersion", "aria2.getSessionInfo",
     "aria2.shutdown", "aria2.forceShutdown", "aria2.getGlobalStat",
     "aria2.saveSession", "system.multicall", "system.listMethods",
+    "system.listNotifications",
 };
 } // namespace
 
 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 {
 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>();
   }
 
+  if (methodName == SystemListNotificationsRpcMethod::getMethodName()) {
+    return make_unique<SystemListNotificationsRpcMethod>();
+  }
+
   return nullptr;
 }
 } // namespace

+ 2 - 0
src/RpcMethodFactory.h

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

+ 20 - 0
src/RpcMethodImpl.cc

@@ -1451,6 +1451,26 @@ RpcResponse SystemListMethodsRpcMethod::execute(RpcRequest req,
                      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,
                                                           DownloadEngine* e)
 {

+ 11 - 0
src/RpcMethodImpl.h

@@ -537,6 +537,17 @@ public:
   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 {
 protected:
   virtual std::unique_ptr<ValueBase> process(const RpcRequest& req,

+ 20 - 0
test/RpcMethodTest.cc

@@ -80,6 +80,7 @@ class RpcMethodTest : public CppUnit::TestFixture {
   CPPUNIT_TEST(testSystemMulticall);
   CPPUNIT_TEST(testSystemMulticall_fail);
   CPPUNIT_TEST(testSystemListMethods);
+  CPPUNIT_TEST(testSystemListNotifications);
   CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -146,6 +147,7 @@ public:
   void testSystemMulticall();
   void testSystemMulticall_fail();
   void testSystemListMethods();
+  void testSystemListNotifications();
 };
 
 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 aria2