Browse Source

Merge branch 'sonnyp-system.listNotifications'

Tatsuhiro Tsujikawa 9 years ago
parent
commit
7105ce31f2

+ 1 - 0
AUTHORS

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

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

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

+ 1 - 1
src/OptionHandlerImpl.cc

@@ -623,7 +623,7 @@ void OptimizeConcurrentDownloadsOptionHandler::parseArg(
     PrefPtr pref = PREF_OPTIMIZE_CONCURRENT_DOWNLOADS_COEFFA;
     PrefPtr pref = PREF_OPTIMIZE_CONCURRENT_DOWNLOADS_COEFFA;
     std::string* sptr = &coeff_a;
     std::string* sptr = &coeff_a;
     for (;;) {
     for (;;) {
-      char *end;
+      char* end;
       errno = 0;
       errno = 0;
       auto dbl = strtod(sptr->c_str(), &end);
       auto dbl = strtod(sptr->c_str(), &end);
       if (errno != 0 || sptr->c_str() + sptr->size() != end) {
       if (errno != 0 || sptr->c_str() + sptr->size() != end) {

+ 21 - 0
src/RpcMethodFactory.cc

@@ -68,11 +68,28 @@ 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 +237,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

+ 2 - 0
src/RpcMethodFactory.h

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

+ 20 - 0
src/RpcMethodImpl.cc

@@ -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)
 {
 {

+ 11 - 0
src/RpcMethodImpl.h

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

+ 20 - 0
test/RpcMethodTest.cc

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