You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by tv...@apache.org on 2013/08/28 21:30:45 UTC
[01/13] git commit: [#6526] Fix typo
Updated Branches:
refs/heads/master 09f02903f -> 6769dc236
[#6526] Fix typo
Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/6ff3125c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/6ff3125c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/6ff3125c
Branch: refs/heads/master
Commit: 6ff3125c01544dffb7fe63a5efd14439e7b6d72d
Parents: 8378ac0
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Tue Aug 27 13:38:31 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Aug 27 17:24:58 2013 +0000
----------------------------------------------------------------------
ForgeImporters/forgeimporters/google/__init__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6ff3125c/ForgeImporters/forgeimporters/google/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/__init__.py b/ForgeImporters/forgeimporters/google/__init__.py
index ad5f8e5..849f924 100644
--- a/ForgeImporters/forgeimporters/google/__init__.py
+++ b/ForgeImporters/forgeimporters/google/__init__.py
@@ -1,4 +1,4 @@
-# LNicensed to the Apache Software Foundation (ASF) under one
+# 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
[12/13] git commit: [#6611] provide mechanism to disable any allura
entry point
Posted by tv...@apache.org.
[#6611] provide mechanism to disable any allura entry point
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/1581f299
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/1581f299
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/1581f299
Branch: refs/heads/master
Commit: 1581f299c20aa4babfa8a5a1f781625e49534346
Parents: 10cb90c
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Aug 28 19:05:30 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 28 19:05:38 2013 +0000
----------------------------------------------------------------------
Allura/allura/command/base.py | 3 +--
Allura/allura/config/resources.py | 6 ++++--
Allura/allura/controllers/project.py | 4 ++--
Allura/allura/ext/admin/admin_main.py | 2 +-
Allura/allura/lib/app_globals.py | 2 +-
Allura/allura/lib/custom_middleware.py | 4 ++--
Allura/allura/lib/helpers.py | 12 +++++++++++-
Allura/allura/lib/package_path_loader.py | 7 +++----
Allura/allura/model/auth.py | 1 -
Allura/docs/extending.rst | 10 +++++++++-
ForgeImporters/forgeimporters/base.py | 10 ++++------
ForgeImporters/forgeimporters/tests/test_base.py | 8 ++++----
scripts/rethumb.py | 6 ++++--
13 files changed, 46 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/Allura/allura/command/base.py
----------------------------------------------------------------------
diff --git a/Allura/allura/command/base.py b/Allura/allura/command/base.py
index 536159d..38bb0d5 100644
--- a/Allura/allura/command/base.py
+++ b/Allura/allura/command/base.py
@@ -20,7 +20,6 @@ import sys
import logging
import shlex
from multiprocessing import Process
-from pkg_resources import iter_entry_points
import pylons
from paste.script import command
@@ -31,6 +30,7 @@ import activitystream
import ming
from allura.config.environment import load_environment
from allura.lib.decorators import task
+from allura.lib.helpers import iter_entry_points
log = None
@@ -117,4 +117,3 @@ class Command(command.Command):
def teardown_globals(self):
self.registry.cleanup()
-
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/Allura/allura/config/resources.py
----------------------------------------------------------------------
diff --git a/Allura/allura/config/resources.py b/Allura/allura/config/resources.py
index 9122687..6e231e4 100644
--- a/Allura/allura/config/resources.py
+++ b/Allura/allura/config/resources.py
@@ -20,6 +20,8 @@ import logging
import pkg_resources
+from allura.lib.helpers import iter_entry_points
+
log = logging.getLogger(__name__)
def register_ew_resources(manager):
@@ -29,7 +31,7 @@ def register_ew_resources(manager):
'css', pkg_resources.resource_filename('allura', 'lib/widgets/resources/css'))
manager.register_directory(
'allura', pkg_resources.resource_filename('allura', 'public/nf'))
- for ep in pkg_resources.iter_entry_points('allura'):
+ for ep in iter_entry_points('allura'):
try:
manager.register_directory(
'tool/%s' % ep.name.lower(),
@@ -39,7 +41,7 @@ def register_ew_resources(manager):
except ImportError:
log.warning('Cannot import entry point %s', ep)
raise
- for ep in pkg_resources.iter_entry_points('allura.theme'):
+ for ep in iter_entry_points('allura.theme'):
try:
theme = ep.load()
theme.register_ew_resources(manager, ep.name)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 5f293a6..9914dc9 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -20,7 +20,6 @@ import logging
from datetime import datetime, timedelta
from urllib import unquote
from itertools import chain, islice
-from pkg_resources import iter_entry_points
from bson import ObjectId
from tg import expose, flash, redirect, validate, request, response, config
@@ -38,6 +37,7 @@ from allura import model as M
from allura.app import SitemapEntry
from allura.lib.base import WsgiDispatchController
from allura.lib import helpers as h
+from allura.lib.helpers import iter_entry_points
from allura.lib import utils
from allura.lib.decorators import require_post
from allura.controllers.error import ErrorController
@@ -310,7 +310,7 @@ class ProjectController(FeedController):
for s in c.project.grouped_navbar_entries():
entry = dict(name=s.label, url=s.url, icon=s.ui_icon, tool_name=s.tool_name)
if s.children:
- entry['children'] = [dict(name=child.label, url=child.url, icon=child.ui_icon, tool_name=child.tool_name)
+ entry['children'] = [dict(name=child.label, url=child.url, icon=child.ui_icon, tool_name=child.tool_name)
for child in s.children]
menu.append(entry)
return dict(menu=menu)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/Allura/allura/ext/admin/admin_main.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/admin_main.py b/Allura/allura/ext/admin/admin_main.py
index 22bd228..314c3a9 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -292,7 +292,7 @@ class ProjectAdminController(BaseController):
'<input name="source_url">'
'<input type="submit">'
'</form>')
- for ep in pkg_resources.iter_entry_points('allura', repo_type):
+ for ep in h.iter_entry_points('allura', repo_type):
break
if ep is None or source_url is None:
raise exc.HTTPNotFound
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 7f45f69..276af63 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -178,7 +178,7 @@ class Globals(object):
# Cache some loaded entry points
def _cache_eps(section_name, dict_cls=dict):
d = dict_cls()
- for ep in pkg_resources.iter_entry_points(section_name):
+ for ep in h.iter_entry_points(section_name):
value = ep.load()
d[ep.name] = value
return d
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/Allura/allura/lib/custom_middleware.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/custom_middleware.py b/Allura/allura/lib/custom_middleware.py
index 4458c48..d4652ab 100644
--- a/Allura/allura/lib/custom_middleware.py
+++ b/Allura/allura/lib/custom_middleware.py
@@ -35,7 +35,7 @@ import allura.model.repo
log = logging.getLogger(__name__)
-tool_entry_points = list(pkg_resources.iter_entry_points('allura'))
+tool_entry_points = list(h.iter_entry_points('allura'))
class StaticFilesMiddleware(object):
'''Custom static file middleware
@@ -169,7 +169,7 @@ class SSLMiddleware(object):
if not resp:
resp = self.app
return resp(environ, start_response)
-
+
class AlluraTimerMiddleware(TimerMiddleware):
def timers(self):
import genshi
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index b7b0060..3715de6 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -49,7 +49,7 @@ from tg.decorators import before_validate
from formencode.variabledecode import variable_decode
import formencode
from jinja2 import Markup
-from paste.deploy.converters import asbool
+from paste.deploy.converters import asbool, aslist
from webhelpers import date, feedgenerator, html, number, misc, text
@@ -984,3 +984,13 @@ def plain2markdown(text, preserve_multiple_spaces=False, has_html_entities=False
text = re_angle_bracket_open.sub('<', text)
text = re_angle_bracket_close.sub('>', text)
return text
+
+
+def iter_entry_points(group, *a, **kw):
+ '''
+ yield entry points that have not been disabled in the config
+ '''
+ disabled = aslist(tg.config.get('disable_entry_points.' + group), sep=',')
+ for ep in pkg_resources.iter_entry_points(group, *a, **kw):
+ if ep.name not in disabled:
+ yield ep
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/Allura/allura/lib/package_path_loader.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/package_path_loader.py b/Allura/allura/lib/package_path_loader.py
index 9bee4c4..8272acf 100644
--- a/Allura/allura/lib/package_path_loader.py
+++ b/Allura/allura/lib/package_path_loader.py
@@ -124,12 +124,11 @@ The positioners are:
"""
import pkg_resources
import os
-from collections import defaultdict
import jinja2
from ming.utils import LazyProperty
-from allura.lib.helpers import topological_sort
+from allura.lib.helpers import topological_sort, iter_entry_points
class PackagePathLoader(jinja2.BaseLoader):
@@ -163,7 +162,7 @@ class PackagePathLoader(jinja2.BaseLoader):
paths = self.default_paths[:] # copy default_paths
paths[-1:0] = [ # insert all eps just before last item, by default
[ep.name, pkg_resources.resource_filename(ep.module_name, "")]
- for ep in pkg_resources.iter_entry_points(self.override_entrypoint)
+ for ep in iter_entry_points(self.override_entrypoint)
]
return paths
@@ -190,7 +189,7 @@ class PackagePathLoader(jinja2.BaseLoader):
"""
order_rules = []
replacement_rules = {}
- for ep in pkg_resources.iter_entry_points(self.override_entrypoint):
+ for ep in iter_entry_points(self.override_entrypoint):
for rule in getattr(ep.load(), 'template_path_rules', []):
if rule[0] == '>':
order_rules.append((ep.name, rule[1]))
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/Allura/allura/model/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index fb58ce9..b048ce6 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -28,7 +28,6 @@ from hashlib import sha256
import uuid
from pytz import timezone
from datetime import timedelta, date, datetime, time
-from pkg_resources import iter_entry_points
import iso8601
import pymongo
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/Allura/docs/extending.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/extending.rst b/Allura/docs/extending.rst
index a430202..6a6abe0 100644
--- a/Allura/docs/extending.rst
+++ b/Allura/docs/extending.rst
@@ -37,7 +37,15 @@ The available extension points for Allura are:
A listing of available 3rd-party extensions is at https://sourceforge.net/p/allura/wiki/Extensions/
-Other entry points are used to provider ``paster`` commands and ``easy_widget`` configuration.
+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.
+For example if you have ForgeImporter set up, but want to disable the google code importers::
+
+ disable_entry_points.allura.project_importers = google-code
+ disable_entry_points.allura.importers = google-code-tracker, google-code-repo
+
+Other entry points are used to provide ``paster`` commands and ``easy_widget`` configuration,
+which are not part of Allura but are used by Allura.
Event Handlers
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index bdff43b..7f25e69 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -20,8 +20,6 @@ import urllib
import urllib2
from collections import defaultdict
-from pkg_resources import iter_entry_points
-
from BeautifulSoup import BeautifulSoup
from tg import expose, validate, flash, redirect, config
from tg.decorators import with_trailing_slash
@@ -176,7 +174,7 @@ class ProjectImporter(BaseController):
as this project importer.
"""
tools = {}
- for ep in iter_entry_points('allura.importers'):
+ for ep in h.iter_entry_points('allura.importers'):
epv = ep.load()
if epv.source == self.source:
tools[ep.name] = epv()
@@ -289,7 +287,7 @@ class ToolImporter(object):
"""
Return a ToolImporter subclass instance given its entry-point name.
"""
- for ep in iter_entry_points('allura.importers', name):
+ for ep in h.iter_entry_points('allura.importers', name):
return ep.load()()
@staticmethod
@@ -298,7 +296,7 @@ class ToolImporter(object):
Return a ToolImporter subclass instance given its target_app class.
"""
importers = {}
- for ep in iter_entry_points('allura.importers'):
+ for ep in h.iter_entry_points('allura.importers'):
importer = ep.load()
if app in aslist(importer.target_app):
importers[ep.name] = importer()
@@ -370,7 +368,7 @@ class ProjectToolsImportController(object):
def index(self, *a, **kw):
importer_matrix = defaultdict(dict)
tools_with_importers = set()
- for ep in iter_entry_points('allura.importers'):
+ for ep in h.iter_entry_points('allura.importers'):
importer = ep.load()
for tool in aslist(importer.target_app):
tools_with_importers.add(tool.tool_label)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/ForgeImporters/forgeimporters/tests/test_base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/test_base.py b/ForgeImporters/forgeimporters/tests/test_base.py
index f1c93ad..92fb0cc 100644
--- a/ForgeImporters/forgeimporters/tests/test_base.py
+++ b/ForgeImporters/forgeimporters/tests/test_base.py
@@ -66,7 +66,7 @@ def ep(name, source=None, importer=None, **kw):
class TestProjectImporter(TestCase):
- @mock.patch.object(base, 'iter_entry_points')
+ @mock.patch.object(base.h, 'iter_entry_points')
def test_tool_importers(self, iep):
eps = iep.return_value = [ep('ep1', 'foo'), ep('ep2', 'bar'), ep('ep3', 'foo')]
pi = base.ProjectImporter(mock.Mock(name='neighborhood'))
@@ -100,7 +100,7 @@ class TI3(base.ToolImporter):
class TestToolImporter(TestCase):
- @mock.patch.object(base, 'iter_entry_points')
+ @mock.patch.object(base.h, 'iter_entry_points')
def test_by_name(self, iep):
eps = iep.return_value = [ep('my-name', 'my-source')]
importer = base.ToolImporter.by_name('my-name')
@@ -113,7 +113,7 @@ class TestToolImporter(TestCase):
iep.assert_called_once_with('allura.importers', 'other-name')
self.assertEqual(importer, None)
- @mock.patch.object(base, 'iter_entry_points')
+ @mock.patch.object(base.h, 'iter_entry_points')
def test_by_app(self, iep):
eps = iep.return_value = [
ep('importer1', importer=TI1),
@@ -190,7 +190,7 @@ class TestProjectToolsImportController(TestController):
def test_pages(self):
admin_page = self.app.get('/admin/')
- with mock.patch.object(base, 'iter_entry_points') as iep:
+ with mock.patch.object(base.h, 'iter_entry_points') as iep:
iep.return_value = [
ep('importer1', importer=TI1),
ep('importer2', importer=TI2),
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1581f299/scripts/rethumb.py
----------------------------------------------------------------------
diff --git a/scripts/rethumb.py b/scripts/rethumb.py
index 5f753ff..6ee190a 100644
--- a/scripts/rethumb.py
+++ b/scripts/rethumb.py
@@ -18,14 +18,16 @@
import sys
import time
-import pkg_resources
import PIL
import tg
from pylons import tmpl_context as c
from paste.deploy.converters import asint
from ming.orm import mapper, ThreadLocalORMSession, session, state, Mapper
+
from allura.command import base
+from allura.lib.helpers import iter_entry_points
+
import forgetracker.model
@@ -109,7 +111,7 @@ class RethumbCommand(base.Command):
self.process_att_of_type(M.DiscussionAttachment, {'app_config_id': app._id, 'discussion_id': {'$ne': None}})
# Otherwise, we'll take attachment classes belonging to app's package
- ep = pkg_resources.iter_entry_points('allura', app.tool_name).next()
+ ep = iter_entry_points('allura', app.tool_name).next()
app_package = ep.module_name.split('.', 1)[0]
if app_package == 'allura':
# Apps in allura known to not define own attachment types
[05/13] git commit: [#6482] simpler logic to build matrix of
importers (thanks Cory)
Posted by tv...@apache.org.
[#6482] simpler logic to build matrix of importers (thanks Cory)
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/ec9c7cf0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/ec9c7cf0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/ec9c7cf0
Branch: refs/heads/master
Commit: ec9c7cf0004f44b1b042aef9b83d22235d92da40
Parents: 7f179dc
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue Aug 13 21:12:37 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Aug 27 17:24:58 2013 +0000
----------------------------------------------------------------------
ForgeImporters/forgeimporters/base.py | 27 ++++----------------
.../forgeimporters/templates/list_all.html | 12 ++++-----
2 files changed, 11 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ec9c7cf0/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index e957b1a..e80235e 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -360,33 +360,16 @@ class ProjectToolsImportController(object):
@with_trailing_slash
@expose('jinja:forgeimporters:templates/list_all.html')
def index(self, *a, **kw):
- # make dictionaries of both axis
- importers_by_source = defaultdict(dict)
- importers_by_tool = defaultdict(dict)
+ importer_matrix = defaultdict(dict)
+ tools_with_importers = set()
for ep in iter_entry_points('allura.importers'):
importer = ep.load()
- importers_by_source[importer.source][ep.name] = importer
for tool in aslist(importer.target_app):
- importers_by_tool[tool][ep.name] = importer
-
- relevant_tools = sorted(importers_by_tool.keys(), key=lambda t: t.tool_label)
-
- # build a full matrix including empty spots
- importer_matrix = dict() # source -> [importer names]
- for source, src_importers in importers_by_source.iteritems():
- row = list()
- for tool in relevant_tools:
- for ep_name, importer in src_importers.iteritems():
- if tool in aslist(importer.target_app):
- row.append(ep_name)
- break
- else:
- row.append(None)
- importer_matrix[source] = row
-
+ tools_with_importers.add(tool.tool_label)
+ importer_matrix[importer.source][tool.tool_label] = ep.name
return {
- 'tools': relevant_tools,
'importer_matrix': importer_matrix,
+ 'tools': tools_with_importers,
}
@expose()
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ec9c7cf0/ForgeImporters/forgeimporters/templates/list_all.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/templates/list_all.html b/ForgeImporters/forgeimporters/templates/list_all.html
index b91e0df..b4c0a06 100644
--- a/ForgeImporters/forgeimporters/templates/list_all.html
+++ b/ForgeImporters/forgeimporters/templates/list_all.html
@@ -31,18 +31,18 @@
<thead>
<tr>
<th></th>
- {% for tool in tools %}
- <th>{{tool.tool_label}}</th>
+ {% for tool in tools|sort %}
+ <th>{{tool}}</th>
{% endfor %}
</tr>
</thead>
- {% for source, importers in importer_matrix|dictsort %}
+ {% for source in importer_matrix.keys()|sort %}
<tr>
<td><strong>{{ source }}</strong></td>
- {% for importer_name in importers %}
+ {% for tool in tools|sort %}
<td>
- {% if importer_name %}
- <a href="{{importer_name}}">Import</a>
+ {% if importer_matrix[source].get(tool) %}
+ <a href="{{ importer_matrix[source][tool] }}">Import</a>
{% endif %}
</td>
{% endfor %}
[10/13] git commit: [#6526] Set c.project before calling
MountPointValidator
Posted by tv...@apache.org.
[#6526] Set c.project before calling MountPointValidator
Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/eceab844
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/eceab844
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/eceab844
Branch: refs/heads/master
Commit: eceab844fdd664eff62b1a64380bce01a0767d07
Parents: 9704ca5
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Wed Aug 28 16:08:34 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Aug 28 16:08:34 2013 +0000
----------------------------------------------------------------------
Allura/allura/lib/validators.py | 6 ++----
Allura/allura/model/project.py | 9 +++++----
2 files changed, 7 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/eceab844/Allura/allura/lib/validators.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/validators.py b/Allura/allura/lib/validators.py
index 9d15429..3295bb0 100644
--- a/Allura/allura/lib/validators.py
+++ b/Allura/allura/lib/validators.py
@@ -90,8 +90,7 @@ class MountPointValidator(fev.UnicodeString):
if mount_point in self.reserved_mount_points:
raise fe.Invalid('Mount point "%s" is reserved' % mount_point,
value, state)
- if (getattr(c, 'project', None) and
- c.project.app_instance(mount_point) is not None):
+ if c.project and c.project.app_instance(mount_point) is not None:
raise fe.Invalid('Mount point "%s" is already in use' % mount_point,
value, state)
return mount_point
@@ -100,8 +99,7 @@ class MountPointValidator(fev.UnicodeString):
base_mount_point = mount_point = self.app_class.default_mount_point
i = 0
while True:
- if (not getattr(c, 'project', None) or
- c.project.app_instance(mount_point) is None):
+ if not c.project or c.project.app_instance(mount_point) is None:
return mount_point
mount_point = base_mount_point + '-%d' % i
i += 1
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/eceab844/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 983ef66..ec39157 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -600,10 +600,11 @@ class Project(MappedClass, ActivityNode, ActivityObject):
def install_app(self, ep_name, mount_point=None, mount_label=None, ordinal=None, **override_options):
App = g.entry_points['tool'][ep_name]
- try:
- mount_point = v.MountPointValidator(App).to_python(mount_point)
- except fe.Invalid as e:
- raise exceptions.ToolError(str(e))
+ with h.push_config(c, project=self):
+ try:
+ mount_point = v.MountPointValidator(App).to_python(mount_point)
+ except fe.Invalid as e:
+ raise exceptions.ToolError(str(e))
if ordinal is None:
ordinal = int(self.ordered_mounts(include_hidden=True)[-1]['ordinal']) + 1
options = App.default_options()
[08/13] git commit: [#6526] Better label on submit button
Posted by tv...@apache.org.
[#6526] Better label on submit button
Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/90651671
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/90651671
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/90651671
Branch: refs/heads/master
Commit: 906516719ecc8b3a6c10c4a253a443d7367c0dbd
Parents: a4dc01b
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Wed Aug 28 14:34:10 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Aug 28 14:34:10 2013 +0000
----------------------------------------------------------------------
ForgeImporters/forgeimporters/templates/importer_base.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/90651671/ForgeImporters/forgeimporters/templates/importer_base.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/templates/importer_base.html b/ForgeImporters/forgeimporters/templates/importer_base.html
index 4bdfe0f..7a25543 100644
--- a/ForgeImporters/forgeimporters/templates/importer_base.html
+++ b/ForgeImporters/forgeimporters/templates/importer_base.html
@@ -75,6 +75,6 @@
{{ error('mount_point') }}
</div>
- <input type="submit" />
+ <input type="submit" value="Import"/>
</form>
{% endblock %}
[11/13] git commit: [#6526] bump Google Code & Trac Wiki importer
versions for their changes
Posted by tv...@apache.org.
[#6526] bump Google Code & Trac Wiki importer versions for their 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/10cb90c7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/10cb90c7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/10cb90c7
Branch: refs/heads/master
Commit: 10cb90c712a79fb8a64d5f7dbcc0aaa5b7132b04
Parents: eceab84
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Aug 28 17:08:01 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 28 17:08:01 2013 +0000
----------------------------------------------------------------------
requirements-sf.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/10cb90c7/requirements-sf.txt
----------------------------------------------------------------------
diff --git a/requirements-sf.txt b/requirements-sf.txt
index a77c839..4e00d83 100644
--- a/requirements-sf.txt
+++ b/requirements-sf.txt
@@ -6,7 +6,7 @@ kombu==1.0.4
coverage==3.5a1-20110413
ForgeHg==0.1.15
ForgePastebin==0.2.7
-GoogleCodeWikiImporter==0.2.0
+GoogleCodeWikiImporter==0.3.0
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.1.0
+TracWikiImporter==0.2.0
# use version built from https://github.com/johnsca/GitPython/commits/tv/6000
# for unmerged fixes for [#5411], [#6000], and [#6078]
[07/13] git commit: [#6526] Fix MountPointValidator to provide
default value
Posted by tv...@apache.org.
[#6526] Fix MountPointValidator to provide default value
Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/a4dc01b3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/a4dc01b3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/a4dc01b3
Branch: refs/heads/master
Commit: a4dc01b395929b0ba05a14f1a37e590ebdf42a6f
Parents: 6ff3125
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Wed Aug 28 14:30:28 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Aug 28 14:30:28 2013 +0000
----------------------------------------------------------------------
Allura/allura/lib/validators.py | 23 ++++++-----
Allura/allura/tests/test_validators.py | 61 +++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a4dc01b3/Allura/allura/lib/validators.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/validators.py b/Allura/allura/lib/validators.py
index fa82d32..3295bb0 100644
--- a/Allura/allura/lib/validators.py
+++ b/Allura/allura/lib/validators.py
@@ -19,6 +19,7 @@ import json
from bson import ObjectId
import formencode as fe
from formencode import validators as fev
+from pylons import tmpl_context as c
from . import helpers as h
from datetime import datetime
@@ -74,20 +75,13 @@ class MaxBytesValidator(fev.FancyValidator):
class MountPointValidator(fev.UnicodeString):
def __init__(self, app_class,
- reserved_mount_points=('feed', 'index', 'icon', '_nav.json')):
- super(self.__class__, self).__init__()
+ reserved_mount_points=('feed', 'index', 'icon', '_nav.json'), **kw):
+ super(self.__class__, self).__init__(**kw)
self.app_class = app_class
self.reserved_mount_points = reserved_mount_points
def _to_python(self, value, state):
- from pylons import tmpl_context as c
- project = state.project if hasattr(state, 'project') else c.project
mount_point, App = value, self.app_class
- if not mount_point:
- base_mount_point = mount_point = App.default_mount_point
- for x in range(10):
- if project.app_instance(mount_point) is None: break
- mount_point = base_mount_point + '-%d' % x
if not App.relaxed_mount_points:
mount_point = mount_point.lower()
if not App.validate_mount_point(mount_point):
@@ -96,11 +90,20 @@ class MountPointValidator(fev.UnicodeString):
if mount_point in self.reserved_mount_points:
raise fe.Invalid('Mount point "%s" is reserved' % mount_point,
value, state)
- if project.app_instance(mount_point) is not None:
+ if c.project and c.project.app_instance(mount_point) is not None:
raise fe.Invalid('Mount point "%s" is already in use' % mount_point,
value, state)
return mount_point
+ def empty_value(self, value):
+ base_mount_point = mount_point = self.app_class.default_mount_point
+ i = 0
+ while True:
+ if not c.project or c.project.app_instance(mount_point) is None:
+ return mount_point
+ mount_point = base_mount_point + '-%d' % i
+ i += 1
+
class TaskValidator(fev.FancyValidator):
def _to_python(self, value, state):
try:
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a4dc01b3/Allura/allura/tests/test_validators.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_validators.py b/Allura/allura/tests/test_validators.py
index b0d165c..26779ce 100644
--- a/Allura/allura/tests/test_validators.py
+++ b/Allura/allura/tests/test_validators.py
@@ -17,6 +17,7 @@
import unittest
import formencode as fe
+from mock import Mock, patch
from allura import model as M
from allura.lib import validators as v
@@ -92,6 +93,66 @@ class TestUserValidator(unittest.TestCase):
self.assertEqual(str(cm.exception), "Invalid username")
+class TestMountPointValidator(unittest.TestCase):
+
+ @patch('allura.lib.validators.c')
+ def test_valid(self, c):
+ App = Mock()
+ App.relaxed_mount_points = False
+ App.validate_mount_point.return_value = True
+ c.project.app_instance.return_value = None
+ val = v.MountPointValidator(App)
+ self.assertEqual('mymount', val.to_python('Mymount'))
+
+ @patch('allura.lib.validators.c')
+ def test_invalid(self, c):
+ App = Mock()
+ App.relaxed_mount_points = False
+ App.validate_mount_point.return_value = False
+ c.project.app_instance.return_value = False
+ val = v.MountPointValidator(App)
+ with self.assertRaises(fe.Invalid):
+ val.to_python('mymount')
+
+ @patch('allura.lib.validators.c')
+ def test_relaxed_mount_points(self, c):
+ App = Mock()
+ App.relaxed_mount_points = True
+ App.validate_mount_point.return_value = True
+ c.project.app_instance.return_value = None
+ val = v.MountPointValidator(App)
+ self.assertEqual('Mymount', val.to_python('Mymount'))
+
+ @patch('allura.lib.validators.c')
+ def test_in_use(self, c):
+ App = Mock()
+ App.relaxed_mount_points = False
+ App.validate_mount_point.return_value = True
+ c.project.app_instance.return_value = True
+ val = v.MountPointValidator(App)
+ with self.assertRaises(fe.Invalid):
+ val.to_python('mymount')
+
+ @patch('allura.lib.validators.c')
+ def test_reserved(self, c):
+ App = Mock()
+ App.relaxed_mount_points = False
+ App.validate_mount_point.return_value = True
+ c.project.app_instance.return_value = False
+ val = v.MountPointValidator(App)
+ with self.assertRaises(fe.Invalid):
+ val.to_python('feed')
+
+ @patch('allura.lib.validators.c')
+ def test_empty(self, c):
+ App = Mock()
+ App.default_mount_point = 'wiki'
+ c.project.app_instance.side_effect = lambda mp: None if mp != 'wiki' else True
+ val = v.MountPointValidator(App)
+ self.assertEqual('wiki-0', val.to_python(''))
+ self.assertEqual('wiki-0', val.to_python(None))
+
+
class TestTaskValidator(unittest.TestCase):
val = v.TaskValidator
[06/13] git commit: [#6482] add a test for the importer admin page
Posted by tv...@apache.org.
[#6482] add a test for the importer admin page
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/7f179dca
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/7f179dca
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/7f179dca
Branch: refs/heads/master
Commit: 7f179dca16b4a37936a1d3427aa18db130a3292a
Parents: b7fb5f2
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue Aug 13 20:38:30 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Aug 27 17:24:58 2013 +0000
----------------------------------------------------------------------
ForgeImporters/forgeimporters/base.py | 4 +-
.../forgeimporters/tests/test_base.py | 74 ++++++++++++++------
2 files changed, 56 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7f179dca/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index c6cdf4a..e957b1a 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -404,5 +404,5 @@ class ImportAdminExtension(AdminExtension):
def update_project_sidebar_menu(self, sidebar_links):
base_url = c.project.url() + 'admin/ext/'
- link = SitemapEntry('Import', base_url+'import')
- sidebar_links.append(link)
+ link = SitemapEntry('Import', base_url+'import/')
+ sidebar_links.append(link)
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7f179dca/ForgeImporters/forgeimporters/tests/test_base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/test_base.py b/ForgeImporters/forgeimporters/tests/test_base.py
index 57ed227..f1c93ad 100644
--- a/ForgeImporters/forgeimporters/tests/test_base.py
+++ b/ForgeImporters/forgeimporters/tests/test_base.py
@@ -19,6 +19,10 @@ from unittest import TestCase
from formencode import Invalid
import mock
+from tg import expose
+from nose.tools import assert_equal
+
+from alluratest.controller import TestController
from .. import base
@@ -76,17 +80,25 @@ TA1 = mock.Mock(tool_label='foo', tool_description='foo_desc')
TA2 = mock.Mock(tool_label='qux', tool_description='qux_desc')
TA3 = mock.Mock(tool_label='baz', tool_description='baz_desc')
-class TestToolImporter(TestCase):
- class TI1(base.ToolImporter):
- target_app = TA1
+class TI1Controller(object):
+ @expose()
+ def index(self, *a, **kw):
+ return 'test importer 1 controller webpage'
+
+class TI1(base.ToolImporter):
+ target_app = TA1
+ controller = TI1Controller
+
+class TI2(base.ToolImporter):
+ target_app = TA2
+ tool_label = 'bar'
+ tool_description = 'bar_desc'
+
+class TI3(base.ToolImporter):
+ target_app = [TA2, TA2]
- class TI2(base.ToolImporter):
- target_app = TA2
- tool_label = 'bar'
- tool_description = 'bar_desc'
+class TestToolImporter(TestCase):
- class TI3(base.ToolImporter):
- target_app = [TA2, TA2]
@mock.patch.object(base, 'iter_entry_points')
def test_by_name(self, iep):
@@ -104,27 +116,27 @@ class TestToolImporter(TestCase):
@mock.patch.object(base, 'iter_entry_points')
def test_by_app(self, iep):
eps = iep.return_value = [
- ep('importer1', importer=self.TI1),
- ep('importer2', importer=self.TI2),
- ep('importer3', importer=self.TI3),
+ ep('importer1', importer=TI1),
+ ep('importer2', importer=TI2),
+ ep('importer3', importer=TI3),
]
importers = base.ToolImporter.by_app(TA2)
self.assertEqual(set(importers.keys()), set([
'importer2',
'importer3',
]))
- self.assertIsInstance(importers['importer2'], self.TI2)
- self.assertIsInstance(importers['importer3'], self.TI3)
+ self.assertIsInstance(importers['importer2'], TI2)
+ self.assertIsInstance(importers['importer3'], TI3)
def test_tool_label(self):
- self.assertEqual(self.TI1().tool_label, 'foo')
- self.assertEqual(self.TI2().tool_label, 'bar')
- self.assertEqual(self.TI3().tool_label, 'qux')
+ self.assertEqual(TI1().tool_label, 'foo')
+ self.assertEqual(TI2().tool_label, 'bar')
+ self.assertEqual(TI3().tool_label, 'qux')
def test_tool_description(self):
- self.assertEqual(self.TI1().tool_description, 'foo_desc')
- self.assertEqual(self.TI2().tool_description, 'bar_desc')
- self.assertEqual(self.TI3().tool_description, 'qux_desc')
+ self.assertEqual(TI1().tool_description, 'foo_desc')
+ self.assertEqual(TI2().tool_description, 'bar_desc')
+ self.assertEqual(TI3().tool_description, 'qux_desc')
class TestToolsValidator(TestCase):
@@ -172,3 +184,25 @@ class TestToolsValidator(TestCase):
mock.call('value1'),
mock.call('value2'),
])
+
+
+class TestProjectToolsImportController(TestController):
+
+ def test_pages(self):
+ admin_page = self.app.get('/admin/')
+ with mock.patch.object(base, 'iter_entry_points') as iep:
+ iep.return_value = [
+ ep('importer1', importer=TI1),
+ ep('importer2', importer=TI2),
+ ep('importer3', importer=TI3),
+ ]
+ import_main_page = admin_page.click('Import')
+ url = import_main_page.environ['PATH_INFO']
+ assert url.endswith('/admin/ext/import/'), url
+
+ with mock.patch.object(base.ToolImporter, 'by_name') as by_name:
+ by_name.return_value = TI1
+ import1_page = import_main_page.click('Import', href=r'importer1$')
+ url = import1_page.environ['PATH_INFO']
+ assert url.endswith('/admin/ext/import/importer1'), url
+ assert_equal(import1_page.body, 'test importer 1 controller webpage')
[02/13] git commit: [#6482] change page to show importers in a grid
Posted by tv...@apache.org.
[#6482] change page to show importers in a grid
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/b7fb5f2d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/b7fb5f2d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/b7fb5f2d
Branch: refs/heads/master
Commit: b7fb5f2dd43636783c58c6f5d03b4fbe0a216820
Parents: f705a17
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue Aug 13 19:20:11 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Aug 27 17:24:58 2013 +0000
----------------------------------------------------------------------
ForgeImporters/forgeimporters/base.py | 31 +++++++++--
.../forgeimporters/templates/list_all.html | 58 ++++++++------------
2 files changed, 51 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b7fb5f2d/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index 620097e..c6cdf4a 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -18,6 +18,7 @@
import logging
import urllib
import urllib2
+from collections import defaultdict
from pkg_resources import iter_entry_points
@@ -359,11 +360,33 @@ class ProjectToolsImportController(object):
@with_trailing_slash
@expose('jinja:forgeimporters:templates/list_all.html')
def index(self, *a, **kw):
- importers = {}
- for app_name, app in g.entry_points['tool'].iteritems():
- importers[app] = ToolImporter.by_app(app)
+ # make dictionaries of both axis
+ importers_by_source = defaultdict(dict)
+ importers_by_tool = defaultdict(dict)
+ for ep in iter_entry_points('allura.importers'):
+ importer = ep.load()
+ importers_by_source[importer.source][ep.name] = importer
+ for tool in aslist(importer.target_app):
+ importers_by_tool[tool][ep.name] = importer
+
+ relevant_tools = sorted(importers_by_tool.keys(), key=lambda t: t.tool_label)
+
+ # build a full matrix including empty spots
+ importer_matrix = dict() # source -> [importer names]
+ for source, src_importers in importers_by_source.iteritems():
+ row = list()
+ for tool in relevant_tools:
+ for ep_name, importer in src_importers.iteritems():
+ if tool in aslist(importer.target_app):
+ row.append(ep_name)
+ break
+ else:
+ row.append(None)
+ importer_matrix[source] = row
+
return {
- 'importers': importers
+ 'tools': relevant_tools,
+ 'importer_matrix': importer_matrix,
}
@expose()
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b7fb5f2d/ForgeImporters/forgeimporters/templates/list_all.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/templates/list_all.html b/ForgeImporters/forgeimporters/templates/list_all.html
index 58c9f34..b91e0df 100644
--- a/ForgeImporters/forgeimporters/templates/list_all.html
+++ b/ForgeImporters/forgeimporters/templates/list_all.html
@@ -21,42 +21,32 @@
{% block title %}{{c.project.name}} / Import{% endblock %}
-{% block header %}Import from external sources{% endblock %}
-
-{% block extra_css %}
-<style type="text/css">
- .tool {
- margin-bottom: 3em;
- }
- .tool img {
- float: left;
- margin: 0 1em;
- }
- .importer .descr {
- margin: 0 2em 1em 2em;
- }
-</style>
-{% endblock %}
+{% block header %}Import{% endblock %}
{% block content %}
- {% for tool, tool_importers in importers.iteritems() %}
- <div class="tool">
- {% for importer_name, importer in tool_importers.iteritems() %}
- {% if loop.first %}
- <img src="{{ g.theme.app_icon_url(tool, 48) }}" alt="{{ tool.tool_label }} icon">
- <h2>{{ tool.tool_label }}</h2>
- {% endif %}
- <div class="importer">
- <a href="{{importer_name}}"><h3>
- {{importer.source}}:
- {{importer.tool_label}}
- </h3>
- </a>
- <div class="descr">
- {{importer.tool_description}}
- </div>
- </div>
+<p>
+ To import from one of these external sources into your project, just click on "Import" and fill out the form.
+</p>
+<table>
+ <thead>
+ <tr>
+ <th></th>
+ {% for tool in tools %}
+ <th>{{tool.tool_label}}</th>
+ {% endfor %}
+ </tr>
+ </thead>
+ {% for source, importers in importer_matrix|dictsort %}
+ <tr>
+ <td><strong>{{ source }}</strong></td>
+ {% for importer_name in importers %}
+ <td>
+ {% if importer_name %}
+ <a href="{{importer_name}}">Import</a>
+ {% endif %}
+ </td>
{% endfor %}
- </div>
+ </tr>
{% endfor %}
+</table>
{% endblock %}
[04/13] git commit: [#6526] Clean up individual tool importers
Posted by tv...@apache.org.
[#6526] Clean up individual tool importers
- Make forms look (slightly) better
- Add validation
- Kick off import as task
Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/8378ac03
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/8378ac03
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/8378ac03
Branch: refs/heads/master
Commit: 8378ac032f3d92ea77d2756336641f45a9c71931
Parents: ec9c7cf
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Wed Aug 21 20:53:33 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Aug 27 17:24:58 2013 +0000
----------------------------------------------------------------------
Allura/allura/lib/validators.py | 29 +++++++
Allura/allura/model/project.py | 23 ++----
ForgeImporters/forgeimporters/base.py | 10 ++-
.../forgeimporters/google/__init__.py | 2 +-
ForgeImporters/forgeimporters/google/code.py | 62 +++++++++++++--
.../google/templates/code/index.html | 25 ++----
.../google/templates/tracker/index.html | 27 +++++++
.../forgeimporters/google/tests/test_code.py | 17 ++---
ForgeImporters/forgeimporters/google/tracker.py | 62 ++++++++++++++-
.../forgeimporters/templates/importer_base.html | 80 ++++++++++++++++++++
.../forgeimporters/tests/google/test_tracker.py | 34 ++++++++-
.../trac/templates/tickets/index.html | 41 ++++------
.../forgeimporters/trac/tests/test_tickets.py | 20 ++---
ForgeImporters/forgeimporters/trac/tickets.py | 40 +++++++---
14 files changed, 364 insertions(+), 108 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/Allura/allura/lib/validators.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/validators.py b/Allura/allura/lib/validators.py
index 9b44d53..fa82d32 100644
--- a/Allura/allura/lib/validators.py
+++ b/Allura/allura/lib/validators.py
@@ -72,6 +72,35 @@ class MaxBytesValidator(fev.FancyValidator):
def from_python(self, value, state):
return h.really_unicode(value or '')
+class MountPointValidator(fev.UnicodeString):
+ def __init__(self, app_class,
+ reserved_mount_points=('feed', 'index', 'icon', '_nav.json')):
+ super(self.__class__, self).__init__()
+ self.app_class = app_class
+ self.reserved_mount_points = reserved_mount_points
+
+ def _to_python(self, value, state):
+ from pylons import tmpl_context as c
+ project = state.project if hasattr(state, 'project') else c.project
+ mount_point, App = value, self.app_class
+ if not mount_point:
+ base_mount_point = mount_point = App.default_mount_point
+ for x in range(10):
+ if project.app_instance(mount_point) is None: break
+ mount_point = base_mount_point + '-%d' % x
+ if not App.relaxed_mount_points:
+ mount_point = mount_point.lower()
+ if not App.validate_mount_point(mount_point):
+ raise fe.Invalid('Mount point "%s" is invalid' % mount_point,
+ value, state)
+ if mount_point in self.reserved_mount_points:
+ raise fe.Invalid('Mount point "%s" is reserved' % mount_point,
+ value, state)
+ if project.app_instance(mount_point) is not None:
+ raise fe.Invalid('Mount point "%s" is already in use' % mount_point,
+ value, state)
+ return mount_point
+
class TaskValidator(fev.FancyValidator):
def _to_python(self, value, state):
try:
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index ebccb3d..983ef66 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -26,6 +26,7 @@ from tg import config
from pylons import tmpl_context as c, app_globals as g
from pylons import request
from paste.deploy.converters import asbool
+import formencode as fe
from ming import schema as S
from ming.utils import LazyProperty
@@ -38,6 +39,7 @@ from allura.lib import helpers as h
from allura.lib import plugin
from allura.lib import exceptions
from allura.lib import security
+from allura.lib import validators as v
from allura.lib.security import has_access
from .session import main_orm_session
@@ -598,23 +600,10 @@ class Project(MappedClass, ActivityNode, ActivityObject):
def install_app(self, ep_name, mount_point=None, mount_label=None, ordinal=None, **override_options):
App = g.entry_points['tool'][ep_name]
- if not mount_point:
- base_mount_point = mount_point = App.default_mount_point
- for x in range(10):
- if self.app_instance(mount_point) is None: break
- mount_point = base_mount_point + '-%d' % x
- if not App.relaxed_mount_points:
- mount_point = mount_point.lower()
- if not App.validate_mount_point(mount_point):
- raise exceptions.ToolError, 'Mount point "%s" is invalid' % mount_point
- # HACK: reserved url components
- if mount_point in ('feed', 'index', 'icon', '_nav.json'):
- raise exceptions.ToolError, (
- 'Mount point "%s" is reserved' % mount_point)
- if self.app_instance(mount_point) is not None:
- raise exceptions.ToolError, (
- 'Mount point "%s" is already in use' % mount_point)
- assert self.app_instance(mount_point) is None
+ try:
+ mount_point = v.MountPointValidator(App).to_python(mount_point)
+ except fe.Invalid as e:
+ raise exceptions.ToolError(str(e))
if ordinal is None:
ordinal = int(self.ordered_mounts(include_hidden=True)[-1]['ordinal']) + 1
options = App.default_options()
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index e80235e..bdff43b 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -35,6 +35,7 @@ from allura.lib.security import require_access
from allura.lib.plugin import ProjectRegistrationProvider, AdminExtension
from allura.lib import helpers as h
from allura.lib import exceptions
+from allura.lib import validators as v
from allura.app import SitemapEntry
from paste.deploy.converters import aslist
@@ -58,6 +59,13 @@ class ProjectImportForm(schema.Schema):
project_name = fev.UnicodeString(not_empty=True, max=40)
+class ToolImportForm(schema.Schema):
+ def __init__(self, tool_class):
+ super(ToolImportForm, self).__init__()
+ self.add_field('mount_point', v.MountPointValidator(tool_class))
+ mount_label = fev.UnicodeString()
+
+
@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)
@@ -388,4 +396,4 @@ class ImportAdminExtension(AdminExtension):
def update_project_sidebar_menu(self, sidebar_links):
base_url = c.project.url() + 'admin/ext/'
link = SitemapEntry('Import', base_url+'import/')
- sidebar_links.append(link)
\ No newline at end of file
+ sidebar_links.append(link)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/ForgeImporters/forgeimporters/google/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/__init__.py b/ForgeImporters/forgeimporters/google/__init__.py
index 849f924..ad5f8e5 100644
--- a/ForgeImporters/forgeimporters/google/__init__.py
+++ b/ForgeImporters/forgeimporters/google/__init__.py
@@ -1,4 +1,4 @@
-# Licensed to the Apache Software Foundation (ASF) under one
+# LNicensed 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
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/ForgeImporters/forgeimporters/google/code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/code.py b/ForgeImporters/forgeimporters/google/code.py
index 11dd7a6..60a0158 100644
--- a/ForgeImporters/forgeimporters/google/code.py
+++ b/ForgeImporters/forgeimporters/google/code.py
@@ -15,6 +15,8 @@
# specific language governing permissions and limitations
# under the License.
+import urllib2
+
import formencode as fe
from formencode import validators as fev
@@ -22,6 +24,7 @@ from pylons import tmpl_context as c
from pylons import app_globals as g
from tg import (
expose,
+ flash,
redirect,
validate,
)
@@ -31,25 +34,30 @@ from tg.decorators import (
)
from allura.controllers import BaseController
-from allura.lib.decorators import require_post
+from allura.lib import validators as v
+from allura.lib.decorators import require_post, task
from forgeimporters.base import ToolImporter
from forgeimporters.google import GoogleCodeProjectExtractor
+REPO_APPS = {}
TARGET_APPS = []
try:
from forgehg.hg_main import ForgeHgApp
TARGET_APPS.append(ForgeHgApp)
+ REPO_APPS['hg'] = ForgeHgApp
except ImportError:
pass
try:
from forgegit.git_main import ForgeGitApp
TARGET_APPS.append(ForgeGitApp)
+ REPO_APPS['git'] = ForgeGitApp
except ImportError:
pass
try:
from forgesvn.svn_main import ForgeSVNApp
TARGET_APPS.append(ForgeSVNApp)
+ REPO_APPS['svn'] = ForgeSVNApp
except ImportError:
pass
@@ -69,28 +77,70 @@ def get_repo_url(project_name, type_):
return REPO_URLS[type_].format(project_name)
-class GoogleRepoImportSchema(fe.Schema):
+def get_repo_class(type_):
+ return REPO_APPS[type_]
+
+
+@task(notifications_disabled=True)
+def import_tool(**kw):
+ GoogleRepoImporter().import_tool(c.project, c.user, **kw)
+
+
+class GoogleRepoImportForm(fe.schema.Schema):
gc_project_name = fev.UnicodeString(not_empty=True)
mount_point = fev.UnicodeString()
mount_label = fev.UnicodeString()
+ def _to_python(self, value, state):
+ value = super(self.__class__, self)._to_python(value, state)
+
+ gc_project_name = value['gc_project_name']
+ mount_point = value['mount_point']
+ try:
+ repo_type = GoogleCodeProjectExtractor(gc_project_name).get_repo_type()
+ except urllib2.HTTPError as e:
+ if e.code == 404:
+ msg = 'No such project'
+ else:
+ msg = str(e)
+ msg = 'gc_project_name:' + msg
+ raise fe.Invalid(msg, value, state)
+ except Exception:
+ raise
+ tool_class = REPO_APPS[repo_type]
+ try:
+ v.MountPointValidator(tool_class).to_python(mount_point)
+ except fe.Invalid as e:
+ raise fe.Invalid('mount_point:' + str(e), value, state)
+ return value
+
class GoogleRepoImportController(BaseController):
+ def __init__(self):
+ self.importer = GoogleRepoImporter()
+
+ @property
+ def target_app(self):
+ return self.importer.target_app[0]
+
@with_trailing_slash
@expose('jinja:forgeimporters.google:templates/code/index.html')
def index(self, **kw):
- return {}
+ return dict(importer=self.importer,
+ target_app=self.target_app)
@without_trailing_slash
@expose()
@require_post()
- @validate(GoogleRepoImportSchema(), error_handler=index)
+ @validate(GoogleRepoImportForm(), error_handler=index)
def create(self, gc_project_name, mount_point, mount_label, **kw):
- app = GoogleRepoImporter().import_tool(c.project, c.user,
+ import_tool.post(
project_name=gc_project_name,
mount_point=mount_point,
mount_label=mount_label)
- redirect(app.url())
+ flash('Repo import has begun. Your new repo will be available '
+ 'when the import is complete.')
+ redirect(c.project.url() + 'admin/')
class GoogleRepoImporter(ToolImporter):
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/ForgeImporters/forgeimporters/google/templates/code/index.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/templates/code/index.html b/ForgeImporters/forgeimporters/google/templates/code/index.html
index 7bace3a..e2cef0c 100644
--- a/ForgeImporters/forgeimporters/google/templates/code/index.html
+++ b/ForgeImporters/forgeimporters/google/templates/code/index.html
@@ -16,27 +16,16 @@
specific language governing permissions and limitations
under the License.
-#}
-{% extends g.theme.master %}
+{% extends 'forgeimporters:templates/importer_base.html' %}
{% block title %}
-{{c.project.name}} / Import Google Code Repo
+{{c.project.name}} / Import your repo from Google Code
{% endblock %}
-{% block header %}
-Import a Repo from a Google Code project
-{% endblock %}
-
-{% block content %}
-<form action="create" method="post" class="pad">
+{% block importer_fields %}
+<div>
<label for="gc_project_name">Google Code project name (as it appears in a URL)</label>
- <input name="gc_project_name" />
-
- <label for="mount_label">Label</label>
- <input name="mount_label" value="Source" />
-
- <label for="mount_point">Mount Point</label>
- <input name="mount_point" value="source" />
-
- <input type="submit" />
-</form>
+ <input name="gc_project_name" value="{{ c.form_values['gc_project_name'] }}" />
+ {{ error('gc_project_name') }}
+</div>
{% endblock %}
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/ForgeImporters/forgeimporters/google/templates/tracker/index.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/templates/tracker/index.html b/ForgeImporters/forgeimporters/google/templates/tracker/index.html
new file mode 100644
index 0000000..08d0084
--- /dev/null
+++ b/ForgeImporters/forgeimporters/google/templates/tracker/index.html
@@ -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.
+-#}
+{% extends 'forgeimporters:templates/importer_base.html' %}
+
+{% block importer_fields %}
+<div>
+ <label for="gc_project_name">Google Code project name (as it appears in a URL)</label>
+ <input name="gc_project_name" value="{{ c.form_values['gc_project_name'] }}" />
+ {{ error('gc_project_name') }}
+</div>
+{% endblock %}
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/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 950246a..c6874ad 100644
--- a/ForgeImporters/forgeimporters/google/tests/test_code.py
+++ b/ForgeImporters/forgeimporters/google/tests/test_code.py
@@ -89,12 +89,8 @@ class TestGoogleRepoImportController(TestController, TestCase):
self.assertIsNotNone(r.html.find(attrs=dict(name="mount_point")))
@with_svn
- @patch('forgeimporters.google.code.GoogleRepoImporter')
- def test_create(self, gri):
- from allura import model as M
- gri = gri.return_value
- gri.import_tool.return_value = Mock()
- gri.import_tool.return_value.url.return_value = '/p/{}/mymount'.format(test_project_with_repo)
+ @patch('forgeimporters.google.code.import_tool')
+ def test_create(self, import_tool):
params = dict(gc_project_name='poop',
mount_label='mylabel',
mount_point='mymount',
@@ -102,8 +98,7 @@ class TestGoogleRepoImportController(TestController, TestCase):
r = self.app.post('/p/{}/admin/src/_importer/create'.format(test_project_with_repo),
params,
status=302)
- project = M.Project.query.get(shortname=test_project_with_repo)
- self.assertEqual(r.location, 'http://localhost/p/{}/mymount'.format(test_project_with_repo))
- self.assertEqual(project._id, gri.import_tool.call_args[0][0]._id)
- self.assertEqual(u'mymount', gri.import_tool.call_args[1]['mount_point'])
- self.assertEqual(u'mylabel', gri.import_tool.call_args[1]['mount_label'])
+ self.assertEqual(r.location, 'http://localhost/p/{}/admin/'.format(test_project_with_repo))
+ 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'])
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/ForgeImporters/forgeimporters/google/tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tracker.py b/ForgeImporters/forgeimporters/google/tracker.py
index 8b1747f..b7fccbe 100644
--- a/ForgeImporters/forgeimporters/google/tracker.py
+++ b/ForgeImporters/forgeimporters/google/tracker.py
@@ -18,23 +18,81 @@
from collections import defaultdict
from datetime import datetime
+from formencode import validators as fev
+
from pylons import tmpl_context as c
from pylons import app_globals as g
from ming.orm import session, ThreadLocalORMSession
from allura import model as M
+#import gdata
+gdata = None
+from tg import (
+ expose,
+ flash,
+ redirect,
+ validate,
+ )
+from tg.decorators import (
+ with_trailing_slash,
+ without_trailing_slash,
+ )
+
+from allura.controllers import BaseController
from allura.lib import helpers as h
+from allura.lib.decorators import require_post, task
from forgetracker.tracker_main import ForgeTrackerApp
from forgetracker import model as TM
-from ..base import ToolImporter
from . import GoogleCodeProjectExtractor
+from forgeimporters.base import (
+ ToolImporter,
+ ToolImportForm,
+ )
+
+
+@task(notifications_disabled=True)
+def import_tool(**kw):
+ GoogleCodeTrackerImporter().import_tool(c.project, c.user, **kw)
+
+
+class GoogleCodeTrackerImportForm(ToolImportForm):
+ gc_project_name = fev.UnicodeString(not_empty=True)
+
+
+class GoogleCodeTrackerImportController(BaseController):
+ def __init__(self):
+ self.importer = GoogleCodeTrackerImporter()
+
+ @property
+ def target_app(self):
+ return self.importer.target_app
+
+ @with_trailing_slash
+ @expose('jinja:forgeimporters.google:templates/tracker/index.html')
+ def index(self, **kw):
+ return dict(importer=self.importer,
+ target_app=self.target_app)
+
+ @without_trailing_slash
+ @expose()
+ @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.')
+ redirect(c.project.url() + 'admin/')
class GoogleCodeTrackerImporter(ToolImporter):
source = 'Google Code'
target_app = ForgeTrackerApp
- controller = None
+ controller = GoogleCodeTrackerImportController
tool_label = 'Issues'
field_types = defaultdict(lambda: 'string',
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/ForgeImporters/forgeimporters/templates/importer_base.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/templates/importer_base.html b/ForgeImporters/forgeimporters/templates/importer_base.html
new file mode 100644
index 0000000..4bdfe0f
--- /dev/null
+++ b/ForgeImporters/forgeimporters/templates/importer_base.html
@@ -0,0 +1,80 @@
+{#-
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-#}
+{% extends g.theme.master %}
+
+{% block title %}
+{{c.project.name}} / {{ importer.tool_description }}
+{% endblock %}
+
+{% block header %}
+{{ importer.tool_description }}
+{% endblock %}
+
+{% block extra_css %}
+ <style type="text/css">
+ form {
+ padding: 0 20px 20px 20px;
+ }
+ form label {
+ display: inline-block;
+ width: 30%;
+ vertical-align: top;
+ }
+ form > div {
+ margin-bottom: 10px;
+ }
+ form > div input {
+ width: 30%;
+ vertical-align: top;
+ }
+ form .error {
+ display: inline-block;
+ color: #f00;
+ background: none;
+ border: none;
+ margin: 0;
+ width: 30%;
+ }
+ </style>
+{% endblock %}
+
+{%- macro error(field_name) %}
+ {% if c.form_errors[field_name] %}
+ <div class="error">{{c.form_errors[field_name]}}</div>
+ {% endif %}
+{%- endmacro %}
+
+{% block content %}
+<form action="create" method="post" enctype="multipart/form-data">
+ {% block importer_fields %}
+ {% endblock %}
+ <div>
+ <label for="mount_label">Label</label>
+ <input name="mount_label" value="{{ c.form_values['mount_label'] or target_app.default_mount_label }}" />
+ {{ error('mount_label') }}
+ </div>
+ <div>
+ <label for="mount_point">Mount Point</label>
+ <input name="mount_point" value="{{ c.form_values['mount_point'] or target_app.default_mount_point }}" />
+ {{ error('mount_point') }}
+ </div>
+
+ <input type="submit" />
+</form>
+{% endblock %}
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/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 4a7c28f..3c7f0aa 100644
--- a/ForgeImporters/forgeimporters/tests/google/test_tracker.py
+++ b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
@@ -16,9 +16,12 @@
# under the License.
from datetime import datetime
-from operator import itemgetter
from unittest import TestCase
import mock
+from mock import patch
+
+from allura.tests import TestController
+from allura.tests.decorators import with_tracker
from ...google import tracker
@@ -239,3 +242,32 @@ class TestTrackerImporter(TestCase):
'options': 'foo bar',
},
])
+
+
+class TestGoogleCodeTrackerImportController(TestController, TestCase):
+ def setUp(self):
+ """Mount Google Code importer on the Tracker admin controller"""
+ super(TestGoogleCodeTrackerImportController, self).setUp()
+ from forgetracker.tracker_main import TrackerAdminController
+ TrackerAdminController._importer = tracker.GoogleCodeTrackerImportController()
+
+ @with_tracker
+ def test_index(self):
+ r = self.app.get('/p/test/admin/bugs/_importer/')
+ self.assertIsNotNone(r.html.find(attrs=dict(name="gc_project_name")))
+ self.assertIsNotNone(r.html.find(attrs=dict(name="mount_label")))
+ self.assertIsNotNone(r.html.find(attrs=dict(name="mount_point")))
+
+ @with_tracker
+ @patch('forgeimporters.google.tracker.import_tool')
+ def test_create(self, import_tool):
+ 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)
+ self.assertEqual(r.location, 'http://localhost/p/test/admin/')
+ 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'])
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/ForgeImporters/forgeimporters/trac/templates/tickets/index.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/trac/templates/tickets/index.html b/ForgeImporters/forgeimporters/trac/templates/tickets/index.html
index 7c278b0..42b8a9f 100644
--- a/ForgeImporters/forgeimporters/trac/templates/tickets/index.html
+++ b/ForgeImporters/forgeimporters/trac/templates/tickets/index.html
@@ -16,30 +16,19 @@
specific language governing permissions and limitations
under the License.
-#}
-{% extends g.theme.master %}
-
-{% block title %}
-{{c.project.name}} / Import Trac Tickets
-{% endblock %}
-
-{% block header %}
-Import tickets from Trac
-{% endblock %}
-
-{% block content %}
-<form action="create" method="post" enctype="multipart/form-data" class="pad">
- <label for="trac_url">URL of the Trac instance</label>
- <input name="trac_url" />
-
- <label for="user_map">JSON file mapping Trac usernames to Allura usernames (optional)</label>
- <input name="user_map" type="file" />
-
- <label for="mount_label">Label</label>
- <input name="mount_label" value="Source" />
-
- <label for="mount_point">Mount Point</label>
- <input name="mount_point" value="source" />
-
- <input type="submit" />
-</form>
+{% extends 'forgeimporters:templates/importer_base.html' %}
+
+{% block importer_fields %}
+ <div>
+ <label for="trac_url">URL of the Trac instance</label>
+ <input name="trac_url" value="{{ c.form_values['trac_url'] }}" />
+ {{ error('trac_url') }}
+ </div>
+ <div>
+ <label for="user_map">User Map (optional)
+ <br><small>JSON file mapping Trac usernames to Allura usernames</small>
+ </label>
+ <input name="user_map" type="file" />
+ {{ error('user_map') }}
+ </div>
{% endblock %}
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/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 2a539df..953c6d7 100644
--- a/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
+++ b/ForgeImporters/forgeimporters/trac/tests/test_tickets.py
@@ -84,12 +84,8 @@ class TestTracTicketImportController(TestController, TestCase):
self.assertIsNotNone(r.html.find(attrs=dict(name="mount_point")))
@with_tracker
- @patch('forgeimporters.trac.tickets.TracTicketImporter')
- def test_create(self, importer):
- from allura import model as M
- importer = importer.return_value
- importer.import_tool.return_value = Mock()
- importer.import_tool.return_value.url.return_value = '/p/test/mymount'
+ @patch('forgeimporters.trac.tickets.import_tool')
+ def test_create(self, import_tool):
params = dict(trac_url='http://example.com/trac/url',
mount_label='mylabel',
mount_point='mymount',
@@ -97,10 +93,8 @@ class TestTracTicketImportController(TestController, TestCase):
r = self.app.post('/p/test/admin/bugs/_importer/create', params,
upload_files=[('user_map', 'myfile', '{"orig_user": "new_user"}')],
status=302)
- project = M.Project.query.get(shortname='test')
- self.assertEqual(r.location, 'http://localhost/p/test/mymount')
- self.assertEqual(project._id, importer.import_tool.call_args[0][0]._id)
- self.assertEqual(u'mymount', importer.import_tool.call_args[1]['mount_point'])
- self.assertEqual(u'mylabel', importer.import_tool.call_args[1]['mount_label'])
- self.assertEqual('{"orig_user": "new_user"}', importer.import_tool.call_args[1]['user_map'])
- self.assertEqual(u'http://example.com/trac/url', importer.import_tool.call_args[1]['trac_url'])
+ self.assertEqual(r.location, 'http://localhost/p/test/admin/')
+ 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('{"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'])
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8378ac03/ForgeImporters/forgeimporters/trac/tickets.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/trac/tickets.py b/ForgeImporters/forgeimporters/trac/tickets.py
index dfbb2a2..3e0e486 100644
--- a/ForgeImporters/forgeimporters/trac/tickets.py
+++ b/ForgeImporters/forgeimporters/trac/tickets.py
@@ -21,7 +21,6 @@ from datetime import (
)
import json
-import formencode as fe
from formencode import validators as fev
from ming.orm import session
@@ -30,6 +29,7 @@ from pylons import app_globals as g
from tg import (
config,
expose,
+ flash,
redirect,
validate,
)
@@ -39,44 +39,60 @@ from tg.decorators import (
)
from allura.controllers import BaseController
-from allura.lib.decorators import require_post
+from allura.lib.decorators import require_post, task
from allura.lib.import_api import AlluraImportApiClient
-from allura.lib.validators import UserMapJsonFile
+from allura.lib import validators as v
from allura.model import ApiTicket
from allura.scripts.trac_export import (
TracExport,
DateJSONEncoder,
)
-from forgeimporters.base import ToolImporter
+from forgeimporters.base import (
+ ToolImporter,
+ ToolImportForm,
+ )
from forgetracker.tracker_main import ForgeTrackerApp
from forgetracker.scripts.import_tracker import import_tracker
-class TracTicketImportSchema(fe.Schema):
+@task(notifications_disabled=True)
+def import_tool(**kw):
+ TracTicketImporter().import_tool(c.project, c.user, **kw)
+
+
+class TracTicketImportForm(ToolImportForm):
trac_url = fev.URL(not_empty=True)
- user_map = UserMapJsonFile(as_string=True)
- mount_point = fev.UnicodeString()
- mount_label = fev.UnicodeString()
+ user_map = v.UserMapJsonFile(as_string=True)
class TracTicketImportController(BaseController):
+ def __init__(self):
+ self.importer = TracTicketImporter()
+
+ @property
+ def target_app(self):
+ return self.importer.target_app
+
@with_trailing_slash
@expose('jinja:forgeimporters.trac:templates/tickets/index.html')
def index(self, **kw):
- return {}
+ return dict(importer=self.importer,
+ target_app=self.target_app)
@without_trailing_slash
@expose()
@require_post()
- @validate(TracTicketImportSchema(), error_handler=index)
+ @validate(TracTicketImportForm(ForgeTrackerApp), error_handler=index)
def create(self, trac_url, mount_point, mount_label, user_map=None, **kw):
- app = TracTicketImporter().import_tool(c.project, c.user,
+ import_tool.post(
mount_point=mount_point,
mount_label=mount_label,
trac_url=trac_url,
user_map=user_map)
- redirect(app.url())
+ flash('Ticket import has begun. Your new tracker will be available '
+ 'when the import is complete.')
+ redirect(c.project.url() + 'admin/')
class TracTicketImporter(ToolImporter):
[09/13] git commit: [#6526] Handle c not having 'project' attr
Posted by tv...@apache.org.
[#6526] Handle c not having 'project' attr
Signed-off-by: Tim Van Steenburgh <tv...@gmail.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/9704ca5c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/9704ca5c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/9704ca5c
Branch: refs/heads/master
Commit: 9704ca5cfc8e6e17622e60094bf48322effc55ea
Parents: 9065167
Author: Tim Van Steenburgh <tv...@gmail.com>
Authored: Wed Aug 28 15:48:14 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Wed Aug 28 15:48:14 2013 +0000
----------------------------------------------------------------------
Allura/allura/lib/validators.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9704ca5c/Allura/allura/lib/validators.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/validators.py b/Allura/allura/lib/validators.py
index 3295bb0..9d15429 100644
--- a/Allura/allura/lib/validators.py
+++ b/Allura/allura/lib/validators.py
@@ -90,7 +90,8 @@ class MountPointValidator(fev.UnicodeString):
if mount_point in self.reserved_mount_points:
raise fe.Invalid('Mount point "%s" is reserved' % mount_point,
value, state)
- if c.project and c.project.app_instance(mount_point) is not None:
+ if (getattr(c, 'project', None) and
+ c.project.app_instance(mount_point) is not None):
raise fe.Invalid('Mount point "%s" is already in use' % mount_point,
value, state)
return mount_point
@@ -99,7 +100,8 @@ class MountPointValidator(fev.UnicodeString):
base_mount_point = mount_point = self.app_class.default_mount_point
i = 0
while True:
- if not c.project or c.project.app_instance(mount_point) is None:
+ if (not getattr(c, 'project', None) or
+ c.project.app_instance(mount_point) is None):
return mount_point
mount_point = base_mount_point + '-%d' % i
i += 1
[03/13] git commit: [#6482] import page for existing projects
Posted by tv...@apache.org.
[#6482] import page for existing projects
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/f705a179
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/f705a179
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/f705a179
Branch: refs/heads/master
Commit: f705a17907a7ad196b9d19c3086b79bc94221908
Parents: 09f0290
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Aug 9 22:14:07 2013 +0000
Committer: Tim Van Steenburgh <tv...@gmail.com>
Committed: Tue Aug 27 17:24:58 2013 +0000
----------------------------------------------------------------------
ForgeImporters/forgeimporters/base.py | 45 ++++++++++++--
.../forgeimporters/templates/list_all.html | 62 ++++++++++++++++++++
ForgeImporters/setup.py | 3 +
3 files changed, 104 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f705a179/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index 19a3d70..620097e 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -24,15 +24,17 @@ from pkg_resources import iter_entry_points
from BeautifulSoup import BeautifulSoup
from tg import expose, validate, flash, redirect, config
from tg.decorators import with_trailing_slash
-from pylons import tmpl_context as c
+from pylons import tmpl_context as c, app_globals as g
from formencode import validators as fev, schema
+from webob import exc
from allura.lib.decorators import require_post
from allura.lib.decorators import task
from allura.lib.security import require_access
-from allura.lib.plugin import ProjectRegistrationProvider
+from allura.lib.plugin import ProjectRegistrationProvider, AdminExtension
from allura.lib import helpers as h
from allura.lib import exceptions
+from allura.app import SitemapEntry
from paste.deploy.converters import aslist
@@ -273,16 +275,16 @@ class ToolImporter(object):
source = None # string description of source, must match project importer
controller = None
- @classmethod
- def by_name(self, name):
+ @staticmethod
+ def by_name(name):
"""
Return a ToolImporter subclass instance given its entry-point name.
"""
for ep in iter_entry_points('allura.importers', name):
return ep.load()()
- @classmethod
- def by_app(self, app):
+ @staticmethod
+ def by_app(app):
"""
Return a ToolImporter subclass instance given its target_app class.
"""
@@ -350,3 +352,34 @@ class ToolsValidator(fev.Set):
pl = 's' if len(invalid) > 1 else ''
raise fev.Invalid('Invalid tool%s selected: %s' % (pl, ', '.join(invalid)), value, state)
return valid
+
+class ProjectToolsImportController(object):
+ '''List all importers available'''
+
+ @with_trailing_slash
+ @expose('jinja:forgeimporters:templates/list_all.html')
+ def index(self, *a, **kw):
+ importers = {}
+ for app_name, app in g.entry_points['tool'].iteritems():
+ importers[app] = ToolImporter.by_app(app)
+ return {
+ 'importers': importers
+ }
+
+ @expose()
+ def _lookup(self, name, *remainder):
+ import_tool = ToolImporter.by_name(name)
+ if import_tool:
+ return import_tool.controller(), remainder
+ else:
+ raise exc.HTTPNotFound
+
+class ImportAdminExtension(AdminExtension):
+ '''Add import link to project admin sidebar'''
+
+ project_admin_controllers = {'import': ProjectToolsImportController}
+
+ def update_project_sidebar_menu(self, sidebar_links):
+ base_url = c.project.url() + 'admin/ext/'
+ link = SitemapEntry('Import', base_url+'import')
+ sidebar_links.append(link)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f705a179/ForgeImporters/forgeimporters/templates/list_all.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/templates/list_all.html b/ForgeImporters/forgeimporters/templates/list_all.html
new file mode 100644
index 0000000..58c9f34
--- /dev/null
+++ b/ForgeImporters/forgeimporters/templates/list_all.html
@@ -0,0 +1,62 @@
+{#-
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-#}
+{% extends g.theme.master %}
+{% import 'allura:templates/jinja_master/lib.html' as lib with context %}
+
+{% block title %}{{c.project.name}} / Import{% endblock %}
+
+{% block header %}Import from external sources{% endblock %}
+
+{% block extra_css %}
+<style type="text/css">
+ .tool {
+ margin-bottom: 3em;
+ }
+ .tool img {
+ float: left;
+ margin: 0 1em;
+ }
+ .importer .descr {
+ margin: 0 2em 1em 2em;
+ }
+</style>
+{% endblock %}
+
+{% block content %}
+ {% for tool, tool_importers in importers.iteritems() %}
+ <div class="tool">
+ {% for importer_name, importer in tool_importers.iteritems() %}
+ {% if loop.first %}
+ <img src="{{ g.theme.app_icon_url(tool, 48) }}" alt="{{ tool.tool_label }} icon">
+ <h2>{{ tool.tool_label }}</h2>
+ {% endif %}
+ <div class="importer">
+ <a href="{{importer_name}}"><h3>
+ {{importer.source}}:
+ {{importer.tool_label}}
+ </h3>
+ </a>
+ <div class="descr">
+ {{importer.tool_description}}
+ </div>
+ </div>
+ {% endfor %}
+ </div>
+ {% endfor %}
+{% endblock %}
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f705a179/ForgeImporters/setup.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/setup.py b/ForgeImporters/setup.py
index cec76b4..d070782 100644
--- a/ForgeImporters/setup.py
+++ b/ForgeImporters/setup.py
@@ -42,4 +42,7 @@ setup(name='ForgeImporters',
google-code-tracker = forgeimporters.google.tracker:GoogleCodeTrackerImporter
google-code-repo = forgeimporters.google.code:GoogleRepoImporter
trac-tickets = forgeimporters.trac.tickets:TracTicketImporter
+
+ [allura.admin]
+ importers = forgeimporters.base:ImportAdminExtension
""",)
[13/13] git commit: put middleware back in proper place so error
pages work correctly (bug introduced in 9a1363)
Posted by tv...@apache.org.
put middleware back in proper place so error pages work correctly (bug introduced in 9a1363)
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/6769dc23
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/6769dc23
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/6769dc23
Branch: refs/heads/master
Commit: 6769dc236d4002e9da51c3cb99439c233fb8a8b2
Parents: 1581f29
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Aug 28 19:02:12 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 28 19:05:47 2013 +0000
----------------------------------------------------------------------
Allura/allura/config/middleware.py | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6769dc23/Allura/allura/config/middleware.py
----------------------------------------------------------------------
diff --git a/Allura/allura/config/middleware.py b/Allura/allura/config/middleware.py
index 1e9b0c7..7395f93 100644
--- a/Allura/allura/config/middleware.py
+++ b/Allura/allura/config/middleware.py
@@ -161,15 +161,17 @@ def _make_core_app(root, global_conf, full_stack=True, **app_conf):
# streaming=true ensures they won't be cleaned up till
# the WSGI application's iterator is exhausted
app = RegistryManager(app, streaming=True)
- # Make sure that the wsgi.scheme is set appropriately when we
- # have the funky HTTP_X_SFINC_SSL environ var
- if asbool(app_conf.get('auth.method', 'local')=='sfx'):
- app = set_scheme_middleware(app)
# "task" wsgi would get a 2nd request to /error/document if we used this middleware
if config.get('override_root') != 'task':
# Converts exceptions to HTTP errors, shows traceback in debug mode
tg.error.footer_html = '<!-- %s %s -->' # don't use TG footer with extra CSS & images that take time to load
app = tg.error.ErrorHandler(app, global_conf, **config['pylons.errorware'])
+
+ # Make sure that the wsgi.scheme is set appropriately when we
+ # have the funky HTTP_X_SFINC_SSL environ var
+ if asbool(app_conf.get('auth.method', 'local')=='sfx'):
+ app = set_scheme_middleware(app)
+
# Redirect some status codes to /error/document
if asbool(config['debug']):
app = StatusCodeRedirect(app, base_config.handle_status_codes)