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/07/23 04:52:44 UTC
[1/9] git commit: [#6456] Changed target_app to allow list and added
by_app to ToolImporter
Updated Branches:
refs/heads/master b2a00e822 -> 5f68604db
[#6456] Changed target_app to allow list and added by_app to ToolImporter
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/138f4318
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/138f4318
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/138f4318
Branch: refs/heads/master
Commit: 138f4318526e5d3c6e2387e905793c48eef8b120
Parents: f690652
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jul 22 21:43:49 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Jul 23 02:45:41 2013 +0000
----------------------------------------------------------------------
ForgeImporters/forgeimporters/base.py | 14 +++++-
.../forgeimporters/tests/test_base.py | 48 ++++++++++++++++----
2 files changed, 50 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/138f4318/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index 01e614a..6632f37 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -18,6 +18,7 @@
from pkg_resources import iter_entry_points
from tg import expose
+from paste.deploy.converters import aslist
from formencode import validators as fev
from ming.utils import LazyProperty
@@ -77,6 +78,15 @@ class ToolImporter(object):
for ep in iter_entry_points('allura.importers', name):
return ep.load()()
+ @classmethod
+ def by_app(self, app):
+ importers = {}
+ for ep in iter_entry_points('allura.importers'):
+ importer = ep.load()
+ if app in aslist(importer.target_app):
+ importers[ep.name] = importer()
+ return importers
+
def import_tool(self, project=None, mount_point=None):
"""
Override this method to perform the tool import.
@@ -85,11 +95,11 @@ class ToolImporter(object):
@property
def tool_label(self):
- return getattr(self.target_app, 'tool_label', None)
+ return getattr(aslist(self.target_app)[0], 'tool_label', None)
@property
def tool_description(self):
- return getattr(self.target_app, 'tool_description', None)
+ return getattr(aslist(self.target_app)[0], 'tool_description', None)
class ToolsValidator(fev.Set):
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/138f4318/ForgeImporters/forgeimporters/tests/test_base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/test_base.py b/ForgeImporters/forgeimporters/tests/test_base.py
index a6a4d18..64096fd 100644
--- a/ForgeImporters/forgeimporters/tests/test_base.py
+++ b/ForgeImporters/forgeimporters/tests/test_base.py
@@ -23,17 +23,20 @@ import mock
from .. import base
-def ep(name, source=None):
- mep = mock.Mock(name='mock_ep')
+def ep(name, source=None, importer=None, **kw):
+ mep = mock.Mock(name='mock_ep', **kw)
mep.name = name
- mep.load.return_value.source = source
- mep.lv = mep.load.return_value.return_value
- mep.lv.source = source
+ if importer is not None:
+ mep.load.return_value = importer
+ else:
+ mep.load.return_value.source = source
+ mep.lv = mep.load.return_value.return_value
+ mep.lv.source = source
return mep
class TestProjectImporterDispatcher(TestCase):
- @mock.patch('forgeimporters.base.iter_entry_points')
+ @mock.patch.object(base, 'iter_entry_points')
def test_lookup(self, iep):
eps = iep.return_value = [ep('ep1', 'first'), ep('ep2', 'second')]
result = base.ProjectImporterDispatcher()._lookup('source', 'rest1', 'rest2')
@@ -42,7 +45,7 @@ class TestProjectImporterDispatcher(TestCase):
class TestProjectImporter(TestCase):
- @mock.patch('forgeimporters.base.iter_entry_points')
+ @mock.patch.object(base, '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()
@@ -51,16 +54,24 @@ class TestProjectImporter(TestCase):
iep.assert_called_once_with('allura.importers')
+
+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 = mock.Mock(tool_label='foo', tool_description='foo_desc')
+ target_app = TA1
class TI2(base.ToolImporter):
- target_app = mock.Mock(tool_label='foo', tool_description='foo_desc')
+ target_app = TA2
tool_label = 'bar'
tool_description = 'bar_desc'
- @mock.patch('forgeimporters.base.iter_entry_points')
+ class TI3(base.ToolImporter):
+ target_app = [TA2, TA2]
+
+ @mock.patch.object(base, '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')
@@ -73,13 +84,30 @@ class TestToolImporter(TestCase):
iep.assert_called_once_with('allura.importers', 'other-name')
self.assertEqual(importer, None)
+ @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),
+ ]
+ 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)
+
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')
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')
class TestToolsValidator(TestCase):
[4/9] git commit: [#6456] Changed field names for GC project import
Posted by br...@apache.org.
[#6456] Changed field names for GC project import
Signed-off-by: Cory Johns <cj...@slashdotmedia.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/a5371df3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/a5371df3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/a5371df3
Branch: refs/heads/master
Commit: a5371df3be09ff8bf017057e86570d6ab3a3c1fc
Parents: 7af8206
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jul 22 18:57:20 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Jul 23 02:45:41 2013 +0000
----------------------------------------------------------------------
.../forgeimporters/google/__init__.py | 4 +--
ForgeImporters/forgeimporters/google/project.py | 19 +++++++------
.../google/templates/project.html | 30 ++++++++++----------
3 files changed, 27 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a5371df3/ForgeImporters/forgeimporters/google/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/__init__.py b/ForgeImporters/forgeimporters/google/__init__.py
index e01dcfb..235791f 100644
--- a/ForgeImporters/forgeimporters/google/__init__.py
+++ b/ForgeImporters/forgeimporters/google/__init__.py
@@ -48,8 +48,8 @@ class GoogleCodeProjectExtractor(object):
})
def __init__(self, project, page='project_info'):
- gc_project_name = project.get_tool_data('google-code', 'project_name')
- page = urllib2.urlopen(self.PAGE_MAP[page] % urllib.quote(gc_project_name))
+ project_name = project.get_tool_data('google-code', 'project_name')
+ page = urllib2.urlopen(self.PAGE_MAP[page] % urllib.quote(project_name))
self.project = project
self.page = BeautifulSoup(page)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a5371df3/ForgeImporters/forgeimporters/google/project.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/project.py b/ForgeImporters/forgeimporters/google/project.py
index fdd3c97..ec8de53 100644
--- a/ForgeImporters/forgeimporters/google/project.py
+++ b/ForgeImporters/forgeimporters/google/project.py
@@ -24,6 +24,7 @@ from allura import model as M
from allura.lib.decorators import require_post
from allura.lib.widgets.forms import NeighborhoodProjectShortNameValidator
from allura.lib import helpers as h
+from allura.lib import exceptions
from .. import base
from . import tasks
@@ -32,8 +33,8 @@ from . import tasks
class GoogleCodeProjectForm(schema.Schema):
neighborhood = fev.PlainText(not_empty=True)
- gc_project_name = fev.Regex(r'^[a-z0-9][a-z0-9-]{,61}$', not_empty=True)
- project_unixname = NeighborhoodProjectShortNameValidator()
+ project_name = fev.Regex(r'^[a-z0-9][a-z0-9-]{,61}$', not_empty=True)
+ project_shortname = NeighborhoodProjectShortNameValidator()
tools = base.ToolsValidator('Google Code')
@@ -49,13 +50,13 @@ class GoogleCodeProjectImporter(base.ProjectImporter):
@require_post()
@expose()
@validate(GoogleCodeProjectForm(), error_handler=index)
- def process(self, gc_project_name=None, project_unixname=None, tools=None, **kw):
+ def process(self, project_name=None, project_shortname=None, tools=None, **kw):
neighborhood = M.Neighborhood.query.get(url_prefix='/p/')
- project_name = h.really_unicode(gc_project_name).encode('utf-8')
- project_unixname = h.really_unicode(project_unixname).encode('utf-8').lower()
+ project_name = h.really_unicode(project_name).encode('utf-8')
+ project_shortname = h.really_unicode(project_shortname).encode('utf-8').lower()
try:
- c.project = neighborhood.register_project(project_unixname,
+ c.project = neighborhood.register_project(project_shortname,
project_name=project_name)
except exceptions.ProjectOverlimitError:
flash("You have exceeded the maximum number of projects you are allowed to create", 'error')
@@ -64,11 +65,11 @@ class GoogleCodeProjectImporter(base.ProjectImporter):
flash("Project creation rate limit exceeded. Please try again later.", 'error')
redirect('.')
except Exception as e:
- log.error('error registering project: %s', project_unixname, exc_info=True)
+ log.error('error registering project: %s', project_shortname, exc_info=True)
flash('Internal Error. Please try again later.', 'error')
redirect('.')
- c.project.set_tool_data('google-code', project_name=gc_project_name)
+ c.project.set_tool_data('google-code', project_name=project_name)
tasks.import_project_info.post()
for tool in tools:
tool.import_tool(c.project)
@@ -79,5 +80,5 @@ class GoogleCodeProjectImporter(base.ProjectImporter):
@expose('json:')
@validate(GoogleCodeProjectForm())
- def check_names(self, gc_project_name=None, project_unixname=None, tools=None, **kw):
+ def check_names(self, project_name=None, project_shortname=None, tools=None, **kw):
return c.form_errors
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a5371df3/ForgeImporters/forgeimporters/google/templates/project.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/templates/project.html b/ForgeImporters/forgeimporters/google/templates/project.html
index ae9362a..a98d5ef 100644
--- a/ForgeImporters/forgeimporters/google/templates/project.html
+++ b/ForgeImporters/forgeimporters/google/templates/project.html
@@ -41,19 +41,19 @@
var manual = false;
function suggest_name() {
if (!manual) {
- $('#project_unixname').val($('#gc_project_name').val()).trigger('change');
+ $('#project_shortname').val($('#project_name').val()).trigger('change');
}
}
function check_names() {
var data = {
'neighborhood': $('#neighborhood').val(),
- 'gc_project_name': $('#gc_project_name').val(),
- 'project_unixname': $('#project_unixname').val()
+ 'project_name': $('#project_name').val(),
+ 'project_shortname': $('#project_shortname').val()
};
$.getJSON('check_names', data, function(result) {
- $('#gc_project_name_error').addClass('hidden');
- $('#project_unixname_error').addClass('hidden');
+ $('#project_name_error').addClass('hidden');
+ $('#project_shortname_error').addClass('hidden');
for(var field in result) {
$('#'+field+'_error').text(result[field]).removeClass('hidden');
}
@@ -61,13 +61,13 @@
}
function update_url() {
- $('#url-fragment').text($('#project_unixname').val());
+ $('#url-fragment').text($('#project_shortname').val());
}
$(function() {
- $('#gc_project_name').focus().bind('change keyup', suggest_name);
+ $('#project_name').focus().bind('change keyup', suggest_name);
- $('#project_unixname').bind('change keyup', function(event) {
+ $('#project_shortname').bind('change keyup', function(event) {
if (event.type == 'keyup') {
manual = true;
}
@@ -83,9 +83,9 @@
<label>Google Project Name</label>
</div>
<div class="grid-10">
- <input id="gc_project_name" name="gc_project_name" value="{{c.form_values['gc_project_name']}}"/>
- <div id="gc_project_name_error" class="error{% if not c.form_errors['gc_project_name'] %} hidden{% endif %}">
- {{c.form_errors['gc_project_name']}}
+ <input id="project_name" name="project_name" value="{{c.form_values['project_name']}}"/>
+ <div id="project_name_error" class="error{% if not c.form_errors['project_name'] %} hidden{% endif %}">
+ {{c.form_errors['project_name']}}
</div>
</div>
@@ -93,12 +93,12 @@
<label>URL Name</label>
</div>
<div class="grid-10">
- <input id="project_unixname" name="project_unixname" value="{{c.form_values['project_unixname']}}"/>
- <div id="project_unixname_error" class="error{% if not c.form_errors['project_unixname'] %} hidden{% endif %}">
- {{c.form_errors['project_unixname']}}
+ <input id="project_shortname" name="project_shortname" value="{{c.form_values['project_shortname']}}"/>
+ <div id="project_shortname_error" class="error{% if not c.form_errors['project_shortname'] %} hidden{% endif %}">
+ {{c.form_errors['project_shortname']}}
</div>
<div id="project-url">
- http://{{request.environ['HTTP_HOST']}}{{neighborhood.url()}}<span id="url-fragment">{{c.form_values['project_unixname']}}</span>
+ http://{{request.environ['HTTP_HOST']}}{{neighborhood.url()}}<span id="url-fragment">{{c.form_values['project_shortname']}}</span>
</div>
</div>
{% endblock %}
[3/9] git commit: [#6456] Added missing license header
Posted by br...@apache.org.
[#6456] Added missing license header
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/519f7470
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/519f7470
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/519f7470
Branch: refs/heads/master
Commit: 519f7470faced7405e2775ebfdcf7894babd94d1
Parents: a5371df
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jul 22 18:57:41 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Jul 23 02:45:41 2013 +0000
----------------------------------------------------------------------
.../forgeimporters/tests/google/__init__.py | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/519f7470/ForgeImporters/forgeimporters/tests/google/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/__init__.py b/ForgeImporters/forgeimporters/tests/google/__init__.py
index e69de29..77505f1 100644
--- a/ForgeImporters/forgeimporters/tests/google/__init__.py
+++ b/ForgeImporters/forgeimporters/tests/google/__init__.py
@@ -0,0 +1,17 @@
+# 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.
+
[6/9] git commit: [#6456] Fixed validation of GC import form
Posted by br...@apache.org.
[#6456] Fixed validation of GC import form
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/5f68604d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/5f68604d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/5f68604d
Branch: refs/heads/master
Commit: 5f68604dbc07864302a5c42ae9d71b8b25a52658
Parents: f70ea75
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jul 22 22:53:25 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Jul 23 02:45:42 2013 +0000
----------------------------------------------------------------------
ForgeImporters/forgeimporters/google/project.py | 6 +++++-
ForgeImporters/forgeimporters/google/templates/project.html | 4 +++-
ForgeImporters/forgeimporters/tests/test_base.py | 4 +++-
3 files changed, 11 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5f68604d/ForgeImporters/forgeimporters/google/project.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/project.py b/ForgeImporters/forgeimporters/google/project.py
index 678f16d..c3e4d17 100644
--- a/ForgeImporters/forgeimporters/google/project.py
+++ b/ForgeImporters/forgeimporters/google/project.py
@@ -34,7 +34,11 @@ from . import tasks
class GoogleCodeProjectForm(schema.Schema):
neighborhood = fev.PlainText(not_empty=True)
- project_name = fev.Regex(r'^[a-z0-9][a-z0-9-]{,61}$', not_empty=True)
+ project_name = fev.Regex(r'^[a-z0-9][a-z0-9-]{,61}$',
+ not_empty=True,
+ messages={
+ 'invalid': 'Please use only letters, numbers, and dashes.',
+ })
project_shortname = NeighborhoodProjectShortNameValidator()
tools = base.ToolsValidator('Google Code')
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5f68604d/ForgeImporters/forgeimporters/google/templates/project.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/templates/project.html b/ForgeImporters/forgeimporters/google/templates/project.html
index 614e1cb..2cda0d0 100644
--- a/ForgeImporters/forgeimporters/google/templates/project.html
+++ b/ForgeImporters/forgeimporters/google/templates/project.html
@@ -40,9 +40,11 @@
var manual = false;
function suggest_name() {
+ var $project_shortname = $('#project_shortname');
if (!manual) {
- $('#project_shortname').val($('#project_name').val()).trigger('change');
+ $project_shortname.val($('#project_name').val());
}
+ $project_shortname.trigger('change');
}
function check_names() {
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5f68604d/ForgeImporters/forgeimporters/tests/test_base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/test_base.py b/ForgeImporters/forgeimporters/tests/test_base.py
index 64096fd..303570d 100644
--- a/ForgeImporters/forgeimporters/tests/test_base.py
+++ b/ForgeImporters/forgeimporters/tests/test_base.py
@@ -39,9 +39,11 @@ class TestProjectImporterDispatcher(TestCase):
@mock.patch.object(base, 'iter_entry_points')
def test_lookup(self, iep):
eps = iep.return_value = [ep('ep1', 'first'), ep('ep2', 'second')]
- result = base.ProjectImporterDispatcher()._lookup('source', 'rest1', 'rest2')
+ nbhd = mock.Mock(name='neighborhood')
+ result = base.ProjectImporterDispatcher(nbhd)._lookup('source', 'rest1', 'rest2')
self.assertEqual(result, (eps[0].lv, ('rest1', 'rest2')))
iep.assert_called_once_with('allura.project_importers', 'source')
+ eps[0].load.return_value.assert_called_once_with(nbhd)
class TestProjectImporter(TestCase):
[8/9] git commit: [#6456] Removed unnecessary !important
Posted by br...@apache.org.
[#6456] Removed unnecessary !important
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/f70ea755
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/f70ea755
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/f70ea755
Branch: refs/heads/master
Commit: f70ea755870d647a4791adc64f325d192547281a
Parents: 22c7f70
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jul 22 22:35:15 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Jul 23 02:45:42 2013 +0000
----------------------------------------------------------------------
Allura/allura/nf/allura/css/site_style.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f70ea755/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index 94db371..662b4f6 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -3106,7 +3106,7 @@ ul.dropdown ul li a:hover {
font-size: 18px;
font-weight: 600;
text-shadow: none;
- color: white !important;
+ color: white;
padding: 1em 2em 1em 2em;
text-decoration: none;
-webkit-border-radius: 5px;
[7/9] git commit: [#6456] Fixed GC project importer being tied to
Projects nbhd and added security check
Posted by br...@apache.org.
[#6456] Fixed GC project importer being tied to Projects nbhd and added security check
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/22c7f701
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/22c7f701
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/22c7f701
Branch: refs/heads/master
Commit: 22c7f7012fadca27b1ffce67428bfa254b180a3a
Parents: 788e9e4
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jul 22 22:32:02 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Jul 23 02:45:42 2013 +0000
----------------------------------------------------------------------
Allura/allura/controllers/project.py | 2 +-
ForgeImporters/forgeimporters/base.py | 6 +++++-
ForgeImporters/forgeimporters/google/project.py | 14 ++++++++++----
.../forgeimporters/google/templates/project.html | 2 +-
.../forgeimporters/templates/project_base.html | 2 +-
5 files changed, 18 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/22c7f701/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index a407bba..91d5a4f 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -74,7 +74,7 @@ class NeighborhoodController(object):
self.browse = NeighborhoodProjectBrowseController(neighborhood=self.neighborhood)
self._admin = NeighborhoodAdminController(self.neighborhood)
self._moderate = NeighborhoodModerateController(self.neighborhood)
- self.import_project = ProjectImporterDispatcher()
+ self.import_project = ProjectImporterDispatcher(self.neighborhood)
def _check_security(self):
require_access(self.neighborhood, 'read')
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/22c7f701/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index 6632f37..334b89a 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -26,10 +26,14 @@ from allura.controllers import BaseController
class ProjectImporterDispatcher(BaseController):
+ def __init__(self, neighborhood, *a, **kw):
+ super(ProjectImporterDispatcher, self).__init__(*a, **kw)
+ self.neighborhood = neighborhood
+
@expose()
def _lookup(self, source, *rest):
for ep in iter_entry_points('allura.project_importers', source):
- return ep.load()(), rest
+ return ep.load()(self.neighborhood), rest
class ProjectImporter(BaseController):
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/22c7f701/ForgeImporters/forgeimporters/google/project.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/project.py b/ForgeImporters/forgeimporters/google/project.py
index 057115f..678f16d 100644
--- a/ForgeImporters/forgeimporters/google/project.py
+++ b/ForgeImporters/forgeimporters/google/project.py
@@ -23,6 +23,7 @@ from formencode import validators as fev, schema
from allura import model as M
from allura.lib.decorators import require_post
from allura.lib.widgets.forms import NeighborhoodProjectShortNameValidator
+from allura.lib.security import require_access
from allura.lib import helpers as h
from allura.lib import exceptions
@@ -41,22 +42,27 @@ class GoogleCodeProjectForm(schema.Schema):
class GoogleCodeProjectImporter(base.ProjectImporter):
source = 'Google Code'
+ def __init__(self, neighborhood, *a, **kw):
+ super(GoogleCodeProjectImporter, self).__init__(*a, **kw)
+ self.neighborhood = neighborhood
+
+ def _check_security(self):
+ require_access(self.neighborhood, 'register')
+
@with_trailing_slash
@expose('jinja:forgeimporters.google:templates/project.html')
def index(self, **kw):
- neighborhood = M.Neighborhood.query.get(url_prefix='/p/')
- return {'importer': self, 'neighborhood': neighborhood}
+ return {'importer': self}
@require_post()
@expose()
@validate(GoogleCodeProjectForm(), error_handler=index)
def process(self, project_name=None, project_shortname=None, tools=None, **kw):
- neighborhood = M.Neighborhood.query.get(url_prefix='/p/')
project_name = h.really_unicode(project_name).encode('utf-8')
project_shortname = h.really_unicode(project_shortname).encode('utf-8').lower()
try:
- c.project = neighborhood.register_project(project_shortname,
+ c.project = self.neighborhood.register_project(project_shortname,
project_name=project_name)
except exceptions.ProjectOverlimitError:
flash("You have exceeded the maximum number of projects you are allowed to create", 'error')
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/22c7f701/ForgeImporters/forgeimporters/google/templates/project.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/templates/project.html b/ForgeImporters/forgeimporters/google/templates/project.html
index a98d5ef..614e1cb 100644
--- a/ForgeImporters/forgeimporters/google/templates/project.html
+++ b/ForgeImporters/forgeimporters/google/templates/project.html
@@ -98,7 +98,7 @@
{{c.form_errors['project_shortname']}}
</div>
<div id="project-url">
- http://{{request.environ['HTTP_HOST']}}{{neighborhood.url()}}<span id="url-fragment">{{c.form_values['project_shortname']}}</span>
+ http://{{request.environ['HTTP_HOST']}}{{importer.neighborhood.url()}}<span id="url-fragment">{{c.form_values['project_shortname']}}</span>
</div>
</div>
{% endblock %}
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/22c7f701/ForgeImporters/forgeimporters/templates/project_base.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/templates/project_base.html b/ForgeImporters/forgeimporters/templates/project_base.html
index d42954f..bd37665 100644
--- a/ForgeImporters/forgeimporters/templates/project_base.html
+++ b/ForgeImporters/forgeimporters/templates/project_base.html
@@ -26,7 +26,7 @@
{% block content %}
<form id="project-import-form" method="POST" action="process">
- <input type="hidden" id="neighborhood" name="neighborhood" value="Projects"/>
+ <input type="hidden" id="neighborhood" name="neighborhood" value="{{importer.neighborhood.name}}"/>
<fieldset id="project-fields">
{% block project_fields %}{% endblock %}
[2/9] git commit: [#6456] Changed import_tool call to task in GC
project importer
Posted by br...@apache.org.
[#6456] Changed import_tool call to task in GC project importer
Signed-off-by: Cory Johns <cj...@slashdotmedia.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/f6906522
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/f6906522
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/f6906522
Branch: refs/heads/master
Commit: f690652203ff7666a4633116b7a44d715936ec44
Parents: 519f747
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jul 22 20:33:44 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Jul 23 02:45:41 2013 +0000
----------------------------------------------------------------------
ForgeImporters/forgeimporters/base.py | 22 ++++---
ForgeImporters/forgeimporters/google/project.py | 4 +-
ForgeImporters/forgeimporters/google/tasks.py | 6 ++
.../forgeimporters/tests/google/test_tasks.py | 9 +++
.../forgeimporters/tests/test_base.py | 66 ++++++++++++--------
5 files changed, 69 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f6906522/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index c3b6946..01e614a 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -68,10 +68,15 @@ class ProjectImporter(BaseController):
class ToolImporter(object):
- target_app = None
- source = None
+ target_app = None # app or list of apps
+ source = None # string description of source, must match project importer
controller = None
+ @classmethod
+ def by_name(self, name):
+ for ep in iter_entry_points('allura.importers', name):
+ return ep.load()()
+
def import_tool(self, project=None, mount_point=None):
"""
Override this method to perform the tool import.
@@ -96,15 +101,12 @@ class ToolsValidator(fev.Set):
value = super(ToolsValidator, self).to_python(value, state)
valid = []
invalid = []
- for i, v in enumerate(value):
- try:
- ep = iter_entry_points('allura.importers', v).next().load()
- except StopIteration:
- ep = None
- if getattr(ep, 'source', None) != self.source:
- invalid.append(v)
+ for name in value:
+ importer = ToolImporter.by_name(name)
+ if importer is not None and importer.source == self.source:
+ valid.append(name)
else:
- valid.append(ep())
+ invalid.append(name)
if invalid:
pl = 's' if len(invalid) > 1 else ''
raise fev.Invalid('Invalid tool%s selected: %s' % (pl, ', '.join(invalid)), value, state)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f6906522/ForgeImporters/forgeimporters/google/project.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/project.py b/ForgeImporters/forgeimporters/google/project.py
index ec8de53..caf1346 100644
--- a/ForgeImporters/forgeimporters/google/project.py
+++ b/ForgeImporters/forgeimporters/google/project.py
@@ -71,8 +71,8 @@ class GoogleCodeProjectImporter(base.ProjectImporter):
c.project.set_tool_data('google-code', project_name=project_name)
tasks.import_project_info.post()
- for tool in tools:
- tool.import_tool(c.project)
+ for importer_name in tools:
+ tasks.import_tool.post(importer_name)
flash('Welcome to the SourceForge Project System! '
'Your project data will be imported and should show up here shortly.')
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f6906522/ForgeImporters/forgeimporters/google/tasks.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tasks.py b/ForgeImporters/forgeimporters/google/tasks.py
index 79851c3..834dc9d 100644
--- a/ForgeImporters/forgeimporters/google/tasks.py
+++ b/ForgeImporters/forgeimporters/google/tasks.py
@@ -22,6 +22,7 @@ from ming.orm import ThreadLocalORMSession
from allura.lib.decorators import task
from . import GoogleCodeProjectExtractor
+from ..base import ToolImporter
@task
@@ -31,3 +32,8 @@ def import_project_info():
extractor.get_icon()
extractor.get_license()
ThreadLocalORMSession.flush_all()
+
+@task
+def import_tool(importer_name, mount_point=None, mount_label=None):
+ importer = ToolImporter.by_name(importer_name)
+ importer.import_tool(c.project, mount_point, mount_label)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f6906522/ForgeImporters/forgeimporters/tests/google/test_tasks.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_tasks.py b/ForgeImporters/forgeimporters/tests/google/test_tasks.py
index a21d083..bb9319d 100644
--- a/ForgeImporters/forgeimporters/tests/google/test_tasks.py
+++ b/ForgeImporters/forgeimporters/tests/google/test_tasks.py
@@ -31,3 +31,12 @@ def test_import_project_info(c, session, gpe):
gpe.return_value.get_icon.assert_called_once_with()
gpe.return_value.get_license.assert_called_once_with()
session.flush_all.assert_called_once_with()
+
+
+@mock.patch.object(tasks.ToolImporter, 'by_name')
+@mock.patch.object(tasks, 'c')
+def test_import_tool(c, by_name):
+ c.project = mock.Mock(name='project')
+ tasks.import_tool('importer_name', 'mount_point', 'mount_label')
+ by_name.assert_called_once_with('importer_name')
+ by_name.return_value.import_tool.assert_called_once_with(c.project, 'mount_point', 'mount_label')
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f6906522/ForgeImporters/forgeimporters/tests/test_base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/test_base.py b/ForgeImporters/forgeimporters/tests/test_base.py
index 394723d..a6a4d18 100644
--- a/ForgeImporters/forgeimporters/tests/test_base.py
+++ b/ForgeImporters/forgeimporters/tests/test_base.py
@@ -28,6 +28,7 @@ def ep(name, source=None):
mep.name = name
mep.load.return_value.source = source
mep.lv = mep.load.return_value.return_value
+ mep.lv.source = source
return mep
@@ -50,7 +51,7 @@ class TestProjectImporter(TestCase):
iep.assert_called_once_with('allura.importers')
-class TestImporter(TestCase):
+class TestToolImporter(TestCase):
class TI1(base.ToolImporter):
target_app = mock.Mock(tool_label='foo', tool_description='foo_desc')
@@ -59,6 +60,19 @@ class TestImporter(TestCase):
tool_label = 'bar'
tool_description = 'bar_desc'
+ @mock.patch('forgeimporters.base.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')
+ iep.assert_called_once_with('allura.importers', 'my-name')
+ self.assertEqual(importer, eps[0].lv)
+
+ iep.reset_mock()
+ iep.return_value = []
+ importer = base.ToolImporter.by_name('other-name')
+ iep.assert_called_once_with('allura.importers', 'other-name')
+ self.assertEqual(importer, None)
+
def test_tool_label(self):
self.assertEqual(self.TI1().tool_label, 'foo')
self.assertEqual(self.TI2().tool_label, 'bar')
@@ -72,44 +86,44 @@ class TestToolsValidator(TestCase):
def setUp(self):
self.tv = base.ToolsValidator('good-source')
- @mock.patch('forgeimporters.base.iter_entry_points')
- def test_empty(self, iep):
+ @mock.patch.object(base.ToolImporter, 'by_name')
+ def test_empty(self, by_name):
self.assertEqual(self.tv.to_python(''), [])
- self.assertEqual(iep.call_count, 0)
+ self.assertEqual(by_name.call_count, 0)
- @mock.patch('forgeimporters.base.iter_entry_points')
- def test_no_ep(self, iep):
- eps = iep.return_value.next.side_effect = StopIteration
+ @mock.patch.object(base.ToolImporter, 'by_name')
+ def test_no_ep(self, by_name):
+ eps = by_name.return_value = None
with self.assertRaises(Invalid) as cm:
self.tv.to_python('my-value')
self.assertEqual(cm.exception.msg, 'Invalid tool selected: my-value')
- iep.assert_called_once_with('allura.importers', 'my-value')
+ by_name.assert_called_once_with('my-value')
- @mock.patch('forgeimporters.base.iter_entry_points')
- def test_bad_source(self, iep):
- eps = iep.return_value.next.side_effect = [ep('ep1', 'bad-source'), ep('ep2', 'good-source')]
+ @mock.patch.object(base.ToolImporter, 'by_name')
+ def test_bad_source(self, by_name):
+ eps = by_name.return_value = ep('ep1', 'bad-source').lv
with self.assertRaises(Invalid) as cm:
self.tv.to_python('my-value')
self.assertEqual(cm.exception.msg, 'Invalid tool selected: my-value')
- iep.assert_called_once_with('allura.importers', 'my-value')
+ by_name.assert_called_once_with('my-value')
- @mock.patch('forgeimporters.base.iter_entry_points')
- def test_multiple(self, iep):
- eps = iep.return_value.next.side_effect = [ep('ep1', 'bad-source'), ep('ep2', 'good-source'), ep('ep3', 'bad-source')]
+ @mock.patch.object(base.ToolImporter, 'by_name')
+ def test_multiple(self, by_name):
+ eps = by_name.side_effect = [ep('ep1', 'bad-source').lv, ep('ep2', 'good-source').lv, ep('ep3', 'bad-source').lv]
with self.assertRaises(Invalid) as cm:
self.tv.to_python(['value1', 'value2', 'value3'])
self.assertEqual(cm.exception.msg, 'Invalid tools selected: value1, value3')
- self.assertEqual(iep.call_args_list, [
- mock.call('allura.importers', 'value1'),
- mock.call('allura.importers', 'value2'),
- mock.call('allura.importers', 'value3'),
+ self.assertEqual(by_name.call_args_list, [
+ mock.call('value1'),
+ mock.call('value2'),
+ mock.call('value3'),
])
- @mock.patch('forgeimporters.base.iter_entry_points')
- def test_valid(self, iep):
- eps = iep.return_value.next.side_effect = [ep('ep1', 'good-source'), ep('ep2', 'good-source'), ep('ep3', 'bad-source')]
- self.assertEqual(self.tv.to_python(['value1', 'value2']), [eps[0].lv, eps[1].lv])
- self.assertEqual(iep.call_args_list, [
- mock.call('allura.importers', 'value1'),
- mock.call('allura.importers', 'value2'),
+ @mock.patch.object(base.ToolImporter, 'by_name')
+ def test_valid(self, by_name):
+ eps = by_name.side_effect = [ep('ep1', 'good-source').lv, ep('ep2', 'good-source').lv, ep('ep3', 'bad-source').lv]
+ self.assertEqual(self.tv.to_python(['value1', 'value2']), ['value1', 'value2'])
+ self.assertEqual(by_name.call_args_list, [
+ mock.call('value1'),
+ mock.call('value2'),
])
[5/9] git commit: [#6456] Added Google Code project importer
Posted by br...@apache.org.
[#6456] Added Google Code project importer
Signed-off-by: Cory Johns <cj...@slashdotmedia.com>
Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/7af82067
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/7af82067
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/7af82067
Branch: refs/heads/master
Commit: 7af82067e7802e2f3a27041f4cc85d67e6d4c291
Parents: b2a00e8
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Fri Jul 19 19:21:05 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Jul 23 02:45:41 2013 +0000
----------------------------------------------------------------------
.../forgeimporters/google/__init__.py | 17 +--
ForgeImporters/forgeimporters/google/project.py | 83 +++++++++++++++
ForgeImporters/forgeimporters/google/tasks.py | 33 ++++++
.../google/templates/project.html | 104 +++++++++++++++++++
.../forgeimporters/tests/google/__init__.py | 0
.../tests/google/test_extractor.py | 93 +++++++++++++++++
.../forgeimporters/tests/google/test_tasks.py | 33 ++++++
ForgeImporters/setup.py | 1 +
8 files changed, 358 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7af82067/ForgeImporters/forgeimporters/google/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/__init__.py b/ForgeImporters/forgeimporters/google/__init__.py
index 0feb64a..e01dcfb 100644
--- a/ForgeImporters/forgeimporters/google/__init__.py
+++ b/ForgeImporters/forgeimporters/google/__init__.py
@@ -19,6 +19,10 @@ import urllib
import urllib2
from urlparse import urlparse
from collections import defaultdict
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from StringIO import StringIO
from BeautifulSoup import BeautifulSoup
@@ -50,19 +54,20 @@ class GoogleCodeProjectExtractor(object):
self.page = BeautifulSoup(page)
def get_short_description(self):
- self.project.short_description = str(self.page.find(itemprop='description')).strip()
+ self.project.short_description = self.page.find(itemprop='description').string.strip()
def get_icon(self):
- icon_url = self.page.find(itemprop='image').src
+ icon_url = self.page.find(itemprop='image').attrMap['src']
icon_name = urllib.unquote(urlparse(icon_url).path).split('/')[-1]
- fp = urllib2.urlopen(icon_url)
+ fp_ish = urllib2.urlopen(icon_url)
+ fp = StringIO(fp_ish.read())
M.ProjectFile.save_image(
- icon_name, fp, fp.info()['content-type'], square=True,
+ icon_name, fp, fp_ish.info()['content-type'], square=True,
thumbnail_size=(48,48),
- thumbnail_meta=dict(project_id=self.project._id, category='icon'))
+ thumbnail_meta={'project_id': self.project._id, 'category': 'icon'})
def get_license(self):
- license = str(self.page.find(text='Code license:').findNext('td')).strip()
+ license = self.page.find(text='Code license').findNext().find('a').string.strip()
trove = M.TroveCategory.query.get(fullname=self.LICENSE_MAP[license])
self.project.trove_license.append(trove._id)
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7af82067/ForgeImporters/forgeimporters/google/project.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/project.py b/ForgeImporters/forgeimporters/google/project.py
new file mode 100644
index 0000000..fdd3c97
--- /dev/null
+++ b/ForgeImporters/forgeimporters/google/project.py
@@ -0,0 +1,83 @@
+# 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.
+
+from tg import expose, validate, flash, redirect
+from tg.decorators import with_trailing_slash
+from pylons import tmpl_context as c
+from formencode import validators as fev, schema
+
+from allura import model as M
+from allura.lib.decorators import require_post
+from allura.lib.widgets.forms import NeighborhoodProjectShortNameValidator
+from allura.lib import helpers as h
+
+from .. import base
+from . import tasks
+
+
+
+class GoogleCodeProjectForm(schema.Schema):
+ neighborhood = fev.PlainText(not_empty=True)
+ gc_project_name = fev.Regex(r'^[a-z0-9][a-z0-9-]{,61}$', not_empty=True)
+ project_unixname = NeighborhoodProjectShortNameValidator()
+ tools = base.ToolsValidator('Google Code')
+
+
+class GoogleCodeProjectImporter(base.ProjectImporter):
+ source = 'Google Code'
+
+ @with_trailing_slash
+ @expose('jinja:forgeimporters.google:templates/project.html')
+ def index(self, **kw):
+ neighborhood = M.Neighborhood.query.get(url_prefix='/p/')
+ return {'importer': self, 'neighborhood': neighborhood}
+
+ @require_post()
+ @expose()
+ @validate(GoogleCodeProjectForm(), error_handler=index)
+ def process(self, gc_project_name=None, project_unixname=None, tools=None, **kw):
+ neighborhood = M.Neighborhood.query.get(url_prefix='/p/')
+ project_name = h.really_unicode(gc_project_name).encode('utf-8')
+ project_unixname = h.really_unicode(project_unixname).encode('utf-8').lower()
+
+ try:
+ c.project = neighborhood.register_project(project_unixname,
+ project_name=project_name)
+ except exceptions.ProjectOverlimitError:
+ flash("You have exceeded the maximum number of projects you are allowed to create", 'error')
+ redirect('.')
+ except exceptions.ProjectRatelimitError:
+ flash("Project creation rate limit exceeded. Please try again later.", 'error')
+ redirect('.')
+ except Exception as e:
+ log.error('error registering project: %s', project_unixname, exc_info=True)
+ flash('Internal Error. Please try again later.', 'error')
+ redirect('.')
+
+ c.project.set_tool_data('google-code', project_name=gc_project_name)
+ tasks.import_project_info.post()
+ for tool in tools:
+ tool.import_tool(c.project)
+
+ flash('Welcome to the SourceForge Project System! '
+ 'Your project data will be imported and should show up here shortly.')
+ redirect(c.project.script_name + 'admin/overview')
+
+ @expose('json:')
+ @validate(GoogleCodeProjectForm())
+ def check_names(self, gc_project_name=None, project_unixname=None, tools=None, **kw):
+ return c.form_errors
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7af82067/ForgeImporters/forgeimporters/google/tasks.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tasks.py b/ForgeImporters/forgeimporters/google/tasks.py
new file mode 100644
index 0000000..79851c3
--- /dev/null
+++ b/ForgeImporters/forgeimporters/google/tasks.py
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+from pylons import tmpl_context as c
+
+from ming.orm import ThreadLocalORMSession
+
+from allura.lib.decorators import task
+
+from . import GoogleCodeProjectExtractor
+
+
+@task
+def import_project_info():
+ extractor = GoogleCodeProjectExtractor(c.project, 'project_info')
+ extractor.get_short_description()
+ extractor.get_icon()
+ extractor.get_license()
+ ThreadLocalORMSession.flush_all()
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7af82067/ForgeImporters/forgeimporters/google/templates/project.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/templates/project.html b/ForgeImporters/forgeimporters/google/templates/project.html
new file mode 100644
index 0000000..ae9362a
--- /dev/null
+++ b/ForgeImporters/forgeimporters/google/templates/project.html
@@ -0,0 +1,104 @@
+{#-
+ 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/project_base.html' %}
+
+{% block extra_css %}
+ {{ super() }}
+ <style type="text/css">
+ #project-import-form #project-fields input {
+ width: 88%;
+ }
+
+ .hidden { display: none; }
+ </style>
+{% endblock %}
+
+{% block extra_js %}
+ {{ super() }}
+ <script type="text/javascript">
+ var timers = {};
+ function delay(callback, ms) {
+ clearTimeout(timers[callback]);
+ timers[callback] = setTimeout(callback, ms);
+ }
+
+ var manual = false;
+ function suggest_name() {
+ if (!manual) {
+ $('#project_unixname').val($('#gc_project_name').val()).trigger('change');
+ }
+ }
+
+ function check_names() {
+ var data = {
+ 'neighborhood': $('#neighborhood').val(),
+ 'gc_project_name': $('#gc_project_name').val(),
+ 'project_unixname': $('#project_unixname').val()
+ };
+ $.getJSON('check_names', data, function(result) {
+ $('#gc_project_name_error').addClass('hidden');
+ $('#project_unixname_error').addClass('hidden');
+ for(var field in result) {
+ $('#'+field+'_error').text(result[field]).removeClass('hidden');
+ }
+ });
+ }
+
+ function update_url() {
+ $('#url-fragment').text($('#project_unixname').val());
+ }
+
+ $(function() {
+ $('#gc_project_name').focus().bind('change keyup', suggest_name);
+
+ $('#project_unixname').bind('change keyup', function(event) {
+ if (event.type == 'keyup') {
+ manual = true;
+ }
+ update_url();
+ delay(check_names, 500);
+ });
+ });
+ </script>
+{% endblock %}
+
+{% block project_fields %}
+ <div class="grid-6">
+ <label>Google Project Name</label>
+ </div>
+ <div class="grid-10">
+ <input id="gc_project_name" name="gc_project_name" value="{{c.form_values['gc_project_name']}}"/>
+ <div id="gc_project_name_error" class="error{% if not c.form_errors['gc_project_name'] %} hidden{% endif %}">
+ {{c.form_errors['gc_project_name']}}
+ </div>
+ </div>
+
+ <div class="grid-6" style="clear:left">
+ <label>URL Name</label>
+ </div>
+ <div class="grid-10">
+ <input id="project_unixname" name="project_unixname" value="{{c.form_values['project_unixname']}}"/>
+ <div id="project_unixname_error" class="error{% if not c.form_errors['project_unixname'] %} hidden{% endif %}">
+ {{c.form_errors['project_unixname']}}
+ </div>
+ <div id="project-url">
+ http://{{request.environ['HTTP_HOST']}}{{neighborhood.url()}}<span id="url-fragment">{{c.form_values['project_unixname']}}</span>
+ </div>
+ </div>
+{% endblock %}
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7af82067/ForgeImporters/forgeimporters/tests/google/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/__init__.py b/ForgeImporters/forgeimporters/tests/google/__init__.py
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7af82067/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
new file mode 100644
index 0000000..f03c82c
--- /dev/null
+++ b/ForgeImporters/forgeimporters/tests/google/test_extractor.py
@@ -0,0 +1,93 @@
+# 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.
+
+from unittest import TestCase
+
+import mock
+
+from ... import google
+
+
+class TestGoogleCodeProjectExtractor(TestCase):
+ def setUp(self):
+ self._p_urlopen = mock.patch.object(google.urllib2, 'urlopen')
+ self._p_soup = mock.patch.object(google, 'BeautifulSoup')
+ self.urlopen = self._p_urlopen.start()
+ self.soup = self._p_soup.start()
+ self.project = mock.Mock(name='project')
+ self.project.get_tool_data.return_value = 'my-project'
+
+ def tearDown(self):
+ self._p_urlopen.stop()
+ self._p_soup.stop()
+
+ def test_init(self):
+ extractor = google.GoogleCodeProjectExtractor(self.project, 'project_info')
+
+ self.project.get_tool_data.assert_called_once_with('google-code', 'project_name')
+ self.urlopen.assert_called_once_with('http://code.google.com/p/my-project/')
+ self.assertEqual(extractor.project, self.project)
+ self.soup.assert_called_once_with(self.urlopen.return_value)
+ self.assertEqual(extractor.page, self.soup.return_value)
+
+ def test_get_short_description(self):
+ extractor = google.GoogleCodeProjectExtractor(self.project, 'project_info')
+ extractor.page.find.return_value.string = 'My Super Project'
+
+ extractor.get_short_description()
+
+ extractor.page.find.assert_called_once_with(itemprop='description')
+ self.assertEqual(self.project.short_description, 'My Super Project')
+
+ @mock.patch.object(google, 'StringIO')
+ @mock.patch.object(google, 'M')
+ def test_get_icon(self, M, StringIO):
+ self.urlopen.return_value.info.return_value = {'content-type': 'image/png'}
+ extractor = google.GoogleCodeProjectExtractor(self.project, 'project_info')
+ extractor.page.find.return_value.attrMap = {'src': 'http://example.com/foo/bar/my-logo.png'}
+ self.urlopen.reset_mock()
+
+ extractor.get_icon()
+
+ extractor.page.find.assert_called_once_with(itemprop='image')
+ self.urlopen.assert_called_once_with('http://example.com/foo/bar/my-logo.png')
+ self.urlopen.return_value.info.assert_called_once_with()
+ StringIO.assert_called_once_with(self.urlopen.return_value.read.return_value)
+ M.ProjectFile.save_image.assert_called_once_with(
+ 'my-logo.png', StringIO.return_value, 'image/png', square=True,
+ thumbnail_size=(48,48), thumbnail_meta={
+ 'project_id': self.project._id, 'category': 'icon'})
+
+ @mock.patch.object(google, 'M')
+ def test_get_license(self, M):
+ self.project.trove_license = []
+ extractor = google.GoogleCodeProjectExtractor(self.project, 'project_info')
+ extractor.page.find.return_value.findNext.return_value.find.return_value.string = ' New BSD License '
+ trove = M.TroveCategory.query.get.return_value
+
+ extractor.get_license()
+
+ extractor.page.find.assert_called_once_with(text='Code license')
+ extractor.page.find.return_value.findNext.assert_called_once_with()
+ extractor.page.find.return_value.findNext.return_value.find.assert_called_once_with('a')
+ self.assertEqual(self.project.trove_license, [trove._id])
+ M.TroveCategory.query.get.assert_called_once_with(fullname='BSD License')
+
+ M.TroveCategory.query.get.reset_mock()
+ extractor.page.find.return_value.findNext.return_value.find.return_value.string = 'non-existant license'
+ extractor.get_license()
+ M.TroveCategory.query.get.assert_called_once_with(fullname='Other/Proprietary License')
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7af82067/ForgeImporters/forgeimporters/tests/google/test_tasks.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_tasks.py b/ForgeImporters/forgeimporters/tests/google/test_tasks.py
new file mode 100644
index 0000000..a21d083
--- /dev/null
+++ b/ForgeImporters/forgeimporters/tests/google/test_tasks.py
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import mock
+
+from ...google import tasks
+
+
+@mock.patch.object(tasks, 'GoogleCodeProjectExtractor')
+@mock.patch.object(tasks, 'ThreadLocalORMSession')
+@mock.patch.object(tasks, 'c')
+def test_import_project_info(c, session, gpe):
+ c.project = mock.Mock(name='project')
+ tasks.import_project_info()
+ gpe.assert_called_once_with(c.project, 'project_info')
+ gpe.return_value.get_short_description.assert_called_once_with()
+ gpe.return_value.get_icon.assert_called_once_with()
+ gpe.return_value.get_license.assert_called_once_with()
+ session.flush_all.assert_called_once_with()
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7af82067/ForgeImporters/setup.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/setup.py b/ForgeImporters/setup.py
index 5e45638..a928504 100644
--- a/ForgeImporters/setup.py
+++ b/ForgeImporters/setup.py
@@ -34,6 +34,7 @@ setup(name='ForgeImporters',
entry_points="""
# -*- Entry points: -*-
[allura.project_importers]
+ google-code = forgeimporters.google.project:GoogleCodeProjectImporter
[allura.importers]
""",)
[9/9] git commit: [#6456] Removed hard-coded reference to SourceForge
Posted by br...@apache.org.
[#6456] Removed hard-coded reference to SourceForge
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/788e9e41
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/788e9e41
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/788e9e41
Branch: refs/heads/master
Commit: 788e9e41bdcffa9f9bdd2e64a252b33a835b202d
Parents: 138f431
Author: Cory Johns <cj...@slashdotmedia.com>
Authored: Mon Jul 22 21:58:50 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Tue Jul 23 02:45:42 2013 +0000
----------------------------------------------------------------------
Allura/allura/controllers/project.py | 4 ++--
Allura/development.ini | 1 +
Allura/test.ini | 1 +
ForgeImporters/forgeimporters/google/project.py | 6 +++---
4 files changed, 7 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/788e9e41/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 24bba79..a407bba 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -225,8 +225,8 @@ class NeighborhoodController(object):
for i, tool in enumerate(tools):
if (tool.lower() not in anchored_tools.keys()) and (c.project.app_instance(tool) is None):
c.project.install_app(tool, ordinal=i + offset)
- flash('Welcome to the SourceForge Project System! '
- 'To get started, fill out some information about your project.')
+ flash('Welcome to the %s Project System! '
+ 'To get started, fill out some information about your project.' % config['site_name'])
redirect(c.project.script_name + 'admin/overview')
@expose()
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/788e9e41/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index ab0877c..338b8ee 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -46,6 +46,7 @@ next=main
use = egg:Allura
full_stack = true
use_queue = true
+site_name = Allura
base_url = http://localhost:8080
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/788e9e41/Allura/test.ini
----------------------------------------------------------------------
diff --git a/Allura/test.ini b/Allura/test.ini
index f1bd5f2..7394359 100644
--- a/Allura/test.ini
+++ b/Allura/test.ini
@@ -37,6 +37,7 @@ port = 5000
use = config:development.ini#tool_test
db_prefix = test_
+site_name = Allura
base_url = http://localhost
# Use test MongoDB DB server
http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/788e9e41/ForgeImporters/forgeimporters/google/project.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/project.py b/ForgeImporters/forgeimporters/google/project.py
index caf1346..057115f 100644
--- a/ForgeImporters/forgeimporters/google/project.py
+++ b/ForgeImporters/forgeimporters/google/project.py
@@ -15,7 +15,7 @@
# specific language governing permissions and limitations
# under the License.
-from tg import expose, validate, flash, redirect
+from tg import expose, validate, flash, redirect, config
from tg.decorators import with_trailing_slash
from pylons import tmpl_context as c
from formencode import validators as fev, schema
@@ -74,8 +74,8 @@ class GoogleCodeProjectImporter(base.ProjectImporter):
for importer_name in tools:
tasks.import_tool.post(importer_name)
- flash('Welcome to the SourceForge Project System! '
- 'Your project data will be imported and should show up here shortly.')
+ flash('Welcome to the %s Project System! '
+ 'Your project data will be imported and should show up here shortly.' % config['site_name'])
redirect(c.project.script_name + 'admin/overview')
@expose('json:')