You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2013/09/17 21:11:59 UTC

[01/20] git commit: remove extraneous app_config_id index on Ticket

Updated Branches:
  refs/heads/db/5822 484d37176 -> a3d6db1df (forced update)


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/db/5822
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',
             ]


[17/20] git commit: [#5822] fix redirect after submitting the new task form

Posted by br...@apache.org.
[#5822] fix redirect after submitting the new task form


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

Branch: refs/heads/db/5822
Commit: d437bd2b67e6d9e635d52649fc329c24626fe250
Parents: 1e8670e
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 11 15:58:13 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Sep 17 18:02:58 2013 +0000

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


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d437bd2b/Allura/allura/controllers/site_admin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/site_admin.py b/Allura/allura/controllers/site_admin.py
index 0051a04..d7e7c0b 100644
--- a/Allura/allura/controllers/site_admin.py
+++ b/Allura/allura/controllers/site_admin.py
@@ -338,7 +338,7 @@ class TaskManagerController(object):
             config_dict['user'] = user
         with h.push_config(c, **config_dict):
             task = task.post(*args, **kw)
-        redirect('../view/%s' % task._id)
+        redirect('view/%s' % task._id)
 
     @expose()
     @require_post()


[08/20] git commit: [#6650] continue past invalid google code attachments

Posted by br...@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/db/5822
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):


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

Posted by br...@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/db/5822
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
                 ]
 


[18/20] git commit: [#5822] allow tasks with no arguments

Posted by br...@apache.org.
[#5822] allow tasks with no arguments


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

Branch: refs/heads/db/5822
Commit: 32f56eec2d2720eb5845ba17125767debe369738
Parents: d437bd2
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 11 15:58:38 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Sep 17 18:02:59 2013 +0000

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


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/32f56eec/Allura/allura/scripts/scripttask.py
----------------------------------------------------------------------
diff --git a/Allura/allura/scripts/scripttask.py b/Allura/allura/scripts/scripttask.py
index b686838..229bbe6 100644
--- a/Allura/allura/scripts/scripttask.py
+++ b/Allura/allura/scripts/scripttask.py
@@ -66,7 +66,7 @@ class ScriptTask(object):
         def __new__(meta, classname, bases, classDict):
             return task(type.__new__(meta, classname, bases, classDict))
 
-    def __new__(cls, arg_string):
+    def __new__(cls, arg_string=''):
         cls._execute_task(arg_string)
 
     @classmethod


[14/20] git commit: [#5966] start adding docs for our scripts

Posted by br...@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/db/5822
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


[11/20] git commit: [#6529] Added login overlay for project importers

Posted by br...@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/db/5822
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'])


[06/20] git commit: [#6540] Added rate limiting on tool imports

Posted by br...@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/db/5822
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/')
 
 


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

Posted by br...@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/db/5822
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)


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

Posted by br...@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/db/5822
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):


[07/20] git commit: [#6654] fix tracker stats, broken in [235614]

Posted by br...@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/db/5822
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


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

Posted by br...@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/db/5822
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)


[20/20] git commit: [#5822] add generic task for installing an app

Posted by br...@apache.org.
[#5822] add generic task for installing an app


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

Branch: refs/heads/db/5822
Commit: a3d6db1df621e4a4d2850bb3f8b987d563d28ecd
Parents: 0e945b3
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue Sep 17 17:58:30 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Sep 17 19:11:21 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tasks/admin_tasks.py | 37 +++++++++++++++++++++++++++++++++
 Allura/allura/tests/test_tasks.py  |  8 ++++++-
 Allura/docs/administration.rst     | 11 +++++++++-
 3 files changed, 54 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a3d6db1d/Allura/allura/tasks/admin_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/admin_tasks.py b/Allura/allura/tasks/admin_tasks.py
new file mode 100644
index 0000000..e8b67c0
--- /dev/null
+++ b/Allura/allura/tasks/admin_tasks.py
@@ -0,0 +1,37 @@
+#       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 inspect
+
+from pylons import tmpl_context as c
+
+from allura import model as M
+from allura.lib.decorators import task
+
+
+@task
+def install_app(*args, **kwargs):
+    '''
+    Install an application directly onto c.project, bypassing the UI and any app
+    constraints like installable=False
+    '''
+    c.project.install_app(*args, **kwargs)
+
+install_app.__doc__ += '''
+    Arguments: ''' + inspect.formatargspec(*inspect.getargspec(
+        M.Project.install_app
+    )).replace('self, ','')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a3d6db1d/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index af7898e..dcbde71 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -47,6 +47,7 @@ from allura.tasks import mail_tasks
 from allura.tasks import notification_tasks
 from allura.tasks import repo_tasks
 from allura.tasks import export_tasks
+from allura.tasks import admin_tasks
 from allura.tests import decorators as td
 from allura.lib.decorators import event_handler, task
 
@@ -372,7 +373,7 @@ class TestExportTasks(unittest.TestCase):
         project_json.assert_called_once()
         temp = '/tmp/bulk_export/p/test/test'
         zipfn = '/tmp/bulk_export/p/test/test.zip'
-        zipdir.assert_caled_with(temp, temp + '/test.zip')
+        zipdir.assert_called_with(temp, zipfn)
         shutil.rmtree.assert_called_once_with(temp)
         # check notification
         M.MonQTask.run_ready()
@@ -410,4 +411,9 @@ class TestExportTasks(unittest.TestCase):
         assert_equal(c.project.bulk_export_status(), 'busy')
 
 
+class TestAdminTasks(unittest.TestCase):
+
+    def test_install_app_docstring(self):
+        assert_in('ep_name, mount_point=None', admin_tasks.install_app.__doc__)
+
 Mapper.compile_all()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a3d6db1d/Allura/docs/administration.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/administration.rst b/Allura/docs/administration.rst
index b58339f..3874179 100644
--- a/Allura/docs/administration.rst
+++ b/Allura/docs/administration.rst
@@ -49,8 +49,17 @@ Scripts are in the `scripts/` directory and run via `paster script`.  An extra
 
     (env-allura) Allura$ paster script development.ini ../scripts/create-allura-sitemap.py -- -u 100
 
+TODO:   explain important scripts, commands
 
-TODO: explain how to run tasks, explain important scripts, commands and tasks here
+Tasks can be run via the web interface at /nf/admin/task_manager  You must know
+the full task name, e.g. `allura.tasks.admin_tasks.install_app`  You can
+optionally provide a username and project and app which will get set on the
+current context (`c`).  You should specify what args and kwargs will be passed
+as parameters to the task.  They are specified in JSON format on the form.
+
+See the listing of :mod:`some available tasks <allura.tasks.admin_tasks>`.
+
+TODO: explain how to run scripttasks and commandtasks
 
 
 Client Scripts


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

Posted by br...@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/db/5822
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')


[15/20] git commit: [#5966] add wiki-copy.py script

Posted by br...@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/db/5822
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()


[19/20] git commit: [#5822] allow routing to nbhd tools if the tool mount point is not a vaild project name

Posted by br...@apache.org.
[#5822] allow routing to nbhd tools if the tool mount point is not a vaild project name


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

Branch: refs/heads/db/5822
Commit: 0e945b3dea494655345c205461413a26c9252373
Parents: 32f56ee
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Sep 11 15:59:19 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Sep 17 18:02:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/project.py | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0e945b3d/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 9914dc9..e2c7ee8 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -85,9 +85,10 @@ class NeighborhoodController(object):
         provider = plugin.ProjectRegistrationProvider.get()
         try:
             provider.shortname_validator.to_python(pname, check_allowed=False, neighborhood=self.neighborhood)
-        except Invalid as e:
-            raise exc.HTTPNotFound, pname
-        project = M.Project.query.get(shortname=self.prefix + pname, neighborhood_id=self.neighborhood._id)
+        except Invalid:
+            project = None
+        else:
+            project = M.Project.query.get(shortname=self.prefix + pname, neighborhood_id=self.neighborhood._id)
         if project is None and self.prefix == 'u/':
             # create user-project if it is missing
             user = M.User.query.get(username=pname, disabled=False)


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

Posted by br...@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/db/5822
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/>


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

Posted by br...@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/db/5822
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]


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

Posted by br...@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/db/5822
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


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

Posted by br...@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/db/5822
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