You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by he...@apache.org on 2015/07/02 17:09:19 UTC
[04/23] allura git commit: [#7884] Add "Project Features"
functionality
[#7884] Add "Project Features" functionality
Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/3bbf0f6d
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/3bbf0f6d
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/3bbf0f6d
Branch: refs/heads/hs/7894
Commit: 3bbf0f6de6dfcbbf33a9c70486b917ebac57ce10
Parents: fbb8da9
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jun 11 15:08:04 2015 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Mon Jun 29 18:04:51 2015 +0000
----------------------------------------------------------------------
Allura/allura/ext/admin/admin_main.py | 13 ++++++++
.../templates/admin_widgets/features_field.html | 32 ++++++++++++++++++++
.../templates/admin_widgets/metadata_admin.html | 7 ++++-
.../ext/admin/templates/project_overview.html | 2 +-
Allura/allura/ext/admin/widgets.py | 18 +++++++++++
Allura/allura/lib/helpers.py | 12 ++++++++
Allura/allura/model/project.py | 1 +
Allura/allura/tests/functional/test_admin.py | 16 ++++++++++
8 files changed, 99 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/allura/blob/3bbf0f6d/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 46cdf9c..5bde57c 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -222,6 +222,10 @@ class ProjectAdminController(BaseController):
def overview(self, **kw):
c.markdown_editor = W.markdown_editor
c.metadata_admin = W.metadata_admin
+ # need this because features field expects data in specific format
+ metadata_admin_value = h.fixed_attrs_proxy(
+ c.project,
+ features=[{'feature': f} for f in c.project.features])
c.explain_export_modal = W.explain_export_modal
show_export_control = asbool(config.get('show_export_control', False))
allow_project_delete = asbool(config.get('allow_project_delete', True))
@@ -236,6 +240,7 @@ class ProjectAdminController(BaseController):
'please contact <a href="mailto:{contact}">{contact}</a>.'.format(contact=config['us_export_contact'])
return dict(show_export_control=show_export_control,
allow_project_delete=allow_project_delete,
+ metadata_admin_value=metadata_admin_value,
explain_export_text=explain_export_text)
@without_trailing_slash
@@ -354,6 +359,7 @@ class ProjectAdminController(BaseController):
@expose()
@require_post()
@validate(W.metadata_admin, error_handler=overview)
+ @h.vardec
def update(self, name=None,
short_description=None,
summary='',
@@ -370,6 +376,7 @@ class ProjectAdminController(BaseController):
export_controlled=False,
export_control_type=None,
tracking_id='',
+ features=None,
**kw):
require_access(c.project, 'update')
@@ -470,6 +477,12 @@ class ProjectAdminController(BaseController):
h.log_action(log, 'change project tracking ID').info('')
M.AuditLog.log('change project tracking ID to %s', tracking_id)
c.project.tracking_id = tracking_id
+ features = [f['feature'].strip() for f in features or []
+ if f.get('feature', '').strip()]
+ if features != c.project.features:
+ h.log_action(log, 'change project features').info('')
+ M.AuditLog.log('change project features to %s', features)
+ c.project.features = features
if icon is not None and icon != '':
if c.project.icon:
http://git-wip-us.apache.org/repos/asf/allura/blob/3bbf0f6d/Allura/allura/ext/admin/templates/admin_widgets/features_field.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/admin_widgets/features_field.html b/Allura/allura/ext/admin/templates/admin_widgets/features_field.html
new file mode 100644
index 0000000..c5ef066
--- /dev/null
+++ b/Allura/allura/ext/admin/templates/admin_widgets/features_field.html
@@ -0,0 +1,32 @@
+{#-
+ 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.
+-#}
+
+<div class="{{css_class}}">
+ {% for f in widget.fields %}
+ {% set ctx=widget.context_for(f) %}
+ <div data-name="{{f.name}}">
+ {% if f.show_label %}
+ <div class="grid-4"><label>{{f.label}}:</label></div>
+ <div class="grid-14">{{f.display(**ctx)}}</div>
+ {% else %}
+ <div>{{f.display(**ctx)}}</div>
+ {% endif %}
+ </div>
+ {% endfor %}
+</div>
http://git-wip-us.apache.org/repos/asf/allura/blob/3bbf0f6d/Allura/allura/ext/admin/templates/admin_widgets/metadata_admin.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/admin_widgets/metadata_admin.html b/Allura/allura/ext/admin/templates/admin_widgets/metadata_admin.html
index 16d1349..a9f9758 100644
--- a/Allura/allura/ext/admin/templates/admin_widgets/metadata_admin.html
+++ b/Allura/allura/ext/admin/templates/admin_widgets/metadata_admin.html
@@ -48,7 +48,12 @@
{{widget.display_field(widget.fields.short_description) }}
<div style="clear:both"> </div>
-
+
+ <fieldset class="preferences">
+ <legend>{{ widget.display_label(widget.fields.features) }}</legend>
+ {{ widget.display_field(widget.fields.features) }}
+ </fieldset>
+
{% if tg.config.get('support_tool_choices') %}
Preferred Support Page (for users of your project):<br>
{% if c.form_errors.get('support_page_url') %}
http://git-wip-us.apache.org/repos/asf/allura/blob/3bbf0f6d/Allura/allura/ext/admin/templates/project_overview.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/project_overview.html b/Allura/allura/ext/admin/templates/project_overview.html
index 3991241..90eca92 100644
--- a/Allura/allura/ext/admin/templates/project_overview.html
+++ b/Allura/allura/ext/admin/templates/project_overview.html
@@ -26,7 +26,7 @@
{% if c.project.deleted %}
<div class="notice">This project has been deleted and is not visible to non-admin users</div>
{% endif %}
- {{c.metadata_admin.display(value=c.project,
+ {{c.metadata_admin.display(value=metadata_admin_value,
show_export_control=show_export_control,
allow_project_delete=allow_project_delete)}}
http://git-wip-us.apache.org/repos/asf/allura/blob/3bbf0f6d/Allura/allura/ext/admin/widgets.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/widgets.py b/Allura/allura/ext/admin/widgets.py
index 5fb5bbd..4ea1fcd 100644
--- a/Allura/allura/ext/admin/widgets.py
+++ b/Allura/allura/ext/admin/widgets.py
@@ -155,6 +155,11 @@ class ScreenshotAdmin(ff.ForgeForm):
return fields
+class FeaturesField(ew.CompoundField):
+ template = 'jinja:allura.ext.admin:templates/admin_widgets/features_field.html'
+ fields = [ew.TextField(name='feature', show_label=False)]
+
+
class MetadataAdmin(ff.AdminForm):
template = 'jinja:allura.ext.admin:templates/admin_widgets/metadata_admin.html'
defaults = dict(
@@ -180,6 +185,19 @@ class MetadataAdmin(ff.AdminForm):
fev.UnicodeString(max=1000),
V.MaxBytesValidator(max=1000)),
attrs=dict(title="Add a few paragraphs describing your project to new users."))
+ # Apparently, child field must be CompoundField with custom template
+ # for SortableRepeatedField to work properly, that's why FeaturesField
+ # is not just ew.TextField
+ features = ffw.SortableRepeatedField(
+ label='Features',
+ empty_msg='No features yet',
+ nonempty_msg='Drag and drop features to reorder. '
+ 'Leave empty to delete a feature.',
+ button=ew.InputField(
+ css_class='add',
+ field_type='button',
+ value='Add feature'),
+ field=FeaturesField())
icon = ew.FileField(label='Icon')
external_homepage = ew.InputField(field_type="text", label='Homepage',
validator=fev.URL(add_http=True))
http://git-wip-us.apache.org/repos/asf/allura/blob/3bbf0f6d/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 1c562f0..3a85c19 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -526,6 +526,18 @@ class proxy(object):
return self._obj(*args, **kwargs)
+class fixed_attrs_proxy(proxy):
+ """
+ On attribute lookup, if keyword parameter matching attribute name was
+ provided during object construction, returns it's value. Otherwise proxies
+ to obj.
+ """
+ def __init__(self, obj, **kw):
+ self._obj = obj
+ for k, v in kw.iteritems():
+ setattr(self, k, v)
+
+
def render_genshi_plaintext(template_name, **template_vars):
assert os.path.exists(template_name)
fd = open(template_name)
http://git-wip-us.apache.org/repos/asf/allura/blob/3bbf0f6d/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 2b0566c..b45af77 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -241,6 +241,7 @@ class Project(SearchIndexable, MappedClass, ActivityNode, ActivityObject):
trove_environment = FieldProperty([S.ObjectId])
tracking_id = FieldProperty(str, if_missing='')
is_nbhd_project = FieldProperty(bool, if_missing=False)
+ features = FieldProperty([str])
# transient properties
notifications_disabled = False
http://git-wip-us.apache.org/repos/asf/allura/blob/3bbf0f6d/Allura/allura/tests/functional/test_admin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_admin.py b/Allura/allura/tests/functional/test_admin.py
index d239591..bd7f373 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -161,6 +161,22 @@ class TestProjectAdmin(TestController):
r = self.app.get('/admin/audit/')
assert "uninstall tool test-tool" in r.body, r.body
+ def test_features(self):
+ proj = M.Project.query.get(shortname='test')
+ assert_equals(proj.features, [])
+ with audits(u"change project features to \[u'One', u'Two'\]"):
+ self.app.post('/admin/update', params={
+ 'features-0.feature': 'One',
+ 'features-1.feature': ' ',
+ 'features-2.feature': ' Two '})
+ r = self.app.get('/admin/overview')
+ features = r.html.find('fieldset').findAll('input', {'type': 'text'})
+ assert_equals(len(features), 2+1) # two features + extra empty input
+ assert_equals(features[0]['value'], u'One')
+ assert_equals(features[1]['value'], u'Two')
+ proj = M.Project.query.get(shortname='test')
+ assert_equals(proj.features, [u'One', u'Two'])
+
def test_admin_export_control(self):
self.app.get('/admin/')
with audits('change project export controlled status to True'):