You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2013/12/20 19:50:31 UTC

[05/36] git commit: [#5502] ticket:462 Prevent adding tools multiple times

[#5502] ticket:462 Prevent adding tools multiple times

  Added max_instances attribute which specifies the maximum number of
tools of this type can be added to the project


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

Branch: refs/heads/db/6388
Commit: b22c02bce86189bdd8d7816862f97e82e4f7f975
Parents: 56590d4
Author: Andriy Sherepa <as...@gmail.com>
Authored: Wed Nov 20 15:12:06 2013 +0200
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Dec 18 20:38:57 2013 +0000

----------------------------------------------------------------------
 Allura/allura/app.py                            | 12 ++++++++--
 Allura/allura/ext/admin/admin_main.py           | 25 +++++++++++++-------
 Allura/allura/ext/project_home/project_main.py  |  1 -
 Allura/allura/ext/search/search_main.py         |  1 -
 Allura/allura/ext/user_profile/user_main.py     |  1 -
 .../widgets/neighborhood_add_project.html       |  2 ++
 ForgeActivity/forgeactivity/main.py             |  1 -
 ForgeBlog/forgeblog/main.py                     |  2 +-
 ForgeChat/forgechat/main.py                     |  2 +-
 ForgeDiscussion/forgediscussion/forum_main.py   |  2 +-
 ForgeGit/forgegit/git_main.py                   |  1 +
 ForgeLink/forgelink/link_main.py                |  1 +
 ForgeSVN/forgesvn/svn_main.py                   |  1 +
 ForgeShortUrl/forgeshorturl/main.py             |  1 -
 ForgeTracker/forgetracker/tracker_main.py       |  1 +
 ForgeUserStats/forgeuserstats/main.py           |  1 -
 ForgeWiki/forgewiki/wiki_main.py                |  1 +
 17 files changed, 37 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/Allura/allura/app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index 0fa7556..21f8434 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -224,7 +224,7 @@ class Application(object):
         'configure': 'Set label and options. Requires admin permission.',
         'admin': 'Set permissions.',
     }
-    installable = True
+    max_instances = 0
     searchable = False
     exportable = False
     DiscussionClass = model.Discussion
@@ -321,6 +321,14 @@ class Application(object):
         """
         return self.config.parent_security_context()
 
+    @property
+    def installable(self):
+        """Return list of app what can be installed.
+
+        """
+        tools_list = [tool.tool_name.lower() for tool in self.project.app_configs]
+        return tools_list.count(self.tool_label.lower()) < self.max_instances
+
     @classmethod
     def validate_mount_point(cls, mount_point):
         """Check if ``mount_point`` is valid for this Application.
@@ -475,7 +483,7 @@ class Application(object):
         not be installed directly by a user, but may be uninstalled).
 
         """
-        return self.installable
+        return self.max_instances > 0
 
     def main_menu(self):
         """Return a list of :class:`SitemapEntries <allura.app.SitemapEntry>`

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/Allura/allura/ext/admin/admin_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index 88eb0cc..314510f 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -75,8 +75,8 @@ class AdminApp(Application):
     a functioning allura project.
     '''
     __version__ = version.__version__
-    installable=False
     _installable_tools = None
+    max_instances = 0
     tool_label = 'admin'
     icons={
         24:'images/admin_24.png',
@@ -100,12 +100,22 @@ class AdminApp(Application):
     @staticmethod
     def installable_tools_for(project):
         cls = AdminApp
-        if cls._installable_tools is None:
-            tools = [dict(name=k, app=v) for k,v in g.entry_points['tool'].iteritems()]
-            tools.sort(key=lambda t:(t['app'].status_int(), t['app'].ordinal))
-            cls._installable_tools = [ t for t in tools if t['app'].installable ]
-        return [ t for t in cls._installable_tools
-            if t['app'].status in project.allowed_tool_status ]
+
+        limited_tools = []
+        for tool in project.app_configs:
+            if not project.app_instance(tool).installable:
+                if tool.tool_name not in limited_tools:
+                    limited_tools.append(tool.tool_name)
+
+        tools = []
+        for k, v in g.entry_points['tool'].iteritems():
+            if k not in limited_tools and v.max_instances > 0:
+                tools.append(dict(name=k, app=v))
+        tools.sort(key=lambda t: (t['app'].status_int(), t['app'].ordinal))
+        cls._installable_tools = [t for t in tools]
+        return [t for t in cls._installable_tools
+            if t['app'].status in project.allowed_tool_status]
+
 
     @staticmethod
     def exportable_tools_for(project):
@@ -759,7 +769,6 @@ class ProjectAdminRestController(BaseController):
             return {'success': False,
                     'info': 'All arguments required.'
                     }
-
         installable_tools = AdminApp.installable_tools_for(c.project)
         tools_names = [t['name'] for t in installable_tools]
         if not tool in tools_names:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/Allura/allura/ext/project_home/project_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/project_home/project_main.py b/Allura/allura/ext/project_home/project_main.py
index e2e9b94..d04e234 100644
--- a/Allura/allura/ext/project_home/project_main.py
+++ b/Allura/allura/ext/project_home/project_main.py
@@ -34,7 +34,6 @@ log = logging.getLogger(__name__)
 
 class ProjectHomeApp(Application):
     __version__ = version.__version__
-    installable = False
     tool_label = 'home'
     default_mount_label='Project Home'
     icons={

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/Allura/allura/ext/search/search_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/search/search_main.py b/Allura/allura/ext/search/search_main.py
index b543e62..de38b80 100644
--- a/Allura/allura/ext/search/search_main.py
+++ b/Allura/allura/ext/search/search_main.py
@@ -36,7 +36,6 @@ class SearchApp(Application):
     all the rich, creamy goodness that is installable apps.
     '''
     __version__ = version.__version__
-    installable = False
     hidden = True
     sitemap=[]
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/Allura/allura/ext/user_profile/user_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/user_main.py b/Allura/allura/ext/user_profile/user_main.py
index 793dbf5..4ea734b 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -47,7 +47,6 @@ class F(object):
 
 class UserProfileApp(Application):
     __version__ = version.__version__
-    installable = False
     tool_label = 'Profile'
     icons={
         24:'images/home_24.png',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/Allura/allura/templates/widgets/neighborhood_add_project.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/neighborhood_add_project.html b/Allura/allura/templates/widgets/neighborhood_add_project.html
index 002b8e4..bf46d32 100644
--- a/Allura/allura/templates/widgets/neighborhood_add_project.html
+++ b/Allura/allura/templates/widgets/neighborhood_add_project.html
@@ -50,6 +50,7 @@
     {% if not neighborhood.project_template %}
     {% for opt in widget.fields.tools.options %}
         {% set tool = g.entry_points["tool"][opt.html_value] %}
+        {% if tool.max_instances > 0 %}
         <div class="tool">
             <img src="{{ g.theme.app_icon_url(tool, 48) }}" alt="{{ opt.label }} icon">
             <input checked type="checkbox" value="{{ opt.html_value }}"
@@ -58,6 +59,7 @@
             <h1><label for="{{ widget.context_for(widget.fields.tools)['rendered_name'] }}_{{ opt.html_value }}">{{ opt.label }}</label></h1>
             <p>{{ tool.tool_description }}</p>
         </div>
+        {% endif %}
     {% endfor %}
     {% endif %}
     {% if h.has_access(neighborhood, 'admin') and not neighborhood.project_template and neighborhood.features['private_projects'] %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/ForgeActivity/forgeactivity/main.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/main.py b/ForgeActivity/forgeactivity/main.py
index 87c7557..2e355b9 100644
--- a/ForgeActivity/forgeactivity/main.py
+++ b/ForgeActivity/forgeactivity/main.py
@@ -41,7 +41,6 @@ class ForgeActivityApp(Application):
     """Project Activity page for projects."""
     __version__ = version.__version__
     default_mount_point = 'activity'
-    installable = False
     searchable = False
 
     def __init__(self, project, config):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 0e408b5..775c78e 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -90,7 +90,7 @@ class ForgeBlogApp(Application):
         'admin': 'Set permissions. Enable/disable commenting.',
     }
     ordinal=14
-    installable=True
+    max_instances = 1
     exportable = True
     config_options = Application.config_options
     default_external_feeds = []

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/ForgeChat/forgechat/main.py
----------------------------------------------------------------------
diff --git a/ForgeChat/forgechat/main.py b/ForgeChat/forgechat/main.py
index 202e01d..4c34bd0 100644
--- a/ForgeChat/forgechat/main.py
+++ b/ForgeChat/forgechat/main.py
@@ -50,7 +50,7 @@ class ForgeChatApp(Application):
     default_mount_label='Chat'
     default_mount_point='chat'
     ordinal=13
-    installable = True
+    max_instances = 1
     permissions = ['configure', 'read' ]
     permissions_desc = {
         'configure': 'Set monitored IRC channel. Requires admin permission.',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/ForgeDiscussion/forgediscussion/forum_main.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py
index 2145037..9332215 100644
--- a/ForgeDiscussion/forgediscussion/forum_main.py
+++ b/ForgeDiscussion/forgediscussion/forum_main.py
@@ -54,7 +54,7 @@ class W:
 
 class ForgeDiscussionApp(Application):
     __version__ = version.__version__
-    #installable=False
+    max_instances = 1
     permissions = ['configure', 'read', 'unmoderated_post', 'post', 'moderate', 'admin']
     permissions_desc = {
         'configure': 'Create new forums.',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/ForgeGit/forgegit/git_main.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/git_main.py b/ForgeGit/forgegit/git_main.py
index 1d11e41..12c3578 100644
--- a/ForgeGit/forgegit/git_main.py
+++ b/ForgeGit/forgegit/git_main.py
@@ -51,6 +51,7 @@ class ForgeGitApp(RepositoryApp):
         handle everything from small to very large projects with speed
         and efficiency.
     """
+    max_instances = 1
     ordinal=2
     forkable=True
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/ForgeLink/forgelink/link_main.py
----------------------------------------------------------------------
diff --git a/ForgeLink/forgelink/link_main.py b/ForgeLink/forgelink/link_main.py
index d37db1b..f9d636e 100644
--- a/ForgeLink/forgelink/link_main.py
+++ b/ForgeLink/forgelink/link_main.py
@@ -54,6 +54,7 @@ class ForgeLinkApp(Application):
     tool_label='External Link'
     default_mount_label='Link name'
     default_mount_point='link'
+    max_instances = 1
     ordinal=1
     icons={
         24:'images/ext_24.png',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/ForgeSVN/forgesvn/svn_main.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/svn_main.py b/ForgeSVN/forgesvn/svn_main.py
index bee61b3..6581a9c 100644
--- a/ForgeSVN/forgesvn/svn_main.py
+++ b/ForgeSVN/forgesvn/svn_main.py
@@ -59,6 +59,7 @@ class ForgeSVNApp(RepositoryApp):
     tool_description="""
         Enterprise-class centralized version control for the masses.
     """
+    max_instances = 1
     ordinal=4
     forkable=False
     default_branch_name='HEAD'

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/ForgeShortUrl/forgeshorturl/main.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/main.py b/ForgeShortUrl/forgeshorturl/main.py
index 8524cda..2081586 100644
--- a/ForgeShortUrl/forgeshorturl/main.py
+++ b/ForgeShortUrl/forgeshorturl/main.py
@@ -64,7 +64,6 @@ class ForgeShortUrlApp(Application):
     default_mount_point = 'url'
     sitemap = []
     ordinal = 14
-    installable = False
     icons = {
         24: 'images/ext_24.png',
         32: 'images/ext_32.png',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 71f7d64..11493aa 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -210,6 +210,7 @@ class ForgeTrackerApp(Application):
             schema.OneOf('NewTicketsOnly', 'AllTicketChanges',
                 'NewPublicTicketsOnly', 'AllPublicTicketChanges'), None)
         ]
+    max_instances = 1
     exportable = True
     searchable=True
     tool_label='Tickets'

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/ForgeUserStats/forgeuserstats/main.py
----------------------------------------------------------------------
diff --git a/ForgeUserStats/forgeuserstats/main.py b/ForgeUserStats/forgeuserstats/main.py
index b4e4abc..dc56640 100644
--- a/ForgeUserStats/forgeuserstats/main.py
+++ b/ForgeUserStats/forgeuserstats/main.py
@@ -98,7 +98,6 @@ class ForgeUserStatsApp(Application):
         'admin': 'Toggle stats visibility.',
     }
     ordinal=15
-    installable=False
     config_options = Application.config_options
     default_external_feeds = []
     icons={

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b22c02bc/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 55ee9a3..28e104f 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -89,6 +89,7 @@ class ForgeWikiApp(Application):
         'delete': 'Delete wiki pages.',
         'admin': 'Set permissions. Configure options. Set wiki home page.',
     }
+    max_instances = 1
     searchable=True
     exportable=True
     tool_label='Wiki'