You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by jo...@apache.org on 2014/01/23 18:29:43 UTC

[01/28] git commit: [#7006] Removed unnecessary message logic

Updated Branches:
  refs/heads/cj/4257 7196f9a06 -> e276acfa3 (forced update)


[#7006] Removed unnecessary message logic

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: afdf5052374837b43fe78c0db5c14087cbd4ce21
Parents: 9b19981
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jan 20 17:11:04 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Mon Jan 20 17:11:16 2014 +0000

----------------------------------------------------------------------
 Allura/allura/lib/widgets/resources/js/commit_browser.js | 10 ----------
 1 file changed, 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/afdf5052/Allura/allura/lib/widgets/resources/js/commit_browser.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/commit_browser.js b/Allura/allura/lib/widgets/resources/js/commit_browser.js
index 0ba78b7..37c4408 100644
--- a/Allura/allura/lib/widgets/resources/js/commit_browser.js
+++ b/Allura/allura/lib/widgets/resources/js/commit_browser.js
@@ -88,16 +88,6 @@ if($('#commit_graph')){
     highlighter.height = canvas.height;
     highlighter_ctx.fillStyle = "#ccc";
 
-    // Hide error message
-    Modernizr.load([
-      {
-        test: Modernizr.canvas,
-        yep: function() {
-          $('#commit_browser_canvas_message').hide();
-        }
-      }
-    ]);
-
     function setHeight(cnt) {
       /*
        * Set proper canvas height for cnt commits.


[13/28] [#4808] Clean up SourceForge references / values

Posted by jo...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index 0222e5a..d4c8acb 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -260,7 +260,7 @@ class TestRootController(TestController):
                                             Upload the backup of your data files to the project web.
 
                                             ~~~~~
-                                            scp projectname_mediawiki_files.tar.gz USERNAME@web.sourceforge.net:
+                                            scp projectname_mediawiki_files.tar.gz USERNAME@web.domain.net:
                                             ~~~~~
 
                                             In the project web shell, unpack the files to the images directory of you wiki installation. In the backup, the images are in a subfolder *projectname*, so follow these steps:
@@ -295,7 +295,7 @@ class TestRootController(TestController):
                                             Upload the backup of your data files to the project web.
 
                                             ~~~~~
-                                            scp projectname_mediawiki_files.tar.gz USERNAME@web.sourceforge.net:
+                                            scp projectname_mediawiki_files.tar.gz USERNAME@web.domain.net:
                                             ~~~~~
 
                                             In the project web shell, unpack the files to the images directory of you wiki installation. In the backup, the images are in a subfolder *projectname*, so follow these steps:


[22/28] git commit: [#4257] Added PJAX Show More paging with scroll state saving

Posted by jo...@apache.org.
[#4257] Added PJAX Show More paging with scroll state saving

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: df82f2887de3791b8070b12402791a98da454d0c
Parents: 28f74b1
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Sat Jan 18 00:50:38 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:03 2014 +0000

----------------------------------------------------------------------
 Allura/LICENSE                                  |   2 +
 Allura/allura/public/nf/js/jquery.viewport.js   |  58 +++++
 ForgeActivity/forgeactivity/main.py             |   4 +
 .../forgeactivity/nf/activity/css/activity.css  |  10 +
 .../forgeactivity/nf/activity/js/activity.js    | 209 +++++++++++++++++++
 .../forgeactivity/templates/index.html          |  21 +-
 .../forgeactivity/templates/timeline.html       |  35 ++++
 7 files changed, 324 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/Allura/LICENSE
----------------------------------------------------------------------
diff --git a/Allura/LICENSE b/Allura/LICENSE
index 7e0be3d..36c9038 100644
--- a/Allura/LICENSE
+++ b/Allura/LICENSE
@@ -232,6 +232,8 @@ under the MIT license.  For details, see the individual files:
     allura/lib/widgets/resources/js/jquery.tools.min.js
     allura/public/nf/js/jquery.flot.js
     allura/public/nf/js/jquery.maxlength.min.js
+    allura/public/nf/js/jquery.viewport.js
+    allura/public/nf/js/jquery.pjax.js
 
 Blueprint, which is available under the MIT license.
 For details, see allura/public/nf/css/blueprint/

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/Allura/allura/public/nf/js/jquery.viewport.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/jquery.viewport.js b/Allura/allura/public/nf/js/jquery.viewport.js
new file mode 100644
index 0000000..7826000
--- /dev/null
+++ b/Allura/allura/public/nf/js/jquery.viewport.js
@@ -0,0 +1,58 @@
+/*
+ * Viewport - jQuery selectors for finding elements in viewport
+ *
+ * Copyright (c) 2008-2009 Mika Tuupola
+ *
+ * Licensed under the MIT license:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *
+ * Project home:
+ *  http://www.appelsiini.net/projects/viewport
+ *
+ */
+(function($) {
+    
+    $.belowthefold = function(element, settings) {
+        var fold = $(window).height() + $(window).scrollTop();
+        return fold <= $(element).offset().top - settings.threshold;
+    };
+
+    $.abovethetop = function(element, settings) {
+        var top = $(window).scrollTop();
+        return top >= $(element).offset().top + $(element).height() - settings.threshold;
+    };
+    
+    $.rightofscreen = function(element, settings) {
+        var fold = $(window).width() + $(window).scrollLeft();
+        return fold <= $(element).offset().left - settings.threshold;
+    };
+    
+    $.leftofscreen = function(element, settings) {
+        var left = $(window).scrollLeft();
+        return left >= $(element).offset().left + $(element).width() - settings.threshold;
+    };
+    
+    $.inviewport = function(element, settings) {
+        return !$.rightofscreen(element, settings) && !$.leftofscreen(element, settings) && !$.belowthefold(element, settings) && !$.abovethetop(element, settings);
+    };
+    
+    $.extend($.expr[':'], {
+        "below-the-fold": function(a, i, m) {
+            return $.belowthefold(a, {threshold : 0});
+        },
+        "above-the-top": function(a, i, m) {
+            return $.abovethetop(a, {threshold : 0});
+        },
+        "left-of-screen": function(a, i, m) {
+            return $.leftofscreen(a, {threshold : 0});
+        },
+        "right-of-screen": function(a, i, m) {
+            return $.rightofscreen(a, {threshold : 0});
+        },
+        "in-viewport": function(a, i, m) {
+            return $.inviewport(a, {threshold : 0});
+        }
+    });
+
+    
+})(jQuery);

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/ForgeActivity/forgeactivity/main.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/main.py b/ForgeActivity/forgeactivity/main.py
index 991bb61..09d0c62 100644
--- a/ForgeActivity/forgeactivity/main.py
+++ b/ForgeActivity/forgeactivity/main.py
@@ -119,6 +119,10 @@ class ForgeActivityController(BaseController):
     def index(self, **kw):
         return self._get_activities_data(**kw)
 
+    @expose('jinja:forgeactivity:templates/timeline.html')
+    def pjax(self, **kw):
+        return self._get_activities_data(**kw)
+
     @without_trailing_slash
     @expose()
     def feed(self, **kw):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/ForgeActivity/forgeactivity/nf/activity/css/activity.css
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/nf/activity/css/activity.css b/ForgeActivity/forgeactivity/nf/activity/css/activity.css
index dc71608..66395ff 100644
--- a/ForgeActivity/forgeactivity/nf/activity/css/activity.css
+++ b/ForgeActivity/forgeactivity/nf/activity/css/activity.css
@@ -46,3 +46,13 @@
   float: left;
   margin: 10px 10px 0 0;
 }
+.activity .page_list {
+    margin-top: 5px;
+}
+.activity .show-more {
+    display: block;
+    text-align: center;
+}
+.activity .show-more.older {
+    margin-top: 10px;
+}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/ForgeActivity/forgeactivity/nf/activity/js/activity.js
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/nf/activity/js/activity.js b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
new file mode 100644
index 0000000..e8c0346
--- /dev/null
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -0,0 +1,209 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+ActivityBrowseOptions = {
+    maintainScrollState: true,
+    usePjax: true,
+    useHash: true,
+    forceAdvancedScroll: false,
+    useShowMore: true,
+    useInfiniteScroll: false
+}
+
+$(function() {
+    var hasAPI = window.history && window.history.pushState && window.history.replaceState;
+    var iOS4 = navigator.userAgent.match(/iP(od|one|ad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork/);
+    if (!hasAPI || iOS4) {
+        ActivityBrowseOptions.usePjax = false;
+    }
+    if (!ActivityBrowseOptions.usePjax) {
+        if (!ActivityBrowseOptions.useHash) {
+            ActivityBrowseOptions.maintainScrollState = false;
+        }
+        if (!ActivityBrowseOptions.forceAdvancedScroll) {
+            ActivityBrowseOptions.useShowMore = false;
+            ActivityBrowseOptions.useInfiniteScroll = false;
+        }
+    }
+
+    var firstVisibleId = null;
+    var oldScrollTop = null;
+    var oldTop = null;
+    function saveScrollPosition() {
+        var $firstVisible = $('.timeline li:in-viewport:first');
+        firstVisibleId = $firstVisible.attr('id');
+        oldScrollTop = $(window).scrollTop();
+        oldTop = $firstVisible.offset().top;
+    }
+    function restoreScrollPosition() {
+        var $window = $(window);
+        var $firstVisible = $('#'+firstVisibleId);
+        if (!$firstVisible.length) {
+            return;
+        }
+        var newTop = $firstVisible.offset().top;
+        var scrollTop = $window.scrollTop();
+        var elemAdjustment = newTop - oldTop;
+        var viewportAdjustment = scrollTop - oldScrollTop;
+        $window.scrollTop(scrollTop + elemAdjustment - viewportAdjustment);
+        //console.log('restoreSP', oldTop, newTop, elemAdjustment, viewportAdjustment, scrollTop, $window.scrollTop());
+        $(window).trigger('scroll');
+    }
+
+    function maintainScrollState_pjax() {
+        var $firstVisibleActivity = $('.timeline li:in-viewport:first');
+        var page = $firstVisibleActivity.data('page');
+        var limit = $('.timeline').data('limit');
+        var hash = $firstVisibleActivity.attr('id');
+        if (page != null && limit != null && hash != null) {
+            history.replaceState(null, null, '?page='+page+'&limit='+limit+'#'+hash);
+        }
+    }
+
+    function maintainScrollState_hash() {
+        var $firstVisibleActivity = $('.timeline li:in-viewport:first');
+        saveScrollPosition();
+        window.location.hash = $firstVisibleActivity.attr('id');  // causes jump...
+        restoreScrollPosition();
+    }
+
+    var delayed = null;
+    function scrollHandler(event) {
+        clearTimeout(delayed);
+        delayed = setTimeout(ActivityBrowseOptions.usePjax
+            ? maintainScrollState_pjax
+            : maintainScrollState_hash, 100);
+    }
+
+    function maintainScrollState() {
+        if (!ActivityBrowseOptions.maintainScrollState) {
+            return;
+        }
+        $(window).scroll(scrollHandler);
+    }
+
+    function pageOut(newer) {
+        var $timeline = $('.timeline li');
+        var limit = $('.timeline').data('limit') || 100;
+        var range = newer ? [0, limit] : [-limit, undefined];
+        $timeline.slice(range[0], range[1]).remove();
+        if (!newer && $('.show-more.older').hasClass('no-more')) {
+            $('.no-more').removeClass('no-more');
+            updateShowMore();
+        }
+    }
+    window.pageOut = pageOut;
+
+    function pageIn(newer, url) {
+        $.get(url, function(html) {
+            saveScrollPosition();
+            if (newer) {
+                $('.timeline').prepend(html);
+            } else {
+                if (html.match(/^\s*$/)) {
+                    $('.show-more.older').addClass('no-more');
+                } else {
+                    $('.timeline').append(html);
+                }
+            }
+            var firstPage = $('.timeline li:first').data('page');
+            var lastPage = $('.timeline li:last').data('page');
+            if (lastPage - firstPage >= 3) {
+                pageOut(!newer);
+            }
+            if (ActivityBrowseOptions.useShowMore) {
+                updateShowMore();
+            }
+            restoreScrollPosition();
+        }).fail(function() {
+            flash('Error loading activities', 'error');
+        });
+    }
+
+    function makeShowMoreHandler(newer) {
+        // has to be factory to prevent closure memory leak
+        // see: https://www.meteor.com/blog/2013/08/13/an-interesting-kind-of-javascript-memory-leak
+        return function(event) {
+            event.preventDefault();
+            pageIn(newer, this.href);
+        };
+    }
+
+    function makeShowMoreLink(newer, targetPage, limit) {
+        var $link = $('<a class="show-more">Show more</a>');
+        $link.addClass(newer ? 'newer' : 'older');
+        $link.attr('href', 'pjax?page='+targetPage+'&limit='+limit);
+        $link.click(makeShowMoreHandler(newer));  // has to be factory to prevent closure memory leak
+        return $link;
+    }
+
+    function updateShowMore() {
+        var $timeline = $('.timeline');
+        if (!$timeline.length) {
+            return;
+        }
+        var noMoreActivities = $('.show-more.older').hasClass('no-more');
+        $('.page_list, .show-more').remove();
+        var limit = $('.timeline').data('limit');
+        var firstPage = $('.timeline li:first').data('page');
+        var lastPage = $('.timeline li:last').data('page');
+        if (firstPage > 0) {
+            $timeline.before(makeShowMoreLink(true, firstPage-1, limit));
+        }
+        if (noMoreActivities) {
+            $timeline.after('<div class="show-more older no-more">No more activities</div>');
+        } else {
+            $timeline.after(makeShowMoreLink(false, lastPage+1, limit));
+        }
+    }
+    window.updateShowMore = updateShowMore;
+
+    function enableInfiniteScroll() {
+    }
+
+    function enableAdvancedPaging() {
+        if (ActivityBrowseOptions.useInfiniteScroll) {
+            enableInfiniteScroll();
+        } else if (ActivityBrowseOptions.useShowMore) {
+            updateShowMore();
+        }
+    }
+
+    maintainScrollState();  // http://xkcd.com/1309/
+    enableAdvancedPaging();
+});
+
+function markTop() {
+    var $marker = $('#offset-marker');
+    if (!$marker.length) {
+        $marker = $('<div id="offset-marker">&nbsp;</div>');
+        $marker.css({
+            'position': 'absolute',
+            'top': 0,
+            'width': '100%',
+            'border-top': '1px solid green'
+        });
+        $marker.appendTo($('body'));
+    }
+    $marker.css({'top': $(window).scrollTop()});
+}
+
+function markFirst() {
+    $('.timeline li:in-viewport:first').css({'background-color': '#f0fff0'});
+}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/ForgeActivity/forgeactivity/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/index.html b/ForgeActivity/forgeactivity/templates/index.html
index e63c904..4b8c162 100644
--- a/ForgeActivity/forgeactivity/templates/index.html
+++ b/ForgeActivity/forgeactivity/templates/index.html
@@ -38,27 +38,18 @@
 {% endblock %}
 
 {% block content %}
+{% do g.register_forge_js('js/jquery.viewport.js') %}
+{% do g.register_app_js('js/activity.js') %}
+
 <div class="activity">
   {% if not timeline %}
     No activity to display.
   {% else %}
-    <ul class="timeline">
-        {% for a in timeline %}
-        <li>
-          <time datetime="{{a.published|datetimeformat}}" title="{{a.published|datetimeformat}}">{{h.ago(a.published, show_date_after=None)}}</time>
-          <h1>
-              {{ am.icon(a.actor, 32, 'avatar') }}
-              {{am.activity_obj(a.actor)}} {{a.verb}} {{am.activity_obj(a.obj)}} {% if a.target.activity_name %}on {{am.activity_obj(a.target)}}{% endif %}
-          </h1>
-          {% if a.obj.activity_extras.get('summary') %}
-          <p>
-            {{ a.obj.activity_extras.get('summary') }}
-          </p>
-          {% endif %}
-        </li>
-        {% endfor %}
+    <ul class="timeline" data-limit="{{limit}}">
+        {% include 'forgeactivity:templates/timeline.html' %}
         {{c.page_list.display(limit=1, page=page, count=page+1, show_label=False, show_if_single_page=True, force_next=True)}}
     </ul>
+    {{c.page_list.display(limit=1, page=page, count=page+1, show_label=False, show_if_single_page=True, force_next=True)}}
   {% endif %}
 </div>
 {% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/df82f288/ForgeActivity/forgeactivity/templates/timeline.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/timeline.html b/ForgeActivity/forgeactivity/templates/timeline.html
new file mode 100644
index 0000000..499fe03
--- /dev/null
+++ b/ForgeActivity/forgeactivity/templates/timeline.html
@@ -0,0 +1,35 @@
+{#-
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+-#}
+
+{% import 'forgeactivity:templates/macros.html' as am with context %}
+
+{% for a in timeline %}
+<li id="{{a._id}}" data-page="{{page}}">
+  <time datetime="{{a.published|datetimeformat}}" title="{{a.published|datetimeformat}}">{{h.ago(a.published, show_date_after=None)}}</time>
+  <h1>
+      {{ am.icon(a.actor, 32, 'avatar') }}
+      {{am.activity_obj(a.actor)}} {{a.verb}} {{am.activity_obj(a.obj)}} {% if a.target.activity_name %}on {{am.activity_obj(a.target)}}{% endif %}
+  </h1>
+  {% if a.obj.activity_extras.get('summary') %}
+  <p>
+    {{ a.obj.activity_extras.get('summary') }}
+  </p>
+  {% endif %}
+</li>
+{% endfor %}


[10/28] git commit: [#7002] Show activity on user profile

Posted by jo...@apache.org.
[#7002] Show activity on user profile

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: cae66cc466d698aded0f83514d0eceb850e20d08
Parents: be272fa
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Jan 15 21:37:51 2014 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jan 22 14:26:21 2014 +0000

----------------------------------------------------------------------
 Allura/allura/ext/user_profile/__init__.py      |  2 +-
 .../ext/user_profile/templates/user_index.html  |  4 ++
 Allura/allura/ext/user_profile/user_main.py     | 41 ++++++++++++++-
 Allura/allura/nf/allura/css/allura.css          |  1 +
 Allura/allura/nf/allura/css/site_style.css      | 53 ++++++++++++++++++++
 .../tests/functional/test_user_profile.py       | 30 +++++++++++
 ForgeActivity/forgeactivity/main.py             | 28 +++++++++++
 .../forgeactivity/templates/index.html          | 20 ++------
 .../forgeactivity/templates/macros.html         | 33 ++++++++++++
 .../templates/widgets/profile_section.html      | 51 +++++++++++++++++++
 ForgeActivity/setup.py                          |  3 ++
 11 files changed, 247 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cae66cc4/Allura/allura/ext/user_profile/__init__.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/__init__.py b/Allura/allura/ext/user_profile/__init__.py
index 2657c92..5b323d6 100644
--- a/Allura/allura/ext/user_profile/__init__.py
+++ b/Allura/allura/ext/user_profile/__init__.py
@@ -15,4 +15,4 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from .user_main import UserProfileApp
+from .user_main import UserProfileApp, ProfileSectionBase

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cae66cc4/Allura/allura/ext/user_profile/templates/user_index.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/templates/user_index.html b/Allura/allura/ext/user_profile/templates/user_index.html
index 41f7f67..e567095 100644
--- a/Allura/allura/ext/user_profile/templates/user_index.html
+++ b/Allura/allura/ext/user_profile/templates/user_index.html
@@ -290,6 +290,10 @@
         </ul>
       </div>
   {% endif %}
+
+  {% for section in sections %}
+    {{ section.display() }}
+  {% endfor %}
 {% endblock %}
 
 {% block extra_js %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cae66cc4/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 9198696..530d5a3 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -16,13 +16,18 @@
 #       under the License.
 
 import logging
+import re
 
 import pkg_resources
 from pylons import tmpl_context as c
+from pylons import app_globals as g
 from pylons import request
 from formencode import validators
 from tg import expose, redirect, validate, flash
+import tg
 from webob import exc
+from ming.utils import LazyProperty
+from jinja2 import Markup
 
 from allura import version
 from allura.app import Application, SitemapEntry
@@ -83,6 +88,18 @@ class UserProfileApp(Application):
     def uninstall(self, project):  # pragma no cover
         pass
 
+    @LazyProperty
+    def profile_sections(self):
+        sections = {}
+        for ep in h.iter_entry_points('allura.user_profile.sections'):
+            sections[ep.name] = ep.load()
+        section_ordering = tg.config.get('user_profile_sections.order', '')
+        ordered_sections = []
+        for section in re.split(r'\s*,\s*', section_ordering):
+            if section in sections:
+                ordered_sections.append(sections.pop(section))
+        return ordered_sections + sections.values()
+
 
 class UserProfileController(BaseController, FeedController):
 
@@ -114,7 +131,12 @@ class UserProfileController(BaseController, FeedController):
         if not user:
             raise exc.HTTPNotFound()
         provider = AuthenticationProvider.get(request)
-        return dict(user=user, reg_date=provider.user_registration_date(user))
+        sections = [section(user, c.project) for section in c.app.profile_sections]
+        return dict(
+                user=user,
+                reg_date=provider.user_registration_date(user),
+                sections=sections,
+            )
 
     def get_feed(self, project, app, user):
         """Return a :class:`allura.controllers.feed.FeedArgs` object describing
@@ -162,3 +184,20 @@ class UserProfileController(BaseController, FeedController):
                 c.user.user_message_max_messages,
                 c.user.user_message_time_interval), 'error')
         return redirect(c.project.user_project_of.url())
+
+
+class ProfileSectionBase(object):
+    template = ''
+
+    def check_display(self):
+        return True
+
+    def prepare_context(self, context):
+        return context
+
+    def display(self, *a, **kw):
+        if not self.check_display():
+            return ''
+        tmpl = g.jinja2_env.get_template(self.template)
+        context = self.prepare_context({'h': h, 'c': c})
+        return Markup(tmpl.render(context))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cae66cc4/Allura/allura/nf/allura/css/allura.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/allura.css b/Allura/allura/nf/allura/css/allura.css
index 628fe61..ddf27cc 100644
--- a/Allura/allura/nf/allura/css/allura.css
+++ b/Allura/allura/nf/allura/css/allura.css
@@ -53,6 +53,7 @@ b.ico.ico-feed { background-position: -16px -176px; }
 b.ico.ico-close { background-position: -80px -128px; }
 b.ico.ico-vote-up { background-image: url('../images/vote_up.png'); }
 b.ico.ico-vote-down { background-image: url('../images/vote_down.png'); }
+b.ico.ico-star { background-position: -240px -96px; }
 
 
 #ticket_search_results_holder{

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cae66cc4/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index 05f1d05..6c6ff02 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -3240,3 +3240,56 @@ ul.dropdown ul li a:hover {
 .content-maximized #restore-content {
     display: inline;
 }
+
+.user-activity {
+    position: absolute;
+    top: 60px;
+    right: 0px;
+    border: 1px solid #ccc;
+    border-radius: 4px;
+}
+.user-activity h3 {
+    background-color: #555555;
+    background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(0%, #666666), color-stop(100%, #555555));
+    background-image: -moz-linear-gradient(top, #666666 0%, #555555 100%);
+    background-image: linear-gradient(top, #666666 0%, #555555 100%);
+    border: 1px solid #333333;
+    color: #fff;
+    padding: 10px;
+    font-weight: normal;
+    font-size: 14px;
+}
+.user-activity h3 a {
+    float: right;
+}
+.user-activity h3 b.ico {
+    background-image: url('../images/neo-icon-set-ffffff-256x350.png');
+}
+.user-activity .empty {
+    padding: 10px;
+    font-style: italic;
+}
+.user-activity ul {
+    margin: 0px;
+    list-style: none;
+}
+.user-activity ul li {
+    padding: 10px;
+    border-bottom: 1px solid #ccc;
+}
+.user-activity ul li img {
+    vertical-align: text-bottom;
+}
+.user-activity ul li p {
+    padding: 5px 0 0 0;
+}
+.user-activity ul li time {
+    display: block;
+    text-align: right;
+    font-size: 10px;
+}
+.user-activity a.view-all {
+    display: block;
+    text-align: right;
+    padding: 5px 10px 5px 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cae66cc4/Allura/allura/tests/functional/test_user_profile.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py
index 3beb105..71ae05a 100644
--- a/Allura/allura/tests/functional/test_user_profile.py
+++ b/Allura/allura/tests/functional/test_user_profile.py
@@ -16,6 +16,8 @@
 #       under the License.
 
 import mock
+import tg
+from nose.tools import assert_equal, assert_in, assert_not_in
 
 from allura.model import Project, User
 from allura.tests import decorators as td
@@ -149,3 +151,31 @@ class TestUserProfile(TestController):
         r = self.app.get('/u/test-user/profile/send_message', status=302)
         assert 'This user has disabled direct email messages' in self.webflash(
             r)
+
+    @td.with_user_project('test-user')
+    def test_profile_sections(self):
+        project = Project.query.get(shortname='u/test-user')
+        app = project.app_instance('profile')
+        def ep(n):
+            m = mock.Mock()
+            m.name = n
+            m.load()().display.return_value = 'Section %s' % n
+            return m
+        eps = map(ep, ['a', 'b', 'c', 'd'])
+        order = {'user_profile_sections.order': 'b, d,c , f '}
+        with mock.patch('allura.lib.helpers.iter_entry_points') as iep:
+            with mock.patch.dict(tg.config, order):
+                iep.return_value = eps
+                sections = app.profile_sections
+                assert_equal(sections, [
+                        eps[1].load(),
+                        eps[3].load(),
+                        eps[2].load(),
+                        eps[0].load(),
+                    ])
+                r = self.app.get('/u/test-user/profile')
+                assert_in('Section a', r.body)
+                assert_in('Section b', r.body)
+                assert_in('Section c', r.body)
+                assert_in('Section d', r.body)
+                assert_not_in('Section f', r.body)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cae66cc4/ForgeActivity/forgeactivity/main.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/main.py b/ForgeActivity/forgeactivity/main.py
index 6bf1199..6d50427 100644
--- a/ForgeActivity/forgeactivity/main.py
+++ b/ForgeActivity/forgeactivity/main.py
@@ -33,6 +33,8 @@ from allura.lib.security import require_authenticated
 from allura.model.timeline import perm_check
 from allura.lib import helpers as h
 from allura.lib.decorators import require_post
+from allura.model.timeline import perm_check
+from allura.ext.user_profile import ProfileSectionBase
 
 from .widgets.follow import FollowToggle
 
@@ -199,3 +201,29 @@ class ForgeActivityRestController(BaseController):
                 'target': a.target._deinstrument(),
             } for a in data['timeline']],
         }
+
+
+class ForgeActivityProfileSection(ProfileSectionBase):
+    template = 'forgeactivity:templates/widgets/profile_section.html'
+
+    def __init__(self, user, project):
+        self.user = user
+        self.project = project
+        self.activity_app = self.project.app_instance('activity')
+
+    def check_display(self):
+        return self.activity_app is not None
+
+    def prepare_context(self, context):
+        context.update({
+                'user': self.user,
+                'follow_toggle': W.follow_toggle,
+                'following': g.director.is_connected(c.user, self.user),
+                'timeline': g.director.get_timeline(
+                    self.user, page=0, limit=5,
+                    actor_only=True,
+                    filter_func=perm_check(c.user)),
+                'activity_app': self.activity_app,
+            })
+        g.register_js('activity_js/follow.js')
+        return context

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cae66cc4/ForgeActivity/forgeactivity/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/index.html b/ForgeActivity/forgeactivity/templates/index.html
index 8293763..435fc82 100644
--- a/ForgeActivity/forgeactivity/templates/index.html
+++ b/ForgeActivity/forgeactivity/templates/index.html
@@ -18,6 +18,7 @@
 -#}
 {% set hide_left_bar = True %}
 {% extends g.theme.master %}
+{% import 'forgeactivity:templates/macros.html' as am with context %}
 
 {% block title %}{{c.project.name}} Activity{% endblock %}
 
@@ -36,21 +37,6 @@
     {% endif %}
 {% endblock %}
 
-{% macro activity_obj(o) %}
-  <a href="{{o.activity_url}}">{{o.activity_name}}</a>
-{% endmacro %}
-
-{% macro icon(o, size, className) -%}
-  {% if o.activity_extras.get('icon_url') %}
-    <img src="{{ o.activity_extras.get('icon_url') }}"
-         alt="{{ o.activity_name }}"
-         title="{{ o.activity_name }}"
-         class="emboss{% if size %} x{{size}}{% endif %}{% if className %} {{className}}{% endif %}">
-  {% else %}
-    <b data-icon="{{g.icons['user'].char}}" class="ico emboss {{g.icons['user'].css}}{% if size %} x{{size}}{% endif %}{% if className %} {{className}}{% endif %}"></b>
-  {% endif %}
-{%- endmacro %}
-
 {% block content %}
 <div class="activity">
   {% if not timeline %}
@@ -61,8 +47,8 @@
         <li>
           <time datetime="{{a.published|datetimeformat}}" title="{{a.published|datetimeformat}}">{{h.ago(a.published, show_date_after=None)}}</time>
           <h1>
-              {{ icon(a.actor, 32, 'avatar') }}
-              {{activity_obj(a.actor)}} {{a.verb}} {{activity_obj(a.obj)}} {% if a.target.activity_name %}on {{activity_obj(a.target)}}{% endif %}
+              {{ am.icon(a.actor, 32, 'avatar') }}
+              {{am.activity_obj(a.actor)}} {{a.verb}} {{am.activity_obj(a.obj)}} {% if a.target.activity_name %}on {{am.activity_obj(a.target)}}{% endif %}
           </h1>
           {% if a.obj.activity_extras.get('summary') %}
           <p>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cae66cc4/ForgeActivity/forgeactivity/templates/macros.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/macros.html b/ForgeActivity/forgeactivity/templates/macros.html
new file mode 100644
index 0000000..c60582e
--- /dev/null
+++ b/ForgeActivity/forgeactivity/templates/macros.html
@@ -0,0 +1,33 @@
+{#-
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+-#}
+
+{% macro activity_obj(o) %}
+  <a href="{{o.activity_url}}">{{o.activity_name}}</a>
+{% endmacro %}
+
+{% macro icon(o, size, className) -%}
+  {% if o.activity_extras.get('icon_url') %}
+    <img src="{{ o.activity_extras.get('icon_url') }}"
+         alt="{{ o.activity_name }}"
+         title="{{ o.activity_name }}"
+         class="emboss{% if size %} x{{size}}{% endif %}{% if className %} {{className}}{% endif %}">
+  {% else %}
+    <b data-icon="{{g.icons['user'].char}}" class="ico emboss {{g.icons['user'].css}}{% if size %} x{{size}}{% endif %}{% if className %} {{className}}{% endif %}"></b>
+  {% endif %}
+{%- endmacro %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cae66cc4/ForgeActivity/forgeactivity/templates/widgets/profile_section.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/widgets/profile_section.html b/ForgeActivity/forgeactivity/templates/widgets/profile_section.html
new file mode 100644
index 0000000..a9e473f
--- /dev/null
+++ b/ForgeActivity/forgeactivity/templates/widgets/profile_section.html
@@ -0,0 +1,51 @@
+{#-
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+-#}
+{% import 'allura:templates/jinja_master/lib.html' as lib with context %}
+{% import 'forgeactivity:templates/macros.html' as am with context %}
+
+<div class="user-activity grid-8">
+    <h3>
+        User Activity
+
+        {% if c.user and not c.user.is_anonymous() and c.user != user %}
+            {{follow_toggle.display(following=following, action=activity_app.url+'follow')}}
+        {% endif %}
+    </h3>
+    {% if not timeline %}
+        <p class="empty">No activity to display.</p>
+    {% else %}
+    <ul class="timeline">
+        {% for a in timeline %}
+        <li>
+            <b>
+                {{am.icon(a.actor, 16, 'avatar')}}{{am.activity_obj(a.actor)}} {{a.verb}} {{am.activity_obj(a.obj)}}
+                {% if a.target.activity_name %}on {{am.activity_obj(a.target)}}{% endif %}
+            </b>
+            {% if a.obj.activity_extras.get('summary') %}
+            <p>
+                {{ a.obj.activity_extras.get('summary') }}
+            </p>
+            {% endif %}
+            <time datetime="{{a.published|datetimeformat}}" title="{{a.published|datetimeformat}}">{{h.ago(a.published, show_date_after=None)}}</time>
+        </li>
+        {% endfor %}
+    </ul>
+    <a class="view-all" href="{{activity_app.url}}">View All</a>
+    {% endif %}
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cae66cc4/ForgeActivity/setup.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/setup.py b/ForgeActivity/setup.py
index 45c546e..9795dfb 100644
--- a/ForgeActivity/setup.py
+++ b/ForgeActivity/setup.py
@@ -41,6 +41,9 @@ setup(name='ForgeActivity',
       [allura]
       activity=forgeactivity.main:ForgeActivityApp
 
+      [allura.user_profile.sections]
+      activity=forgeactivity.main:ForgeActivityProfileSection
+
       [easy_widgets.resources]
       ew_resources=forgeactivity.config.resources:register_ew_resources
       """,


[25/28] git commit: [#4257] More IE hacks to avoid Access Denied

Posted by jo...@apache.org.
[#4257] More IE hacks to avoid Access Denied

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: e276acfa3a48acb28862af6213c8284ba4331d44
Parents: de4f5b7
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Jan 22 21:34:56 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:04 2014 +0000

----------------------------------------------------------------------
 ForgeActivity/forgeactivity/nf/activity/js/activity.js | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/e276acfa/ForgeActivity/forgeactivity/nf/activity/js/activity.js
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/nf/activity/js/activity.js b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
index 0ed3b0e..ad835d2 100644
--- a/ForgeActivity/forgeactivity/nf/activity/js/activity.js
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -210,14 +210,14 @@ $(function() {
     }
 
     function makeShowMoreLink(newer, targetPage) {
-        var $link = $('<a class="show-more">Show More</a>');
-        $link.addClass(newer ? 'newer' : 'older');
-        $link.attr('href', makePageUrl(targetPage));
-        $link.click(function(event) {
+        var cls = newer ? 'newer' : 'older';
+        var url = makePageUrl(targetPage);
+        var link = '<a class="show-more '+cls+'" href="'+url+'">Show More</a>';
+        $('.timeline')[newer ? 'before' : 'after'](link);
+        $('.show-more.'+cls).click(function(event) {
             event.preventDefault();
             pageIn(newer, this.href);
         });
-        $('.timeline')[newer ? 'before' : 'after']($link);
     }
 
     function updateShowMore() {


[12/28] git commit: [#7002] Fix failing tests with s/json/json:/

Posted by jo...@apache.org.
[#7002] Fix failing tests with s/json/json:/

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


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

Branch: refs/heads/cj/4257
Commit: 1a9552eb6b4bccf1097ab1a1c591d6a56055ed81
Parents: 168a80f
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Wed Jan 22 14:57:07 2014 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jan 22 14:57:07 2014 +0000

----------------------------------------------------------------------
 ForgeWiki/forgewiki/wiki_main.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1a9552eb/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 7a90a3b..2709733 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -532,7 +532,7 @@ class PageController(BaseController, FeedController):
                     hide_left_bar=hide_left_bar)
 
     @without_trailing_slash
-    @expose('json')
+    @expose('json:')
     @require_post()
     def delete(self):
         require_access(self.page, 'delete')
@@ -540,7 +540,7 @@ class PageController(BaseController, FeedController):
         return dict(location='../' + self.page.title + '/?deleted=True')
 
     @without_trailing_slash
-    @expose('json')
+    @expose('json:')
     @require_post()
     def undelete(self):
         require_access(self.page, 'delete')
@@ -600,7 +600,7 @@ class PageController(BaseController, FeedController):
             self.page.url())
 
     @without_trailing_slash
-    @expose('json')
+    @expose('json:')
     @require_post()
     @validate(dict(version=validators.Int(if_empty=1, if_invalid=1)))
     def revert(self, version, **kw):


[05/28] git commit: [#7006] Added modernizr.js to rat-excludes

Posted by jo...@apache.org.
[#7006] Added modernizr.js to rat-excludes

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: 0a0145005018a0d2e7154066f2525a794ca4913b
Parents: ffbb420
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Jan 21 22:34:30 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Jan 21 22:34:30 2014 +0000

----------------------------------------------------------------------
 rat-excludes.txt | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0a014500/rat-excludes.txt
----------------------------------------------------------------------
diff --git a/rat-excludes.txt b/rat-excludes.txt
index cc89a91..3e52b40 100644
--- a/rat-excludes.txt
+++ b/rat-excludes.txt
@@ -29,6 +29,7 @@ Allura/allura/public/nf/js/jquery.maxlength.min.js
 Allura/allura/public/nf/css/blueprint/
 Allura/allura/public/nf/js/spin.min.js
 Allura/allura/public/nf/js/sylvester.js
+Allura/allura/public/nf/js/modernizr.js
 Allura/allura/tests/data/genshi_hello_tmpl
 Allura/allura/tests/data/test_mime/text_file.txt
 AlluraTest/jslint/


[21/28] git commit: [#4257] Refactors, added doc comments, fixed duplicate paging controls

Posted by jo...@apache.org.
[#4257] Refactors, added doc comments, fixed duplicate paging controls

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: f1f4ff499c4abd3f6137fc6ac24cca71334f0b86
Parents: df82f28
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Sat Jan 18 16:15:43 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:03 2014 +0000

----------------------------------------------------------------------
 .../forgeactivity/nf/activity/css/activity.css  |   7 +-
 .../forgeactivity/nf/activity/js/activity.js    | 150 +++++++++++--------
 .../forgeactivity/templates/index.html          |   1 -
 3 files changed, 96 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1f4ff49/ForgeActivity/forgeactivity/nf/activity/css/activity.css
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/nf/activity/css/activity.css b/ForgeActivity/forgeactivity/nf/activity/css/activity.css
index 66395ff..f3a5324 100644
--- a/ForgeActivity/forgeactivity/nf/activity/css/activity.css
+++ b/ForgeActivity/forgeactivity/nf/activity/css/activity.css
@@ -49,10 +49,13 @@
 .activity .page_list {
     margin-top: 5px;
 }
-.activity .show-more {
+.activity .no-more.newer {
+    display: none;
+}
+.activity .show-more, .activity .no-more {
     display: block;
     text-align: center;
 }
-.activity .show-more.older {
+.activity .show-more.older, .activity .no-more.older {
     margin-top: 10px;
 }

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1f4ff49/ForgeActivity/forgeactivity/nf/activity/js/activity.js
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/nf/activity/js/activity.js b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
index e8c0346..a1313c6 100644
--- a/ForgeActivity/forgeactivity/nf/activity/js/activity.js
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -17,8 +17,8 @@
        under the License.
 */
 
-ActivityBrowseOptions = {
-    maintainScrollState: true,
+ASOptions = {
+    maintainScrollHistory: true,
     usePjax: true,
     useHash: true,
     forceAdvancedScroll: false,
@@ -27,18 +27,20 @@ ActivityBrowseOptions = {
 }
 
 $(function() {
-    var hasAPI = window.history && window.history.pushState && window.history.replaceState;
-    var iOS4 = navigator.userAgent.match(/iP(od|one|ad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork/);
-    if (!hasAPI || iOS4) {
-        ActivityBrowseOptions.usePjax = false;
-    }
-    if (!ActivityBrowseOptions.usePjax) {
-        if (!ActivityBrowseOptions.useHash) {
-            ActivityBrowseOptions.maintainScrollState = false;
+    function detectFeatures() {
+        var hasAPI = window.history && window.history.pushState && window.history.replaceState;
+        var iOS4 = navigator.userAgent.match(/iP(od|one|ad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork/);
+        if (!hasAPI || iOS4) {
+            ASOptions.usePjax = false;
         }
-        if (!ActivityBrowseOptions.forceAdvancedScroll) {
-            ActivityBrowseOptions.useShowMore = false;
-            ActivityBrowseOptions.useInfiniteScroll = false;
+        if (!ASOptions.usePjax) {
+            if (!ASOptions.useHash) {
+                ASOptions.maintainScrollHistory = false;
+            }
+            if (!ASOptions.forceAdvancedScroll) {
+                ASOptions.useShowMore = false;
+                ASOptions.useInfiniteScroll = false;
+            }
         }
     }
 
@@ -46,12 +48,20 @@ $(function() {
     var oldScrollTop = null;
     var oldTop = null;
     function saveScrollPosition() {
+        // Save the relative position of the first visible element of
+        // interest for later restore to keep the important visible content
+        // at the same viewport position before / after DOM changes.
+        // TODO: This could be made more generic by making the "interesting
+        // elements" selector configurable.
         var $firstVisible = $('.timeline li:in-viewport:first');
         firstVisibleId = $firstVisible.attr('id');
         oldScrollTop = $(window).scrollTop();
         oldTop = $firstVisible.offset().top;
     }
+
     function restoreScrollPosition() {
+        // Restore the relative position of "interesting" content previously
+        // saved by saveScrollPosition.
         var $window = $(window);
         var $firstVisible = $('#'+firstVisibleId);
         if (!$firstVisible.length) {
@@ -66,7 +76,10 @@ $(function() {
         $(window).trigger('scroll');
     }
 
-    function maintainScrollState_pjax() {
+    function maintainScrollHistory_pjax() {
+        // Use the HTML5 history API to record page and scroll position.
+        // TODO: Page changes should pushState while just scroll changes
+        // should replaceState.
         var $firstVisibleActivity = $('.timeline li:in-viewport:first');
         var page = $firstVisibleActivity.data('page');
         var limit = $('.timeline').data('limit');
@@ -76,7 +89,11 @@ $(function() {
         }
     }
 
-    function maintainScrollState_hash() {
+    function maintainScrollHistory_hash() {
+        // Use the location.hash to record the scroll position.
+        // TODO/FIXME: This doesn't record the page for forceAdvancedPaging, and since
+        // the hash history is additive (confirm?), it can require clicking Back
+        // through all of your scrolling.
         var $firstVisibleActivity = $('.timeline li:in-viewport:first');
         saveScrollPosition();
         window.location.hash = $firstVisibleActivity.attr('id');  // causes jump...
@@ -86,48 +103,63 @@ $(function() {
     var delayed = null;
     function scrollHandler(event) {
         clearTimeout(delayed);
-        delayed = setTimeout(ActivityBrowseOptions.usePjax
-            ? maintainScrollState_pjax
-            : maintainScrollState_hash, 100);
-    }
-
-    function maintainScrollState() {
-        if (!ActivityBrowseOptions.maintainScrollState) {
+        var method = ASOptions.usePjax
+            ? maintainScrollHistory_pjax
+            : maintainScrollHistory_hash;
+        var delay = ASOptions.usePjax
+            ? 100   // scrolls replace history and don't affect scrolling, so more is ok
+            : 750;  // scrolls add history and affect scrolling, so make sure they're done
+        delayed = setTimeout(method, delay);
+    }
+
+    function enableScrollHistory() {
+        // Attempt to record the scroll position in the browser history
+        // using either the HTML5 history API (aka PJAX) or via the location
+        // hash.  Otherwise, when the user clicks a link and then comes back,
+        // they will lose their scroll position and, in the case of advanced
+        // paging, which page they were on.  See: http://xkcd.com/1309/
+        if (!ASOptions.maintainScrollHistory) {
             return;
         }
         $(window).scroll(scrollHandler);
     }
 
     function pageOut(newer) {
+        // Remove a single page of either newer or older content.
         var $timeline = $('.timeline li');
-        var limit = $('.timeline').data('limit') || 100;
+        var limit = $('.timeline').data('limit');
         var range = newer ? [0, limit] : [-limit, undefined];
         $timeline.slice(range[0], range[1]).remove();
-        if (!newer && $('.show-more.older').hasClass('no-more')) {
-            $('.no-more').removeClass('no-more');
-            updateShowMore();
-        }
+        $('.no-more.'+(newer ? 'newer' : 'older')).remove();
     }
-    window.pageOut = pageOut;
 
     function pageIn(newer, url) {
+        // Load a single page of either newer or older content from the URL.
+        // If the added page causes too many to be on screen, calls pageOut
+        // to keep memory usage in check.  Also uses save/restoreScrollPosition
+        // to try to keep the same content in view at the same place.
         $.get(url, function(html) {
+            var $html = $(html);
+            var $timeline = $('.timeline');
+            var limit = $('.timeline').data('limit');
             saveScrollPosition();
-            if (newer) {
-                $('.timeline').prepend(html);
-            } else {
-                if (html.match(/^\s*$/)) {
-                    $('.show-more.older').addClass('no-more');
-                } else {
-                    $('.timeline').append(html);
-                }
+            if ($html.length < limit) {
+                var method = newer ? 'before' : 'after';
+                var cls = newer ? 'newer' : 'older';
+                $timeline[method]('<div class="no-more '+cls+'">No more activities</div>');
             }
+            var method = newer ? 'prepend' : 'append';
+            $timeline[method]($html);
             var firstPage = $('.timeline li:first').data('page');
             var lastPage = $('.timeline li:last').data('page');
             if (lastPage - firstPage >= 3) {
                 pageOut(!newer);
             }
-            if (ActivityBrowseOptions.useShowMore) {
+            if (ASOptions.useShowMore) {
+                // this has to be here instead of showMoreLink handler to
+                // ensure that scroll changes between added / removed content
+                // and Show More links combine properly and don't cause a jump
+                // due to hitting the edge of the page
                 updateShowMore();
             }
             restoreScrollPosition();
@@ -136,56 +168,56 @@ $(function() {
         });
     }
 
-    function makeShowMoreHandler(newer) {
-        // has to be factory to prevent closure memory leak
-        // see: https://www.meteor.com/blog/2013/08/13/an-interesting-kind-of-javascript-memory-leak
-        return function(event) {
-            event.preventDefault();
-            pageIn(newer, this.href);
-        };
-    }
-
     function makeShowMoreLink(newer, targetPage, limit) {
-        var $link = $('<a class="show-more">Show more</a>');
+        var $link = $('<a class="show-more">Show More</a>');
         $link.addClass(newer ? 'newer' : 'older');
         $link.attr('href', 'pjax?page='+targetPage+'&limit='+limit);
-        $link.click(makeShowMoreHandler(newer));  // has to be factory to prevent closure memory leak
+        $link.click(function(event) {
+            event.preventDefault();
+            pageIn(newer, this.href);
+        });
         return $link;
     }
 
     function updateShowMore() {
+        // Update the state of the Show More links when using "Show More"-style
+        // advanced paging.
         var $timeline = $('.timeline');
         if (!$timeline.length) {
             return;
         }
-        var noMoreActivities = $('.show-more.older').hasClass('no-more');
-        $('.page_list, .show-more').remove();
         var limit = $('.timeline').data('limit');
         var firstPage = $('.timeline li:first').data('page');
         var lastPage = $('.timeline li:last').data('page');
-        if (firstPage > 0) {
+        var noMoreNewer = firstPage == 0 || $('.no-more.newer').length;
+        var noMoreOlder = $('.no-more.older').length;
+        $('.show-more').remove();  // TODO: could update HREFs instead of always re-creating links
+        if (!noMoreNewer) {
             $timeline.before(makeShowMoreLink(true, firstPage-1, limit));
         }
-        if (noMoreActivities) {
-            $timeline.after('<div class="show-more older no-more">No more activities</div>');
-        } else {
+        if (!noMoreOlder) {
             $timeline.after(makeShowMoreLink(false, lastPage+1, limit));
         }
     }
-    window.updateShowMore = updateShowMore;
+
+    function enableShowMore() {
+        $('.page_list').remove();
+        updateShowMore();
+    }
 
     function enableInfiniteScroll() {
     }
 
     function enableAdvancedPaging() {
-        if (ActivityBrowseOptions.useInfiniteScroll) {
+        if (ASOptions.useInfiniteScroll) {
             enableInfiniteScroll();
-        } else if (ActivityBrowseOptions.useShowMore) {
-            updateShowMore();
+        } else if (ASOptions.useShowMore) {
+            enableShowMore();
         }
     }
 
-    maintainScrollState();  // http://xkcd.com/1309/
+    detectFeatures();
+    enableScrollHistory();
     enableAdvancedPaging();
 });
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1f4ff49/ForgeActivity/forgeactivity/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/index.html b/ForgeActivity/forgeactivity/templates/index.html
index 4b8c162..5b222f7 100644
--- a/ForgeActivity/forgeactivity/templates/index.html
+++ b/ForgeActivity/forgeactivity/templates/index.html
@@ -47,7 +47,6 @@
   {% else %}
     <ul class="timeline" data-limit="{{limit}}">
         {% include 'forgeactivity:templates/timeline.html' %}
-        {{c.page_list.display(limit=1, page=page, count=page+1, show_label=False, show_if_single_page=True, force_next=True)}}
     </ul>
     {{c.page_list.display(limit=1, page=page, count=page+1, show_label=False, show_if_single_page=True, force_next=True)}}
   {% endif %}


[24/28] git commit: [#4257] Fixed page back to start, and more refactors

Posted by jo...@apache.org.
[#4257] Fixed page back to start, and more refactors

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: 3d9ff04e51d3a5ef3e1a4871954b3253f00a5b70
Parents: f1f4ff4
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Sun Jan 19 01:14:51 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:04 2014 +0000

----------------------------------------------------------------------
 .../forgeactivity/nf/activity/js/activity.js    | 66 ++++++++++++--------
 1 file changed, 41 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3d9ff04e/ForgeActivity/forgeactivity/nf/activity/js/activity.js
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/nf/activity/js/activity.js b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
index a1313c6..48b699f 100644
--- a/ForgeActivity/forgeactivity/nf/activity/js/activity.js
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -18,6 +18,7 @@
 */
 
 ASOptions = {
+    maxPages: 3,
     maintainScrollHistory: true,
     usePjax: true,
     useHash: true,
@@ -27,6 +28,17 @@ ASOptions = {
 }
 
 $(function() {
+    if (!$('.timeline li').length) {
+        return;  // no timeline, no paging
+    }
+
+    $.expr[':']['timeline-page'] = $.expr.createPseudo(function(page) {
+        // Select timeline elements by their page.  NB: only works on activity LIs.
+        return function(elem) {
+            return $(elem).data('page') == page;
+        }
+    });
+
     function detectFeatures() {
         var hasAPI = window.history && window.history.pushState && window.history.replaceState;
         var iOS4 = navigator.userAgent.match(/iP(od|one|ad).+\bOS\s+[1-4]|WebApps\/.+CFNetwork/);
@@ -72,7 +84,6 @@ $(function() {
         var elemAdjustment = newTop - oldTop;
         var viewportAdjustment = scrollTop - oldScrollTop;
         $window.scrollTop(scrollTop + elemAdjustment - viewportAdjustment);
-        //console.log('restoreSP', oldTop, newTop, elemAdjustment, viewportAdjustment, scrollTop, $window.scrollTop());
         $(window).trigger('scroll');
     }
 
@@ -125,36 +136,35 @@ $(function() {
     }
 
     function pageOut(newer) {
-        // Remove a single page of either newer or older content.
+        // Remove newest or oldest page to keep memory usage in check.
         var $timeline = $('.timeline li');
-        var limit = $('.timeline').data('limit');
-        var range = newer ? [0, limit] : [-limit, undefined];
-        $timeline.slice(range[0], range[1]).remove();
+        var firstPage = $timeline.first().data('page');
+        var lastPage = $timeline.last().data('page');
+        var numPages = lastPage - firstPage + 1;
+        if (numPages <= ASOptions.maxPages) {
+            return;
+        }
+        var pageToRemove = newer ? firstPage : lastPage;
+        $('.timeline li:timeline-page('+pageToRemove+')').remove();
         $('.no-more.'+(newer ? 'newer' : 'older')).remove();
     }
 
     function pageIn(newer, url) {
         // Load a single page of either newer or older content from the URL.
-        // If the added page causes too many to be on screen, calls pageOut
+        // Then calls pageOut to ensure that not too many are loaded at once,
         // to keep memory usage in check.  Also uses save/restoreScrollPosition
         // to try to keep the same content in view at the same place.
         $.get(url, function(html) {
             var $html = $(html);
             var $timeline = $('.timeline');
+            var newPage = $html.data('page');
             var limit = $('.timeline').data('limit');
             saveScrollPosition();
-            if ($html.length < limit) {
-                var method = newer ? 'before' : 'after';
-                var cls = newer ? 'newer' : 'older';
-                $timeline[method]('<div class="no-more '+cls+'">No more activities</div>');
-            }
-            var method = newer ? 'prepend' : 'append';
-            $timeline[method]($html);
-            var firstPage = $('.timeline li:first').data('page');
-            var lastPage = $('.timeline li:last').data('page');
-            if (lastPage - firstPage >= 3) {
-                pageOut(!newer);
+            if ($html.length < limit || newPage == 0) {
+                makeNoMore(newer);
             }
+            $timeline[newer ? 'prepend' : 'append']($html);
+            pageOut(!newer);
             if (ASOptions.useShowMore) {
                 // this has to be here instead of showMoreLink handler to
                 // ensure that scroll changes between added / removed content
@@ -168,6 +178,13 @@ $(function() {
         });
     }
 
+    function makeNoMore(newer) {
+        var $timeline = $('.timeline');
+        var method = newer ? 'before' : 'after';
+        var cls = newer ? 'newer' : 'older';
+        $timeline[method]('<div class="no-more '+cls+'">No more activities</div>');
+    }
+
     function makeShowMoreLink(newer, targetPage, limit) {
         var $link = $('<a class="show-more">Show More</a>');
         $link.addClass(newer ? 'newer' : 'older');
@@ -176,32 +193,31 @@ $(function() {
             event.preventDefault();
             pageIn(newer, this.href);
         });
-        return $link;
+        $('.timeline')[newer ? 'before' : 'after']($link);
     }
 
     function updateShowMore() {
         // Update the state of the Show More links when using "Show More"-style
         // advanced paging.
-        var $timeline = $('.timeline');
-        if (!$timeline.length) {
-            return;
-        }
         var limit = $('.timeline').data('limit');
         var firstPage = $('.timeline li:first').data('page');
         var lastPage = $('.timeline li:last').data('page');
-        var noMoreNewer = firstPage == 0 || $('.no-more.newer').length;
+        var noMoreNewer = $('.no-more.newer').length;
         var noMoreOlder = $('.no-more.older').length;
         $('.show-more').remove();  // TODO: could update HREFs instead of always re-creating links
         if (!noMoreNewer) {
-            $timeline.before(makeShowMoreLink(true, firstPage-1, limit));
+            makeShowMoreLink(true, firstPage-1, limit);
         }
         if (!noMoreOlder) {
-            $timeline.after(makeShowMoreLink(false, lastPage+1, limit));
+            makeShowMoreLink(false, lastPage+1, limit);
         }
     }
 
     function enableShowMore() {
         $('.page_list').remove();
+        if ($('.timeline li:first').data('page') == 0) {
+            makeNoMore(true);
+        }
         updateShowMore();
     }
 


[09/28] git commit: [#7002] Improved profile section caching and added docstring

Posted by jo...@apache.org.
[#7002] Improved profile section caching and added docstring

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: dc1ade5827eeb4b3d80fc3c11de6cdc4de2b814b
Parents: cae66cc
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Thu Jan 16 16:03:13 2014 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jan 22 14:26:21 2014 +0000

----------------------------------------------------------------------
 Allura/allura/ext/user_profile/user_main.py     | 21 +++++++++++++++++---
 .../tests/functional/test_user_profile.py       | 12 +++++------
 2 files changed, 24 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dc1ade58/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 530d5a3..788d8a2 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -26,7 +26,6 @@ from formencode import validators
 from tg import expose, redirect, validate, flash
 import tg
 from webob import exc
-from ming.utils import LazyProperty
 from jinja2 import Markup
 
 from allura import version
@@ -88,8 +87,23 @@ class UserProfileApp(Application):
     def uninstall(self, project):  # pragma no cover
         pass
 
-    @LazyProperty
+    @property
     def profile_sections(self):
+        """
+        Loads and caches user profile sections.
+
+        Profile sections are loaded unless disabled (see
+        `allura.lib.helpers.iter_entry_points`) and are sorted according
+        to the `user_profile_sections.order` config value.
+
+        The config should contain a comma-separated list of entry point names
+        in the order that they should appear in the profile.  Unknown or
+        disabled sections are ignored, and available sections that are not
+        specified in the order come after all explicitly ordered sections,
+        sorted randomly.
+        """
+        if hasattr(UserProfileApp, '_sections'):
+            return UserProfileApp._sections
         sections = {}
         for ep in h.iter_entry_points('allura.user_profile.sections'):
             sections[ep.name] = ep.load()
@@ -98,7 +112,8 @@ class UserProfileApp(Application):
         for section in re.split(r'\s*,\s*', section_ordering):
             if section in sections:
                 ordered_sections.append(sections.pop(section))
-        return ordered_sections + sections.values()
+        UserProfileApp._sections = ordered_sections + sections.values()
+        return UserProfileApp._sections
 
 
 class UserProfileController(BaseController, FeedController):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dc1ade58/Allura/allura/tests/functional/test_user_profile.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py
index 71ae05a..1f58868 100644
--- a/Allura/allura/tests/functional/test_user_profile.py
+++ b/Allura/allura/tests/functional/test_user_profile.py
@@ -173,9 +173,9 @@ class TestUserProfile(TestController):
                         eps[2].load(),
                         eps[0].load(),
                     ])
-                r = self.app.get('/u/test-user/profile')
-                assert_in('Section a', r.body)
-                assert_in('Section b', r.body)
-                assert_in('Section c', r.body)
-                assert_in('Section d', r.body)
-                assert_not_in('Section f', r.body)
+        r = self.app.get('/u/test-user/profile')
+        assert_in('Section a', r.body)
+        assert_in('Section b', r.body)
+        assert_in('Section c', r.body)
+        assert_in('Section d', r.body)
+        assert_not_in('Section f', r.body)


[19/28] git commit: [#7002] Improved documentation of user profile sections extension point

Posted by jo...@apache.org.
[#7002] Improved documentation of user profile sections extension point

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: 88b250031a3b93c0568d7a819c5c38e93189aaf7
Parents: 6c2cb1a
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Jan 22 23:04:22 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Wed Jan 22 23:13:31 2014 +0000

----------------------------------------------------------------------
 Allura/allura/ext/user_profile/user_main.py | 43 +++++++++++++++++++++++-
 Allura/docs/api/ext.rst                     | 28 +++++++++++++++
 Allura/docs/api/ext/user_profile.rst        | 24 +++++++++++++
 Allura/docs/extending.rst                   |  5 +--
 ForgeActivity/forgeactivity/main.py         |  5 ++-
 5 files changed, 99 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/88b25003/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 31e4bf0..a9758e1 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -47,6 +47,10 @@ class F(object):
 
 
 class UserProfileApp(Application):
+    """
+    This is the Profile tool, which is automatically installed as
+    the default (first) tool on any user project.
+    """
     __version__ = version.__version__
     tool_label = 'Profile'
     max_instances = 0
@@ -90,7 +94,8 @@ class UserProfileApp(Application):
     @property
     def profile_sections(self):
         """
-        Loads and caches user profile sections.
+        Loads and caches user profile sections from the entry-point
+        group ``[allura.user_profile.sections]``.
 
         Profile sections are loaded unless disabled (see
         `allura.lib.helpers.iter_entry_points`) and are sorted according
@@ -202,15 +207,51 @@ class UserProfileController(BaseController, FeedController):
 
 
 class ProfileSectionBase(object):
+    """
+    This is the base class for sections on the Profile tool.
+
+    .. py:attribute:: template
+
+       A resource string pointing to the template for this section.  E.g.::
+
+           template = "allura.ext.user_profile:templates/projects.html"
+
+    Sections must be pointed to by an entry-point in the group
+    ``[allura.user_profile.sections]``.
+    """
     template = ''
 
+    def __init__(self, user, project):
+        """
+        Creates a section for the given :param:`user` and user
+        :param:`project`.  Stores the values as attributes of
+        the same name.
+        """
+        self.user = user
+        self.project = project
+
     def check_display(self):
+        """
+        Should return True if the section should be displayed.
+        """
         return True
 
     def prepare_context(self, context):
+        """
+        Should be overridden to add any values to the template context prior
+        to display.
+        """
         return context
 
     def display(self, *a, **kw):
+        """
+        Renders the section using the context from :meth:`prepare_context`
+        and the :attr:`template`, if :meth:`check_display` returns True.
+
+        If overridden or this base class is not used, this method should
+        return either plain text (which will be escaped) or a `jinja2.Markup`
+        instance.
+        """
         if not self.check_display():
             return ''
         tmpl = g.jinja2_env.get_template(self.template)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/88b25003/Allura/docs/api/ext.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/api/ext.rst b/Allura/docs/api/ext.rst
new file mode 100644
index 0000000..9f1580b
--- /dev/null
+++ b/Allura/docs/api/ext.rst
@@ -0,0 +1,28 @@
+..     Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+
+.. _ext_module:
+
+:mod:`allura.ext`
+--------------------------------
+
+.. toctree::
+   :maxdepth: 1
+   :glob:
+
+   ext/*
+

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/88b25003/Allura/docs/api/ext/user_profile.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/api/ext/user_profile.rst b/Allura/docs/api/ext/user_profile.rst
new file mode 100644
index 0000000..f247693
--- /dev/null
+++ b/Allura/docs/api/ext/user_profile.rst
@@ -0,0 +1,24 @@
+..     Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+
+.. _user_profile_module:
+
+:mod:`allura.ext.user_profile`
+-------------------------------------
+
+.. automodule:: allura.ext.user_profile.user_main
+    :members:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/88b25003/Allura/docs/extending.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/extending.rst b/Allura/docs/extending.rst
index c39d572..9758f55 100644
--- a/Allura/docs/extending.rst
+++ b/Allura/docs/extending.rst
@@ -15,8 +15,8 @@
        specific language governing permissions and limitations
        under the License.
 
-Extending Allura with Entry Points
-===================================
+Extension APIs and Entry Points
+===============================
 
 There are many extension points to extending Allura.  They all make themselves
 known to Allura via python entry points defined in ``setup.py``.  Many are then
@@ -35,6 +35,7 @@ The available extension points for Allura are:
 * ``site_stats`` in the root API data.  Docs in :class:`allura.controllers.rest.RestController`
 * :mod:`allura.lib.package_path_loader` (for overriding templates)
 * ``[allura.timers]`` functions which return a list or single :class:`timermiddleware.Timer` which will be included in stats.log timings
+* :mod:`allura.ext.user_profile`
 
 A listing of available 3rd-party extensions is at https://forge-allura.apache.org/p/allura/wiki/Extensions/
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/88b25003/ForgeActivity/forgeactivity/main.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/main.py b/ForgeActivity/forgeactivity/main.py
index a86d00f..da81307 100644
--- a/ForgeActivity/forgeactivity/main.py
+++ b/ForgeActivity/forgeactivity/main.py
@@ -206,9 +206,8 @@ class ForgeActivityRestController(BaseController):
 class ForgeActivityProfileSection(ProfileSectionBase):
     template = 'forgeactivity:templates/widgets/profile_section.html'
 
-    def __init__(self, user, project):
-        self.user = user
-        self.project = project
+    def __init__(self, *a, **kw):
+        super(ForgeActivityProfileSection, self).__init__(*a, **kw)
         self.activity_app = self.project.app_instance('activity')
 
     def check_display(self):


[17/28] git commit: [#6393] Remove download button from default wiki text

Posted by jo...@apache.org.
[#6393] Remove download button from default wiki text

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


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

Branch: refs/heads/cj/4257
Commit: a2bc2dd6444f1271a59ace9bf956c57b1c5072b7
Parents: 586eb2c
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Jan 21 21:43:58 2014 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Jan 22 19:36:00 2014 +0000

----------------------------------------------------------------------
 ForgeWiki/forgewiki/wiki_main.py | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a2bc2dd6/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 2709733..01a6008 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -146,6 +146,16 @@ class ForgeWikiApp(Application):
             if globals is not None:
                 session(globals).flush(globals)
 
+    def default_root_page_text(self):
+        return """Welcome to your wiki!
+
+This is the default page, edit it as you see fit. To add a new page simply reference it within brackets, e.g.: [SamplePage].
+
+The wiki uses [Markdown](%s) syntax.
+
+[[members limit=20]]
+""" % (self.url + 'markdown_syntax/')
+
     @Property
     def show_discussion():
         def fget(self):
@@ -272,16 +282,7 @@ class ForgeWikiApp(Application):
             with h.push_config(c, app=self):
                 p = WM.Page.upsert(new_root)
                 p.viewable_by = ['all']
-                url = c.app.url + 'markdown_syntax' + '/'
-                p.text = """Welcome to your wiki!
-
-This is the default page, edit it as you see fit. To add a new page simply reference it within brackets, e.g.: [SamplePage].
-
-The wiki uses [Markdown](%s) syntax.
-
-[[members limit=20]]
-[[download_button]]
-""" % url
+                p.text = self.default_root_page_text()
                 p.commit()
 
     def uninstall(self, project):


[11/28] git commit: [#7002] Fixed test failing when run after other tests

Posted by jo...@apache.org.
[#7002] Fixed test failing when run after other tests

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: 9cd00168ca5e20a4b6b221e28dd7f2c76ae5cdac
Parents: dc1ade5
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Jan 21 22:57:45 2014 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jan 22 14:26:21 2014 +0000

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_user_profile.py | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9cd00168/Allura/allura/tests/functional/test_user_profile.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py
index 1f58868..a243bf5 100644
--- a/Allura/allura/tests/functional/test_user_profile.py
+++ b/Allura/allura/tests/functional/test_user_profile.py
@@ -163,16 +163,16 @@ class TestUserProfile(TestController):
             return m
         eps = map(ep, ['a', 'b', 'c', 'd'])
         order = {'user_profile_sections.order': 'b, d,c , f '}
+        delattr(type(app), '_sections')
         with mock.patch('allura.lib.helpers.iter_entry_points') as iep:
             with mock.patch.dict(tg.config, order):
                 iep.return_value = eps
                 sections = app.profile_sections
                 assert_equal(sections, [
-                        eps[1].load(),
-                        eps[3].load(),
-                        eps[2].load(),
-                        eps[0].load(),
-                    ])
+                    eps[1].load(),
+                    eps[3].load(),
+                    eps[2].load(),
+                    eps[0].load()])
         r = self.app.get('/u/test-user/profile')
         assert_in('Section a', r.body)
         assert_in('Section b', r.body)


[07/28] git commit: [#7002] Remove unused user_profile.css

Posted by jo...@apache.org.
[#7002] Remove unused user_profile.css

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


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

Branch: refs/heads/cj/4257
Commit: 168a80f8676907a06b0fcdf49ee62434f79aa249
Parents: fd3bc74
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Wed Jan 22 14:26:09 2014 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jan 22 14:26:21 2014 +0000

----------------------------------------------------------------------
 .../ext/user_profile/nf/home/css/user_profile.css | 18 ------------------
 .../templates/user_dashboard_configuration.html   |  6 ------
 .../ext/user_profile/templates/user_index.html    |  5 -----
 3 files changed, 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/168a80f8/Allura/allura/ext/user_profile/nf/home/css/user_profile.css
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/nf/home/css/user_profile.css b/Allura/allura/ext/user_profile/nf/home/css/user_profile.css
deleted file mode 100644
index a5d9eba..0000000
--- a/Allura/allura/ext/user_profile/nf/home/css/user_profile.css
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
-*/

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/168a80f8/Allura/allura/ext/user_profile/templates/user_dashboard_configuration.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/templates/user_dashboard_configuration.html b/Allura/allura/ext/user_profile/templates/user_dashboard_configuration.html
index 0ff962a..e543b5f 100644
--- a/Allura/allura/ext/user_profile/templates/user_dashboard_configuration.html
+++ b/Allura/allura/ext/user_profile/templates/user_dashboard_configuration.html
@@ -22,12 +22,6 @@
 
 {% block header %}Configure Dashboard for {{user.display_name}}{% endblock %}
 
-{% block extra_css %}
-    <link rel="stylesheet" type="text/css"
-          href="{{g.app_static('css/user_profile.css')}}"/>
-{% endblock %}
-
-
 {% block content %}
 
 {% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/168a80f8/Allura/allura/ext/user_profile/templates/user_index.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/user_profile/templates/user_index.html b/Allura/allura/ext/user_profile/templates/user_index.html
index e567095..e639b58 100644
--- a/Allura/allura/ext/user_profile/templates/user_index.html
+++ b/Allura/allura/ext/user_profile/templates/user_index.html
@@ -23,11 +23,6 @@
 
 {% block header %}{{ user.display_name|default(user.username) }}{% endblock %}
 
-{% block extra_css %}
-  <link rel="stylesheet" type="text/css"
-        href="{{g.app_static('css/user_profile.css')}}"/>
-{% endblock %}
-
 {% block head %}
   <link rel="alternate" type="application/rss+xml" title="RSS" href="feed.rss">
   <link rel="alternate" type="application/atom+xml" title="Atom" href="feed.atom">


[18/28] git commit: Fix some tests and bump GC wiki import version

Posted by jo...@apache.org.
Fix some tests and bump GC wiki import version

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


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

Branch: refs/heads/cj/4257
Commit: 6c2cb1a6c269307faa9770f1da1562301254f9ee
Parents: a2bc2dd
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Wed Jan 22 22:39:18 2014 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jan 22 22:39:18 2014 +0000

----------------------------------------------------------------------
 Allura/allura/tests/test_helpers.py   | 2 +-
 Allura/allura/tests/test_mail_util.py | 4 ++--
 requirements-sf.txt                   | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6c2cb1a6/Allura/allura/tests/test_helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_helpers.py b/Allura/allura/tests/test_helpers.py
index 48f4309..d89df75 100644
--- a/Allura/allura/tests/test_helpers.py
+++ b/Allura/allura/tests/test_helpers.py
@@ -273,7 +273,7 @@ def test_log_if_changed():
 
 def test_get_tool_package():
     assert h.get_tool_package('tickets') == 'forgetracker'
-    assert h.get_tool_package('Wiki') == 'forgewiki'
+    assert h.get_tool_package('Tickets') == 'forgetracker'
     assert h.get_tool_package('wrong_tool') == ''
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6c2cb1a6/Allura/allura/tests/test_mail_util.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_mail_util.py b/Allura/allura/tests/test_mail_util.py
index 6b1657d..64a1c92 100644
--- a/Allura/allura/tests/test_mail_util.py
+++ b/Allura/allura/tests/test_mail_util.py
@@ -27,7 +27,7 @@ from ming.orm import ThreadLocalORMSession
 
 from alluratest.controller import setup_basic_test, setup_global_objects
 from allura.lib.utils import ConfigProxy
-
+from allura.app import Application
 from allura.lib.mail_util import (
     parse_address,
     parse_message,
@@ -74,7 +74,7 @@ class TestReactor(unittest.TestCase):
             'foo@wiki.test.p' + config.common_suffix)
         assert_equal(topic, 'foo')
         assert_equal(project.shortname, 'test')
-        assert_equal(app.__class__.__name__, 'ForgeWikiApp')
+        assert_true(isinstance(app, Application))
 
     def test_unicode_simple_message(self):
         charset = 'utf-8'

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6c2cb1a6/requirements-sf.txt
----------------------------------------------------------------------
diff --git a/requirements-sf.txt b/requirements-sf.txt
index 8dd935a..1db3bd4 100644
--- a/requirements-sf.txt
+++ b/requirements-sf.txt
@@ -6,7 +6,7 @@ kombu==1.0.4
 coverage==3.5a1-20110413
 ForgeHg==0.1.21
 ForgePastebin==0.3.0
-GoogleCodeWikiImporter==0.4.7
+GoogleCodeWikiImporter==0.4.8
 mechanize==0.2.4
 mercurial==1.4.3
 MySQL-python==1.2.3c1


[20/28] git commit: [#4257] Added basic paging to Activity page

Posted by jo...@apache.org.
[#4257] Added basic paging to Activity page

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: 28f74b117b018468a80558824601a085afd2cb90
Parents: 88b2500
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Sat Jan 18 00:46:57 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:26:26 2014 +0000

----------------------------------------------------------------------
 Allura/allura/lib/widgets/form_fields.py         | 14 +++++++++++++-
 Allura/allura/templates/widgets/page_list.html   |  6 ++++--
 ForgeActivity/forgeactivity/main.py              | 13 +++++++++++--
 ForgeActivity/forgeactivity/templates/index.html |  1 +
 4 files changed, 29 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/28f74b11/Allura/allura/lib/widgets/form_fields.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/form_fields.py b/Allura/allura/lib/widgets/form_fields.py
index 2249372..e3060dc 100644
--- a/Allura/allura/lib/widgets/form_fields.py
+++ b/Allura/allura/lib/widgets/form_fields.py
@@ -285,7 +285,9 @@ class PageList(ew_core.Widget):
         limit=None,
         count=0,
         page=0,
-        show_label=False)
+        show_label=True,
+        show_if_single_page=False,
+        force_next=False)
 
     def paginator(self, count, page, limit, zero_based_pages=True):
         page_offset = 1 if zero_based_pages else 0
@@ -298,6 +300,16 @@ class PageList(ew_core.Widget):
         return paginate.Page(range(count), page + page_offset, int(limit),
                              url=page_url)
 
+    def prepare_context(self, context):
+        context = super(PageList, self).prepare_context(context)
+        count = context['count']
+        page = context['page']
+        limit = context['limit']
+        context['paginator'] = self.paginator(count, page, limit)
+        if context['force_next']:
+            context['paginator'].next_page = context['paginator'].page + 1
+        return context
+
     def resources(self):
         yield ew.CSSLink('css/page_list.css')
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/28f74b11/Allura/allura/templates/widgets/page_list.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/page_list.html b/Allura/allura/templates/widgets/page_list.html
index a5f39b2..64ff18f 100644
--- a/Allura/allura/templates/widgets/page_list.html
+++ b/Allura/allura/templates/widgets/page_list.html
@@ -18,8 +18,10 @@
 -#}
 <div>
   <div class="page_list">
-    {% set paginator = widget.paginator(count, page, limit) %}
-    {{paginator.pager('$link_first $link_previous ~2~ $link_next $link_last (Page $page of $page_count)')}}
+    {{paginator.pager(
+            format='$link_first $link_previous ~2~ $link_next $link_last' + (show_label and ' (Page $page of $page_count)' or ''),
+            show_if_single_page=show_if_single_page
+        )}}
   </div>
   <div class="clear"></div>
 </div>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/28f74b11/ForgeActivity/forgeactivity/main.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/main.py b/ForgeActivity/forgeactivity/main.py
index da81307..991bb61 100644
--- a/ForgeActivity/forgeactivity/main.py
+++ b/ForgeActivity/forgeactivity/main.py
@@ -22,7 +22,7 @@ from pylons import tmpl_context as c, app_globals as g
 from pylons import request, response
 from tg import expose, validate, config
 from tg.decorators import with_trailing_slash, without_trailing_slash
-from paste.deploy.converters import asbool
+from paste.deploy.converters import asbool, asint
 from webob import exc
 from webhelpers import feedgenerator as FG
 
@@ -33,6 +33,7 @@ from allura.lib.security import require_authenticated
 from allura.model.timeline import perm_check
 from allura.lib import helpers as h
 from allura.lib.decorators import require_post
+from allura.lib.widgets.form_fields import PageList
 from allura.ext.user_profile import ProfileSectionBase
 
 from .widgets.follow import FollowToggle
@@ -65,6 +66,7 @@ class ForgeActivityApp(Application):
 
 class W:
     follow_toggle = FollowToggle()
+    page_list = PageList()
 
 
 class ForgeActivityController(BaseController):
@@ -91,6 +93,7 @@ class ForgeActivityController(BaseController):
             raise exc.HTTPNotFound()
 
         c.follow_toggle = W.follow_toggle
+        c.page_list = W.page_list
         if c.project.is_user_project:
             followee = c.project.user_project_of
             actor_only = followee != c.user
@@ -103,7 +106,13 @@ class ForgeActivityController(BaseController):
                                            limit=kw.get('limit', 100),
                                            actor_only=actor_only,
                                            filter_func=perm_check(c.user))
-        return dict(followee=followee, following=following, timeline=timeline)
+        return dict(
+                followee=followee,
+                following=following,
+                timeline=timeline,
+                page=asint(kw.get('page', 0)),
+                limit=asint(kw.get('limit', 100)),
+            )
 
     @expose('jinja:forgeactivity:templates/index.html')
     @with_trailing_slash

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/28f74b11/ForgeActivity/forgeactivity/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/index.html b/ForgeActivity/forgeactivity/templates/index.html
index 435fc82..e63c904 100644
--- a/ForgeActivity/forgeactivity/templates/index.html
+++ b/ForgeActivity/forgeactivity/templates/index.html
@@ -57,6 +57,7 @@
           {% endif %}
         </li>
         {% endfor %}
+        {{c.page_list.display(limit=1, page=page, count=page+1, show_label=False, show_if_single_page=True, force_next=True)}}
     </ul>
   {% endif %}
 </div>


[16/28] git commit: [#6393] Cleanup

Posted by jo...@apache.org.
[#6393] Cleanup

* Removed download button test
* Changed show_download_button macro default to False
* Added docs for extending Allura with macros

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


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

Branch: refs/heads/cj/4257
Commit: 586eb2c1931754e69eab10c0b8a07d76b864dd12
Parents: bc594e1
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Thu Jan 16 13:11:51 2014 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Jan 22 19:35:54 2014 +0000

----------------------------------------------------------------------
 Allura/allura/lib/app_globals.py               |  2 +
 Allura/allura/lib/macro.py                     |  6 +--
 Allura/allura/templates/neighborhood_help.html |  2 +-
 Allura/allura/tests/test_globals.py            |  8 ----
 Allura/docs/extending.rst                      | 41 +++++++++++++++++++++
 5 files changed, 47 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/586eb2c1/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index f53776d..d4f1b06 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -254,6 +254,8 @@ class Globals(object):
             stats=_cache_eps('allura.stats'),
             site_stats=_cache_eps('allura.site_stats'),
             admin=_cache_eps('allura.admin'),
+            # macro eps are used solely for ensuring that external macros are
+            # imported (after load, the ep itself is not used)
             macros=_cache_eps('allura.macros'),
         )
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/586eb2c1/Allura/allura/lib/macro.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/macro.py b/Allura/allura/lib/macro.py
index 957fcb8..efb1433 100644
--- a/Allura/allura/lib/macro.py
+++ b/Allura/allura/lib/macro.py
@@ -164,7 +164,7 @@ def project_blog_posts(max_number=5, sort='timestamp', summary=False, mount_poin
 def get_projects_for_macro(
         category=None, display_mode='grid', sort='last_updated',
         show_total=False, limit=100, labels='', award='', private=False,
-        columns=1, show_proj_icon=True, show_download_button=True, show_awards_banner=True,
+        columns=1, show_proj_icon=True, show_download_button=False, show_awards_banner=True,
         grid_view_tools='',
         initial_q={}):
     from allura.lib.widgets.project_list import ProjectList
@@ -267,7 +267,7 @@ def get_projects_for_macro(
 @macro('neighborhood-wiki')
 def projects(category=None, display_mode='grid', sort='last_updated',
              show_total=False, limit=100, labels='', award='', private=False,
-             columns=1, show_proj_icon=True, show_download_button=True, show_awards_banner=True,
+             columns=1, show_proj_icon=True, show_download_button=False, show_awards_banner=True,
              grid_view_tools=''):
     initial_q = dict(neighborhood_id=c.project.neighborhood_id)
     return get_projects_for_macro(
@@ -281,7 +281,7 @@ def projects(category=None, display_mode='grid', sort='last_updated',
 @macro('userproject-wiki')
 def my_projects(category=None, display_mode='grid', sort='last_updated',
                 show_total=False, limit=100, labels='', award='', private=False,
-                columns=1, show_proj_icon=True, show_download_button=True, show_awards_banner=True,
+                columns=1, show_proj_icon=True, show_download_button=False, show_awards_banner=True,
                 grid_view_tools=''):
 
     myproj_user = c.project.user_project_of

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/586eb2c1/Allura/allura/templates/neighborhood_help.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/neighborhood_help.html b/Allura/allura/templates/neighborhood_help.html
index ed57b53..5c5d27a 100644
--- a/Allura/allura/templates/neighborhood_help.html
+++ b/Allura/allura/templates/neighborhood_help.html
@@ -45,7 +45,7 @@
     <li><code>display_mode</code> = grid/list.  Default is 'grid'</li>
     <li><code>show_proj_icon</code> = yes/no.  Default 'yes'</li>
     <li><code>grid_view_tools</code> = git,hg,svn,tickets,wiki... Limit the tools shown in project list. Multivalue option (example grid_view_tools=git,wiki).  Default ''</li>
-    <li><code>show_download_button</code> = yes/no.  Default 'yes'</li>
+    <li><code>show_download_button</code> = yes/no.  Default 'no'</li>
 	<li><code>show_awards_banner</code> = yes/no.  Default 'yes'</li>
     <li><code>sort</code> = last_updated/alpha/random/last_registered.  Default 'last_updated'</li>
     <li><code>show_total</code> = yes/no.  Adds a sentence with a total count of how many projects are listed. Default 'no'</li>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/586eb2c1/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index 1910e89..c8553a1 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -499,14 +499,6 @@ def test_projects_macro():
         r = g.markdown_wiki.convert('[[projects display_mode=list columns=3]]')
         assert two_column_style not in r
 
-        # test project download button
-        r = g.markdown_wiki.convert(
-            '[[projects display_mode=list show_download_button=True]]')
-        assert 'download-button' in r
-        r = g.markdown_wiki.convert(
-            '[[projects display_mode=list show_download_button=False]]')
-        assert 'download-button' not in r
-
 
 @td.with_wiki
 def test_limit_tools_macro():

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/586eb2c1/Allura/docs/extending.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/extending.rst b/Allura/docs/extending.rst
index 7fb46da..c39d572 100644
--- a/Allura/docs/extending.rst
+++ b/Allura/docs/extending.rst
@@ -64,3 +64,44 @@ The events that allura publishes are:
 * repo_cloned
 * repo_refreshed
 * repo_clone_task_failed
+
+
+Markdown Macros
+===============
+
+Most text inputs in Allura accept Markdown text which is parsed and turned into
+HTML before being rendered. The Markdown text may contain "macros" - custom
+commands which extend the Markdown language. Here's an example of a macro
+that comes with Allura::
+
+    [[project_admins]]
+
+Include this macro in a wiki page or other Markdown content, and when rendered
+it will be replaced by an actual list of the project's admin users.
+
+Extending Allura with your own macros is simple, requiring two basic steps:
+
+1. Decide on a name for your macro, then create a function with that name, and
+   decorate it with the `macro()` decorator from Allura. The function can
+   accept keyword arguments, and must return text or HTML. For example::
+
+    from allura.lib.macro import macro
+
+    @macro()
+    def hello(name='World'):
+        return "<p>Hello {}!</p>".format(name)
+
+2. Add an entry point for your macro to the `setup.py` for your package::
+
+    [allura.macros]
+    hello_macro = mypkg.mymodule:hello
+
+Note that the key name (`hello_macro` in this case) doesn't matter - the macro
+is named after the function name. Our example macro could be used in a couple
+ways::
+
+    [[hello]]
+    [[hello name=Universe]]
+
+For more help with macros, consult the source code for the macros that ship
+with Allura. You can find them in the `allura.lib.macro` package.


[15/28] git commit: [#6393] Load macros from external packages

Posted by jo...@apache.org.
[#6393] Load macros from external packages

* Moved download_button macro out of allura
* Fixed/cleaned up tests that rely on pylons globals

Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>


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

Branch: refs/heads/cj/4257
Commit: bc594e1625698bdb83577749d17fba336fe594a8
Parents: 5d46b78
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Jan 14 18:06:46 2014 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Jan 22 19:35:54 2014 +0000

----------------------------------------------------------------------
 Allura/allura/lib/app_globals.py                |  1 +
 Allura/allura/lib/macro.py                      | 20 ------------
 Allura/allura/lib/widgets/macros.py             | 11 -------
 .../templates/widgets/download_button.html      | 19 ------------
 Allura/allura/tests/model/test_openid.py        |  9 ++----
 Allura/allura/tests/test_app.py                 |  7 ++---
 Allura/allura/tests/test_globals.py             | 32 +++++++++-----------
 Allura/allura/tests/test_utils.py               |  1 -
 AlluraTest/alluratest/controller.py             |  5 +--
 9 files changed, 24 insertions(+), 81 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bc594e16/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index ecc7b35..f53776d 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -254,6 +254,7 @@ class Globals(object):
             stats=_cache_eps('allura.stats'),
             site_stats=_cache_eps('allura.site_stats'),
             admin=_cache_eps('allura.admin'),
+            macros=_cache_eps('allura.macros'),
         )
 
         # Zarkov logger

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bc594e16/Allura/allura/lib/macro.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/macro.py b/Allura/allura/lib/macro.py
index d22b431..957fcb8 100644
--- a/Allura/allura/lib/macro.py
+++ b/Allura/allura/lib/macro.py
@@ -318,26 +318,6 @@ def gittip_button(username):
     response = button.display(username=username)
     return response
 
-# FIXME: this is SourceForge specific - need to provide a way for macros
-# to come from other packages
-
-
-@macro()
-def download_button():
-    from allura.lib.widgets.macros import DownloadButton
-    button = DownloadButton(project=c.project)
-    try:
-        res_mgr = g.resource_manager
-    except TypeError:
-        # e.g. "TypeError: No object (name: widget_context) has been registered for this thread"
-        # this is an ugly way to check to see if we're outside of a web request
-        # and avoid errors
-        return '[[download_button]]'
-    else:
-        res_mgr.register(button)
-        response = button.display(project=c.project)
-        return response
-
 
 @macro()
 def include(ref=None, **kw):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bc594e16/Allura/allura/lib/widgets/macros.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/macros.py b/Allura/allura/lib/widgets/macros.py
index 18268cb..77c329a 100644
--- a/Allura/allura/lib/widgets/macros.py
+++ b/Allura/allura/lib/widgets/macros.py
@@ -33,17 +33,6 @@ class GittipButton(ew.Widget):
     project = None
 
 
-class DownloadButton(ew.Widget):
-    template = 'jinja:allura:templates/widgets/download_button.html'
-    params = ['project']
-    project = None
-
-    def resources(self):
-        yield ew.jinja2_ew.JSScript('''
-            $(function(){$(".download-button-%s").load("%s");
-        });''' % (self.project._id, self.project.best_download_url()))
-
-
 class NeighborhoodFeeds(ew.Widget):
     template = 'jinja:allura:templates/macro/neighborhood_feeds.html'
     params = ['feeds']

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bc594e16/Allura/allura/templates/widgets/download_button.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/download_button.html b/Allura/allura/templates/widgets/download_button.html
deleted file mode 100644
index 44e3b36..0000000
--- a/Allura/allura/templates/widgets/download_button.html
+++ /dev/null
@@ -1,19 +0,0 @@
-{#-
-       Licensed to the Apache Software Foundation (ASF) under one
-       or more contributor license agreements.  See the NOTICE file
-       distributed with this work for additional information
-       regarding copyright ownership.  The ASF licenses this file
-       to you under the Apache License, Version 2.0 (the
-       "License"); you may not use this file except in compliance
-       with the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-       Unless required by applicable law or agreed to in writing,
-       software distributed under the License is distributed on an
-       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-       KIND, either express or implied.  See the License for the
-       specific language governing permissions and limitations
-       under the License.
--#}
-<p><span class="download-button-{{project._id}}" style="margin-bottom: 1em; display: block;"></span></p>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bc594e16/Allura/allura/tests/model/test_openid.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_openid.py b/Allura/allura/tests/model/test_openid.py
index 056f030..30dcdb4 100644
--- a/Allura/allura/tests/model/test_openid.py
+++ b/Allura/allura/tests/model/test_openid.py
@@ -23,22 +23,17 @@ Model tests for openid_model
 import time
 
 import mock
-from pylons import tmpl_context as c, app_globals as g
-from pylons import request
-from webob import Request
 from openid.association import Association
 
 from ming.orm.ormsession import ThreadLocalORMSession
 
-from allura.lib.app_globals import Globals
+from alluratest.controller import setup_unit_test
 from allura import model as M
 from allura.lib import helpers as h
 
 
 def setUp():
-    g._push_object(Globals())
-    c._push_object(mock.Mock())
-    request._push_object(Request.blank('/'))
+    setup_unit_test()
     ThreadLocalORMSession.close_all()
     M.EmailAddress.query.remove({})
     M.OpenIdNonce.query.remove({})

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bc594e16/Allura/allura/tests/test_app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_app.py b/Allura/allura/tests/test_app.py
index f5f5ac4..a31f112 100644
--- a/Allura/allura/tests/test_app.py
+++ b/Allura/allura/tests/test_app.py
@@ -15,17 +15,16 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from pylons import tmpl_context as c, app_globals as g
+from pylons import tmpl_context as c
 import mock
 from ming.base import Object
 
+from alluratest.controller import setup_unit_test
 from allura import app
-from allura.lib.app_globals import Globals
 
 
 def setUp():
-    g._push_object(Globals())
-    c._push_object(mock.Mock())
+    setup_unit_test()
     c.user._id = None
     c.project = mock.Mock()
     c.project.name = 'Test Project'

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bc594e16/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index e537c2d..1910e89 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -26,13 +26,16 @@ import hashlib
 from mock import patch
 
 from bson import ObjectId
-
 from nose.tools import with_setup, assert_equal, assert_in
 from pylons import tmpl_context as c, app_globals as g
 import tg
 
 from ming.orm import ThreadLocalORMSession
-from alluratest.controller import setup_basic_test, setup_global_objects
+from alluratest.controller import (
+        setup_basic_test,
+        setup_global_objects,
+        setup_unit_test,
+        )
 
 from allura import model as M
 from allura.lib import helpers as h
@@ -46,9 +49,14 @@ from forgeblog import model as BM
 def setUp():
     """Method called by nose once before running the package.  Some functions need it run again to reset data"""
     setup_basic_test()
+    setup_unit_test()
     setup_with_tools()
 
 
+def tearDown():
+    setUp()
+
+
 @td.with_wiki
 def setup_with_tools():
     setup_global_objects()
@@ -66,7 +74,7 @@ def test_app_globals():
         assert g.url('/foo') == 'http://localhost/foo', g.url('/foo')
 
 
-@with_setup(teardown=setUp)  # reset everything we changed
+@with_setup(setUp)
 def test_macro_projects():
     file_name = 'neo-icon-set-454545-256x350.png'
     file_path = os.path.join(
@@ -153,16 +161,6 @@ def test_macro_projects():
         assert '<img alt="Test Project Logo"' not in r
 
 
-def test_macro_download_button():
-    p_nbhd = M.Neighborhood.query.get(name='Projects')
-    p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
-    with h.push_config(c, project=p_test):
-        r = g.markdown_wiki.convert('[[download_button]]')
-    assert_equal(
-        r, '<div class="markdown_content"><p><span class="download-button-%s" style="margin-bottom: 1em; display: block;"></span></p>\n</div>' %
-        p_test._id)
-
-
 def test_macro_gittip_button():
     p_nbhd = M.Neighborhood.query.get(name='Projects')
     p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
@@ -204,7 +202,7 @@ def test_macro_neighborhood_feeds():
         assert 'test content' in r
 
 
-@with_setup(setUp, setUp)  # start clean and reset everything we change
+@with_setup(setUp)
 def test_macro_members():
     p_nbhd = M.Neighborhood.query.get(name='Projects')
     p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)
@@ -220,7 +218,7 @@ def test_macro_members():
                  '</div>')
 
 
-@with_setup(teardown=setUp)  # reset everything we changed
+@with_setup(setUp)
 def test_macro_members_escaping():
     user = M.User.by_username('test-admin')
     user.display_name = u'Test Admin <script>'
@@ -231,7 +229,7 @@ def test_macro_members_escaping():
                  u'</ul>\n</div>')
 
 
-@with_setup(teardown=setUp)  # reset everything we changed
+@with_setup(setUp)
 def test_macro_project_admins():
     user = M.User.by_username('test-admin')
     user.display_name = u'Test Ådmin <script>'
@@ -241,7 +239,7 @@ def test_macro_project_admins():
         r, u'<div class="markdown_content"><h6>Project Admins:</h6>\n<ul class="md-users-list">\n<li><a href="/u/test-admin/">Test \xc5dmin &lt;script&gt;</a></li>\n</ul>\n</div>')
 
 
-@with_setup(teardown=setUp)  # reset everything we changed
+@with_setup(setUp)
 def test_macro_project_admins_one_br():
     p_nbhd = M.Neighborhood.query.get(name='Projects')
     p_test = M.Project.query.get(shortname='test', neighborhood_id=p_nbhd._id)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bc594e16/Allura/allura/tests/test_utils.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_utils.py b/Allura/allura/tests/test_utils.py
index 232763a..92f1e28 100644
--- a/Allura/allura/tests/test_utils.py
+++ b/Allura/allura/tests/test_utils.py
@@ -96,7 +96,6 @@ class TestAntispam(unittest.TestCase):
 
     def setUp(self):
         setup_unit_test()
-        pylons.request._push_object(Request.blank('/'))
         pylons.request.remote_addr = '127.0.0.1'
         self.a = utils.AntiSpam()
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bc594e16/AlluraTest/alluratest/controller.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/controller.py b/AlluraTest/alluratest/controller.py
index 8386d0b..dcd7c53 100644
--- a/AlluraTest/alluratest/controller.py
+++ b/AlluraTest/alluratest/controller.py
@@ -26,9 +26,9 @@ from paste.deploy import loadapp
 from paste.deploy.converters import asbool
 from paste.script.appinstall import SetupCommand
 from pylons import tmpl_context as c, app_globals as g
-from pylons import url, response, session
+from pylons import url, request, response, session
 import tg
-from webob import Response
+from webob import Response, Request
 import ew
 from ming.orm import ThreadLocalORMSession
 import ming.orm
@@ -101,6 +101,7 @@ def setup_unit_test():
     REGISTRY.register(g, Globals())
     REGISTRY.register(c, mock.Mock())
     REGISTRY.register(url, lambda: None)
+    REGISTRY.register(request, Request.blank('/'))
     REGISTRY.register(response, Response())
     REGISTRY.register(session, beaker.session.SessionObject({}))
     REGISTRY.register(allura.credentials, allura.lib.security.Credentials())


[04/28] git commit: [#7047] further debugging to see if BatchIndexer is in use

Posted by jo...@apache.org.
[#7047] further debugging to see if BatchIndexer is in use


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

Branch: refs/heads/cj/4257
Commit: ffbb4201aa4922335d0bfa3760199cfa22c07c87
Parents: afdf505
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Jan 21 14:30:56 2014 -0500
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Tue Jan 21 14:30:56 2014 -0500

----------------------------------------------------------------------
 Allura/allura/model/session.py | 34 +++++++++++++++++++++++++++-------
 1 file changed, 27 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ffbb4201/Allura/allura/model/session.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/session.py b/Allura/allura/model/session.py
index f52d164..5354f87 100644
--- a/Allura/allura/model/session.py
+++ b/Allura/allura/model/session.py
@@ -70,6 +70,22 @@ class ArtifactSessionExtension(SessionExtension):
             except Exception:
                 log.exception(
                     "Failed to update artifact references. Is this a borked project migration?")
+            try:
+                l = logging.getLogger('allura.debug7047')
+                from tg import request
+                task = request.environ.get('task')
+            except:
+                pass
+            else:
+                try:
+                    if task and task.task_name == 'forgetracker.tasks.bulk_edit':
+                        l.debug('this extension: %s', type(self))
+                        l.debug('active session extensions are: %s', artifact_orm_session._kwargs.get('extensions'))
+                        l.debug('threadlocal session is for: %s', [s.impl.db for s in artifact_orm_session._session_registry.values()])
+                        l.debug('current session is: %s', self.session.impl.db)
+                except Exception:
+                    log.info('error running extra debug pt1', exc_info=True)
+
             self.update_index(self.objects_deleted, arefs)
             for obj in self.objects_added:
                 g.zarkov_event('create', extra=obj.index_id())
@@ -93,15 +109,19 @@ class ArtifactSessionExtension(SessionExtension):
             l = logging.getLogger('allura.debug7047')
             from tg import request
             task = request.environ.get('task')
-            if task and task.task_name == 'forgetracker.tasks.bulk_edit':
-                l.debug('session: %s %s', self.session.impl.db, self.session)
-                l.debug('arefs: %s', arefs)
-                l.debug('objects_added: %s', [o._id for o in self.objects_added])
-                l.debug('objects_modified: %s', [o._id for o in self.objects_modified])
-                l.debug('objects_deleted: %s', [o._id for o in self.objects_deleted])
-                l.debug('add_artifacts task: %s', add_task)
         except:
             pass
+        else:
+            try:
+                if task and task.task_name == 'forgetracker.tasks.bulk_edit':
+                    #l.debug('session: %s %s', self.session.impl.db, self.session)
+                    l.debug('arefs: %s', arefs)
+                    l.debug('objects_added: %s', [o._id for o in self.objects_added])
+                    l.debug('objects_modified: %s', [o._id for o in self.objects_modified])
+                    l.debug('objects_deleted: %s', [o._id for o in self.objects_deleted])
+                    l.debug('add_artifacts task: %s', add_task)
+            except Exception:
+                log.info('error running extra debug pt2', exc_info=True)
 
 
 class BatchIndexer(ArtifactSessionExtension):


[14/28] git commit: [#4808] Clean up SourceForge references / values

Posted by jo...@apache.org.
[#4808] Clean up SourceForge references / values

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: 5d46b785d64d43336666b75c7423520b3d582ee1
Parents: 1a9552e
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Jan 21 22:27:48 2014 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jan 22 15:38:03 2014 +0000

----------------------------------------------------------------------
 Allura/allura/app.py                            |  4 +-
 Allura/allura/controllers/auth.py               |  8 +--
 Allura/allura/controllers/project.py            |  7 ++-
 .../ext/admin/templates/project_admin.html      |  6 +--
 .../ext/admin/templates/project_overview.html   |  2 +-
 Allura/allura/lib/app_globals.py                |  6 ++-
 Allura/allura/lib/helpers.py                    | 21 +-------
 Allura/allura/lib/mail_util.py                  |  3 +-
 Allura/allura/lib/markdown_extensions.py        | 12 ++---
 Allura/allura/model/discuss.py                  |  3 +-
 Allura/allura/model/notification.py             | 12 +++--
 Allura/allura/model/project.py                  |  4 +-
 Allura/allura/model/repo_refresh.py             |  2 +-
 Allura/allura/model/repository.py               |  3 +-
 Allura/allura/model/session.py                  |  4 +-
 Allura/allura/tasks/mail_tasks.py               | 10 ++--
 Allura/allura/templates/jinja_master/lib.html   | 10 ++--
 Allura/allura/templates/mail/footer.txt         |  2 +-
 .../templates/mail/monitor_email_footer.txt     |  2 +-
 Allura/allura/tests/functional/test_admin.py    |  5 --
 Allura/allura/tests/functional/test_auth.py     |  2 +-
 Allura/allura/tests/model/test_artifact.py      |  6 +--
 Allura/allura/tests/model/test_auth.py          | 18 +++----
 Allura/allura/tests/model/test_notification.py  | 11 ++--
 Allura/allura/tests/test_globals.py             | 28 ++++++----
 Allura/allura/tests/test_mail_util.py           |  6 +--
 Allura/allura/tests/test_tasks.py               | 56 ++++++++++----------
 Allura/allura/tests/unit/test_app.py            |  2 +-
 Allura/allura/websetup/bootstrap.py             |  2 +-
 Allura/development.ini                          |  3 +-
 Allura/test.ini                                 |  4 +-
 AlluraTest/alluratest/validation.py             |  6 ---
 .../forgeactivity/tests/functional/test_root.py |  2 +-
 ForgeChat/forgechat/command.py                  | 10 ++--
 .../tests/functional/test_forum.py              | 18 +++----
 .../tests/functional/test_forum_admin.py        |  2 +-
 ForgeGit/forgegit/templates/git/index.html      |  2 +-
 .../tests/functional/test_controllers.py        |  7 +--
 .../forgeimporters/github/tests/test_wiki.py    | 31 +++++------
 .../trac/tests/data/test-list.html              | 18 ++-----
 .../trac/tests/data/trac-export.json            | 10 ++--
 ForgeLink/forgelink/tests/test_app.py           |  4 +-
 ForgeSVN/forgesvn/templates/svn/index.html      |  2 +-
 .../hooks/post-commit                           |  4 +-
 .../tests/data/testsvn/hooks/post-commit        |  8 +--
 .../forgesvn/tests/model/test_repository.py     |  7 +--
 .../forgeshorturl/tests/functional/test.py      |  4 +-
 .../forgetracker/tests/functional/data/sf.json  | 10 ++--
 .../forgetracker/tests/functional/test_root.py  |  5 +-
 .../forgewiki/tests/functional/test_root.py     |  4 +-
 50 files changed, 199 insertions(+), 219 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index abefd3c..e5e9287 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -287,10 +287,10 @@ class Application(object):
 
         Email address constructed from Application's url, and looks like this:
 
-            wiki@test.p.in.sf.net
+            wiki@test.p.in.domain.net
 
         where 'wiki@test.p' comes from app url (in this case /p/test/wiki/)
-        and '.in.sf.net' comes from 'forgemail.domain' config entry.
+        and '.in.domain.net' comes from 'forgemail.domain' config entry.
 
         Assumes self.url returns a url path without domain, starting with '/'
         """

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/controllers/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index 8e08e13..e7a58b8 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -140,7 +140,7 @@ class AuthController(BaseController):
         session['userid'] = c.user._id
         session.save()
         if not c.user.username:
-            flash('Please choose a user name for SourceForge, %s.'
+            flash('Please choose a user name, %s.'
                   % c.user.get_pref('display_name'))
             redirect('setup_openid_user')
         redirect(kw.pop('return_to', '/'))
@@ -312,10 +312,7 @@ To reset your password on %s, please visit the following URL:
     @expose()
     def logout(self):
         plugin.AuthenticationProvider.get(request).logout()
-        if config.get('auth.method', 'local') == 'sfx':
-            redirect(g.logout_url)
-        else:
-            redirect('/')
+        redirect(config.get('auth.post_logout_url', '/'))
 
     @expose()
     @require_post()
@@ -345,7 +342,6 @@ To reset your password on %s, please visit the following URL:
 
     def _auth_repos(self, user):
         def _unix_group_name(neighborhood, shortname):
-            'shameless copied from sfx_api.py'
             path = neighborhood.url_prefix + \
                 shortname[len(neighborhood.shortname_prefix):]
             parts = [p for p in path.split('/') if p]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index b231205..2b48697 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -301,7 +301,7 @@ class NeighborhoodProjectBrowseController(ProjectBrowseController):
 class HostNeighborhoodController(WsgiDispatchController, NeighborhoodController):
 
     '''Neighborhood controller with support for use as a root controller, for
-    instance, when using adobe.sourceforge.net (if this is allowed).
+    instance, when using adobe.domain.net (if this is allowed).
     '''
 
     auth = AuthController()
@@ -539,7 +539,10 @@ class NeighborhoodAdminController(object):
     def overview(self, **kw):
         set_nav(self.neighborhood)
         c.overview_form = W.neighborhood_overview_form
-        return dict(neighborhood=self.neighborhood)
+        allow_undelete = asbool(config.get('allow_project_undelete', True))
+        return dict(
+            neighborhood=self.neighborhood,
+            allow_project_undelete=allow_undelete)
 
     @without_trailing_slash
     @expose('jinja:allura:templates/neighborhood_admin_permissions.html')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/ext/admin/templates/project_admin.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/project_admin.html b/Allura/allura/ext/admin/templates/project_admin.html
index f8453f2..3c9b4f5 100644
--- a/Allura/allura/ext/admin/templates/project_admin.html
+++ b/Allura/allura/ext/admin/templates/project_admin.html
@@ -26,14 +26,14 @@
 {% block header %}Project Admin{% endblock %}
 
 {% block content %}
-  <p>SourceForge projects come with a number of Tools, which can be configured and adjusted to your needs.</p>
+  <p>{{config.site_name}} projects come with a number of Tools, which can be configured and adjusted to your needs.</p>
 
   <div class="grid-2">
     <img src="{{g.forge_static('images/project_default.png')}}" alt="">
   </div>
   <div class="grid-13">
     <h3>Project Setup</h3>
-    <p>The first thing to do to setup your project is to create a solid description, so folks coming to your page can figure out what the project is all about. You'll then want to input information about the project, and we'll make sure all this relevant information gets added to the SourceForge sourceforge project directory.</p>
+    <p>The first thing to do to setup your project is to create a solid description, so folks coming to your page can figure out what the project is all about. You'll then want to input information about the project, and we'll make sure all this relevant information gets added to the {{config.site_name}} project directory.</p>
   </div>
   <div class="grid-4">
     <a href="overview">Update MetaData</a>
@@ -78,7 +78,7 @@
   </div>
   <div class="grid-13">
   <h3>Tickets</h3>
-    <p>With the SourceForge tracker you can keep track of items of work that need to be done. You can create one or more trackers for bugs, enhancements, tasks, that will help you plan and manage your development process.</p>
+    <p>With the {{config.site_name}} tracker you can keep track of items of work that need to be done. You can create one or more trackers for bugs, enhancements, tasks, that will help you plan and manage your development process.</p>
   </div>
   <div class="grid-4">
     {% for tool in c.project.app_configs %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/ext/admin/templates/project_overview.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/project_overview.html b/Allura/allura/ext/admin/templates/project_overview.html
index 3c77be2..af2aca1 100644
--- a/Allura/allura/ext/admin/templates/project_overview.html
+++ b/Allura/allura/ext/admin/templates/project_overview.html
@@ -95,7 +95,7 @@
             $removal_original.attr('checked', true);
           }
         }
-        {% if config.get('auth.method', 'local') == 'sfx' %}
+        {% if not allow_project_undelete %}
         else if($(this).val()!=='deleted' && currently_deleted){
           alert('You may not undelete a project that has already been deleted.');
           $removal_original.attr('checked', true);

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 8bc929e..ecc7b35 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -163,7 +163,7 @@ class Globals(object):
             self.solr_short_timeout = None
         self.use_queue = asbool(config.get('use_queue', False))
 
-        # Load login/logout urls; only used for SFX logins
+        # Load login/logout urls; only used for customized logins
         self.login_url = config.get('auth.login_url', '/auth/')
         self.logout_url = config.get('auth.logout_url', '/auth/logout')
         self.login_fragment_url = config.get(
@@ -605,6 +605,10 @@ class Globals(object):
     def year(self):
         return datetime.datetime.utcnow().year
 
+    @LazyProperty
+    def noreply(self):
+        return unicode(config.get('noreply', 'noreply@%s' % config['domain']))
+
 
 class Icon(object):
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 4f84813..18cdc53 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -457,8 +457,8 @@ def gen_message_id(_id=None):
         addr = '%s.%s' % (_id, c.app.config.options['mount_point'])
     else:
         addr = _id
-    return '%s@%s.sourceforge.net' % (
-        addr, '.'.join(reversed(parts)))
+    return '%s@%s.%s' % (
+        addr, '.'.join(reversed(parts)), tg.config['domain'])
 
 
 class ProxiedAttrMeta(type):
@@ -533,23 +533,6 @@ def render_genshi_plaintext(template_name, **template_vars):
     stream = tt.generate(**template_vars)
     return stream.render(encoding='utf-8').decode('utf-8')
 
-site_url = None  # cannot set it just yet since tg.config is empty
-
-
-def full_url(url):
-    """Make absolute URL from the relative one.
-    """
-    global site_url
-    if site_url is None:
-        # XXX: add a separate tg option instead of re-using openid.realm
-        site_url = tg.config.get(
-            'openid.realm', 'https://newforge.sf.geek.net/')
-        site_url = site_url.replace('https:', 'http:')
-        if not site_url.endswith('/'):
-            site_url += '/'
-    if url.startswith('/'):
-        url = url[1:]
-    return site_url + url
 
 
 @tg.expose(content_type='text/plain')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/lib/mail_util.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/mail_util.py b/Allura/allura/lib/mail_util.py
index 5ec98da..4da1819 100644
--- a/Allura/allura/lib/mail_util.py
+++ b/Allura/allura/lib/mail_util.py
@@ -27,6 +27,7 @@ import tg
 from paste.deploy.converters import asbool, asint, aslist
 from formencode import validators as fev
 from pylons import tmpl_context as c
+from pylons import app_globals as g
 
 from allura.lib.utils import ConfigProxy
 from allura.lib import exceptions as exc
@@ -201,7 +202,7 @@ def _parse_smtp_addr(addr):
         return addrs[0]
     if '@' in addr:
         return addr
-    return u'noreply@in.sf.net'
+    return g.noreply
 
 
 def isvalid(addr):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/lib/markdown_extensions.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/markdown_extensions.py b/Allura/allura/lib/markdown_extensions.py
index a7af428..60bf943 100644
--- a/Allura/allura/lib/markdown_extensions.py
+++ b/Allura/allura/lib/markdown_extensions.py
@@ -477,11 +477,11 @@ class RelativeLinkRewriter(markdown.postprocessors.Postprocessor):
             val = val.replace(' ', '%20')
             tag[attr] = val
         if '://' in val:
-            if 'sf.net' in val or 'sourceforge.net' in val:
-                return
-            else:
-                tag['rel'] = 'nofollow'
-                return
+            for domain in re.split(r'\s*,\s*', config.get('nofollow_exempt_domains', '')):
+                if domain and domain in val:
+                    return
+            tag['rel'] = 'nofollow'
+            return
         if val.startswith('/'):
             return
         if val.startswith('.'):
@@ -495,7 +495,7 @@ class RelativeLinkRewriter(markdown.postprocessors.Postprocessor):
     def _rewrite_abs(self, tag, attr):
         self._rewrite(tag, attr)
         val = tag.get(attr)
-        val = urljoin(config.get('base_url', 'http://sourceforge.net/'), val)
+        val = urljoin(config['base_url'], val)
         tag[attr] = val
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index 1fddf91..2741d03 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -22,6 +22,7 @@ import jinja2
 import pymongo
 from pymongo.errors import DuplicateKeyError
 from pylons import tmpl_context as c, app_globals as g
+import tg
 
 from ming import schema
 from ming.orm.base import session
@@ -304,7 +305,7 @@ class Thread(Artifact, ActivityObject):
             _id=artifact.url() + post._id,
             from_address=str(author._id) if author != User.anonymous()
             else None,
-            reply_to_address=u'noreply@in.sf.net',
+            reply_to_address=g.noreply,
             subject=subject,
             text=text,
             in_reply_to=post.parent_id,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/model/notification.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index 3bb81fc..cbacc3a 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -176,7 +176,7 @@ class Notification(MappedClass):
                     author._id) if author != User.anonymous() else None,
                 reply_to_address='"%s" <%s>' % (
                     subject_prefix, getattr(
-                        artifact, 'email_address', u'noreply@in.sf.net')),
+                        artifact, 'email_address', g.noreply)),
                 subject=subject_prefix + subject,
                 text=text,
                 in_reply_to=parent_msg_id,
@@ -193,7 +193,7 @@ class Notification(MappedClass):
                 h.get_first(idx, 'title'), c.user.get_pref('display_name')))
             reply_to = '"%s" <%s>' % (
                 h.get_first(idx, 'title'),
-                getattr(artifact, 'email_address', u'noreply@in.sf.net'))
+                getattr(artifact, 'email_address', g.noreply))
             d = dict(
                 from_address=reply_to,
                 reply_to_address=reply_to,
@@ -655,11 +655,11 @@ class Mailbox(MappedClass):
                         ', '.join([n._id for n in ns]), self._id, self.user_id)
         elif self.type == 'digest':
             Notification.send_digest(
-                self.user_id, u'noreply@in.sf.net', 'Digest Email',
+                self.user_id, g.noreply, 'Digest Email',
                 notifications)
         elif self.type == 'summary':
             Notification.send_summary(
-                self.user_id, u'noreply@in.sf.net', 'Digest Email',
+                self.user_id, g.noreply, 'Digest Email',
                 notifications)
 
 
@@ -676,12 +676,14 @@ class MailFooter(object):
     @classmethod
     def standard(cls, notification):
         return cls._render('mail/footer.txt',
+                           domain=config['domain'],
                            notification=notification,
-                           prefix=config.get('forgemail.url', 'https://sourceforge.net'))
+                           prefix=config['forgemail.url'])
 
     @classmethod
     def monitored(cls, toaddr, app_url, setting_url):
         return cls._render('mail/monitor_email_footer.txt',
+                           domain=config['domain'],
                            email=toaddr,
                            app_url=app_url,
                            setting_url=setting_url)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 9b2024c..f971293 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -257,8 +257,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
         if sps:
             result.append(SitemapEntry('Child Projects'))
             result += [
-                SitemapEntry(p.name or p.script_name, p.script_name)
-                for p in sps]
+                SitemapEntry(sp.name or sp.script_name, sp.script_name)
+                for sp in sps]
         return result
 
     def troves_by_type(self, trove_type):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/model/repo_refresh.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repo_refresh.py b/Allura/allura/model/repo_refresh.py
index c34739a..d5ba927 100644
--- a/Allura/allura/model/repo_refresh.py
+++ b/Allura/allura/model/repo_refresh.py
@@ -418,7 +418,7 @@ def send_notifications(repo, commit_ids):
     '''Create appropriate notification and feed objects for a refresh'''
     from allura.model import Feed, Notification
     commit_msgs = []
-    base_url = tg.config.get('base_url', 'sourceforge.net')
+    base_url = tg.config['base_url']
     for oids in utils.chunked_iter(commit_ids, QSIZE):
         chunk = list(oids)
         index = dict(

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/model/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/repository.py b/Allura/allura/model/repository.py
index b6cfb9a..60bceaa 100644
--- a/Allura/allura/model/repository.py
+++ b/Allura/allura/model/repository.py
@@ -185,7 +185,8 @@ class RepositoryImplementation(object):
 
     def _setup_special_files(self, source_path=None):
         magic_file = os.path.join(
-            self._repo.fs_path, self._repo.name, '.SOURCEFORGE-REPOSITORY')
+            self._repo.fs_path, self._repo.name, tg.config.get(
+                'scm.magic_file', '.ALLURA-REPOSITORY'))
         with open(magic_file, 'w') as f:
             f.write(self._repo.repo_id)
         os.chmod(magic_file, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/model/session.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/session.py b/Allura/allura/model/session.py
index 5354f87..e7da553 100644
--- a/Allura/allura/model/session.py
+++ b/Allura/allura/model/session.py
@@ -61,8 +61,8 @@ class ArtifactSessionExtension(SessionExtension):
             arefs = []
             try:
                 arefs = [
-                    ArtifactReference.from_artifact(obj)
-                    for obj in self.objects_added + self.objects_modified]
+                    ArtifactReference.from_artifact(o)
+                    for o in self.objects_added + self.objects_modified]
                 for obj in self.objects_added + self.objects_modified:
                     Shortlink.from_artifact(obj)
                 # Flush shortlinks

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/tasks/mail_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/mail_tasks.py b/Allura/allura/tasks/mail_tasks.py
index 31c16f0..9676842 100644
--- a/Allura/allura/tasks/mail_tasks.py
+++ b/Allura/allura/tasks/mail_tasks.py
@@ -36,7 +36,7 @@ def route_email(
         peer, mailfrom, rcpttos, data):
     '''Route messages according to their destination:
 
-    <topic>@<mount_point>.<subproj2>.<subproj1>.<project>.projects.sourceforge.net
+    <topic>@<mount_point>.<subproj2>.<subproj1>.<project>.projects.domain.net
     gets sent to c.app.handle_message(topic, message)
     '''
     try:
@@ -90,13 +90,13 @@ def sendmail(fromaddr, destinations, text, reply_to, subject,
     addrs_html = []
     addrs_multi = []
     if fromaddr is None:
-        fromaddr = u'noreply@in.sf.net'
+        fromaddr = g.noreply
     elif '@' not in fromaddr:
         log.warning('Looking up user with fromaddr: %s', fromaddr)
         user = M.User.query.get(_id=ObjectId(fromaddr), disabled=False)
         if not user:
             log.warning('Cannot find user with ID: %s', fromaddr)
-            fromaddr = u'noreply@in.sf.net'
+            fromaddr = g.noreply
         else:
             fromaddr = user.email_address_header()
     # Divide addresses based on preferred email formats
@@ -159,13 +159,13 @@ def sendsimplemail(
         cc=None):
     from allura import model as M
     if fromaddr is None:
-        fromaddr = u'noreply@in.sf.net'
+        fromaddr = g.noreply
     elif '@' not in fromaddr:
         log.warning('Looking up user with fromaddr: %s', fromaddr)
         user = M.User.query.get(_id=ObjectId(fromaddr), disabled=False)
         if not user:
             log.warning('Cannot find user with ID: %s', fromaddr)
-            fromaddr = u'noreply@in.sf.net'
+            fromaddr = g.noreply
         else:
             fromaddr = user.email_address_header()
     htmlparser = HTMLParser.HTMLParser()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/templates/jinja_master/lib.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/lib.html b/Allura/allura/templates/jinja_master/lib.html
index f83e23c..9d3aa2c 100644
--- a/Allura/allura/templates/jinja_master/lib.html
+++ b/Allura/allura/templates/jinja_master/lib.html
@@ -185,7 +185,7 @@
 <h1>Markdown Syntax Guide</h1>
 
 <div class="markdown_syntax_section md_ex_toc{{id}}">
-<p>SourceForge uses markdown syntax everywhere to allow you to create rich<br>text markup, and extends markdown in several ways to allow for quick linking<br>to other artifacts in your project. </p>
+<p>{{config.site_name}} uses markdown syntax everywhere to allow you to create rich<br>text markup, and extends markdown in several ways to allow for quick linking<br>to other artifacts in your project. </p>
 <p>Markdown was created to be easy to read, easy to write, and still readable in plain text format.</p>
 
 <ul class="markdown_syntax_toc">
@@ -549,21 +549,21 @@ you will get a header
 <h2 id="md_ex_img{{id}}">Images</h2>
 <p>To include an image, just put a "!" in front of a text link:</p>
 <div class="codehilite"><pre>
-![alternate text](https://sourceforge.net/images/icon_linux.gif)
+![alternate text](https://{{config.domain}}/images/icon_linux.gif)
 </pre></div>
 
 <p>Output:</p>
-{{g.markdown.convert('''![alternate text](http://sourceforge.net/images/icon_linux.gif)''')}}
+{{g.markdown.convert('''![alternate text](http://'''+config.domain+'''/images/icon_linux.gif)''')}}
 
 <p>The "alternate text" will show up if the browser can't load the
 image.</p>
 <p>You can also use a title if you want, like this:</p>
 <div class="codehilite"><pre>
-![tiny arrow](https://sourceforge.net/images/icon_linux.gif "tiny arrow")
+![tiny arrow](https://{{config.domain}}/images/icon_linux.gif "tiny arrow")
 </pre></div>
 
 <p>Output:</p>
-{{g.markdown.convert('''![tiny arrow](http://sourceforge.net/images/icon_linux.gif "tiny arrow")''')}}
+{{g.markdown.convert('''![tiny arrow](http://'''+config.domain+'''/images/icon_linux.gif "tiny arrow")''')}}
 
 <p>To reference an attached image, just use the img macro.  You can add more attributes:</p>
 <div class="codehilite"><pre>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/templates/mail/footer.txt
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/mail/footer.txt b/Allura/allura/templates/mail/footer.txt
index 6d15625..608b5a2 100644
--- a/Allura/allura/templates/mail/footer.txt
+++ b/Allura/allura/templates/mail/footer.txt
@@ -20,6 +20,6 @@
 
 ---
 
-Sent from sourceforge.net because you indicated interest in <{{ prefix }}{{ notification.link }}>
+Sent from {{domain}} because you indicated interest in <{{ prefix }}{{ notification.link }}>
 
 To unsubscribe from further messages, please visit <{{ prefix }}/auth/subscriptions/>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/templates/mail/monitor_email_footer.txt
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/mail/monitor_email_footer.txt b/Allura/allura/templates/mail/monitor_email_footer.txt
index ce53c08..d3492ca 100644
--- a/Allura/allura/templates/mail/monitor_email_footer.txt
+++ b/Allura/allura/templates/mail/monitor_email_footer.txt
@@ -20,6 +20,6 @@
 
 ---
 
-Sent from sourceforge.net because {{email}} is subscribed to {{app_url}}
+Sent from {{domain}} because {{email}} is subscribed to {{app_url}}
 
 To unsubscribe from further messages, a project admin can change settings at {{setting_url}}.  Or, if this is a mailing list, you can unsubscribe from the mailing list.

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/tests/functional/test_admin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py
index 78cdbcb..00a8b0d 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -31,11 +31,6 @@ from pylons import tmpl_context as c, app_globals as g
 import mock
 
 
-try:
-    import sfx
-except ImportError:
-    sfx = None
-
 from allura.tests import TestController
 from allura.tests import decorators as td
 from alluratest.controller import TestRestApiBase

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/tests/functional/test_auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index c892f87..cff1e47 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -819,7 +819,7 @@ To reset your password on %s, please visit the following URL:
         sendmail.post.assert_called_once_with(
             destinations=[email._id],
             fromaddr=config['forgemail.return_path'],
-            reply_to='noreply@sourceforge.net',
+            reply_to=config['forgemail.return_path'],
             subject='Password recovery',
             message_id=gen_message_id(),
             text=text)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/tests/model/test_artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_artifact.py b/Allura/allura/tests/model/test_artifact.py
index 6b2ec66..e9ac6ec 100644
--- a/Allura/allura/tests/model/test_artifact.py
+++ b/Allura/allura/tests/model/test_artifact.py
@@ -143,21 +143,21 @@ def test_artifactlink():
 
 @with_setup(setUp, tearDown)
 def test_gen_messageid():
-    assert re.match(r'[0-9a-zA-Z]*.wiki@test.p.sourceforge.net',
+    assert re.match(r'[0-9a-zA-Z]*.wiki@test.p.localhost',
                     h.gen_message_id())
 
 
 @with_setup(setUp, tearDown)
 def test_gen_messageid_with_id_set():
     oid = ObjectId()
-    assert re.match(r'%s.wiki@test.p.sourceforge.net' %
+    assert re.match(r'%s.wiki@test.p.localhost' %
                     str(oid), h.gen_message_id(oid))
 
 
 @with_setup(setUp, tearDown)
 def test_artifact_messageid():
     p = WM.Page(title='T')
-    assert re.match(r'%s.wiki@test.p.sourceforge.net' %
+    assert re.match(r'%s.wiki@test.p.localhost' %
                     str(p._id), p.message_id())
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/tests/model/test_auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_auth.py b/Allura/allura/tests/model/test_auth.py
index 237d2ab..cb548da 100644
--- a/Allura/allura/tests/model/test_auth.py
+++ b/Allura/allura/tests/model/test_auth.py
@@ -52,22 +52,22 @@ def test_password_encoder():
 
 @with_setup(setUp)
 def test_email_address():
-    addr = M.EmailAddress(_id='test_admin@sf.net',
+    addr = M.EmailAddress(_id='test_admin@domain.net',
                           claimed_by_user_id=c.user._id)
     ThreadLocalORMSession.flush_all()
     assert addr.claimed_by_user() == c.user
-    addr2 = M.EmailAddress.upsert('test@sf.net')
-    addr3 = M.EmailAddress.upsert('test_admin@sf.net')
+    addr2 = M.EmailAddress.upsert('test@domain.net')
+    addr3 = M.EmailAddress.upsert('test_admin@domain.net')
     assert addr3 is addr
     assert addr2 is not addr
     assert addr2
-    addr4 = M.EmailAddress.upsert('test@SF.NET')
+    addr4 = M.EmailAddress.upsert('test@DOMAIN.NET')
     assert addr4 is addr2
     with patch('allura.lib.app_globals.request', Request.blank('/')):
         addr.send_verification_link()
-    assert addr is c.user.address_object('test_admin@sf.net')
-    c.user.claim_address('test@SF.NET')
-    assert 'test@sf.net' in c.user.email_addresses
+    assert addr is c.user.address_object('test_admin@domain.net')
+    c.user.claim_address('test@DOMAIN.NET')
+    assert 'test@domain.net' in c.user.email_addresses
 
 
 @with_setup(setUp)
@@ -170,7 +170,7 @@ def test_project_role():
     ThreadLocalORMSession.flush_all()
     roles = g.credentials.user_roles(
         c.user._id, project_id=c.project.root_project._id)
-    roles_ids = [role['_id'] for role in roles]
+    roles_ids = [r['_id'] for r in roles]
     roles = M.ProjectRole.query.find({'_id': {'$in': roles_ids}})
     for pr in roles:
         assert pr.display()
@@ -225,7 +225,7 @@ def test_openid_claimed_by_user():
 
 @with_setup(setUp)
 def test_email_address_claimed_by_user():
-    addr = M.EmailAddress(_id='test_admin@sf.net',
+    addr = M.EmailAddress(_id='test_admin@domain.net',
                           claimed_by_user_id=c.user._id)
     c.user.disabled = True
     ThreadLocalORMSession.flush_all()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/tests/model/test_notification.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_notification.py b/Allura/allura/tests/model/test_notification.py
index 88bdf45..b1dff66 100644
--- a/Allura/allura/tests/model/test_notification.py
+++ b/Allura/allura/tests/model/test_notification.py
@@ -94,7 +94,7 @@ class TestNotification(unittest.TestCase):
             message_id='_id',
             in_reply_to='in_reply_to',
             references=['a'],
-            sender='wiki@test.p.in.sf.net',
+            sender='wiki@test.p.in.localhost',
             text='text footer',
         )
 
@@ -157,7 +157,7 @@ class TestNotification(unittest.TestCase):
             message_id='_id',
             in_reply_to='in_reply_to',
             references=['a'],
-            sender='wiki@test.p.in.sf.net',
+            sender='wiki@test.p.in.localhost',
             text='text footer',
         )
 
@@ -245,8 +245,8 @@ class TestPostNotifications(unittest.TestCase):
                      '"Test Admin" <te...@users.localhost>')
         assert_equal(email_tasks[1].kwargs['fromaddr'],
                      '"Test Admin" <te...@users.localhost>')
-        assert_equal(email_tasks[0].kwargs['sender'], 'wiki@test.p.in.sf.net')
-        assert_equal(email_tasks[1].kwargs['sender'], 'wiki@test.p.in.sf.net')
+        assert_equal(email_tasks[0].kwargs['sender'], 'wiki@test.p.in.localhost')
+        assert_equal(email_tasks[1].kwargs['sender'], 'wiki@test.p.in.localhost')
         assert email_tasks[0].kwargs['text'].startswith(
             'Home modified by Test Admin')
         assert 'you indicated interest in ' in email_tasks[0].kwargs['text']
@@ -288,7 +288,8 @@ class TestPostNotifications(unittest.TestCase):
         assert 'test@mail.com is subscribed to http://test1.com' in footer
         assert 'admin can change settings at http://test2.com' in footer
         footer = MailFooter.standard(M.Notification())
-        assert 'Sent from sourceforge.net because you indicated interest in' in footer
+        self.assertIn('Sent from localhost because you indicated interest',
+                      footer)
 
     def _subscribe(self, **kw):
         self.pg.subscribe(type='direct', **kw)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index ea7313d..e537c2d 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -29,6 +29,7 @@ from bson import ObjectId
 
 from nose.tools import with_setup, assert_equal, assert_in
 from pylons import tmpl_context as c, app_globals as g
+import tg
 
 from ming.orm import ThreadLocalORMSession
 from alluratest.controller import setup_basic_test, setup_global_objects
@@ -322,16 +323,21 @@ def test_wiki_artifact_links():
 
 
 def test_markdown_links():
+    with patch.dict(tg.config, {'nofollow_exempt_domains': 'foobar.net'}):
+        text = g.markdown.convert(
+            'Read [here](http://foobar.net/) about our project')
+        assert_in('href="http://foobar.net/">here</a> about', text)
+
     text = g.markdown.convert(
-        'Read [here](http://foobar.sf.net/) about our project')
-    assert_in('href="http://foobar.sf.net/">here</a> about', text)
+        'Read [here](http://foobar.net/) about our project')
+    assert_in('href="http://foobar.net/" rel="nofollow">here</a> about', text)
 
     text = g.markdown.convert('Read [here](/p/foobar/blah) about our project')
     assert_in('href="/p/foobar/blah">here</a> about', text)
 
-    text = g.markdown.convert('Read <http://foobar.sf.net/> about our project')
+    text = g.markdown.convert('Read <http://foobar.net/> about our project')
     assert_in(
-        'href="http://foobar.sf.net/">http://foobar.sf.net/</a> about', text)
+        'href="http://foobar.net/" rel="nofollow">http://foobar.net/</a> about', text)
 
 
 def test_markdown_and_html():
@@ -394,20 +400,20 @@ def test_markdown_autolink():
     s = g.markdown.convert('This is %s' % tgt)
     assert_equal(
         s, '<div class="markdown_content"><p>This is <a href="%s" rel="nofollow">%s</a></p></div>' % (tgt, tgt))
-    assert '<a href=' in g.markdown.convert('This is http://sf.net')
+    assert '<a href=' in g.markdown.convert('This is http://domain.net')
     # beginning of doc
-    assert_in('<a href=', g.markdown.convert('http://sf.net abc'))
+    assert_in('<a href=', g.markdown.convert('http://domain.net abc'))
     # beginning of a line
     assert_in('<br />\n<a href="http://',
-              g.markdown.convert('foobar\nhttp://sf.net abc'))
+              g.markdown.convert('foobar\nhttp://domain.net abc'))
     # no conversion of these urls:
     assert_in('a blahttp://sdf.com z',
               g.markdown.convert('a blahttp://sdf.com z'))
-    assert_in('literal <code>http://sf.net</code> literal',
-              g.markdown.convert('literal `http://sf.net` literal'))
-    assert_in('<pre>preformatted http://sf.net\n</pre>',
+    assert_in('literal <code>http://domain.net</code> literal',
+              g.markdown.convert('literal `http://domain.net` literal'))
+    assert_in('<pre>preformatted http://domain.net\n</pre>',
               g.markdown.convert('    :::text\n'
-                                 '    preformatted http://sf.net'))
+                                 '    preformatted http://domain.net'))
 
 
 def test_markdown_autolink_with_escape():

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/tests/test_mail_util.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_mail_util.py b/Allura/allura/tests/test_mail_util.py
index 0ae42a0..6b1657d 100644
--- a/Allura/allura/tests/test_mail_util.py
+++ b/Allura/allura/tests/test_mail_util.py
@@ -228,7 +228,7 @@ class TestIdentifySender(object):
 
 
 def test_parse_message_id():
-    assert_equal(_parse_message_id('<de...@libjpeg-turbo.p.sourceforge.net>, </p...@libjpeg-turbo.p.sourceforge.net>'), [
-        'de31888f6be2d87dc377d9e713876bb514548625.patches@libjpeg-turbo.p.sourceforge.net',
-        'de31888f6be2d87dc377d9e713876bb514548625.patches@libjpeg-turbo.p.sourceforge.net',
+    assert_equal(_parse_message_id('<de...@libjpeg-turbo.p.domain.net>, </p...@libjpeg-turbo.p.domain.net>'), [
+        'de31888f6be2d87dc377d9e713876bb514548625.patches@libjpeg-turbo.p.domain.net',
+        'de31888f6be2d87dc377d9e713876bb514548625.patches@libjpeg-turbo.p.domain.net',
     ])

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index e948276..f06ee06 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -125,8 +125,8 @@ class TestIndexTasks(unittest.TestCase):
                 5 == new_solr_size, "Solr additions didn't happen"
             M.main_orm_session.flush()
             M.main_orm_session.clear()
-            a = _TestArtifact.query.get(_shorthand_id='t3')
-            assert len(a.backrefs) == 5, a.backrefs
+            t3 = _TestArtifact.query.get(_shorthand_id='t3')
+            assert len(t3.backrefs) == 5, t3.backrefs
             assert_equal(find_slinks.call_args_list,
                          [mock.call(a.index().get('text')) for a in artifacts])
 
@@ -177,7 +177,7 @@ class TestMailTasks(unittest.TestCase):
                 fromaddr=str(c.user._id),
                 destinations=[str(c.user._id)],
                 text=u'This is a test',
-                reply_to=u'noreply@sf.net',
+                reply_to=g.noreply,
                 subject=u'Test subject',
                 message_id=h.gen_message_id())
             assert_equal(_client.sendmail.call_count, 1)
@@ -185,7 +185,7 @@ class TestMailTasks(unittest.TestCase):
             body = body.split('\n')
 
             assert_equal(rcpts, [c.user.get_pref('email_address')])
-            assert_in('Reply-To: noreply@sf.net', body)
+            assert_in('Reply-To: %s' % g.noreply, body)
             assert_in('From: "Test Admin" <te...@users.localhost>', body)
             assert_in('Subject: Test subject', body)
             # plain
@@ -200,7 +200,7 @@ class TestMailTasks(unittest.TestCase):
                 fromaddr=u'"По" <fo...@bar.com>',
                 destinations=['blah@blah.com'],
                 text=u'Громады стройные теснятся',
-                reply_to=u'noreply@sf.net',
+                reply_to=g.noreply,
                 subject=u'По оживлённым берегам',
                 message_id=h.gen_message_id())
             assert_equal(_client.sendmail.call_count, 1)
@@ -208,7 +208,7 @@ class TestMailTasks(unittest.TestCase):
             body = body.split('\n')
 
             assert_equal(rcpts, ['blah@blah.com'])
-            assert_in('Reply-To: noreply@sf.net', body)
+            assert_in('Reply-To: %s' % g.noreply, body)
 
             # The address portion must not be encoded, only the name portion can be.
             # Also it is apparently not necessary to have the double-quote separators present
@@ -233,13 +233,13 @@ class TestMailTasks(unittest.TestCase):
                 fromaddr=str(c.user._id),
                 destinations=[str(destination_user._id)],
                 text=u'This is a test',
-                reply_to=u'noreply@sf.net',
+                reply_to=g.noreply,
                 subject=u'Test subject',
                 message_id=h.gen_message_id())
             assert_equal(_client.sendmail.call_count, 1)
             return_path, rcpts, body = _client.sendmail.call_args[0]
             body = body.split('\n')
-            assert_in('From: noreply@in.sf.net', body)
+            assert_in('From: %s' % g.noreply, body)
 
     def test_send_email_with_disabled_destination_user(self):
         c.user = M.User.by_username('test-admin')
@@ -252,7 +252,7 @@ class TestMailTasks(unittest.TestCase):
                 fromaddr=str(c.user._id),
                 destinations=[str(destination_user._id)],
                 text=u'This is a test',
-                reply_to=u'noreply@sf.net',
+                reply_to=g.noreply,
                 subject=u'Test subject',
                 message_id=h.gen_message_id())
             assert_equal(_client.sendmail.call_count, 0)
@@ -264,7 +264,7 @@ class TestMailTasks(unittest.TestCase):
                 fromaddr=str(c.user._id),
                 toaddr='test@mail.com',
                 text=u'This is a test',
-                reply_to=u'noreply@sf.net',
+                reply_to=g.noreply,
                 subject=u'Test subject',
                 message_id=h.gen_message_id())
             assert_equal(_client.sendmail.call_count, 1)
@@ -278,13 +278,13 @@ class TestMailTasks(unittest.TestCase):
                 fromaddr=str(c.user._id),
                 toaddr='test@mail.com',
                 text=u'This is a test',
-                reply_to=u'noreply@sf.net',
+                reply_to=g.noreply,
                 subject=u'Test subject',
                 message_id=h.gen_message_id())
             assert_equal(_client.sendmail.call_count, 2)
             return_path, rcpts, body = _client.sendmail.call_args[0]
             body = body.split('\n')
-            assert_in('From: noreply@in.sf.net', body)
+            assert_in('From: %s' % g.noreply, body)
 
     def test_email_sender_to_headers(self):
         c.user = M.User.by_username('test-admin')
@@ -293,15 +293,15 @@ class TestMailTasks(unittest.TestCase):
                 fromaddr=str(c.user._id),
                 toaddr='test@mail.com',
                 text=u'This is a test',
-                reply_to=u'noreply@sf.net',
+                reply_to=g.noreply,
                 subject=u'Test subject',
-                sender=u'tickets@test.p.sf.net',
+                sender=u'tickets@test.p.domain.net',
                 message_id=h.gen_message_id())
             assert_equal(_client.sendmail.call_count, 1)
             return_path, rcpts, body = _client.sendmail.call_args[0]
             body = body.split('\n')
             assert_in('From: "Test Admin" <te...@users.localhost>', body)
-            assert_in('Sender: tickets@test.p.sf.net', body)
+            assert_in('Sender: tickets@test.p.domain.net', body)
             assert_in('To: test@mail.com', body)
 
             _client.reset_mock()
@@ -309,16 +309,16 @@ class TestMailTasks(unittest.TestCase):
                 fromaddr=str(c.user._id),
                 destinations=[str(c.user._id)],
                 text=u'This is a test',
-                reply_to=u'123@tickets.test.p.sf.net',
+                reply_to=u'123@tickets.test.p.domain.net',
                 subject=u'Test subject',
-                sender=u'tickets@test.p.sf.net',
+                sender=u'tickets@test.p.domain.net',
                 message_id=h.gen_message_id())
             assert_equal(_client.sendmail.call_count, 1)
             return_path, rcpts, body = _client.sendmail.call_args[0]
             body = body.split('\n')
             assert_in('From: "Test Admin" <te...@users.localhost>', body)
-            assert_in('Sender: tickets@test.p.sf.net', body)
-            assert_in('To: 123@tickets.test.p.sf.net', body)
+            assert_in('Sender: tickets@test.p.domain.net', body)
+            assert_in('To: 123@tickets.test.p.domain.net', body)
 
     def test_email_references_header(self):
         c.user = M.User.by_username('test-admin')
@@ -327,7 +327,7 @@ class TestMailTasks(unittest.TestCase):
                 fromaddr=str(c.user._id),
                 toaddr='test@mail.com',
                 text=u'This is a test',
-                reply_to=u'noreply@sf.net',
+                reply_to=g.noreply,
                 subject=u'Test subject',
                 references=['a', 'b', 'c'],
                 message_id=h.gen_message_id())
@@ -342,7 +342,7 @@ class TestMailTasks(unittest.TestCase):
                 fromaddr=str(c.user._id),
                 destinations=[str(c.user._id)],
                 text=u'This is a test',
-                reply_to=u'noreply@sf.net',
+                reply_to=g.noreply,
                 subject=u'Test subject',
                 references=u'ref',
                 message_id=h.gen_message_id())
@@ -359,7 +359,7 @@ class TestMailTasks(unittest.TestCase):
                 fromaddr=str(c.user._id),
                 toaddr='test@mail.com',
                 text=u'This is a test',
-                reply_to=u'noreply@sf.net',
+                reply_to=g.noreply,
                 subject=u'Test subject',
                 cc=u'someone@example.com',
                 message_id=h.gen_message_id())
@@ -375,7 +375,7 @@ class TestMailTasks(unittest.TestCase):
         with mock.patch.object(forgewiki.wiki_main.ForgeWikiApp, 'handle_message') as f:
             mail_tasks.route_email(
                 '0.0.0.0', c.user.email_addresses[0],
-                ['Page@wiki.test.p.in.sf.net'],
+                ['Page@wiki.test.p.in.localhost'],
                 'This is a mail message')
             args, kwargs = f.call_args
             assert args[0] == 'Page'
@@ -384,8 +384,8 @@ class TestMailTasks(unittest.TestCase):
     @td.with_tool('test', 'Tickets', 'bugs')
     def test_receive_autoresponse(self):
         message = '''Date: Wed, 30 Oct 2013 01:38:40 -0700
-From: <te...@sf.net>
-To: <1...@bugs.test.p.in.sf.net>
+From: <te...@domain.net>
+To: <1...@bugs.test.p.in.localhost>
 Message-ID: <super-unique-id>
 Subject: Not here Re: Message notification
 Precedence: bulk
@@ -399,7 +399,7 @@ I'm not here'''
             mail_tasks.route_email(
                 '0.0.0.0',
                 c.user.email_addresses[0],
-                ['1@bugs.test.p.in.sf.net'],
+                ['1@bugs.test.p.in.localhost'],
                 message)
             assert_equal(hm.call_count, 0)
 
@@ -500,8 +500,8 @@ class TestExportTasks(unittest.TestCase):
         assert_equal(len(tasks), 1)
         assert_equal(tasks[0].kwargs['subject'],
                      'Bulk export for project test completed')
-        assert_equal(tasks[0].kwargs['fromaddr'], 'noreply@sourceforge.net')
-        assert_equal(tasks[0].kwargs['reply_to'], 'noreply@sourceforge.net')
+        assert_equal(tasks[0].kwargs['fromaddr'], g.noreply)
+        assert_equal(tasks[0].kwargs['reply_to'], g.noreply)
         text = tasks[0].kwargs['text']
         assert_in('The bulk export for project test is completed.', text)
         assert_in('The following tools were exported:\n- wiki', text)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/tests/unit/test_app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_app.py b/Allura/allura/tests/unit/test_app.py
index e429407..95c56c5 100644
--- a/Allura/allura/tests/unit/test_app.py
+++ b/Allura/allura/tests/unit/test_app.py
@@ -100,7 +100,7 @@ class TestAppDefaults(WithDatabase):
 
     def test_email_address(self):
         self.app.url = '/p/project/mount-point/'
-        assert self.app.email_address == 'mount-point@project.p.in.sf.net'
+        assert self.app.email_address == 'mount-point@project.p.in.localhost'
 
 
 def install_app():

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/allura/websetup/bootstrap.py
----------------------------------------------------------------------
diff --git a/Allura/allura/websetup/bootstrap.py b/Allura/allura/websetup/bootstrap.py
index abe8234..91c4fd9 100644
--- a/Allura/allura/websetup/bootstrap.py
+++ b/Allura/allura/websetup/bootstrap.py
@@ -75,7 +75,7 @@ def bootstrap(command, conf, vars):
         kw.update(make_project=make_user_projects)
         return create_user(*args, **kw)
 
-    # Our bootstrap doesn't play nicely with SFX project and user APIs
+    # Temporarily disable auth extensions to prevent unintended side-effects
     tg.config['auth.method'] = tg.config['registration.method'] = 'local'
     assert tg.config['auth.method'] == 'local'
     conf['auth.method'] = conf['registration.method'] = 'local'

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index edfb794..2e88542 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -48,6 +48,7 @@ full_stack = true
 use_queue = true
 site_name = Allura
 
+domain = forge-allura.apache.org
 base_url = http://localhost:8080
 
 #lang = ru
@@ -429,4 +430,4 @@ datefmt = %d/%b/%Y:%H:%M:%S UTC
 
 [formatter_timermiddleware]
 format = {"time": "%(asctime)s,%(msecs)03d", "level": "%(levelname)-5.5s", "name": "%(name)s", "message": %(message)s}
-datefmt = %Y-%m-%d %H:%M:%S
\ No newline at end of file
+datefmt = %Y-%m-%d %H:%M:%S

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/Allura/test.ini
----------------------------------------------------------------------
diff --git a/Allura/test.ini b/Allura/test.ini
index 2d71468..9a11bb4 100644
--- a/Allura/test.ini
+++ b/Allura/test.ini
@@ -39,6 +39,7 @@ db_prefix = test_
 
 site_name = Allura
 base_url = http://localhost
+domain = localhost
 
 mediawikiimporter.db_config_prefix = hostedapps.db.
 mediawikiimporter.attachments_dir_prefix = /nfs/mediawiki-attachments/
@@ -70,8 +71,9 @@ smtp.mock = true
 # Forgemail server
 forgemail.host = 0.0.0.0
 forgemail.port = 8825
-forgemail.domain = .in.sf.net
+forgemail.domain = .in.localhost
 forgemail.url = http://localhost:8080
+forgemail.return_path = noreply@localhost
 
 load_test_data = true
 cache_test_data = false

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/AlluraTest/alluratest/validation.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/validation.py b/AlluraTest/alluratest/validation.py
index 4af5012..1bf6b22 100644
--- a/AlluraTest/alluratest/validation.py
+++ b/AlluraTest/alluratest/validation.py
@@ -68,12 +68,6 @@ class Config(object):
             self.ini_config = conf
         return self.ini_config
 
-    @LazyProperty
-    def hostname(self):
-        if os.path.exists('/etc/soghost'):
-            with open('/etc/soghost') as fp:
-                return fp.read().strip()
-
     def validation_enabled(self, val_type):
         env_var = os.getenv('ALLURA_VALIDATION')
         if env_var == 'all':

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeActivity/forgeactivity/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/tests/functional/test_root.py b/ForgeActivity/forgeactivity/tests/functional/test_root.py
index 6ac88d9..441fa82 100644
--- a/ForgeActivity/forgeactivity/tests/functional/test_root.py
+++ b/ForgeActivity/forgeactivity/tests/functional/test_root.py
@@ -62,7 +62,7 @@ class TestActivityController(TestController):
             "_id": ObjectId("529fa331033c5e6406d8b338"),
             "obj": {
                 "activity_extras": {
-                    "allura_id": "Post:971389ad979eaafa658beb807bf4629d30f5f642.tickets@test.p.sourceforge.net",
+                    "allura_id": "Post:971389ad979eaafa658beb807bf4629d30f5f642.tickets@test.p.domain.net",
                     "summary": "Just wanted to leave a comment on this..."
                 },
                 "activity_url": "/p/test/tickets/_discuss/thread/08e74efd/ed7c/",

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeChat/forgechat/command.py
----------------------------------------------------------------------
diff --git a/ForgeChat/forgechat/command.py b/ForgeChat/forgechat/command.py
index 16f730f..6af2eaa 100644
--- a/ForgeChat/forgechat/command.py
+++ b/ForgeChat/forgechat/command.py
@@ -67,7 +67,9 @@ class IRCBotCommand(allura.command.Command):
 class IRCBot(asynchat.async_chat):
     TIME_BETWEEN_CONFIGS = timedelta(minutes=1)
 
-    def __init__(self, host, port, nick='sfbot'):
+    def __init__(self, host, port, nick=None):
+        if nick is None:
+            nick = tg.config.get('ircbot.nick', 'allurabot')
         self.logger = logging.getLogger(__name__)
         self.host = host
         self.port = port
@@ -79,7 +81,9 @@ class IRCBot(asynchat.async_chat):
         self.data = []
         self.channels = {}
         self.set_nick('000')
-        self.say('USER sfbot %s %s :SFBot 0.0' % (self.host, self.host))
+        self.say('USER {nick} {host} {host} :{nick} 0.0'.format(
+            nick=self.nick,
+            host=self.host))
         self.configure()
 
     def set_nick(self, suffix=None):
@@ -174,7 +178,7 @@ class IRCBot(asynchat.async_chat):
             index = art.index()
             text = index['snippet_s'] or h.get_first(index, 'title')
             url = urljoin(
-                tg.config.get('base_url', 'http://sourceforge.net'), index['url_s'])
+                tg.config['base_url'], index['url_s'])
             self.notice(rcpt, '[%s] - [%s](%s)' % (lnk.link, text, url))
 
     def log_channel(self, sender, cmd, rcpt, rest):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index a42a025..34b71c9 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -157,32 +157,32 @@ class TestForumAsync(TestController):
 
     def test_reply(self):
         self._post('testforum', 'Test Thread', 'Nothing here',
-                   message_id='test_reply@sf.net')
+                   message_id='test_reply@domain.net')
         assert_equal(FM.ForumThread.query.find().count(), 1)
         posts = FM.ForumPost.query.find()
         assert_equal(posts.count(), 1)
         assert_equal(FM.ForumThread.query.get().num_replies, 1)
         assert_equal(FM.ForumThread.query.get()
-                     .first_post_id, 'test_reply@sf.net')
+                     .first_post_id, 'test_reply@domain.net')
 
         post = posts.first()
         self._post('testforum', 'Test Reply', 'Nothing here, either',
                    message_id=post.thread.url() + post._id,
-                   in_reply_to=['test_reply@sf.net'])
+                   in_reply_to=['test_reply@domain.net'])
         assert_equal(FM.ForumThread.query.find().count(), 1)
         assert_equal(FM.ForumPost.query.find().count(), 2)
         assert_equal(FM.ForumThread.query.get()
-                     .first_post_id, 'test_reply@sf.net')
+                     .first_post_id, 'test_reply@domain.net')
 
     def test_attach(self):
         self._post('testforum', 'Attachment Thread', 'This is a text file',
-                   message_id='test.attach.100@sf.net',
+                   message_id='test.attach.100@domain.net',
                    filename='test.txt',
                    content_type='text/plain')
         self._post('testforum', 'Test Thread', 'Nothing here',
-                   message_id='test.attach.100@sf.net')
+                   message_id='test.attach.100@domain.net')
         self._post('testforum', 'Attachment Thread', 'This is a text file',
-                   message_id='test.attach.100@sf.net',
+                   message_id='test.attach.100@domain.net',
                    content_type='text/plain')
 
     def test_threads(self):
@@ -225,9 +225,9 @@ class TestForumAsync(TestController):
         params[post_form.find('textarea')['name']] = 'text'
         r = self.app.post(url + 'reply', params=params)
         self._post('testforum', 'Test Reply', 'Nothing here, either',
-                   message_id='test_posts@sf.net',
+                   message_id='test_posts@domain.net',
                    in_reply_to=[p._id])
-        reply = FM.ForumPost.query.get(_id='test_posts@sf.net')
+        reply = FM.ForumPost.query.get(_id='test_posts@domain.net')
         r = self.app.get(thd_url + reply.slug + '/')
         # Check attachments
         r = self.app.post(url + 'attach',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
index 2f28cbc..0eb4168 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum_admin.py
@@ -306,7 +306,7 @@ class TestForumAdmin(TestController):
         M.MonQTask.run_ready()
         email_tasks = M.MonQTask.query.find(
             dict(task_name='allura.tasks.mail_tasks.sendsimplemail')).all()
-        assert 'Sent from sourceforge.net because email@monitoring.com is subscribed to http://localhost/p/test/discussion/testforum/' in email_tasks[
+        assert 'Sent from localhost because email@monitoring.com is subscribed to http://localhost/p/test/discussion/testforum/' in email_tasks[
             0].kwargs['text'], email_tasks[0].kwargs['text']
         assert 'a project admin can change settings at http://localhost/p/test/admin/discussion/forums' in email_tasks[
             0].kwargs['text']

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeGit/forgegit/templates/git/index.html
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/templates/git/index.html b/ForgeGit/forgegit/templates/git/index.html
index f300d7a..4ef57ea 100644
--- a/ForgeGit/forgegit/templates/git/index.html
+++ b/ForgeGit/forgegit/templates/git/index.html
@@ -78,7 +78,7 @@ git branch --set-upstream master origin/master  # so 'git pull' will work later<
     &nbsp;
     <div class="message info scm-ssh-key">
       <div class="content">
-        Did you get asked for your SourceForge password during this process? You can securely use your Git repository and avoid having to re-enter your password by <a href="https://sourceforge.net/account/ssh">setting up an ssh-key</a>.
+      Did you get asked for your {{config.site_name}} password during this process? You can securely use your Git repository and avoid having to re-enter your password by <a href="https://{{config.domain}}/account/ssh">setting up an ssh-key</a>.
       </div>
     </div>
     {% else %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 5fd0805..4943fce 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -260,13 +260,14 @@ class TestRootController(_TestCase):
 
     def test_refresh(self):
         notification = M.Notification.query.find(
-            dict(subject='[test:src-git] 5 new commits to Test Project Git')).first()
+            dict(subject='[test:src-git] 5 new commits to Test Project Git')
+            ).first()
         assert notification
         domain = '.'.join(
             reversed(c.app.url[1:-1].split('/'))).replace('_', '-')
-        common_suffix = tg.config.get('forgemail.domain', '.sourceforge.net')
+        common_suffix = tg.config['forgemail.domain']
         email = 'noreply@%s%s' % (domain, common_suffix)
-        assert email in notification['reply_to_address']
+        assert_in(email, notification['reply_to_address'])
 
     def test_file_force_display(self):
         ci = self._get_ci()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeImporters/forgeimporters/github/tests/test_wiki.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/github/tests/test_wiki.py b/ForgeImporters/forgeimporters/github/tests/test_wiki.py
index 1eb996a..f231f49 100644
--- a/ForgeImporters/forgeimporters/github/tests/test_wiki.py
+++ b/ForgeImporters/forgeimporters/github/tests/test_wiki.py
@@ -73,9 +73,6 @@ class TestGitHubWikiImporter(TestCase):
                 project=p, user=u, url='foo')
             g.post_event.assert_called_once_with('project_updated')
 
-
-class TestGitHubWikiImporter(TestCase):
-
     def setUp(self):
         setup_basic_test()
         self.blob1 = Mock()
@@ -260,17 +257,17 @@ class TestGitHubWikiImporter(TestCase):
 
     def test_convert_gollum_external_links(self):
         f = GitHubWikiImporter().convert_gollum_tags
-        assert_equal(f(u'[[http://sf.net]]'), u'<http://sf.net>')
-        assert_equal(f(u'[[https://sf.net]]'), u'<https://sf.net>')
-        assert_equal(f(u'[[SourceForge|http://sf.net]]'),
-                     u'[SourceForge](http://sf.net)')
+        assert_equal(f(u'[[http://domain.net]]'), u'<http://domain.net>')
+        assert_equal(f(u'[[https://domain.net]]'), u'<https://domain.net>')
+        assert_equal(f(u'[[Site|http://domain.net]]'),
+                     u'[Site](http://domain.net)')
 
     def test_convert_gollum_external_links_escaped(self):
         f = GitHubWikiImporter().convert_gollum_tags
-        assert_equal(f(u"'[[http://sf.net]]"), u'[[http://sf.net]]')
-        assert_equal(f(u"'[[https://sf.net]]"), u'[[https://sf.net]]')
-        assert_equal(f(u"'[[SourceForge|http://sf.net]]"),
-                     u'[[SourceForge|http://sf.net]]')
+        assert_equal(f(u"'[[http://domain.net]]"), u'[[http://domain.net]]')
+        assert_equal(f(u"'[[https://domain.net]]"), u'[[https://domain.net]]')
+        assert_equal(f(u"'[[Site|http://domain.net]]"),
+                     u'[[Site|http://domain.net]]')
 
     def test_convert_gollum_toc(self):
         f = GitHubWikiImporter().convert_gollum_tags
@@ -283,7 +280,7 @@ class TestGitHubWikiImporter(TestCase):
 
 More info at: [[MoreInfo]] [[Even More Info]]
 
-Our website is [[http://sf.net]].
+Our website is [[http://domain.net]].
 
 '[[Escaped Tag]]'''
 
@@ -291,7 +288,7 @@ Our website is [[http://sf.net]].
 
 More info at: [MoreInfo] [Even More Info]
 
-Our website is <http://sf.net>.
+Our website is <http://domain.net>.
 
 [[Escaped Tag]]'''
 
@@ -310,7 +307,7 @@ Our website is <http://sf.net>.
 
 More info at: [[MoreInfo]] [[Even More Info]]
 
-Our website is [[http://sf.net]].
+Our website is [[http://domain.net]].
 
 '[[Escaped Tag]]
 
@@ -327,7 +324,7 @@ sha aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'''
 
 More info at: [MoreInfo] [Even More Info]
 
-Our website is <http://sf.net>.
+Our website is <http://domain.net>.
 
 [[Escaped Tag]]
 
@@ -354,7 +351,7 @@ sha [aaaaaa]'''
 
 More info at: [[MoreInfo]] [[Even More Info]]
 
-Our website is [[http://sf.net]].
+Our website is [[http://domain.net]].
 
 '[[Escaped Tag]]
 
@@ -364,7 +361,7 @@ Our website is [[http://sf.net]].
 
         result = u'''<p>Look at [[this page|Some Page]]</p>
 <p>More info at: [[MoreInfo]] [[Even More Info]]</p>
-<p>Our website is [[http://sf.net]].</p>
+<p>Our website is [[http://domain.net]].</p>
 <p>'[[Escaped Tag]]</p>
 <p>[External link to the wiki page](https://github.com/a/b/wiki/Page)</p>
 <p>[External link](https://github.com/a/b/issues/1)</p>'''

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeImporters/forgeimporters/trac/tests/data/test-list.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/trac/tests/data/test-list.html b/ForgeImporters/forgeimporters/trac/tests/data/test-list.html
index 2e96702..ccd10c9 100644
--- a/ForgeImporters/forgeimporters/trac/tests/data/test-list.html
+++ b/ForgeImporters/forgeimporters/trac/tests/data/test-list.html
@@ -47,8 +47,6 @@
     </script>
   <link type="text/css" href="/apps/trac/open-ms/chrome/site/ha-css/default2.css" rel="stylesheet" />
 
-    <link rel="stylesheet" type="text/css" href="http://static.sourceforge.net/css/develop/hosted.php?secure=0&amp;1383143209" media="all" />
-
     <!-- BEGIN: AdSolution-Tag 4.2: Global-Code [PLACE IN HTML-HEAD-AREA!] -->
     <!-- DoubleClick Random Number -->
     <script type="text/javascript">
@@ -80,22 +78,16 @@
 <div id="sf_header">
     <div class="sfh_n">
         <ol class="sfh_n_ol">
-            <li class="sfh_n_li"><span><a href="/" id="sf_logo"><strong>SourceForge</strong></a></span></li>
-            <li class="sfh_n_li"><span><a href="/projects/open-ms" title="Summary page hosted on SourceForge.net">Summary</a></span></li>
+            <li class="sfh_n_li"><span><a href="/" id="sf_logo"><strong>Domain</strong></a></span></li>
+            <li class="sfh_n_li"><span><a href="/projects/open-ms" title="Summary page">Summary</a></span></li>
             <li class="sfh_n_li"><span><a href="/projects/open-ms/files" title="Files available for download">Files</a></span></li>                            <li class="sfh_n_li"><span><a href="/projects/open-ms/support">Support</a></span></li>
                         <li class="sfh_n_li"><span><a href="/support">Report Spam</a></span></li>
-                            <li class="sfh_n_li right"><span><a href="/user/registration/" title="Get a SourceForge.net account">Create account</a></span></li>
+                            <li class="sfh_n_li right"><span><a href="/user/registration/" title="Get an account">Create account</a></span></li>
                 <li class="sfh_n_li right"><span><a href="/account/login.php" title="Log in and gain access to additional features">Log in</a></span></li>
                     </ol>
     </div>
 </div>
 <div id="fad1happ" class="ads">
-   <script type="text/javascript">
-   //<![CDATA[
-    document.write('<script src="http://ad.doubleclick.net/adj/ostg.sourceforge/cons_hosted_apps_p11_spons;pg=default;sz=728x90;tile='+dfp_tile+';tpc=project;tpc=open-ms;ord='+dfp_ord+'?" type="text/javascript"><\/script>');
-     dfp_tile++;
-    //]]>
-    </script>
 </div>
     
 
@@ -105,7 +97,6 @@
 <!-- End Header -->
     <div id="banner">
       <div id="header">
-        <h1><a href="http://sourceforge.net/projects/open-ms/">OpenMS</a></h1>
       </div>
       <form id="search" action="/apps/trac/open-ms/search" method="get">
         <div>
@@ -329,8 +320,7 @@ fixed in rev. 10330<br />
 <!-- End Footer -->
 
     
-<p class="copyright">&copy; 2013 SourceForge. All Rights Reserved.
-SourceForge is a <a href="http://www.diceholdingsinc.com/phoenix.zhtml?c=211152&p=irol-landing">Dice Holdings, Inc.</a> company &nbsp;
+<p class="copyright">
 <a href="http://slashdotmedia.com/terms-of-use">Terms of Use</a> -
 <a href="http://slashdotmedia.com/privacy-statement/">Privacy Policy</a> -
 <a href="http://slashdotmedia.com/opt-out-choices">Cookies/Opt Out</a>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeImporters/forgeimporters/trac/tests/data/trac-export.json
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/trac/tests/data/trac-export.json b/ForgeImporters/forgeimporters/trac/tests/data/trac-export.json
index 82d7b89..597475e 100644
--- a/ForgeImporters/forgeimporters/trac/tests/data/trac-export.json
+++ b/ForgeImporters/forgeimporters/trac/tests/data/trac-export.json
@@ -12,7 +12,7 @@
               "description": "Shows the display error", 
               "filename": "SF%20display%20error.JPG", 
               "size": 184728, 
-              "url": "http://sourceforge.net/apps/trac/sourceforge/raw-attachment/ticket/204/SF%20display%20error.JPG"
+              "url": "http://domain.net/apps/trac/project/raw-attachment/ticket/204/SF%20display%20error.JPG"
             }
           ], 
           "cc": "ma_boehm", 
@@ -26,7 +26,7 @@
             }, 
             {
               "class": "COMMENT", 
-              "comment": "  * **owner** set to _hinojosa_\n\n  * **status** changed from _new_ to _assigned_\n\nHi,\n\nI'm investigating this. I need to fire up my system with this browser.\n\nIf you need anything else, please post a response to this request.\n\nCheers!,\n\nDaniel Hinojosa - Sr. Manager, [SourceForge][1].net Support\n\nP.S., Be sure to monitor our Site Status page,\n[https://sourceforge.net/sitestatus][2].\n\n   [1]: http://sourceforge.net/apps/trac/sourceforge/wiki/SourceForge\n\n   [2]: https://sourceforge.net/sitestatus\n\n", 
+              "comment": "  * **owner** set to _hinojosa_\n\n  * **status** changed from _new_ to _assigned_\n\nHi,\n\nI'm investigating this. I need to fire up my system with this browser.\n\nIf you need anything else, please post a response to this request.\n\nCheers!,\n\nDaniel Hinojosa - Sr. Manager, Support\n\nP.S., Be sure to monitor our Site Status page,\n\n", 
               "date": "2009-04-13T15:46:18Z", 
               "submitter": "hinojosa"
             }, 
@@ -38,20 +38,20 @@
             }, 
             {
               "class": "COMMENT", 
-              "comment": "  * **status** changed from _accepted_ to _closed_\n\n  * **resolution** set to _fixed_\n\nHello,\n\nThis issue is should be resolved with the site redesign.\n\nRegards, Chris Tsai, SourceForge.net Support\n\n", 
+              "comment": "  * **status** changed from _accepted_ to _closed_\n\n  * **resolution** set to _fixed_\n\nHello,\n\nThis issue is should be resolved with the site redesign.\n\nRegards, Chris Tsai, Support\n\n", 
               "date": "2009-07-20T15:44:32Z", 
               "submitter": "ctsai"
             },
             {
               "class": "COMMENT",
-              "comment": "test link [[2496]](http://testlink.com)  test ticket ([#201](http://sourceforge.net/apps/trac/sourceforge/ticket/201)) \n [test comment](http://sourceforge.net/apps/trac/sourceforge/ticket/204#comment:1) \n [test comment](http://sourceforge.net/apps/trac/sourceforge/ticket/204#comment:45)",
+              "comment": "test link [[2496]](http://testlink.com)  test ticket ([#201](http://domain.net/apps/trac/project/ticket/201)) \n [test comment](http://domain.net/apps/trac/project/ticket/204#comment:1) \n [test comment](http://domain.net/apps/trac/project/ticket/204#comment:45)",
               "date": "2009-07-21T15:44:32Z",
               "submitter": "ctsai"
             }
           ], 
           "date": "2009-04-13T08:49:13Z", 
           "date_updated": "2009-07-20T15:44:32Z", 
-          "description": "This problem occurs with IE 7, Windows Vista:\r\nOn the project's public info page (for example:\r\nhttps://sourceforge.net/project/admin/public_info.php?group_id=258655), the text boxes next to \"Descriptive Name\" and \"Project Description\" are not aligned properly; see the screenshot attached. ",
+          "description": "This problem occurs with IE 7, Windows Vista:\r\nOn the project's public info page (for example:\r\nhttps://domain.net/project/admin/public_info.php?group_id=258655), the text boxes next to \"Descriptive Name\" and \"Project Description\" are not aligned properly; see the screenshot attached. ",
           "id": 204, 
           "keywords": "ENGR",
           "milestone": "test_milestone",

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeLink/forgelink/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeLink/forgelink/tests/test_app.py b/ForgeLink/forgelink/tests/test_app.py
index 8149815..f4bbe84 100644
--- a/ForgeLink/forgelink/tests/test_app.py
+++ b/ForgeLink/forgelink/tests/test_app.py
@@ -39,8 +39,8 @@ class TestBulkExport(object):
 
         project = M.Project.query.get(shortname='test')
         link = project.app_instance('link')
-        link.config.options['url'] = 'http://sf.net'
+        link.config.options['url'] = 'http://domain.net'
         f = tempfile.TemporaryFile()
         link.bulk_export(f)
         f.seek(0)
-        assert_equal(json.loads(f.read())['url'], 'http://sf.net')
+        assert_equal(json.loads(f.read())['url'], 'http://domain.net')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeSVN/forgesvn/templates/svn/index.html
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/templates/svn/index.html b/ForgeSVN/forgesvn/templates/svn/index.html
index 9b81fe3..8625b0b 100644
--- a/ForgeSVN/forgesvn/templates/svn/index.html
+++ b/ForgeSVN/forgesvn/templates/svn/index.html
@@ -87,7 +87,7 @@ svn import {{c.app.repo.clone_url('rw', c.user.username)}} -m "Initial commit"</
     &nbsp;
     <div class="message info scm-ssh-key">
       <div class="content">
-        Did you get asked for your SourceForge password during this process? You can securely use your Subversion repository and avoid having to re-enter your password by <a href="https://sourceforge.net/account/ssh">setting up an ssh-key</a>.
+      Did you get asked for your {{config.site_name}} password during this process? You can securely use your Subversion repository and avoid having to re-enter your password by <a href="https://{{config.domain}}/account/ssh">setting up an ssh-key</a>.
       </div>
     </div>
     {% else %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeSVN/forgesvn/tests/data/testsvn-trunk-tags-branches/hooks/post-commit
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/data/testsvn-trunk-tags-branches/hooks/post-commit b/ForgeSVN/forgesvn/tests/data/testsvn-trunk-tags-branches/hooks/post-commit
index 1ad70a4..6c22c26 100755
--- a/ForgeSVN/forgesvn/tests/data/testsvn-trunk-tags-branches/hooks/post-commit
+++ b/ForgeSVN/forgesvn/tests/data/testsvn-trunk-tags-branches/hooks/post-commit
@@ -1,8 +1,8 @@
 #!/bin/bash
 # The following is required for site integration, do not remove/modify.
 # Place user hook code in post-commit-user and it will be called from here.
-curl -s http://sf-fortytwo-7045.sb.sf.net/auth/refresh_repo/p/test/code-1/
+curl -s http://domain.net/auth/refresh_repo/p/test/code-1/
 
 DIR="$(dirname "${BASH_SOURCE[0]}")"
 if [ -x $DIR/post-commit-user ]; then  exec $DIR/post-commit-user "$@"
-fi
\ No newline at end of file
+fi

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeSVN/forgesvn/tests/data/testsvn/hooks/post-commit
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/data/testsvn/hooks/post-commit b/ForgeSVN/forgesvn/tests/data/testsvn/hooks/post-commit
index d6f67b5..5534ed7 100755
--- a/ForgeSVN/forgesvn/tests/data/testsvn/hooks/post-commit
+++ b/ForgeSVN/forgesvn/tests/data/testsvn/hooks/post-commit
@@ -1,9 +1,5 @@
 #!/bin/sh
 # THIS FILE IS AUTOGENERATED - DO NOT EDIT
-/var/local/mastertree/host/sfp-svn/hook-scripts/sf-svn-stats-hook.py $*
-/var/local/mastertree/host/sfp-svn/hook-scripts/keepsake -p "$1"
-/var/local/mastertree/host/sfp-svn/hook-scripts/ciabot_svn.py --revisionURI="http://t2809.svn.sourceforge.net/%(project)s/?view=rev&rev=%(revision)s" --repositoryURI=https://t2809.svn.sourceforge.net/svnroot/t2809 "$1" "$2" t2809
-/var/local/mastertree/host/sfp-svn/hook-scripts/ciabot_svn.py --revisionURI="http://t2809.svn.sourceforge.net/t2809/?view=rev&rev=%(revision)s" --repositoryURI=https://t2809.svn.sourceforge.net/svnroot/t2809 "$1" "$2" "foo"
-/var/local/mastertree/host/sfp-svn/hook-scripts/svnnotify --repos-path "$1" --revision "$2" --to "test@example.com" --subject-prefix "SF.net SVN: t2809:" --subject-cx --no-first-line --with-diff --viewcvs-url "http://t2809.svn.sourceforge.net/t2809/?rev=%s&view=rev" --user-domain "users.sourceforge.net" --footer "This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site." -l /usr/bin/svnlook --max-diff-length 100000
-/var/local/mastertree/host/sfp-svn/hook-scripts/svnnotify --repos-path "$1" --revision "$2" --to "test@example.com" --subject-prefix "SF.net SVN: t2809:" --subject-cx --no-first-line --viewcvs-url "http://t2809.svn.sourceforge.net/t2809/?rev=%s&view=rev" --user-domain "users.sourceforge.net" --footer "This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site." -l /usr/bin/svnlook --max-diff-length 100000
+/hook-scripts/sf-svn-stats-hook.py $*
+/hook-scripts/keepsake -p "$1"
 exit 0

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeSVN/forgesvn/tests/model/test_repository.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/model/test_repository.py b/ForgeSVN/forgesvn/tests/model/test_repository.py
index 7f0c7b9..9b527f0 100644
--- a/ForgeSVN/forgesvn/tests/model/test_repository.py
+++ b/ForgeSVN/forgesvn/tests/model/test_repository.py
@@ -162,10 +162,11 @@ class TestSVNRepo(unittest.TestCase, RepoImplTestBase):
         assert os.access(
             os.path.join(g.tmpdir, 'testsvn/hooks/post-commit'), os.X_OK)
         with open(os.path.join(g.tmpdir, 'testsvn/hooks/post-commit')) as f:
-            c = f.read()
+            hook_data = f.read()
         self.assertIn(
-            'curl -s http://localhost/auth/refresh_repo/p/test/src/\n', c)
-        self.assertIn('exec $DIR/post-commit-user "$@"\n', c)
+            'curl -s http://localhost/auth/refresh_repo/p/test/src/\n',
+            hook_data)
+        self.assertIn('exec $DIR/post-commit-user "$@"\n', hook_data)
 
         repo.refresh(notify=False)
         assert len(list(repo.log()))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeShortUrl/forgeshorturl/tests/functional/test.py
----------------------------------------------------------------------
diff --git a/ForgeShortUrl/forgeshorturl/tests/functional/test.py b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
index 67931aa..0cc8db3 100644
--- a/ForgeShortUrl/forgeshorturl/tests/functional/test.py
+++ b/ForgeShortUrl/forgeshorturl/tests/functional/test.py
@@ -108,12 +108,12 @@ class TestRootController(TestController):
         assert 'exists' in self.webflash(r)
 
     def test_shorturl_chars_restrictions(self):
-        d = dict(short_url='', full_url='http://sf.net/')
+        d = dict(short_url='', full_url='http://domain.net/')
         r = self.app.post('/admin/url/add', params=d)
         assert ShortUrl.query.find(
             dict(app_config_id=c.app.config._id)).count() == 0
         assert 'Please enter a value' in self.webflash(r)
-        d = dict(short_url='g*', full_url='http://sf.net/')
+        d = dict(short_url='g*', full_url='http://domain.net/')
         r = self.app.post('/admin/url/add', params=d)
         assert ShortUrl.query.find(
             dict(app_config_id=c.app.config._id)).count() == 0

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeTracker/forgetracker/tests/functional/data/sf.json
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/data/sf.json b/ForgeTracker/forgetracker/tests/functional/data/sf.json
index 82d7b89..597475e 100644
--- a/ForgeTracker/forgetracker/tests/functional/data/sf.json
+++ b/ForgeTracker/forgetracker/tests/functional/data/sf.json
@@ -12,7 +12,7 @@
               "description": "Shows the display error", 
               "filename": "SF%20display%20error.JPG", 
               "size": 184728, 
-              "url": "http://sourceforge.net/apps/trac/sourceforge/raw-attachment/ticket/204/SF%20display%20error.JPG"
+              "url": "http://domain.net/apps/trac/project/raw-attachment/ticket/204/SF%20display%20error.JPG"
             }
           ], 
           "cc": "ma_boehm", 
@@ -26,7 +26,7 @@
             }, 
             {
               "class": "COMMENT", 
-              "comment": "  * **owner** set to _hinojosa_\n\n  * **status** changed from _new_ to _assigned_\n\nHi,\n\nI'm investigating this. I need to fire up my system with this browser.\n\nIf you need anything else, please post a response to this request.\n\nCheers!,\n\nDaniel Hinojosa - Sr. Manager, [SourceForge][1].net Support\n\nP.S., Be sure to monitor our Site Status page,\n[https://sourceforge.net/sitestatus][2].\n\n   [1]: http://sourceforge.net/apps/trac/sourceforge/wiki/SourceForge\n\n   [2]: https://sourceforge.net/sitestatus\n\n", 
+              "comment": "  * **owner** set to _hinojosa_\n\n  * **status** changed from _new_ to _assigned_\n\nHi,\n\nI'm investigating this. I need to fire up my system with this browser.\n\nIf you need anything else, please post a response to this request.\n\nCheers!,\n\nDaniel Hinojosa - Sr. Manager, Support\n\nP.S., Be sure to monitor our Site Status page,\n\n", 
               "date": "2009-04-13T15:46:18Z", 
               "submitter": "hinojosa"
             }, 
@@ -38,20 +38,20 @@
             }, 
             {
               "class": "COMMENT", 
-              "comment": "  * **status** changed from _accepted_ to _closed_\n\n  * **resolution** set to _fixed_\n\nHello,\n\nThis issue is should be resolved with the site redesign.\n\nRegards, Chris Tsai, SourceForge.net Support\n\n", 
+              "comment": "  * **status** changed from _accepted_ to _closed_\n\n  * **resolution** set to _fixed_\n\nHello,\n\nThis issue is should be resolved with the site redesign.\n\nRegards, Chris Tsai, Support\n\n", 
               "date": "2009-07-20T15:44:32Z", 
               "submitter": "ctsai"
             },
             {
               "class": "COMMENT",
-              "comment": "test link [[2496]](http://testlink.com)  test ticket ([#201](http://sourceforge.net/apps/trac/sourceforge/ticket/201)) \n [test comment](http://sourceforge.net/apps/trac/sourceforge/ticket/204#comment:1) \n [test comment](http://sourceforge.net/apps/trac/sourceforge/ticket/204#comment:45)",
+              "comment": "test link [[2496]](http://testlink.com)  test ticket ([#201](http://domain.net/apps/trac/project/ticket/201)) \n [test comment](http://domain.net/apps/trac/project/ticket/204#comment:1) \n [test comment](http://domain.net/apps/trac/project/ticket/204#comment:45)",
               "date": "2009-07-21T15:44:32Z",
               "submitter": "ctsai"
             }
           ], 
           "date": "2009-04-13T08:49:13Z", 
           "date_updated": "2009-07-20T15:44:32Z", 
-          "description": "This problem occurs with IE 7, Windows Vista:\r\nOn the project's public info page (for example:\r\nhttps://sourceforge.net/project/admin/public_info.php?group_id=258655), the text boxes next to \"Descriptive Name\" and \"Project Description\" are not aligned properly; see the screenshot attached. ",
+          "description": "This problem occurs with IE 7, Windows Vista:\r\nOn the project's public info page (for example:\r\nhttps://domain.net/project/admin/public_info.php?group_id=258655), the text boxes next to \"Descriptive Name\" and \"Project Description\" are not aligned properly; see the screenshot attached. ",
           "id": 204, 
           "keywords": "ENGR",
           "milestone": "test_milestone",

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5d46b785/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index d6ec7e0..a4688b9 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -31,6 +31,7 @@ from nose.tools import assert_true, assert_false, assert_equal, assert_in
 from nose.tools import assert_raises, assert_not_in, assert_items_equal
 from formencode.variabledecode import variable_encode
 from pylons import tmpl_context as c
+from pylons import app_globals as g
 
 from alluratest.controller import TestController, setup_basic_test
 from allura import model as M
@@ -2259,7 +2260,7 @@ class TestFunctionalController(TrackerTestController):
                 fromaddr=str(c.user._id),
                 destinations=[str(c.user._id)],
                 text=text,
-                reply_to=u'noreply@sf.net',
+                reply_to=g.noreply,
                 subject=email.kwargs.subject,
                 message_id=h.gen_message_id())
             assert_equal(_client.sendmail.call_count, 1)
@@ -2496,7 +2497,7 @@ class TestEmailMonitoring(TrackerTestController):
         M.MonQTask.run_ready()
         email_tasks = M.MonQTask.query.find(
             dict(task_name='allura.tasks.mail_tasks.sendsimplemail')).all()
-        assert 'Sent from sourceforge.net because mailinglist@example.com is subscribed to http://localhost/p/test/bugs/' in email_tasks[
+        assert 'Sent from localhost because mailinglist@example.com is subscribed to http://localhost/p/test/bugs/' in email_tasks[
             0].kwargs['text']
         assert 'a project admin can change settings at http://localhost/p/test/admin/bugs/options' in email_tasks[
             0].kwargs['text']


[26/28] git commit: [#4257] Disable hash-based scroll management as it's not worth it

Posted by jo...@apache.org.
[#4257] Disable hash-based scroll management as it's not worth it

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: de4f5b715c58a9d04945f14259351c886cf962a0
Parents: a3c5bf7
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Jan 22 17:12:35 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:04 2014 +0000

----------------------------------------------------------------------
 ForgeActivity/forgeactivity/nf/activity/js/activity.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/de4f5b71/ForgeActivity/forgeactivity/nf/activity/js/activity.js
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/nf/activity/js/activity.js b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
index 80b79d8..0ed3b0e 100644
--- a/ForgeActivity/forgeactivity/nf/activity/js/activity.js
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -21,7 +21,7 @@ ASOptions = {
     maxPages: 3,
     maintainScrollHistory: true,
     usePjax: true,
-    useHash: true,
+    useHash: false, // not worth the jitter
     forceAdvancedScroll: false,
     useShowMore: false,
     useInfiniteScroll: true


[23/28] git commit: [#4257] Ugly hack to fix Access Denied error in IE

Posted by jo...@apache.org.
[#4257] Ugly hack to fix Access Denied error in IE

It seems that some combination of IE11, jQuery 1.8.0, and possibly
something else on our page, doing $('<li>elem</li>') causes IE to raise
an "Access denied" error claiming that we're attempting cross-site
javascript iframe access.  However, doing $('#elem').append('<li>elem</li>')
works fine.  I'd prefer to upgrade jQuery but this is a quicker work-around.

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: a3c5bf7f2328c21303f17a6a1f1aeffb7fab02d2
Parents: c77b366
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Jan 22 17:05:58 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:04 2014 +0000

----------------------------------------------------------------------
 .../forgeactivity/nf/activity/js/activity.js         | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a3c5bf7f/ForgeActivity/forgeactivity/nf/activity/js/activity.js
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/nf/activity/js/activity.js b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
index f6807d7..80b79d8 100644
--- a/ForgeActivity/forgeactivity/nf/activity/js/activity.js
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -164,16 +164,21 @@ $(function() {
         }
         var newerText = newer ? 'newer' : 'older';
         $.get(url, function(html) {
-            var $html = $(html);
             var $timeline = $('.timeline');
-            var newPage = $html.data('page');
+            var empty = html.match(/^\s*$/);
+            var newestPage = newer && $('.timeline li:first').data('page') <= 1;
             var limit = $('.timeline').data('limit');
+            var fullPage = true;
             saveScrollPosition();
-            if ($html.length < limit || newPage == 0) {
+            if (!empty) {
+                $timeline[newer ? 'prepend' : 'append'](html);
+                var newPage = $timeline.find('li:' + (newer ? 'first' : 'last')).data('page');
+                fullPage = $timeline.find('li:timeline-page('+newPage+')').length == limit;
+                pageOut(!newer);
+            }
+            if (empty || !fullPage || newestPage) {
                 makeNoMore(newer);
             }
-            $timeline[newer ? 'prepend' : 'append']($html);
-            pageOut(!newer);
             if (ASOptions.useShowMore) {
                 // this has to be here instead of showMoreLink handler to
                 // ensure that scroll changes between added / removed content


[06/28] git commit: [#7002] Fixed notifications not working in base theme

Posted by jo...@apache.org.
[#7002] Fixed notifications not working in base theme

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: be272fa80d38ec0e39e9f3d4b943c371f8f3b39f
Parents: 0a01450
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Jan 15 20:39:10 2014 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jan 22 14:26:20 2014 +0000

----------------------------------------------------------------------
 Allura/allura/public/nf/js/allura-base.js | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/be272fa8/Allura/allura/public/nf/js/allura-base.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/allura-base.js b/Allura/allura/public/nf/js/allura-base.js
index e6e205e..ec32bf6 100644
--- a/Allura/allura/public/nf/js/allura-base.js
+++ b/Allura/allura/public/nf/js/allura-base.js
@@ -178,6 +178,8 @@ function addCommas(num) {
 }
 
 $(function(){
+    $('html').removeClass('no-js').addClass('js');
+
     // Add notifications for form submission.
     attach_form_retry('form.can-retry');
 


[02/28] git commit: [#7006] Added modernizr to LICENSE

Posted by jo...@apache.org.
[#7006] Added modernizr to LICENSE

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: 9b19981770c5f25380f91e0ca4bd7a37b252dc2e
Parents: 2b25b86
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jan 20 17:04:03 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Mon Jan 20 17:11:16 2014 +0000

----------------------------------------------------------------------
 Allura/LICENSE | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9b199817/Allura/LICENSE
----------------------------------------------------------------------
diff --git a/Allura/LICENSE b/Allura/LICENSE
index 13b7b54..7e0be3d 100644
--- a/Allura/LICENSE
+++ b/Allura/LICENSE
@@ -241,3 +241,6 @@ For details, see allura/public/nf/js/spin.min.js
 
 Sylvester, which is available under the MIT license.
 For details, see allura/public/nf/js/sylvester.js
+
+Modernizr, which is available under the MIT license.
+For details, see allura/public/nf/js/modernizr.js


[03/28] git commit: [#7006] ticket:511 Added Modernizr to suppress canvas error message

Posted by jo...@apache.org.
[#7006] ticket:511 Added Modernizr to suppress canvas error message


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

Branch: refs/heads/cj/4257
Commit: 2b25b864f08899250d8b8e58811006d406086461
Parents: f6b77b8
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Thu Jan 16 17:37:55 2014 +0200
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Mon Jan 20 17:11:16 2014 +0000

----------------------------------------------------------------------
 Allura/allura/lib/widgets/resources/js/commit_browser.js | 10 ++++++++++
 Allura/allura/public/nf/js/modernizr.js                  |  4 ++++
 Allura/allura/templates/jinja_master/master.html         |  1 +
 3 files changed, 15 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2b25b864/Allura/allura/lib/widgets/resources/js/commit_browser.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/commit_browser.js b/Allura/allura/lib/widgets/resources/js/commit_browser.js
index 37c4408..0ba78b7 100644
--- a/Allura/allura/lib/widgets/resources/js/commit_browser.js
+++ b/Allura/allura/lib/widgets/resources/js/commit_browser.js
@@ -88,6 +88,16 @@ if($('#commit_graph')){
     highlighter.height = canvas.height;
     highlighter_ctx.fillStyle = "#ccc";
 
+    // Hide error message
+    Modernizr.load([
+      {
+        test: Modernizr.canvas,
+        yep: function() {
+          $('#commit_browser_canvas_message').hide();
+        }
+      }
+    ]);
+
     function setHeight(cnt) {
       /*
        * Set proper canvas height for cnt commits.

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2b25b864/Allura/allura/public/nf/js/modernizr.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/modernizr.js b/Allura/allura/public/nf/js/modernizr.js
new file mode 100644
index 0000000..f4a54e2
--- /dev/null
+++ b/Allura/allura/public/nf/js/modernizr.js
@@ -0,0 +1,4 @@
+/* Modernizr 2.7.1 (Custom Build) | MIT & BSD
+ * Build: http://modernizr.com/download/#-canvas-canvastext-cssclasses-load
+ */
+;window.Modernizr=function(a,b,c){function u(a){j.cssText=a}function v(a,b){return u(prefixes.join(a+";")+(b||""))}function w(a,b){return typeof a===b}function x(a,b){return!!~(""+a).indexOf(b)}function y(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:w(f,"function")?f.bind(d||b):f}return!1}var d="2.7.1",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m={},n={},o={},p=[],q=p.slice,r,s={}.hasOwnProperty,t;!w(s,"undefined")&&!w(s.call,"undefined")?t=function(a,b){return s.call(a,b)}:t=function(a,b){return b in a&&w(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=q.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(q.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(q.call(arguments)))};return e}),m.canvas=function()
 {var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},m.canvastext=function(){return!!e.canvas&&!!w(b.createElement("canvas").getContext("2d").fillText,"function")};for(var z in m)t(m,z)&&(r=z.toLowerCase(),e[r]=m[z](),p.push((e[r]?"":"no-")+r));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)t(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},u(""),i=k=null,e._version=d,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+p.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){funct
 ion k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isAr
 ray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&
 &b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadyst
 atechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))};

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2b25b864/Allura/allura/templates/jinja_master/master.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/master.html b/Allura/allura/templates/jinja_master/master.html
index 723e56e..dd9c313 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -24,6 +24,7 @@
 {% endif %}
 {% do g.register_forge_js('js/jquery-base.js') %}
 {% do g.register_forge_js('js/jquery.notify.js') %}
+{% do g.register_forge_js('js/modernizr.js') %}
 {% do g.register_forge_js('js/sylvester.js') %}
 {% do g.register_forge_js('js/pb.transformie.min.js') %}
 {% do g.register_forge_js('js/allura-base.js') %}


[08/28] git commit: [#7002] Added activitystream.enabled check to profile section check_display

Posted by jo...@apache.org.
[#7002] Added activitystream.enabled check to profile section check_display

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: fd3bc746a94c5f3bf47cae4b92553dc1c128b7bf
Parents: 9cd0016
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Jan 21 23:05:35 2014 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Jan 22 14:26:21 2014 +0000

----------------------------------------------------------------------
 Allura/allura/ext/user_profile/user_main.py | 10 +++++-----
 ForgeActivity/forgeactivity/main.py         | 11 ++++++++---
 2 files changed, 13 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/fd3bc746/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 788d8a2..31e4bf0 100644
--- a/Allura/allura/ext/user_profile/user_main.py
+++ b/Allura/allura/ext/user_profile/user_main.py
@@ -146,12 +146,12 @@ class UserProfileController(BaseController, FeedController):
         if not user:
             raise exc.HTTPNotFound()
         provider = AuthenticationProvider.get(request)
-        sections = [section(user, c.project) for section in c.app.profile_sections]
+        sections = [section(user, c.project)
+                    for section in c.app.profile_sections]
         return dict(
-                user=user,
-                reg_date=provider.user_registration_date(user),
-                sections=sections,
-            )
+            user=user,
+            reg_date=provider.user_registration_date(user),
+            sections=sections)
 
     def get_feed(self, project, app, user):
         """Return a :class:`allura.controllers.feed.FeedArgs` object describing

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/fd3bc746/ForgeActivity/forgeactivity/main.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/main.py b/ForgeActivity/forgeactivity/main.py
index 6d50427..a86d00f 100644
--- a/ForgeActivity/forgeactivity/main.py
+++ b/ForgeActivity/forgeactivity/main.py
@@ -33,7 +33,6 @@ from allura.lib.security import require_authenticated
 from allura.model.timeline import perm_check
 from allura.lib import helpers as h
 from allura.lib.decorators import require_post
-from allura.model.timeline import perm_check
 from allura.ext.user_profile import ProfileSectionBase
 
 from .widgets.follow import FollowToggle
@@ -101,7 +100,8 @@ class ForgeActivityController(BaseController):
 
         following = g.director.is_connected(c.user, followee)
         timeline = g.director.get_timeline(followee, page=kw.get('page', 0),
-                                           limit=kw.get('limit', 100), actor_only=actor_only,
+                                           limit=kw.get('limit', 100),
+                                           actor_only=actor_only,
                                            filter_func=perm_check(c.user))
         return dict(followee=followee, following=following, timeline=timeline)
 
@@ -212,7 +212,12 @@ class ForgeActivityProfileSection(ProfileSectionBase):
         self.activity_app = self.project.app_instance('activity')
 
     def check_display(self):
-        return self.activity_app is not None
+        app_installed = self.activity_app is not None
+        activity_enabled = config.get('activitystream.enabled', False)
+        activity_enabled = request.cookies.get(
+            'activitystream.enabled', activity_enabled)
+        activity_enabled = asbool(activity_enabled)
+        return app_installed and activity_enabled
 
     def prepare_context(self, context):
         context.update({


[27/28] git commit: [#4257] Added infinite scroll

Posted by jo...@apache.org.
[#4257] Added infinite scroll

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: 23ad4247bb7b7f9461d8f79c715f2954f5d5b4ec
Parents: 3d9ff04
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Sun Jan 19 18:58:10 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:04 2014 +0000

----------------------------------------------------------------------
 .../forgeactivity/nf/activity/js/activity.js    | 65 +++++++++++++++++---
 1 file changed, 55 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/23ad4247/ForgeActivity/forgeactivity/nf/activity/js/activity.js
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/nf/activity/js/activity.js b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
index 48b699f..f6807d7 100644
--- a/ForgeActivity/forgeactivity/nf/activity/js/activity.js
+++ b/ForgeActivity/forgeactivity/nf/activity/js/activity.js
@@ -23,8 +23,8 @@ ASOptions = {
     usePjax: true,
     useHash: true,
     forceAdvancedScroll: false,
-    useShowMore: true,
-    useInfiniteScroll: false
+    useShowMore: false,
+    useInfiniteScroll: true
 }
 
 $(function() {
@@ -111,16 +111,16 @@ $(function() {
         restoreScrollPosition();
     }
 
-    var delayed = null;
+    var scrollHandlerDelayed = null;
     function scrollHandler(event) {
-        clearTimeout(delayed);
+        clearTimeout(scrollHandlerDelayed);
         var method = ASOptions.usePjax
             ? maintainScrollHistory_pjax
             : maintainScrollHistory_hash;
         var delay = ASOptions.usePjax
             ? 100   // scrolls replace history and don't affect scrolling, so more is ok
             : 750;  // scrolls add history and affect scrolling, so make sure they're done
-        delayed = setTimeout(method, delay);
+        scrollHandlerDelayed = setTimeout(method, delay);
     }
 
     function enableScrollHistory() {
@@ -149,11 +149,20 @@ $(function() {
         $('.no-more.'+(newer ? 'newer' : 'older')).remove();
     }
 
+    var pageInQueue = [];
     function pageIn(newer, url) {
         // Load a single page of either newer or older content from the URL.
         // Then calls pageOut to ensure that not too many are loaded at once,
         // to keep memory usage in check.  Also uses save/restoreScrollPosition
         // to try to keep the same content in view at the same place.
+        if ($('.no-more.'+(newer ? 'newer' : 'older')).length) {
+            return;
+        }
+        pageInQueue.push({newer: newer, url: url});
+        if (pageInQueue.length > 1) {
+            return;
+        }
+        var newerText = newer ? 'newer' : 'older';
         $.get(url, function(html) {
             var $html = $(html);
             var $timeline = $('.timeline');
@@ -173,6 +182,11 @@ $(function() {
                 updateShowMore();
             }
             restoreScrollPosition();
+            pageInQueue.shift();
+            if (pageInQueue.length) {
+                var next = pageInQueue.shift();
+                pageIn(next.newer, next.url);
+            }
         }).fail(function() {
             flash('Error loading activities', 'error');
         });
@@ -185,10 +199,15 @@ $(function() {
         $timeline[method]('<div class="no-more '+cls+'">No more activities</div>');
     }
 
-    function makeShowMoreLink(newer, targetPage, limit) {
+    function makePageUrl(targetPage) {
+        var limit = $('.timeline').data('limit');
+        return 'pjax?page='+targetPage+'&limit='+limit;
+    }
+
+    function makeShowMoreLink(newer, targetPage) {
         var $link = $('<a class="show-more">Show More</a>');
         $link.addClass(newer ? 'newer' : 'older');
-        $link.attr('href', 'pjax?page='+targetPage+'&limit='+limit);
+        $link.attr('href', makePageUrl(targetPage));
         $link.click(function(event) {
             event.preventDefault();
             pageIn(newer, this.href);
@@ -199,17 +218,16 @@ $(function() {
     function updateShowMore() {
         // Update the state of the Show More links when using "Show More"-style
         // advanced paging.
-        var limit = $('.timeline').data('limit');
         var firstPage = $('.timeline li:first').data('page');
         var lastPage = $('.timeline li:last').data('page');
         var noMoreNewer = $('.no-more.newer').length;
         var noMoreOlder = $('.no-more.older').length;
         $('.show-more').remove();  // TODO: could update HREFs instead of always re-creating links
         if (!noMoreNewer) {
-            makeShowMoreLink(true, firstPage-1, limit);
+            makeShowMoreLink(true, firstPage-1);
         }
         if (!noMoreOlder) {
-            makeShowMoreLink(false, lastPage+1, limit);
+            makeShowMoreLink(false, lastPage+1);
         }
     }
 
@@ -221,7 +239,34 @@ $(function() {
         updateShowMore();
     }
 
+    var currentPage = null;
+    function handleInfiniteScroll(event) {
+        var newPage = $('.timeline li:in-viewport:first').data('page');
+        if (newPage == currentPage) {
+            return;
+        }
+        var firstPage = $('.timeline li:first').data('page');
+        var lastPage = $('.timeline li:last').data('page');
+        var noMoreNewer = $('.no-more.newer').length;
+        var noMoreOlder = $('.no-more.older').length;
+        if (newPage < currentPage && !noMoreNewer) {
+            pageIn(true, makePageUrl(firstPage-1));
+        } else if (newPage > currentPage && !noMoreOlder) {
+            pageIn(false, makePageUrl(lastPage+1));
+        }
+        currentPage = newPage;
+    }
+
     function enableInfiniteScroll() {
+        $('.page_list').remove();
+        currentPage = $('.timeline li:first').data('page');
+        if (currentPage == 0) {
+            makeNoMore(true);
+        } else {
+            pageIn(true, makePageUrl(currentPage-1));
+        }
+        pageIn(false, makePageUrl(currentPage+1));
+        $(window).scroll(handleInfiniteScroll);
     }
 
     function enableAdvancedPaging() {


[28/28] git commit: [#4257] Fixed page controls not showing on last page of activity stream

Posted by jo...@apache.org.
[#4257] Fixed page controls not showing on last page of activity stream

Signed-off-by: Cory Johns <cj...@slashdotmedia.com>


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

Branch: refs/heads/cj/4257
Commit: c77b366cf65c146f7fad3582504a9e5c5575c3bb
Parents: 23ad424
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Jan 21 23:25:57 2014 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Thu Jan 23 17:28:04 2014 +0000

----------------------------------------------------------------------
 ForgeActivity/forgeactivity/main.py              | 14 ++++++++------
 ForgeActivity/forgeactivity/templates/index.html |  4 ++--
 2 files changed, 10 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c77b366c/ForgeActivity/forgeactivity/main.py
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/main.py b/ForgeActivity/forgeactivity/main.py
index 09d0c62..f269336 100644
--- a/ForgeActivity/forgeactivity/main.py
+++ b/ForgeActivity/forgeactivity/main.py
@@ -106,13 +106,15 @@ class ForgeActivityController(BaseController):
                                            limit=kw.get('limit', 100),
                                            actor_only=actor_only,
                                            filter_func=perm_check(c.user))
+        page = asint(kw.get('page', 0))
+        limit = asint(kw.get('limit', 100))
         return dict(
-                followee=followee,
-                following=following,
-                timeline=timeline,
-                page=asint(kw.get('page', 0)),
-                limit=asint(kw.get('limit', 100)),
-            )
+            followee=followee,
+            following=following,
+            timeline=timeline,
+            page=page,
+            limit=limit,
+            has_more=len(timeline) == limit)
 
     @expose('jinja:forgeactivity:templates/index.html')
     @with_trailing_slash

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c77b366c/ForgeActivity/forgeactivity/templates/index.html
----------------------------------------------------------------------
diff --git a/ForgeActivity/forgeactivity/templates/index.html b/ForgeActivity/forgeactivity/templates/index.html
index 5b222f7..fef165a 100644
--- a/ForgeActivity/forgeactivity/templates/index.html
+++ b/ForgeActivity/forgeactivity/templates/index.html
@@ -43,12 +43,12 @@
 
 <div class="activity">
   {% if not timeline %}
-    No activity to display.
+    No {% if page > 0 %} more {% endif %} activity to display.
   {% else %}
     <ul class="timeline" data-limit="{{limit}}">
         {% include 'forgeactivity:templates/timeline.html' %}
     </ul>
-    {{c.page_list.display(limit=1, page=page, count=page+1, show_label=False, show_if_single_page=True, force_next=True)}}
   {% endif %}
+  {{c.page_list.display(limit=1, page=page, count=page+1, show_label=False, show_if_single_page=True, force_next=has_more)}}
 </div>
 {% endblock %}