allura-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From brond...@apache.org
Subject [1/9] allura git commit: [#7981] don't allow overlapping subscriptions between Forums and its Threads
Date Mon, 05 Dec 2016 16:39:34 GMT
Repository: allura
Updated Branches:
  refs/heads/master 23cf3566d -> 3b8240fc2


[#7981] don't allow overlapping subscriptions between Forums and its Threads


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/dec2ab0b
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/dec2ab0b
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/dec2ab0b

Branch: refs/heads/master
Commit: dec2ab0baa2fcbf3e7137cac4c4ead385d006c8b
Parents: a02c913
Author: Dave Brondsema <dave@brondsema.net>
Authored: Fri Nov 18 17:52:02 2016 -0500
Committer: Dave Brondsema <dave@brondsema.net>
Committed: Mon Dec 5 11:39:20 2016 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/site_admin.py         |  7 ++---
 Allura/allura/lib/search.py                     | 31 ++++++++++++++++++++
 Allura/allura/model/artifact.py                 |  2 +-
 Allura/allura/model/notification.py             |  3 +-
 .../allura/tests/functional/test_site_admin.py  | 12 ++++----
 .../forgediscussion/controllers/forum.py        | 24 ++++++++++++++-
 requirements.txt                                |  2 +-
 7 files changed, 66 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/dec2ab0b/Allura/allura/controllers/site_admin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/site_admin.py b/Allura/allura/controllers/site_admin.py
index 459362e..a7ece1a 100644
--- a/Allura/allura/controllers/site_admin.py
+++ b/Allura/allura/controllers/site_admin.py
@@ -272,12 +272,9 @@ class SiteAdminController(object):
             if match:
                 count = match.hits
                 objects = match.docs
-                ids = [obj['id'].split('#')[1] for obj in objects]
-                ids = [bson.ObjectId(_id) for _id in ids if _id != 'None']
-                mongo_objects = {}
-                for obj in model.query.find({'_id': {'$in': ids}}):
-                    mongo_objects[str(obj._id)] = obj
 
+                ids = [obj['id'] for obj in objects]
+                mongo_objects = search.mapped_artifacts_from_index_ids(ids, model)
                 for i in range(len(objects)):
                     obj = objects[i]
                     _id = obj['id'].split('#')[1]

http://git-wip-us.apache.org/repos/asf/allura/blob/dec2ab0b/Allura/allura/lib/search.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/search.py b/Allura/allura/lib/search.py
index 2ee9b82..02afa05 100644
--- a/Allura/allura/lib/search.py
+++ b/Allura/allura/lib/search.py
@@ -21,6 +21,7 @@ from logging import getLogger
 from urllib import urlencode
 from itertools import imap
 
+import bson
 import markdown
 import jinja2
 from tg import redirect, url
@@ -330,3 +331,33 @@ def find_shortlinks(text):
     md.convert(text)
     link_index = md.treeprocessors['links'].alinks
     return [link for link in link_index if link is not None]
+
+
+def artifacts_from_index_ids(index_ids, model, objectid_id=True):
+    '''
+    :param list[str] index_ids: a list of search/subscription/artifact-reference index_id
values
+    :param type model: the Artifact class
+    :param bool objectid_id: whether the _id values are ObjectIds
+    :return: instances of the model, for each id given
+    :rtype: list
+    '''
+    # this could be made more flexible to not require the model passed in
+    ids = [index_id.split('#')[1] for index_id in index_ids]
+    if objectid_id:
+        ids = [bson.ObjectId(_id) for _id in ids if id != 'None']
+    return model.query.find({'_id': {'$in': ids}}).all()
+
+
+def mapped_artifacts_from_index_ids(index_ids, model, objectid_id=True):
+    '''
+    :param list[str] index_ids: a list of search/subscription/artifact-reference index_id
values
+    :param type model: the Artifact class
+    :param bool objectid_id: whether the _id values are ObjectIds
+    :return: instances of the model, keyed by str(_id)
+    :rtype: dict
+    '''
+    models = artifacts_from_index_ids(index_ids, model, objectid_id=objectid_id)
+    map = {}
+    for m in models:
+        map[str(m._id)] = m
+    return map
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/dec2ab0b/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 39316d2..523a7ad 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -201,7 +201,7 @@ class Artifact(MappedClass, SearchIndexable):
         from allura.model import Mailbox
         if user is None:
             user = c.user
-        Mailbox.subscribe(
+        return Mailbox.subscribe(
             user_id=user._id,
             project_id=self.app_config.project_id,
             app_config_id=self.app_config._id,

http://git-wip-us.apache.org/repos/asf/allura/blob/dec2ab0b/Allura/allura/model/notification.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index 52ef451..80ff6a6 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -486,8 +486,9 @@ class Mailbox(MappedClass):
             # tool
             for other_mbox in cls.query.find(dict(
                     user_id=user_id, project_id=project_id, app_config_id=app_config_id)):
-                if other_mbox is not mbox:
+                if other_mbox != mbox:
                     other_mbox.delete()
+        return mbox
 
     @classmethod
     def unsubscribe(

http://git-wip-us.apache.org/repos/asf/allura/blob/dec2ab0b/Allura/allura/tests/functional/test_site_admin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_site_admin.py b/Allura/allura/tests/functional/test_site_admin.py
index 7889136..c46e2b1 100644
--- a/Allura/allura/tests/functional/test_site_admin.py
+++ b/Allura/allura/tests/functional/test_site_admin.py
@@ -407,9 +407,9 @@ class TestUsersSearch(TestController):
             M.User(_id=_id, username='darth')
             ThreadLocalORMSession().flush_all()
 
-    @patch('allura.controllers.site_admin.search')
-    def test_default_fields(self, search):
-        search.site_admin_search.return_value = self.TEST_HIT
+    @patch('allura.controllers.site_admin.search.site_admin_search')
+    def test_default_fields(self, site_admin_search):
+        site_admin_search.return_value = self.TEST_HIT
         r = self.app.get('/nf/admin/search_users?q=fake&f=username')
         options = [o['value'] for o in r.html.findAll('option')]
         assert_equal(options, ['username', 'display_name', '__custom__'])
@@ -417,9 +417,9 @@ class TestUsersSearch(TestController):
         assert_equal(ths, ['Username', 'Display name', 'Email', 'Registered',
                            'Status', 'Details'])
 
-    @patch('allura.controllers.site_admin.search')
-    def test_additional_fields(self, search):
-        search.site_admin_search.return_value = self.TEST_HIT
+    @patch('allura.controllers.site_admin.search.site_admin_search')
+    def test_additional_fields(self, site_admin_search):
+        site_admin_search.return_value = self.TEST_HIT
         with h.push_config(config, **{'search.user.additional_search_fields': 'email_addresses,
url',
                                       'search.user.additional_display_fields': 'url'}):
             r = self.app.get('/nf/admin/search_users?q=fake&f=username')

http://git-wip-us.apache.org/repos/asf/allura/blob/dec2ab0b/ForgeDiscussion/forgediscussion/controllers/forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/forum.py b/ForgeDiscussion/forgediscussion/controllers/forum.py
index bb0fa33..52b3b7c 100644
--- a/ForgeDiscussion/forgediscussion/controllers/forum.py
+++ b/ForgeDiscussion/forgediscussion/controllers/forum.py
@@ -16,7 +16,10 @@
 #       under the License.
 
 import logging
+import re
+
 import pymongo
+from allura.lib.search import mapped_artifacts_from_index_ids
 
 from tg import expose, validate, redirect
 from tg import request
@@ -116,7 +119,6 @@ class ForumController(DiscussionController):
             limit=limit,
             page=page)
 
-
     @expose('jinja:forgediscussion:templates/discussionforums/deleted.html')
     def deleted(self):
         return dict()
@@ -127,8 +129,28 @@ class ForumController(DiscussionController):
     def subscribe_to_forum(self, subscribe=None, unsubscribe=None, shortname=None, **kw):
         if subscribe:
             self.discussion.subscribe(type='direct')
+
+            # unsubscribe from all individual threads that are part of this forum, so you
don't have overlapping subscriptions
+            forumthread_index_prefix = (DM.ForumThread.__module__ + '.' + DM.ForumThread.__name__).replace('.',
'/') + '#'
+            thread_mboxes = M.Mailbox.query.find(dict(
+                user_id=c.user._id,
+                project_id=c.project._id,
+                app_config_id=c.app.config._id,
+                artifact_index_id=re.compile('^' + re.escape(forumthread_index_prefix)),
+            )).all()
+            # get the ForumThread objects from the subscriptions
+            thread_index_ids = [mbox.artifact_index_id for mbox in thread_mboxes]
+            threads_by_id = mapped_artifacts_from_index_ids(thread_index_ids, DM.ForumThread,
objectid_id=False)
+            for mbox in thread_mboxes:
+                thread_id = mbox.artifact_index_id.split('#')[1]
+                thread = threads_by_id[thread_id]
+                # only delete if the ForumThread is part of this forum
+                if thread.discussion_id == self.discussion._id:
+                    mbox.delete()
+
         elif unsubscribe:
             self.discussion.unsubscribe()
+
         return {
             'status': 'ok',
             'subscribed': M.Mailbox.subscribed(artifact=self.discussion),

http://git-wip-us.apache.org/repos/asf/allura/blob/dec2ab0b/requirements.txt
----------------------------------------------------------------------
diff --git a/requirements.txt b/requirements.txt
index 30f99f3..1d8dffd 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -21,7 +21,7 @@ httplib2==0.7.4
 iso8601==0.1.4
 Jinja2==2.8
 Markdown==2.2.0
-Ming==0.5.4
+Ming==0.5.5
 oauth2==1.5.170
 # tg2 dep PasteDeploy must specified before TurboGears2, to avoid a version/allow-hosts problem
 Paste==1.7.5.1


Mime
View raw message