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 2013/09/17 21:57:28 UTC

[01/50] git commit: fix typo in README

Updated Branches:
  refs/heads/cj/6422 6ce8edf50 -> 1e8670ebb


fix typo in README


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

Branch: refs/heads/cj/6422
Commit: f19076913fb56b9312a7c1369d6f87bba3c7b09f
Parents: 781e22b
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Sep 9 15:28:43 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 9 15:28:43 2013 +0000

----------------------------------------------------------------------
 README.markdown | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f1907691/README.markdown
----------------------------------------------------------------------
diff --git a/README.markdown b/README.markdown
index 30f6e49..dcebab0 100644
--- a/README.markdown
+++ b/README.markdown
@@ -108,8 +108,8 @@ We have a custom config ready for use.
     (env-allura)~/src$ cp -f allura/solr_config/schema.xml solr-4.2.1/example/solr/collection1/conf
 
     (env-allura)~/src$ cd solr-4.2.1/example/
-    (env-allura)~/src/apache-solr-1.4.1/example/$ mkdir ~/logs/
-    (env-allura)~/src/apache-solr-1.4.1/example/$ nohup java -jar start.jar > ~/logs/solr.log &
+    (env-allura)~/src/apache-solr-4.2.1/example/$ mkdir ~/logs/
+    (env-allura)~/src/apache-solr-4.2.1/example/$ nohup java -jar start.jar > ~/logs/solr.log &
 
 
 ### Allura task processing


[05/50] git commit: [#6541] Override url in AuditLog on tool import

Posted by jo...@apache.org.
[#6541] Override url in AuditLog on tool import

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/89cfb5ab
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/89cfb5ab
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/89cfb5ab

Branch: refs/heads/cj/6422
Commit: 89cfb5abd76efb0e8ae999621dc377d222b0c8a1
Parents: 44b2a36
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Fri Sep 6 18:17:05 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 9 20:27:30 2013 +0000

----------------------------------------------------------------------
 ForgeImporters/forgeimporters/google/code.py               | 2 +-
 ForgeImporters/forgeimporters/google/tests/test_code.py    | 3 ++-
 ForgeImporters/forgeimporters/google/tracker.py            | 1 +
 ForgeImporters/forgeimporters/tests/google/test_tracker.py | 3 ++-
 ForgeImporters/forgeimporters/trac/tests/test_tickets.py   | 3 ++-
 ForgeImporters/forgeimporters/trac/tickets.py              | 2 +-
 6 files changed, 9 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/89cfb5ab/ForgeImporters/forgeimporters/google/code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/code.py b/ForgeImporters/forgeimporters/google/code.py
index c5f34cd..134ecb6 100644
--- a/ForgeImporters/forgeimporters/google/code.py
+++ b/ForgeImporters/forgeimporters/google/code.py
@@ -178,6 +178,6 @@ class GoogleRepoImporter(ToolImporter):
                 'import tool %s from %s on %s' % (
                     app.config.options.mount_point,
                     project_name, self.source,
-                ), project=project, user=user)
+                ), project=project, user=user, url=app.url)
         g.post_event('project_updated')
         return app

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/89cfb5ab/ForgeImporters/forgeimporters/google/tests/test_code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tests/test_code.py b/ForgeImporters/forgeimporters/google/tests/test_code.py
index 4028076..806a004 100644
--- a/ForgeImporters/forgeimporters/google/tests/test_code.py
+++ b/ForgeImporters/forgeimporters/google/tests/test_code.py
@@ -67,6 +67,7 @@ class TestGoogleRepoImporter(TestCase):
         u = Mock(name='c.user')
         app = p.install_app.return_value
         app.config.options.mount_point = 'code'
+        app.url = 'foo'
         GoogleRepoImporter().import_tool(p, u, project_name='project_name')
         get_repo_url.assert_called_once_with('project_name', 'git')
         p.install_app.assert_called_once_with('Git',
@@ -80,7 +81,7 @@ class TestGoogleRepoImporter(TestCase):
             )
         M.AuditLog.log.assert_called_once_with(
                 'import tool code from project_name on Google Code',
-                project=p, user=u)
+                project=p, user=u, url='foo')
         g.post_event.assert_called_once_with('project_updated')
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/89cfb5ab/ForgeImporters/forgeimporters/google/tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tracker.py b/ForgeImporters/forgeimporters/google/tracker.py
index cf6067e..9c259dd 100644
--- a/ForgeImporters/forgeimporters/google/tracker.py
+++ b/ForgeImporters/forgeimporters/google/tracker.py
@@ -147,6 +147,7 @@ class GoogleCodeTrackerImporter(ToolImporter):
                         ),
                     project=project,
                     user=user,
+                    url=app.url,
                 )
             g.post_event('project_updated')
             app.globals.invalidate_bin_counts()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/89cfb5ab/ForgeImporters/forgeimporters/tests/google/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
index 8f434df..d795bab 100644
--- a/ForgeImporters/forgeimporters/tests/google/test_tracker.py
+++ b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
@@ -48,6 +48,7 @@ class TestTrackerImporter(TestCase):
                 'project_name': 'project_name',
             }
         app.config.options.get = lambda *a: getattr(app.config.options, *a)
+        app.url = 'foo'
         issues = gpe.iter_issues.return_value = [(50, mock.Mock()), (100, mock.Mock())]
         tickets = TM.Ticket.side_effect = [mock.Mock(), mock.Mock()]
 
@@ -91,7 +92,7 @@ class TestTrackerImporter(TestCase):
         self.assertEqual(app.globals.last_ticket_num, 100)
         M.AuditLog.log.assert_called_once_with(
                 'import tool mount_point from project_name on Google Code',
-                project=project, user=user)
+                project=project, user=user, url='foo')
         g.post_event.assert_called_once_with('project_updated')
         app.globals.invalidate_bin_counts.assert_called_once_with()
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/89cfb5ab/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/trac/tests/test_tickets.py b/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
index 2e0c199..92e7854 100644
--- a/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
+++ b/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
@@ -48,6 +48,7 @@ class TestTracTicketImporter(TestCase):
         app = Mock(name='ForgeTrackerApp')
         app.config.options.mount_point = 'bugs'
         app.config.options.get = lambda *a: getattr(app.config.options, *a)
+        app.url = 'foo'
         project = Mock(name='Project', shortname='myproject')
         project.install_app.return_value = app
         user = Mock(name='User', _id='id')
@@ -78,7 +79,7 @@ class TestTracTicketImporter(TestCase):
                 validate=False)
         AuditLog.log.assert_called_once_with(
                 'import tool bugs from http://example.com/trac/url/',
-                project=project, user=user)
+                project=project, user=user, url='foo')
         g.post_event.assert_called_once_with('project_updated')
 
     @patch('forgeimporters.trac.tickets.session')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/89cfb5ab/ForgeImporters/forgeimporters/trac/tickets.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/trac/tickets.py b/ForgeImporters/forgeimporters/trac/tickets.py
index e5238e3..9e4f493 100644
--- a/ForgeImporters/forgeimporters/trac/tickets.py
+++ b/ForgeImporters/forgeimporters/trac/tickets.py
@@ -141,7 +141,7 @@ class TracTicketImporter(ToolImporter):
                         app.config.options.mount_point, 
                         trac_url, 
                     ), 
-                project=project, user=user, 
+                project=project, user=user, url=app.url,
             ) 
             g.post_event('project_updated')
             return app


[50/50] git commit: [#5966] change sf.net/p/allura URLs (except tickets) to apache

Posted by jo...@apache.org.
[#5966] change sf.net/p/allura URLs (except tickets) to apache


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

Branch: refs/heads/cj/6422
Commit: 1e8670ebb7719c66b524e14c6b259bca1ab58df4
Parents: 0951bee
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Sep 13 17:53:00 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Sep 17 17:02:37 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/jinja_master/theme_macros.html | 4 ++--
 Allura/docs/extending.rst                              | 4 ++--
 Allura/docs/installation.rst                           | 2 +-
 Allura/docs/online.rst                                 | 4 ++--
 Allura/setup.py                                        | 7 +++----
 CONTRIBUTING                                           | 6 ++----
 ForgeImporters/forgeimporters/base.py                  | 2 +-
 ForgeImporters/forgeimporters/tests/test_base.py       | 2 +-
 README.markdown                                        | 2 +-
 9 files changed, 15 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e8670eb/Allura/allura/templates/jinja_master/theme_macros.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/theme_macros.html b/Allura/allura/templates/jinja_master/theme_macros.html
index 7fc070c..5439e0f 100644
--- a/Allura/allura/templates/jinja_master/theme_macros.html
+++ b/Allura/allura/templates/jinja_master/theme_macros.html
@@ -36,8 +36,8 @@
 {%- macro footer(year, path_to_static='') %}
 <footer id="site-footer">
   <nav>
-	  This project is powered by <a href="http://sourceforge.net/p/allura/">Allura</a>.
-	</nav>
+      This project is powered by <a href="https://forge-allura.apache.org/p/allura/">Allura</a>.
+  </nav>
 </footer>
 {%- endmacro %}
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e8670eb/Allura/docs/extending.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/extending.rst b/Allura/docs/extending.rst
index 6a6abe0..5458b69 100644
--- a/Allura/docs/extending.rst
+++ b/Allura/docs/extending.rst
@@ -35,7 +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)
 
-A listing of available 3rd-party extensions is at https://sourceforge.net/p/allura/wiki/Extensions/
+A listing of available 3rd-party extensions is at https://forge-allura.apache.org/p/allura/wiki/Extensions/
 
 To disable any Allura entry point, simply add an entry in your ``.ini`` config file
 with names and values corresponding to entry points defined in any ``setup.py`` file.
@@ -60,4 +60,4 @@ The events that allura publishes are:
 * project_updated
 * repo_cloned
 * repo_refreshed
-* repo_clone_task_failed
\ No newline at end of file
+* repo_clone_task_failed

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e8670eb/Allura/docs/installation.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/installation.rst b/Allura/docs/installation.rst
index 8b36cfc..44eb0ad 100644
--- a/Allura/docs/installation.rst
+++ b/Allura/docs/installation.rst
@@ -21,7 +21,7 @@ Installation
 Easy Setup
 ---------------
 
-Our easy setup instructions are in our README.rst file.  You can read it online at https://sourceforge.net/p/allura/git/#readme
+Our easy setup instructions are in our README.rst file.  You can read it online at https://forge-allura.apache.org/p/allura/git/ci/master/tree/README.markdown
 
 You should be able to get Allura up and running in well under an hour by following those instructions.
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e8670eb/Allura/docs/online.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/online.rst b/Allura/docs/online.rst
index 37c3103..632d1c9 100644
--- a/Allura/docs/online.rst
+++ b/Allura/docs/online.rst
@@ -22,9 +22,9 @@ Generated API docs, useful for browsing through the code, viewing inheritance, e
 
 * http://allura.sourceforge.net/epydoc/
 
-Our SourceForge project page, including tickets, discussion forums, etc.:
+Our project page, including tickets, discussion forums, etc.:
 
-* http://sourceforge.net/p/allura/home/
+* https://forge-allura.apache.org/p/allura/
 
 
 Much of the current forge was inspired by Roundup

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e8670eb/Allura/setup.py
----------------------------------------------------------------------
diff --git a/Allura/setup.py b/Allura/setup.py
index 4a5f4f1..32e6eb4 100644
--- a/Allura/setup.py
+++ b/Allura/setup.py
@@ -36,10 +36,9 @@ setup(
     version=__version__,
     description='Base distribution of the Allura development platform',
     long_description=PROJECT_DESCRIPTION,
-    author='SourceForge Team',
-    author_email='develop@discussion.allura.p.re.sf.net',
-    url='http://sourceforge.net/p/allura',
-    keywords='sourceforge allura turbogears pylons jinja2 mongodb rabbitmq',
+    author='Allura Team',
+    url='https://forge-allura.apache.org/p/allura/',
+    keywords='allura forge turbogears pylons jinja2 mongodb',
     license='Apache License, http://www.apache.org/licenses/LICENSE-2.0',
     platforms=[
         'Linux',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e8670eb/CONTRIBUTING
----------------------------------------------------------------------
diff --git a/CONTRIBUTING b/CONTRIBUTING
index c8ed765..e52c1f1 100644
--- a/CONTRIBUTING
+++ b/CONTRIBUTING
@@ -25,7 +25,7 @@ number of individual projects.
 SourceForge.net is running an instance of Allura (aka New Forge, or
 Forge 2.0); and Allura itself is a project managed there:
 
-  <https://sourceforge.net/p/allura/>
+  <https://forge-allura.apache.org/p/allura/>
 
 The source for Allura is available there from a Git repo under the
 Apache License, Version 2.0.
@@ -83,8 +83,6 @@ The code is self-hosted in a public git repository.  Get it by cloning:
 
   git clone https://git-wip-us.apache.org/repos/asf/incubator-allura.git allura
 
-You can also 'fork' our repo at <https://sourceforge.net/p/allura/git/>.
-
 - CONTRIBUTING CODE
 
 Develop and test your patches locally and then get them to us in one of
@@ -134,7 +132,7 @@ mailing list:
 
 First, is your question already answered in the FAQ?
 
-  <https://sourceforge.net/p/allura/wiki/FAQ/>
+  <https://forge-allura.apache.org/p/allura/wiki/FAQ/>
 
 If not, then the right place to ask is either the mailing list (above)
 or the IRC channel:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e8670eb/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index 8c01b62..653a172 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -118,7 +118,7 @@ class ProjectExtractor(object):
     @staticmethod
     def urlopen(url, retries=3, codes=(408,), **kw):
         req = urllib2.Request(url, **kw)
-        req.add_header('User-Agent', 'Allura Data Importer (http://sf.net/p/allura)')
+        req.add_header('User-Agent', 'Allura Data Importer (https://forge-allura.apache.org/p/allura/)')
         return h.urlopen(req, retries=retries, codes=codes)
 
     def get_page(self, page_name_or_url, parser=None, **kw):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e8670eb/ForgeImporters/forgeimporters/tests/test_base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/test_base.py b/ForgeImporters/forgeimporters/tests/test_base.py
index d4b403d..ded4e37 100644
--- a/ForgeImporters/forgeimporters/tests/test_base.py
+++ b/ForgeImporters/forgeimporters/tests/test_base.py
@@ -37,7 +37,7 @@ class TestProjectExtractor(TestCase):
         Request.assert_called_once_with('myurl', data='foo')
         req = Request.return_value
         req.add_header.assert_called_once_with(
-                'User-Agent', 'Allura Data Importer (http://sf.net/p/allura)')
+                'User-Agent', 'Allura Data Importer (https://forge-allura.apache.org/p/allura/)')
         urlopen.assert_called_once_with(req, retries=3, codes=(408,))
         self.assertEqual(r, urlopen.return_value)
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1e8670eb/README.markdown
----------------------------------------------------------------------
diff --git a/README.markdown b/README.markdown
index dcebab0..9869152 100644
--- a/README.markdown
+++ b/README.markdown
@@ -146,4 +146,4 @@ register a new project in your own forge, visit /p/add_project
     * Including how to enable extra features: <http://allura.sourceforge.net/installation.html>
 * Run the test suite (slow): `$ ALLURA_VALIDATION=none ./run_tests`
 * File bug reports at <https://sourceforge.net/p/allura/tickets/new/> (login required)
-* Contribute code according to this guide: <http://sourceforge.net/p/allura/wiki/Contributing%20Code/>
+* Contribute code according to this guide: <https://forge-allura.apache.org/p/allura/wiki/Contributing%20Code/>


[35/50] git commit: remove extraneous app_config_id index on Ticket

Posted by jo...@apache.org.
remove extraneous app_config_id index on Ticket


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

Branch: refs/heads/cj/6422
Commit: 8e5201d56a6089d5d79affb4c8a2cc06f4b04582
Parents: 21b64d0
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 11 18:20:44 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Sep 11 18:20:44 2013 +0000

----------------------------------------------------------------------
 ForgeTracker/forgetracker/model/ticket.py | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8e5201d5/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 505a991..71fe6c5 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -526,7 +526,6 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
         history_class = TicketHistory
         indexes = [
             'ticket_num',
-            'app_config_id',
             ('app_config_id', 'custom_fields._milestone'),
             'import_id',
             ]


[24/50] git commit: [#6545] ignore query string when checking for active sidebar item

Posted by jo...@apache.org.
[#6545] ignore query string when checking for active sidebar item


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

Branch: refs/heads/cj/6422
Commit: dc3199182f24158b75a9ecc26a54c4812a65e63a
Parents: 73bb7ca
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Sep 6 20:33:41 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 14:35:48 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/jinja_master/sidebar_menu.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dc319918/Allura/allura/templates/jinja_master/sidebar_menu.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/sidebar_menu.html b/Allura/allura/templates/jinja_master/sidebar_menu.html
index f8b9c8e..08beed2 100644
--- a/Allura/allura/templates/jinja_master/sidebar_menu.html
+++ b/Allura/allura/templates/jinja_master/sidebar_menu.html
@@ -23,7 +23,7 @@
       <ul class="sidebarmenu">
       {% do ul_active.append(True) %}
     {% endif %}
-    <li{% if request.url.find(s.url,-s.url.__len__()) != -1 %} class="active"{% endif %}>
+    <li{% if request.path.find(s.url,-s.url.__len__()) != -1 %} class="active"{% endif %}>
       <a href="{{s.url}}"{% if s.className %} class="{{s.className or ''}}"{% endif %}>{% if s.ui_icon %}<b data-icon="{{s.ui_icon.char}}" class="ico {{s.ui_icon.css}}"></b> {% endif %}<span{% if s.small != None %} class="has_small"{% endif %}>{{h.really_unicode(s.label)}}</span>{% if s.small != None %}<small>{{s.small}}</small>{% endif %}</a>
     </li>
   {% else %}


[20/50] git commit: [#6545] re-order app_config_id, label index so it can be shared

Posted by jo...@apache.org.
[#6545] re-order app_config_id,label index so it can be shared

..shared with the main app_config_id index.  It was added in 1fc1d377
for faster ticket label lookup, but the order doesn't matter, so
better to share the first part of the index.


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

Branch: refs/heads/cj/6422
Commit: 28d8c31ee0cfb67005d5f9ecc7c855df92e4cafc
Parents: 5445e84
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 4 13:53:35 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 14:31:47 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/artifact.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/28d8c31e/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 3910cad..9f91c6b 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -61,7 +61,9 @@ class Artifact(MappedClass):
     class __mongometa__:
         session = artifact_orm_session
         name='artifact'
-        indexes = [ 'app_config_id', ('labels', 'app_config_id') ]
+        indexes = [
+            ('app_config_id', 'label'),
+        ]
         def before_save(data):
             if not getattr(artifact_orm_session._get(), 'skip_mod_date', False):
                 data['mod_date'] = datetime.utcnow()


[13/50] git commit: Merge branch 'db/6640' of https://git-wip-us.apache.org/repos/asf/incubator-allura into db/6640

Posted by jo...@apache.org.
Merge branch 'db/6640' of https://git-wip-us.apache.org/repos/asf/incubator-allura into db/6640


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

Branch: refs/heads/cj/6422
Commit: 4eb88f5b6cc6dfbcfab2d6955f6dd8656555e015
Parents: 6e4fe74 f3d3166
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Sep 10 12:53:26 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 12:53:26 2013 +0000

----------------------------------------------------------------------

----------------------------------------------------------------------



[10/50] git commit: [#6541] Added audit log on project import

Posted by jo...@apache.org.
[#6541] Added audit log on project import

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/99a09b45
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/99a09b45
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/99a09b45

Branch: refs/heads/cj/6422
Commit: 99a09b45530617a4668b3f296bc599dda4eb1536
Parents: ad81824
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Aug 28 20:19:13 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 9 20:27:30 2013 +0000

----------------------------------------------------------------------
 ForgeImporters/forgeimporters/base.py           |  2 ++
 .../forgeimporters/tests/test_base.py           | 24 ++++++++++++++++++++
 2 files changed, 26 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/99a09b45/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index e0e9d6f..ffb1650 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -37,6 +37,7 @@ from allura.lib import helpers as h
 from allura.lib import exceptions
 from allura.lib import validators as v
 from allura.app import SitemapEntry
+from allura import model as M
 
 from paste.deploy.converters import aslist
 
@@ -245,6 +246,7 @@ class ProjectImporter(BaseController):
         self.after_project_create(c.project, **kw)
         for importer_name in kw['tools']:
             import_tool.post(importer_name, **kw)
+        M.AuditLog.log('import project from %s' % self.source)
 
         flash('Welcome to the %s Project System! '
               'Your project data will be imported and should show up here shortly.' % config['site_name'])

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/99a09b45/ForgeImporters/forgeimporters/tests/test_base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/test_base.py b/ForgeImporters/forgeimporters/tests/test_base.py
index 7de0625..4aefc35 100644
--- a/ForgeImporters/forgeimporters/tests/test_base.py
+++ b/ForgeImporters/forgeimporters/tests/test_base.py
@@ -99,6 +99,30 @@ class TestProjectImporter(TestCase):
         self.assertEqual(pi.tool_importers, {'ep1': eps[0].lv, 'ep3': eps[2].lv})
         iep.assert_called_once_with('allura.importers')
 
+    @mock.patch.object(base, 'redirect')
+    @mock.patch.object(base, 'flash')
+    @mock.patch.object(base, 'import_tool')
+    @mock.patch.object(base, 'M')
+    @mock.patch.object(base, 'c')
+    def test_process(self, c, M, import_tool, flash, redirect):
+        pi = base.ProjectImporter(mock.Mock())
+        pi.source = 'Source'
+        pi.after_project_create = mock.Mock()
+        pi.neighborhood.register_project.return_value.script_name = 'script_name/'
+        kw = {
+                'project_name': 'project_name',
+                'project_shortname': 'shortname',
+                'tools': ['tool'],
+            }
+        with mock.patch.dict(base.config, {'site_name': 'foo'}):
+            pi.process(**kw)
+        pi.neighborhood.register_project.assert_called_once_with('shortname', project_name='project_name')
+        pi.after_project_create.assert_called_once_with(c.project, **kw)
+        import_tool.post.assert_called_once_with('tool', **kw)
+        M.AuditLog.log.assert_called_once_with('import project from Source')
+        self.assertEqual(flash.call_count, 1)
+        redirect.assert_called_once_with('script_name/admin/overview')
+
 
 
 TA1 = mock.Mock(tool_label='foo', tool_description='foo_desc')


[08/50] git commit: [#6541] Added import_id and AuditLog to Trac ticket importer

Posted by jo...@apache.org.
[#6541] Added import_id and AuditLog to Trac ticket importer

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/4a4ee8f3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/4a4ee8f3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/4a4ee8f3

Branch: refs/heads/cj/6422
Commit: 4a4ee8f37b510309d6b62c37424c97a043d37d1a
Parents: 99a09b4
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Aug 28 20:32:05 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 9 20:27:30 2013 +0000

----------------------------------------------------------------------
 .../forgeimporters/trac/tests/test_tickets.py       | 16 ++++++++++++++--
 ForgeImporters/forgeimporters/trac/tickets.py       | 15 +++++++++++++--
 2 files changed, 27 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/4a4ee8f3/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/trac/tests/test_tickets.py b/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
index 74e1049..2e0c199 100644
--- a/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
+++ b/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
@@ -19,6 +19,8 @@ import json
 from unittest import TestCase
 from mock import Mock, patch
 
+from tg import config
+
 from allura.tests import TestController
 from allura.tests.decorators import with_tracker
 
@@ -31,18 +33,21 @@ from forgeimporters.trac.tickets import (
 class TestTracTicketImporter(TestCase):
     @patch('forgeimporters.trac.tickets.session')
     @patch('forgeimporters.trac.tickets.g')
+    @patch('forgeimporters.trac.tickets.AuditLog')
     @patch('forgeimporters.trac.tickets.import_tracker')
     @patch('forgeimporters.trac.tickets.AlluraImportApiClient')
     @patch('forgeimporters.trac.tickets.datetime')
     @patch('forgeimporters.trac.tickets.ApiTicket')
     @patch('forgeimporters.trac.tickets.TracExport')
-    def test_import_tool(self, TracExport, ApiTicket, dt, ApiClient, import_tracker, g, session):
+    def test_import_tool(self, TracExport, ApiTicket, dt, ApiClient, import_tracker, AuditLog, g, session):
         from datetime import datetime, timedelta
         now = datetime.utcnow()
         dt.utcnow.return_value = now
         user_map = {"orig_user":"new_user"}
         importer = TracTicketImporter()
         app = Mock(name='ForgeTrackerApp')
+        app.config.options.mount_point = 'bugs'
+        app.config.options.get = lambda *a: getattr(app.config.options, *a)
         project = Mock(name='Project', shortname='myproject')
         project.install_app.return_value = app
         user = Mock(name='User', _id='id')
@@ -55,7 +60,11 @@ class TestTracTicketImporter(TestCase):
                     )
         self.assertEqual(res, app)
         project.install_app.assert_called_once_with(
-                'Tickets', mount_point='bugs', mount_label='Bugs')
+                'Tickets', mount_point='bugs', mount_label='Bugs',
+                import_id={
+                        'source': 'Trac',
+                        'trac_url': 'http://example.com/trac/url/',
+                    })
         TracExport.return_value = []
         TracExport.assert_called_once_with('http://example.com/trac/url/')
         ApiTicket.assert_called_once_with(
@@ -67,6 +76,9 @@ class TestTracTicketImporter(TestCase):
                 api_client, 'myproject', 'bugs',
                 {"user_map": user_map}, '[]',
                 validate=False)
+        AuditLog.log.assert_called_once_with(
+                'import tool bugs from http://example.com/trac/url/',
+                project=project, user=user)
         g.post_event.assert_called_once_with('project_updated')
 
     @patch('forgeimporters.trac.tickets.session')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/4a4ee8f3/ForgeImporters/forgeimporters/trac/tickets.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/trac/tickets.py b/ForgeImporters/forgeimporters/trac/tickets.py
index 3063d71..e5238e3 100644
--- a/ForgeImporters/forgeimporters/trac/tickets.py
+++ b/ForgeImporters/forgeimporters/trac/tickets.py
@@ -43,7 +43,7 @@ from allura.lib.decorators import require_post, task
 from allura.lib.import_api import AlluraImportApiClient
 from allura.lib import validators as v
 from allura.lib import helpers as h
-from allura.model import ApiTicket
+from allura.model import ApiTicket, AuditLog
 from allura.scripts.trac_export import (
         TracExport,
         DateJSONEncoder,
@@ -117,7 +117,11 @@ class TracTicketImporter(ToolImporter):
                 'Tickets',
                 mount_point=mount_point,
                 mount_label=mount_label or 'Tickets',
-                )
+                import_id={
+                        'source': self.source,
+                        'trac_url': trac_url,
+                    },
+            )
         session(app.config).flush(app.config)
         session(app.globals).flush(app.globals)
         try:
@@ -132,6 +136,13 @@ class TracTicketImporter(ToolImporter):
             import_tracker(cli, project.shortname, mount_point,
                     {'user_map': json.loads(user_map) if user_map else {}},
                     export_string, validate=False)
+            AuditLog.log(
+                'import tool %s from %s' % (
+                        app.config.options.mount_point, 
+                        trac_url, 
+                    ), 
+                project=project, user=user, 
+            ) 
             g.post_event('project_updated')
             return app
         except Exception as e:


[17/50] git commit: [#6626] ticket:427 Returned use of url_for_commit() in controller

Posted by jo...@apache.org.
[#6626] ticket:427 Returned use of url_for_commit() in controller


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

Branch: refs/heads/cj/6422
Commit: 307921bad476db88eb8a06b238638c162d944e23
Parents: 43f055c
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Sep 10 12:14:43 2013 +0300
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 13:34:15 2013 +0000

----------------------------------------------------------------------
 ForgeSVN/forgesvn/controllers.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/307921ba/ForgeSVN/forgesvn/controllers.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/controllers.py b/ForgeSVN/forgesvn/controllers.py
index 62f3d55..44d1a69 100644
--- a/ForgeSVN/forgesvn/controllers.py
+++ b/ForgeSVN/forgesvn/controllers.py
@@ -38,8 +38,9 @@ class BranchBrowser(repository.BranchBrowser, FeedController):
         latest = c.app.repo.latest(branch=self._branch)
         if is_empty or not latest:
             return dict(allow_fork=False, log=[], is_empty=is_empty)
-        redirect('%s/tree/' % c.app.default_branch_name)
+        redirect(c.app.repo.url_for_commit(c.app.default_branch_name) + 'tree/')
 
     @expose()
     def _lookup(self, rev, *remainder):
         return repository.CommitBrowser(rev), remainder
+


[39/50] git commit: [#6540] bump GoogleCodeWikiImporter and TracWikiImporter versions for their rate-limiting additions

Posted by jo...@apache.org.
[#6540] bump GoogleCodeWikiImporter and TracWikiImporter versions for their rate-limiting additions


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

Branch: refs/heads/cj/6422
Commit: b6776afe3b6cdba86a7a75648044279b40476fdc
Parents: 3c0a7e0
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Sep 12 19:56:33 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Sep 12 19:56:41 2013 +0000

----------------------------------------------------------------------
 requirements-sf.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b6776afe/requirements-sf.txt
----------------------------------------------------------------------
diff --git a/requirements-sf.txt b/requirements-sf.txt
index ecad4a2..071e528 100644
--- a/requirements-sf.txt
+++ b/requirements-sf.txt
@@ -6,7 +6,7 @@ kombu==1.0.4
 coverage==3.5a1-20110413
 ForgeHg==0.1.16
 ForgePastebin==0.2.7
-GoogleCodeWikiImporter==0.3.3
+GoogleCodeWikiImporter==0.4.3
 mechanize==0.2.4
 mercurial==1.4.3
 MySQL-python==1.2.3c1
@@ -20,7 +20,7 @@ wsgipreload==1.2
 pyzmq==2.1.7
 html2text==3.200.3dev-20121112
 PyMollom==0.1
-TracWikiImporter==0.2.2
+TracWikiImporter==0.3.2
 
 # use version built from https://github.com/johnsca/GitPython/commits/tv/6000
 # for unmerged fixes for [#5411], [#6000], and [#6078]


[25/50] git commit: [#6545] tweak graph point size

Posted by jo...@apache.org.
[#6545] tweak graph point size


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

Branch: refs/heads/cj/6422
Commit: 73bb7caec845aa4ccc05350fdb3fcededd53677c
Parents: c1685f6
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Sep 6 20:17:20 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 14:35:48 2013 +0000

----------------------------------------------------------------------
 .../templates/discussionforums/stats_graph.html         | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/73bb7cae/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html b/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
index e05506b..39e4ef8 100644
--- a/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
+++ b/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
@@ -65,9 +65,17 @@
   /*global chartProjectStats */
   $(document).ready(function () {
     var series = function(data){
+      var size;
+      if (data.length < 20) {
+        size = 3;
+      } else if (data.length < 100) {
+        size = 2;
+      } else  {
+        size = 1;
+      }
       return [{label: "Posts",
-              lines: {show: true, lineWidth: 3},
-              points: {show:true, radius:2, fill: true, fillColor: '#0685c6'},
+              lines: {show: true, lineWidth: size},
+              points: {show:true, radius:size, fill: true, fillColor: '#0685c6'},
               data: data, shadowSize: 0}
              ];
     };


[31/50] git commit: [#6545] add forum selector

Posted by jo...@apache.org.
[#6545] add forum selector


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

Branch: refs/heads/cj/6422
Commit: 7f639f9d6335946a7cd1c4f02a7e2c05dd7b52b1
Parents: 021ee37
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Sep 6 21:43:13 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 14:36:31 2013 +0000

----------------------------------------------------------------------
 Allura/allura/nf/allura/css/site_style.css         |  3 +--
 .../forgediscussion/controllers/root.py            |  8 +++++---
 .../templates/discussionforums/stats_graph.html    | 17 ++++++++++++++++-
 3 files changed, 22 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7f639f9d/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 b85f54d..acee986 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -2609,7 +2609,6 @@ div.attachment_thumb .file_type span {
 /* Stats Graph */
 
 #stats_date_picker {
-  text-align: right;
   width: 340px;
   display: inline;
   float: left;
@@ -2618,7 +2617,7 @@ div.attachment_thumb .file_type span {
   margin: 0 10px;
 }
 #stats_date_picker input {
-  width: 228px !important;
+  width: 14em;
 }
 
 #stats-viz-container {

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7f639f9d/ForgeDiscussion/forgediscussion/controllers/root.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py b/ForgeDiscussion/forgediscussion/controllers/root.py
index 9250ad0..fdf8f11 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -216,13 +216,14 @@ class RootController(BaseController, DispatchIndex, FeedController):
 
     @without_trailing_slash
     @expose('jinja:forgediscussion:templates/discussionforums/stats_graph.html')
-    def stats(self, dates=None, **kw):
+    def stats(self, dates=None, forum=None, **kw):
         if not dates:
             dates = "{} to {}".format(
                 (date.today() - timedelta(days=60)).strftime('%Y-%m-%d'),
                 date.today().strftime('%Y-%m-%d'))
         return dict(
             dates=dates,
+            selected_forum=forum,
         )
 
     @expose('json')
@@ -230,12 +231,13 @@ class RootController(BaseController, DispatchIndex, FeedController):
         begin=h.DateTimeConverter(if_empty=None, if_invalid=None),
         end=h.DateTimeConverter(if_empty=None, if_invalid=None),
     ))
-    def stats_data(self, begin=None, end=None, **kw):
+    def stats_data(self, begin=None, end=None, forum=None, **kw):
         end = end or date.today()
         begin = begin or end - timedelta(days=60)
 
         discussion_id_q = {
-            '$in': [d._id for d in c.app.forums]
+            '$in': [d._id for d in c.app.forums
+                    if d.shortname == forum or forum is None]
         }
         # must be ordered dict, so that sorting by this works properly
         grouping = OrderedDict()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7f639f9d/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html b/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
index 39e4ef8..d702657 100644
--- a/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
+++ b/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
@@ -28,6 +28,15 @@
     <label for="dates">Date Range: </label>
     <input value="{{dates}}" type="text" class="text ui-corner-all" name="dates" id="dates">
   </div>
+  <label for="forum">Forum:</label>
+  <select name="forum">
+    <option value="">All</option>
+    {% for forum in c.app.forums %}
+        <option value="{{forum.shortname}}"
+          {%- if forum.shortname == selected_forum %} selected{% endif -%}
+          >{{forum.name}}</option>
+    {% endfor %}
+  </select>
 </form>
 
 <div id="stats-viz-container" class="project_stats">
@@ -82,7 +91,13 @@
     var checkEmpty = function(data){
       return !data.length;
     };
-    chartProjectStats('{{c.app.url}}stats_data',{},series,checkEmpty);
+    chartProjectStats('{{c.app.url}}stats_data',
+                      {forum: $('select[name=forum]').val()},
+                      series, checkEmpty);
+
+    $('select[name=forum]').change(function(){
+        $(this).parent('form').submit();
+    });
   });
 </script>
 {% endblock %}
\ No newline at end of file


[36/50] git commit: [#6545] add "timestamp" index back to ForumPost which was removed from Artifact in [58083948]

Posted by jo...@apache.org.
[#6545] add "timestamp" index back to ForumPost which was removed from Artifact in [58083948]


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

Branch: refs/heads/cj/6422
Commit: 224017c76aec0b4009ff069e4a834bf969befe7d
Parents: 8e5201d
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 11 19:57:07 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Sep 11 19:57:07 2013 +0000

----------------------------------------------------------------------
 ForgeDiscussion/forgediscussion/model/forum.py | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/224017c7/ForgeDiscussion/forgediscussion/model/forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/model/forum.py b/ForgeDiscussion/forgediscussion/model/forum.py
index 84040da..c13bb57 100644
--- a/ForgeDiscussion/forgediscussion/model/forum.py
+++ b/ForgeDiscussion/forgediscussion/model/forum.py
@@ -205,6 +205,9 @@ class ForumPost(M.Post):
     class __mongometa__:
         name='forum_post'
         history_class = ForumPostHistory
+        indexes = [
+            'timestamp',  # for the posts_24hr site_stats query
+        ]
     type_s = 'Post'
 
     discussion_id = ForeignIdProperty(Forum)


[34/50] git commit: Oh TG, you are so dumb.

Posted by jo...@apache.org.
Oh TG, you are so dumb.

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/21b64d07
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/21b64d07
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/21b64d07

Branch: refs/heads/cj/6422
Commit: 21b64d073b9909497a21c9fe86f92558ebd99ea8
Parents: 27f2b34
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Sep 10 16:52:10 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 16:52:10 2013 +0000

----------------------------------------------------------------------
 ForgeDiscussion/forgediscussion/controllers/root.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/21b64d07/ForgeDiscussion/forgediscussion/controllers/root.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py b/ForgeDiscussion/forgediscussion/controllers/root.py
index 5ec19ad..c6f9019 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -226,7 +226,7 @@ class RootController(BaseController, DispatchIndex, FeedController):
             selected_forum=forum,
         )
 
-    @expose('json')
+    @expose('json:')
     @validate(dict(
         begin=h.DateTimeConverter(if_empty=None, if_invalid=None),
         end=h.DateTimeConverter(if_empty=None, if_invalid=None),


[27/50] git commit: [#6545] add CSS for daterange picker, graph

Posted by jo...@apache.org.
[#6545] add CSS for daterange picker, graph


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

Branch: refs/heads/cj/6422
Commit: c1685f6104359e92c1edf04bf2657dbe3834e00f
Parents: 2356145
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Sep 6 19:58:15 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 14:35:48 2013 +0000

----------------------------------------------------------------------
 Allura/allura/nf/allura/css/site_style.css      |  77 +++++++++++++-
 .../public/nf/css/forge/ui.daterangepicker.css  | 103 +++++++++++++++++++
 Allura/allura/public/nf/js/stats.js             |  13 +--
 .../templates/discussionforums/stats_graph.html |   1 +
 rat-excludes.txt                                |   1 +
 5 files changed, 184 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c1685f61/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 662b4f6..b85f54d 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -1905,7 +1905,6 @@ nav .ico {
   -ms-border-radius: 4px;
   -khtml-border-radius: 4px;
   border-radius: 4px;
-  z-index: 1;
   position: relative;
   width: 785px;
 }
@@ -2607,6 +2606,82 @@ div.attachment_thumb .file_type span {
   overflow: auto;
 }
 
+/* Stats Graph */
+
+#stats_date_picker {
+  text-align: right;
+  width: 340px;
+  display: inline;
+  float: left;
+  overflow: hidden;
+  *zoom: 1;
+  margin: 0 10px;
+}
+#stats_date_picker input {
+  width: 228px !important;
+}
+
+#stats-viz-container {
+  width: 700px;
+  display: inline;
+  float: left;
+  overflow: hidden;
+  *zoom: 1;
+  margin: 0 10px;
+  overflow: hidden;
+}
+
+#stats-viz {
+  height: 400px;
+}
+#stats-viz td {
+  border-width: 0;
+}
+
+#stats-viz .xaxis {
+  text-align: center;
+} 
+#stats-viz .yaxis {
+  -webkit-transform: rotate(270deg);  -moz-transform: rotate(270deg);
+  -ms-transform: rotate(270deg);
+  -o-transform: rotate(270deg);
+  transform: rotate(270deg);
+  max-width: 1em;
+}
+  
+#project_stats_holder {
+  width: 600px;
+  height: 350px;
+} 
+#project_stats_holder div.legend table {
+  width: auto;
+}
+#project_stats_holder .tickLabel {
+  margin-left: -4px;
+}
+#project_stats_holder .tooltip {
+  background: #3f3f3f;
+  border: 1px solid #222;
+  opacity: .8;
+  z-index: 1000;
+  padding: 5px 10px;
+  color: #fff;
+}
+#project_stats_holder .base, #project_stats_holder #content_base {
+  margin: 0;
+  background: none;
+  border-width: 0;
+}
+
+.chart-tooltip {
+  position: absolute;
+  display: none;
+  background: white;
+  border: 1px solid black;
+  border-radius: 0.5em;
+  padding: 0 0.3em;
+}
+
 /* Messages */
 .error, .notice, .success, .ok, .info {
   padding: .8em;

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c1685f61/Allura/allura/public/nf/css/forge/ui.daterangepicker.css
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/css/forge/ui.daterangepicker.css b/Allura/allura/public/nf/css/forge/ui.daterangepicker.css
new file mode 100644
index 0000000..6c71e83
--- /dev/null
+++ b/Allura/allura/public/nf/css/forge/ui.daterangepicker.css
@@ -0,0 +1,103 @@
+/*styles for jquery ui daterangepicker plugin */
+
+.ui-daterangepickercontain {
+	position: absolute;
+	z-index: 999;
+}
+.ui-daterangepickercontain .ui-daterangepicker {
+	float: left;
+	padding: 5px !important;
+	width: auto;
+	display: inline;
+	background-image: none !important;
+	clear: left;
+}
+.ui-daterangepicker ul, .ui-daterangepicker .ranges, .ui-daterangepicker .range-start, .ui-daterangepicker .range-end {
+	float: left;
+	padding: 0;
+	margin: 0;
+}
+.ui-daterangepicker .ranges {
+	width: auto;
+	position: relative;
+	padding: 5px 5px 40px 0;
+	margin-left: 10px;
+}
+.ui-daterangepicker .range-start, .ui-daterangepicker .range-end {
+	margin-left: 5px;
+}
+.ui-daterangepicker button.btnDone {
+	margin: 0 5px 5px 0;
+	position: absolute;
+	bottom: 0;
+	right: 0;
+	clear: both;
+	cursor: pointer;
+	font-size: 1.1em;
+}
+.ui-daterangepicker ul {
+	width: 17.6em;
+	background: none;
+	border: 0;
+}
+.ui-daterangepicker li {
+	list-style: none;
+	padding: 1px;
+	cursor: pointer;
+	margin: 1px 0;
+}
+.ui-daterangepicker li.ui-state-hover, .ui-daterangepicker li.ui-state-active {
+	padding: 0;
+}
+.ui-daterangepicker li.preset_0 {
+	margin-top: 1.5em !important;
+}
+.ui-daterangepicker .ui-widget-content a {
+	text-decoration: none !important;
+}
+.ui-daterangepicker li a {
+	font-weight: normal;
+	margin: .3em .5em;
+	display: block;
+}
+.ui-daterangepicker li span {
+	float: right;
+	margin: .3em .2em;
+}
+.ui-daterangepicker .title-start, .ui-daterangepicker .title-end {
+	display: block;
+	margin: 0 0 .2em;
+	font-size: 1em;
+	padding: 0 4px 2px;
+}
+.ui-daterangepicker .ui-datepicker-inline {
+	font-size: 1em;
+}
+.ui-daterangepicker-arrows {
+	padding: 2px;
+	width: 204px;
+	position: relative;
+}
+.ui-daterangepicker-arrows input.ui-rangepicker-input {
+	width: 158px;
+	margin: 0 2px 0 20px;
+	padding: 2px;
+	height: 1.1em;
+}
+.ui-daterangepicker-arrows .ui-daterangepicker-prev, .ui-daterangepicker-arrows .ui-daterangepicker-next {
+	position: absolute;
+	top: 2px; 
+	padding: 1px;
+}
+.ui-daterangepicker-arrows .ui-daterangepicker-prev {
+	left: 2px;
+}
+.ui-daterangepicker-arrows .ui-daterangepicker-next {
+	right: 2px;
+}
+.ui-daterangepicker-arrows .ui-daterangepicker-prev:hover, 
+.ui-daterangepicker-arrows .ui-daterangepicker-next:hover,
+.ui-daterangepicker-arrows .ui-daterangepicker-prev:focus, 
+.ui-daterangepicker-arrows .ui-daterangepicker-next:focus {
+	padding: 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c1685f61/Allura/allura/public/nf/js/stats.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/stats.js b/Allura/allura/public/nf/js/stats.js
index 72e12dc..efbf938 100644
--- a/Allura/allura/public/nf/js/stats.js
+++ b/Allura/allura/public/nf/js/stats.js
@@ -100,25 +100,18 @@ function chartProjectStats(url, params, series, checkEmpty, tooltipFormat){
         if (previousPoint !== item.dataIndex) {
           previousPoint = item.dataIndex;
 
-          $("#tooltip").remove();
+          $(".chart-tooltip").remove();
           var x = item.datapoint[0].toFixed(0),
           y = item.datapoint[1].toFixed(0);
 
-          $('<div id="tooltip" class="tooltip">' + tooltipFormat(x,y,item) + '</div>').css( {
-            position: 'absolute',
-            display: 'none',
+          $('<div class="chart-tooltip">' + tooltipFormat(x,y,item) + '</div>').css( {
             top: item.pageY - 5,
             left: item.pageX + 5,
-            zIndex: 1,
-            background: 'white',
-            border: '1px solid black',
-            borderRadius: '0.5em',
-            padding: '0 0.3em',
           }).appendTo("body").fadeIn(200);
         }
       }
       else {
-        $("#tooltip").remove();
+        $(".chart-tooltip").remove();
         previousPoint = null;
       }
   });

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c1685f61/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html b/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
index a6587b3..e05506b 100644
--- a/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
+++ b/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
@@ -54,6 +54,7 @@
 
 {% block extra_css %}
 <link rel="stylesheet" type="text/css" href="{{g.forge_static('css/smoothness/jquery-ui-1.8.4.custom.css')}}"/>
+<link rel="stylesheet" type="text/css" href="{{g.forge_static('css/forge/ui.daterangepicker.css')}}"/>
 {% endblock %}
 
 {% block extra_js %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c1685f61/rat-excludes.txt
----------------------------------------------------------------------
diff --git a/rat-excludes.txt b/rat-excludes.txt
index d62c09f..30ded2a 100644
--- a/rat-excludes.txt
+++ b/rat-excludes.txt
@@ -22,6 +22,7 @@ Allura/allura/lib/widgets/resources/js/jquery.textarea.js
 Allura/allura/lib/widgets/resources/js/jquery.tools.min.js
 Allura/allura/public/nf/css/blueprint/
 Allura/allura/public/nf/css/forge/accordion.css
+Allura/allura/public/nf/css/forge/ui.daterangepicker.css
 Allura/allura/public/nf/css/smoothness/jquery-ui-1.8.4.custom.css
 Allura/allura/public/nf/images/beta_sf.psd
 Allura/allura/public/nf/js/jquery-base.js


[04/50] git commit: [#6541] Added import_id for GC tracker importer

Posted by jo...@apache.org.
[#6541] Added import_id for GC tracker importer

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/c3d8491e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/c3d8491e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/c3d8491e

Branch: refs/heads/cj/6422
Commit: c3d8491eaca5562414ae42a4fd2819b671920b6d
Parents: f190769
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Aug 26 21:48:36 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 9 20:27:29 2013 +0000

----------------------------------------------------------------------
 ForgeImporters/forgeimporters/google/tracker.py                | 4 +++-
 .../forgeimporters/tests/google/functional/test_tracker.py     | 6 ++++++
 ForgeImporters/forgeimporters/tests/google/test_tracker.py     | 1 +
 3 files changed, 10 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c3d8491e/ForgeImporters/forgeimporters/google/tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tracker.py b/ForgeImporters/forgeimporters/google/tracker.py
index 40dd939..eebdae0 100644
--- a/ForgeImporters/forgeimporters/google/tracker.py
+++ b/ForgeImporters/forgeimporters/google/tracker.py
@@ -116,6 +116,7 @@ class GoogleCodeTrackerImporter(ToolImporter):
                 EnableVoting=True,
                 open_status_names='New Accepted Started',
                 closed_status_names='Fixed Verified Invalid Duplicate WontFix Done',
+                import_id='%s/%s/issues' % (self.source, project_name),
             )
         ThreadLocalORMSession.flush_all()
         try:
@@ -126,7 +127,8 @@ class GoogleCodeTrackerImporter(ToolImporter):
                     ticket = TM.Ticket(
                         app_config_id=app.config._id,
                         custom_fields=dict(),
-                        ticket_num=ticket_num)
+                        ticket_num=ticket_num,
+                        import_id='%s/%s' % (app.config.options.import_id, ticket_num))
                     self.process_fields(ticket, issue)
                     self.process_labels(ticket, issue)
                     self.process_comments(ticket, issue)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c3d8491e/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
index 24081d9..0bd97ab 100644
--- a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
+++ b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
@@ -140,6 +140,12 @@ class TestGCTrackerImporter(TestCase):
         self.assertEqual(ticket.votes_up, 1)
         self.assertEqual(ticket.votes, 1)
 
+    def test_import_id(self):
+        ticket = self._make_ticket(self.test_issue, issue_id=6)
+        self.assertEqual(ticket.app.config.options.import_id, 'Google Code/test-issue-project/issues')
+        self.assertEqual(ticket.ticket_num, 6)
+        self.assertEqual(ticket.import_id, 'Google Code/test-issue-project/issues/6')
+
     @skipif(module_not_available('html2text'))
     def test_html2text_escaping(self):
         ticket = self._make_ticket(self.test_issue)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c3d8491e/ForgeImporters/forgeimporters/tests/google/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
index 5bbf836..d2cedc6 100644
--- a/ForgeImporters/forgeimporters/tests/google/test_tracker.py
+++ b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
@@ -52,6 +52,7 @@ class TestTrackerImporter(TestCase):
                 EnableVoting=True,
                 open_status_names='New Accepted Started',
                 closed_status_names='Fixed Verified Invalid Duplicate WontFix Done',
+                import_id='Google Code/project_name/issues',
             )
         gpe.iter_issues.assert_called_once_with('project_name')
         self.assertEqual(importer.process_fields.call_args_list, [


[44/50] git commit: [#6529] Added login overlay for project importers

Posted by jo...@apache.org.
[#6529] Added login overlay for project importers

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/55a9de83
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/55a9de83
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/55a9de83

Branch: refs/heads/cj/6422
Commit: 55a9de83489358bb706b2f8caf6febf75b706635
Parents: 68c74e4
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Tue Sep 10 21:55:05 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 16 22:34:13 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/auth.py               |  4 ++
 Allura/allura/lib/app_globals.py                |  7 +++
 Allura/allura/lib/security.py                   | 10 +++-
 Allura/allura/lib/widgets/forms.py              |  3 +-
 .../lib/widgets/resources/js/login_overlay.js   | 27 +++++++++
 Allura/allura/nf/allura/css/allura.css          | 13 ++++-
 .../allura/templates/jinja_master/master.html   |  3 +
 .../templates/jinja_master/theme_macros.html    | 11 +++-
 Allura/allura/templates/login_fragment.html     | 60 ++++++++++++++++++++
 Allura/allura/templates/widgets/forge_form.html |  1 +
 ForgeImporters/forgeimporters/base.py           |  3 +-
 11 files changed, 135 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/55a9de83/Allura/allura/controllers/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/auth.py b/Allura/allura/controllers/auth.py
index 4c1ee37..fa00208 100644
--- a/Allura/allura/controllers/auth.py
+++ b/Allura/allura/controllers/auth.py
@@ -105,6 +105,10 @@ class AuthController(BaseController):
         c.form = F.login_form
         return dict(oid_providers=OID_PROVIDERS, return_to=return_to)
 
+    @expose('jinja:allura:templates/login_fragment.html')
+    def login_fragment(self, *args, **kwargs):
+        return self.index(*args, **kwargs)
+
     @expose('jinja:allura:templates/custom_login.html')
     def login_verify_oid(self, provider, username, return_to=None):
         if provider:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/55a9de83/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index c1c0b32..e684383 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -115,6 +115,7 @@ class Globals(object):
         # Load login/logout urls; only used for SFX 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('auth.login_fragment_url', '/auth/login_fragment')
 
         # Setup Gravatar
         self.gravatar = gravatar.url
@@ -401,6 +402,12 @@ class Globals(object):
     def resource_manager(self):
         return ew_core.widget_context.resource_manager
 
+    def register_css(self, href, **kw):
+        self.resource_manager.register(ew.CSSLink(href, **kw))
+
+    def register_js(self, href, **kw):
+        self.resource_manager.register(ew.JSLink(href, **kw))
+
     def register_forge_css(self, href, **kw):
         self.resource_manager.register(ew.CSSLink('allura/' + href, **kw))
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/55a9de83/Allura/allura/lib/security.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/security.py b/Allura/allura/lib/security.py
index a0497ca..4718e56 100644
--- a/Allura/allura/lib/security.py
+++ b/Allura/allura/lib/security.py
@@ -383,7 +383,7 @@ def all_allowed(obj, user_or_role=None, project=None):
         return set([M.ALL_PERMISSIONS])
     return perms
 
-def require(predicate, message=None):
+def require(predicate, message=None, login_overlay=False):
     '''
     Example: require(has_access(c.app, 'read'))
 
@@ -401,13 +401,17 @@ def require(predicate, message=None):
     if c.user != M.User.anonymous():
         request.environ['error_message'] = message
         raise exc.HTTPForbidden(detail=message)
+    elif login_overlay:
+        c.show_login_overlay = True
     else:
         raise exc.HTTPUnauthorized()
 
-def require_access(obj, permission, **kwargs):
+def require_access(obj, permission, login_overlay=False, **kwargs):
     if obj is not None:
         predicate = has_access(obj, permission, **kwargs)
-        return require(predicate, message='%s access required' % permission.capitalize())
+        return require(predicate,
+                message='%s access required' % permission.capitalize(),
+                login_overlay=login_overlay)
     else:
         raise exc.HTTPForbidden(detail="Could not verify permissions for this page.")
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/55a9de83/Allura/allura/lib/widgets/forms.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/forms.py b/Allura/allura/lib/widgets/forms.py
index ae90b26..9d3f602 100644
--- a/Allura/allura/lib/widgets/forms.py
+++ b/Allura/allura/lib/widgets/forms.py
@@ -84,7 +84,8 @@ class ForgeForm(ew.SimpleForm):
         submit_text='Save',
         style='standard',
         method='post',
-        enctype=None)
+        enctype=None,
+        target=None)
 
     def display_label(self, field, label_text=None):
         ctx = super(ForgeForm, self).context_for(field)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/55a9de83/Allura/allura/lib/widgets/resources/js/login_overlay.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/login_overlay.js b/Allura/allura/lib/widgets/resources/js/login_overlay.js
new file mode 100644
index 0000000..c852916
--- /dev/null
+++ b/Allura/allura/lib/widgets/resources/js/login_overlay.js
@@ -0,0 +1,27 @@
+/*
+       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.
+*/
+
+/*global jQuery, $ */
+jQuery(function($) {
+    $('#login_overlay').draggable().lightbox_me({
+            closeClick: false,
+            closeEsc: false,
+            centered: true
+        });
+});

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/55a9de83/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 1334b0c..38404f7 100644
--- a/Allura/allura/nf/allura/css/allura.css
+++ b/Allura/allura/nf/allura/css/allura.css
@@ -215,4 +215,15 @@ b.ico.ico-vote-down { background-image: url('../images/vote_down.png'); }
 tr.rev div.markdown_content p {
     padding: 0;
     margin-bottom: 0;
-}
\ No newline at end of file
+}
+
+#login_overlay .title {
+    margin-bottom: 0;
+    padding-left: 10px;
+    border-top-left-radius: 4px;
+    border-top-right-radius: 4px;
+}
+
+#login_overlay iframe {
+    width: 400px;
+}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/55a9de83/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 e3afa6a..8060240 100644
--- a/Allura/allura/templates/jinja_master/master.html
+++ b/Allura/allura/templates/jinja_master/master.html
@@ -132,6 +132,9 @@
           </section>
         {% endfor %}
     </div>
+    {% if c.show_login_overlay %}
+        {{theme_macros.login_overlay()}}
+    {% endif %}
     {% for blob in g.resource_manager.emit('body_js') %}
       {{ blob }}
     {% endfor %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/55a9de83/Allura/allura/templates/jinja_master/theme_macros.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/jinja_master/theme_macros.html b/Allura/allura/templates/jinja_master/theme_macros.html
index 61f5e2f..7fc070c 100644
--- a/Allura/allura/templates/jinja_master/theme_macros.html
+++ b/Allura/allura/templates/jinja_master/theme_macros.html
@@ -112,4 +112,13 @@
          {% endif %}
       </div>
   {% endif %}
-{%- endmacro %}
\ No newline at end of file
+{%- endmacro %}
+
+{%- macro login_overlay() %}
+    {% do g.register_js('js/jquery.lightbox_me.js') %}
+    {% do g.register_js('js/login_overlay.js') %}
+    <div id="login_overlay" class="ui-widget-content">
+        <h2 class="dark title">Login Required</h2>
+        <iframe src="{{g.login_fragment_url}}"></iframe>
+    </div>
+{%- endmacro %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/55a9de83/Allura/allura/templates/login_fragment.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/login_fragment.html b/Allura/allura/templates/login_fragment.html
new file mode 100644
index 0000000..31fb26d
--- /dev/null
+++ b/Allura/allura/templates/login_fragment.html
@@ -0,0 +1,60 @@
+{#-
+       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.
+-#}
+<!DOCTYPE html>
+<!-- Server: {{g.server_name}} -->
+{% import 'allura:templates/jinja_master/lib.html' as lib with context %}
+{% if g.theme.jinja_macros %}
+  {% import g.theme.jinja_macros as theme_macros with context %}
+{% endif %}
+{% do g.register_forge_js('js/jquery-base.js') %}
+{% do g.register_forge_js('js/allura-base.js') %}
+{% do g.theme.require() %}
+{% do g.resource_manager.register_widgets(c) %}
+{# paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ #}
+<!--[if lt IE 7 ]> <html lang="en" class="no-js ie6"> <![endif]-->
+<!--[if IE 7 ]>    <html lang="en" class="no-js ie7"> <![endif]-->
+<!--[if IE 8 ]>    <html lang="en" class="no-js ie8"> <![endif]-->
+<!--[if IE 9 ]>    <html lang="en" class="no-js ie9"> <![endif]-->
+<!--[if (gt IE 9)|!(IE)]>--> <html lang="en" class="no-js"> <!--<![endif]-->
+    <head>
+        {{theme_macros.extra_header(g.theme_href(''))}}
+        {% for blob in g.resource_manager.emit('head_css') %}
+          {{ blob }}
+        {% endfor %}
+        {% for blob in g.resource_manager.emit('head_js') %}
+          {{ blob }}
+        {% endfor %}
+        <style type="text/css">
+            html {
+                overflow: hidden;
+            }
+            body {
+                padding-top: 1em;
+                width: 1000px;
+            }
+        </style>
+    </head>
+    <body>
+        {{ c.form.display(action='../do_login', target='_top', value=dict(return_to=return_to)) }}
+
+        {% for blob in g.resource_manager.emit('body_js_tail') %}
+          {{ blob }}
+        {% endfor %}
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/55a9de83/Allura/allura/templates/widgets/forge_form.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/forge_form.html b/Allura/allura/templates/widgets/forge_form.html
index 8adde73..adbc01c 100644
--- a/Allura/allura/templates/widgets/forge_form.html
+++ b/Allura/allura/templates/widgets/forge_form.html
@@ -18,6 +18,7 @@
 -#}
 <form method="{{method}}"
       {% if enctype %}enctype="{{enctype}}"{% endif %}
+      {% if target %}target="{{target}}"{% endif %}
       action="{{action}}">
   {% set extra_width = 0 %}
   {% if style == 'wide' %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/55a9de83/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index d7479b3..0b07c6d 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -190,7 +190,7 @@ class ProjectImporter(BaseController):
         self.neighborhood = neighborhood
 
     def _check_security(self):
-        require_access(self.neighborhood, 'register')
+        require_access(self.neighborhood, 'register', login_overlay=True)
 
     @LazyProperty
     def tool_importers(self):
@@ -231,6 +231,7 @@ class ProjectImporter(BaseController):
         tools installed and redirect to the new project, presumably with a
         message indicating that some data will not be available immediately.
         """
+        require_access(self.neighborhood, 'register', login_overlay=False)
         try:
             c.project = self.neighborhood.register_project(kw['project_shortname'],
                     project_name=kw['project_name'])


[28/50] git commit: [#6545] Fix typo

Posted by jo...@apache.org.
[#6545] Fix typo

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/d6648e11
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/d6648e11
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/d6648e11

Branch: refs/heads/cj/6422
Commit: d6648e119fa142b0bbd41d0423feb695b486aaee
Parents: 7f639f9
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Sep 10 14:07:09 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 14:36:31 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/artifact.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d6648e11/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 66d323e..8cfd6ab 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -62,7 +62,7 @@ class Artifact(MappedClass):
         session = artifact_orm_session
         name='artifact'
         indexes = [
-            ('app_config_id', 'label'),
+            ('app_config_id', 'labels'),
         ]
         def before_save(data):
             if not getattr(artifact_orm_session._get(), 'skip_mod_date', False):


[03/50] git commit: [#6541] Refactored import_id and ImportIdConverter

Posted by jo...@apache.org.
[#6541] Refactored import_id and ImportIdConverter

Made default import_id implementation use a dict to
record source and other info for use with multiple importers.

Requires Ming 0.3.9 (from 0.3.x branch) for MIM bug fixes for
tests to pass.

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/44866429
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/44866429
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/44866429

Branch: refs/heads/cj/6422
Commit: 448664290746b2c16fb99c8df1b04434f0296e37
Parents: c3d8491
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Aug 28 16:31:26 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 9 20:27:29 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/plugin.py                     | 32 ++++++++++++++++++++
 Allura/allura/model/artifact.py                 |  7 +++--
 ForgeImporters/forgeimporters/google/tracker.py | 11 +++++--
 .../tests/google/functional/test_tracker.py     | 11 +++++--
 .../forgeimporters/tests/google/test_tracker.py | 11 ++++++-
 ForgeTracker/forgetracker/model/ticket.py       |  2 +-
 ForgeTracker/forgetracker/plugins.py            | 25 ---------------
 .../forgetracker/tests/functional/test_root.py  |  2 +-
 ForgeTracker/forgetracker/tracker_main.py       | 12 +++++---
 requirements-common.txt                         |  2 +-
 10 files changed, 75 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/44866429/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index f600363..3376034 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -947,3 +947,35 @@ class AdminExtension(object):
         :rtype: ``None``
         """
         pass
+
+class ImportIdConverter(object):
+    '''
+    An interface to convert to and from import_id values for indexing,
+    searching, or displaying.
+
+    To provide a new converter, expose an entry point in setup.py:
+
+        [allura.tickets.import_id_converter]
+        mysource = foo.bar:SourceIdConverter
+
+    Then in your .ini file, set tickets.import_id_converter=mysource
+    '''
+
+    @classmethod
+    def get(cls):
+        converter = config.get('import_id_converter')
+        if converter:
+            return g.entry_points['allura.import_id_converter'][converter]()
+        return cls()
+
+    def simplify(self, import_id):
+        if hasattr(import_id, 'get'):
+            return import_id.get('source_id')
+        return None
+
+    def expand(self, source_id, app_instance):
+        import_id = {
+                'source_id': source_id,
+            }
+        import_id.update(app_instance.config.options.get('import_id', {}))
+        return import_id

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/44866429/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 294c3d0..46c4b01 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -83,8 +83,11 @@ class Artifact(MappedClass):
     references = FieldProperty(S.Deprecated)
     backreferences = FieldProperty(S.Deprecated)
     app_config = RelationProperty('AppConfig')
-    # Not null if artifact originated from external import, then API ticket id
-    import_id = FieldProperty(str, if_missing=None)
+    # Not null if artifact originated from external import.  The import ID is
+    # implementation specific, but should probably be an object indicating
+    # the source, original ID, and any other info needed to identify where
+    # the artifact came from.  But if you only have one source, a str might do.
+    import_id = FieldProperty(None, if_missing=None)
     deleted=FieldProperty(bool, if_missing=False)
 
     def __json__(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/44866429/ForgeImporters/forgeimporters/google/tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tracker.py b/ForgeImporters/forgeimporters/google/tracker.py
index eebdae0..58f28d2 100644
--- a/ForgeImporters/forgeimporters/google/tracker.py
+++ b/ForgeImporters/forgeimporters/google/tracker.py
@@ -40,11 +40,12 @@ from tg.decorators import (
 
 from allura.controllers import BaseController
 from allura.lib import helpers as h
+from allura.lib.plugin import ImportIdConverter
 from allura.lib.decorators import require_post, task
 
 from forgetracker.tracker_main import ForgeTrackerApp
 from forgetracker import model as TM
-from . import GoogleCodeProjectExtractor
+from forgeimporters.google import GoogleCodeProjectExtractor
 from forgeimporters.base import (
         ToolImporter,
         ToolImportForm,
@@ -112,11 +113,15 @@ class GoogleCodeTrackerImporter(ToolImporter):
 
     def import_tool(self, project, user, project_name, mount_point=None,
             mount_label=None, **kw):
+        import_id_converter = ImportIdConverter.get()
         app = project.install_app('tickets', mount_point, mount_label,
                 EnableVoting=True,
                 open_status_names='New Accepted Started',
                 closed_status_names='Fixed Verified Invalid Duplicate WontFix Done',
-                import_id='%s/%s/issues' % (self.source, project_name),
+                import_id={
+                        'source': self.source,
+                        'project_name': project_name,
+                    },
             )
         ThreadLocalORMSession.flush_all()
         try:
@@ -128,7 +133,7 @@ class GoogleCodeTrackerImporter(ToolImporter):
                         app_config_id=app.config._id,
                         custom_fields=dict(),
                         ticket_num=ticket_num,
-                        import_id='%s/%s' % (app.config.options.import_id, ticket_num))
+                        import_id=import_id_converter.expand(ticket_num, app))
                     self.process_fields(ticket, issue)
                     self.process_labels(ticket, issue)
                     self.process_comments(ticket, issue)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/44866429/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
index 0bd97ab..7f504a5 100644
--- a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
+++ b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
@@ -142,9 +142,16 @@ class TestGCTrackerImporter(TestCase):
 
     def test_import_id(self):
         ticket = self._make_ticket(self.test_issue, issue_id=6)
-        self.assertEqual(ticket.app.config.options.import_id, 'Google Code/test-issue-project/issues')
+        self.assertEqual(ticket.app.config.options.import_id, {
+                'source': 'Google Code',
+                'project_name': 'test-issue-project',
+            })
         self.assertEqual(ticket.ticket_num, 6)
-        self.assertEqual(ticket.import_id, 'Google Code/test-issue-project/issues/6')
+        self.assertEqual(ticket.import_id, {
+                'source': 'Google Code',
+                'project_name': 'test-issue-project',
+                'source_id': 6,
+            })
 
     @skipif(module_not_available('html2text'))
     def test_html2text_escaping(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/44866429/ForgeImporters/forgeimporters/tests/google/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
index d2cedc6..05b33ae 100644
--- a/ForgeImporters/forgeimporters/tests/google/test_tracker.py
+++ b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
@@ -42,6 +42,12 @@ class TestTrackerImporter(TestCase):
         importer.postprocess_custom_fields = mock.Mock()
         project, user = mock.Mock(), mock.Mock()
         app = project.install_app.return_value
+        app.config.options = {
+                'import_id': {
+                        'source': 'Google Code',
+                        'project_name': 'project_name',
+                    },
+            }
         issues = gpe.iter_issues.return_value = [(50, mock.Mock()), (100, mock.Mock())]
         tickets = TM.Ticket.side_effect = [mock.Mock(), mock.Mock()]
 
@@ -52,7 +58,10 @@ class TestTrackerImporter(TestCase):
                 EnableVoting=True,
                 open_status_names='New Accepted Started',
                 closed_status_names='Fixed Verified Invalid Duplicate WontFix Done',
-                import_id='Google Code/project_name/issues',
+                import_id={
+                        'source': 'Google Code',
+                        'project_name': 'project_name',
+                    }
             )
         gpe.iter_issues.assert_called_once_with('project_name')
         self.assertEqual(importer.process_fields.call_args_list, [

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/44866429/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index d16039e..1d4aeb2 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -47,9 +47,9 @@ from allura.lib import security
 from allura.lib.search import search_artifact, SearchError
 from allura.lib import utils
 from allura.lib import helpers as h
+from allura.lib.plugin import ImportIdConverter
 from allura.tasks import mail_tasks
 
-from forgetracker.plugins import ImportIdConverter
 
 log = logging.getLogger(__name__)
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/44866429/ForgeTracker/forgetracker/plugins.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/plugins.py b/ForgeTracker/forgetracker/plugins.py
index a32dcfc..3afbca2 100644
--- a/ForgeTracker/forgetracker/plugins.py
+++ b/ForgeTracker/forgetracker/plugins.py
@@ -22,28 +22,3 @@ from pylons import app_globals as g
 
 log = logging.getLogger(__name__)
 
-
-class ImportIdConverter(object):
-    '''
-    An interface to provide authentication services for Allura.
-
-    To provide a new converter, expose an entry point in setup.py:
-
-        [allura.tickets.import_id_converter]
-        mylegacy = foo.bar:LegacyConverter
-
-    Then in your .ini file, set tickets.import_id_converter=mylegacy
-    '''
-
-    @classmethod
-    def get(cls):
-        converter = config.get('tickets.import_id_converter')
-        if converter:
-            return g.entry_points['allura.tickets.import_id_converter'][converter]()
-        return cls()
-
-    def simplify(self, import_id):
-        return import_id
-
-    def expand(self, url_part, app_instance):
-        return url_part

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/44866429/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 0ba4f0b..86ef522 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -1573,7 +1573,7 @@ class TestFunctionalController(TrackerTestController):
     def test_imported_tickets_redirect(self):
         self.new_ticket(summary='Imported ticket')
         ticket = tm.Ticket.query.get(ticket_num=1)
-        ticket.import_id = '42000'
+        ticket.import_id = {'source_id': '42000'}
         ThreadLocalORMSession.flush_all()
 
         # expect permanent redirect to /p/test/bugs/1/

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/44866429/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 8aa29f6..3afdb15 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -58,6 +58,7 @@ from allura.lib import validators as V
 from allura.lib.widgets import form_fields as ffw
 from allura.lib.widgets.subscriptions import SubscribeForm
 from allura.lib.zarkov_helpers import zero_fill_zarkov_result
+from allura.lib.plugin import ImportIdConverter
 from allura.controllers import AppDiscussionController, AppDiscussionRestController
 from allura.controllers import attachments as ac
 from allura.controllers import BaseController
@@ -75,7 +76,6 @@ from forgetracker.widgets.bin_form import BinForm
 from forgetracker.widgets.ticket_search import TicketSearchResults, MassEdit, MassEditForm, MassMoveForm, SearchHelp
 from forgetracker.widgets.admin_custom_fields import TrackerFieldAdmin, TrackerFieldDisplay
 from forgetracker.import_support import ImportSupport
-from forgetracker.plugins import ImportIdConverter
 
 log = logging.getLogger(__name__)
 
@@ -1196,11 +1196,15 @@ class TicketController(BaseController, FeedController):
             self.ticket = TM.Ticket.query.get(app_config_id=c.app.config._id,
                                                     ticket_num=self.ticket_num)
             if self.ticket is None:
-                self.ticket = TM.Ticket.query.get(
-                        app_config_id=c.app.config._id,
-                        import_id=str(ImportIdConverter.get().expand(ticket_num, c.app)))
+                query = {'app_config_id': c.app.config._id}
+                import_id = ImportIdConverter.get().expand(ticket_num, c.app)
+                if import_id:
+                    query.update({'import_id.%s' % k: v for k,v in import_id.iteritems()})
+                self.ticket = TM.Ticket.query.get(**query)
                 if self.ticket is not None:
                     utils.permanent_redirect(self.ticket.url())
+                else:
+                    raise exc.HTTPNotFound('Ticket #%s does not exist.' % ticket_num)
             self.attachment = AttachmentsController(self.ticket)
             # self.comments = CommentController(self.ticket)
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/44866429/requirements-common.txt
----------------------------------------------------------------------
diff --git a/requirements-common.txt b/requirements-common.txt
index 5e261a0..5e4d6cc 100644
--- a/requirements-common.txt
+++ b/requirements-common.txt
@@ -21,7 +21,7 @@ httplib2==0.7.4
 iso8601==0.1.4
 Jinja2==2.6
 Markdown==2.2.0
-Ming==0.3.7
+Ming==0.3.9
 oauth2==1.5.170
 # tg2 dep PasteDeploy must specified before TurboGears2, to avoid a version/allow-hosts problem
 Paste==1.7.5.1


[12/50] git commit: [#6640] expose votes_up and votes_down in ticket API & export

Posted by jo...@apache.org.
[#6640] expose votes_up and votes_down in ticket API & export


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

Branch: refs/heads/cj/6422
Commit: 6e4fe74ed10b05cfff37a981e7849d0575ec0776
Parents: 815ef4f
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Sep 9 20:22:47 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 12:52:05 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/artifact.py                           |  6 ++++++
 Allura/allura/tests/unit/test_mixins.py                   | 10 ++++++++++
 ForgeTracker/forgetracker/model/ticket.py                 |  7 ++++++-
 ForgeTracker/forgetracker/tests/unit/test_ticket_model.py |  9 ++++++++-
 4 files changed, 30 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6e4fe74e/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 46c4b01..3910cad 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -896,3 +896,9 @@ class VotableArtifact(MappedClass):
         if votes_count == 0:
             return 0
         return int(float(self.votes_up) / votes_count * 100)
+
+    def __json__(self):
+        return {
+            'votes_up': self.votes_up,
+            'votes_down': self.votes_down,
+        }

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6e4fe74e/Allura/allura/tests/unit/test_mixins.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_mixins.py b/Allura/allura/tests/unit/test_mixins.py
index a35cbb6..a6c508f 100644
--- a/Allura/allura/tests/unit/test_mixins.py
+++ b/Allura/allura/tests/unit/test_mixins.py
@@ -75,3 +75,13 @@ class TestVotableArtifact(object):
         assert vote.votes_down_users == [self.user1.username]
         assert vote.votes_up == 0
         assert len(vote.votes_up_users) == 0
+
+    def test_json(self):
+        vote = VotableArtifact()
+        assert vote.__json__() == {'votes_up': 0, 'votes_down': 0}
+
+        vote.vote_down(self.user1)
+        assert vote.__json__() == {'votes_up': 0, 'votes_down': 1}
+
+        vote.vote_up(self.user2)
+        assert vote.__json__() == {'votes_up': 1, 'votes_down': 1}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6e4fe74e/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 1d4aeb2..505a991 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -947,7 +947,12 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
         return ticket
 
     def __json__(self):
-        return dict(super(Ticket,self).__json__(),
+        parents_json = {}
+        for parent in reversed(type(self).mro()):
+            if parent != type(self) and hasattr(parent, '__json__'):
+                parents_json.update(parent.__json__(self))
+
+        return dict(parents_json,
             created_date=self.created_date,
             ticket_num=self.ticket_num,
             summary=self.summary,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6e4fe74e/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
index 145bc7c..7f7fdd7 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
@@ -21,7 +21,7 @@ import urllib2
 
 from ming.orm.ormsession import ThreadLocalORMSession
 from ming import schema
-from nose.tools import raises, assert_raises, assert_equal
+from nose.tools import raises, assert_raises, assert_equal, assert_in
 
 from forgetracker.model import Ticket, TicketAttachment
 from forgetracker.tests.unit import TrackerTestWithModel
@@ -277,3 +277,10 @@ class TestTicketModel(TrackerTestWithModel):
         ThreadLocalORMSession.flush_all()
         assert_equal(len(ticket.attachments), 1)
         assert_equal(ticket.attachments.first().filename, 'test_ticket_model.py')
+
+    def test_json_parents(self):
+        ticket = Ticket.new()
+        json_keys = ticket.__json__().keys()
+        assert_in('related_artifacts', json_keys)  # from Artifact
+        assert_in('votes_up', json_keys)  # VotableArtifact
+        assert_in('ticket_num', json_keys)  # Ticket


[33/50] git commit: [#6545] 'All' forums is empty string, not None

Posted by jo...@apache.org.
[#6545] 'All' forums is empty string, not None

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/27f2b34a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/27f2b34a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/27f2b34a

Branch: refs/heads/cj/6422
Commit: 27f2b34ac5b0c35dc1c5dbe824298b5499ac3c5f
Parents: 657d510
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Sep 10 15:31:53 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 15:31:53 2013 +0000

----------------------------------------------------------------------
 ForgeDiscussion/forgediscussion/controllers/root.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/27f2b34a/ForgeDiscussion/forgediscussion/controllers/root.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py b/ForgeDiscussion/forgediscussion/controllers/root.py
index fdf8f11..5ec19ad 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -237,7 +237,7 @@ class RootController(BaseController, DispatchIndex, FeedController):
 
         discussion_id_q = {
             '$in': [d._id for d in c.app.forums
-                    if d.shortname == forum or forum is None]
+                    if d.shortname == forum or not forum]
         }
         # must be ordered dict, so that sorting by this works properly
         grouping = OrderedDict()


[07/50] git commit: [#6541] Added import_id and AuditLog to GC repo importer

Posted by jo...@apache.org.
[#6541] Added import_id and AuditLog to GC repo importer

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/59a395df
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/59a395df
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/59a395df

Branch: refs/heads/cj/6422
Commit: 59a395dfcccf6829162fb2c9ff2f4c02737c97ff
Parents: 4a4ee8f
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Aug 28 20:42:33 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 9 20:27:30 2013 +0000

----------------------------------------------------------------------
 ForgeImporters/forgeimporters/google/code.py      | 12 +++++++++++-
 .../forgeimporters/google/tests/test_code.py      | 18 ++++++++++++++----
 2 files changed, 25 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/59a395df/ForgeImporters/forgeimporters/google/code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/code.py b/ForgeImporters/forgeimporters/google/code.py
index 4cf752d..c5f34cd 100644
--- a/ForgeImporters/forgeimporters/google/code.py
+++ b/ForgeImporters/forgeimporters/google/code.py
@@ -36,6 +36,7 @@ from tg.decorators import (
 from allura.controllers import BaseController
 from allura.lib import validators as v
 from allura.lib.decorators import require_post, task
+from allura import model as M
 
 from forgeimporters.base import (
         ToolImporter,
@@ -168,6 +169,15 @@ class GoogleRepoImporter(ToolImporter):
                 mount_point=mount_point or 'code',
                 mount_label=mount_label or 'Code',
                 init_from_url=repo_url,
-                )
+                import_id={
+                        'source': self.source,
+                        'project_name': project_name,
+                    }
+            )
+        M.AuditLog.log(
+                'import tool %s from %s on %s' % (
+                    app.config.options.mount_point,
+                    project_name, self.source,
+                ), project=project, user=user)
         g.post_event('project_updated')
         return app

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/59a395df/ForgeImporters/forgeimporters/google/tests/test_code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tests/test_code.py b/ForgeImporters/forgeimporters/google/tests/test_code.py
index c6874ad..4028076 100644
--- a/ForgeImporters/forgeimporters/google/tests/test_code.py
+++ b/ForgeImporters/forgeimporters/google/tests/test_code.py
@@ -57,20 +57,30 @@ class TestGoogleRepoImporter(TestCase):
         return project
 
     @patch('forgeimporters.google.code.g')
+    @patch('forgeimporters.google.code.M')
     @patch('forgeimporters.google.code.GoogleCodeProjectExtractor')
     @patch('forgeimporters.google.code.get_repo_url')
-    def test_import_tool_happy_path(self, get_repo_url, gcpe, g):
+    def test_import_tool_happy_path(self, get_repo_url, gcpe, M, g):
         gcpe.return_value.get_repo_type.return_value = 'git'
         get_repo_url.return_value = 'http://remote/clone/url/'
         p = self._make_project(gc_proj_name='myproject')
-        GoogleRepoImporter().import_tool(p, Mock(name='c.user'),
-                project_name='project_name')
+        u = Mock(name='c.user')
+        app = p.install_app.return_value
+        app.config.options.mount_point = 'code'
+        GoogleRepoImporter().import_tool(p, u, project_name='project_name')
         get_repo_url.assert_called_once_with('project_name', 'git')
         p.install_app.assert_called_once_with('Git',
                 mount_point='code',
                 mount_label='Code',
                 init_from_url='http://remote/clone/url/',
-                )
+                import_id={
+                        'source': 'Google Code',
+                        'project_name': 'project_name',
+                    },
+            )
+        M.AuditLog.log.assert_called_once_with(
+                'import tool code from project_name on Google Code',
+                project=p, user=u)
         g.post_event.assert_called_once_with('project_updated')
 
 


[48/50] git commit: [#5966] add wiki-copy.py script

Posted by jo...@apache.org.
[#5966] add wiki-copy.py script


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

Branch: refs/heads/cj/6422
Commit: 1b62fd9fc1e4a4d2df965f8562bdf03c67e9a485
Parents: a1779fa
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 11 19:54:24 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Sep 17 17:00:13 2013 +0000

----------------------------------------------------------------------
 scripts/wiki-copy.py | 136 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 136 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1b62fd9f/scripts/wiki-copy.py
----------------------------------------------------------------------
diff --git a/scripts/wiki-copy.py b/scripts/wiki-copy.py
new file mode 100644
index 0000000..bca726d
--- /dev/null
+++ b/scripts/wiki-copy.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+
+#       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 re
+import os
+import sys
+import urllib
+import urlparse
+from optparse import OptionParser
+import json
+
+from ConfigParser import ConfigParser, NoOptionError
+import webbrowser
+import oauth2 as oauth
+
+
+def main():
+    cp = ConfigParser()
+    cp.read('/var/local/allura/Allura/production.ini')
+
+    op = OptionParser(usage='usage: %prog [options]')
+    op.add_option('-u', '--base-url', action='store', dest='base_url',
+            default=cp.get('app:main', 'base_url'), help='URL of API to upload to [default: %default]')
+    op.add_option('-D', '--debug', action='store_true', dest='debug', default=False)
+    op.add_option('-f', '--from-wiki', action='store', dest='from_wiki',
+            help='URL of wiki to copy from like http://fromserver.com/rest/p/test/wiki/')
+    op.add_option('-t', '--to-wiki', action='store', dest='to_wiki',
+            help='URL of wiki to copy to like http://toserver.com/rest/p/test/wiki/')
+    (options, args) = op.parse_args(sys.argv[1:])
+
+    oauth_client = make_oauth_client(options.base_url)
+
+    wiki_data = urllib.urlopen(options.from_wiki).read()
+    wiki_json = json.loads(wiki_data)['pages']
+    for p in wiki_json:
+        from_url = options.from_wiki+urllib.quote(p)
+        to_url = options.to_wiki+urllib.quote(p)
+        try:
+            page_data = urllib.urlopen(from_url).read()
+            page_json = json.loads(page_data)
+            if options.debug:
+                print page_json['text']
+                break
+            resp = oauth_client.request(to_url, 'POST', body=urllib.urlencode(dict(text=page_json['text'].encode('utf-8'))))
+            if resp[0]['status'] == '200':
+                print "Posted {0} to {1}".format(page_json['title'], to_url)
+            else:
+                print "Error posting {0} to {1}: {2} (project may not exist)".format(page_json['title'], to_url, resp[0]['status'])
+                break
+        except:
+            print "Error processing " + p
+            raise
+
+def make_oauth_client(base_url):
+    """
+    Build an oauth.Client with which callers can query Allura.
+
+    Based on Allura, sfpy, and sfx push scripts
+    """
+
+    cp = ConfigParser()
+    cp.read(os.path.join(os.environ['HOME'], '.convertrc'))
+
+    # https://sourceforge.net/p/forge/documentation/API%20-%20Beta/
+    REQUEST_TOKEN_URL = base_url+'/rest/oauth/request_token'
+    AUTHORIZE_URL =     base_url+'/rest/oauth/authorize'
+    ACCESS_TOKEN_URL =  base_url+'/rest/oauth/access_token'
+    oauth_key = option(cp, base_url, 'oauth_key', 'Forge API OAuth Key (%s/auth/oauth/): ' % base_url)
+    oauth_secret = option(cp, base_url, 'oauth_secret', 'Forge API Oauth Secret: ')
+    consumer = oauth.Consumer(oauth_key, oauth_secret)
+
+    try:
+        oauth_token = cp.get(base_url, 'oauth_token')
+        oauth_token_secret = cp.get(base_url, 'oauth_token_secret')
+    except NoOptionError:
+        client = oauth.Client(consumer)
+        resp, content = client.request(REQUEST_TOKEN_URL, 'GET')
+        assert resp['status'] == '200', resp
+
+        request_token = dict(urlparse.parse_qsl(content))
+        pin_url = "%s?oauth_token=%s" % (AUTHORIZE_URL, request_token['oauth_token'])
+        if getattr(webbrowser.get(), 'name', '') == 'links':
+            # sandboxes
+            print("Go to %s" % pin_url)
+        else:
+            webbrowser.open(pin_url)
+        oauth_verifier = raw_input('What is the PIN? ')
+
+        token = oauth.Token(request_token['oauth_token'], request_token['oauth_token_secret'])
+        token.set_verifier(oauth_verifier)
+        client = oauth.Client(consumer, token)
+        resp, content = client.request(ACCESS_TOKEN_URL, "GET")
+        access_token = dict(urlparse.parse_qsl(content))
+        oauth_token = access_token['oauth_token']
+        oauth_token_secret = access_token['oauth_token_secret']
+
+        cp.set(base_url, 'oauth_token', oauth_token)
+        cp.set(base_url, 'oauth_token_secret', oauth_token_secret)
+
+    # save oauth token for later use
+    cp.write(open(os.path.join(os.environ['HOME'], '.convertrc'), 'w'))
+
+    access_token = oauth.Token(oauth_token, oauth_token_secret)
+    oauth_client = oauth.Client(consumer, access_token)
+    return oauth_client
+
+def option(cp, section, key, prompt=None):
+    """ shared (copy/paste) between Allura & sfpy """
+    if not cp.has_section(section):
+        cp.add_section(section)
+    if cp.has_option(section, key):
+        value = cp.get(section, key)
+    else:
+        value = raw_input(prompt or ('%s: ' % key))
+        cp.set(section, key, value)
+    return value
+
+
+if __name__ == '__main__':
+    main()


[02/50] git commit: [#6640] expose votes_up and votes_down in ticket API & export

Posted by jo...@apache.org.
[#6640] expose votes_up and votes_down in ticket API & export


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

Branch: refs/heads/cj/6422
Commit: f3d3166dff92da0488fdbb6f9b8fc3ad3a1019a5
Parents: f190769
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Sep 9 20:22:47 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 9 20:22:47 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/artifact.py                           |  6 ++++++
 Allura/allura/tests/unit/test_mixins.py                   | 10 ++++++++++
 ForgeTracker/forgetracker/model/ticket.py                 |  7 ++++++-
 ForgeTracker/forgetracker/tests/unit/test_ticket_model.py |  9 ++++++++-
 4 files changed, 30 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f3d3166d/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 294c3d0..82baad6 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -893,3 +893,9 @@ class VotableArtifact(MappedClass):
         if votes_count == 0:
             return 0
         return int(float(self.votes_up) / votes_count * 100)
+
+    def __json__(self):
+        return {
+            'votes_up': self.votes_up,
+            'votes_down': self.votes_down,
+        }

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f3d3166d/Allura/allura/tests/unit/test_mixins.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_mixins.py b/Allura/allura/tests/unit/test_mixins.py
index a35cbb6..a6c508f 100644
--- a/Allura/allura/tests/unit/test_mixins.py
+++ b/Allura/allura/tests/unit/test_mixins.py
@@ -75,3 +75,13 @@ class TestVotableArtifact(object):
         assert vote.votes_down_users == [self.user1.username]
         assert vote.votes_up == 0
         assert len(vote.votes_up_users) == 0
+
+    def test_json(self):
+        vote = VotableArtifact()
+        assert vote.__json__() == {'votes_up': 0, 'votes_down': 0}
+
+        vote.vote_down(self.user1)
+        assert vote.__json__() == {'votes_up': 0, 'votes_down': 1}
+
+        vote.vote_up(self.user2)
+        assert vote.__json__() == {'votes_up': 1, 'votes_down': 1}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f3d3166d/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index d16039e..9995257 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -947,7 +947,12 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
         return ticket
 
     def __json__(self):
-        return dict(super(Ticket,self).__json__(),
+        parents_json = {}
+        for parent in reversed(type(self).mro()):
+            if parent != type(self) and hasattr(parent, '__json__'):
+                parents_json.update(parent.__json__(self))
+
+        return dict(parents_json,
             created_date=self.created_date,
             ticket_num=self.ticket_num,
             summary=self.summary,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f3d3166d/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
index 145bc7c..7f7fdd7 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_ticket_model.py
@@ -21,7 +21,7 @@ import urllib2
 
 from ming.orm.ormsession import ThreadLocalORMSession
 from ming import schema
-from nose.tools import raises, assert_raises, assert_equal
+from nose.tools import raises, assert_raises, assert_equal, assert_in
 
 from forgetracker.model import Ticket, TicketAttachment
 from forgetracker.tests.unit import TrackerTestWithModel
@@ -277,3 +277,10 @@ class TestTicketModel(TrackerTestWithModel):
         ThreadLocalORMSession.flush_all()
         assert_equal(len(ticket.attachments), 1)
         assert_equal(ticket.attachments.first().filename, 'test_ticket_model.py')
+
+    def test_json_parents(self):
+        ticket = Ticket.new()
+        json_keys = ticket.__json__().keys()
+        assert_in('related_artifacts', json_keys)  # from Artifact
+        assert_in('votes_up', json_keys)  # VotableArtifact
+        assert_in('ticket_num', json_keys)  # Ticket


[21/50] git commit: [#6545] [#5907] use status in last_post()

Posted by jo...@apache.org.
[#6545] [#5907] use status in last_post()

* we only want to show approved posts
* it uses the (discussion_id, status, timestamp) index


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

Branch: refs/heads/cj/6422
Commit: 192793e8b2d81b66b8050f40bb134444c5f6a848
Parents: 5808394
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 4 15:24:44 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 14:31:48 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/discuss.py                                 | 5 +++--
 ForgeDiscussion/forgediscussion/tests/functional/test_forum.py | 5 ++---
 2 files changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/192793e8/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index 07a6269..e227b47 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -92,9 +92,10 @@ class Discussion(Artifact, ActivityObject):
 
     @LazyProperty
     def last_post(self):
-        # TODO add status: to query
         q = self.post_class().query.find(dict(
-                discussion_id=self._id))\
+                discussion_id=self._id,
+                status='ok'
+                ))\
             .sort('timestamp', pymongo.DESCENDING)\
             .limit(1)\
             .hint([('discussion_id', pymongo.ASCENDING),

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/192793e8/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 89efa7c..12238c8 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -353,9 +353,8 @@ class TestForum(TestController):
             assert r.location.startswith('http://localhost/p/test/discussion/testforum/thread/'), r.location
 
         def _check():
-            # FIXME fix [#5907]
-            #r = self.app.get('/discussion/')
-            #assert 'Test Zero Posts' not in r
+            r = self.app.get('/discussion/')
+            assert 'Test Zero Posts' not in r
             r = self.app.get('/discussion/testforum/')
             assert 'Test Zero Posts' not in r
 


[47/50] git commit: [#5966] start adding docs for our scripts

Posted by jo...@apache.org.
[#5966] start adding docs for our scripts


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

Branch: refs/heads/cj/6422
Commit: 0951bee782d45d365763863ce570118d26b9c09a
Parents: 21b2c16
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Sep 12 18:44:50 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Sep 17 17:00:13 2013 +0000

----------------------------------------------------------------------
 Allura/docs/administration.rst | 66 +++++++++++++++++++++++++++++++++++++
 Allura/docs/index.rst          |  1 +
 2 files changed, 67 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0951bee7/Allura/docs/administration.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/administration.rst b/Allura/docs/administration.rst
new file mode 100644
index 0000000..b58339f
--- /dev/null
+++ b/Allura/docs/administration.rst
@@ -0,0 +1,66 @@
+..     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.
+
+Administration
+=================
+
+Commands, Scripts, and Tasks
+----------------------------
+
+Allura has many `paster` commands and `paster` scripts that can be run from the
+server commandline to administrate Allura.  There are also tasks that can be
+run through the `taskd` system.  New tasks can be submitted via the web at
+/nf/admin/task_manager  Some paster commands and scripts have been set up
+so that they are runnable as tasks too, giving you the convenience of starting
+them through the web and letting `taskd` execute them, rather than from a server
+shell.
+
+Commands can be discovered and run via the `paster` command when you are in the
+'Allura' directory that has your .ini file.  For example::
+
+    (env-allura) Allura$ paster help
+    ... all commands listed here ...
+
+    (env-allura) Allura$ paster create-neighborhood --help
+    ... specific command help ...
+
+    (env-allura) Allura$ paster create-neighborhood development.ini myneighborhood myuser ...
+
+
+Scripts are in the `scripts/` directory and run via `paster script`.  An extra
+`--` is required to separate script arguments from paster arguments.  Example::
+
+    (env-allura) Allura$ paster script development.ini ../scripts/create-allura-sitemap.py -- --help
+    ... help output ...
+
+    (env-allura) Allura$ paster script development.ini ../scripts/create-allura-sitemap.py -- -u 100
+
+
+TODO: explain how to run tasks, explain important scripts, commands and tasks here
+
+
+Client Scripts
+--------------
+
+Allura includes some client scripts that use Allura APIs and do not have to be run
+from an Allura server.  They do require various python packages to be installed
+and possibly a local Allura codebase set up.
+
+One such script is `wiki-copy.py` which reads the wiki pages from one Allura wiki
+instance and uploads them to another Allura wiki instance.  It can be run as::
+
+$ python scripts/wiki-copy.py --help

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0951bee7/Allura/docs/index.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/index.rst b/Allura/docs/index.rst
index 877b98d..ebbd0bf 100644
--- a/Allura/docs/index.rst
+++ b/Allura/docs/index.rst
@@ -35,6 +35,7 @@ Getting Started
    :maxdepth: 2
 
    installation
+   administration
    platform_tour
    scm_host
    migration


[32/50] git commit: [#6545] Remove hint() - no longer needed

Posted by jo...@apache.org.
[#6545] Remove hint() - no longer needed

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/657d5101
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/657d5101
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/657d5101

Branch: refs/heads/cj/6422
Commit: 657d5101a7f31aba1643c35a36855ecdeae8c2ed
Parents: d6648e1
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Sep 10 15:22:17 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 15:22:17 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/discuss.py | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/657d5101/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index e227b47..03c991e 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -97,13 +97,7 @@ class Discussion(Artifact, ActivityObject):
                 status='ok'
                 ))\
             .sort('timestamp', pymongo.DESCENDING)\
-            .limit(1)\
-            .hint([('discussion_id', pymongo.ASCENDING),
-                   ('status', pymongo.ASCENDING),
-                   ('timestamp', pymongo.ASCENDING),
-                   ])
-            # hint is to try to force the index to be used, since mongo wouldn't select it sometimes
-            # https://groups.google.com/forum/#!topic/mongodb-user/0TEqPfXxQU8
+            .limit(1)
         return q.first()
 
     def url(self):


[22/50] git commit: [#6545] remove old indexes and code; add 'timestamp' to discussion_id,status index

Posted by jo...@apache.org.
[#6545] remove old indexes and code; add 'timestamp' to discussion_id,status index

* Message's index on timestamp was added in 76e8541c for stats on ticket comments,
  our new index is a better fit
* Message's slug & parent_id indexes were added in ebb201de for now-unused
  replies() and descendants() methods


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

Branch: refs/heads/cj/6422
Commit: 58083948e5611ff57a899ced570718f71c0366fd
Parents: 28d8c31
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 4 13:58:06 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 14:31:48 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/artifact.py              | 25 -----------------------
 Allura/allura/model/discuss.py               | 17 +++++++--------
 Allura/allura/tests/model/test_artifact.py   | 18 ----------------
 Allura/allura/tests/model/test_discussion.py |  1 -
 ForgeTracker/forgetracker/tracker_main.py    |  4 +++-
 5 files changed, 12 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/58083948/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 9f91c6b..66d323e 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -564,7 +564,6 @@ class Message(Artifact):
     class __mongometa__:
         session = artifact_orm_session
         name='message'
-        indexes = Artifact.__mongometa__.indexes + [ 'slug', 'parent_id', 'timestamp' ]
     type_s='Generic Message'
 
     _id=FieldProperty(str, if_missing=h.gen_message_id)
@@ -594,30 +593,6 @@ class Message(Artifact):
         from .auth import User
         return User.query.get(_id=self.author_id) or User.anonymous()
 
-    def reply(self):
-        new_id = h.gen_message_id()
-        slug, full_slug = self.make_slugs(self)
-        new_args = dict(
-            state(self).document,
-            _id=new_id,
-            slug=slug,
-            full_slug=full_slug,
-            parent_id=self._id,
-            timestamp=datetime.utcnow(),
-            author_id=c.user._id)
-        return self.__class__(**new_args)
-
-    def descendants(self):
-        q = self.query.find(dict(slug={'$gt':self.slug})).sort('slug')
-        for msg in q:
-            if msg.slug.startswith(self.slug):
-                yield msg
-            else:
-                break
-
-    def replies(self):
-        return self.query.find(dict(parent_id=self._id))
-
     def index(self):
         result = Artifact.index(self)
         author = self.author()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/58083948/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index 057bb97..07a6269 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -92,11 +92,15 @@ class Discussion(Artifact, ActivityObject):
 
     @LazyProperty
     def last_post(self):
+        # TODO add status: to query
         q = self.post_class().query.find(dict(
                 discussion_id=self._id))\
             .sort('timestamp', pymongo.DESCENDING)\
             .limit(1)\
-            .hint([('discussion_id', pymongo.ASCENDING), ('status', pymongo.ASCENDING)])
+            .hint([('discussion_id', pymongo.ASCENDING),
+                   ('status', pymongo.ASCENDING),
+                   ('timestamp', pymongo.ASCENDING),
+                   ])
             # hint is to try to force the index to be used, since mongo wouldn't select it sometimes
             # https://groups.google.com/forum/#!topic/mongodb-user/0TEqPfXxQU8
         return q.first()
@@ -358,12 +362,6 @@ class Thread(Artifact, ActivityObject):
         return self.query_posts(page=page, limit=limit,
                                 timestamp=timestamp, style=style).all()
 
-    def top_level_posts(self):
-        return self.post_class().query.find(dict(
-                thread_id=self._id,
-                parent_id=None,
-                status='ok'))
-
     def url(self):
         # Can't use self.discussion because it might change during the req
         discussion = self.discussion_class().query.get(_id=self.discussion_id)
@@ -441,7 +439,10 @@ class Post(Message, VersionedArtifact, ActivityObject):
     class __mongometa__:
         name = 'post'
         history_class = PostHistory
-        indexes = [('discussion_id', 'status'), 'thread_id']
+        indexes = [
+            ('discussion_id', 'status', 'timestamp'),  # used in general lookups, last_post, etc
+            'thread_id'
+        ]
     type_s = 'Post'
 
     thread_id = ForeignIdProperty(Thread)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/58083948/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 d110d5e..639b247 100644
--- a/Allura/allura/tests/model/test_artifact.py
+++ b/Allura/allura/tests/model/test_artifact.py
@@ -158,24 +158,6 @@ def test_versioning():
     assert ss.text != pg.text
     assert pg.history().count() == 3
 
-@with_setup(setUp, tearDown)
-def test_messages():
-    m = Checkmessage()
-    assert m.author() == c.user
-    rm1 = m.reply()
-    assert rm1.slug.startswith(m.slug)
-    rm2 = rm1.reply()
-    rm3 = m.reply()
-    ThreadLocalORMSession.flush_all()
-    assert rm1 in list(m.descendants())
-    assert rm2 in list(m.descendants())
-    assert rm1 in list(m.replies())
-    assert rm2 not in list(m.replies())
-    idx = m.index()
-    assert 'author_user_name_t' in idx
-    assert 'author_display_name_t' in idx
-    assert 'timestamp_dt' in idx
-    assert m.shorthand_id() == m.slug
 
 @with_setup(setUp, tearDown)
 def test_messages_unknown_lookup():

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/58083948/Allura/allura/tests/model/test_discussion.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index 34e550a..36731bc 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -108,7 +108,6 @@ def test_thread_methods():
     assert t.subscription
     t.subscription = False
     assert not t.subscription
-    assert t.top_level_posts().count() == 2
     assert t.post_count == 3
     jsn = t.__json__()
     assert '_id' in jsn

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/58083948/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 61f7a99..c273279 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -896,7 +896,9 @@ class RootController(BaseController, FeedController):
 
     def ticket_comments_since(self, when=None):
         q = dict(
-            discussion_id=c.app.config.discussion_id)
+            discussion_id=c.app.config.discussion_id,
+            status='ok',
+        )
         if when is not None:
             q['timestamp'] = {'$gte':when}
         return M.Post.query.find(q).count()


[43/50] git commit: [#6652] don't use mktime() which assumes time tuple is local time

Posted by jo...@apache.org.
[#6652] don't use mktime() which assumes time tuple is local time


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

Branch: refs/heads/cj/6422
Commit: 68c74e40c577aa03eaef7fdce586c90c72e10c1f
Parents: 1ce95a3
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Sep 12 14:43:09 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Mon Sep 16 21:42:44 2013 +0000

----------------------------------------------------------------------
 AlluraTest/alluratest/test_syntax.py                | 4 +++-
 ForgeBlog/forgeblog/command/rssfeeds.py             | 4 ++--
 ForgeDiscussion/forgediscussion/controllers/root.py | 5 +++--
 3 files changed, 8 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/68c74e40/AlluraTest/alluratest/test_syntax.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/test_syntax.py b/AlluraTest/alluratest/test_syntax.py
index b394798..b72052c 100644
--- a/AlluraTest/alluratest/test_syntax.py
+++ b/AlluraTest/alluratest/test_syntax.py
@@ -69,11 +69,13 @@ def test_pyflakes():
     if error:
         raise Exception('pyflakes failure, see stdout')
 
-def test_no_now():
+def test_no_local_tz_functions():
     if run(find_py + " | xargs grep '\.now(' ") not in [1,123]:
         raise Exception("These should use .utcnow()")
     if run(find_py + " | xargs grep '\.fromtimestamp(' ") not in [1,123]:
         raise Exception("These should use .utcfromtimestamp()")
+    if run(find_py + " | xargs grep 'mktime(' ") not in [1,123]:
+        raise Exception("These should use calendar.timegm()")
 
 def test_no_prints():
     skips = [

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/68c74e40/ForgeBlog/forgeblog/command/rssfeeds.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/command/rssfeeds.py b/ForgeBlog/forgeblog/command/rssfeeds.py
index 0e70ea9..eeac4b2 100644
--- a/ForgeBlog/forgeblog/command/rssfeeds.py
+++ b/ForgeBlog/forgeblog/command/rssfeeds.py
@@ -15,7 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from time import mktime
+import calendar
 from datetime import datetime
 import re
 
@@ -128,7 +128,7 @@ class RssFeedsCommand(base.BlogCommand):
                                             getattr(e, 'title'))))
 
         content += u' [link](%s)' % e.link
-        updated = datetime.utcfromtimestamp(mktime(e.updated_parsed))
+        updated = datetime.utcfromtimestamp(calendar.timegm(e.updated_parsed))
 
         base_slug = BM.BlogPost.make_base_slug(title, updated)
         b_count = BM.BlogPost.query.find(dict(slug=base_slug, app_config_id=appid)).count()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/68c74e40/ForgeDiscussion/forgediscussion/controllers/root.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py b/ForgeDiscussion/forgediscussion/controllers/root.py
index c6f9019..aa1130e 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -19,9 +19,10 @@ import json
 import logging
 from urllib import unquote
 from datetime import date, datetime, timedelta, time
-from time import mktime
+import calendar
 from collections import OrderedDict
 
+
 from tg import expose, validate, redirect, flash, response
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from pylons import tmpl_context as c, app_globals as g
@@ -271,7 +272,7 @@ class RootController(BaseController, DispatchIndex, FeedController):
         def reformat_data(mongo_data):
             def item(day, val):
                 return [
-                    mktime(day.timetuple()) * 1000,
+                    calendar.timegm(day.timetuple()) * 1000,
                     val
                 ]
 


[42/50] git commit: [#6650] continue past invalid google code attachments

Posted by jo...@apache.org.
[#6650] continue past invalid google code attachments

Convert one of the test attachment links to an invalid one, refactor
shared attachment handling code between comments and issue


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

Branch: refs/heads/cj/6422
Commit: 1ce95a3bb6c1b88998328bea2c50ff9990a0b495
Parents: 5600821
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Sep 12 20:37:18 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Mon Sep 16 21:33:06 2013 +0000

----------------------------------------------------------------------
 .../forgeimporters/google/__init__.py           | 35 +++++++++++---------
 .../tests/data/google/test-issue.html           | 12 +++----
 .../tests/google/functional/test_tracker.py     |  1 -
 .../tests/google/test_extractor.py              |  5 +--
 4 files changed, 26 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1ce95a3b/ForgeImporters/forgeimporters/google/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/__init__.py b/ForgeImporters/forgeimporters/google/__init__.py
index 849f924..10ddc86 100644
--- a/ForgeImporters/forgeimporters/google/__init__.py
+++ b/ForgeImporters/forgeimporters/google/__init__.py
@@ -190,11 +190,7 @@ class GoogleCodeProjectExtractor(ProjectExtractor):
         return [_as_text(l) for l in label_nodes]
 
     def get_issue_attachments(self):
-        attachments = self.page.find(id='hc0').find('div', 'attachments')
-        if attachments:
-            return [Attachment(a.parent) for a in attachments.findAll('a', text='Download')]
-        else:
-            return []
+        return _get_attachments(self.page.find(id='hc0'))
 
     def get_issue_stars(self):
         stars_re = re.compile(r'(\d+) (person|people) starred this issue')
@@ -221,13 +217,29 @@ class UserLink(object):
         else:
             return self.name
 
+def _get_attachments(tag):
+    attachment_links = tag.find('div', 'attachments')
+    if attachment_links:
+        attachments = []
+        for a in attachment_links.findAll('a', text='Download'):
+            url = a.parent.get('href')
+            try:
+                attachment = Attachment(url)
+            except Exception:
+                log.exception('Could not get attachment: %s', url)
+            else:
+                attachments.append(attachment)
+        return attachments
+    else:
+        return []
+
 class Comment(object):
     def __init__(self, tag):
         self.author = UserLink(tag.find('span', 'author').find(True, 'userlink'))
         self.created_date = tag.find('span', 'date').get('title')
         self.body = _as_text(tag.find('pre')).strip()
         self._get_updates(tag)
-        self._get_attachments(tag)
+        self.attachments = _get_attachments(tag)
 
     def _get_updates(self, tag):
         _updates = tag.find('div', 'updates')
@@ -238,13 +250,6 @@ class Comment(object):
         else:
             self.updates = {}
 
-    def _get_attachments(self, tag):
-        attachments = tag.find('div', 'attachments')
-        if attachments:
-            self.attachments = [Attachment(a.parent) for a in attachments.findAll('a', text='Download')]
-        else:
-            self.attachments = []
-
     @property
     def annotated_text(self):
         text = (
@@ -272,7 +277,7 @@ class File(object):
         self.file = extractor.page['data']
 
 class Attachment(File):
-    def __init__(self, tag):
-        url = urljoin(GoogleCodeProjectExtractor.BASE_URL, tag.get('href'))
+    def __init__(self, url):
+        url = urljoin(GoogleCodeProjectExtractor.BASE_URL, url)
         filename = parse_qs(urlparse(url).query)['name'][0]
         super(Attachment, self).__init__(url, filename)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1ce95a3b/ForgeImporters/forgeimporters/tests/data/google/test-issue.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/data/google/test-issue.html b/ForgeImporters/forgeimporters/tests/data/google/test-issue.html
index 63670fd..693ca1d 100644
--- a/ForgeImporters/forgeimporters/tests/data/google/test-issue.html
+++ b/ForgeImporters/forgeimporters/tests/data/google/test-issue.html
@@ -305,19 +305,17 @@ That's all
 </table>
 <table cellspacing="3" cellpadding="2" border="0">
 <tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&amp;name=at2.txt&amp;token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">
+<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&amp;name=&amp;token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">
 <img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
 </a>
 </td>
 <td style="min-width:16em" valign="top">
-<b>at2.txt</b>
+<b></b>
 <br />
- 13 bytes
-
+ 0 bytes
 
- &nbsp; <a href="../../allura-google-importer/issues/attachmentText?id=7&amp;aid=70000001&amp;name=at2.txt&amp;token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255" target="_blank">View</a>
 
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&amp;name=at2.txt&amp;token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">Download</a>
+ &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&amp;name=&amp;token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">Download</a>
 </td>
 </tr>
 </table>
@@ -339,7 +337,7 @@ Test *comment* is a comment
 <div class="attachments">
 <table cellspacing="3" cellpadding="2" border="0">
 <tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60001000&amp;name=at2.txt&amp;token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667">
+<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60001000&amp;name=&amp;token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667">
 <img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
 </a>
 </td>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1ce95a3b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
index 9f48257..ca7c8a5 100644
--- a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
+++ b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
@@ -190,7 +190,6 @@ class TestGCTrackerImporter(TestCase):
         ticket = self._make_ticket(self.test_issue)
         self._assert_attachments(ticket.attachments,
                 ('at1.txt', 'text/plain', 'http://allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255'),
-                ('at2.txt', 'text/plain', 'http://allura-google-importer.googlecode.com/issues/attachment?aid=70000001&name=at2.txt&token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255'),
             )
 
     @without_module('html2text')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1ce95a3b/ForgeImporters/forgeimporters/tests/google/test_extractor.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_extractor.py b/ForgeImporters/forgeimporters/tests/google/test_extractor.py
index 668662e..a6c09be 100644
--- a/ForgeImporters/forgeimporters/tests/google/test_extractor.py
+++ b/ForgeImporters/forgeimporters/tests/google/test_extractor.py
@@ -217,13 +217,10 @@ class TestGoogleCodeProjectExtractor(TestCase):
         test_issue = open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/test-issue.html')).read()
         gpe = self._make_extractor(test_issue)
         attachments = gpe.get_issue_attachments()
-        self.assertEqual(len(attachments), 2)
+        self.assertEqual(len(attachments), 1)
         self.assertEqual(attachments[0].filename, 'at1.txt')
         self.assertEqual(attachments[0].url, 'http://allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255')
         self.assertEqual(attachments[0].type, 'text/plain')
-        self.assertEqual(attachments[1].filename, 'at2.txt')
-        self.assertEqual(attachments[1].url, 'http://allura-google-importer.googlecode.com/issues/attachment?aid=70000001&name=at2.txt&token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255')
-        self.assertEqual(attachments[1].type, 'text/plain')
 
     @mock.patch.object(google, 'StringIO')
     def test_iter_comments(self, StringIO):


[19/50] git commit: [#6626] ticket:427 Handle HEAD in url_for_commit for svn

Posted by jo...@apache.org.
[#6626] ticket:427 Handle HEAD in url_for_commit for svn


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

Branch: refs/heads/cj/6422
Commit: 5445e8403ca9ed4a61973b207a7f91ec0c5762a6
Parents: 307921b
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Sep 10 12:47:15 2013 +0300
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 13:34:16 2013 +0000

----------------------------------------------------------------------
 ForgeSVN/forgesvn/model/svn.py | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5445e840/ForgeSVN/forgesvn/model/svn.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/model/svn.py b/ForgeSVN/forgesvn/model/svn.py
index 3e6ea25..089572c 100644
--- a/ForgeSVN/forgesvn/model/svn.py
+++ b/ForgeSVN/forgesvn/model/svn.py
@@ -171,6 +171,8 @@ class SVNImplementation(M.RepositoryImplementation):
     def url_for_commit(self, commit, url_type=None):
         if hasattr(commit, '_id'):
             object_id = commit._id
+        elif commit == self._repo.app.default_branch_name:
+            object_id = commit
         else:
             object_id = self.rev_parse(commit)
         if ':' in object_id:


[29/50] git commit: [#6545] bump ming version for query.aggregate

Posted by jo...@apache.org.
[#6545] bump ming version for query.aggregate


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

Branch: refs/heads/cj/6422
Commit: 88b3fadb123247a7a9e809407863f46ca0291d6d
Parents: dc31991
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Sep 6 20:37:03 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 14:36:31 2013 +0000

----------------------------------------------------------------------
 requirements-common.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/88b3fadb/requirements-common.txt
----------------------------------------------------------------------
diff --git a/requirements-common.txt b/requirements-common.txt
index 5e4d6cc..42bdadb 100644
--- a/requirements-common.txt
+++ b/requirements-common.txt
@@ -21,7 +21,7 @@ httplib2==0.7.4
 iso8601==0.1.4
 Jinja2==2.6
 Markdown==2.2.0
-Ming==0.3.9
+Ming==0.3.10
 oauth2==1.5.170
 # tg2 dep PasteDeploy must specified before TurboGears2, to avoid a version/allow-hosts problem
 Paste==1.7.5.1


[15/50] git commit: [#6628] ticket:434 use generic "From address" in export emails

Posted by jo...@apache.org.
[#6628]  ticket:434 use generic "From address" in export emails


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

Branch: refs/heads/cj/6422
Commit: e2840fed6480cdce166962f52e8e6cc4ea300aab
Parents: 4eb88f5
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Mon Sep 9 12:03:27 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 13:04:26 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tasks/export_tasks.py | 2 +-
 Allura/allura/tests/test_tasks.py   | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/e2840fed/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index d06105e..8146b0f 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -91,7 +91,7 @@ def _bulk_export(project, tools, user):
         'not_exported_tools': not_exported_tools,
     }
     email = {
-        'fromaddr': unicode(user.email_address_header()),
+        'fromaddr': unicode(tg.config['forgemail.return_path']),
         'reply_to': unicode(user.email_address_header()),
         'message_id': h.gen_message_id(),
         'destinations': [unicode(user._id)],

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/e2840fed/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 80ecdfa..9123fa3 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -380,6 +380,7 @@ class TestExportTasks(unittest.TestCase):
             dict(task_name='allura.tasks.mail_tasks.sendmail')).all()
         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')
         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)


[41/50] git commit: [#6654] fix tracker stats, broken in [235614]

Posted by jo...@apache.org.
[#6654] fix tracker stats, broken in [235614]


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

Branch: refs/heads/cj/6422
Commit: 560082138424a38215b93e98401223581ab2f146
Parents: b6776af
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Sep 13 03:16:12 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Fri Sep 13 03:16:12 2013 +0000

----------------------------------------------------------------------
 ForgeTracker/forgetracker/templates/tracker/stats.html  | 3 ++-
 ForgeTracker/forgetracker/tests/functional/test_root.py | 7 +++++++
 2 files changed, 9 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/56008213/ForgeTracker/forgetracker/templates/tracker/stats.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/stats.html b/ForgeTracker/forgetracker/templates/tracker/stats.html
index 9db3fb3..5c8b509 100644
--- a/ForgeTracker/forgetracker/templates/tracker/stats.html
+++ b/ForgeTracker/forgetracker/templates/tracker/stats.html
@@ -41,4 +41,5 @@
 <li>7 days: {{week_comments}}</li>
 <li>14 days: {{fortnight_comments}}</li>
 <li>30 days: {{month_comments}}</li>
-</ul>
\ No newline at end of file
+</ul>
+{% endblock %}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/56008213/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 86ef522..d2185fa 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -2543,3 +2543,10 @@ class TestBulkMove(TrackerTestController):
 def sidebar_contains(response, text):
     sidebar_menu = response.html.find('div', attrs={'id': 'sidebar'})
     return text in str(sidebar_menu)
+
+
+class TestStats(TrackerTestController):
+
+    def test_stats(self):
+        r = self.app.get('/bugs/stats/', status=200)
+        assert_in('# tickets: 0', r.body)
\ No newline at end of file


[23/50] git commit: [#6545] Add graph of forum posts

Posted by jo...@apache.org.
[#6545] Add graph of forum posts


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

Branch: refs/heads/cj/6422
Commit: aad259f0bbbc598358a5b2cf08ed30da19014e48
Parents: 192793e
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 4 22:06:19 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 14:31:48 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/helpers.py                    |  6 ++
 Allura/allura/public/nf/js/stats.js             | 29 ++++---
 .../forgediscussion/controllers/root.py         | 81 +++++++++++++++++++-
 ForgeDiscussion/forgediscussion/forum_main.py   |  2 +-
 .../templates/discussionforums/stats_graph.html | 79 +++++++++++++++++++
 .../forgetracker/templates/tracker/stats.html   |  4 -
 6 files changed, 184 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/aad259f0/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 0e13fad..9c3d9e4 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -1006,3 +1006,9 @@ def iter_entry_points(group, *a, **kw):
     for ep in pkg_resources.iter_entry_points(group, *a, **kw):
         if ep.name not in disabled:
             yield ep
+
+
+# http://stackoverflow.com/a/1060330/79697
+def daterange(start_date, end_date):
+    for n in range(int((end_date - start_date).days)):
+        yield start_date + timedelta(n)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/aad259f0/Allura/allura/public/nf/js/stats.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/stats.js b/Allura/allura/public/nf/js/stats.js
index 2c803f6..72e12dc 100644
--- a/Allura/allura/public/nf/js/stats.js
+++ b/Allura/allura/public/nf/js/stats.js
@@ -20,26 +20,30 @@
 /*global jQuery, $, addCommas */
 jQuery(function($) {
     // date range picker
-    if ($('.picker input').length) {
-        $('.picker input').daterangepicker({
+    var input = $('#stats_date_picker input');
+    if (input.length) {
+        input.daterangepicker({
             onOpen: function() {
-                $('.picker input')[0].prev_value = $('.picker input').val();
+                input[0].prev_value = input.val();
             },
             onClose: function() {
-                if ($('.picker input')[0].prev_value !== $('.picker input').val()) {
-                    $('.picker input').parents('form').submit();
-                    //console.log('close',$('.picker input').val());
+                if (input[0].prev_value !== input.val()) {
+                    input.parents('form').submit();
                 }
             },
             rangeSplitter: 'to',
             dateFormat: 'yy-mm-dd', // yy is 4 digit
-            earliestDate: new Date($('.picker input').attr('data-start-date')),
+            earliestDate: new Date(input.attr('data-start-date')),
             latestDate: new Date()
         });
     }
 });
 
 function chartProjectStats(url, params, series, checkEmpty, tooltipFormat){
+    var timeformat = "%y-%0m-%0d";
+    tooltipFormat = tooltipFormat || function(x,y,item) {
+        return y + " on " + $.plot.formatDate(new Date(parseInt(x, 10)), timeformat);
+    };
     var holder = $('#stats-viz');
     var dates = $('#dates').val().split(' to ');
     var begin = Date.parse(dates[0]).setTimezoneOffset(0);
@@ -64,7 +68,7 @@ function chartProjectStats(url, params, series, checkEmpty, tooltipFormat){
             colors: ['#0685c6','#87c706','#c7c706','#c76606'],
             xaxis:{
               mode: "time",
-              timeformat: "%y-%0m-%0d",
+              timeformat: timeformat,
               minTickSize: [1, "day"],
               min: begin,
               max: end,
@@ -103,8 +107,13 @@ function chartProjectStats(url, params, series, checkEmpty, tooltipFormat){
           $('<div id="tooltip" class="tooltip">' + tooltipFormat(x,y,item) + '</div>').css( {
             position: 'absolute',
             display: 'none',
-            top: item.pageY + 5,
-            left: item.pageX + 5
+            top: item.pageY - 5,
+            left: item.pageX + 5,
+            zIndex: 1,
+            background: 'white',
+            border: '1px solid black',
+            borderRadius: '0.5em',
+            padding: '0 0.3em',
           }).appendTo("body").fadeIn(200);
         }
       }

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/aad259f0/ForgeDiscussion/forgediscussion/controllers/root.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py b/ForgeDiscussion/forgediscussion/controllers/root.py
index fa0e97b..9250ad0 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -18,10 +18,12 @@
 import json
 import logging
 from urllib import unquote
-from itertools import imap
+from datetime import date, datetime, timedelta, time
+from time import mktime
+from collections import OrderedDict
 
 from tg import expose, validate, redirect, flash, response
-from tg.decorators import with_trailing_slash
+from tg.decorators import with_trailing_slash, without_trailing_slash
 from pylons import tmpl_context as c, app_globals as g
 from pylons import request
 from formencode import validators
@@ -212,6 +214,81 @@ class RootController(BaseController, DispatchIndex, FeedController):
              'Recent posts to %s' % app.config.options.mount_label,
             app.url)
 
+    @without_trailing_slash
+    @expose('jinja:forgediscussion:templates/discussionforums/stats_graph.html')
+    def stats(self, dates=None, **kw):
+        if not dates:
+            dates = "{} to {}".format(
+                (date.today() - timedelta(days=60)).strftime('%Y-%m-%d'),
+                date.today().strftime('%Y-%m-%d'))
+        return dict(
+            dates=dates,
+        )
+
+    @expose('json')
+    @validate(dict(
+        begin=h.DateTimeConverter(if_empty=None, if_invalid=None),
+        end=h.DateTimeConverter(if_empty=None, if_invalid=None),
+    ))
+    def stats_data(self, begin=None, end=None, **kw):
+        end = end or date.today()
+        begin = begin or end - timedelta(days=60)
+
+        discussion_id_q = {
+            '$in': [d._id for d in c.app.forums]
+        }
+        # must be ordered dict, so that sorting by this works properly
+        grouping = OrderedDict()
+        grouping['year'] = {'$year': '$timestamp'}
+        grouping['month'] = {'$month': '$timestamp'}
+        grouping['day'] = {'$dayOfMonth': '$timestamp'}
+        {
+            'year': {'$year': '$timestamp'},
+            'month': {'$month': '$timestamp'},
+            'day': {'$dayOfMonth': '$timestamp'},
+        }
+        mongo_data = model.ForumPost.query.aggregate([
+            {'$match': {
+                'discussion_id': discussion_id_q,
+                'status': 'ok',
+                'timestamp': {
+                    # convert date to datetime to make pymongo happy
+                    '$gte': datetime.combine(begin, time.min),
+                    '$lte': datetime.combine(end, time.max),
+                },
+            }},
+            {'$group': {
+                '_id': grouping,
+                'posts': {'$sum': 1},
+            }},
+            {'$sort': {
+                '_id': pymongo.ASCENDING,
+            }},
+        ])['result']
+
+        def reformat_data(mongo_data):
+            def item(day, val):
+                return [
+                    mktime(day.timetuple()) * 1000,
+                    val
+                ]
+
+            next_expected_date = begin
+            for d in mongo_data:
+                this_date = datetime(d['_id']['year'], d['_id']['month'], d['_id']['day'])
+                for day in h.daterange(next_expected_date, this_date):
+                    yield item(day, 0)
+                yield item(this_date, d['posts'])
+                next_expected_date = this_date + timedelta(days=1)
+            for day in h.daterange(next_expected_date, end + timedelta(days=1)):
+                yield item(day, 0)
+
+        return dict(
+            begin=begin,
+            end=end,
+            data=list(reformat_data(mongo_data)),
+        )
+
 
 class RootRestController(BaseController):
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/aad259f0/ForgeDiscussion/forgediscussion/forum_main.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py
index 54c4bef..2145037 100644
--- a/ForgeDiscussion/forgediscussion/forum_main.py
+++ b/ForgeDiscussion/forgediscussion/forum_main.py
@@ -172,6 +172,7 @@ class ForgeDiscussionApp(Application):
                 l.append(SitemapEntry(
                         'Mark as Spam', 'flag_as_spam',
                         ui_icon=g.icons['flag'], className='sidebar_thread_spam'))
+            l.append(SitemapEntry('Stats Graph', c.app.url + 'stats', ui_icon=g.icons['stats']))
             if forum_links:
                 l.append(SitemapEntry('Forums'))
                 l = l + forum_links
@@ -301,4 +302,3 @@ class ForumAdminController(DefaultAdminController):
     def add_forum(self, add_forum=None, **kw):
         f = utils.create_forum(self.app, add_forum)
         redirect(f.url())
-

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/aad259f0/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html b/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
new file mode 100644
index 0000000..a6587b3
--- /dev/null
+++ b/ForgeDiscussion/forgediscussion/templates/discussionforums/stats_graph.html
@@ -0,0 +1,79 @@
+{#-
+       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.
+-#}
+{% extends g.theme.master %}
+
+{% block title %}{{c.project.name}} / {{c.app.config.options.mount_label}} / Stats{% endblock %}
+
+{% block header %}Stats{% endblock %}
+
+{% block content %}
+<form>
+  <div id="stats_date_picker">
+    <label for="dates">Date Range: </label>
+    <input value="{{dates}}" type="text" class="text ui-corner-all" name="dates" id="dates">
+  </div>
+</form>
+
+<div id="stats-viz-container" class="project_stats">
+  <div id="stats-viz" class="ui-corner-left ui-corner-br">
+    <table>
+      <tr>
+        <td class="yaxis">Posts</td>
+        <td>
+          <div id="project_stats_holder">
+            <div id="grid">
+                <div class="busy"></div>
+            </div>
+          </div>
+        </td>
+      </tr>
+      <tr>
+        <td colspan="2" class="xaxis">Date</td>
+      </tr>
+    </table>
+  </div>
+</div>
+
+{% endblock %}
+
+{% block extra_css %}
+<link rel="stylesheet" type="text/css" href="{{g.forge_static('css/smoothness/jquery-ui-1.8.4.custom.css')}}"/>
+{% endblock %}
+
+{% block extra_js %}
+<script type="text/javascript" src="{{g.forge_static('js/jquery.flot.js')}}"></script>
+<script type="text/javascript" src="{{g.forge_static('js/jquery.daterangepicker.js')}}"></script>
+<script type="text/javascript" src="{{g.forge_static('js/stats.js')}}"></script>
+<script type="text/javascript">
+  /*global chartProjectStats */
+  $(document).ready(function () {
+    var series = function(data){
+      return [{label: "Posts",
+              lines: {show: true, lineWidth: 3},
+              points: {show:true, radius:2, fill: true, fillColor: '#0685c6'},
+              data: data, shadowSize: 0}
+             ];
+    };
+    var checkEmpty = function(data){
+      return !data.length;
+    };
+    chartProjectStats('{{c.app.url}}stats_data',{},series,checkEmpty);
+  });
+</script>
+{% endblock %}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/aad259f0/ForgeTracker/forgetracker/templates/tracker/stats.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/stats.html b/ForgeTracker/forgetracker/templates/tracker/stats.html
index f4ac5b9..6351cf7 100644
--- a/ForgeTracker/forgetracker/templates/tracker/stats.html
+++ b/ForgeTracker/forgetracker/templates/tracker/stats.html
@@ -91,10 +91,6 @@
       return y + " tickets";
     };
     chartProjectStats('{{c.app.url}}stats_data',{},series,checkEmpty,tooltipFormat);
-
-    $('#dates').change(function(){
-      $("form.bp").submit();
-    });
   });
 </script>
 {% endif %}


[26/50] git commit: [#6545] remove SF-specific ticket graph (was deteriorating anyway)

Posted by jo...@apache.org.
[#6545] remove SF-specific ticket graph (was deteriorating anyway)


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

Branch: refs/heads/cj/6422
Commit: 235614508e37b2b1d31c1c7fc30db930e3e844ff
Parents: aad259f
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Sep 6 19:37:49 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 14:35:48 2013 +0000

----------------------------------------------------------------------
 .../forgetracker/templates/tracker/stats.html   | 55 +-------------------
 ForgeTracker/forgetracker/tracker_main.py       | 27 +---------
 2 files changed, 2 insertions(+), 80 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/23561450/ForgeTracker/forgetracker/templates/tracker/stats.html
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/templates/tracker/stats.html b/ForgeTracker/forgetracker/templates/tracker/stats.html
index 6351cf7..9db3fb3 100644
--- a/ForgeTracker/forgetracker/templates/tracker/stats.html
+++ b/ForgeTracker/forgetracker/templates/tracker/stats.html
@@ -41,57 +41,4 @@
 <li>7 days: {{week_comments}}</li>
 <li>14 days: {{fortnight_comments}}</li>
 <li>30 days: {{month_comments}}</li>
-</ul>
-{% if show_stats %}
-<h2>Open and closed tickets over time</h2>
-<form class="bp" action="{{request.path_url}}">
-  <div id="stats_date_picker">
-    <label for="dates">Date Range: </label>
-    <input value="{{dates}}" type="text" class="text ui-corner-all" name="dates" id="dates">
-  </div>
-</form>
-
-<div id="stats-viz-container" class="project_stats">
-  <div id="stats-viz" class="ui-corner-left ui-corner-br">
-    <table>
-      <tr>
-        <td class="yaxis">Tickets</td>
-        <td>
-          <div id="project_stats_holder">
-            <div id="grid">
-                <div class="busy"></div>
-            </div>
-          </div>
-        </td>
-      </tr>
-      <tr>
-        <td colspan="2" class="xaxis">Date</td>
-      </tr>
-    </table>
-  </div>
-</div>
-{% endif %}
-{% endblock %}
-{% block extra_js %}
-{% if show_stats %}
-<script type="text/javascript" src="{{g.forge_static('js/jquery.flot.js')}}"></script>
-<script type="text/javascript" src="{{g.forge_static('js/jquery.daterangepicker.js')}}"></script>
-<script type="text/javascript" src="{{g.forge_static('js/stats.js')}}"></script>
-<script type="text/javascript">
-  /*global chartProjectStats */
-  $(document).ready(function () {
-    var series = function(data){
-      return [{label: "Opened", lines: {show: true, lineWidth: 3}, points: {show:true, radius:2, fill: true, fillColor: '#0685c6'}, data: data.opened, shadowSize: 0},
-              {label: "Closed", lines: {show: true, lineWidth: 3}, points: {show:true, radius:2, fill: true, fillColor: '#87c706'}, data: data.closed, shadowSize: 0}];
-    };
-    var checkEmpty = function(data){
-      return !data.opened && !data.closed;
-    };
-    var tooltipFormat = function(x,y,item){
-      return y + " tickets";
-    };
-    chartProjectStats('{{c.app.url}}stats_data',{},series,checkEmpty,tooltipFormat);
-  });
-</script>
-{% endif %}
-{% endblock %}
\ No newline at end of file
+</ul>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/23561450/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index c273279..df1e084 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -57,7 +57,6 @@ from allura.lib import widgets as w
 from allura.lib import validators as V
 from allura.lib.widgets import form_fields as ffw
 from allura.lib.widgets.subscriptions import SubscribeForm
-from allura.lib.zarkov_helpers import zero_fill_zarkov_result
 from allura.lib.plugin import ImportIdConverter
 from allura.controllers import AppDiscussionController, AppDiscussionRestController
 from allura.controllers import attachments as ac
@@ -928,10 +927,6 @@ class RootController(BaseController, FeedController):
         if dates is None:
             today = datetime.utcnow()
             dates = "%s to %s" % ((today - timedelta(days=61)).strftime('%Y-%m-%d'), today.strftime('%Y-%m-%d'))
-        if c.app.config.get_tool_data('sfx', 'group_artifact_id') and config.get('zarkov.webservice_host'):
-            show_stats = True
-        else:
-            show_stats = False
         return dict(
                 now=str(now),
                 week_ago=str(week_ago),
@@ -949,28 +944,8 @@ class RootController(BaseController, FeedController):
                 closed=closed,
                 globals=globals,
                 dates=dates,
-                show_stats=show_stats)
+        )
 
-    @expose('json:')
-    def stats_data(self, begin=None, end=None, **kw):
-        if c.app.config.get_tool_data('sfx', 'group_artifact_id') and config.get('zarkov.webservice_host'):
-            if begin is None and end is None:
-                end_time = datetime.utcnow()
-                begin_time = (end_time - timedelta(days=61))
-                end = end_time.strftime('%Y-%m-%d')
-                begin = begin_time.strftime('%Y-%m-%d')
-            else:
-                end_time = datetime.strptime(end,'%Y-%m-%d')
-                begin_time = datetime.strptime(begin,'%Y-%m-%d')
-            time_interval = 'date'
-            if end_time - begin_time > timedelta(days=183):
-                time_interval = 'month'
-            q_filter = 'group-tracker-%s/%s/%s/' % (time_interval,c.project.get_tool_data('sfx', 'group_id'),c.app.config.get_tool_data('sfx', 'group_artifact_id'))
-            params = urlencode({'data': '{"c":"tracker","b":"'+q_filter+begin+'","e":"'+q_filter+end+'"}'})
-            read_zarkov = json.load(urlopen(config.get('zarkov.webservice_host')+'/q', params))
-            return zero_fill_zarkov_result(read_zarkov, time_interval, begin, end)
-        else:
-            return dict()
 
     @expose()
     @validate(W.subscribe_form)


[11/50] git commit: [#6541] bump trac & GC wiki importers, for their audit log addition

Posted by jo...@apache.org.
[#6541] bump trac & GC wiki importers, for their audit log addition


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

Branch: refs/heads/cj/6422
Commit: 815ef4fbf2d0021f6263b39f3943ecbbbc9c9cd4
Parents: 89cfb5a
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Sep 9 20:29:00 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 9 20:29:00 2013 +0000

----------------------------------------------------------------------
 requirements-sf.txt | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/815ef4fb/requirements-sf.txt
----------------------------------------------------------------------
diff --git a/requirements-sf.txt b/requirements-sf.txt
index 286c95a..ecad4a2 100644
--- a/requirements-sf.txt
+++ b/requirements-sf.txt
@@ -6,7 +6,7 @@ kombu==1.0.4
 coverage==3.5a1-20110413
 ForgeHg==0.1.16
 ForgePastebin==0.2.7
-GoogleCodeWikiImporter==0.3.1
+GoogleCodeWikiImporter==0.3.3
 mechanize==0.2.4
 mercurial==1.4.3
 MySQL-python==1.2.3c1
@@ -20,7 +20,7 @@ wsgipreload==1.2
 pyzmq==2.1.7
 html2text==3.200.3dev-20121112
 PyMollom==0.1
-TracWikiImporter==0.2.1
+TracWikiImporter==0.2.2
 
 # use version built from https://github.com/johnsca/GitPython/commits/tv/6000
 # for unmerged fixes for [#5411], [#6000], and [#6078]


[38/50] git commit: [#6613] don't expose TicketMonitoringEmail in API, and associated TestRestApiBase changes

Posted by jo...@apache.org.
[#6613] don't expose TicketMonitoringEmail in API, and associated TestRestApiBase changes


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

Branch: refs/heads/cj/6422
Commit: cd1be45da425cc914b50690588585741dad3fd01
Parents: 023a0a3
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Sep 12 17:59:12 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Sep 12 17:59:12 2013 +0000

----------------------------------------------------------------------
 .../tests/functional/test_rest_api_tickets.py   |  3 +-
 AlluraTest/alluratest/controller.py             | 34 +++++++++++++-------
 .../tests/functional/test_import.py             |  8 ++---
 .../tests/functional/test_import.py             | 10 +++---
 .../forgetracker/tests/functional/test_rest.py  |  4 +++
 ForgeTracker/forgetracker/tracker_main.py       |  7 +++-
 6 files changed, 44 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cd1be45d/Allura/allura/tests/functional/test_rest_api_tickets.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_rest_api_tickets.py b/Allura/allura/tests/functional/test_rest_api_tickets.py
index 11e149f..145e143 100644
--- a/Allura/allura/tests/functional/test_rest_api_tickets.py
+++ b/Allura/allura/tests/functional/test_rest_api_tickets.py
@@ -29,7 +29,8 @@ class TestApiTicket(TestRestApiBase):
     def set_api_ticket(self, expire=None):
         if not expire:
             expire = timedelta(days=1)
-        api_ticket = M.ApiTicket(user_id=self.user._id, capabilities={'import': ['Projects','test']},
+        test_admin = M.User.query.get(username='test-admin')
+        api_ticket = M.ApiTicket(user_id=test_admin._id, capabilities={'import': ['Projects','test']},
                                  expires=datetime.utcnow() + expire)
         session(api_ticket).flush()
         self.set_api_token(api_ticket)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cd1be45d/AlluraTest/alluratest/controller.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/controller.py b/AlluraTest/alluratest/controller.py
index 7b38700..577088d 100644
--- a/AlluraTest/alluratest/controller.py
+++ b/AlluraTest/alluratest/controller.py
@@ -145,23 +145,35 @@ class TestRestApiBase(TestController):
     def setUp(self):
         super(TestRestApiBase, self).setUp()
         setup_global_objects()
-#        h.set_context('test', 'home')
-        self.user = M.User.query.get(username='test-admin')
-        self.token = M.ApiToken(user_id=self.user._id)
-        ming.orm.session(self.token).flush()
+        self._use_token = None
+        self._token_cache = {}
 
     def set_api_token(self, token):
-        self.token = token
+        self._use_token = token
+
+    def token(self, username):
+        if self._use_token:
+            return self._use_token
+
+        # only create token once, else ming gets dupe key error
+        if username not in self._token_cache:
+            user = M.User.query.get(username=username)
+            token = M.ApiToken(user_id=user._id)
+            ming.orm.session(token).flush()
+            self._token_cache[username] = token
+
+        return self._token_cache[username]
 
     def _api_getpost(self, method, path, api_key=None, api_timestamp=None, api_signature=None,
-                 wrap_args=None, **params):
+                 wrap_args=None, user='test-admin', **params):
         if wrap_args:
             params = {wrap_args: params}
         params = variabledecode.variable_encode(params, add_repetitions=False)
         if api_key: params['api_key'] = api_key
         if api_timestamp: params['api_timestamp'] = api_timestamp
         if api_signature: params['api_signature'] = api_signature
-        params = self.token.sign_request(path, params)
+
+        params = self.token(user).sign_request(path, params)
 
         fn = self.app.post if method=='POST' else self.app.get
 
@@ -175,9 +187,9 @@ class TestRestApiBase(TestController):
             return response
 
     def api_get(self, path, api_key=None, api_timestamp=None, api_signature=None,
-                 wrap_args=None, **params):
-        return self._api_getpost('GET', path, api_key, api_timestamp, api_signature, wrap_args, **params)
+                 wrap_args=None, user='test-admin', **params):
+        return self._api_getpost('GET', path, api_key, api_timestamp, api_signature, wrap_args, user, **params)
 
     def api_post(self, path, api_key=None, api_timestamp=None, api_signature=None,
-                 wrap_args=None, **params):
-        return self._api_getpost('POST', path, api_key, api_timestamp, api_signature, wrap_args, **params)
+                 wrap_args=None, user='test-admin', **params):
+        return self._api_getpost('POST', path, api_key, api_timestamp, api_signature, wrap_args, user, **params)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cd1be45d/ForgeDiscussion/forgediscussion/tests/functional/test_import.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_import.py b/ForgeDiscussion/forgediscussion/tests/functional/test_import.py
index 17d13c7..76d7896 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_import.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_import.py
@@ -57,7 +57,7 @@ class TestImportController(TestRestApiBase):#TestController):
         assert not r.json['errors']
 
     def test_import_anon(self):
-        api_ticket = M.ApiTicket(user_id=self.user._id, capabilities={'import': ['Projects', 'test']},
+        api_ticket = M.ApiTicket(user_id=c.user._id, capabilities={'import': ['Projects', 'test']},
                                  expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
         self.set_api_token(api_ticket)
@@ -76,7 +76,7 @@ class TestImportController(TestRestApiBase):#TestController):
         assert 'Anonymous' in str(r)
 
     def test_import_map(self):
-        api_ticket = M.ApiTicket(user_id=self.user._id, capabilities={'import': ['Projects', 'test']},
+        api_ticket = M.ApiTicket(user_id=c.user._id, capabilities={'import': ['Projects', 'test']},
                                  expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
         self.set_api_token(api_ticket)
@@ -97,7 +97,7 @@ class TestImportController(TestRestApiBase):#TestController):
         assert 'Anonymous' not in str(r)
 
     def test_import_create(self):
-        api_ticket = M.ApiTicket(user_id=self.user._id, capabilities={'import': ['Projects', 'test']},
+        api_ticket = M.ApiTicket(user_id=c.user._id, capabilities={'import': ['Projects', 'test']},
                                  expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
         self.set_api_token(api_ticket)
@@ -117,7 +117,7 @@ class TestImportController(TestRestApiBase):#TestController):
         assert 'test-rick446' in str(r)
 
     def set_api_ticket(self, caps={'import': ['Projects', 'test']}):
-        api_ticket = M.ApiTicket(user_id=self.user._id, capabilities=caps,
+        api_ticket = M.ApiTicket(user_id=c.user._id, capabilities=caps,
                                  expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
         self.set_api_token(api_ticket)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cd1be45d/ForgeTracker/forgetracker/tests/functional/test_import.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_import.py b/ForgeTracker/forgetracker/tests/functional/test_import.py
index f876b93..8192115 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_import.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_import.py
@@ -46,7 +46,7 @@ class TestImportController(TestRestApiBase):
         return resp.follow()
 
     def set_api_ticket(self, caps={'import': ['Projects','test']}):
-        api_ticket = M.ApiTicket(user_id=self.user._id, capabilities=caps,
+        api_ticket = M.ApiTicket(user_id=c.user._id, capabilities=caps,
                                  expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
         self.set_api_token(api_ticket)
@@ -107,7 +107,7 @@ class TestImportController(TestRestApiBase):
             '/admin/bugs/set_custom_fields',
             params=variable_encode(params))
         here_dir = os.path.dirname(__file__)
-        api_ticket = M.ApiTicket(user_id=self.user._id, capabilities={'import': ['Projects','test']},
+        api_ticket = M.ApiTicket(user_id=c.user._id, capabilities={'import': ['Projects','test']},
                                  expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
         self.set_api_token(api_ticket)
@@ -129,7 +129,7 @@ class TestImportController(TestRestApiBase):
     @td.with_tracker
     def test_import(self):
         here_dir = os.path.dirname(__file__)
-        api_ticket = M.ApiTicket(user_id=self.user._id, capabilities={'import': ['Projects','test']},
+        api_ticket = M.ApiTicket(user_id=c.user._id, capabilities={'import': ['Projects','test']},
                                  expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
         self.set_api_token(api_ticket)
@@ -184,7 +184,7 @@ class TestImportController(TestRestApiBase):
 
     @td.with_tracker
     def test_links(self):
-        api_ticket = M.ApiTicket(user_id=self.user._id, capabilities={'import': ['Projects','test']},
+        api_ticket = M.ApiTicket(user_id=c.user._id, capabilities={'import': ['Projects','test']},
                                  expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
         self.set_api_token(api_ticket)
@@ -207,7 +207,7 @@ class TestImportController(TestRestApiBase):
 
     @td.with_tracker
     def test_slug(self):
-        api_ticket = M.ApiTicket(user_id=self.user._id, capabilities={'import': ['Projects','test']},
+        api_ticket = M.ApiTicket(user_id=c.user._id, capabilities={'import': ['Projects','test']},
                                  expires=datetime.utcnow() + timedelta(days=1))
         ming.orm.session(api_ticket).flush()
         self.set_api_token(api_ticket)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cd1be45d/ForgeTracker/forgetracker/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_rest.py b/ForgeTracker/forgetracker/tests/functional/test_rest.py
index df0a422..b687efb 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_rest.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_rest.py
@@ -96,6 +96,10 @@ class TestRestUpdateTicket(TestTrackerApiBase):
         assert tickets.json['milestones'][0]['name'] == '1.0'
         assert tickets.json['milestones'][1]['name'] == '2.0'
 
+    def test_ticket_index_noauth(self):
+        tickets = self.api_get('/rest/p/test/bugs', user='*anonymous')
+        assert 'TicketMonitoringEmail' not in tickets.json['tracker_config']['options']
+
     def test_update_ticket(self):
         args = dict(self.ticket_args, summary='test update ticket', labels='',
                     assigned_to=self.ticket_args['assigned_to_id'] or '')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cd1be45d/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index bc66e6c..28bd4aa 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1583,7 +1583,12 @@ class RootRestController(BaseController):
                                         limit=int(limit), page=int(page))
         results['tickets'] = [dict(ticket_num=t.ticket_num, summary=t.summary)
                               for t in results['tickets']]
-        results['tracker_config'] = c.app.config
+        results['tracker_config'] = c.app.config.__json__()
+        if not has_access(c.app, 'admin', c.user):
+            try:
+                del results['tracker_config']['options']['TicketMonitoringEmail']
+            except KeyError:
+                pass
         results['milestones'] = c.app.milestones
         results['saved_bins'] = c.app.bins
         results.pop('q', None)


[45/50] git commit: [#6529] Refactored login overlay logic out of allura.lib.security and added tests

Posted by jo...@apache.org.
[#6529] Refactored login overlay logic out of allura.lib.security and added 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/b930a634
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/b930a634
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/b930a634

Branch: refs/heads/cj/6422
Commit: b930a634aee55ac839b6f6941980164d36e90694
Parents: 55a9de8
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Thu Sep 12 20:10:19 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 16 22:34:13 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/helpers.py                    | 13 ++++++++++
 Allura/allura/lib/security.py                   | 10 +++-----
 Allura/allura/tests/test_helpers.py             | 14 ++++++++++-
 ForgeImporters/forgeimporters/base.py           |  5 ++--
 .../tests/github/functional/test_github.py      |  8 +++++++
 .../forgeimporters/tests/test_base.py           | 25 ++++++++++++++++++++
 6 files changed, 65 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b930a634/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 9c3d9e4..0b92968 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -52,6 +52,7 @@ from jinja2 import Markup
 from paste.deploy.converters import asbool, aslist
 
 from webhelpers import date, feedgenerator, html, number, misc, text
+from webob.exc import HTTPUnauthorized
 
 from allura.lib import exceptions as exc
 # Reimport to make available to templates
@@ -1012,3 +1013,15 @@ def iter_entry_points(group, *a, **kw):
 def daterange(start_date, end_date):
     for n in range(int((end_date - start_date).days)):
         yield start_date + timedelta(n)
+
+
+@contextmanager
+def login_overlay(exceptions=None):
+    try:
+        yield
+    except HTTPUnauthorized as e:
+        if exceptions:
+            for exception in exceptions:
+                if request.path.rstrip('/').endswith('/%s' % exception):
+                    raise
+        c.show_login_overlay = True

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b930a634/Allura/allura/lib/security.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/security.py b/Allura/allura/lib/security.py
index 4718e56..a0497ca 100644
--- a/Allura/allura/lib/security.py
+++ b/Allura/allura/lib/security.py
@@ -383,7 +383,7 @@ def all_allowed(obj, user_or_role=None, project=None):
         return set([M.ALL_PERMISSIONS])
     return perms
 
-def require(predicate, message=None, login_overlay=False):
+def require(predicate, message=None):
     '''
     Example: require(has_access(c.app, 'read'))
 
@@ -401,17 +401,13 @@ def require(predicate, message=None, login_overlay=False):
     if c.user != M.User.anonymous():
         request.environ['error_message'] = message
         raise exc.HTTPForbidden(detail=message)
-    elif login_overlay:
-        c.show_login_overlay = True
     else:
         raise exc.HTTPUnauthorized()
 
-def require_access(obj, permission, login_overlay=False, **kwargs):
+def require_access(obj, permission, **kwargs):
     if obj is not None:
         predicate = has_access(obj, permission, **kwargs)
-        return require(predicate,
-                message='%s access required' % permission.capitalize(),
-                login_overlay=login_overlay)
+        return require(predicate, message='%s access required' % permission.capitalize())
     else:
         raise exc.HTTPForbidden(detail="Could not verify permissions for this page.")
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b930a634/Allura/allura/tests/test_helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_helpers.py b/Allura/allura/tests/test_helpers.py
index d4e5a0c..38a67c5 100644
--- a/Allura/allura/tests/test_helpers.py
+++ b/Allura/allura/tests/test_helpers.py
@@ -27,6 +27,7 @@ from nose.tools import eq_, assert_equals
 from IPython.testing.decorators import skipif, module_not_available
 from datadiff import tools as dd
 from webob import Request
+from webob.exc import HTTPUnauthorized
 from ming.orm import ThreadLocalORMSession
 
 from allura import model as M
@@ -432,4 +433,15 @@ def test_absurl_with_request():
 
 def test_daterange():
     assert_equals(list(h.daterange(datetime(2013, 1, 1), datetime(2013, 1, 4))),
-                 [datetime(2013, 1, 1), datetime(2013, 1, 2), datetime(2013, 1, 3)])
\ No newline at end of file
+                 [datetime(2013, 1, 1), datetime(2013, 1, 2), datetime(2013, 1, 3)])
+
+@patch.object(h, 'request',
+              new=Request.blank('/p/test/foobar', base_url='https://www.mysite.com/p/test/foobar'))
+def test_login_overlay():
+    with h.login_overlay():
+        raise HTTPUnauthorized()
+    with h.login_overlay(exceptions=['foo']):
+        raise HTTPUnauthorized()
+    with td.raises(HTTPUnauthorized):
+        with h.login_overlay(exceptions=['foobar']):
+            raise HTTPUnauthorized()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b930a634/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index 0b07c6d..8c01b62 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -26,6 +26,7 @@ from tg import expose, validate, flash, redirect, config
 from tg.decorators import with_trailing_slash
 from pylons import app_globals as g
 from pylons import tmpl_context as c
+from pylons import request
 from formencode import validators as fev, schema
 from webob import exc
 
@@ -190,7 +191,8 @@ class ProjectImporter(BaseController):
         self.neighborhood = neighborhood
 
     def _check_security(self):
-        require_access(self.neighborhood, 'register', login_overlay=True)
+        with h.login_overlay(exceptions=['process']):
+            require_access(self.neighborhood, 'register')
 
     @LazyProperty
     def tool_importers(self):
@@ -231,7 +233,6 @@ class ProjectImporter(BaseController):
         tools installed and redirect to the new project, presumably with a
         message indicating that some data will not be available immediately.
         """
-        require_access(self.neighborhood, 'register', login_overlay=False)
         try:
             c.project = self.neighborhood.register_project(kw['project_shortname'],
                     project_name=kw['project_name'])

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b930a634/ForgeImporters/forgeimporters/tests/github/functional/test_github.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/github/functional/test_github.py b/ForgeImporters/forgeimporters/tests/github/functional/test_github.py
index 3c05a2d..cee88c0 100644
--- a/ForgeImporters/forgeimporters/tests/github/functional/test_github.py
+++ b/ForgeImporters/forgeimporters/tests/github/functional/test_github.py
@@ -26,3 +26,11 @@ class TestGitHubImportController(TestController, TestCase):
         assert '<input id="user_name" name="user_name" value="" autofocus/>' in r
         assert '<input id="project_name" name="project_name" value="" />' in r
         assert '<input id="project_shortname" name="project_shortname" value=""/>' in r
+
+    def test_login_overlay(self):
+        r = self.app.get('/p/import_project/github/', extra_environ=dict(username='*anonymous'))
+        self.assertIn('GitHub Project Importer', r)
+        self.assertIn('Login Required', r)
+
+        r = self.app.post('/p/import_project/github/process', extra_environ=dict(username='*anonymous'), status=302)
+        self.assertIn('/auth/', r.location)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b930a634/ForgeImporters/forgeimporters/tests/test_base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/test_base.py b/ForgeImporters/forgeimporters/tests/test_base.py
index 4aefc35..d4b403d 100644
--- a/ForgeImporters/forgeimporters/tests/test_base.py
+++ b/ForgeImporters/forgeimporters/tests/test_base.py
@@ -21,8 +21,10 @@ from formencode import Invalid
 import mock
 from tg import expose
 from nose.tools import assert_equal, assert_raises
+from webob.exc import HTTPUnauthorized
 
 from alluratest.controller import TestController
+from allura.tests import decorators as td
 
 from .. import base
 
@@ -123,6 +125,29 @@ class TestProjectImporter(TestCase):
         self.assertEqual(flash.call_count, 1)
         redirect.assert_called_once_with('script_name/admin/overview')
 
+    @mock.patch.object(base.h, 'request')
+    @mock.patch.object(base, 'require_access')
+    @mock.patch.object(base.h, 'c')
+    def test_login_overlay(self, c, require_access, request):
+        pi = base.ProjectImporter(mock.Mock())
+        require_access.side_effect = HTTPUnauthorized
+
+        c.show_login_overlay = False
+        request.path = '/test-importer/'
+        pi._check_security()
+        self.assertEqual(c.show_login_overlay, True)
+
+        c.show_login_overlay = False
+        request.path = '/test-importer/check_names/'
+        pi._check_security()
+        self.assertEqual(c.show_login_overlay, True)
+
+        c.show_login_overlay = False
+        request.path = '/test-importer/process/'
+        with td.raises(HTTPUnauthorized):
+            pi._check_security()
+        self.assertEqual(c.show_login_overlay, False)
+
 
 
 TA1 = mock.Mock(tool_label='foo', tool_description='foo_desc')


[46/50] git commit: [#6529] Added docstring and example config entry for login_overlay

Posted by jo...@apache.org.
[#6529] Added docstring and example config entry for login_overlay

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/a1779fa8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/a1779fa8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/a1779fa8

Branch: refs/heads/cj/6422
Commit: a1779fa8d9ff0cabf61399fe7911a5d7b351b306
Parents: b930a63
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Sep 16 20:54:58 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 16 22:34:13 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/helpers.py | 35 +++++++++++++++++++++++++++++++++++
 Allura/development.ini       |  1 +
 2 files changed, 36 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a1779fa8/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 0b92968..76bedbc 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -1017,6 +1017,41 @@ def daterange(start_date, end_date):
 
 @contextmanager
 def login_overlay(exceptions=None):
+    """
+    Override the default behavior of redirecting to the auth.login_url and
+    instead display an overlay with content from auth.login_fragment_url.
+
+    This is to allow pages that require authentication for any actions but
+    not for the initial view to be more apparent what you will get once
+    logged in.
+
+    This should be wrapped around call to `require_access()` (presumably in
+    the `_check_security()` method on a controller).  The `exceptions` param
+    can be given a list of exposed views to leave with the original behavior.
+
+    For example:
+
+        class MyController(BaseController);
+            def _check_security(self):
+                with login_overlay(exceptions=['process']):
+                    require_access(self.neighborhood, 'register')
+
+            @expose
+            def index(self, *args, **kw):
+                return {}
+
+            @expose
+            def list(self, *args, **kw):
+                return {}
+
+            @expose
+            def process(self, *args, **kw):
+                return {}
+
+    This would show the overlay to unauthenticated users who visit `/`
+    or `/list` but would perform the normal redirect when `/process` is
+    visited.
+    """
     try:
         yield
     except HTTPUnauthorized as e:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a1779fa8/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index ee9911b..9cb4b16 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -78,6 +78,7 @@ show_export_control = false
 auth.method = local
 # auth.login_url = /auth/
 # auth.logout_url = /auth/logout
+# auth.login_fragment_url = /auth/login_fragment
 
 auth.ldap.server = ldap://localhost
 auth.ldap.suffix = ou=people,dc=localdomain


[16/50] git commit: [#6640] Can't post vote counts with ticket update

Posted by jo...@apache.org.
[#6640] Can't post vote counts with ticket update

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/6bfdafdd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/6bfdafdd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/6bfdafdd

Branch: refs/heads/cj/6422
Commit: 6bfdafddccbb8abb0a1925c2ede6979ff7b18e0a
Parents: c0b098c
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Sep 10 13:33:37 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 13:33:37 2013 +0000

----------------------------------------------------------------------
 ForgeTracker/forgetracker/tests/functional/test_rest.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6bfdafdd/ForgeTracker/forgetracker/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_rest.py b/ForgeTracker/forgetracker/tests/functional/test_rest.py
index f6dd061..750bd0e 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_rest.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_rest.py
@@ -88,7 +88,8 @@ class TestRestUpdateTicket(TestTrackerApiBase):
     def test_update_ticket(self):
         args = dict(self.ticket_args, summary='test update ticket', labels='',
                     assigned_to=self.ticket_args['assigned_to_id'] or '')
-        for bad_key in ('ticket_num', 'assigned_to_id', 'created_date', 'reported_by', 'reported_by_id', '_id'):
+        for bad_key in ('ticket_num', 'assigned_to_id', 'created_date',
+                'reported_by', 'reported_by_id', '_id', 'votes_up', 'votes_down'):
             del args[bad_key]
         args['private'] = str(args['private'])
         ticket_view = self.api_post('/rest/p/test/bugs/1/save', wrap_args='ticket_form', **h.encode_keys(args))


[49/50] git commit: [#5966] remove SF-internal references; PEP-8 cleanup; determine base_url automatically

Posted by jo...@apache.org.
[#5966] remove SF-internal references; PEP-8 cleanup; determine base_url automatically


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

Branch: refs/heads/cj/6422
Commit: 21b2c16d6e4438d441ee72b3b20a8ac5537e7ae6
Parents: 1b62fd9
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 11 22:12:59 2013 +0000
Committer: Cory Johns <cj...@slashdotmedia.com>
Committed: Tue Sep 17 17:00:13 2013 +0000

----------------------------------------------------------------------
 scripts/wiki-copy.py | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/21b2c16d/scripts/wiki-copy.py
----------------------------------------------------------------------
diff --git a/scripts/wiki-copy.py b/scripts/wiki-copy.py
index bca726d..35e0077 100644
--- a/scripts/wiki-copy.py
+++ b/scripts/wiki-copy.py
@@ -17,7 +17,6 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-import re
 import os
 import sys
 import urllib
@@ -31,20 +30,16 @@ import oauth2 as oauth
 
 
 def main():
-    cp = ConfigParser()
-    cp.read('/var/local/allura/Allura/production.ini')
-
     op = OptionParser(usage='usage: %prog [options]')
-    op.add_option('-u', '--base-url', action='store', dest='base_url',
-            default=cp.get('app:main', 'base_url'), help='URL of API to upload to [default: %default]')
-    op.add_option('-D', '--debug', action='store_true', dest='debug', default=False)
     op.add_option('-f', '--from-wiki', action='store', dest='from_wiki',
-            help='URL of wiki to copy from like http://fromserver.com/rest/p/test/wiki/')
+                  help='URL of wiki API to copy from like http://fromserver.com/rest/p/test/wiki/')
     op.add_option('-t', '--to-wiki', action='store', dest='to_wiki',
-            help='URL of wiki to copy to like http://toserver.com/rest/p/test/wiki/')
+                  help='URL of wiki API to copy to like http://toserver.com/rest/p/test/wiki/')
+    op.add_option('-D', '--debug', action='store_true', dest='debug', default=False)
     (options, args) = op.parse_args(sys.argv[1:])
 
-    oauth_client = make_oauth_client(options.base_url)
+    base_url = options.to_wiki.split('/rest/')[0]
+    oauth_client = make_oauth_client(base_url)
 
     wiki_data = urllib.urlopen(options.from_wiki).read()
     wiki_json = json.loads(wiki_data)['pages']
@@ -67,20 +62,18 @@ def main():
             print "Error processing " + p
             raise
 
+
 def make_oauth_client(base_url):
     """
     Build an oauth.Client with which callers can query Allura.
-
-    Based on Allura, sfpy, and sfx push scripts
     """
-
+    config_file = os.path.join(os.environ['HOME'], '.allurarc')
     cp = ConfigParser()
-    cp.read(os.path.join(os.environ['HOME'], '.convertrc'))
+    cp.read(config_file)
 
-    # https://sourceforge.net/p/forge/documentation/API%20-%20Beta/
     REQUEST_TOKEN_URL = base_url+'/rest/oauth/request_token'
-    AUTHORIZE_URL =     base_url+'/rest/oauth/authorize'
-    ACCESS_TOKEN_URL =  base_url+'/rest/oauth/access_token'
+    AUTHORIZE_URL = base_url+'/rest/oauth/authorize'
+    ACCESS_TOKEN_URL = base_url+'/rest/oauth/access_token'
     oauth_key = option(cp, base_url, 'oauth_key', 'Forge API OAuth Key (%s/auth/oauth/): ' % base_url)
     oauth_secret = option(cp, base_url, 'oauth_secret', 'Forge API Oauth Secret: ')
     consumer = oauth.Consumer(oauth_key, oauth_secret)
@@ -114,14 +107,16 @@ def make_oauth_client(base_url):
         cp.set(base_url, 'oauth_token_secret', oauth_token_secret)
 
     # save oauth token for later use
-    cp.write(open(os.path.join(os.environ['HOME'], '.convertrc'), 'w'))
+    cp.write(open(config_file, 'w'))
+    print 'Saving oauth tokens in {} for later re-use'.format(config_file)
+    print
 
     access_token = oauth.Token(oauth_token, oauth_token_secret)
     oauth_client = oauth.Client(consumer, access_token)
     return oauth_client
 
+
 def option(cp, section, key, prompt=None):
-    """ shared (copy/paste) between Allura & sfpy """
     if not cp.has_section(section):
         cp.add_section(section)
     if cp.has_option(section, key):


[06/50] git commit: [#6541] Revert to exact match on import_id and fix ImportIdConverter docstring

Posted by jo...@apache.org.
[#6541] Revert to exact match on import_id and fix ImportIdConverter 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/44b2a366
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/44b2a366
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/44b2a366

Branch: refs/heads/cj/6422
Commit: 44b2a36672d086a9175806a91622edcbe231ae1c
Parents: 59a395d
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Fri Sep 6 17:56:55 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 9 20:27:30 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/plugin.py               | 4 ++--
 ForgeTracker/forgetracker/tracker_main.py | 9 ++++-----
 2 files changed, 6 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/44b2a366/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 3376034..8e24cb2 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -955,10 +955,10 @@ class ImportIdConverter(object):
 
     To provide a new converter, expose an entry point in setup.py:
 
-        [allura.tickets.import_id_converter]
+        [allura.import_id_converter]
         mysource = foo.bar:SourceIdConverter
 
-    Then in your .ini file, set tickets.import_id_converter=mysource
+    Then in your .ini file, set import_id_converter=mysource
     '''
 
     @classmethod

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/44b2a366/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 3afdb15..61f7a99 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1196,11 +1196,10 @@ class TicketController(BaseController, FeedController):
             self.ticket = TM.Ticket.query.get(app_config_id=c.app.config._id,
                                                     ticket_num=self.ticket_num)
             if self.ticket is None:
-                query = {'app_config_id': c.app.config._id}
-                import_id = ImportIdConverter.get().expand(ticket_num, c.app)
-                if import_id:
-                    query.update({'import_id.%s' % k: v for k,v in import_id.iteritems()})
-                self.ticket = TM.Ticket.query.get(**query)
+                self.ticket = TM.Ticket.query.get(
+                        app_config_id = c.app.config._id,
+                        import_id = ImportIdConverter.get().expand(ticket_num, c.app),
+                    )
                 if self.ticket is not None:
                     utils.permanent_redirect(self.ticket.url())
                 else:


[40/50] git commit: [#6540] Added rate limiting on tool imports

Posted by jo...@apache.org.
[#6540] Added rate limiting on tool imports

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/3c0a7e0f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/3c0a7e0f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/3c0a7e0f

Branch: refs/heads/cj/6422
Commit: 3c0a7e0f5fd179096d48239e3db8c014960a2181
Parents: cd1be45
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Sep 9 22:35:20 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Sep 12 19:56:41 2013 +0000

----------------------------------------------------------------------
 ForgeImporters/forgeimporters/base.py           | 44 +++++++++++++++++++-
 ForgeImporters/forgeimporters/github/code.py    | 19 +++++----
 .../forgeimporters/github/tests/test_code.py    | 20 +++++++++
 ForgeImporters/forgeimporters/google/code.py    | 17 ++++----
 .../forgeimporters/google/tests/test_code.py    | 18 ++++++++
 ForgeImporters/forgeimporters/google/tracker.py | 19 +++++----
 .../forgeimporters/tests/google/test_tracker.py | 20 ++++++++-
 .../forgeimporters/trac/tests/test_tickets.py   | 18 ++++++++
 ForgeImporters/forgeimporters/trac/tickets.py   | 19 +++++----
 9 files changed, 160 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3c0a7e0f/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index ffb1650..d7479b3 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -68,14 +68,16 @@ class ToolImportForm(schema.Schema):
 
 
 class ImportErrorHandler(object):
-    def __init__(self, importer, project_name):
+    def __init__(self, importer, project_name, project):
         self.importer = importer
         self.project_name = project_name
+        self.project = project
 
     def __enter__(self):
         pass
 
     def __exit__(self, exc_type, exc_val, exc_tb):
+        self.importer.clear_pending(self.project)
         if exc_type:
             g.post_event('import_tool_task_failed',
                 error=str(exc_val),
@@ -89,7 +91,7 @@ class ImportErrorHandler(object):
 @task(notifications_disabled=True)
 def import_tool(importer_name, project_name=None, mount_point=None, mount_label=None, **kw):
     importer = ToolImporter.by_name(importer_name)
-    with ImportErrorHandler(importer, project_name):
+    with ImportErrorHandler(importer, project_name, c.project):
         importer.import_tool(c.project, c.user, project_name=project_name,
                 mount_point=mount_point, mount_label=mount_label, **kw)
 
@@ -326,6 +328,44 @@ class ToolImporter(object):
                 importers[ep.name] = importer()
         return importers
 
+    @property
+    def classname(self):
+        return self.__class__.__name__
+
+    def enforce_limit(self, project):
+        """
+        Enforce rate limiting of tool imports on a given project.
+
+        Returns False if limit is met / exceeded.  Otherwise, increments the
+        count of pending / in-progress imports and returns True.
+        """
+        limit = config.get('tool_import.rate_limit', 1)
+        pending_key = 'tool_data.%s.pending' % self.classname
+        modified_project = M.Project.query.find_and_modify(
+                query={
+                        '_id': project._id,
+                        '$or': [
+                                {pending_key: None},
+                                {pending_key: {'$lt': limit}},
+                            ],
+                    },
+                update={'$inc': {pending_key: 1}},
+                new=True,
+            )
+        return modified_project is not None
+
+    def clear_pending(self, project):
+        """
+        Decrement the pending counter for this importer on the given project,
+        to indicate that an import is complete.
+        """
+        pending_key = 'tool_data.%s.pending' % self.classname
+        M.Project.query.find_and_modify(
+                query={'_id': project._id},
+                update={'$inc': {pending_key: -1}},
+                new=True,
+            )
+
     def import_tool(self, project, user, project_name=None,
             mount_point=None, mount_label=None, **kw):
         """

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3c0a7e0f/ForgeImporters/forgeimporters/github/code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/github/code.py b/ForgeImporters/forgeimporters/github/code.py
index 92e5626..aa5fe7d 100644
--- a/ForgeImporters/forgeimporters/github/code.py
+++ b/ForgeImporters/forgeimporters/github/code.py
@@ -45,7 +45,7 @@ from forgeimporters.github import GitHubProjectExtractor
 @task(notifications_disabled=True)
 def import_tool(**kw):
     importer = GitHubRepoImporter()
-    with ImportErrorHandler(importer, kw.get('project_name')):
+    with ImportErrorHandler(importer, kw.get('project_name'), c.project):
         importer.import_tool(c.project, c.user, **kw)
 
 
@@ -73,13 +73,16 @@ class GitHubRepoImportController(BaseController):
     @require_post()
     @validate(GitHubRepoImportForm(ForgeGitApp), error_handler=index)
     def create(self, gh_project_name, gh_user_name, mount_point, mount_label, **kw):
-        import_tool.post(
-                project_name=gh_project_name,
-                user_name=gh_user_name,
-                mount_point=mount_point,
-                mount_label=mount_label)
-        flash('Repo import has begun. Your new repo will be available '
-                'when the import is complete.')
+        if GitHubRepoImporter().enforce_limit(c.project):
+            import_tool.post(
+                    project_name=gh_project_name,
+                    user_name=gh_user_name,
+                    mount_point=mount_point,
+                    mount_label=mount_label)
+            flash('Repo import has begun. Your new repo will be available '
+                    'when the import is complete.')
+        else:
+            flash('There are too many imports pending at this time.  Please wait and try again.', 'error')
         redirect(c.project.url() + 'admin/')
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3c0a7e0f/ForgeImporters/forgeimporters/github/tests/test_code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/github/tests/test_code.py b/ForgeImporters/forgeimporters/github/tests/test_code.py
index 09afa87..729d8c5 100644
--- a/ForgeImporters/forgeimporters/github/tests/test_code.py
+++ b/ForgeImporters/forgeimporters/github/tests/test_code.py
@@ -17,9 +17,11 @@
 
 from unittest import TestCase
 from mock import Mock, patch
+from ming.odm import ThreadLocalORMSession
 
 from allura.tests import TestController
 from allura.tests.decorators import with_tool
+from allura import model as M
 from forgeimporters.github.code import GitHubRepoImporter
 
 
@@ -76,3 +78,21 @@ class TestGitHubImportController(TestController, TestCase):
         self.assertEqual(u'mylabel', import_tool.post.call_args[1]['mount_label'])
         self.assertEqual(u'poop', import_tool.post.call_args[1]['project_name'])
         self.assertEqual(u'spooky', import_tool.post.call_args[1]['user_name'])
+
+    @with_git
+    @patch('forgeimporters.github.code.import_tool')
+    def test_create_limit(self, import_tool):
+        project = M.Project.query.get(shortname=test_project_with_repo)
+        project.set_tool_data('GitHubRepoImporter', pending=1)
+        ThreadLocalORMSession.flush_all()
+        params = dict(
+                gh_user_name='spooky',
+                gh_project_name='poop',
+                mount_label='mylabel',
+                mount_point='mymount',
+                )
+        r = self.app.post('/p/{}/admin/ext/import/github-repo/create'.format(test_project_with_repo),
+                params,
+                status=302).follow()
+        self.assertIn('Please wait and try again', r)
+        self.assertEqual(import_tool.post.call_count, 0)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3c0a7e0f/ForgeImporters/forgeimporters/google/code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/code.py b/ForgeImporters/forgeimporters/google/code.py
index 134ecb6..f8e42b3 100644
--- a/ForgeImporters/forgeimporters/google/code.py
+++ b/ForgeImporters/forgeimporters/google/code.py
@@ -88,7 +88,7 @@ def get_repo_class(type_):
 @task(notifications_disabled=True)
 def import_tool(**kw):
     importer = GoogleRepoImporter()
-    with ImportErrorHandler(importer, kw.get('project_name')):
+    with ImportErrorHandler(importer, kw.get('project_name'), c.project):
         importer.import_tool(c.project, c.user, **kw)
 
 
@@ -140,12 +140,15 @@ class GoogleRepoImportController(BaseController):
     @require_post()
     @validate(GoogleRepoImportForm(), error_handler=index)
     def create(self, gc_project_name, mount_point, mount_label, **kw):
-        import_tool.post(
-                project_name=gc_project_name,
-                mount_point=mount_point,
-                mount_label=mount_label)
-        flash('Repo import has begun. Your new repo will be available '
-                'when the import is complete.')
+        if GoogleRepoImporter().enforce_limit(c.project):
+            import_tool.post(
+                    project_name=gc_project_name,
+                    mount_point=mount_point,
+                    mount_label=mount_label)
+            flash('Repo import has begun. Your new repo will be available '
+                    'when the import is complete.')
+        else:
+            flash('There are too many imports pending at this time.  Please wait and try again.', 'error')
         redirect(c.project.url() + 'admin/')
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3c0a7e0f/ForgeImporters/forgeimporters/google/tests/test_code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tests/test_code.py b/ForgeImporters/forgeimporters/google/tests/test_code.py
index 806a004..96dd687 100644
--- a/ForgeImporters/forgeimporters/google/tests/test_code.py
+++ b/ForgeImporters/forgeimporters/google/tests/test_code.py
@@ -17,9 +17,11 @@
 
 from unittest import TestCase
 from mock import Mock, patch
+from ming.odm import ThreadLocalORMSession
 
 from allura.tests import TestController
 from allura.tests.decorators import with_tool
+from allura import model as M
 
 
 # important to be distinct from 'test' which ForgeSVN uses, so that the tests can run in parallel and not clobber each other
@@ -113,3 +115,19 @@ class TestGoogleRepoImportController(TestController, TestCase):
         self.assertEqual(u'mymount', import_tool.post.call_args[1]['mount_point'])
         self.assertEqual(u'mylabel', import_tool.post.call_args[1]['mount_label'])
         self.assertEqual(u'poop', import_tool.post.call_args[1]['project_name'])
+
+    @with_svn
+    @patch('forgeimporters.google.code.import_tool')
+    def test_create_limit(self, import_tool):
+        project = M.Project.query.get(shortname=test_project_with_repo)
+        project.set_tool_data('GoogleRepoImporter', pending=1)
+        ThreadLocalORMSession.flush_all()
+        params = dict(gc_project_name='poop',
+                mount_label='mylabel',
+                mount_point='mymount',
+                )
+        r = self.app.post('/p/{}/admin/src/_importer/create'.format(test_project_with_repo),
+                params,
+                status=302).follow()
+        self.assertIn('Please wait and try again', r)
+        self.assertEqual(import_tool.post.call_count, 0)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3c0a7e0f/ForgeImporters/forgeimporters/google/tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tracker.py b/ForgeImporters/forgeimporters/google/tracker.py
index 9c259dd..d52945e 100644
--- a/ForgeImporters/forgeimporters/google/tracker.py
+++ b/ForgeImporters/forgeimporters/google/tracker.py
@@ -54,7 +54,7 @@ from forgeimporters.base import (
 @task(notifications_disabled=True)
 def import_tool(**kw):
     importer = GoogleCodeTrackerImporter()
-    with ImportErrorHandler(importer, kw.get('project_name')):
+    with ImportErrorHandler(importer, kw.get('project_name'), c.project):
         importer.import_tool(c.project, c.user, **kw)
 
 
@@ -81,13 +81,16 @@ class GoogleCodeTrackerImportController(BaseController):
     @require_post()
     @validate(GoogleCodeTrackerImportForm(ForgeTrackerApp), error_handler=index)
     def create(self, gc_project_name, mount_point, mount_label, **kw):
-        import_tool.post(
-                project_name=gc_project_name,
-                mount_point=mount_point,
-                mount_label=mount_label,
-                )
-        flash('Ticket import has begun. Your new tracker will be available '
-                'when the import is complete.')
+        if GoogleCodeTrackerImporter().enforce_limit(c.project):
+            import_tool.post(
+                    project_name=gc_project_name,
+                    mount_point=mount_point,
+                    mount_label=mount_label,
+                    )
+            flash('Ticket import has begun. Your new tracker will be available '
+                    'when the import is complete.')
+        else:
+            flash('There are too many imports pending at this time.  Please wait and try again.', 'error')
         redirect(c.project.url() + 'admin/')
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3c0a7e0f/ForgeImporters/forgeimporters/tests/google/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
index d795bab..98216f9 100644
--- a/ForgeImporters/forgeimporters/tests/google/test_tracker.py
+++ b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
@@ -17,13 +17,16 @@
 
 from datetime import datetime
 from unittest import TestCase
+
 import mock
 from mock import patch
+from ming.odm import ThreadLocalORMSession
 
 from allura.tests import TestController
 from allura.tests.decorators import with_tracker
 
-from ...google import tracker
+from allura import model as M
+from forgeimporters.google import tracker
 
 
 class TestTrackerImporter(TestCase):
@@ -299,3 +302,18 @@ class TestGoogleCodeTrackerImportController(TestController, TestCase):
         self.assertEqual(u'mymount', import_tool.post.call_args[1]['mount_point'])
         self.assertEqual(u'mylabel', import_tool.post.call_args[1]['mount_label'])
         self.assertEqual(u'test', import_tool.post.call_args[1]['project_name'])
+
+    @with_tracker
+    @patch('forgeimporters.google.tracker.import_tool')
+    def test_create_limit(self, import_tool):
+        project = M.Project.query.get(shortname='test')
+        project.set_tool_data('GoogleCodeTrackerImporter', pending=1)
+        ThreadLocalORMSession.flush_all()
+        params = dict(gc_project_name='test',
+                mount_label='mylabel',
+                mount_point='mymount',
+                )
+        r = self.app.post('/p/test/admin/bugs/_importer/create', params,
+                status=302).follow()
+        self.assertIn('Please wait and try again', r)
+        self.assertEqual(import_tool.post.call_count, 0)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3c0a7e0f/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/trac/tests/test_tickets.py b/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
index 92e7854..b3d2fcb 100644
--- a/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
+++ b/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
@@ -18,12 +18,14 @@
 import json
 from unittest import TestCase
 from mock import Mock, patch
+from ming.orm import ThreadLocalORMSession
 
 from tg import config
 
 from allura.tests import TestController
 from allura.tests.decorators import with_tracker
 
+from allura import model as M
 from forgeimporters.trac.tickets import (
     TracTicketImporter,
     TracTicketImportController,
@@ -132,3 +134,19 @@ class TestTracTicketImportController(TestController, TestCase):
         self.assertEqual(u'mylabel', import_tool.post.call_args[1]['mount_label'])
         self.assertEqual('{"orig_user": "new_user"}', import_tool.post.call_args[1]['user_map'])
         self.assertEqual(u'http://example.com/trac/url', import_tool.post.call_args[1]['trac_url'])
+
+    @with_tracker
+    @patch('forgeimporters.trac.tickets.import_tool')
+    def test_create_limit(self, import_tool):
+        project = M.Project.query.get(shortname='test')
+        project.set_tool_data('TracTicketImporter', pending=1)
+        ThreadLocalORMSession.flush_all()
+        params = dict(trac_url='http://example.com/trac/url',
+                mount_label='mylabel',
+                mount_point='mymount',
+                )
+        r = self.app.post('/p/test/admin/bugs/_importer/create', params,
+                upload_files=[('user_map', 'myfile', '{"orig_user": "new_user"}')],
+                status=302).follow()
+        self.assertIn('Please wait and try again', r)
+        self.assertEqual(import_tool.post.call_count, 0)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3c0a7e0f/ForgeImporters/forgeimporters/trac/tickets.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/trac/tickets.py b/ForgeImporters/forgeimporters/trac/tickets.py
index 9e4f493..cafd403 100644
--- a/ForgeImporters/forgeimporters/trac/tickets.py
+++ b/ForgeImporters/forgeimporters/trac/tickets.py
@@ -61,7 +61,7 @@ from forgetracker.scripts.import_tracker import import_tracker
 @task(notifications_disabled=True)
 def import_tool(**kw):
     importer = TracTicketImporter()
-    with ImportErrorHandler(importer, kw.get('trac_url')):
+    with ImportErrorHandler(importer, kw.get('trac_url'), c.project):
         importer.import_tool(c.project, c.user, **kw)
 
 
@@ -89,13 +89,16 @@ class TracTicketImportController(BaseController):
     @require_post()
     @validate(TracTicketImportForm(ForgeTrackerApp), error_handler=index)
     def create(self, trac_url, mount_point, mount_label, user_map=None, **kw):
-        import_tool.post(
-                mount_point=mount_point,
-                mount_label=mount_label,
-                trac_url=trac_url,
-                user_map=user_map)
-        flash('Ticket import has begun. Your new tracker will be available '
-                'when the import is complete.')
+        if TracTicketImporter().enforce_limit(c.project):
+            import_tool.post(
+                    mount_point=mount_point,
+                    mount_label=mount_label,
+                    trac_url=trac_url,
+                    user_map=user_map)
+            flash('Ticket import has begun. Your new tracker will be available '
+                    'when the import is complete.')
+        else:
+            flash('There are too many imports pending at this time.  Please wait and try again.', 'error')
         redirect(c.project.url() + 'admin/')
 
 


[30/50] git commit: [#6545] tests

Posted by jo...@apache.org.
[#6545] tests


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

Branch: refs/heads/cj/6422
Commit: 021ee37fc6369d14c22be587bf5874362f38fb98
Parents: 88b3fad
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Sep 6 21:05:29 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 14:36:31 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/test_helpers.py             |  7 +++-
 .../tests/functional/test_forum.py              | 43 ++++++++++++++++++++
 2 files changed, 49 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/021ee37f/Allura/allura/tests/test_helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_helpers.py b/Allura/allura/tests/test_helpers.py
index e9bc8f9..d4e5a0c 100644
--- a/Allura/allura/tests/test_helpers.py
+++ b/Allura/allura/tests/test_helpers.py
@@ -19,8 +19,9 @@
 
 from unittest import TestCase
 from os import path
-from mock import Mock, patch
+from datetime import datetime
 
+from mock import Mock, patch
 from pylons import tmpl_context as c
 from nose.tools import eq_, assert_equals
 from IPython.testing.decorators import skipif, module_not_available
@@ -428,3 +429,7 @@ def test_absurl_no_request():
 def test_absurl_with_request():
     assert_equals(h.absurl('/p/test/foobar'), 'https://www.mysite.com/p/test/foobar')
 
+
+def test_daterange():
+    assert_equals(list(h.daterange(datetime(2013, 1, 1), datetime(2013, 1, 4))),
+                 [datetime(2013, 1, 1), datetime(2013, 1, 2), datetime(2013, 1, 3)])
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/021ee37f/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 12238c8..7980bee 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -762,3 +762,46 @@ class TestForum(TestController):
         assert u'téstforum'.encode('utf-8') in r
         r = self.app.get(u'/p/test/discussion/create_topic/téstforum/'.encode('utf-8'))
         assert u'<option value="téstforum" selected>Tést Forum</option>' in r
+
+
+class TestForumStats(TestController):
+
+    def test_stats(self):
+        self.app.get('/discussion/stats', status=200)
+
+    @mock.patch('ming.session.Session.aggregate')  # mim doesn't support aggregate
+    def test_stats_data(self, aggregate):
+        # partial data, some days are implicit 0
+        aggregate.return_value = {'result': [
+            {"_id": {
+                "year": 2013,
+                "month": 1,
+                "day": 2},
+             "posts": 3
+            },
+            {"_id": {
+                "year": 2013,
+                "month": 1,
+                "day": 3},
+             "posts": 5
+            },
+            {"_id": {
+                "year": 2013,
+                "month": 1,
+                "day": 5},
+             "posts": 2
+            },
+        ]}
+        r = self.app.get('/discussion/stats_data?begin=2013-01-01&end=2013-01-06')
+        assert_equal(r.json, {
+            'begin': '2013-01-01 00:00:00',
+            'end': '2013-01-06 00:00:00',
+            'data': [
+                [1356998400000, 0],
+                [1357084800000, 3],
+                [1357171200000, 5],
+                [1357257600000, 0],
+                [1357344000000, 2],
+                [1357430400000, 0],
+            ]
+        })


[18/50] git commit: [#6626] ticket:427 Use HEAD revision as default for SVN

Posted by jo...@apache.org.
[#6626] ticket:427 Use HEAD revision as default for SVN


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

Branch: refs/heads/cj/6422
Commit: 43f055caac9cd5e1e049922f2db27d3f73f4b0e9
Parents: 6bfdafd
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Mon Sep 9 13:52:29 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 13:34:15 2013 +0000

----------------------------------------------------------------------
 ForgeSVN/forgesvn/controllers.py                       | 3 +--
 ForgeSVN/forgesvn/tests/functional/test_controllers.py | 5 +++++
 2 files changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/43f055ca/ForgeSVN/forgesvn/controllers.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/controllers.py b/ForgeSVN/forgesvn/controllers.py
index 44d1a69..62f3d55 100644
--- a/ForgeSVN/forgesvn/controllers.py
+++ b/ForgeSVN/forgesvn/controllers.py
@@ -38,9 +38,8 @@ class BranchBrowser(repository.BranchBrowser, FeedController):
         latest = c.app.repo.latest(branch=self._branch)
         if is_empty or not latest:
             return dict(allow_fork=False, log=[], is_empty=is_empty)
-        redirect(c.app.repo.url_for_commit(c.app.default_branch_name) + 'tree/')
+        redirect('%s/tree/' % c.app.default_branch_name)
 
     @expose()
     def _lookup(self, rev, *remainder):
         return repository.CommitBrowser(rev), remainder
-

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/43f055ca/ForgeSVN/forgesvn/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeSVN/forgesvn/tests/functional/test_controllers.py b/ForgeSVN/forgesvn/tests/functional/test_controllers.py
index ae8c86d..691bd2e 100644
--- a/ForgeSVN/forgesvn/tests/functional/test_controllers.py
+++ b/ForgeSVN/forgesvn/tests/functional/test_controllers.py
@@ -59,6 +59,11 @@ class SVNTestController(TestController):
 
 
 class TestRootController(SVNTestController):
+
+    def test_head(self):
+        r = self.app.get('/src/')
+        assert r.location.endswith('/src/HEAD/tree/')
+
     def test_status(self):
         resp = self.app.get('/src/status')
         d = json.loads(resp.body)


[37/50] git commit: [#6613] ticket:428 Tracker API include config & milestones & saved bins

Posted by jo...@apache.org.
[#6613]  ticket:428  Tracker API include config & milestones & saved bins


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

Branch: refs/heads/cj/6422
Commit: 023a0a34c9c106efe6fd640a93573c8a5ec3c2af
Parents: 224017c
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Thu Sep 12 14:48:43 2013 +0400
Committer: Yuriy Arhipov <yu...@yandex.ru>
Committed: Thu Sep 12 14:48:43 2013 +0400

----------------------------------------------------------------------
 ForgeTracker/forgetracker/model/ticket.py               |  2 +-
 ForgeTracker/forgetracker/tests/functional/test_rest.py | 11 +++++++++++
 ForgeTracker/forgetracker/tracker_main.py               |  3 +++
 3 files changed, 15 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/023a0a34/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 71fe6c5..f7534e9 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -513,7 +513,7 @@ class Bin(Artifact, ActivityObject):
         return result
 
     def __json__(self):
-        return dict(super(Bin,self).__json__(),
+        return dict(
             _id=self._id,
             summary=self.summary,
             terms=self.terms,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/023a0a34/ForgeTracker/forgetracker/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_rest.py b/ForgeTracker/forgetracker/tests/functional/test_rest.py
index 750bd0e..df0a422 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_rest.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_rest.py
@@ -84,6 +84,17 @@ class TestRestUpdateTicket(TestTrackerApiBase):
         assert len(tickets.json['tickets']) == 1, tickets.json
         assert (tickets.json['tickets'][0]
                 == dict(ticket_num=1, summary='test new ticket')), tickets.json['tickets'][0]
+        assert tickets.json['tracker_config']['options']['mount_point'] == 'bugs'
+        assert tickets.json['tracker_config']['options']['TicketMonitoringType'] == 'AllTicketChanges'
+        assert not tickets.json['tracker_config']['options']['EnableVoting']
+        assert tickets.json['tracker_config']['options']['TicketMonitoringEmail'] == 'test@localhost'
+        assert tickets.json['tracker_config']['options']['mount_label'] == 'Tickets'
+        assert tickets.json['saved_bins'][0]['sort'] == 'mod_date_dt desc'
+        assert tickets.json['saved_bins'][0]['terms'] == '!status:wont-fix && !status:closed'
+        assert tickets.json['saved_bins'][0]['summary'] == 'Changes'
+        assert len(tickets.json['saved_bins'][0]) == 4
+        assert tickets.json['milestones'][0]['name'] == '1.0'
+        assert tickets.json['milestones'][1]['name'] == '2.0'
 
     def test_update_ticket(self):
         args = dict(self.ticket_args, summary='test update ticket', labels='',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/023a0a34/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index df1e084..bc66e6c 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1583,6 +1583,9 @@ class RootRestController(BaseController):
                                         limit=int(limit), page=int(page))
         results['tickets'] = [dict(ticket_num=t.ticket_num, summary=t.summary)
                               for t in results['tickets']]
+        results['tracker_config'] = c.app.config
+        results['milestones'] = c.app.milestones
+        results['saved_bins'] = c.app.bins
         results.pop('q', None)
         results.pop('sort', None)
         return results


[14/50] git commit: [#6628] ticket:434 use generic "From address" in export emails for reply_to

Posted by jo...@apache.org.
[#6628]  ticket:434 use generic "From address" in export emails for reply_to


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

Branch: refs/heads/cj/6422
Commit: c0b098cf629e541d4a40116ae86c0e940877064e
Parents: e2840fe
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Tue Sep 10 14:20:07 2013 +0400
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Sep 10 13:04:26 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tasks/export_tasks.py | 2 +-
 Allura/allura/tests/test_tasks.py   | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c0b098cf/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index 8146b0f..ecd538c 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -92,7 +92,7 @@ def _bulk_export(project, tools, user):
     }
     email = {
         'fromaddr': unicode(tg.config['forgemail.return_path']),
-        'reply_to': unicode(user.email_address_header()),
+        'reply_to': unicode(tg.config['forgemail.return_path']),
         'message_id': h.gen_message_id(),
         'destinations': [unicode(user._id)],
         'subject': u'Bulk export for project %s completed' % project.shortname,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c0b098cf/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 9123fa3..af7898e 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -381,6 +381,7 @@ 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')
         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)


[09/50] git commit: [#6541] Added AuditLog on GC tracker import

Posted by jo...@apache.org.
[#6541] Added AuditLog on GC tracker import

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/ad81824e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/ad81824e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/ad81824e

Branch: refs/heads/cj/6422
Commit: ad81824eb88349296e5c5baa810b42923003d8e6
Parents: 4486642
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Wed Aug 28 19:38:10 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Sep 9 20:27:30 2013 +0000

----------------------------------------------------------------------
 ForgeImporters/forgeimporters/google/tracker.py        | 12 +++++++++---
 .../tests/google/functional/test_tracker.py            |  1 +
 .../forgeimporters/tests/google/test_tracker.py        | 13 ++++++++-----
 3 files changed, 18 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ad81824e/ForgeImporters/forgeimporters/google/tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tracker.py b/ForgeImporters/forgeimporters/google/tracker.py
index 58f28d2..cf6067e 100644
--- a/ForgeImporters/forgeimporters/google/tracker.py
+++ b/ForgeImporters/forgeimporters/google/tracker.py
@@ -24,9 +24,6 @@ from pylons import tmpl_context as c
 from pylons import app_globals as g
 from ming.orm import session, ThreadLocalORMSession
 
-from allura import model as M
-#import gdata
-gdata = None
 from tg import (
         expose,
         flash,
@@ -42,6 +39,7 @@ from allura.controllers import BaseController
 from allura.lib import helpers as h
 from allura.lib.plugin import ImportIdConverter
 from allura.lib.decorators import require_post, task
+from allura import model as M
 
 from forgetracker.tracker_main import ForgeTrackerApp
 from forgetracker import model as TM
@@ -142,6 +140,14 @@ class GoogleCodeTrackerImporter(ToolImporter):
                 app.globals.custom_fields = self.postprocess_custom_fields()
                 app.globals.last_ticket_num = self.max_ticket_num
                 ThreadLocalORMSession.flush_all()
+            M.AuditLog.log(
+                    'import tool %s from %s on %s' % (
+                            app.config.options.mount_point,
+                            project_name, self.source,
+                        ),
+                    project=project,
+                    user=user,
+                )
             g.post_event('project_updated')
             app.globals.invalidate_bin_counts()
             return app

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ad81824e/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
index 7f504a5..9f48257 100644
--- a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
+++ b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
@@ -50,6 +50,7 @@ class TestGCTrackerImporter(TestCase):
         self.assertIsNone(self.project.app_instance('test-issue'))
         with mock.patch.object(base.h, 'urlopen') as urlopen,\
              mock.patch.object(google.tracker, 'GoogleCodeProjectExtractor') as GPE,\
+             mock.patch.object(google.tracker.M, 'AuditLog') as AL,\
              mock.patch('forgetracker.tasks.update_bin_counts') as ubc:
             urlopen.side_effect = lambda req, **kw: mock.Mock(read=req.get_full_url, info=lambda:{'content-type': 'text/plain'})
             GPE.iter_issues.return_value = [(issue_id, issue)]

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ad81824e/ForgeImporters/forgeimporters/tests/google/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
index 05b33ae..8f434df 100644
--- a/ForgeImporters/forgeimporters/tests/google/test_tracker.py
+++ b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
@@ -42,12 +42,12 @@ class TestTrackerImporter(TestCase):
         importer.postprocess_custom_fields = mock.Mock()
         project, user = mock.Mock(), mock.Mock()
         app = project.install_app.return_value
-        app.config.options = {
-                'import_id': {
-                        'source': 'Google Code',
-                        'project_name': 'project_name',
-                    },
+        app.config.options.mount_point = 'mount_point'
+        app.config.options.import_id = {
+                'source': 'Google Code',
+                'project_name': 'project_name',
             }
+        app.config.options.get = lambda *a: getattr(app.config.options, *a)
         issues = gpe.iter_issues.return_value = [(50, mock.Mock()), (100, mock.Mock())]
         tickets = TM.Ticket.side_effect = [mock.Mock(), mock.Mock()]
 
@@ -89,6 +89,9 @@ class TestTrackerImporter(TestCase):
                 mock.call(tickets[1]),
             ])
         self.assertEqual(app.globals.last_ticket_num, 100)
+        M.AuditLog.log.assert_called_once_with(
+                'import tool mount_point from project_name on Google Code',
+                project=project, user=user)
         g.post_event.assert_called_once_with('project_updated')
         app.globals.invalidate_bin_counts.assert_called_once_with()