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 2020/05/05 20:26:04 UTC

[allura] branch db/8360 created (now 054887d)

This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch db/8360
in repository https://gitbox.apache.org/repos/asf/allura.git.


      at 054887d  [#8360] ignore hidden dirs like .tox when running syntax checks

This branch includes the following new commits:

     new 769c5c1  [#8360] faster App.installable checks without instantiating apps, don't do query when ChatChannel app is instantiated
     new 9ef97f7  [#8360] track more in timermiddleware
     new a679f38  [#8360] optimize nav calls for admins
     new b399eca  [#8360] avoid many sequential app_config lookups
     new dc2e275  [#8360] some minor short-circuiting speedups
     new a031841  [#8360] only do /users ajax call when needed (for user mentions in markdown)
     new a5d76cc  [#8360] provide option to have icons hosted through a CDN
     new 054887d  [#8360] ignore hidden dirs like .tox when running syntax checks

The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[allura] 06/08: [#8360] only do /users ajax call when needed (for user mentions in markdown)

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8360
in repository https://gitbox.apache.org/repos/asf/allura.git

commit a0318410cdf5ac9ac6d7c0d76847184e40202966
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Tue May 5 12:11:21 2020 -0400

    [#8360] only do /users ajax call when needed (for user mentions in markdown)
---
 Allura/allura/ext/admin/admin_main.py                    |  2 --
 Allura/allura/lib/widgets/form_fields.py                 |  1 +
 .../lib/widgets/resources/js/usermentions-helper.js      | 16 +++++++++-------
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index 5fa4b65..3930a94 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -61,7 +61,6 @@ log = logging.getLogger(__name__)
 
 
 class W:
-    markdown_editor = ffw.MarkdownEdit()
     label_edit = ffw.LabelEdit()
     group_card = aw.GroupCard()
     permission_card = aw.PermissionCard()
@@ -223,7 +222,6 @@ class ProjectAdminController(BaseController):
     @without_trailing_slash
     @expose('jinja:allura.ext.admin:templates/project_overview.html')
     def overview(self, **kw):
-        c.markdown_editor = W.markdown_editor
         c.metadata_admin = W.metadata_admin
         # need this because features field expects data in specific format
         metadata_admin_value = h.fixed_attrs_proxy(
diff --git a/Allura/allura/lib/widgets/form_fields.py b/Allura/allura/lib/widgets/form_fields.py
index 4e69621..e02d6b8 100644
--- a/Allura/allura/lib/widgets/form_fields.py
+++ b/Allura/allura/lib/widgets/form_fields.py
@@ -291,6 +291,7 @@ class MarkdownEdit(ew.TextArea):
         yield ew.JSLink('js/usermentions-helper.js')
         yield onready('getProjectUsers(\'%s/users\')' % c.project.url())
 
+
 class PageList(ew_core.Widget):
     template = 'jinja:allura:templates/widgets/page_list.html'
     defaults = dict(
diff --git a/Allura/allura/lib/widgets/resources/js/usermentions-helper.js b/Allura/allura/lib/widgets/resources/js/usermentions-helper.js
index d1d0ea8..ce200ab 100644
--- a/Allura/allura/lib/widgets/resources/js/usermentions-helper.js
+++ b/Allura/allura/lib/widgets/resources/js/usermentions-helper.js
@@ -20,14 +20,16 @@
 var userMentionList;
 
 var getProjectUsers = function(users_url) {
-    $.get(users_url, function(data) {
-        userMentionList = data.options.map(function(item) {
-            return {
-                text: item.value,
-                displayText: item.label
-            };
+    if ($('.markdown_edit').length) {  // only do ajax call if really needed (the MarkdownEdit widget's resources can end up on many pages even if template doesn't expose edit forms)
+        $.get(users_url, function (data) {
+            userMentionList = data.options.map(function (item) {
+                return {
+                    text: item.value,
+                    displayText: item.label
+                };
+            });
         });
-    });
+    }
 }
 
 CodeMirror.registerHelper('hint', 'alluraUserMentions', function (editor) {


[allura] 05/08: [#8360] some minor short-circuiting speedups

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8360
in repository https://gitbox.apache.org/repos/asf/allura.git

commit dc2e27545f34970c0525e0abca391e2251856f85
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Mon May 4 18:40:23 2020 -0400

    [#8360] some minor short-circuiting speedups
---
 Allura/allura/lib/helpers.py        | 2 +-
 Allura/allura/model/neighborhood.py | 2 +-
 Allura/allura/model/notification.py | 3 +++
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index f51cc96..4007ed2 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -646,7 +646,7 @@ def pop_user_notifications(user=None):
     if user is None:
         user = c.user
     mbox = M.Mailbox.query.get(user_id=user._id, is_flash=True)
-    if mbox:
+    if mbox and mbox.queue:
         notifications = M.Notification.query.find(
             dict(_id={'$in': mbox.queue}))
         mbox.queue = []
diff --git a/Allura/allura/model/neighborhood.py b/Allura/allura/model/neighborhood.py
index 6a08117..74c18ac 100644
--- a/Allura/allura/model/neighborhood.py
+++ b/Allura/allura/model/neighborhood.py
@@ -164,7 +164,7 @@ class Neighborhood(MappedClass):
         return (self.neighborhood_project
                     .app_config_by_tool_type('home') is not None)
 
-    @property
+    @LazyProperty
     def icon(self):
         # New icon storage uses the neighborhood_project object, so Project.icon* methods can be shared
         if self.neighborhood_project.get_tool_data('allura', 'icon_original_size'):
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index 4a2cded..1b8ee27 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -625,6 +625,9 @@ class Mailbox(MappedClass):
         '''
         Send all notifications that this mailbox has enqueued.
         '''
+        if len(self.queue) == 0:
+            return
+
         notifications = Notification.query.find(dict(_id={'$in': self.queue}))
         notifications = notifications.all()
         if len(notifications) != len(self.queue):


[allura] 02/08: [#8360] track more in timermiddleware

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8360
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 9ef97f753c7fa65553eb5293d00ed9820a393360
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Mon May 4 17:35:36 2020 -0400

    [#8360] track more in timermiddleware
---
 Allura/allura/lib/custom_middleware.py | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/Allura/allura/lib/custom_middleware.py b/Allura/allura/lib/custom_middleware.py
index fab0520..1b21f92 100644
--- a/Allura/allura/lib/custom_middleware.py
+++ b/Allura/allura/lib/custom_middleware.py
@@ -33,6 +33,7 @@ import pysolr
 import six
 
 from allura.lib import helpers as h
+from allura import model as M
 import allura.model.repository
 from six.moves import range
 
@@ -308,6 +309,7 @@ class AlluraTimerMiddleware(TimerMiddleware):
         import activitystream
         import pygments
         import difflib
+        import requests
 
         timers = self.entry_point_timers() + [
             Timer(
@@ -320,6 +322,7 @@ class AlluraTimerMiddleware(TimerMiddleware):
             Timer('activitystream.activity_manager.{method_name}',
                   activitystream.managers.ActivityManager, '*'),
             Timer('jinja', jinja2.Template, 'render', 'stream', 'generate'),
+            Timer('jinja.compile', jinja2.Environment, 'compile'),
             Timer('markdown', markdown.Markdown, 'convert'),
             Timer('ming', ming.odm.odmsession.ODMCursor, 'next',  # FIXME: this may captures timings ok, but is misleading for counts
                   debug_each_call=False),
@@ -351,10 +354,13 @@ class AlluraTimerMiddleware(TimerMiddleware):
                   'flush', debug_each_call=False),
             Timer('solr', pysolr.Solr, 'add', 'delete', 'search', 'commit'),
             Timer('urlopen', urlopen_pkg, 'urlopen'),
+            Timer('requests.get', requests, 'get'),
             Timer('base_repo_tool.{method_name}',
                   allura.model.repository.RepositoryImplementation, 'last_commit_ids'),
             Timer('pygments', pygments, 'highlight'),  # often called from within a template so will overlap w/ jinja
             Timer('difflib', difflib, '_mdiff', 'unified_diff'),
+            Timer('logging', logging.Logger, '_log', debug_each_call=False),
+            Timer('navbar', M.Project, 'nav_data', 'grouped_navbar_entries'),
         ] + [Timer('sidebar', ep.load(), 'sidebar_menu') for ep in tool_entry_points]
 
         try:
@@ -368,6 +374,13 @@ class AlluraTimerMiddleware(TimerMiddleware):
                       'bind_s', 'unbind_s', 'add_s', 'modify_s', 'search_s'),
             ]
 
+        if self.config.get('memcached_host'):
+            import pylibmc
+            timers += [
+                Timer('memcache.get', pylibmc.client.Client, 'get'),
+                Timer('memcache.set', pylibmc.client.Client, 'set'),
+            ]
+
         return timers
 
     def before_logging(self, stat_record):


[allura] 07/08: [#8360] provide option to have icons hosted through a CDN

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8360
in repository https://gitbox.apache.org/repos/asf/allura.git

commit a5d76ccae0057964539071f13f1efad10e29aced
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Tue May 5 16:25:26 2020 -0400

    [#8360] provide option to have icons hosted through a CDN
---
 Allura/allura/lib/widgets/project_list.py     |  2 +-
 Allura/allura/model/auth.py                   |  2 +-
 Allura/allura/model/project.py                |  6 +++++-
 Allura/allura/templates/jinja_master/lib.html |  2 +-
 Allura/allura/tests/unit/test_project.py      | 13 +++++++++++++
 Allura/development.ini                        |  3 ++-
 6 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/Allura/allura/lib/widgets/project_list.py b/Allura/allura/lib/widgets/project_list.py
index 1c53cf0..c3a38e7 100644
--- a/Allura/allura/lib/widgets/project_list.py
+++ b/Allura/allura/lib/widgets/project_list.py
@@ -48,7 +48,7 @@ class ProjectSummary(ew_core.Widget):
 
         if response['icon_url'] is None:
             if value.icon:
-                response['icon_url'] = value.url() + 'icon'
+                response['icon_url'] = value.icon_url()
         if response['accolades'] is None:
             response['accolades'] = value.accolades
 
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index cdb90ab..c8b3cd8 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -618,7 +618,7 @@ class User(MappedClass, ActivityNode, ActivityObject, SearchIndexable):
             private_project = None
         icon_source = None
         if private_project and private_project.icon:
-            icon_url = self.url() + 'user_icon'
+            icon_url = config.get('static.icon_base', '') + self.url() + 'user_icon'
             icon_source = 'local'
         elif self.preferences.email_address:
             gravatar_args = {}
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index bf884db..5c8ca1b 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -354,6 +354,10 @@ class Project(SearchIndexable, MappedClass, ActivityNode, ActivityObject):
         else:
             return url
 
+    def icon_url(self):
+        icon_url = config.get('static.icon_base', '') + self.url() + 'icon'
+        return icon_url
+
     def best_download_url(self):
         provider = plugin.ProjectRegistrationProvider.get()
         return provider.best_download_url(self)
@@ -484,7 +488,7 @@ class Project(SearchIndexable, MappedClass, ActivityNode, ActivityObject):
         for icon in ProjectFile.query.find(dict(
                 project_id={'$in': list(result.keys())},
                 category='icon')):
-            result[icon.project_id] = project_index[icon.project_id].url() + 'icon'
+            result[icon.project_id] = project_index[icon.project_id].icon_url()
         return result
 
     @classmethod
diff --git a/Allura/allura/templates/jinja_master/lib.html b/Allura/allura/templates/jinja_master/lib.html
index 3c19984..a0a3c67 100644
--- a/Allura/allura/templates/jinja_master/lib.html
+++ b/Allura/allura/templates/jinja_master/lib.html
@@ -215,7 +215,7 @@
  icon_url param is entirely optional; only pass it if you already have one for effeciency
 #}
 {%- macro project_icon_srcs(project, icon_url=None, base_size=48) %}
-    {% set icon_url = icon_url or project.url() + 'icon' %}
+    {% set icon_url = icon_url or project.icon_url() %}
     {% set proj_max_size = project.icon_max_size or 0 %}
     src="{{icon_url}}?{{project.icon_timestamp}}{% if base_size != 48 and proj_max_size >= base_size %}&amp;w={{base_size}}{% endif %}"
     {% if proj_max_size >= base_size*1.5 -%}
diff --git a/Allura/allura/tests/unit/test_project.py b/Allura/allura/tests/unit/test_project.py
index d2b66b7..6fb0bc0 100644
--- a/Allura/allura/tests/unit/test_project.py
+++ b/Allura/allura/tests/unit/test_project.py
@@ -20,7 +20,10 @@ from __future__ import absolute_import
 import unittest
 from mock import Mock
 
+from tg import config
+
 from allura import model as M
+from allura.lib import helpers as h
 from allura.app import SitemapEntry
 
 
@@ -101,3 +104,13 @@ class TestProject(unittest.TestCase):
         old = {'last_updated': 1, 'a': 1}
         new = {'last_updated': 2, 'a': 2}
         self.assertTrue(p.should_update_index(old, new))
+
+    def test_icon_url(self):
+        p = M.Project(
+            shortname='myproj',
+            neighborhood = M.Neighborhood(url_prefix='/nbhd/'),
+        )
+        self.assertEqual(p.icon_url(), '/nbhd/myproj/icon')
+
+        with h.push_config(config, **{'static.icon_base': 'https://mycdn.com/mysite'}):
+            self.assertEqual(p.icon_url(), 'https://mycdn.com/mysite/nbhd/myproj/icon')
diff --git a/Allura/development.ini b/Allura/development.ini
index 488c82a..6bc5cf1 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -325,11 +325,12 @@ webhook.repo_push.max_hooks = {"git": 3, "hg": 3, "svn": 3}
 ; Set the locations of some static resources.  ("ew" stands for EasyWidgets library)
 ;  script_name is the path that is handled by the application
 ;  url_base is the prefix that references to the static resources should have
-; If you use a CDN, put your CDN prefix in the url_base values
+; If you use a CDN, put your CDN prefix in the url_base values and icon_base value
 ew.script_name = /nf/%(build_key)s/_ew_/
 ew.url_base = /nf/%(build_key)s/_ew_/
 static.script_name = /nf/%(build_key)s/_static_/
 static.url_base = /nf/%(build_key)s/_static_/
+; static.icon_base = https://some.cdn/path
 
 ; Expires header for "static" resources served through allura (e.g. icons, attachments, /nf/tool_icon_css)
 ; 2 weeks:


[allura] 08/08: [#8360] ignore hidden dirs like .tox when running syntax checks

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8360
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 054887d315897913493c3d9e085be0898ba49625
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Tue May 5 11:36:05 2020 -0400

    [#8360] ignore hidden dirs like .tox when running syntax checks
---
 AlluraTest/alluratest/test_syntax.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/AlluraTest/alluratest/test_syntax.py b/AlluraTest/alluratest/test_syntax.py
index af48ae0..856f47a 100644
--- a/AlluraTest/alluratest/test_syntax.py
+++ b/AlluraTest/alluratest/test_syntax.py
@@ -36,7 +36,7 @@ def run(cmd):
     return proc.returncode
 
 
-find_py = "find Allura Forge* -name '*.py'"
+find_py = r"find Allura Forge* -not -path '*/\.*' -name '*.py'"
 
 
 # a recipe from itertools doc


[allura] 03/08: [#8360] optimize nav calls for admins

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8360
in repository https://gitbox.apache.org/repos/asf/allura.git

commit a679f382e313524e5455c4aec332112e17f44e70
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Mon May 4 17:35:47 2020 -0400

    [#8360] optimize nav calls for admins
---
 Allura/allura/model/project.py                              | 13 +++++++++++--
 Allura/allura/templates/jinja_master/top_nav.html           |  5 +++--
 .../allura/templates_responsive/jinja_master/top_nav.html   |  5 +++--
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 2a6c8ff..d40313e 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -622,7 +622,14 @@ class Project(SearchIndexable, MappedClass, ActivityNode, ActivityObject):
                 i += 1
         return new_tools
 
-    def nav_data(self, admin_options=False):
+    def nav_data(self, admin_options=False, navbar_entries=None):
+        """
+        Return data about project nav entries
+
+        :param bool admin_options: include admin options?
+        :param navbar_entries: for performance, include this if you already have grouped_navbar_entries data
+        :return:
+        """
         from allura.ext.admin.admin_main import ProjectAdminRestController
 
         grouping_threshold = self.get_tool_data('allura', 'grouping_threshold', 1)
@@ -646,7 +653,9 @@ class Project(SearchIndexable, MappedClass, ActivityNode, ActivityObject):
                 entry['admin_options'] = [dict(text='Subproject Admin', href=s.url + 'admin', className=None)]
             return entry
 
-        for s in self.grouped_navbar_entries():
+        if navbar_entries is None:
+            navbar_entries = self.grouped_navbar_entries()
+        for s in navbar_entries:
             entry = make_entry(s)
             if s.children:
                 entry['children'] = [make_entry(child) for child in s.children]
diff --git a/Allura/allura/templates/jinja_master/top_nav.html b/Allura/allura/templates/jinja_master/top_nav.html
index ac3727d..6b5a43e 100644
--- a/Allura/allura/templates/jinja_master/top_nav.html
+++ b/Allura/allura/templates/jinja_master/top_nav.html
@@ -19,7 +19,8 @@
 {% if c.project %}
 <div id="top_nav_admin">
 <ul class="dropdown">
-  {% for s in c.project.grouped_navbar_entries() %}
+  {% set navbar_entries = c.project.grouped_navbar_entries() %}
+  {% for s in navbar_entries %}
     <li class="{% if s.matches_url(request) %}selected{% endif %}">
         <a href="{{s.url}}" class="tool-{{(s.tool_name or 'admin').lower()}}-32" {{ s.extra_html_attrs|xmlattr }}>
             {{s.label}}
@@ -52,7 +53,7 @@
     <script>
         'use strict';
         /*global ReactDOM, React, Main, ToggleAddNewTool */
-        var _data = {{ h.escape_json(c.project.nav_data(admin_options=True))|safe }};
+        var _data = {{ h.escape_json(c.project.nav_data(admin_options=True, navbar_entries=navbar_entries))|safe }};
         $(document).ready(function () {
             $('#toggle-admin-btn').click(function () {
                 if (typeof Main === 'undefined') {
diff --git a/Allura/allura/templates_responsive/jinja_master/top_nav.html b/Allura/allura/templates_responsive/jinja_master/top_nav.html
index a0373a9..b010df1 100644
--- a/Allura/allura/templates_responsive/jinja_master/top_nav.html
+++ b/Allura/allura/templates_responsive/jinja_master/top_nav.html
@@ -19,7 +19,8 @@
 {% if c.project %}
 <div id="top_nav_admin" class="row">
 <ul class="menu dropdown" data-dropdown-menu>
-  {% for s in c.project.grouped_navbar_entries() %}
+  {% set navbar_entries = c.project.grouped_navbar_entries() %}
+  {% for s in navbar_entries %}
     <li class="{% if s.matches_url(request) %}selected{% endif %}">
         <a href="{{s.url}}" class="tool-{{(s.tool_name or 'admin').lower()}}-32">
             {{s.label}}
@@ -52,7 +53,7 @@
     <script>
         'use strict';
         /*global ReactDOM, React, Main, ToggleAddNewTool */
-        var _data = {{ h.escape_json(c.project.nav_data(admin_options=True))|safe }};
+        var _data = {{ h.escape_json(c.project.nav_data(admin_options=True, navbar_entries=navbar_entries))|safe }};
         $(document).ready(function () {
             $('#toggle-admin-btn').click(function () {
                 if (typeof Main === 'undefined') {


[allura] 01/08: [#8360] faster App.installable checks without instantiating apps, don't do query when ChatChannel app is instantiated

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8360
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 769c5c159192b3a35cb8b839002e0c678f0d4fad
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Mon May 4 17:28:12 2020 -0400

    [#8360] faster App.installable checks without instantiating apps, don't do query when ChatChannel app is instantiated
---
 Allura/allura/app.py                  | 2 ++
 Allura/allura/ext/admin/admin_main.py | 3 +--
 ForgeChat/forgechat/main.py           | 6 +++++-
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index c206c3b..a631fb7 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -413,6 +413,8 @@ class Application(object):
 
     @classmethod
     def _installable(cls, tool_name, nbhd, project_tools):
+        if cls.installable is False:  # handle class level `installable = False` declarations
+            return False
         if tool_name.lower() in nbhd.get_prohibited_tools():
             return False
         tools_list = [tool.tool_name.lower() for tool in project_tools]
diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index 8505439..5f96184 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -107,8 +107,7 @@ class AdminApp(Application):
         tools = []
         for name, App in six.iteritems(g.entry_points['tool']):
             cfg = M.AppConfig(project_id=project._id, tool_name=name)
-            app = App(project, cfg)
-            if app.installable:
+            if App._installable(name, project.neighborhood, project.app_configs):
                 tools.append(dict(name=name, app=App))
             # prevent from saving temporary config to db
             session(cfg).expunge(cfg)
diff --git a/ForgeChat/forgechat/main.py b/ForgeChat/forgechat/main.py
index 4c7a43c..8742489 100644
--- a/ForgeChat/forgechat/main.py
+++ b/ForgeChat/forgechat/main.py
@@ -28,6 +28,7 @@ from tg import expose, validate, redirect, flash
 from tg.decorators import with_trailing_slash
 from tg import tmpl_context as c, request
 from formencode import validators
+from ming.utils import LazyProperty
 
 # Pyforge-specific imports
 from allura.app import Application, ConfigOption, SitemapEntry, DefaultAdminController
@@ -71,10 +72,13 @@ class ForgeChatApp(Application):
 
     def __init__(self, project, config):
         Application.__init__(self, project, config)
-        self.channel = CM.ChatChannel.query.get(app_config_id=config._id)
         self.root = RootController()
         self.admin = AdminController(self)
 
+    @LazyProperty
+    def channel(self):
+        return CM.ChatChannel.query.get(app_config_id=self.config._id)
+
     def main_menu(self):
         return [SitemapEntry(self.config.options.mount_label, '.')]
 


[allura] 04/08: [#8360] avoid many sequential app_config lookups

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch db/8360
in repository https://gitbox.apache.org/repos/asf/allura.git

commit b399ecadfe89f9cf206d8c33c3c7cc31da6879c8
Author: Dave Brondsema <da...@brondsema.net>
AuthorDate: Mon May 4 18:40:02 2020 -0400

    [#8360] avoid many sequential app_config lookups
---
 Allura/allura/ext/admin/admin_main.py |  2 ++
 Allura/allura/model/project.py        | 12 +++++++-----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index 5f96184..5fa4b65 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -818,6 +818,8 @@ class ProjectAdminRestController(BaseController):
     def admin_options(self, mount_point=None, **kw):
         """
         Returns the admin options for a given mount_point
+
+        :type mount_point: str|allura.model.project.AppConfig
         """
 
         if not mount_point:
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index d40313e..bf884db 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -636,7 +636,7 @@ class Project(SearchIndexable, MappedClass, ActivityNode, ActivityObject):
         anchored_tools = self.neighborhood.get_anchored_tools()
         children = []
 
-        def make_entry(s):
+        def make_entry(s, app_config):
             entry = dict(name=s.label,
                          url=s.url,
                          icon=s.ui_icon or 'tool-admin',
@@ -644,9 +644,9 @@ class Project(SearchIndexable, MappedClass, ActivityNode, ActivityObject):
                          mount_point=s.mount_point,
                          is_anchored=s.tool_name in list(anchored_tools.keys()),
                          )
-            if admin_options and s.tool_name and s.mount_point:
+            if admin_options and app_config:
                 try:
-                    entry['admin_options'] = ProjectAdminRestController().admin_options(s.mount_point)['options']
+                    entry['admin_options'] = ProjectAdminRestController().admin_options(app_config)['options']
                 except exc.HTTPError:
                     log.debug('Could not get admin_options mount_point for tool: %s', s.url, exc_info=True)
             if admin_options and not s.tool_name:
@@ -655,10 +655,12 @@ class Project(SearchIndexable, MappedClass, ActivityNode, ActivityObject):
 
         if navbar_entries is None:
             navbar_entries = self.grouped_navbar_entries()
+        tools_by_mount = {ac.options.mount_point: ac for ac in self.app_configs if ac.options.mount_point}
         for s in navbar_entries:
-            entry = make_entry(s)
+            entry = make_entry(s, tools_by_mount.get(s.mount_point))
             if s.children:
-                entry['children'] = [make_entry(child) for child in s.children]
+                entry['children'] = [make_entry(child, tools_by_mount.get(child.mount_point))
+                                     for child in s.children]
             children.append(entry)
 
         response = dict(grouping_threshold=grouping_threshold, menu=children)