Răsfoiți Sursa

Write documentation for the archive API. Also add another test.

update #306
JC Brand 10 ani în urmă
părinte
comite
69de033cea
2 a modificat fișierele cu 173 adăugiri și 11 ștergeri
  1. 144 11
      docs/source/development.rst
  2. 29 0
      spec/mam.js

+ 144 - 11
docs/source/development.rst

@@ -51,14 +51,14 @@ directory:
 On Windows you need to specify Makefile.win to be used by running: ::
 
     make -f Makefile.win dev
-    
+
 Or alternatively, if you don't have GNU Make:
 
 ::
 
     npm install
     bower update
-    
+
 This will first install the Node.js development tools (like Grunt and Bower)
 and then use Bower to install all of Converse.js's front-end dependencies.
 
@@ -125,7 +125,7 @@ Please read the `style guide </docs/html/style_guide.html>`_ and make sure that
 Add tests for your bugfix or feature
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 Add a test for any bug fixed or feature added. We use Jasmine
-for testing. 
+for testing.
 
 Take a look at `tests.html <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
 and the `spec files <https://github.com/jcbrand/converse.js/blob/master/tests.html>`_
@@ -146,7 +146,7 @@ Developer API
         Earlier versions of Converse.js might have different API methods or none at all.
 
 In the Converse.js API, you traverse towards a logical grouping, from
-which you can then call certain standardised accessors and mutators, like::
+which you can then call certain standardised accessors and mutators, such as::
 
     .get
     .set
@@ -202,6 +202,139 @@ Example:
             roster_groups: true
         });
 
+The "archive" grouping
+----------------------
+
+Converse.js supports the *Message Archive Management*
+(`XEP-0313 <https://xmpp.org/extensions/xep-0313.html>`_) protocol,
+through which it is able to query an XMPP server for archived messages.
+
+query
+~~~~~
+
+The ``query`` method is used to query for archived messages.
+
+It accepts the following optional parameters:
+
+* **options** an object containing the query parameters. Valid query parameters
+  are ``with``, ``start``, ``end``, ``first``, ``last``, ``after``, ``before``, ``index`` and ``count``.
+* **callback** is the callback method that will be called when all the messages
+  have been received.
+* **errback** is the callback method to be called when an error is returned by
+  the XMPP server, for example when it doesn't support message archiving.
+
+Examples
+^^^^^^^^
+
+**Requesting all archived messages**
+
+The simplest query that can be made is to simply not pass in any parameters.
+Such a query will return all archived messages for the current user.
+
+Generally, you'll however always want to pass in a callback method, to receive
+the returned messages.
+
+.. code-block:: javascript
+
+    var errback = function (iq) {
+        // The query was not successful, perhaps inform the user?
+        // The IQ stanza returned by the XMPP server is passed in, so that you
+        // may inspect it and determine what the problem was.
+    }
+    var callback = function (messages) {
+        // Do something with the messages, like showing them in your webpage.
+    }
+    converse.archive.query(callback, errback))
+
+
+**Requesting all archived messages for a particular contact or room**
+
+To query for messages sent between the current user and another user or room,
+the query options need to contain the the JID (Jabber ID) of the user or
+room under the  ``with`` key.
+
+.. code-block:: javascript
+
+    // For a particular user
+    converse.archive.query({'with': 'john@doe.net'}, callback, errback);)
+
+    // For a particular room
+    converse.archive.query({'with': 'discuss@conference.doglovers.net'}, callback, errback);)
+
+
+**Requesting all archived messages before or after a certain date**
+
+The ``start`` and ``end`` parameters are used to query for messages
+within a certain timeframe. The passed in date values may either be ISO8601
+formatted date strings, or Javascript Date objects.
+
+.. code-block:: javascript
+
+    var options = {
+        'with': 'john@doe.net',
+        'start': '2010-06-07T00:00:00Z',
+        'end': '2010-07-07T13:23:54Z'
+    };
+    converse.archive.query(options, callback, errback);
+
+
+**Limiting the amount of messages returned**
+
+The amount of returned messages may be limited with the ``max`` parameter.
+By default, the messages are returned from oldest to newest.
+
+.. code-block:: javascript
+
+    // Return maximum 10 archived messages
+    converse.archive.query({'with': 'john@doe.net', 'max':10}, callback, errback);
+
+
+**Paging forwards through a set of archived messages**
+
+When limiting the amount of messages returned per query, you might want to
+repeatedly make a further query to fetch the next batch of messages.
+
+To simplify this usecase for you, the callback method receives not only an array
+with the returned archived messages, but also a special RSM (*Result Set
+Management*) object which contains the query parameters you passed in, as well
+as two utility methods ``next``, and ``previous``.
+
+When you call one of these utility methods on the returned RSM object, and then
+pass the result into a new query, you'll receive the next or previous batch of
+archived messages.
+
+.. code-block:: javascript
+
+    var callback = function (messages, rsm) {
+        // Do something with the messages, like showing them in your webpage.
+        // ...
+        // You can now use the returned "rsm" object, to fetch the next batch of messages:
+        converse.archive.query(rsm.next(), callback, errback))
+
+    }
+    converse.archive.query({'with': 'john@doe.net', 'max':10}, callback, errback);
+
+**Paging backwards through a set of archived messages**
+
+To page backwards through the archive, you need to know the UID of the message
+which you'd like to page backwards from and then pass that as value for the
+``before`` parameter. If you simply want to page backwards from the most recent
+message, pass in the ``before`` parameter with a value of ``null``.
+
+.. code-block:: javascript
+
+    converse.archive.query({'before': null, 'max':5}, function (message, rsm) {
+        // Do something with the messages, like showing them in your webpage.
+        // ...
+        // You can now use the returned "rsm" object, to fetch the previous batch of messages:
+        rsm.previous(); // Call previous method, to update the object
+                        // parameters so that the previous batch of messages will be returned.
+        rsm.count = 10; // Increase the page size (currently it's set to 1,
+                        // because that was what we specified in our last query.
+        // Now we query again, to get the previous batch.
+        converse.archive.query(rsm, callback, errback);
+    }
+
 
 The "user" grouping
 -------------------
@@ -213,7 +346,7 @@ logout
 
 Log the user out of the current XMPP session.
 
-.. code-block:: javascript 
+.. code-block:: javascript
 
     converse.user.logout();
 
@@ -228,7 +361,7 @@ get
 
 Return the current user's availability status:
 
-.. code-block:: javascript 
+.. code-block:: javascript
 
     converse.user.status.get(); // Returns for example "dnd"
 
@@ -246,7 +379,7 @@ The user's status can be set to one of the following values:
 
 For example:
 
-.. code-block:: javascript 
+.. code-block:: javascript
 
     converse.user.status.set('dnd');
 
@@ -254,7 +387,7 @@ Because the user's availability is often set together with a custom status
 message, this method also allows you to pass in a status message as a
 second parameter:
 
-.. code-block:: javascript 
+.. code-block:: javascript
 
     converse.user.status.set('dnd', 'In a meeting');
 
@@ -264,7 +397,7 @@ The "message" sub-grouping
 The ``user.status.message`` sub-grouping exposes methods for setting and
 retrieving the user's custom status message.
 
-.. code-block:: javascript 
+.. code-block:: javascript
 
     converse.user.status.message.set('In a meeting');
 
@@ -344,7 +477,7 @@ Provide the JID of the contact you want to add:
     .. code-block:: javascript
 
     converse.contacts.add('buddy@example.com')
-    
+
 You may also provide the fullname. If not present, we use the jid as fullname:
 
     .. code-block:: javascript
@@ -663,7 +796,7 @@ An example plugin
     }(this, function ($, strophe, utils, converse_api) {
 
         // Wrap your UI strings with the __ function for translation support.
-        var __ = $.proxy(utils.__, this); 
+        var __ = $.proxy(utils.__, this);
 
         // Strophe methods for building stanzas
         var Strophe = strophe.Strophe;

+ 29 - 0
spec/mam.js

@@ -227,6 +227,35 @@
                 Date.prototype.getTimezoneOffset = getTimezoneOffset;
            });
 
+           it("accepts \"before\" with an empty string as value to reverse the order", function () {
+                var sent_stanza, IQ_id;
+                var sendIQ = converse.connection.sendIQ;
+                spyOn(converse.connection, 'sendIQ').andCallFake(function (iq, callback, errback) {
+                    sent_stanza = iq;
+                    IQ_id = sendIQ.bind(this)(iq, callback, errback);
+                });
+                if (!converse.features.findWhere({'var': Strophe.NS.MAM})) {
+                    converse.features.create({'var': Strophe.NS.MAM});
+                }
+                converse_api.archive.query({'before': '', 'max':10});
+                var queryid = $(sent_stanza.toString()).find('query').attr('queryid');
+                expect(sent_stanza.toString()).toBe(
+                    "<iq type='set' xmlns='jabber:client' id='"+IQ_id+"'>"+
+                        "<query xmlns='urn:xmpp:mam:0' queryid='"+queryid+"'>"+
+                            "<x xmlns='jabber:x:data'>"+
+                                "<field var='FORM_TYPE'>"+
+                                    "<value>urn:xmpp:mam:0</value>"+
+                                "</field>"+
+                            "</x>"+
+                            "<set xmlns='http://jabber.org/protocol/rsm'>"+
+                                "<max>10</max>"+
+                                "<before></before>"+
+                            "</set>"+
+                        "</query>"+
+                    "</iq>"
+                );
+           });
+
         }, converse, mock, test_utils));
 
         describe("The default preference", $.proxy(function (mock, test_utils) {