changeset 828:0c824ebe9d87

server (blog): implemented tag/category filtering: - the tag=[quoted tag] query is used to use the filtering - MAM data use request.mam_extra instead of request.extra_dict to avoid using it with item_ids - getDefaultQueryData function is used to keep query data (link MAM category filtering) between links - filtering is help when displaying a blog post, this way it's easy to navigate between thematic posts - filtering can be removed by clicking on user avatar/nick (with default theme)
author Goffi <goffi@goffi.org>
date Fri, 08 Jan 2016 19:58:08 +0100
parents f1fc7245b910
children c1000ea40e6c
files src/common/constants.py src/server/blog.py
diffstat 2 files changed, 48 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/common/constants.py	Fri Jan 08 19:53:51 2016 +0100
+++ b/src/common/constants.py	Fri Jan 08 19:58:08 2016 +0100
@@ -53,3 +53,6 @@
     DEFAULT_AVATAR_URL = os.path.join(MEDIA_DIR, "misc", DEFAULT_AVATAR_FILE)
     EMPTY_AVATAR_FILE = "empty_avatar"
     EMPTY_AVATAR_URL = os.path.join(MEDIA_DIR, "misc", EMPTY_AVATAR_FILE)
+
+    # blog
+    MAM_FILTER_CATEGORY = 'http://salut-a-toi.org/protocols/mam_filter_category'
--- a/src/server/blog.py	Fri Jan 08 19:53:51 2016 +0100
+++ b/src/server/blog.py	Fri Jan 08 19:58:08 2016 +0100
@@ -44,6 +44,20 @@
 # TODO: chech disco features and use max_items when RSM is not available
 
 
+def getDefaultQueryData(request):
+    """Return query data which must be present in all links
+
+    @param request(twisted.web.http.Request): request instance comming from render
+    @return (dict): a dict with values as expected by urllib.urlencode
+    """
+    default_query_data = {}
+    try:
+        default_query_data['tag'] = request.extra_dict['mam_filter_{}'.format(C.MAM_FILTER_CATEGORY)].encode('utf-8')
+    except KeyError:
+        pass
+    return default_query_data
+
+
 def _quote(value):
     """Quote a value for use in url
 
@@ -170,14 +184,17 @@
             # TODO: use max_items only when RSM is not available
 
         if request.atom:
+            request.extra_dict.update(request.mam_extra)
             self.host.bridge.mbGetAtom(pub_jid.userhost(), '', max_items, item_ids,
                                        request.extra_dict, C.SERVICE_PROFILE,
                                        lambda feed: self.renderAtomFeed(feed, request),
                                        lambda failure: self.renderError(failure, request, pub_jid))
         elif request.item_id:
+            # we can't merge mam_extra now because we'll use item_ids
             self.getItemById(pub_jid, request.item_id, request.extra_dict,
                              request.extra_comments_dict, request, profile)
         else:
+            request.extra_dict.update(request.mam_extra)
             self.getItems(pub_jid, max_items, request.extra_dict,
                           request.extra_comments_dict, request, profile)
 
@@ -203,6 +220,7 @@
         # XXX: request.display_single is True when only one blog post is visible
         request.display_single = (request.item_id is not None) or int(request.extra_dict['rsm_max']) == 1
         self.parseURLParamsCommentsRSM(request)
+        self.parseURLParamsMAM(request)
 
     def parseURLParamsRSM(self, request):
         """Parse RSM request data from the URL parameters for main items
@@ -250,6 +268,22 @@
         else:
             request.extra_comments_dict['rsm_max'] = "0"
 
+    def parseURLParamsMAM(self, request):
+        """Parse MAM request data from the URL parameters for main items
+
+        fill request.extra_dict accordingly
+        @param request: HTTP request
+        """
+        # XXX: we use a separate dict for MAM as the filters are not used
+        #      when display_single is set (because it then use item_ids which
+        #      can't be used with MAM), but it is still used in this case
+        #      for navigation links.
+        request.mam_extra = {}
+        try:
+            request.mam_extra['mam_filter_{}'.format(C.MAM_FILTER_CATEGORY)] = request.args['tag'][0]
+        except KeyError:
+            pass
+
     ## Items retrieval
 
     def getItemById(self, pub_jid, item_id, extra_dict, extra_comments_dict, request, profile):
@@ -281,6 +315,8 @@
                 metadata['rsm_first'] = metadata['rsm_last'] = item["id"]
 
                 def gotComments(comments):
+                    # at this point we can merge mam dict
+                    request.extra_dict.update(request.mam_extra)
                     # build the items as self.getItems would do it (and as self.renderHTML expects them to be)
                     comments = [(item['comments_service'], item['comments_node'], "", comments[0], comments[1])]
                     self.renderHTML([(item, comments)], metadata, request, pub_jid, profile)
@@ -454,6 +490,10 @@
         @param base_url (unicode): the base URL for this user's blog
         @return: dict
         """
+        # query data which must be present in all links
+        default_query_data = getDefaultQueryData(request)
+
+        # which links we need to display
         if request.display_single:
             links = ('later_message', 'older_message')
             # key must exist when using the template
@@ -462,8 +502,9 @@
             links = ('later_messages', 'older_messages')
             self.later_message = self.older_message = ''
 
+        # now we set the links according to RSM
         for key in links:
-            query_data = {}
+            query_data = default_query_data.copy()
 
             if key.startswith('later_message'):
                 try:
@@ -546,6 +587,9 @@
         else:
             self.author = '&nbsp;'
             self.url = "{}/{}".format(base_url, _quote(entry['id']))
+            query_data = getDefaultQueryData(request)
+            if query_data:
+                self.url += '?{}'.format(urllib.urlencode(query_data))
             self.title = self.getText(entry, 'title')
             self.tags = list(common.dict2iter('tag', entry))