Return-Path: X-Original-To: apmail-allura-commits-archive@www.apache.org Delivered-To: apmail-allura-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id D962A188D4 for ; Wed, 25 Nov 2015 19:37:55 +0000 (UTC) Received: (qmail 14940 invoked by uid 500); 25 Nov 2015 19:37:55 -0000 Delivered-To: apmail-allura-commits-archive@allura.apache.org Received: (qmail 14908 invoked by uid 500); 25 Nov 2015 19:37:55 -0000 Mailing-List: contact commits-help@allura.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@allura.apache.org Delivered-To: mailing list commits@allura.apache.org Received: (qmail 14842 invoked by uid 99); 25 Nov 2015 19:37:55 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 25 Nov 2015 19:37:55 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 9137EE0972; Wed, 25 Nov 2015 19:37:55 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: brondsem@apache.org To: commits@allura.apache.org Date: Wed, 25 Nov 2015 19:37:57 -0000 Message-Id: <8248d3b2debd4bdcab235ef6788b4ce9@git.apache.org> In-Reply-To: <2a2bc8e18a0249a797d014a2061fb17b@git.apache.org> References: <2a2bc8e18a0249a797d014a2061fb17b@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [03/17] allura git commit: [#7999] ticket:854 Add delete projects page to nf admin [#7999] ticket:854 Add delete projects page to nf admin Project: http://git-wip-us.apache.org/repos/asf/allura/repo Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/15181034 Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/15181034 Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/15181034 Branch: refs/heads/master Commit: 151810348e63ed41236c81ca4722c7d200f7042b Parents: e7b50b5 Author: Igor Bondarenko Authored: Thu Oct 29 15:02:33 2015 +0200 Committer: Dave Brondsema Committed: Wed Nov 25 14:37:41 2015 -0500 ---------------------------------------------------------------------- Allura/allura/controllers/site_admin.py | 20 ++++++++ Allura/allura/lib/plugin.py | 15 ++++++ .../templates/site_admin_delete_projects.html | 51 ++++++++++++++++++++ Allura/allura/tests/test_plugin.py | 10 ++++ 4 files changed, 96 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/allura/blob/15181034/Allura/allura/controllers/site_admin.py ---------------------------------------------------------------------- diff --git a/Allura/allura/controllers/site_admin.py b/Allura/allura/controllers/site_admin.py index 8bcd192..621963c 100644 --- a/Allura/allura/controllers/site_admin.py +++ b/Allura/allura/controllers/site_admin.py @@ -87,6 +87,7 @@ class SiteAdminController(object): SitemapEntry('Reclone Repo', base_url + 'reclone_repo', ui_icon=g.icons['admin']), SitemapEntry('Task Manager', base_url + 'task_manager?state=busy', ui_icon=g.icons['stats']), SitemapEntry('Search Projects', base_url + 'search_projects', ui_icon=g.icons['search']), + SitemapEntry('Delete Projects', base_url + 'delete_projects', ui_icon=g.icons['delete']), SitemapEntry('Search Users', base_url + 'search_users', ui_icon=g.icons['search']), ] for ep_name in sorted(g.entry_points['site_admin']): @@ -317,6 +318,25 @@ class SiteAdminController(object): return r @without_trailing_slash + @expose('jinja:allura:templates/site_admin_delete_projects.html') + @validate(validators=dict(projects=validators.UnicodeString(if_empty=None))) + def delete_projects(self, projects=None, **kw): + if request.method == "POST": + if not projects: + flash(u'No projects specified', 'warning') + redirect('delete_projects') + provider = ProjectRegistrationProvider.get() + projects = projects.split() + log.info('Got projects for delete: %s', projects) + projects = [provider.project_from_url(p.strip()) for p in projects] + projects = [p for p in projects if p] + log.info('Parsed projects: %s', projects) + # TODO: fire delete project task + flash(u'Delete scheduled for %s' % projects, 'ok') + redirect('delete_projects') + return {} + + @without_trailing_slash @expose('jinja:allura:templates/site_admin_search.html') @validate(validators=dict(q=validators.UnicodeString(if_empty=None), limit=validators.Int(if_invalid=None), http://git-wip-us.apache.org/repos/asf/allura/blob/15181034/Allura/allura/lib/plugin.py ---------------------------------------------------------------------- diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py index 46cd3e8..eb19152 100644 --- a/Allura/allura/lib/plugin.py +++ b/Allura/allura/lib/plugin.py @@ -26,6 +26,7 @@ import string import crypt import random from urllib2 import urlopen +from urlparse import urlparse from cStringIO import StringIO from random import randint from hashlib import sha256 @@ -1009,6 +1010,20 @@ class ProjectRegistrationProvider(object): (project.url() + 'admin/audit/', 'Audit Trail'), ] + def project_from_url(self, url): + '''Return pair where (n, p) parsed from project url + where n is neighborhood's url_prefix and p is project's shortname + + Return None if url can't be parsed + ''' + if url is None: + return None + url = urlparse(url) + url = [u for u in url.path.split('/') if u] + if len(url) < 2: + return None + return (u'/{}/'.format(url[0]), url[1]) + class ThemeProvider(object): http://git-wip-us.apache.org/repos/asf/allura/blob/15181034/Allura/allura/templates/site_admin_delete_projects.html ---------------------------------------------------------------------- diff --git a/Allura/allura/templates/site_admin_delete_projects.html b/Allura/allura/templates/site_admin_delete_projects.html new file mode 100644 index 0000000..4b92892 --- /dev/null +++ b/Allura/allura/templates/site_admin_delete_projects.html @@ -0,0 +1,51 @@ +{#- + 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. +-#} + +{% set page = 'delete_projects' %} + +{% extends 'allura:templates/site_admin.html' %} + +{% block title %}Delete Projects{% endblock %} +{% block header %}Delete Projects{% endblock %} + +{% block content %} +
+

Put project URLs separated by newline or whitespace

+

Be carefull. This will delete all projects data!

+
+
+ +
+
+ +
+ {{lib.csrf_token()}} +
+
+{% endblock %} + +{% block extra_css %} + +{% endblock %} http://git-wip-us.apache.org/repos/asf/allura/blob/15181034/Allura/allura/tests/test_plugin.py ---------------------------------------------------------------------- diff --git a/Allura/allura/tests/test_plugin.py b/Allura/allura/tests/test_plugin.py index 2b8b039..ec20288 100644 --- a/Allura/allura/tests/test_plugin.py +++ b/Allura/allura/tests/test_plugin.py @@ -89,6 +89,16 @@ class TestProjectRegistrationProvider(object): Project.query.get.return_value = Mock() assert_raises(ProjectConflict, v, 'thisislegit', neighborhood=nbhd) + def test_project_from_url(self): + parse = self.provider.project_from_url + assert_is_none(parse(None)) + assert_is_none(parse('')) + assert_is_none(parse('/p/')) + assert_equal(('/p/', 'test'), parse('/p/test/')) + assert_equal(('/p/', 'test'), parse('/p/test/tickets/1')) + assert_equal(('/adobe/', 'adobe-1'), parse('/adobe/adobe-1')) + assert_equal(('/p/', 'test'), parse('http://localhost:8080/p/test/wiki')) + class UserMock(object): def __init__(self):