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/08/21 17:26:43 UTC

[01/50] git commit: [#3154] ticket:386 Add file handle param to bulk_export()

Updated Branches:
  refs/heads/db/3154b [created] 272bd5c36


[#3154] ticket:386 Add file handle param to bulk_export()


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

Branch: refs/heads/db/3154b
Commit: b8397ea73b8fdf4fed93ef7096b8610deb02ad5b
Parents: 2debd08
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 4 12:42:30 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:53 2013 +0000

----------------------------------------------------------------------
 Allura/allura/app.py             | 4 +++-
 ForgeWiki/forgewiki/wiki_main.py | 4 ++++
 2 files changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b8397ea7/Allura/allura/app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index c5ddb87..be2f70a 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -543,9 +543,11 @@ class Application(object):
                 text=text,
                 subject=message['headers'].get('Subject', 'no subject'))
 
-    def bulk_export(self):
+    def bulk_export(self, f):
         """Export all artifacts in the tool into json file.
 
+        :param f: File Object to write to
+
         Set exportable to True for applications implementing this.
         """
         raise NotImplementedError, 'bulk_export'

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b8397ea7/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index ace2926..30b4860 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -286,6 +286,10 @@ The wiki uses [Markdown](%s) syntax.
         WM.Globals.query.remove(dict(app_config_id=self.config._id))
         super(ForgeWikiApp, self).uninstall(project)
 
+    def bulk_export(self, f):
+        # TODO: implement this
+        f.write('{}\n')
+
 
 class RootController(BaseController, DispatchIndex, FeedController):
 


[45/50] git commit: [#3154] ticket:411 config bool refactor

Posted by br...@apache.org.
[#3154] ticket:411 config bool refactor


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

Branch: refs/heads/db/3154b
Commit: b098e1ea89023ebd528403ce303011cdf8c95da2
Parents: 7be9277
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Thu Aug 15 16:39:59 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/ext/admin/admin_main.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b098e1ea/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 9cc0f28..f763258 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -142,7 +142,7 @@ class AdminApp(Application):
                     SitemapEntry('Categorization', admin_url+'trove')
                 ]
         links.append(SitemapEntry('Tools', admin_url+'tools'))
-        if config.get('bulk_export_enabled', 'true') == 'true':
+        if asbool(config.get('bulk_export_enabled', True)):
             links.append(SitemapEntry('Export', admin_url + 'export'))
         if c.project.is_root and has_access(c.project, 'admin')():
             links.append(SitemapEntry('User Permissions', admin_url+'groups/'))
@@ -636,7 +636,7 @@ class ProjectAdminController(BaseController):
 
     @expose('jinja:allura.ext.admin:templates/export.html')
     def export(self, tools=None):
-        if config.get('bulk_export_enabled', 'true') != 'true':
+        if not asbool(config.get('bulk_export_enabled', True)):
             redirect('.')
         exportable_tools = AdminApp.exportable_tools_for(c.project)
         if request.method == 'POST':


[11/50] git commit: [#3153] ticket:389 fixed tests for export

Posted by br...@apache.org.
[#3153] ticket:389 fixed tests for export


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

Branch: refs/heads/db/3154b
Commit: 9216776f7d5f8d74dade35cbf5ee77197b90e14e
Parents: f2930dc
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Tue Jul 23 19:17:07 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:55 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_admin.py | 16 ++++++++--------
 Allura/allura/tests/test_tasks.py            |  6 +++---
 2 files changed, 11 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9216776f/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 774fd36..d3a5bd9 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -776,8 +776,8 @@ class TestExport(TestController):
         self.setup_with_tools()
 
     @td.with_wiki
-    @td.with_tool('test', 'Wiki', 'wiki2', 'Wiki 2')
     @td.with_tool('test', 'Tickets', 'bugs', 'Bugs')
+    @td.with_tool('test', 'ShortUrl', 'urls', 'Urls')
     def setup_with_tools(self):
         pass
 
@@ -785,7 +785,7 @@ class TestExport(TestController):
         project = M.Project.query.get(shortname='test')
         tools = [t.options.mount_point
                  for t in AdminApp.exportable_tools_for(project)]
-        assert_equals(tools, [u'wiki', u'wiki2'])
+        assert_equals(tools, [u'wiki', u'bugs'])
 
     def test_access(self):
         r = self.app.get('/admin/export',
@@ -804,15 +804,15 @@ class TestExport(TestController):
     def test_export_page_contains_exportable_tools(self):
         r = self.app.get('/admin/export')
         assert_in('Wiki</label> <a href="/p/test/wiki/">/p/test/wiki/</a>', r)
-        assert_in('Wiki 2</label> <a href="/p/test/wiki2/">/p/test/wiki2/</a>', r)
-        assert_not_in('Bugs</label> <a href="/p/test/bugs/">/p/test/bugs/</a>', r)
+        assert_in('Bugs</label> <a href="/p/test/bugs/">/p/test/bugs/</a>', r)
+        assert_not_in('Urls</label> <a href="/p/test/urls/">/p/test/urls/</a>', r)
 
     def test_tools_not_selected(self):
         r = self.app.post('/admin/export')
         assert_in('error', self.webflash(r))
 
     def test_bad_tool(self):
-        r = self.app.post('/admin/export', {'tools': u'bugs'})
+        r = self.app.post('/admin/export', {'tools': u'urls'})
         assert_in('error', self.webflash(r))
 
     @mock.patch('allura.ext.admin.admin_main.export_tasks')
@@ -824,10 +824,10 @@ class TestExport(TestController):
 
     @mock.patch('allura.ext.admin.admin_main.export_tasks')
     def test_selected_multiple_tools(self, export_tasks):
-        r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
+        r = self.app.post('/admin/export', {'tools': [u'wiki', u'bugs']})
         assert_in('ok', self.webflash(r))
         export_tasks.bulk_export.post.assert_called_once_with(
-            'test', [u'wiki', u'wiki2'], u'test-admin')
+            'test', [u'wiki', u'bugs'], u'test-admin')
 
     @patch('allura.ext.admin.admin_main.export_tasks')
     def test_export_in_progress(self, export_tasks):
@@ -835,7 +835,7 @@ class TestExport(TestController):
         tmpdir = os.path.join(p.bulk_export_path(), p.shortname)
         shutil.rmtree(p.bulk_export_path(), ignore_errors=True)
         os.makedirs(tmpdir)
-        r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
+        r = self.app.post('/admin/export', {'tools': [u'wiki', u'bugs']})
         assert_in('info', self.webflash(r))
         assert_equals(export_tasks.bulk_export.post.call_count, 0)
         shutil.rmtree(p.bulk_export_path(), ignore_errors=True)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9216776f/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 39c3397..654ed37 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -354,13 +354,13 @@ class TestExportTasks(unittest.TestCase):
             mock.call('Can not load app for blog mount point. Skipping.')])
 
     @mock.patch('allura.tasks.export_tasks.log')
-    @td.with_tool('test', 'Tickets', 'bugs')
+    @td.with_tool('test', 'ShortUrl', 'urls')
     @td.with_tool('test', 'Blog', 'blog')
     def test_bulk_export_not_exportable_tool(self, log):
-        export_tasks.bulk_export('test', [u'bugs', u'blog'], 'test-admin')
+        export_tasks.bulk_export('test', [u'urls', u'blog'], 'test-admin')
         assert_equal(log.info.call_count, 2)
         assert_equal(log.info.call_args_list, [
-            mock.call('Tool bugs is not exportable. Skipping.'),
+            mock.call('Tool urls is not exportable. Skipping.'),
             mock.call('Tool blog is not exportable. Skipping.')])
 
     @mock.patch('allura.tasks.export_tasks.shutil')


[28/50] git commit: [#3154] ticket:395 added project metadata to bulk export task

Posted by br...@apache.org.
[#3154] ticket:395 added project metadata to bulk export task


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

Branch: refs/heads/db/3154b
Commit: 21cd30e56685e84c0715045ebb8368dee31f3863
Parents: 36ae6b0
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Thu Jul 25 13:46:28 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:57 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tasks/export_tasks.py | 8 ++++++++
 1 file changed, 8 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/21cd30e5/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index 9001500..395970c 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -15,6 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+import json
 import os
 import logging
 import shutil
@@ -64,6 +65,13 @@ def bulk_export(project_shortname, tools, username):
             continue
 
     try:
+        path = create_export_dir(project)
+        with open(os.path.join(path, 'project.json'), 'w') as f:
+            json.dump(project, f, cls=tg.jsonify.GenericJSON)
+    except:
+        log.error('Something went wrong during export of project metadata', exc_info=True)
+
+    try:
         zip_and_cleanup(project)
     except:
         log.error('Something went wrong during zipping exported data.', exc_info=True)


[38/50] git commit: [#3154] ticket:408 clean up export tests

Posted by br...@apache.org.
[#3154]  ticket:408 clean up export tests


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

Branch: refs/heads/db/3154b
Commit: 0c71f0a82442c5d93b7f2ca1372ee60fb03889d7
Parents: dd4700d
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Fri Aug 9 17:12:09 2013 +0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:58 2013 +0000

----------------------------------------------------------------------
 Allura/allura/ext/admin/admin_main.py        |  2 +-
 Allura/allura/tests/functional/test_admin.py | 25 +++++++++++++++--------
 2 files changed, 17 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0c71f0a8/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 ca55645..0dbc5a5 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -108,7 +108,7 @@ class AdminApp(Application):
         cls = AdminApp
         tools = []
         if cls._exportable_tools is None:
-            for tool in project.ordered_mounts():
+            for tool in project.ordered_mounts(include_hidden=True):
                 if not tool.get('ac'):
                     continue
                 if project.app_instance(tool['ac']).exportable:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0c71f0a8/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 d3a5bd9..6d17263 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -776,8 +776,7 @@ class TestExport(TestController):
         self.setup_with_tools()
 
     @td.with_wiki
-    @td.with_tool('test', 'Tickets', 'bugs', 'Bugs')
-    @td.with_tool('test', 'ShortUrl', 'urls', 'Urls')
+    @td.with_tool('test', 'Wiki', 'wiki2', 'Wiki2')
     def setup_with_tools(self):
         pass
 
@@ -785,7 +784,7 @@ class TestExport(TestController):
         project = M.Project.query.get(shortname='test')
         tools = [t.options.mount_point
                  for t in AdminApp.exportable_tools_for(project)]
-        assert_equals(tools, [u'wiki', u'bugs'])
+        assert_equals(tools, [u'wiki', u'wiki2'])
 
     def test_access(self):
         r = self.app.get('/admin/export',
@@ -804,15 +803,22 @@ class TestExport(TestController):
     def test_export_page_contains_exportable_tools(self):
         r = self.app.get('/admin/export')
         assert_in('Wiki</label> <a href="/p/test/wiki/">/p/test/wiki/</a>', r)
-        assert_in('Bugs</label> <a href="/p/test/bugs/">/p/test/bugs/</a>', r)
-        assert_not_in('Urls</label> <a href="/p/test/urls/">/p/test/urls/</a>', r)
+        assert_in('Wiki2</label> <a href="/p/test/wiki2/">/p/test/wiki2/</a>', r)
+        assert_not_in('Search</label> <a href="/p/test/search/">/p/test/search/</a>', r)
+
+    @patch('allura.ext.search.search_main.SearchApp.exportable')
+    def test_export_page_contains_hidden_tools(self, search_app):
+        project = M.Project.query.get(shortname='test')
+        tools = [t.options.mount_point
+                 for t in AdminApp.exportable_tools_for(project)]
+        assert_equals(tools, [u'search', u'wiki', u'wiki2'])
 
     def test_tools_not_selected(self):
         r = self.app.post('/admin/export')
         assert_in('error', self.webflash(r))
 
     def test_bad_tool(self):
-        r = self.app.post('/admin/export', {'tools': u'urls'})
+        r = self.app.post('/admin/export', {'tools': u'search'})
         assert_in('error', self.webflash(r))
 
     @mock.patch('allura.ext.admin.admin_main.export_tasks')
@@ -824,10 +830,10 @@ class TestExport(TestController):
 
     @mock.patch('allura.ext.admin.admin_main.export_tasks')
     def test_selected_multiple_tools(self, export_tasks):
-        r = self.app.post('/admin/export', {'tools': [u'wiki', u'bugs']})
+        r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
         assert_in('ok', self.webflash(r))
         export_tasks.bulk_export.post.assert_called_once_with(
-            'test', [u'wiki', u'bugs'], u'test-admin')
+            'test', [u'wiki', u'wiki2'], u'test-admin')
 
     @patch('allura.ext.admin.admin_main.export_tasks')
     def test_export_in_progress(self, export_tasks):
@@ -835,7 +841,8 @@ class TestExport(TestController):
         tmpdir = os.path.join(p.bulk_export_path(), p.shortname)
         shutil.rmtree(p.bulk_export_path(), ignore_errors=True)
         os.makedirs(tmpdir)
-        r = self.app.post('/admin/export', {'tools': [u'wiki', u'bugs']})
+        r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
+        r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
         assert_in('info', self.webflash(r))
         assert_equals(export_tasks.bulk_export.post.call_count, 0)
         shutil.rmtree(p.bulk_export_path(), ignore_errors=True)


[41/50] git commit: ticket:411 bulk_export_enabled added to config

Posted by br...@apache.org.
ticket:411 bulk_export_enabled added to config


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

Branch: refs/heads/db/3154b
Commit: 9293bdd3a976e5f2c76ed6dbfce92462d077ed31
Parents: d87f7ae
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Tue Aug 13 19:07:09 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/ext/admin/admin_main.py | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/9293bdd3/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 d1f98da..6031625 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -142,7 +142,8 @@ class AdminApp(Application):
                     SitemapEntry('Categorization', admin_url+'trove')
                 ]
         links.append(SitemapEntry('Tools', admin_url+'tools'))
-        links.append(SitemapEntry('Export', admin_url + 'export'))
+        if config.get('bulk_export_enabled', 'false') == 'true':
+            links.append(SitemapEntry('Export', admin_url + 'export'))
         if c.project.is_root and has_access(c.project, 'admin')():
             links.append(SitemapEntry('User Permissions', admin_url+'groups/'))
         if not c.project.is_root and has_access(c.project, 'admin')():
@@ -635,6 +636,8 @@ class ProjectAdminController(BaseController):
 
     @expose('jinja:allura.ext.admin:templates/export.html')
     def export(self, tools=None):
+        if config.get('bulk_export_enabled', 'true') != 'true':
+            redirect('.')
         exportable_tools = AdminApp.exportable_tools_for(c.project)
         if request.method == 'POST':
             if not tools:


[48/50] git commit: [#3154] call bulk_export_filename() just once per export; better status check; include filename & `c` in config templates

Posted by br...@apache.org.
[#3154] call bulk_export_filename() just once per export; better status check; include filename & `c` in config templates


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

Branch: refs/heads/db/3154b
Commit: a885568cf6fcfa1e13dca1cdaf4e6cdd91ad3ab0
Parents: 2dae15a
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Mon Aug 19 18:23:31 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:26:27 2013 +0000

----------------------------------------------------------------------
 Allura/allura/ext/admin/admin_main.py         |  3 +-
 Allura/allura/ext/admin/templates/export.html | 12 ++---
 Allura/allura/model/project.py                | 27 +++++++---
 Allura/allura/tasks/export_tasks.py           | 58 ++++++++++++----------
 Allura/allura/tests/functional/test_admin.py  | 30 +++--------
 Allura/allura/tests/test_tasks.py             | 43 ++++------------
 6 files changed, 76 insertions(+), 97 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a885568c/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 cbb1e2c..0e33c94 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -652,9 +652,10 @@ class ProjectAdminController(BaseController):
             if c.project.bulk_export_status() == 'busy':
                 flash('Export for project %s already running' % c.project.shortname, 'info')
                 redirect('export')
-            export_tasks.bulk_export.post(c.project.shortname, tools, c.user.username, c.project.neighborhood.name)
+            export_tasks.bulk_export.post(tools)
             flash('Export scheduled', 'ok')
             redirect('export')
+
         return {
             'tools': exportable_tools,
             'status': c.project.bulk_export_status()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a885568c/Allura/allura/ext/admin/templates/export.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/export.html b/Allura/allura/ext/admin/templates/export.html
index eff9d5a..f0429c2 100644
--- a/Allura/allura/ext/admin/templates/export.html
+++ b/Allura/allura/ext/admin/templates/export.html
@@ -24,12 +24,10 @@
 
 {% block content %}
 
-{% if status == 'ready' %}
-<div class="error">
-  <h2>Careful!</h2>
-  This project has been exported already.
-  Follow instructions in notification email to get the exported data.
-  If you run export again previous exported data will be lost.
+{% if status == 'busy' %}
+<div class="info">
+  <h2>Busy</h2>
+  This project is queued for export.  You can't start another export yet.
 </div>
 {% endif %}
 
@@ -42,7 +40,7 @@
         <label for="tool-{{ loop.index }}">{{ tool.options.mount_label }}</label> <a href="{{ tool.url() }}">{{ tool.url() }}</a>
       </div>
       {% endfor %}
-      <p><div class="grid-19"><input type="submit" value="Export"></div></p>
+      <p><div class="grid-19"><input type="submit" value="Export" {% if status == 'busy' %}disabled{% endif %}></div></p>
     </form>
   {% else %}
     There are no exportable tools in your project.

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a885568c/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 95ad80f..f57dc34 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -46,6 +46,7 @@ from .neighborhood import Neighborhood
 from .auth import ProjectRole, User
 from .timeline import ActivityNode, ActivityObject
 from .types import ACL, ACE
+from .monq_model import MonQTask
 
 from filesystem import File
 
@@ -855,9 +856,15 @@ class Project(MappedClass, ActivityNode, ActivityObject):
             shortname = self.shortname.split('/')[0]
         return config['bulk_export_path'].format(
                 nbhd=self.neighborhood.url_prefix.strip('/'),
-                project=shortname)
+                project=shortname,
+                c=c,
+        )
 
     def bulk_export_filename(self):
+        '''
+        Return a filename (configurable) for this project export.  The current timestamp
+        may be included, so only run this method once per export.
+        '''
         shortname = self.shortname
         if self.is_nbhd_project:
             shortname = self.url().strip('/')
@@ -869,13 +876,21 @@ class Project(MappedClass, ActivityNode, ActivityObject):
         return config['bulk_export_filename'].format(project=shortname, date=datetime.utcnow())
 
     def bulk_export_status(self):
-        fn = os.path.join(self.bulk_export_path(), self.bulk_export_filename())
-        tmpdir = os.path.join(self.bulk_export_path(), self.shortname)
-        if os.path.isfile(fn):
-            return 'ready'
-        elif os.path.exists(tmpdir):
+        '''
+        Returns 'busy' if an export is queued or in-progress.  Returns None otherwise
+        '''
+        q = {
+            'task_name': 'allura.tasks.export_tasks.bulk_export',
+            'state': {'$in': ['busy', 'ready']},
+            'context.project_id': self._id,
+        }
+        export_task = MonQTask.query.get(**q)
+        if not export_task:
+            return
+        if export_task.state in ('busy', 'ready'):
             return 'busy'
 
+
     def __json__(self):
         return dict(
             shortname=self.shortname,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a885568c/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index b6a84ac..ee07057 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -15,14 +15,13 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-import json
 import os
 import logging
 import shutil
 from tempfile import mkstemp
 
 import tg
-from pylons import app_globals as g
+from pylons import app_globals as g, tmpl_context as c
 
 from allura import model as M
 from allura.tasks import mail_tasks
@@ -35,15 +34,19 @@ log = logging.getLogger(__name__)
 
 
 @task
-def bulk_export(project_shortname, tools, username, neighborhood):
-    neighborhood = M.Neighborhood.query.get(name=neighborhood)
-    project = M.Project.query.get(shortname=project_shortname, neighborhood_id=neighborhood._id)
-    if not project:
-        log.error('Project %s not found' % project_shortname)
-        return
-    if project.bulk_export_status() == 'busy':
-        log.info('Another export is running for project %s. Skipping.' % project_shortname)
-        return
+def bulk_export(tools):
+    '''
+    Export the current project data.  Send notification to current user
+
+    :param list tools: list of mount_points to export
+    '''
+    # it's very handy to use c.* within a @task,
+    # but let's be explicit and keep it separate from the main code
+    return _bulk_export(c.project, tools, c.user)
+
+
+def _bulk_export(project, tools, user):
+    export_filename = project.bulk_export_filename()
     not_exported_tools = []
     for tool in tools or []:
         app = project.app_instance(tool)
@@ -57,7 +60,7 @@ def bulk_export(project_shortname, tools, username, neighborhood):
             continue
         log.info('Exporting %s...' % tool)
         try:
-            path = create_export_dir(project)
+            path = create_export_dir(project, export_filename)
             temp_name = mkstemp(dir=path)[1]
             with open(temp_name, 'w') as f:
                 with h.push_context(project._id):
@@ -71,17 +74,17 @@ def bulk_export(project_shortname, tools, username, neighborhood):
     if tools and len(not_exported_tools) < len(tools):
         # If that fails, we need to let it fail
         # there won't be a valid zip file for the user to get.
-        zip_and_cleanup(project)
+        zip_and_cleanup(project, export_filename)
     else:
         log.error('Nothing to export')
+        None
 
-    user = M.User.by_username(username)
     if not user:
-        log.info('Can not find user %s. Skipping notification.' % username)
+        log.info('No user. Skipping notification.')
         return
     tmpl = g.jinja2_env.get_template('allura:templates/mail/bulk_export.html')
     instructions = tg.config.get('bulk_export_download_instructions', '')
-    instructions = instructions.format(project=project.shortname)
+    instructions = instructions.format(project=project.shortname, filename=export_filename, c=c)
     tmpl_context = {
         'instructions': instructions,
         'project': project,
@@ -93,34 +96,35 @@ def bulk_export(project_shortname, tools, username, neighborhood):
         'reply_to': unicode(user.email_address_header()),
         'message_id': h.gen_message_id(),
         'destinations': [unicode(user._id)],
-        'subject': u'Bulk export for project %s completed' % project_shortname,
+        'subject': u'Bulk export for project %s completed' % project.shortname,
         'text': tmpl.render(tmpl_context),
     }
     mail_tasks.sendmail.post(**email)
 
 
-def create_export_dir(project):
+def create_export_dir(project, export_filename):
     """Create temporary directory for export files"""
-    zip_fn = project.bulk_export_filename()
     # Name temporary directory after project shortname,
     # thus zipdir() will use proper prefix inside the archive.
-    tmp_dir_suffix = zip_fn.split('.')[0]
+    tmp_dir_suffix = export_filename.split('.')[0]
     path = os.path.join(project.bulk_export_path(), tmp_dir_suffix)
     if not os.path.exists(path):
         os.makedirs(path)
     return path
 
 
-def zip_and_cleanup(project):
-    """Zip exported data. Copy it to proper location. Remove temporary files."""
+def zip_and_cleanup(project, export_filename):
+    """
+    Zip exported data. Copy it to proper location. Remove temporary files.
+    Returns base filename of zip file
+    """
     path = project.bulk_export_path()
-    zip_fn = project.bulk_export_filename()
-    temp = os.path.join(path, zip_fn.split('.')[0])
-    zip_path_temp = os.path.join(temp, zip_fn)
-    zip_path = os.path.join(path, zip_fn)
+    temp = os.path.join(path, export_filename.split('.')[0])
+    zip_path_temp = os.path.join(temp, export_filename)
+    zip_path = os.path.join(path, export_filename)
 
     zipdir(temp, zip_path_temp)
 
     # cleanup
     shutil.move(zip_path_temp, zip_path)
-    shutil.rmtree(temp)
+    shutil.rmtree(temp)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a885568c/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 669f113..9c5aed6 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -836,37 +836,19 @@ class TestExport(TestController):
     def test_selected_one_tool(self, export_tasks):
         r = self.app.post('/admin/export', {'tools': u'wiki'})
         assert_in('ok', self.webflash(r))
-        export_tasks.bulk_export.post.assert_called_once_with(
-            'test', [u'wiki'], u'test-admin', u'Projects')
+        export_tasks.bulk_export.post.assert_called_once_with([u'wiki'])
 
     @mock.patch('allura.ext.admin.admin_main.export_tasks')
     def test_selected_multiple_tools(self, export_tasks):
         r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
         assert_in('ok', self.webflash(r))
-        export_tasks.bulk_export.post.assert_called_once_with(
-            'test', [u'wiki', u'wiki2'], u'test-admin', u'Projects')
+        export_tasks.bulk_export.post.assert_called_once_with([u'wiki', u'wiki2'])
 
-    @mock.patch('allura.ext.admin.admin_main.export_tasks')
-    def test_export_in_progress(self, export_tasks):
-        p = M.Project.query.get(shortname='test')
-        tmpdir = os.path.join(p.bulk_export_path(), p.shortname)
-        shutil.rmtree(p.bulk_export_path(), ignore_errors=True)
-        os.makedirs(tmpdir)
-        r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
-        assert_in('info', self.webflash(r))
-        assert_equals(export_tasks.bulk_export.post.call_count, 0)
-        shutil.rmtree(p.bulk_export_path(), ignore_errors=True)
-
-    def test_export_done(self):
-        p = M.Project.query.get(shortname='test')
-        shutil.rmtree(p.bulk_export_path(), ignore_errors=True)
-        os.makedirs(p.bulk_export_path())
-        fn = os.path.join(p.bulk_export_path(), p.bulk_export_filename())
-        with open(fn, 'w') as f:
-            f.write('Pretending I am zip archive')
+    def test_export_in_progress(self):
+        from allura.tasks import export_tasks
+        export_tasks.bulk_export.post(['wiki'])
         r = self.app.get('/admin/export')
-        assert_in('<h2>Careful!</h2>', r)
-        shutil.rmtree(p.bulk_export_path(), ignore_errors=True)
+        assert_in('<h2>Busy</h2>', r.body)
 
     @td.with_user_project('test-user')
     def test_bulk_export_path_for_user_project(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a885568c/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index a1e09c3..9f307ee 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -341,13 +341,8 @@ class TestExportTasks(unittest.TestCase):
         shutil.rmtree(project.bulk_export_path(), ignore_errors=True)
 
     @mock.patch('allura.tasks.export_tasks.log')
-    def test_bulk_export_invalid_project(self, log):
-        export_tasks.bulk_export('bad', [u'wiki'], 'test-admin', 'Projects')
-        log.error.assert_called_once_with('Project bad not found')
-
-    @mock.patch('allura.tasks.export_tasks.log')
     def test_bulk_export_invalid_tool(self, log):
-        export_tasks.bulk_export('test', [u'bugs', u'blog'], 'test-admin', 'Projects')
+        export_tasks.bulk_export([u'bugs', u'blog'])
         assert_equal(log.info.call_count, 2)
         assert_equal(log.info.call_args_list, [
             mock.call('Can not load app for bugs mount point. Skipping.'),
@@ -360,7 +355,7 @@ class TestExportTasks(unittest.TestCase):
     @td.with_tool('test', 'Blog', 'blog')
     def test_bulk_export_not_exportable_tool(self, mail_tasks, app, log):
         app.return_value.exportable = False
-        export_tasks.bulk_export('test', [u'bugs', u'blog'], 'test-admin', 'Projects')
+        export_tasks.bulk_export([u'bugs', u'blog'])
         assert_equal(log.info.call_count, 2)
         assert_equal(log.info.call_args_list, [
             mock.call('Tool bugs is not exportable. Skipping.'),
@@ -374,7 +369,7 @@ class TestExportTasks(unittest.TestCase):
     @td.with_wiki
     def test_bulk_export(self, log, wiki_bulk_export, zipdir, shutil, project_json):
         M.MonQTask.query.remove()
-        export_tasks.bulk_export('test', [u'wiki'], 'test-admin', 'Projects')
+        export_tasks.bulk_export([u'wiki'])
         assert_equal(log.info.call_count, 1)
         assert_equal(log.info.call_args_list, [
             mock.call('Exporting wiki...')])
@@ -396,21 +391,11 @@ class TestExportTasks(unittest.TestCase):
         assert_in('The following tools were exported:\n- wiki', text)
         assert_in('Sample instructions for test', text)
 
-    @mock.patch('forgewiki.wiki_main.ForgeWikiApp.bulk_export')
-    @mock.patch('allura.tasks.export_tasks.log')
-    @td.with_wiki
-    def test_bulk_export_quits_if_another_export_is_running(self, log, wiki_bulk_export):
-        project = M.Project.query.get(shortname='test')
-        export_tasks.create_export_dir(project)
-        assert_equal(project.bulk_export_status(), 'busy')
-        export_tasks.bulk_export('test', [u'wiki'], 'test-admin', 'Projects')
-        log.info.assert_called_once_with('Another export is running for project test. Skipping.')
-        assert_equal(wiki_bulk_export.call_count, 0)
-
     def test_create_export_dir(self):
         project = M.Project.query.get(shortname='test')
         export_path = project.bulk_export_path()
-        path = export_tasks.create_export_dir(project)
+        export_filename = project.bulk_export_filename()
+        path = export_tasks.create_export_dir(project, export_filename)
         assert_equal(path, '/tmp/bulk_export/p/test/test')
         assert os.path.exists(os.path.join(export_path, project.shortname))
 
@@ -418,22 +403,16 @@ class TestExportTasks(unittest.TestCase):
     def test_zip_and_cleanup(self):
         project = M.Project.query.get(shortname='test')
         export_path = project.bulk_export_path()
-        path = export_tasks.create_export_dir(project)
-        export_tasks.zip_and_cleanup(project)
+        export_filename = project.bulk_export_filename()
+        path = export_tasks.create_export_dir(project, export_filename)
+        export_tasks.zip_and_cleanup(project, export_filename)
         assert not os.path.exists(path)
         assert os.path.exists(os.path.join(export_path, 'test.zip'))
 
     def test_bulk_export_status(self):
-        project = M.Project.query.get(shortname='test')
-        assert_equal(project.bulk_export_status(), None)
-
-        export_tasks.create_export_dir(project)
-        assert_equal(project.bulk_export_status(), 'busy')
-
-        with open(os.path.join(project.bulk_export_path(),
-                               project.bulk_export_filename()), 'w') as f:
-            f.write('just test')
-        assert_equal(project.bulk_export_status(), 'ready')
+        assert_equal(c.project.bulk_export_status(), None)
+        export_tasks.bulk_export.post(['wiki'])
+        assert_equal(c.project.bulk_export_status(), 'busy')
 
 
 Mapper.compile_all()


[13/50] git commit: [#3154] ticket:394 Bulk export: ForgeLink

Posted by br...@apache.org.
[#3154]  ticket:394 Bulk export: ForgeLink


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

Branch: refs/heads/db/3154b
Commit: 6a12be79874bec6c41f3ea904a08070f2946ac3c
Parents: e4f7cf5
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Mon Jul 22 16:47:33 2013 +0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:55 2013 +0000

----------------------------------------------------------------------
 ForgeLink/forgelink/link_main.py      |  5 ++++
 ForgeLink/forgelink/tests/test_app.py | 39 ++++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6a12be79/ForgeLink/forgelink/link_main.py
----------------------------------------------------------------------
diff --git a/ForgeLink/forgelink/link_main.py b/ForgeLink/forgelink/link_main.py
index be8c918..2350e84 100644
--- a/ForgeLink/forgelink/link_main.py
+++ b/ForgeLink/forgelink/link_main.py
@@ -49,6 +49,7 @@ class ForgeLinkApp(Application):
         ConfigOption('url', str, None)
     ]
     searchable=True
+    exportable=True
     tool_label='External Link'
     default_mount_label='Link name'
     default_mount_point='link'
@@ -93,6 +94,10 @@ class ForgeLinkApp(Application):
         "Remove all the tool's artifacts from the database"
         super(ForgeLinkApp, self).uninstall(project)
 
+    def bulk_export(self, f):
+        f.write('{"url": "%s"}' % self.config.options.get('url', 'test'))
+
+
 class RootController(BaseController):
 
     def _check_security(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6a12be79/ForgeLink/forgelink/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeLink/forgelink/tests/test_app.py b/ForgeLink/forgelink/tests/test_app.py
new file mode 100644
index 0000000..2176b10
--- /dev/null
+++ b/ForgeLink/forgelink/tests/test_app.py
@@ -0,0 +1,39 @@
+#       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 tempfile
+import json
+
+from allura.tests import decorators as td
+from allura import model as M
+from alluratest.controller import setup_basic_test
+
+
+class TestBulkExport(object):
+
+    def setUp(self):
+        setup_basic_test()
+
+    @td.with_link
+    def test_bulk_export(self):
+        self.project = M.Project.query.get(shortname='test')
+        self.link = self.project.app_instance('link')
+        self.link.config.options['url'] = 'http://sf.net'
+        f = tempfile.TemporaryFile()
+        self.link.bulk_export(f)
+        f.seek(0)
+        assert json.loads(f.read())['url']=='http://sf.net'
\ No newline at end of file


[43/50] git commit: [#3154] ticket:411 added exportable to Application docstring

Posted by br...@apache.org.
[#3154] ticket:411 added exportable to Application docstring


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

Branch: refs/heads/db/3154b
Commit: 6d3d0bbbdf369129baaca3c6942890921e808111
Parents: ae2d4e8
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Tue Aug 13 16:16:30 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/app.py | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6d3d0bbb/Allura/allura/app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index be2f70a..5de6a12 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -174,6 +174,7 @@ class Application(object):
         is 'production'.
     :cvar bool searchable: If True, show search box in the left menu of this
         Application. Default is True.
+    :cvar bool exportable: Default is False, Application can't be exported to json.
     :cvar list permissions: Named permissions used by instances of this
         Application. Default is [].
     :cvar dict permissions_desc: Descriptions of the named permissions.


[29/50] git commit: [#3154] add & update project json API

Posted by br...@apache.org.
[#3154] add & update project json API

* add screenshots
    * fix screenshot url encoding on screenshot admin page
* add trove categories
* add a few individual fields
* rename fields to match their usage better
* remove download field since it's SourceForge-specific


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

Branch: refs/heads/db/3154b
Commit: 73756443e9120a62909a37cb755f7017f63c6777
Parents: f9dd322
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Aug 1 15:35:24 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:57 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/auth.py                     |  2 +-
 Allura/allura/model/project.py                  | 52 +++++++++++++++++---
 .../templates/widgets/project_screenshots.html  |  2 +-
 Allura/allura/tests/functional/test_rest.py     | 11 ++---
 4 files changed, 53 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/73756443/Allura/allura/model/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index c8964f3..fb58ce9 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -702,7 +702,7 @@ class User(MappedClass, ActivityNode, ActivityObject):
         return dict(
             username=self.username,
             name=self.display_name,
-            url=self.url(),
+            url=h.absurl(self.url()),
         )
 
 class OldProjectRole(MappedClass):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/73756443/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 941b360..2258c18 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -20,6 +20,7 @@ import logging
 from collections import Counter, OrderedDict
 from datetime import datetime
 from copy import deepcopy
+import urllib
 
 from tg import config
 from pylons import tmpl_context as c, app_globals as g
@@ -137,6 +138,14 @@ class TroveCategory(MappedClass):
             crumbs.append((trove.fullname, url))
         return crumbs
 
+    def __json__(self):
+        return dict(
+            id=self.trove_cat_id,
+            shortname=self.shortname,
+            fullname=self.fullname,
+            fullpath=self.fullpath,
+        )
+
 class ProjectMapperExtension(MapperExtension):
     def after_insert(self, obj, st, sess):
         g.zarkov_event('project_create', project=obj)
@@ -250,6 +259,21 @@ class Project(MappedClass, ActivityNode, ActivityObject):
     def troves_by_type(self, trove_type):
         return TroveCategory.query.find({'_id':{'$in':getattr(self,'trove_%s' % trove_type)}}).all()
 
+    def all_troves(self):
+        '''
+        Returns a dict of human-readable root troves => [categories]
+        '''
+        troves = {}
+        for attr in dir(self):
+            if attr.startswith('trove_'):
+                trove_type = attr.replace('trove_','')
+                nice_name = dict(
+                    natlanguage='translation',
+                    root_database='database',
+                ).get(trove_type, trove_type)
+                troves[nice_name] = self.troves_by_type(trove_type)
+        return troves
+
     def get_tool_data(self, tool, key, default=None):
         return self.tool_data.get(tool, {}).get(key, default)
 
@@ -839,17 +863,33 @@ class Project(MappedClass, ActivityNode, ActivityObject):
 
     def __json__(self):
         return dict(
-            name=self.shortname,
-            title=self.name,
+            shortname=self.shortname,
+            name=self.name,
             _id=self._id,
+            url=h.absurl(self.url()),
             private=self.private,
             short_description=self.short_description,
-            description=self.description,
-            download_page=self.best_download_url(),
-            preferred_support=self.support_page_url,
+            summary=self.summary,
+            external_homepage=self.external_homepage,
+            socialnetworks=self.socialnetworks,
+            status=self.removal or 'active',
+            moved_to_url=self.moved_to_url,
+            preferred_support_tool=self.support_page,
+            preferred_support_url=self.support_page_url,
             developers=self.users_with_role('Developer'),
             tools=[dict(name=t.tool_name, mount_point=t.options.mount_point, label=t.options.mount_label)
-                   for t in self.app_configs if h.has_access(t, 'read')]
+                   for t in self.app_configs if h.has_access(t, 'read')],
+            labels=self.labels,
+            categories=self.all_troves(),
+            icon_url=h.absurl(self.url() + 'icon') if self.icon else None,
+            screenshots = [
+                dict(
+                    url = h.absurl(self.url() + 'screenshot/' + urllib.quote(ss.filename)),
+                    thumbnail_url = h.absurl(self.url() + 'screenshot/' + urllib.quote(ss.filename) + '/thumb'),
+                    caption = ss.caption,
+                )
+                for ss in self.get_screenshots()
+            ]
         )
 
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/73756443/Allura/allura/templates/widgets/project_screenshots.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/project_screenshots.html b/Allura/allura/templates/widgets/project_screenshots.html
index 01d9849..7d3d338 100644
--- a/Allura/allura/templates/widgets/project_screenshots.html
+++ b/Allura/allura/templates/widgets/project_screenshots.html
@@ -24,7 +24,7 @@
   {% for ss in screenshots %}
   <div data-ss-id="{{ ss._id }}" class="screenshot">
     <div class="image">
-      <a href="{{project.url()}}screenshot/{{ss.filename}}"><img src="{{project.url()}}screenshot/{{ss.filename}}/thumb" alt="Screenshot thumbnail"/></a>
+      <a href="{{project.url()}}screenshot/{{h.urlquote(ss.filename)}}"><img src="{{project.url()}}screenshot/{{h.urlquote(ss.filename)}}/thumb" alt="Screenshot thumbnail"/></a>
       {% if not edit %}
       <br>
       {{ss.caption}}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/73756443/Allura/allura/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py
index 0278666..0977f26 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -74,14 +74,13 @@ class TestRestHome(TestRestApiBase):
 
     def test_project_data(self):
         r = self.api_get('/rest/p/test/')
-        assert_equal(r.json['name'], 'test')
-        assert_equal(r.json['title'], 'Test Project')
-        assert_equal(r.json['description'], 'You can edit this description in the admin page')
+        assert_equal(r.json['shortname'], 'test')
+        assert_equal(r.json['name'], 'Test Project')
         assert_equal(len(r.json['developers']), 1)
         admin_dev = r.json['developers'][0]
         assert_equal(admin_dev['username'], 'test-admin')
         assert_equal(admin_dev['name'], 'Test Admin')
-        assert_equal(admin_dev['url'], '/u/test-admin/')
+        assert_equal(admin_dev['url'], 'http://localhost:80/u/test-admin/')
 
     @td.with_tool('test', 'Tickets', 'bugs')
     @td.with_tool('test', 'Tickets', 'private-bugs')
@@ -95,14 +94,14 @@ class TestRestHome(TestRestApiBase):
 
         # admin sees both 'Tickets' tools
         r = self.api_get('/rest/p/test/')
-        assert_equal(r.json['name'], 'test')
+        assert_equal(r.json['shortname'], 'test')
         tool_mounts = [t['mount_point'] for t in r.json['tools']]
         assert_in('bugs', tool_mounts)
         assert_in('private-bugs', tool_mounts)
 
         # anonymous sees only non-private tool
         r = self.app.get('/rest/p/test/', extra_environ={'username': '*anonymous'})
-        assert_equal(r.json['name'], 'test')
+        assert_equal(r.json['shortname'], 'test')
         tool_mounts = [t['mount_point'] for t in r.json['tools']]
         assert_in('bugs', tool_mounts)
         assert_not_in('private-bugs', tool_mounts)


[33/50] git commit: [#3154] ticket:408 refactored export tests

Posted by br...@apache.org.
[#3154]  ticket:408 refactored export tests


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

Branch: refs/heads/db/3154b
Commit: 060ecbf6c3f4347b54382e494a77576318e9e5a0
Parents: 0c71f0a
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Mon Aug 12 14:23:27 2013 +0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:58 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_admin.py | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/060ecbf6/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 6d17263..4fd0d19 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -806,12 +806,11 @@ class TestExport(TestController):
         assert_in('Wiki2</label> <a href="/p/test/wiki2/">/p/test/wiki2/</a>', r)
         assert_not_in('Search</label> <a href="/p/test/search/">/p/test/search/</a>', r)
 
-    @patch('allura.ext.search.search_main.SearchApp.exportable')
-    def test_export_page_contains_hidden_tools(self, search_app):
-        project = M.Project.query.get(shortname='test')
-        tools = [t.options.mount_point
-                 for t in AdminApp.exportable_tools_for(project)]
-        assert_equals(tools, [u'search', u'wiki', u'wiki2'])
+    def test_export_page_contains_hidden_tools(self):
+        with patch('allura.ext.search.search_main.SearchApp.exportable'):
+            project = M.Project.query.get(shortname='test')
+            tools = [t.options.mount_point for t in AdminApp.exportable_tools_for(project)]
+            assert_equals(tools, [u'search', u'wiki', u'wiki2'])
 
     def test_tools_not_selected(self):
         r = self.app.post('/admin/export')
@@ -842,7 +841,6 @@ class TestExport(TestController):
         shutil.rmtree(p.bulk_export_path(), ignore_errors=True)
         os.makedirs(tmpdir)
         r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
-        r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
         assert_in('info', self.webflash(r))
         assert_equals(export_tasks.bulk_export.post.call_count, 0)
         shutil.rmtree(p.bulk_export_path(), ignore_errors=True)


[04/50] git commit: [#3154] ticket:386 Pass file handles to the bulk_export()

Posted by br...@apache.org.
[#3154] ticket:386 Pass file handles to the bulk_export()


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

Branch: refs/heads/db/3154b
Commit: 1024e06394c108bfb479904e2d01a80b90371a3a
Parents: b8397ea
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 4 12:48:56 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:54 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tasks/export_tasks.py | 28 ++++++++++++++++++++++++++--
 1 file changed, 26 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/1024e063/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index 29f99a8..4c1f95a 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -15,6 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+import os
 import logging
 
 from allura import model as M
@@ -39,5 +40,28 @@ def bulk_export(project_shortname, tools):
             log.info('Tool %s is not exportable. Skipping.' % tool)
             continue
         log.info('Exporting %s...' % tool)
-        # TODO: Create file handle for *.json and pass it to bulk_export
-        app.bulk_export()
+        try:
+            path = create_export_dir(project)
+            with open(os.path.join(path, '%s.json' % tool), 'w') as f:
+                app.bulk_export(f)
+        except:
+            log.error('Something went wrong during export of %s' % tool, exc_info=True)
+            continue
+
+    try:
+        cleanup()
+    except:
+        log.error('Error on cleanup.', exc_info=True)
+
+
+def create_export_dir(project):
+    """Create temporary directory for export files"""
+    path = os.path.join(project.bulk_export_path(), 'tmp')
+    if not os.path.exists(path):
+        os.makedirs(path)
+    return path
+
+
+def cleanup():
+    """Copy zip with export data to proper location. Remove temporary files."""
+    pass


[12/50] git commit: [#3154] ticket:394 Set up context before calling bulk_export

Posted by br...@apache.org.
[#3154] ticket:394 Set up context before calling bulk_export

Also, use controller's method inside ForgeLink's bulk_export()
to get app's json representation to avoid code duplication.


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

Branch: refs/heads/db/3154b
Commit: e2b56bbdd9b5a83ab983b3ba4c773b71ee1c7117
Parents: 6a12be7
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Jul 23 13:48:26 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:55 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tasks/export_tasks.py |  3 ++-
 ForgeLink/forgelink/link_main.py    | 10 +++++++---
 2 files changed, 9 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/e2b56bbd/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index 672f51b..9001500 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -56,7 +56,8 @@ def bulk_export(project_shortname, tools, username):
         try:
             path = create_export_dir(project)
             with open(os.path.join(path, '%s.json' % tool), 'w') as f:
-                app.bulk_export(f)
+                with h.push_context(project._id, app_config_id=app.config._id):
+                    app.bulk_export(f)
         except:
             log.error('Something went wrong during export of %s' % tool, exc_info=True)
             not_exported_tools.append(tool)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/e2b56bbd/ForgeLink/forgelink/link_main.py
----------------------------------------------------------------------
diff --git a/ForgeLink/forgelink/link_main.py b/ForgeLink/forgelink/link_main.py
index 2350e84..b5dd0d4 100644
--- a/ForgeLink/forgelink/link_main.py
+++ b/ForgeLink/forgelink/link_main.py
@@ -17,10 +17,11 @@
 
 #-*- python -*-
 import logging
+import json
 
 # Non-stdlib imports
 import pkg_resources
-from tg import expose, validate, redirect, response, flash
+from tg import expose, validate, redirect, response, flash, jsonify
 from pylons import tmpl_context as c, app_globals as g
 from pylons import request
 
@@ -95,7 +96,7 @@ class ForgeLinkApp(Application):
         super(ForgeLinkApp, self).uninstall(project)
 
     def bulk_export(self, f):
-        f.write('{"url": "%s"}' % self.config.options.get('url', 'test'))
+        json.dump(RootRestController().link_json(), f, cls=jsonify.GenericJSON)
 
 
 class RootController(BaseController):
@@ -132,9 +133,12 @@ class RootRestController(BaseController):
     def _check_security(self):
         require_access(c.app, 'read')
 
+    def link_json(self):
+        return dict(url=c.app.config.options.get('url'))
+
     @expose('json:')
     def index(self, url='', **kw):
         if (request.method == 'POST') and (url != ''):
             require_access(c.app, 'configure')
             c.app.config.options.url = url
-        return dict(url=c.app.config.options.get('url'))
+        return self.link_json()


[23/50] git commit: [#3153] ticket:389 added saved search bins to tracker bulk_export

Posted by br...@apache.org.
[#3153] ticket:389 added saved search bins to tracker bulk_export


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

Branch: refs/heads/db/3154b
Commit: 0a98936fca299fac567167ec4ea3f9a68528fa67
Parents: a7fe240
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Tue Jul 23 20:46:36 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:56 2013 +0000

----------------------------------------------------------------------
 ForgeTracker/forgetracker/model/ticket.py   | 8 ++++++++
 ForgeTracker/forgetracker/tests/test_app.py | 3 +++
 ForgeTracker/forgetracker/tracker_main.py   | 3 +++
 3 files changed, 14 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0a98936f/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 80ce102..0536f71 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -512,6 +512,14 @@ class Bin(Artifact, ActivityObject):
             terms_s=self.terms)
         return result
 
+    def __json__(self):
+        return dict(super(Bin,self).__json__(),
+            _id=self._id,
+            summary=self.summary,
+            terms=self.terms,
+            sort=self.sort,
+        )
+
 class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
     class __mongometa__:
         name = 'ticket'

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0a98936f/ForgeTracker/forgetracker/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/test_app.py b/ForgeTracker/forgetracker/tests/test_app.py
index a718885..c84fa8d 100644
--- a/ForgeTracker/forgetracker/tests/test_app.py
+++ b/ForgeTracker/forgetracker/tests/test_app.py
@@ -63,3 +63,6 @@ class TestBulkExport(TrackerTestController):
         milestones = sorted(tracker['milestones'], key=operator.itemgetter('name'))
         assert_equal(milestones[0]['name'], '1.0')
         assert_equal(milestones[1]['name'], '2.0')
+
+        saved_bins_summaries = [bin['summary'] for bin in tracker['saved_bins']]
+        assert_true('Closed Tickets' in saved_bins_summaries)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/0a98936f/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 02daa5b..15b0085 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -423,6 +423,9 @@ class ForgeTrackerApp(Application):
         f.write(', "milestones":')
         milestones = self.milestones
         json.dump(milestones, f, cls=jsonify.GenericJSON)
+        f.write(', "saved_bins":')
+        bins = self.bins        
+        json.dump(bins, f, cls=jsonify.GenericJSON)
         f.write('}')
 
     @property


[42/50] git commit: [#4154] ticket:411 project export refactoring

Posted by br...@apache.org.
[#4154] ticket:411 project export refactoring


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

Branch: refs/heads/db/3154b
Commit: 7be92777feee97569877d1134c3aaad2c579a6e8
Parents: 663cc9a
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Thu Aug 15 14:31:27 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/ext/admin/admin_main.py         |  7 +++--
 Allura/allura/ext/admin/templates/export.html |  5 ++++
 Allura/allura/model/project.py                |  6 +++-
 Allura/allura/tasks/export_tasks.py           | 33 ++++++++++------------
 Allura/allura/tests/functional/test_admin.py  | 10 +++++--
 5 files changed, 37 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7be92777/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 6031625..9cc0f28 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -106,7 +106,7 @@ class AdminApp(Application):
     @staticmethod
     def exportable_tools_for(project):
         cls = AdminApp
-        tools = []
+        tools = [project]
         if cls._exportable_tools is None:
             for tool in project.ordered_mounts(include_hidden=True):
                 if not tool.get('ac'):
@@ -142,7 +142,7 @@ class AdminApp(Application):
                     SitemapEntry('Categorization', admin_url+'trove')
                 ]
         links.append(SitemapEntry('Tools', admin_url+'tools'))
-        if config.get('bulk_export_enabled', 'false') == 'true':
+        if config.get('bulk_export_enabled', 'true') == 'true':
             links.append(SitemapEntry('Export', admin_url + 'export'))
         if c.project.is_root and has_access(c.project, 'admin')():
             links.append(SitemapEntry('User Permissions', admin_url+'groups/'))
@@ -645,7 +645,8 @@ class ProjectAdminController(BaseController):
                 redirect('export')
             if isinstance(tools, basestring):
                 tools = [tools]
-            allowed = set(t.options.mount_point for t in exportable_tools)
+            allowed = set(t.options.mount_point for t in exportable_tools if hasattr(t, 'options'))
+            allowed.add('project')
             if not set(tools).issubset(allowed):
                 flash('Wrong tools in input data', 'error')
                 redirect('export')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7be92777/Allura/allura/ext/admin/templates/export.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/export.html b/Allura/allura/ext/admin/templates/export.html
index eff9d5a..6287be7 100644
--- a/Allura/allura/ext/admin/templates/export.html
+++ b/Allura/allura/ext/admin/templates/export.html
@@ -38,8 +38,13 @@
     <form method="POST" action="">
       {% for tool in tools %}
       <div class="grid-19">
+        {% if tool.name %}
+          <input type="checkbox" name="tools" id="tool-{{ loop.index }}" value="project">
+          <label for="tool-{{ loop.index }}">{{ tool.name }}</label> <a href="{{ tool.url() }}">{{ tool.url() }}</a>
+        {% else %}
         <input type="checkbox" name="tools" id="tool-{{ loop.index }}" value="{{ tool.options.mount_point }}">
         <label for="tool-{{ loop.index }}">{{ tool.options.mount_label }}</label> <a href="{{ tool.url() }}">{{ tool.url() }}</a>
+        {% endif %}
       </div>
       {% endfor %}
       <p><div class="grid-19"><input type="submit" value="Export"></div></p>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7be92777/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 18bd934..41ea5c7 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -17,12 +17,13 @@
 
 import os
 import logging
+import json
 from collections import Counter, OrderedDict
 from datetime import datetime
 from copy import deepcopy
 import urllib
 
-from tg import config
+from tg import config, jsonify
 from pylons import tmpl_context as c, app_globals as g
 from pylons import request
 from paste.deploy.converters import asbool
@@ -875,6 +876,9 @@ class Project(MappedClass, ActivityNode, ActivityObject):
         elif os.path.exists(tmpdir):
             return 'busy'
 
+    def bulk_export(self, f):
+        json.dump(self, f, cls=jsonify.GenericJSON, indent=2)
+
     def __json__(self):
         return dict(
             shortname=self.shortname,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7be92777/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index b5fcb34..bbd4b1d 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -45,33 +45,30 @@ def bulk_export(project_shortname, tools, username, neighborhood):
         return
     not_exported_tools = []
     for tool in tools or []:
-        app = project.app_instance(tool)
-        if not app:
-            log.info('Can not load app for %s mount point. Skipping.' % tool)
-            not_exported_tools.append(tool)
-            continue
-        if not app.exportable:
-            log.info('Tool %s is not exportable. Skipping.' % tool)
-            not_exported_tools.append(tool)
-            continue
+        entry_to_export = None
+        if tool == 'project':
+            entry_to_export = project
+        else:
+            entry_to_export = project.app_instance(tool)
+            if not entry_to_export:
+                log.info('Can not load app for %s mount point. Skipping.' % tool)
+                not_exported_tools.append(tool)
+                continue
+            if not entry_to_export.exportable:
+                log.info('Tool %s is not exportable. Skipping.' % tool)
+                not_exported_tools.append(tool)
+                continue
         log.info('Exporting %s...' % tool)
         try:
             path = create_export_dir(project)
             with open(os.path.join(path, '%s.json' % tool), 'w') as f:
-                with h.push_context(project._id, app_config_id=app.config._id):
-                    app.bulk_export(f)
+                with h.push_context(project._id):
+                    entry_to_export.bulk_export(f)
         except:
             log.error('Something went wrong during export of %s' % tool, exc_info=True)
             not_exported_tools.append(tool)
             continue
 
-    try:
-        path = create_export_dir(project)
-        with open(os.path.join(path, 'project.json'), 'w') as f:
-            json.dump(project, f, cls=tg.jsonify.GenericJSON, indent=2)
-    except:
-        log.error('Something went wrong during export of project metadata', exc_info=True)
-
     if tools and len(not_exported_tools) < len(tools):
         # If that fails, we need to let it fail
         # there won't be a valid zip file for the user to get.

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/7be92777/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 bc16982..9703b76 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -783,9 +783,12 @@ class TestExport(TestController):
 
     def test_exportable_tools_for(self):
         project = M.Project.query.get(shortname='test')
+        exportable_tools = AdminApp.exportable_tools_for(project)
         tools = [t.options.mount_point
-                 for t in AdminApp.exportable_tools_for(project)]
+                 for t in AdminApp.exportable_tools_for(project)
+                 if hasattr(t, 'options')]
         assert_equals(tools, [u'wiki', u'wiki2'])
+        assert_in(project, exportable_tools)
 
     def test_access(self):
         r = self.app.get('/admin/export',
@@ -820,8 +823,11 @@ class TestExport(TestController):
     def test_export_page_contains_hidden_tools(self):
         with patch('allura.ext.search.search_main.SearchApp.exportable'):
             project = M.Project.query.get(shortname='test')
-            tools = [t.options.mount_point for t in AdminApp.exportable_tools_for(project)]
+            exportable_tools = AdminApp.exportable_tools_for(project)
+            tools = [t.options.mount_point for t in exportable_tools
+                                           if hasattr(t, 'options')]
             assert_equals(tools, [u'search', u'wiki', u'wiki2'])
+            assert_in(project, exportable_tools)
 
     def test_tools_not_selected(self):
         r = self.app.post('/admin/export')


[26/50] git commit: [#3154] ticket:395 added test for project api

Posted by br...@apache.org.
[#3154] ticket:395 added test for project api


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

Branch: refs/heads/db/3154b
Commit: 36ae6b083a0b28791a5e4424f28c290fb963bb9c
Parents: a63d2b4
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Thu Jul 25 12:46:11 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:57 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_rest.py | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/36ae6b08/Allura/allura/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py
index d5ed769..0278666 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -72,9 +72,20 @@ class TestRestHome(TestRestApiBase):
         r = self.api_get('/rest/p/test/')
         assert r.status_int == 200
 
+    def test_project_data(self):
+        r = self.api_get('/rest/p/test/')
+        assert_equal(r.json['name'], 'test')
+        assert_equal(r.json['title'], 'Test Project')
+        assert_equal(r.json['description'], 'You can edit this description in the admin page')
+        assert_equal(len(r.json['developers']), 1)
+        admin_dev = r.json['developers'][0]
+        assert_equal(admin_dev['username'], 'test-admin')
+        assert_equal(admin_dev['name'], 'Test Admin')
+        assert_equal(admin_dev['url'], '/u/test-admin/')
+
     @td.with_tool('test', 'Tickets', 'bugs')
     @td.with_tool('test', 'Tickets', 'private-bugs')
-    def test_project_data(self):
+    def test_project_data_tools(self):
         # Deny anonymous to see 'private-bugs' tool
         role = M.ProjectRole.by_name('*anonymous')._id
         read_permission = M.ACE.allow(role, 'read')


[16/50] git commit: [#3153] ticket:389 bulk_export outline for tracker

Posted by br...@apache.org.
[#3153] ticket:389 bulk_export outline for tracker


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

Branch: refs/heads/db/3154b
Commit: 394474abdb2060a3146c7334ef9af6072b3bcb40
Parents: 3e41cb8
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Mon Jul 22 19:23:02 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:55 2013 +0000

----------------------------------------------------------------------
 Allura/allura/lib/helpers.py                |  9 ++++-
 ForgeTracker/forgetracker/tests/test_app.py | 47 ++++++++++++++++++++++++
 ForgeTracker/forgetracker/tracker_main.py   | 14 ++++++-
 3 files changed, 68 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/394474ab/Allura/allura/lib/helpers.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/helpers.py b/Allura/allura/lib/helpers.py
index 0511dc7..e768201 100644
--- a/Allura/allura/lib/helpers.py
+++ b/Allura/allura/lib/helpers.py
@@ -343,7 +343,14 @@ class DateTimeConverter(FancyValidator):
 def absurl(url):
     if url is None: return None
     if '://' in url: return url
-    return request.scheme + '://' + request.host + url
+    # some __json__ methods call absurl
+    # and in tests request is not set so exception raises
+    # this check prevents it
+    try:
+        host = request.scheme + '://' + request.host
+    except TypeError:
+        host = ''
+    return host + url
 
 def diff_text(t1, t2, differ=None):
     t1_lines = t1.replace('\r', '').split('\n')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/394474ab/ForgeTracker/forgetracker/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/test_app.py b/ForgeTracker/forgetracker/tests/test_app.py
new file mode 100644
index 0000000..9c7e61e
--- /dev/null
+++ b/ForgeTracker/forgetracker/tests/test_app.py
@@ -0,0 +1,47 @@
+#       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 datetime
+import tempfile
+import json
+import operator
+
+from nose.tools import assert_equal
+
+from allura import model as M
+from allura.tests import decorators as td
+from forgetracker import model as TM
+from forgetracker.tests.functional.test_root import TrackerTestController
+
+
+class TestBulkExport(TrackerTestController):
+    @td.with_tracker
+    def setup_with_tools(self):
+        super(TestBulkExport, self).setup_with_tools()
+        self.project = M.Project.query.get(shortname='test')
+        self.tracker = self.project.app_instance('bugs')
+        self.new_ticket(summary='foo', _milestone='1.0')
+
+    def test_bulk_export(self):
+        f = tempfile.TemporaryFile()
+        self.tracker.bulk_export(f)
+        f.seek(0)
+        tracker = json.loads(f.read())
+        #tickets = sorted(tracker['tickets'], key=operator.itemgetter('title'))
+        tickets = tracker['tickets']
+        print tickets
+        assert_equal(len(tickets), 1)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/394474ab/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 2b432df..d39d8d6 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -28,7 +28,7 @@ import jinja2
 
 # Non-stdlib imports
 import pkg_resources
-from tg import expose, validate, redirect, flash, url, config
+from tg import expose, validate, redirect, flash, url, config, jsonify
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from paste.deploy.converters import aslist
 from pylons import tmpl_context as c, app_globals as g
@@ -407,6 +407,18 @@ class ForgeTrackerApp(Application):
         TM.Globals.query.remove(app_config_id)
         super(ForgeTrackerApp, self).uninstall(project)
 
+    def bulk_export(self, f):
+        f.write('{"tickets": [')
+        tickets = TM.Ticket.query.find(dict(
+            app_config_id=self.config._id,
+            deleted=False)).all()
+        count = len(tickets)
+        for i, ticket in enumerate(tickets):
+            json.dump(ticket, f, cls=jsonify.GenericJSON)
+            if i < (count - 1):
+                f.write(',')
+        f.write(']}')
+
     @property
     def bins(self):
         return TM.Bin.query.find(dict(app_config_id=self.config._id)).sort('summary').all()


[07/50] git commit: [#3154] ticket:386 Check export status in UI

Posted by br...@apache.org.
[#3154] ticket:386 Check export status in UI


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

Branch: refs/heads/db/3154b
Commit: 8fb67504dc42805a9346a194dd888ea3e8e4d529
Parents: 6afdaf5
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 4 16:00:36 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:54 2013 +0000

----------------------------------------------------------------------
 Allura/allura/ext/admin/admin_main.py         |  8 +++++++-
 Allura/allura/ext/admin/templates/export.html | 10 ++++++++++
 Allura/allura/tests/functional/test_admin.py  | 16 ++++++++++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8fb67504/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 6b39c35..ee59e1d 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -646,10 +646,16 @@ class ProjectAdminController(BaseController):
             if not set(tools).issubset(allowed):
                 flash('Wrong tools in input data', 'error')
                 redirect('export')
+            if c.project.bulk_export_status() == 'busy':
+                flash('Export for project %s already running' % c.project.shortname, 'info')
+                redirect('export')
             export_tasks.bulk_export.post(c.project.shortname, tools)
             flash('Export scheduled', 'ok')
             redirect('export')
-        return {'tools': exportable_tools}
+        return {
+            'tools': exportable_tools,
+            'status': c.project.bulk_export_status()
+        }
 
 
 class PermissionsController(BaseController):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8fb67504/Allura/allura/ext/admin/templates/export.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/export.html b/Allura/allura/ext/admin/templates/export.html
index 6b69fdc..eff9d5a 100644
--- a/Allura/allura/ext/admin/templates/export.html
+++ b/Allura/allura/ext/admin/templates/export.html
@@ -23,6 +23,16 @@
 {% block header %}Project Export{% endblock %}
 
 {% block content %}
+
+{% if status == 'ready' %}
+<div class="error">
+  <h2>Careful!</h2>
+  This project has been exported already.
+  Follow instructions in notification email to get the exported data.
+  If you run export again previous exported data will be lost.
+</div>
+{% endif %}
+
 <div class="grid-19">
   {% if tools %}
     <form method="POST" action="">

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8fb67504/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 fd8d791..8e205b5 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -17,6 +17,7 @@
 
 import re
 import os, allura
+import shutil
 import pkg_resources
 import StringIO
 from contextlib import contextmanager
@@ -827,3 +828,18 @@ class TestExport(TestController):
         assert_in('ok', self.webflash(r))
         export_tasks.bulk_export.post.assert_called_once_with(
             'test', [u'wiki', u'wiki2'])
+
+    @patch('allura.ext.admin.admin_main.export_tasks')
+    def test_export_in_progress(self, export_tasks):
+        p = M.Project.query.get(shortname='test')
+        tmpdir = os.path.join(p.bulk_export_path(), p.shortname)
+        shutil.rmtree(tmpdir, ignore_errors=True)
+        os.makedirs(tmpdir)
+        r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
+        assert_in('info', self.webflash(r))
+        assert_equals(export_tasks.bulk_export.post.call_count, 0)
+        shutil.rmtree(tmpdir, ignore_errors=True)
+
+    def test_export_done(self):
+        r = self.app.get('/admin/export')
+        assert_in('<h2>Careful!</h2>', r)


[39/50] git commit: [#3154] merge fix conflict

Posted by br...@apache.org.
[#3154] merge fix conflict


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

Branch: refs/heads/db/3154b
Commit: b45aa78c758076c2111a454709b2a628f3e702d5
Parents: efe13f9
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Aug 16 18:33:37 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_admin.py | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/b45aa78c/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 9703b76..4988a8c 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -821,7 +821,7 @@ class TestExport(TestController):
         assert_not_in('Search</label> <a href="/p/test/search/">/p/test/search/</a>', r)
 
     def test_export_page_contains_hidden_tools(self):
-        with patch('allura.ext.search.search_main.SearchApp.exportable'):
+        with mock.patch('allura.ext.search.search_main.SearchApp.exportable'):
             project = M.Project.query.get(shortname='test')
             exportable_tools = AdminApp.exportable_tools_for(project)
             tools = [t.options.mount_point for t in exportable_tools
@@ -851,7 +851,7 @@ class TestExport(TestController):
         export_tasks.bulk_export.post.assert_called_once_with(
             'test', [u'wiki', u'wiki2'], u'test-admin', u'Projects')
 
-    @patch('allura.ext.admin.admin_main.export_tasks')
+    @mock.patch('allura.ext.admin.admin_main.export_tasks')
     def test_export_in_progress(self, export_tasks):
         p = M.Project.query.get(shortname='test')
         tmpdir = os.path.join(p.bulk_export_path(), p.shortname)
@@ -890,4 +890,3 @@ class TestExport(TestController):
     def test_bulk_export_path_for_nbhd(self):
         project = M.Project.query.get(name='Home Project for Projects')
         assert_equals(project.bulk_export_path(), '/tmp/bulk_export/p/p')
-


[27/50] git commit: [#3154] ticket:395 added more info to project json

Posted by br...@apache.org.
[#3154] ticket:395 added more info to project json


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

Branch: refs/heads/db/3154b
Commit: a63d2b461fb99d1f11e99664caf8915f347f3d28
Parents: 546bfcc
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Wed Jul 24 17:21:11 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:57 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/auth.py    | 7 +++++++
 Allura/allura/model/project.py | 8 ++++++++
 2 files changed, 15 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a63d2b46/Allura/allura/model/auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index da0b164..c8964f3 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -698,6 +698,13 @@ class User(MappedClass, ActivityNode, ActivityObject):
     def withskill(cls, skill):
         return cls.query.find({"skills.category_id" : skill._id})
 
+    def __json__(self):
+        return dict(
+            username=self.username,
+            name=self.display_name,
+            url=self.url(),
+        )
+
 class OldProjectRole(MappedClass):
     class __mongometa__:
         session = project_orm_session

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a63d2b46/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 1525eec..941b360 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -840,6 +840,14 @@ class Project(MappedClass, ActivityNode, ActivityObject):
     def __json__(self):
         return dict(
             name=self.shortname,
+            title=self.name,
+            _id=self._id,
+            private=self.private,
+            short_description=self.short_description,
+            description=self.description,
+            download_page=self.best_download_url(),
+            preferred_support=self.support_page_url,
+            developers=self.users_with_role('Developer'),
             tools=[dict(name=t.tool_name, mount_point=t.options.mount_point, label=t.options.mount_label)
                    for t in self.app_configs if h.has_access(t, 'read')]
         )


[35/50] git commit: [#3154] pretty JSON output in exports

Posted by br...@apache.org.
[#3154] pretty JSON output in exports


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

Branch: refs/heads/db/3154b
Commit: bda31defb59380546c36ba9b38c583cfd7ef8dfe
Parents: 691f997
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Aug 1 19:24:48 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:58 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tasks/export_tasks.py           |  2 +-
 ForgeBlog/forgeblog/main.py                   |  2 +-
 ForgeDiscussion/forgediscussion/forum_main.py |  2 +-
 ForgeLink/forgelink/link_main.py              |  2 +-
 ForgeTracker/forgetracker/tracker_main.py     | 14 +++++++-------
 ForgeWiki/forgewiki/wiki_main.py              |  2 +-
 6 files changed, 12 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bda31def/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index 395970c..9933e26 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -67,7 +67,7 @@ def bulk_export(project_shortname, tools, username):
     try:
         path = create_export_dir(project)
         with open(os.path.join(path, 'project.json'), 'w') as f:
-            json.dump(project, f, cls=tg.jsonify.GenericJSON)
+            json.dump(project, f, cls=tg.jsonify.GenericJSON, indent=2)
     except:
         log.error('Something went wrong during export of project metadata', exc_info=True)
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bda31def/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index afcc076..e6da34f 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -195,7 +195,7 @@ class ForgeBlogApp(Application):
         posts = BM.BlogPost.query.find(dict(app_config_id=self.config._id)).sort('timestamp', pymongo.DESCENDING)
         count = len(posts)
         for i, post in enumerate(posts):
-            json.dump(post, f, cls=jsonify.GenericJSON)
+            json.dump(post, f, cls=jsonify.GenericJSON, indent=2)
             if i < (count - 1):
                 f.write(',')
         f.write(']}')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bda31def/ForgeDiscussion/forgediscussion/forum_main.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py
index 2465312..bf1835d 100644
--- a/ForgeDiscussion/forgediscussion/forum_main.py
+++ b/ForgeDiscussion/forgediscussion/forum_main.py
@@ -222,7 +222,7 @@ class ForgeDiscussionApp(Application):
         forums = DM.Forum.query.find(dict(app_config_id=self.config._id)).sort('mod_date', pymongo.DESCENDING).all()
         count = len(forums)
         for i, forum in enumerate(forums):
-            json.dump(forum, f, cls=jsonify.GenericJSON)
+            json.dump(forum, f, cls=jsonify.GenericJSON, indent=2)
             if i < (count - 1):
                 f.write(',')
         f.write(']}')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bda31def/ForgeLink/forgelink/link_main.py
----------------------------------------------------------------------
diff --git a/ForgeLink/forgelink/link_main.py b/ForgeLink/forgelink/link_main.py
index b5dd0d4..199304a 100644
--- a/ForgeLink/forgelink/link_main.py
+++ b/ForgeLink/forgelink/link_main.py
@@ -96,7 +96,7 @@ class ForgeLinkApp(Application):
         super(ForgeLinkApp, self).uninstall(project)
 
     def bulk_export(self, f):
-        json.dump(RootRestController().link_json(), f, cls=jsonify.GenericJSON)
+        json.dump(RootRestController().link_json(), f, cls=jsonify.GenericJSON, indent=2)
 
 
 class RootController(BaseController):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bda31def/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 791b50f..f76a843 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -415,17 +415,17 @@ class ForgeTrackerApp(Application):
             deleted=False)).all()
         count = len(tickets)
         for i, ticket in enumerate(tickets):
-            json.dump(ticket, f, cls=jsonify.GenericJSON)
+            json.dump(ticket, f, cls=jsonify.GenericJSON, indent=2)
             if i < (count - 1):
                 f.write(',')
-        f.write('], "tracker_config":')
-        json.dump(self.config, f, cls=jsonify.GenericJSON)
-        f.write(', "milestones":')
+        f.write('],\n"tracker_config":')
+        json.dump(self.config, f, cls=jsonify.GenericJSON, indent=2)
+        f.write(',\n"milestones":')
         milestones = self.milestones
-        json.dump(milestones, f, cls=jsonify.GenericJSON)
-        f.write(', "saved_bins":')
+        json.dump(milestones, f, cls=jsonify.GenericJSON, indent=2)
+        f.write(',\n"saved_bins":')
         bins = self.bins
-        json.dump(bins, f, cls=jsonify.GenericJSON)
+        json.dump(bins, f, cls=jsonify.GenericJSON, indent=2)
         f.write('}')
 
     @property

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bda31def/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index f27ff73..f0b85a7 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -294,7 +294,7 @@ The wiki uses [Markdown](%s) syntax.
             deleted=False)).all()
         count = len(pages)
         for i, page in enumerate(pages):
-            json.dump(page, f, cls=jsonify.GenericJSON)
+            json.dump(page, f, cls=jsonify.GenericJSON, indent=2)
             if i < (count - 1):
                 f.write(',')
         f.write(']}')


[37/50] git commit: [#3154] avoid doing an extra count() query or storing all items in memory

Posted by br...@apache.org.
[#3154] avoid doing an extra count() query or storing all items in memory


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

Branch: refs/heads/db/3154b
Commit: dd4700db10eb5d6687e5e643534e695f3682adbf
Parents: 8c96f3a
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Tue Aug 6 15:37:20 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:58 2013 +0000

----------------------------------------------------------------------
 ForgeBlog/forgeblog/main.py                   | 5 ++---
 ForgeDiscussion/forgediscussion/forum_main.py | 7 +++----
 ForgeTracker/forgetracker/tracker_main.py     | 7 +++----
 ForgeWiki/forgewiki/wiki_main.py              | 7 +++----
 4 files changed, 11 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dd4700db/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index e6da34f..6f344cb 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -193,11 +193,10 @@ class ForgeBlogApp(Application):
     def bulk_export(self, f):
         f.write('{"posts": [')
         posts = BM.BlogPost.query.find(dict(app_config_id=self.config._id)).sort('timestamp', pymongo.DESCENDING)
-        count = len(posts)
         for i, post in enumerate(posts):
-            json.dump(post, f, cls=jsonify.GenericJSON, indent=2)
-            if i < (count - 1):
+            if i > 0:
                 f.write(',')
+            json.dump(post, f, cls=jsonify.GenericJSON, indent=2)
         f.write(']}')
 
 class RootController(BaseController, FeedController):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dd4700db/ForgeDiscussion/forgediscussion/forum_main.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py
index bf1835d..a91508d 100644
--- a/ForgeDiscussion/forgediscussion/forum_main.py
+++ b/ForgeDiscussion/forgediscussion/forum_main.py
@@ -219,12 +219,11 @@ class ForgeDiscussionApp(Application):
 
     def bulk_export(self, f):
         f.write('{"forums": [')
-        forums = DM.Forum.query.find(dict(app_config_id=self.config._id)).sort('mod_date', pymongo.DESCENDING).all()
-        count = len(forums)
+        forums = DM.Forum.query.find(dict(app_config_id=self.config._id)).sort('mod_date', pymongo.DESCENDING)
         for i, forum in enumerate(forums):
-            json.dump(forum, f, cls=jsonify.GenericJSON, indent=2)
-            if i < (count - 1):
+            if i > 0:
                 f.write(',')
+            json.dump(forum, f, cls=jsonify.GenericJSON, indent=2)
         f.write(']}')
 
 class ForumAdminController(DefaultAdminController):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dd4700db/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index f76a843..d09710d 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -412,12 +412,11 @@ class ForgeTrackerApp(Application):
         f.write('{"tickets": [')
         tickets = TM.Ticket.query.find(dict(
             app_config_id=self.config._id,
-            deleted=False)).all()
-        count = len(tickets)
+            deleted=False))
         for i, ticket in enumerate(tickets):
-            json.dump(ticket, f, cls=jsonify.GenericJSON, indent=2)
-            if i < (count - 1):
+            if i > 0:
                 f.write(',')
+            json.dump(ticket, f, cls=jsonify.GenericJSON, indent=2)
         f.write('],\n"tracker_config":')
         json.dump(self.config, f, cls=jsonify.GenericJSON, indent=2)
         f.write(',\n"milestones":')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dd4700db/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index f0b85a7..5fecbb2 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -291,12 +291,11 @@ The wiki uses [Markdown](%s) syntax.
         f.write('{"pages": [')
         pages = WM.Page.query.find(dict(
             app_config_id=self.config._id,
-            deleted=False)).all()
-        count = len(pages)
+            deleted=False))
         for i, page in enumerate(pages):
-            json.dump(page, f, cls=jsonify.GenericJSON, indent=2)
-            if i < (count - 1):
+            if i > 0:
                 f.write(',')
+            json.dump(page, f, cls=jsonify.GenericJSON, indent=2)
         f.write(']}')
 
 


[31/50] git commit: [#3154] ticket:409 fixed bulk export for nbhd and user projects

Posted by br...@apache.org.
[#3154]  ticket:409 fixed bulk export for nbhd and user 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/c2ab8949
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/c2ab8949
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/c2ab8949

Branch: refs/heads/db/3154b
Commit: c2ab8949c70d633164001e081a92047269c9675b
Parents: 060ecbf
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Tue Aug 13 18:15:28 2013 +0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:58 2013 +0000

----------------------------------------------------------------------
 Allura/allura/ext/admin/admin_main.py        |  2 +-
 Allura/allura/model/project.py               | 18 ++++++++++++++++--
 Allura/allura/tasks/export_tasks.py          |  5 +++--
 Allura/allura/tests/functional/test_admin.py | 23 +++++++++++++++++++++--
 Allura/allura/tests/test_tasks.py            | 10 +++++-----
 5 files changed, 46 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c2ab8949/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 0dbc5a5..d1f98da 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -649,7 +649,7 @@ class ProjectAdminController(BaseController):
             if c.project.bulk_export_status() == 'busy':
                 flash('Export for project %s already running' % c.project.shortname, 'info')
                 redirect('export')
-            export_tasks.bulk_export.post(c.project.shortname, tools, c.user.username)
+            export_tasks.bulk_export.post(c.project.shortname, tools, c.user.username, c.project.neighborhood.name)
             flash('Export scheduled', 'ok')
             redirect('export')
         return {

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c2ab8949/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 1b21d37..18bd934 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -846,12 +846,26 @@ class Project(MappedClass, ActivityNode, ActivityObject):
                 ))
 
     def bulk_export_path(self):
+        shortname = self.shortname
+        if self.is_nbhd_project:
+            shortname = self.url().strip('/')
+        elif self.is_user_project:
+            shortname = self.shortname.split('/')[1]
+        elif not self.is_root:
+            shortname = self.shortname.split('/')[0]
         return config['bulk_export_path'].format(
                 nbhd=self.neighborhood.url_prefix.strip('/'),
-                project=self.shortname)
+                project=shortname)
 
     def bulk_export_filename(self):
-        return '%s.zip' % self.shortname
+        shortname = self.shortname
+        if self.is_nbhd_project:
+            shortname = self.url().strip('/')
+        elif self.is_user_project:
+            shortname = self.shortname.split('/')[1]
+        elif not self.is_root:
+            shortname = self.shortname.split('/')[1]
+        return '%s.zip' % shortname
 
     def bulk_export_status(self):
         fn = os.path.join(self.bulk_export_path(), self.bulk_export_filename())

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c2ab8949/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index 9933e26..0eb99e0 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -34,8 +34,9 @@ log = logging.getLogger(__name__)
 
 
 @task
-def bulk_export(project_shortname, tools, username):
-    project = M.Project.query.get(shortname=project_shortname)
+def bulk_export(project_shortname, tools, username, neighborhood):
+    neighborhood = M.Neighborhood.query.get(name=neighborhood)
+    project = M.Project.query.get(shortname=project_shortname, neighborhood_id=neighborhood._id)
     if not project:
         log.error('Project %s not found' % project_shortname)
         return

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c2ab8949/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 4fd0d19..9ee232f 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -825,14 +825,14 @@ class TestExport(TestController):
         r = self.app.post('/admin/export', {'tools': u'wiki'})
         assert_in('ok', self.webflash(r))
         export_tasks.bulk_export.post.assert_called_once_with(
-            'test', [u'wiki'], u'test-admin')
+            'test', [u'wiki'], u'test-admin', u'Projects')
 
     @mock.patch('allura.ext.admin.admin_main.export_tasks')
     def test_selected_multiple_tools(self, export_tasks):
         r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
         assert_in('ok', self.webflash(r))
         export_tasks.bulk_export.post.assert_called_once_with(
-            'test', [u'wiki', u'wiki2'], u'test-admin')
+            'test', [u'wiki', u'wiki2'], u'test-admin', u'Projects')
 
     @patch('allura.ext.admin.admin_main.export_tasks')
     def test_export_in_progress(self, export_tasks):
@@ -855,3 +855,22 @@ class TestExport(TestController):
         r = self.app.get('/admin/export')
         assert_in('<h2>Careful!</h2>', r)
         shutil.rmtree(p.bulk_export_path(), ignore_errors=True)
+
+    @td.with_user_project('test-user')
+    def test_bulk_export_path_for_user_project(self):
+        project = M.Project.query.get(shortname='u/test-user')
+        assert_equals(project.bulk_export_path(), '/tmp/bulk_export/u/test-user')
+
+    @td.with_user_project('test-user')
+    def test_bulk_export_filename_for_user_project(self):
+        project = M.Project.query.get(shortname='u/test-user')
+        assert_equals(project.bulk_export_filename(), 'test-user.zip')
+
+    def test_bulk_export_filename_for_nbhd(self):
+        project = M.Project.query.get(name='Home Project for Projects')
+        assert_equals(project.bulk_export_filename(), 'p.zip')
+
+    def test_bulk_export_path_for_nbhd(self):
+        project = M.Project.query.get(name='Home Project for Projects')
+        assert_equals(project.bulk_export_path(), '/tmp/bulk_export/p/p')
+

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c2ab8949/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index c772253..a1e09c3 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -342,12 +342,12 @@ class TestExportTasks(unittest.TestCase):
 
     @mock.patch('allura.tasks.export_tasks.log')
     def test_bulk_export_invalid_project(self, log):
-        export_tasks.bulk_export('bad', [u'wiki'], 'test-admin')
+        export_tasks.bulk_export('bad', [u'wiki'], 'test-admin', 'Projects')
         log.error.assert_called_once_with('Project bad not found')
 
     @mock.patch('allura.tasks.export_tasks.log')
     def test_bulk_export_invalid_tool(self, log):
-        export_tasks.bulk_export('test', [u'bugs', u'blog'], 'test-admin')
+        export_tasks.bulk_export('test', [u'bugs', u'blog'], 'test-admin', 'Projects')
         assert_equal(log.info.call_count, 2)
         assert_equal(log.info.call_args_list, [
             mock.call('Can not load app for bugs mount point. Skipping.'),
@@ -360,7 +360,7 @@ class TestExportTasks(unittest.TestCase):
     @td.with_tool('test', 'Blog', 'blog')
     def test_bulk_export_not_exportable_tool(self, mail_tasks, app, log):
         app.return_value.exportable = False
-        export_tasks.bulk_export('test', [u'bugs', u'blog'], 'test-admin')
+        export_tasks.bulk_export('test', [u'bugs', u'blog'], 'test-admin', 'Projects')
         assert_equal(log.info.call_count, 2)
         assert_equal(log.info.call_args_list, [
             mock.call('Tool bugs is not exportable. Skipping.'),
@@ -374,7 +374,7 @@ class TestExportTasks(unittest.TestCase):
     @td.with_wiki
     def test_bulk_export(self, log, wiki_bulk_export, zipdir, shutil, project_json):
         M.MonQTask.query.remove()
-        export_tasks.bulk_export('test', [u'wiki'], 'test-admin')
+        export_tasks.bulk_export('test', [u'wiki'], 'test-admin', 'Projects')
         assert_equal(log.info.call_count, 1)
         assert_equal(log.info.call_args_list, [
             mock.call('Exporting wiki...')])
@@ -403,7 +403,7 @@ class TestExportTasks(unittest.TestCase):
         project = M.Project.query.get(shortname='test')
         export_tasks.create_export_dir(project)
         assert_equal(project.bulk_export_status(), 'busy')
-        export_tasks.bulk_export('test', [u'wiki'], 'test-admin')
+        export_tasks.bulk_export('test', [u'wiki'], 'test-admin', 'Projects')
         log.info.assert_called_once_with('Another export is running for project test. Skipping.')
         assert_equal(wiki_bulk_export.call_count, 0)
 


[14/50] git commit: [#3153] ticket:389 added config to tracker bulk_export

Posted by br...@apache.org.
[#3153] ticket:389 added config to tracker bulk_export


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

Branch: refs/heads/db/3154b
Commit: f2930dc4d6c22eb5c58a50e5be55ebacccb256b6
Parents: bdd607c
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Tue Jul 23 18:30:31 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:55 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/project.py              | 14 ++++++++++++++
 ForgeTracker/forgetracker/tests/test_app.py | 11 +++++++++--
 ForgeTracker/forgetracker/tracker_main.py   |  4 +++-
 3 files changed, 26 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f2930dc4/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index fb14fc7..b6d6a1f 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -902,3 +902,17 @@ class AppConfig(MappedClass):
     def breadcrumbs(self):
         return self.project.breadcrumbs() + [
             (self.options.mount_point, self.url()) ]
+
+    def __json__(self):
+        return dict(
+            _id=self._id,
+            project_id=self.project_id,
+            discussion_id=self.discussion_id,
+            tool_name=self.tool_name,
+            version=self.version,
+            options=self.options,
+            # project=self.project,
+            # discussion=self.discussion
+            tool_data=self.tool_data,
+            acl=self.acl,
+        )

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f2930dc4/ForgeTracker/forgetracker/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/test_app.py b/ForgeTracker/forgetracker/tests/test_app.py
index e99948b..7437e4d 100644
--- a/ForgeTracker/forgetracker/tests/test_app.py
+++ b/ForgeTracker/forgetracker/tests/test_app.py
@@ -20,7 +20,7 @@ import tempfile
 import json
 import operator
 
-from nose.tools import assert_equal
+from nose.tools import assert_equal, assert_true
 
 from allura import model as M
 from allura.tests import decorators as td
@@ -44,6 +44,7 @@ class TestBulkExport(TrackerTestController):
         self.tracker.bulk_export(f)
         f.seek(0)
         tracker = json.loads(f.read())
+
         tickets = sorted(tracker['tickets'], key=operator.itemgetter('summary'))
         assert_equal(len(tickets), 2)
         ticket_foo = tickets[1]
@@ -51,4 +52,10 @@ class TestBulkExport(TrackerTestController):
         assert_equal(ticket_foo['custom_fields']['_milestone'], '1.0')
         posts_foo = ticket_foo['discussion_thread']['posts']
         assert_equal(len(posts_foo), 1)
-        assert_equal(posts_foo[0]['text'], 'silly comment')                
+        assert_equal(posts_foo[0]['text'], 'silly comment')         
+
+        tracker_config = tracker['tracker_config']
+        assert_equal(tracker_config['project_id'], unicode(self.project._id))
+        assert_true('options' in tracker_config.keys())
+        assert_true('acl' in tracker_config.keys())
+        assert_equal(tracker_config['options']['mount_point'], 'bugs')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f2930dc4/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 11c495d..8b34b35 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -418,7 +418,9 @@ class ForgeTrackerApp(Application):
             json.dump(ticket, f, cls=jsonify.GenericJSON)
             if i < (count - 1):
                 f.write(',')
-        f.write(']}')
+        f.write('], "tracker_config":')
+        json.dump(self.config, f, cls=jsonify.GenericJSON)
+        f.write('}')
 
     @property
     def bins(self):


[02/50] git commit: [#3154] ticket:386 Config option for export dir

Posted by br...@apache.org.
[#3154] ticket:386 Config option for export dir


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

Branch: refs/heads/db/3154b
Commit: 2debd0871e7c57d0401da67c1ee89019587c0d14
Parents: d06a7f8
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 4 12:24:07 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:53 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/project.py | 6 ++++++
 Allura/development.ini         | 2 ++
 2 files changed, 8 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2debd087/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index db7da13..82c9a97 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -820,6 +820,12 @@ class Project(MappedClass, ActivityNode, ActivityObject):
                 accounturl=accounturl
                 ))
 
+    def bulk_export_path(self):
+        return config['bulk_export_path'].format(
+                nbhd=self.neighborhood.url_prefix.strip('/'),
+                project=self.shortname)
+
+
 class AppConfig(MappedClass):
     """
     Configuration information for an instantiated :class:`Application <allura.app.Application>`

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2debd087/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 338b8ee..6fe2e6e 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -142,6 +142,8 @@ scm.repos.tarball.root = /usr/share/nginx/www/
 scm.repos.tarball.url_prefix = http://localhost/
 scm.repos.tarball.zip_binary = /usr/bin/zip
 
+bulk_export_path = /tmp/bulk_export/{nbhd}/{project}
+
 # space-separated list of tool names that are valid options
 # for project admins to set for their 'support_page' field
 # this field is not used by default in Allura, so this option


[15/50] git commit: [#3153] ticket:389 finished tickets with posts export

Posted by br...@apache.org.
[#3153] ticket:389 finished tickets with posts export


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

Branch: refs/heads/db/3154b
Commit: bdd607cf74d294928ff5f41641d2c23e08cce761
Parents: 394474a
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Tue Jul 23 17:39:23 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:55 2013 +0000

----------------------------------------------------------------------
 ForgeTracker/forgetracker/tests/test_app.py | 15 +++++++++++----
 ForgeTracker/forgetracker/tracker_main.py   |  1 +
 2 files changed, 12 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bdd607cf/ForgeTracker/forgetracker/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/test_app.py b/ForgeTracker/forgetracker/tests/test_app.py
index 9c7e61e..e99948b 100644
--- a/ForgeTracker/forgetracker/tests/test_app.py
+++ b/ForgeTracker/forgetracker/tests/test_app.py
@@ -35,13 +35,20 @@ class TestBulkExport(TrackerTestController):
         self.project = M.Project.query.get(shortname='test')
         self.tracker = self.project.app_instance('bugs')
         self.new_ticket(summary='foo', _milestone='1.0')
+        self.new_ticket(summary='bar', _milestone='1.0')
+        ticket = TM.Ticket.query.find(dict(summary='foo')).first()
+        ticket.discussion_thread.add_post(text='silly comment')
 
     def test_bulk_export(self):
         f = tempfile.TemporaryFile()
         self.tracker.bulk_export(f)
         f.seek(0)
         tracker = json.loads(f.read())
-        #tickets = sorted(tracker['tickets'], key=operator.itemgetter('title'))
-        tickets = tracker['tickets']
-        print tickets
-        assert_equal(len(tickets), 1)
+        tickets = sorted(tracker['tickets'], key=operator.itemgetter('summary'))
+        assert_equal(len(tickets), 2)
+        ticket_foo = tickets[1]
+        assert_equal(ticket_foo['summary'], 'foo')                
+        assert_equal(ticket_foo['custom_fields']['_milestone'], '1.0')
+        posts_foo = ticket_foo['discussion_thread']['posts']
+        assert_equal(len(posts_foo), 1)
+        assert_equal(posts_foo[0]['text'], 'silly comment')                

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/bdd607cf/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index d39d8d6..11c495d 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -206,6 +206,7 @@ class ForgeTrackerApp(Application):
             schema.OneOf('NewTicketsOnly', 'AllTicketChanges',
                 'NewPublicTicketsOnly', 'AllPublicTicketChanges'), None)
         ]
+    exportable = True
     searchable=True
     tool_label='Tickets'
     tool_description="""


[44/50] git commit: [#3154] ticket:411 test fixes for zip_and_cleanup

Posted by br...@apache.org.
[#3154] ticket:411 test fixes for zip_and_cleanup


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

Branch: refs/heads/db/3154b
Commit: d87f7ae99c7986d36a41b8ba5b24c673c05297ba
Parents: 6d3d0bb
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Tue Aug 13 17:25:27 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tasks/export_tasks.py               | 9 ++++++---
 ForgeDiscussion/forgediscussion/tests/test_app.py | 2 ++
 2 files changed, 8 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d87f7ae9/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index 3e2a9af..b5fcb34 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -72,9 +72,12 @@ def bulk_export(project_shortname, tools, username, neighborhood):
     except:
         log.error('Something went wrong during export of project metadata', exc_info=True)
 
-    # If that fails, we need to let it fail
-    # there won't be a valid zip file for the user to get.
-    zip_and_cleanup(project)
+    if tools and len(not_exported_tools) < len(tools):
+        # If that fails, we need to let it fail
+        # there won't be a valid zip file for the user to get.
+        zip_and_cleanup(project)
+    else:
+        log.error('Nothing to export')
 
     user = M.User.by_username(username)
     if not user:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/d87f7ae9/ForgeDiscussion/forgediscussion/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/test_app.py b/ForgeDiscussion/forgediscussion/tests/test_app.py
index bc9dcb1..07b65f4 100644
--- a/ForgeDiscussion/forgediscussion/tests/test_app.py
+++ b/ForgeDiscussion/forgediscussion/tests/test_app.py
@@ -41,6 +41,8 @@ class TestBulkExport(TestDiscussionApiBase):
         assert_equal(forums[0]['shortname'], u'general')
         assert_equal(forums[0]['description'], u'Forum about anything you want to talk about.')
         assert_equal(forums[0]['name'], u'General Discussion')
+        forums[0]['threads'] = sorted(forums[0]['threads'],
+            key=lambda x: x['posts'][0]['subject'])
         assert_equal(forums[0]['threads'][0]['posts'][0]['text'], u'Hi boys and girls')
         assert_equal(forums[0]['threads'][0]['posts'][0]['subject'], u'Hi guys')
         assert_equal(forums[0]['threads'][1]['posts'][0]['text'], u'1st post')


[06/50] git commit: [#3154] ticket:386 Notify user when export finished

Posted by br...@apache.org.
[#3154] ticket:386 Notify user when export finished


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

Branch: refs/heads/db/3154b
Commit: 23bc5dd0d8b5a613c5f812039a7f839fb9245e24
Parents: 8fb6750
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 4 17:28:24 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:54 2013 +0000

----------------------------------------------------------------------
 Allura/allura/ext/admin/admin_main.py         |  2 +-
 Allura/allura/tasks/export_tasks.py           | 29 +++++++++++++++++++++-
 Allura/allura/templates/mail/bulk_export.html | 29 ++++++++++++++++++++++
 Allura/allura/tests/functional/test_admin.py  | 15 ++++++++---
 Allura/allura/tests/test_tasks.py             | 21 ++++++++++++----
 Allura/development.ini                        |  1 +
 Allura/test.ini                               |  1 +
 7 files changed, 87 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/23bc5dd0/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 ee59e1d..ca55645 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -649,7 +649,7 @@ class ProjectAdminController(BaseController):
             if c.project.bulk_export_status() == 'busy':
                 flash('Export for project %s already running' % c.project.shortname, 'info')
                 redirect('export')
-            export_tasks.bulk_export.post(c.project.shortname, tools)
+            export_tasks.bulk_export.post(c.project.shortname, tools, c.user.username)
             flash('Export scheduled', 'ok')
             redirect('export')
         return {

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/23bc5dd0/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index 64aee3f..d097205 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -19,8 +19,13 @@ import os
 import logging
 import shutil
 
+import tg
+from pylons import app_globals as g
+
 from allura import model as M
+from allura.tasks import mail_tasks
 from allura.lib.decorators import task
+from allura.lib import helpers as h
 from allura.model.repository import zipdir
 
 
@@ -28,7 +33,7 @@ log = logging.getLogger(__name__)
 
 
 @task
-def bulk_export(project_shortname, tools):
+def bulk_export(project_shortname, tools, username):
     project = M.Project.query.get(shortname=project_shortname)
     if not project:
         log.error('Project %s not found' % project_shortname)
@@ -58,6 +63,28 @@ def bulk_export(project_shortname, tools):
     except:
         log.error('Something went wrong during zipping exported data.', exc_info=True)
 
+    user = M.User.by_username(username)
+    if not user:
+        log.info('Can not find user %s. Skipping notification.' % username)
+        return
+    tmpl = g.jinja2_env.get_template('allura:templates/mail/bulk_export.html')
+    instructions = tg.config.get('bulk_export_download_instructions', '')
+    instructions = instructions.format(project=project.shortname)
+    tmpl_context = {
+        'instructions': instructions,
+        'project': project,
+        'tools': tools,
+    }
+    email = {
+        'fromaddr': unicode(user.email_address_header()),
+        'reply_to': unicode(user.email_address_header()),
+        'message_id': h.gen_message_id(),
+        'destinations': [unicode(user._id)],
+        'subject': u'Bulk export for project %s completed' % project_shortname,
+        'text': tmpl.render(tmpl_context),
+    }
+    mail_tasks.sendmail.post(**email)
+
 
 def create_export_dir(project):
     """Create temporary directory for export files"""

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/23bc5dd0/Allura/allura/templates/mail/bulk_export.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/mail/bulk_export.html b/Allura/allura/templates/mail/bulk_export.html
new file mode 100644
index 0000000..420848f
--- /dev/null
+++ b/Allura/allura/templates/mail/bulk_export.html
@@ -0,0 +1,29 @@
+{#
+       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.
+#}
+
+Bulk export for project {{ project.shortname }} is completed.
+
+Following tools was exported:
+{% for tool in tools %}
+- {{ tool }}
+{% endfor %}
+
+Follow instructions below to get exported data.
+
+{{ instructions }}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/23bc5dd0/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 8e205b5..774fd36 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -820,26 +820,33 @@ class TestExport(TestController):
         r = self.app.post('/admin/export', {'tools': u'wiki'})
         assert_in('ok', self.webflash(r))
         export_tasks.bulk_export.post.assert_called_once_with(
-            'test', [u'wiki'])
+            'test', [u'wiki'], u'test-admin')
 
     @mock.patch('allura.ext.admin.admin_main.export_tasks')
     def test_selected_multiple_tools(self, export_tasks):
         r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
         assert_in('ok', self.webflash(r))
         export_tasks.bulk_export.post.assert_called_once_with(
-            'test', [u'wiki', u'wiki2'])
+            'test', [u'wiki', u'wiki2'], u'test-admin')
 
     @patch('allura.ext.admin.admin_main.export_tasks')
     def test_export_in_progress(self, export_tasks):
         p = M.Project.query.get(shortname='test')
         tmpdir = os.path.join(p.bulk_export_path(), p.shortname)
-        shutil.rmtree(tmpdir, ignore_errors=True)
+        shutil.rmtree(p.bulk_export_path(), ignore_errors=True)
         os.makedirs(tmpdir)
         r = self.app.post('/admin/export', {'tools': [u'wiki', u'wiki2']})
         assert_in('info', self.webflash(r))
         assert_equals(export_tasks.bulk_export.post.call_count, 0)
-        shutil.rmtree(tmpdir, ignore_errors=True)
+        shutil.rmtree(p.bulk_export_path(), ignore_errors=True)
 
     def test_export_done(self):
+        p = M.Project.query.get(shortname='test')
+        shutil.rmtree(p.bulk_export_path(), ignore_errors=True)
+        os.makedirs(p.bulk_export_path())
+        fn = os.path.join(p.bulk_export_path(), p.bulk_export_filename())
+        with open(fn, 'w') as f:
+            f.write('Pretending I am zip archive')
         r = self.app.get('/admin/export')
         assert_in('<h2>Careful!</h2>', r)
+        shutil.rmtree(p.bulk_export_path(), ignore_errors=True)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/23bc5dd0/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 5f2e44c..39c3397 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -342,12 +342,12 @@ class TestExportTasks(unittest.TestCase):
 
     @mock.patch('allura.tasks.export_tasks.log')
     def test_bulk_export_invalid_project(self, log):
-        export_tasks.bulk_export('bad', [u'wiki'])
+        export_tasks.bulk_export('bad', [u'wiki'], 'test-admin')
         log.error.assert_called_once_with('Project bad not found')
 
     @mock.patch('allura.tasks.export_tasks.log')
     def test_bulk_export_invalid_tool(self, log):
-        export_tasks.bulk_export('test', [u'bugs', u'blog'])
+        export_tasks.bulk_export('test', [u'bugs', u'blog'], 'test-admin')
         assert_equal(log.info.call_count, 2)
         assert_equal(log.info.call_args_list, [
             mock.call('Can not load app for bugs mount point. Skipping.'),
@@ -357,7 +357,7 @@ class TestExportTasks(unittest.TestCase):
     @td.with_tool('test', 'Tickets', 'bugs')
     @td.with_tool('test', 'Blog', 'blog')
     def test_bulk_export_not_exportable_tool(self, log):
-        export_tasks.bulk_export('test', [u'bugs', u'blog'])
+        export_tasks.bulk_export('test', [u'bugs', u'blog'], 'test-admin')
         assert_equal(log.info.call_count, 2)
         assert_equal(log.info.call_args_list, [
             mock.call('Tool bugs is not exportable. Skipping.'),
@@ -369,7 +369,8 @@ class TestExportTasks(unittest.TestCase):
     @mock.patch('allura.tasks.export_tasks.log')
     @td.with_wiki
     def test_bulk_export(self, log, wiki_bulk_export, zipdir, shutil):
-        export_tasks.bulk_export('test', [u'wiki'])
+        M.MonQTask.query.remove()
+        export_tasks.bulk_export('test', [u'wiki'], 'test-admin')
         assert_equal(log.info.call_count, 1)
         assert_equal(log.info.call_args_list, [
             mock.call('Exporting wiki...')])
@@ -379,6 +380,16 @@ class TestExportTasks(unittest.TestCase):
         zipdir.assert_caled_once_with(temp, temp + '/test.zip')
         shutil.move.assert_called_once_with(temp + '/test.zip',  zipfn)
         shutil.rmtree.assert_called_once_with(temp)
+        # check notification
+        M.MonQTask.run_ready()
+        tasks = M.MonQTask.query.find(
+            dict(task_name='allura.tasks.mail_tasks.sendmail')).all()
+        assert_equal(len(tasks), 1)
+        assert_equal(tasks[0].kwargs['subject'], 'Bulk export for project test completed')
+        text = tasks[0].kwargs['text']
+        assert_in('Bulk export for project test is completed.', text)
+        assert_in('Following tools was exported:\n\n- wiki', text)
+        assert_in('Sample instructions for test', text)
 
     @mock.patch('forgewiki.wiki_main.ForgeWikiApp.bulk_export')
     @mock.patch('allura.tasks.export_tasks.log')
@@ -387,7 +398,7 @@ class TestExportTasks(unittest.TestCase):
         project = M.Project.query.get(shortname='test')
         export_tasks.create_export_dir(project)
         assert_equal(project.bulk_export_status(), 'busy')
-        export_tasks.bulk_export('test', [u'wiki'])
+        export_tasks.bulk_export('test', [u'wiki'], 'test-admin')
         log.info.assert_called_once_with('Another export is running for project test. Skipping.')
         assert_equal(wiki_bulk_export.call_count, 0)
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/23bc5dd0/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 6fe2e6e..0d3386b 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -143,6 +143,7 @@ scm.repos.tarball.url_prefix = http://localhost/
 scm.repos.tarball.zip_binary = /usr/bin/zip
 
 bulk_export_path = /tmp/bulk_export/{nbhd}/{project}
+bulk_export_download_instructions = Sample instructions for {project}
 
 # space-separated list of tool names that are valid options
 # for project admins to set for their 'support_page' field

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/23bc5dd0/Allura/test.ini
----------------------------------------------------------------------
diff --git a/Allura/test.ini b/Allura/test.ini
index 6babfaf..9ce586e 100644
--- a/Allura/test.ini
+++ b/Allura/test.ini
@@ -103,6 +103,7 @@ scm.repos.tarball.root = /tmp/tarball
 scm.repos.tarball.url_prefix = file://
 
 bulk_export_path = /tmp/bulk_export/{nbhd}/{project}
+bulk_export_download_instructions = Sample instructions for {project}
 
 support_tool_choices = wiki tickets discussion
 


[08/50] git commit: [#3154] ticket:386 Don't run export if another one is running

Posted by br...@apache.org.
[#3154] ticket:386 Don't run export if another one is running


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

Branch: refs/heads/db/3154b
Commit: 6afdaf596f7627751aadbbc9935b28f59d205420
Parents: 18c6449
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 4 15:21:10 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:54 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/project.py      |  9 +++++++
 Allura/allura/tasks/export_tasks.py |  3 +++
 Allura/allura/tests/test_tasks.py   | 42 ++++++++++++++++++++++++++++----
 3 files changed, 49 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6afdaf59/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index aaf5828..fb14fc7 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -15,6 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+import os
 import logging
 from collections import Counter, OrderedDict
 from datetime import datetime
@@ -828,6 +829,14 @@ class Project(MappedClass, ActivityNode, ActivityObject):
     def bulk_export_filename(self):
         return '%s.zip' % self.shortname
 
+    def bulk_export_status(self):
+        fn = os.path.join(self.bulk_export_path(), self.bulk_export_filename())
+        tmpdir = os.path.join(self.bulk_export_path(), self.shortname)
+        if os.path.isfile(fn):
+            return 'ready'
+        elif os.path.exists(tmpdir):
+            return 'busy'
+
 
 class AppConfig(MappedClass):
     """

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6afdaf59/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index f2f5371..64aee3f 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -33,6 +33,9 @@ def bulk_export(project_shortname, tools):
     if not project:
         log.error('Project %s not found' % project_shortname)
         return
+    if project.bulk_export_status() == 'busy':
+        log.info('Another export is running for project %s. Skipping.' % project_shortname)
+        return
     for tool in tools or []:
         app = project.app_instance(tool)
         if not app:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/6afdaf59/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index d6f676e..5f2e44c 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -333,6 +333,12 @@ class TestExportTasks(unittest.TestCase):
     def setUp(self):
         setup_basic_test()
         setup_global_objects()
+        project = M.Project.query.get(shortname='test')
+        shutil.rmtree(project.bulk_export_path(), ignore_errors=True)
+
+    def tearDown(self):
+        project = M.Project.query.get(shortname='test')
+        shutil.rmtree(project.bulk_export_path(), ignore_errors=True)
 
     @mock.patch('allura.tasks.export_tasks.log')
     def test_bulk_export_invalid_project(self, log):
@@ -357,35 +363,61 @@ class TestExportTasks(unittest.TestCase):
             mock.call('Tool bugs is not exportable. Skipping.'),
             mock.call('Tool blog is not exportable. Skipping.')])
 
+    @mock.patch('allura.tasks.export_tasks.shutil')
+    @mock.patch('allura.tasks.export_tasks.zipdir')
     @mock.patch('forgewiki.wiki_main.ForgeWikiApp.bulk_export')
     @mock.patch('allura.tasks.export_tasks.log')
     @td.with_wiki
-    def test_bulk_export(self, log, wiki_bulk_export):
+    def test_bulk_export(self, log, wiki_bulk_export, zipdir, shutil):
         export_tasks.bulk_export('test', [u'wiki'])
         assert_equal(log.info.call_count, 1)
         assert_equal(log.info.call_args_list, [
             mock.call('Exporting wiki...')])
         wiki_bulk_export.assert_called_once()
+        temp = '/tmp/bulk_export/p/test/test'
+        zipfn = '/tmp/bulk_export/p/test/test.zip'
+        zipdir.assert_caled_once_with(temp, temp + '/test.zip')
+        shutil.move.assert_called_once_with(temp + '/test.zip',  zipfn)
+        shutil.rmtree.assert_called_once_with(temp)
+
+    @mock.patch('forgewiki.wiki_main.ForgeWikiApp.bulk_export')
+    @mock.patch('allura.tasks.export_tasks.log')
+    @td.with_wiki
+    def test_bulk_export_quits_if_another_export_is_running(self, log, wiki_bulk_export):
+        project = M.Project.query.get(shortname='test')
+        export_tasks.create_export_dir(project)
+        assert_equal(project.bulk_export_status(), 'busy')
+        export_tasks.bulk_export('test', [u'wiki'])
+        log.info.assert_called_once_with('Another export is running for project test. Skipping.')
+        assert_equal(wiki_bulk_export.call_count, 0)
 
     def test_create_export_dir(self):
         project = M.Project.query.get(shortname='test')
         export_path = project.bulk_export_path()
-        shutil.rmtree(export_path, ignore_errors=True)
         path = export_tasks.create_export_dir(project)
         assert_equal(path, '/tmp/bulk_export/p/test/test')
         assert os.path.exists(os.path.join(export_path, project.shortname))
-        shutil.rmtree(export_path, ignore_errors=True)
 
     @onlyif(os.path.exists(tg.config.get('scm.repos.tarball.zip_binary', '/usr/bin/zip')), 'zip binary is missing')
     def test_zip_and_cleanup(self):
         project = M.Project.query.get(shortname='test')
         export_path = project.bulk_export_path()
-        shutil.rmtree(export_path, ignore_errors=True)
         path = export_tasks.create_export_dir(project)
         export_tasks.zip_and_cleanup(project)
         assert not os.path.exists(path)
         assert os.path.exists(os.path.join(export_path, 'test.zip'))
-        shutil.rmtree(export_path, ignore_errors=True)
+
+    def test_bulk_export_status(self):
+        project = M.Project.query.get(shortname='test')
+        assert_equal(project.bulk_export_status(), None)
+
+        export_tasks.create_export_dir(project)
+        assert_equal(project.bulk_export_status(), 'busy')
+
+        with open(os.path.join(project.bulk_export_path(),
+                               project.bulk_export_filename()), 'w') as f:
+            f.write('just test')
+        assert_equal(project.bulk_export_status(), 'ready')
 
 
 Mapper.compile_all()


[40/50] git commit: [#3154] ticket:410 used mkstemp with tmp file in export

Posted by br...@apache.org.
[#3154]  ticket:410 used mkstemp with tmp file in export


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

Branch: refs/heads/db/3154b
Commit: efe13f99f531dfc3b729a9b3b98d61c024fe3eff
Parents: b098e1e
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Wed Aug 14 17:14:04 2013 +0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/project.py      | 3 ++-
 Allura/allura/tasks/export_tasks.py | 5 ++++-
 Allura/development.ini              | 1 +
 Allura/test.ini                     | 1 +
 4 files changed, 8 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/efe13f99/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 41ea5c7..021bb47 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -866,7 +866,8 @@ class Project(MappedClass, ActivityNode, ActivityObject):
             shortname = self.shortname.split('/')[1]
         elif not self.is_root:
             shortname = self.shortname.split('/')[1]
-        return '%s.zip' % shortname
+
+        return config['bulk_export_filename'].format(project=shortname, date=datetime.utcnow())
 
     def bulk_export_status(self):
         fn = os.path.join(self.bulk_export_path(), self.bulk_export_filename())

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/efe13f99/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index bbd4b1d..4b30c36 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -19,6 +19,7 @@ import json
 import os
 import logging
 import shutil
+from tempfile import mkstemp
 
 import tg
 from pylons import app_globals as g
@@ -61,9 +62,11 @@ def bulk_export(project_shortname, tools, username, neighborhood):
         log.info('Exporting %s...' % tool)
         try:
             path = create_export_dir(project)
-            with open(os.path.join(path, '%s.json' % tool), 'w') as f:
+            temp_name = mkstemp(dir=path)[1]
+            with open(temp_name, 'w') as f:
                 with h.push_context(project._id):
                     entry_to_export.bulk_export(f)
+            os.rename(temp_name, os.path.join(path, '%s.json' % tool))
         except:
             log.error('Something went wrong during export of %s' % tool, exc_info=True)
             not_exported_tools.append(tool)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/efe13f99/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 0d3386b..ee9911b 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -143,6 +143,7 @@ scm.repos.tarball.url_prefix = http://localhost/
 scm.repos.tarball.zip_binary = /usr/bin/zip
 
 bulk_export_path = /tmp/bulk_export/{nbhd}/{project}
+bulk_export_filename = {project}-backup-{date:%Y-%m-%d-%H%M%S}.zip
 bulk_export_download_instructions = Sample instructions for {project}
 
 # space-separated list of tool names that are valid options

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/efe13f99/Allura/test.ini
----------------------------------------------------------------------
diff --git a/Allura/test.ini b/Allura/test.ini
index 9ce586e..2546149 100644
--- a/Allura/test.ini
+++ b/Allura/test.ini
@@ -103,6 +103,7 @@ scm.repos.tarball.root = /tmp/tarball
 scm.repos.tarball.url_prefix = file://
 
 bulk_export_path = /tmp/bulk_export/{nbhd}/{project}
+bulk_export_filename = {project}.zip
 bulk_export_download_instructions = Sample instructions for {project}
 
 support_tool_choices = wiki tickets discussion


[20/50] git commit: [#3154] ticket:390 Bulk export: discussion

Posted by br...@apache.org.
[#3154]  ticket:390 Bulk export: discussion


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

Branch: refs/heads/db/3154b
Commit: 2988f808b9b2ecfd23e31a5f4d96df61fe8997a3
Parents: cc71ea5
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Fri Jul 26 10:31:30 2013 +0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:56 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/discuss.py                  |  9 ++--
 ForgeDiscussion/forgediscussion/forum_main.py   | 14 +++++-
 ForgeDiscussion/forgediscussion/model/forum.py  |  6 ---
 .../forgediscussion/tests/test_app.py           | 50 ++++++++++++++++++++
 4 files changed, 69 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2988f808/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index d13b7e9..ec5ccdc 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -64,8 +64,9 @@ class Discussion(Artifact, ActivityObject):
             shortname=self.shortname,
             name=self.name,
             description=self.description,
-            threads=[dict(_id=t._id, subject=t.subject)
-                     for t in self.threads])
+            threads=[t.__json__() for t in self.thread_class().query.find(
+                dict(discussion_id=self._id)).sort(
+                    'last_post_date', pymongo.DESCENDING)])
 
     @property
     def activity_name(self):
@@ -169,7 +170,9 @@ class Thread(Artifact, ActivityObject):
                         subject=p.subject,
                         attachments=[dict(bytes=attach.length,
                                           url=h.absurl(attach.url())) for attach in p.attachments])
-                   for p in self.posts if p.status == 'ok'])
+                   for p in self.post_class().query.find(
+                   dict(discussion_id=self.discussion_id, thread_id=self._id, status='ok')
+                   ).sort('timestamp', pymongo.DESCENDING)])
 
     @property
     def activity_name(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2988f808/ForgeDiscussion/forgediscussion/forum_main.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py
index 730f007..2465312 100644
--- a/ForgeDiscussion/forgediscussion/forum_main.py
+++ b/ForgeDiscussion/forgediscussion/forum_main.py
@@ -19,12 +19,13 @@
 import logging
 import urllib
 from itertools import islice
+import json
 
 # Non-stdlib imports
 import pymongo
 from pylons import tmpl_context as c, app_globals as g
 from pylons import request
-from tg import expose, redirect, flash, url, validate
+from tg import expose, redirect, flash, url, validate, jsonify
 from tg.decorators import with_trailing_slash
 from bson import ObjectId
 from ming import schema
@@ -67,6 +68,7 @@ class ForgeDiscussionApp(Application):
     PostClass=DM.ForumPost
     AttachmentClass=DM.ForumAttachment
     searchable=True
+    exportable=True
     tool_label='Discussion'
     tool_description="""
         Collaborate with your community in your forum.
@@ -215,6 +217,16 @@ class ForgeDiscussionApp(Application):
         DM.ForumPost.query.remove(dict(app_config_id=self.config._id))
         super(ForgeDiscussionApp, self).uninstall(project)
 
+    def bulk_export(self, f):
+        f.write('{"forums": [')
+        forums = DM.Forum.query.find(dict(app_config_id=self.config._id)).sort('mod_date', pymongo.DESCENDING).all()
+        count = len(forums)
+        for i, forum in enumerate(forums):
+            json.dump(forum, f, cls=jsonify.GenericJSON)
+            if i < (count - 1):
+                f.write(',')
+        f.write(']}')
+
 class ForumAdminController(DefaultAdminController):
 
     def _check_security(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2988f808/ForgeDiscussion/forgediscussion/model/forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/model/forum.py b/ForgeDiscussion/forgediscussion/model/forum.py
index 42d1dc0..84040da 100644
--- a/ForgeDiscussion/forgediscussion/model/forum.py
+++ b/ForgeDiscussion/forgediscussion/model/forum.py
@@ -194,12 +194,6 @@ class ForumThread(M.Thread):
             {'$set':dict(discussion_id=new_forum._id)})
         self.discussion_id = new_forum._id
 
-    def __json__(self):
-        return dict(
-            _id=self._id,
-            discussion_id=str(self.discussion_id),
-            subject=self.subject)
-
 
 class ForumPostHistory(M.PostHistory):
     class __mongometa__:

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2988f808/ForgeDiscussion/forgediscussion/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/test_app.py b/ForgeDiscussion/forgediscussion/tests/test_app.py
new file mode 100644
index 0000000..d54ab5a
--- /dev/null
+++ b/ForgeDiscussion/forgediscussion/tests/test_app.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+#       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.
+
+#-*- python -*-
+
+import tempfile
+import json
+from nose.tools import assert_equal
+
+from allura import model as M
+from forgediscussion.tests.functional.test_rest import TestDiscussionApiBase
+
+
+class TestBulkExport(TestDiscussionApiBase):
+
+    def test_bulk_export(self):
+        project = M.Project.query.get(shortname='test')
+        discussion = project.app_instance('discussion')
+        f = tempfile.TemporaryFile()
+        discussion.bulk_export(f)
+        f.seek(0)
+        discussion = json.loads(f.read())
+        forums = discussion['forums']
+
+        assert_equal(forums[0]['shortname'], u'general')
+        assert_equal(forums[0]['description'], u'Forum about anything you want to talk about.')
+        assert_equal(forums[0]['name'], u'General Discussion')
+        assert_equal(forums[0]['threads'][0]['posts'][0]['text'], u'Hi boys and girls')
+        assert_equal(forums[0]['threads'][0]['posts'][0]['subject'], u'Hi guys')
+        assert_equal(forums[0]['threads'][1]['posts'][0]['text'], u'1st post')
+        assert_equal(forums[0]['threads'][1]['posts'][0]['subject'], u"Let's talk")
+        assert_equal(forums[1]['shortname'], u'héllo')
+        assert_equal(forums[1]['description'], u'Say héllo here')
+        assert_equal(forums[1]['name'], u'Say Héllo')


[25/50] git commit: [#3154] ticket:395 updated bulk_export test

Posted by br...@apache.org.
[#3154] ticket:395 updated bulk_export test


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

Branch: refs/heads/db/3154b
Commit: f9dd322db50aa71b11f737941ba7cd41068d6778
Parents: 21cd30e
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Thu Jul 25 17:09:08 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:57 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/test_tasks.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/f9dd322d/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 06d4ede..cd10683 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -366,21 +366,23 @@ class TestExportTasks(unittest.TestCase):
             mock.call('Tool bugs is not exportable. Skipping.'),
             mock.call('Tool blog is not exportable. Skipping.')])
 
+    @mock.patch('allura.model.project.Project.__json__')
     @mock.patch('allura.tasks.export_tasks.shutil')
     @mock.patch('allura.tasks.export_tasks.zipdir')
     @mock.patch('forgewiki.wiki_main.ForgeWikiApp.bulk_export')
     @mock.patch('allura.tasks.export_tasks.log')
     @td.with_wiki
-    def test_bulk_export(self, log, wiki_bulk_export, zipdir, shutil):
+    def test_bulk_export(self, log, wiki_bulk_export, zipdir, shutil, project_json):
         M.MonQTask.query.remove()
         export_tasks.bulk_export('test', [u'wiki'], 'test-admin')
         assert_equal(log.info.call_count, 1)
         assert_equal(log.info.call_args_list, [
             mock.call('Exporting wiki...')])
         wiki_bulk_export.assert_called_once()
+        project_json.assert_called_once()
         temp = '/tmp/bulk_export/p/test/test'
         zipfn = '/tmp/bulk_export/p/test/test.zip'
-        zipdir.assert_caled_once_with(temp, temp + '/test.zip')
+        zipdir.assert_caled_with(temp, temp + '/test.zip')
         shutil.move.assert_called_once_with(temp + '/test.zip',  zipfn)
         shutil.rmtree.assert_called_once_with(temp)
         # check notification


[32/50] git commit: [#3154] ticket#411 removed sort in export queries

Posted by br...@apache.org.
[#3154] ticket#411 removed sort in export queries


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

Branch: refs/heads/db/3154b
Commit: 315f269565c59a1deb8560861f642476a7449080
Parents: c2ab894
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Tue Aug 13 14:41:00 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:58 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/discuss.py                    | 7 ++++---
 ForgeBlog/forgeblog/main.py                       | 2 +-
 ForgeBlog/forgeblog/tests/test_app.py             | 1 +
 ForgeDiscussion/forgediscussion/forum_main.py     | 2 +-
 ForgeDiscussion/forgediscussion/tests/test_app.py | 2 +-
 5 files changed, 8 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/315f2695/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index ec5ccdc..057bb97 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -65,8 +65,8 @@ class Discussion(Artifact, ActivityObject):
             name=self.name,
             description=self.description,
             threads=[t.__json__() for t in self.thread_class().query.find(
-                dict(discussion_id=self._id)).sort(
-                    'last_post_date', pymongo.DESCENDING)])
+                dict(discussion_id=self._id))]
+        )
 
     @property
     def activity_name(self):
@@ -172,7 +172,8 @@ class Thread(Artifact, ActivityObject):
                                           url=h.absurl(attach.url())) for attach in p.attachments])
                    for p in self.post_class().query.find(
                    dict(discussion_id=self.discussion_id, thread_id=self._id, status='ok')
-                   ).sort('timestamp', pymongo.DESCENDING)])
+                   )]
+        )
 
     @property
     def activity_name(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/315f2695/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 6f344cb..3abf4f0 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -192,7 +192,7 @@ class ForgeBlogApp(Application):
 
     def bulk_export(self, f):
         f.write('{"posts": [')
-        posts = BM.BlogPost.query.find(dict(app_config_id=self.config._id)).sort('timestamp', pymongo.DESCENDING)
+        posts = BM.BlogPost.query.find(dict(app_config_id=self.config._id))
         for i, post in enumerate(posts):
             if i > 0:
                 f.write(',')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/315f2695/ForgeBlog/forgeblog/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/tests/test_app.py b/ForgeBlog/forgeblog/tests/test_app.py
index 622dccf..7427b9b 100644
--- a/ForgeBlog/forgeblog/tests/test_app.py
+++ b/ForgeBlog/forgeblog/tests/test_app.py
@@ -56,6 +56,7 @@ class TestBulkExport(object):
         blog.bulk_export(f)
         f.seek(0)
         blog = json.loads(f.read())
+        blog['posts'] = sorted(blog['posts'], key=lambda x: x['title'], reverse=True)
         assert_equal(blog['posts'][0]['title'], 'Test2 title')
         assert_equal(blog['posts'][0]['text'], 'test2 post')
         assert_equal(blog['posts'][1]['title'], 'Test title')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/315f2695/ForgeDiscussion/forgediscussion/forum_main.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py
index a91508d..54c4bef 100644
--- a/ForgeDiscussion/forgediscussion/forum_main.py
+++ b/ForgeDiscussion/forgediscussion/forum_main.py
@@ -219,7 +219,7 @@ class ForgeDiscussionApp(Application):
 
     def bulk_export(self, f):
         f.write('{"forums": [')
-        forums = DM.Forum.query.find(dict(app_config_id=self.config._id)).sort('mod_date', pymongo.DESCENDING)
+        forums = DM.Forum.query.find(dict(app_config_id=self.config._id))
         for i, forum in enumerate(forums):
             if i > 0:
                 f.write(',')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/315f2695/ForgeDiscussion/forgediscussion/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/test_app.py b/ForgeDiscussion/forgediscussion/tests/test_app.py
index d54ab5a..bc9dcb1 100644
--- a/ForgeDiscussion/forgediscussion/tests/test_app.py
+++ b/ForgeDiscussion/forgediscussion/tests/test_app.py
@@ -36,7 +36,7 @@ class TestBulkExport(TestDiscussionApiBase):
         discussion.bulk_export(f)
         f.seek(0)
         discussion = json.loads(f.read())
-        forums = discussion['forums']
+        forums = sorted(discussion['forums'], key=lambda x: x['name'])
 
         assert_equal(forums[0]['shortname'], u'general')
         assert_equal(forums[0]['description'], u'Forum about anything you want to talk about.')


[36/50] git commit: [#3154] fix blog export test

Posted by br...@apache.org.
[#3154] fix blog export test


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

Branch: refs/heads/db/3154b
Commit: 8c96f3affde7cd81f8bb97fe650d4eb7a12ed8e3
Parents: bda31de
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Aug 1 19:31:42 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:58 2013 +0000

----------------------------------------------------------------------
 ForgeBlog/forgeblog/tests/test_app.py | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/8c96f3af/ForgeBlog/forgeblog/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/tests/test_app.py b/ForgeBlog/forgeblog/tests/test_app.py
index 7929dab..622dccf 100644
--- a/ForgeBlog/forgeblog/tests/test_app.py
+++ b/ForgeBlog/forgeblog/tests/test_app.py
@@ -44,11 +44,13 @@ class TestBulkExport(object):
         post.text = 'test post'
         post.labels = ['the firstlabel', 'the second label']
         post.make_slug()
+        post.commit()
         post.discussion_thread.add_post(text='test comment')
         post2 = BM.BlogPost()
         post2.title = 'Test2 title'
         post2.text = 'test2 post'
         post2.make_slug()
+        post2.commit()
 
         f = tempfile.TemporaryFile()
         blog.bulk_export(f)


[50/50] git commit: [#3154] don't hide task errors when run in tests

Posted by br...@apache.org.
[#3154] don't hide task errors when run in tests


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

Branch: refs/heads/db/3154b
Commit: a598db57dd2e6045839d176665ed09422f65ae21
Parents: a885568
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Aug 21 15:19:43 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:26:27 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/monq_model.py | 17 +++++++++++------
 Allura/test.ini                   |  3 +++
 2 files changed, 14 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a598db57/Allura/allura/model/monq_model.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/monq_model.py b/Allura/allura/model/monq_model.py
index 3163ea5..faac14b 100644
--- a/Allura/allura/model/monq_model.py
+++ b/Allura/allura/model/monq_model.py
@@ -23,6 +23,8 @@ from datetime import datetime, timedelta
 
 import pymongo
 from pylons import tmpl_context as c, app_globals as g
+from tg import config
+from paste.deploy.converters import asbool
 
 import ming
 from ming.utils import LazyProperty
@@ -257,13 +259,16 @@ class MonQTask(MappedClass):
             self.state = 'complete'
             return self.result
         except Exception, exc:
-            log.exception('Error "%s" on job %s', exc, self)
-            self.state = 'error'
-            if hasattr(exc, 'format_error'):
-                self.result = exc.format_error()
-                log.error(self.result)
+            if asbool(config.get('monq.raise_errors')):
+                raise
             else:
-                self.result = traceback.format_exc()
+                log.exception('Error "%s" on job %s', exc, self)
+                self.state = 'error'
+                if hasattr(exc, 'format_error'):
+                    self.result = exc.format_error()
+                    log.error(self.result)
+                else:
+                    self.result = traceback.format_exc()
         finally:
             self.time_stop = datetime.utcnow()
             session(self).flush(self)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a598db57/Allura/test.ini
----------------------------------------------------------------------
diff --git a/Allura/test.ini b/Allura/test.ini
index 2546149..9892e3c 100644
--- a/Allura/test.ini
+++ b/Allura/test.ini
@@ -68,6 +68,9 @@ load_test_data = true
 cache_test_data = false
 site_admin_project = test
 
+# useful primarily for test suites, where we want to see the error right away
+monq.raise_errors = true
+
 # Set the locations of some static resources
 #  script_name is the path that is handled by the application
 #  url_base is the prefix that references to the static resources should have


[21/50] git commit: [#3154] ticket:395 created project __json__

Posted by br...@apache.org.
[#3154] ticket:395 created project __json__


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

Branch: refs/heads/db/3154b
Commit: 546bfcc2ef1f540ceeaadd9722c1bf1338b02357
Parents: 2988f80
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Wed Jul 24 16:44:02 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:56 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/rest.py | 6 +-----
 Allura/allura/model/project.py    | 7 +++++++
 2 files changed, 8 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/546bfcc2/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index 6a41be3..d1b6cb1 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -281,8 +281,4 @@ class ProjectRestController(object):
 
     @expose('json:')
     def index(self, **kw):
-        return dict(
-            name=c.project.shortname,
-            tools=[dict(name=t.tool_name, mount_point=t.options.mount_point, label=t.options.mount_label)
-                   for t in c.project.app_configs if h.has_access(t, 'read')]
-        )
+        return c.project.__json__()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/546bfcc2/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 02fddac..1525eec 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -837,6 +837,13 @@ class Project(MappedClass, ActivityNode, ActivityObject):
         elif os.path.exists(tmpdir):
             return 'busy'
 
+    def __json__(self):
+        return dict(
+            name=self.shortname,
+            tools=[dict(name=t.tool_name, mount_point=t.options.mount_point, label=t.options.mount_label)
+                   for t in self.app_configs if h.has_access(t, 'read')]
+        )
+
 
 class AppConfig(MappedClass):
     """


[03/50] git commit: [#3154] ticket:388 Add not exported tools to notification email

Posted by br...@apache.org.
[#3154] ticket:388 Add not exported tools to notification email


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

Branch: refs/heads/db/3154b
Commit: e4f7cf540e246bd52be0ab6d74362571b9863cb9
Parents: 5beb58e
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 5 13:35:34 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:54 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tasks/export_tasks.py           | 7 ++++++-
 Allura/allura/templates/mail/bulk_export.html | 7 +++++++
 2 files changed, 13 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/e4f7cf54/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index d097205..672f51b 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -41,13 +41,16 @@ def bulk_export(project_shortname, tools, username):
     if project.bulk_export_status() == 'busy':
         log.info('Another export is running for project %s. Skipping.' % project_shortname)
         return
+    not_exported_tools = []
     for tool in tools or []:
         app = project.app_instance(tool)
         if not app:
             log.info('Can not load app for %s mount point. Skipping.' % tool)
+            not_exported_tools.append(tool)
             continue
         if not app.exportable:
             log.info('Tool %s is not exportable. Skipping.' % tool)
+            not_exported_tools.append(tool)
             continue
         log.info('Exporting %s...' % tool)
         try:
@@ -56,6 +59,7 @@ def bulk_export(project_shortname, tools, username):
                 app.bulk_export(f)
         except:
             log.error('Something went wrong during export of %s' % tool, exc_info=True)
+            not_exported_tools.append(tool)
             continue
 
     try:
@@ -73,7 +77,8 @@ def bulk_export(project_shortname, tools, username):
     tmpl_context = {
         'instructions': instructions,
         'project': project,
-        'tools': tools,
+        'tools': list(set(tools) - set(not_exported_tools)),
+        'not_exported_tools': not_exported_tools,
     }
     email = {
         'fromaddr': unicode(user.email_address_header()),

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/e4f7cf54/Allura/allura/templates/mail/bulk_export.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/mail/bulk_export.html b/Allura/allura/templates/mail/bulk_export.html
index 420848f..95ade78 100644
--- a/Allura/allura/templates/mail/bulk_export.html
+++ b/Allura/allura/templates/mail/bulk_export.html
@@ -24,6 +24,13 @@ Following tools was exported:
 - {{ tool }}
 {% endfor %}
 
+{% if not_exported_tools %}
+Following tools was not exported:
+{% for tool in not_exported_tools %}
+- {{ tool }}
+{% endfor %}
+{% endif %}
+
 Follow instructions below to get exported data.
 
 {{ instructions }}


[09/50] git commit: [#3154] ticket:386 Zip exported data

Posted by br...@apache.org.
[#3154] ticket:386 Zip exported data


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

Branch: refs/heads/db/3154b
Commit: 18c644981366f2e38e0bbcd75b69b3eeb77ca166
Parents: 1024e06
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 4 14:55:35 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:54 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/project.py      |  3 +++
 Allura/allura/tasks/export_tasks.py | 28 ++++++++++++++++++++++------
 Allura/allura/tests/test_tasks.py   | 24 ++++++++++++++++++++++++
 Allura/test.ini                     |  2 ++
 4 files changed, 51 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/18c64498/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 82c9a97..aaf5828 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -825,6 +825,9 @@ class Project(MappedClass, ActivityNode, ActivityObject):
                 nbhd=self.neighborhood.url_prefix.strip('/'),
                 project=self.shortname)
 
+    def bulk_export_filename(self):
+        return '%s.zip' % self.shortname
+
 
 class AppConfig(MappedClass):
     """

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/18c64498/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index 4c1f95a..f2f5371 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -17,9 +17,11 @@
 
 import os
 import logging
+import shutil
 
 from allura import model as M
 from allura.lib.decorators import task
+from allura.model.repository import zipdir
 
 
 log = logging.getLogger(__name__)
@@ -49,19 +51,33 @@ def bulk_export(project_shortname, tools):
             continue
 
     try:
-        cleanup()
+        zip_and_cleanup(project)
     except:
-        log.error('Error on cleanup.', exc_info=True)
+        log.error('Something went wrong during zipping exported data.', exc_info=True)
 
 
 def create_export_dir(project):
     """Create temporary directory for export files"""
-    path = os.path.join(project.bulk_export_path(), 'tmp')
+    zip_fn = project.bulk_export_filename()
+    # Name temporary directory after project shortname,
+    # thus zipdir() will use proper prefix inside the archive.
+    tmp_dir_suffix = zip_fn.split('.')[0]
+    path = os.path.join(project.bulk_export_path(), tmp_dir_suffix)
     if not os.path.exists(path):
         os.makedirs(path)
     return path
 
 
-def cleanup():
-    """Copy zip with export data to proper location. Remove temporary files."""
-    pass
+def zip_and_cleanup(project):
+    """Zip exported data. Copy it to proper location. Remove temporary files."""
+    path = project.bulk_export_path()
+    zip_fn = project.bulk_export_filename()
+    temp = os.path.join(path, zip_fn.split('.')[0])
+    zip_path_temp = os.path.join(temp, zip_fn)
+    zip_path = os.path.join(path, zip_fn)
+
+    zipdir(temp, zip_path_temp)
+
+    # cleanup
+    shutil.move(zip_path_temp, zip_path)
+    shutil.rmtree(temp)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/18c64498/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 74a5d18..d6f676e 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -17,12 +17,15 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+import os
 import operator
+import shutil
 import sys
 import unittest
 from base64 import b64encode
 import logging
 
+import tg
 import mock
 from pylons import tmpl_context as c, app_globals as g
 from datadiff.tools import assert_equal
@@ -30,6 +33,7 @@ from nose.tools import assert_in
 from ming.orm import FieldProperty, Mapper
 from ming.orm import ThreadLocalORMSession
 from testfixtures import LogCapture
+from IPython.testing.decorators import onlyif
 
 from alluratest.controller import setup_basic_test, setup_global_objects
 
@@ -363,5 +367,25 @@ class TestExportTasks(unittest.TestCase):
             mock.call('Exporting wiki...')])
         wiki_bulk_export.assert_called_once()
 
+    def test_create_export_dir(self):
+        project = M.Project.query.get(shortname='test')
+        export_path = project.bulk_export_path()
+        shutil.rmtree(export_path, ignore_errors=True)
+        path = export_tasks.create_export_dir(project)
+        assert_equal(path, '/tmp/bulk_export/p/test/test')
+        assert os.path.exists(os.path.join(export_path, project.shortname))
+        shutil.rmtree(export_path, ignore_errors=True)
+
+    @onlyif(os.path.exists(tg.config.get('scm.repos.tarball.zip_binary', '/usr/bin/zip')), 'zip binary is missing')
+    def test_zip_and_cleanup(self):
+        project = M.Project.query.get(shortname='test')
+        export_path = project.bulk_export_path()
+        shutil.rmtree(export_path, ignore_errors=True)
+        path = export_tasks.create_export_dir(project)
+        export_tasks.zip_and_cleanup(project)
+        assert not os.path.exists(path)
+        assert os.path.exists(os.path.join(export_path, 'test.zip'))
+        shutil.rmtree(export_path, ignore_errors=True)
+
 
 Mapper.compile_all()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/18c64498/Allura/test.ini
----------------------------------------------------------------------
diff --git a/Allura/test.ini b/Allura/test.ini
index 7394359..6babfaf 100644
--- a/Allura/test.ini
+++ b/Allura/test.ini
@@ -102,6 +102,8 @@ scm.repos.tarball.enable = true
 scm.repos.tarball.root = /tmp/tarball
 scm.repos.tarball.url_prefix = file://
 
+bulk_export_path = /tmp/bulk_export/{nbhd}/{project}
+
 support_tool_choices = wiki tickets discussion
 
 #stats.sample_rate = 0


[22/50] git commit: [#3154] ticket:389 Remove trailing spaces and commented code

Posted by br...@apache.org.
[#3154] ticket:389 Remove trailing spaces and commented code


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

Branch: refs/heads/db/3154b
Commit: dc81c672753321140271f99804a34929baebf7e2
Parents: 0a98936
Author: Igor Bondarenko <je...@gmail.com>
Authored: Wed Jul 24 11:01:10 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:56 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/project.py              | 2 --
 ForgeTracker/forgetracker/tests/test_app.py | 4 ++--
 ForgeTracker/forgetracker/tracker_main.py   | 2 +-
 3 files changed, 3 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dc81c672/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index b6d6a1f..02fddac 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -911,8 +911,6 @@ class AppConfig(MappedClass):
             tool_name=self.tool_name,
             version=self.version,
             options=self.options,
-            # project=self.project,
-            # discussion=self.discussion
             tool_data=self.tool_data,
             acl=self.acl,
         )

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dc81c672/ForgeTracker/forgetracker/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/test_app.py b/ForgeTracker/forgetracker/tests/test_app.py
index c84fa8d..0568829 100644
--- a/ForgeTracker/forgetracker/tests/test_app.py
+++ b/ForgeTracker/forgetracker/tests/test_app.py
@@ -48,11 +48,11 @@ class TestBulkExport(TrackerTestController):
         tickets = sorted(tracker['tickets'], key=operator.itemgetter('summary'))
         assert_equal(len(tickets), 2)
         ticket_foo = tickets[1]
-        assert_equal(ticket_foo['summary'], 'foo')                
+        assert_equal(ticket_foo['summary'], 'foo')
         assert_equal(ticket_foo['custom_fields']['_milestone'], '1.0')
         posts_foo = ticket_foo['discussion_thread']['posts']
         assert_equal(len(posts_foo), 1)
-        assert_equal(posts_foo[0]['text'], 'silly comment')         
+        assert_equal(posts_foo[0]['text'], 'silly comment')
 
         tracker_config = tracker['tracker_config']
         assert_equal(tracker_config['project_id'], unicode(self.project._id))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/dc81c672/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 15b0085..791b50f 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -424,7 +424,7 @@ class ForgeTrackerApp(Application):
         milestones = self.milestones
         json.dump(milestones, f, cls=jsonify.GenericJSON)
         f.write(', "saved_bins":')
-        bins = self.bins        
+        bins = self.bins
         json.dump(bins, f, cls=jsonify.GenericJSON)
         f.write('}')
 


[24/50] git commit: [#3154] only include options in config (exported by Tracker tool). ACL and other fields aren't useful on their own

Posted by br...@apache.org.
[#3154] only include options in config (exported by Tracker tool).  ACL and other fields aren't useful on their own


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

Branch: refs/heads/db/3154b
Commit: 691f997c80f8ef920c5eeebdbbfe3078615aec14
Parents: 43baa35
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Aug 1 19:24:14 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:57 2013 +0000

----------------------------------------------------------------------
 Allura/allura/model/project.py              | 6 ------
 ForgeTracker/forgetracker/tests/test_app.py | 2 --
 2 files changed, 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/691f997c/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 2258c18..1b21d37 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -961,11 +961,5 @@ class AppConfig(MappedClass):
     def __json__(self):
         return dict(
             _id=self._id,
-            project_id=self.project_id,
-            discussion_id=self.discussion_id,
-            tool_name=self.tool_name,
-            version=self.version,
             options=self.options,
-            tool_data=self.tool_data,
-            acl=self.acl,
         )

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/691f997c/ForgeTracker/forgetracker/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/test_app.py b/ForgeTracker/forgetracker/tests/test_app.py
index 0568829..b92a72f 100644
--- a/ForgeTracker/forgetracker/tests/test_app.py
+++ b/ForgeTracker/forgetracker/tests/test_app.py
@@ -55,9 +55,7 @@ class TestBulkExport(TrackerTestController):
         assert_equal(posts_foo[0]['text'], 'silly comment')
 
         tracker_config = tracker['tracker_config']
-        assert_equal(tracker_config['project_id'], unicode(self.project._id))
         assert_true('options' in tracker_config.keys())
-        assert_true('acl' in tracker_config.keys())
         assert_equal(tracker_config['options']['mount_point'], 'bugs')
 
         milestones = sorted(tracker['milestones'], key=operator.itemgetter('name'))


[05/50] git commit: [#3154] ticket:388 Export wiki

Posted by br...@apache.org.
[#3154] ticket:388 Export wiki


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

Branch: refs/heads/db/3154b
Commit: 5beb58e6c43eaa59ce150d09185888c2df27283f
Parents: 23bc5dd
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 5 13:45:13 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:54 2013 +0000

----------------------------------------------------------------------
 ForgeWiki/forgewiki/tests/test_app.py | 78 ++++++++++++++++++++++++++++++
 ForgeWiki/forgewiki/wiki_main.py      | 15 ++++--
 2 files changed, 90 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5beb58e6/ForgeWiki/forgewiki/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/test_app.py b/ForgeWiki/forgewiki/tests/test_app.py
new file mode 100644
index 0000000..b6db6a2
--- /dev/null
+++ b/ForgeWiki/forgewiki/tests/test_app.py
@@ -0,0 +1,78 @@
+#       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 datetime
+import tempfile
+import json
+import operator
+
+from nose.tools import assert_equal
+
+from allura import model as M
+from allura.tests import decorators as td
+from alluratest.controller import setup_basic_test, setup_global_objects
+from forgewiki import model as WM
+
+
+class TestBulkExport(object):
+
+    def setUp(self):
+        setup_basic_test()
+        setup_global_objects()
+        self.setup_with_tools()
+
+    @td.with_wiki
+    def setup_with_tools(self):
+        self.project = M.Project.query.get(shortname='test')
+        self.wiki = self.project.app_instance('wiki')
+        page = WM.Page.upsert('A New Hope')
+        page.text = 'Star Wars Episode IV: A New Hope'
+        page.mod_date = datetime.datetime(2013, 7, 5)
+        page.labels = ['star wars', 'movies']
+        page.commit()
+        page.discussion_thread.add_post(text='Embrace the Dark Side')
+        page.discussion_thread.add_post(text='Nope')
+        page = WM.Page.upsert('The Empire Strikes Back')
+        page.text = 'Star Wars Episode V: The Empire Strikes Back'
+        page.commit()
+        page = WM.Page.upsert('Return of the Jedi')
+        page.text = 'Star Wars Episode VI: Return of the Jedi'
+        page.commit()
+        page = WM.Page.query.get(app_config_id=self.wiki.config._id, title='Home')
+        page.deleted = True
+        page.commit()
+
+    def test_bulk_export(self):
+        f = tempfile.TemporaryFile()
+        self.wiki.bulk_export(f)
+        f.seek(0)
+        wiki = json.loads(f.read())
+        pages = sorted(wiki['pages'], key=operator.itemgetter('title'))
+        assert_equal(len(pages), 3)
+        assert_equal(pages[0]['title'], 'A New Hope')
+        assert_equal(pages[0]['text'], 'Star Wars Episode IV: A New Hope')
+        assert_equal(pages[0]['mod_date'], '2013-07-05 00:00:00')
+        assert_equal(pages[0]['labels'], ['star wars', 'movies'])
+        assert_equal(len(pages[0]['discussion_thread']['posts']), 2)
+
+        assert_equal(pages[1]['title'], 'Return of the Jedi')
+        assert_equal(pages[1]['text'], 'Star Wars Episode VI: Return of the Jedi')
+        assert_equal(len(pages[1]['discussion_thread']['posts']), 0)
+
+        assert_equal(pages[2]['title'], 'The Empire Strikes Back')
+        assert_equal(pages[2]['text'], 'Star Wars Episode V: The Empire Strikes Back')
+        assert_equal(len(pages[2]['discussion_thread']['posts']), 0)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/5beb58e6/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 30b4860..f27ff73 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -16,13 +16,14 @@
 #       under the License.
 
 #-*- python -*-
+import json
 import logging
 from pprint import pformat
 from urllib import unquote
 from datetime import datetime
 
 # Non-stdlib imports
-from tg import expose, validate, redirect, response, flash
+from tg import expose, validate, redirect, response, flash, jsonify
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from tg.controllers import RestController
 from pylons import tmpl_context as c, app_globals as g
@@ -287,8 +288,16 @@ The wiki uses [Markdown](%s) syntax.
         super(ForgeWikiApp, self).uninstall(project)
 
     def bulk_export(self, f):
-        # TODO: implement this
-        f.write('{}\n')
+        f.write('{"pages": [')
+        pages = WM.Page.query.find(dict(
+            app_config_id=self.config._id,
+            deleted=False)).all()
+        count = len(pages)
+        for i, page in enumerate(pages):
+            json.dump(page, f, cls=jsonify.GenericJSON)
+            if i < (count - 1):
+                f.write(',')
+        f.write(']}')
 
 
 class RootController(BaseController, DispatchIndex, FeedController):


[49/50] git commit: [#3154] remove unused Artifact.tool_version and make tracker models less dependent on `c`

Posted by br...@apache.org.
[#3154] remove unused Artifact.tool_version and make tracker models less dependent on `c`


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

Branch: refs/heads/db/3154b
Commit: 272bd5c36a1e6617f07c8c86913772b80079d5a5
Parents: a598db5
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Aug 21 15:21:02 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:26:27 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/project.py            |  7 +--
 Allura/allura/model/artifact.py                 |  6 +--
 Allura/allura/tests/test_globals.py             |  3 +-
 ForgeBlog/forgeblog/command/rssfeeds.py         |  1 -
 ForgeTracker/forgetracker/model/ticket.py       | 54 ++++++++++----------
 ForgeTracker/forgetracker/tests/test_app.py     |  6 ++-
 .../tests/unit/test_globals_model.py            | 22 ++++----
 scripts/project-import.py                       |  2 +-
 8 files changed, 50 insertions(+), 51 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/272bd5c3/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index d2b8510..5f293a6 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -778,9 +778,8 @@ class NeighborhoodAwardsController(object):
     def create(self, icon=None, short=None, full=None):
         require_access(self.neighborhood, 'admin')
         app_config_id = ObjectId()
-        tool_version = {'neighborhood': '0'}
         if short:
-            award = M.Award(app_config_id=app_config_id, tool_version=tool_version)
+            award = M.Award(app_config_id=app_config_id)
             award.short = short
             award.full = full
             award.created_by_neighborhood_id = self.neighborhood._id
@@ -802,9 +801,7 @@ class NeighborhoodAwardsController(object):
             deleted=False)).first()
         if grant_q and recipient_q:
             app_config_id = ObjectId()
-            tool_version = {'neighborhood': '0'}
-            award = M.AwardGrant(app_config_id=app_config_id,
-                                 tool_version=tool_version)
+            award = M.AwardGrant(app_config_id=app_config_id)
             award.award_id = grant_q._id
             award.granted_to_project_id = recipient_q._id
             award.granted_by_neighborhood_id = self.neighborhood._id

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/272bd5c3/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index b41b103..294c3d0 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -54,7 +54,6 @@ class Artifact(MappedClass):
     - Has a discussion thread that can have files attached to it
 
     :var mod_date: last-modified :class:`datetime`
-    :var tool_version: defaults to the parent Application's version
     :var acl: dict of permission name => [roles]
     :var labels: list of plain old strings
 
@@ -77,9 +76,7 @@ class Artifact(MappedClass):
     mod_date = FieldProperty(datetime, if_missing=datetime.utcnow)
     app_config_id = ForeignIdProperty('AppConfig', if_missing=lambda:c.app.config._id)
     plugin_verson = FieldProperty(S.Deprecated)
-    tool_version = FieldProperty(
-        { str: str },
-        if_missing=lambda:{c.app.config.tool_name:c.app.__version__})
+    tool_version = FieldProperty(S.Deprecated)
     acl = FieldProperty(ACL)
     tags = FieldProperty(S.Deprecated)
     labels = FieldProperty([str])
@@ -368,6 +365,7 @@ class Artifact(MappedClass):
         if t is None:
             idx = self.index()
             t = Thread.new(
+                app_config_id=self.app_config_id,
                 discussion_id=self.app_config.discussion_id,
                 ref_id=idx['id'],
                 subject='%s discussion' % h.get_first(idx, 'title'))

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/272bd5c3/Allura/allura/tests/test_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_globals.py b/Allura/allura/tests/test_globals.py
index 526af04..437021b 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -504,8 +504,7 @@ def test_hideawards_macro():
     p_nbhd = M.Neighborhood.query.get(name='Projects')
 
     app_config_id = ObjectId()
-    tool_version = {'neighborhood': '0'}
-    award = M.Award(app_config_id=app_config_id, tool_version=tool_version)
+    award = M.Award(app_config_id=app_config_id)
     award.short = u'Award short'
     award.full = u'Award full'
     award.created_by_neighborhood_id = p_nbhd._id

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/272bd5c3/ForgeBlog/forgeblog/command/rssfeeds.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/command/rssfeeds.py b/ForgeBlog/forgeblog/command/rssfeeds.py
index 305bc5a..aefacdb 100644
--- a/ForgeBlog/forgeblog/command/rssfeeds.py
+++ b/ForgeBlog/forgeblog/command/rssfeeds.py
@@ -169,7 +169,6 @@ class RssFeedsCommand(base.BlogCommand):
         if b_count == 0:
             post = BM.BlogPost(title=title, text=content, timestamp=updated,
                             app_config_id=appid,
-                            tool_version={'blog': version.__version__},
                             state='published')
             post.neighborhood_id=c.project.neighborhood_id
             post.make_slug()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/272bd5c3/ForgeTracker/forgetracker/model/ticket.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index 0536f71..d16039e 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -73,7 +73,8 @@ class Globals(MappedClass):
 
     type_s = 'Globals'
     _id = FieldProperty(schema.ObjectId)
-    app_config_id = ForeignIdProperty('AppConfig', if_missing=lambda:c.app.config._id)
+    app_config_id = ForeignIdProperty(AppConfig, if_missing=lambda:c.app.config._id)
+    app_config = RelationProperty(AppConfig, via='app_config_id')
     last_ticket_num = FieldProperty(int)
     status_names = FieldProperty(str)
     open_status_names = FieldProperty(str)
@@ -97,13 +98,12 @@ class Globals(MappedClass):
                                                             'labels': False,
                                                             })
 
-    @classmethod
-    def next_ticket_num(cls):
-        gbl = cls.query.find_and_modify(
-            query=dict(app_config_id=c.app.config._id),
+    def next_ticket_num(self):
+        gbl = Globals.query.find_and_modify(
+            query=dict(app_config_id=self.app_config_id),
             update={'$inc': { 'last_ticket_num': 1}},
             new=True)
-        session(cls).expunge(gbl)
+        session(gbl).expunge(gbl)
         return gbl.last_ticket_num
 
     @property
@@ -189,11 +189,11 @@ class Globals(MappedClass):
             return d
         mongo_query = {'custom_fields.%s' % fld_name: m_name}
         r = Ticket.query.find(dict(
-            mongo_query, app_config_id=c.app.config._id, deleted=False))
+            mongo_query, app_config_id=self.app_config_id, deleted=False))
         tickets = [t for t in r if security.has_access(t, 'read')]
         d['hits'] = len(tickets)
         d['closed'] = sum(1 for t in tickets
-                          if t.status in c.app.globals.set_of_closed_status_names)
+                          if t.status in self.set_of_closed_status_names)
         return d
 
     def invalidate_bin_counts(self):
@@ -229,13 +229,13 @@ class Globals(MappedClass):
 
     def has_deleted_tickets(self):
         return Ticket.query.find(dict(
-            app_config_id=c.app.config._id, deleted=True)).count() > 0
+            app_config_id=self.app_config_id, deleted=True)).count() > 0
 
     def move_tickets(self, ticket_ids, destination_tracker_id):
         tracker = AppConfig.query.get(_id=destination_tracker_id)
         tickets = Ticket.query.find(dict(
             _id={'$in': [ObjectId(id) for id in ticket_ids]},
-            app_config_id=c.app.config._id)).sort('ticket_num').all()
+            app_config_id=self.app_config_id)).sort('ticket_num').all()
         filtered = self.filtered_by_subscription({t._id: t for t in tickets})
         original_ticket_nums = {t._id: t.ticket_num for t in tickets}
         users = User.query.find({'_id': {'$in': filtered.keys()}}).all()
@@ -247,13 +247,13 @@ class Globals(MappedClass):
             fromaddr = str(c.user.email_address_header()),
             reply_to = str(c.user.email_address_header()),
             subject = '[%s:%s] Mass ticket moving by %s' % (c.project.shortname,
-                                                          c.app.config.options.mount_point,
+                                                          self.app_config.options.mount_point,
                                                           c.user.display_name))
         tmpl = g.jinja2_env.get_template('forgetracker:data/mass_move_report.html')
 
         tmpl_context = {
             'original_tracker': '%s:%s' % (c.project.shortname,
-                                           c.app.config.options.mount_point),
+                                           self.app_config.options.mount_point),
             'destination_tracker': '%s:%s' % (tracker.project.shortname,
                                               tracker.options.mount_point),
             'tickets': [],
@@ -270,16 +270,16 @@ class Globals(MappedClass):
                 destinations = [str(user._id)]))
             mail_tasks.sendmail.post(**mail)
 
-        if c.app.config.options.get('TicketMonitoringType') in (
+        if self.app_config.options.get('TicketMonitoringType') in (
                 'AllTicketChanges', 'AllPublicTicketChanges'):
-            monitoring_email = c.app.config.options.get('TicketMonitoringEmail')
+            monitoring_email = self.app_config.options.get('TicketMonitoringEmail')
             tmpl_context['tickets'] = [{
                     'original_num': original_ticket_nums[_id],
                     'destination_num': moved_tickets[_id].ticket_num,
                     'summary': moved_tickets[_id].summary
                 } for _id, t in moved_tickets.iteritems()
                   if (not t.private or
-                      c.app.config.options.get('TicketMonitoringType') ==
+                      self.app_config.options.get('TicketMonitoringType') ==
                       'AllTicketChanges')]
             if len(tmpl_context['tickets']) > 0:
                 mail.update(dict(
@@ -288,7 +288,7 @@ class Globals(MappedClass):
                     destinations = [monitoring_email]))
                 mail_tasks.sendmail.post(**mail)
 
-        moved_from = '%s/%s' % (c.project.shortname, c.app.config.options.mount_point)
+        moved_from = '%s/%s' % (c.project.shortname, self.app_config.options.mount_point)
         moved_to = '%s/%s' % (tracker.project.shortname, tracker.options.mount_point)
         text = 'Tickets moved from %s to %s' % (moved_from, moved_to)
         Notification.post_user(c.user, None, 'flash', text=text)
@@ -297,7 +297,7 @@ class Globals(MappedClass):
         from forgetracker.tracker_main import get_change_text, get_label
         tickets = Ticket.query.find(dict(
                 _id={'$in':[ObjectId(id) for id in aslist(post_data['__ticket_ids'])]},
-                app_config_id=c.app.config._id)).all()
+                app_config_id=self.app_config_id)).all()
 
         fields = set(['status'])
         values = {}
@@ -314,7 +314,7 @@ class Globals(MappedClass):
 
         custom_values = {}
         custom_fields = {}
-        for cf in c.app.globals.custom_fields or []:
+        for cf in self.custom_fields or []:
             v = post_data.get(cf.name)
             if v:
                 custom_values[cf.name] = v
@@ -369,7 +369,7 @@ class Globals(MappedClass):
             fromaddr = str(c.user._id),
             reply_to = str(c.user._id),
             subject = '[%s:%s] Mass edit changes by %s' % (c.project.shortname,
-                                                           c.app.config.options.mount_point,
+                                                           self.app_config.options.mount_point,
                                                            c.user.display_name),
         )
         tmpl = g.jinja2_env.get_template('forgetracker:data/mass_report.html')
@@ -394,13 +394,13 @@ class Globals(MappedClass):
                 destinations = [str(user._id)]))
             mail_tasks.sendmail.post(**mail)
 
-        if c.app.config.options.get('TicketMonitoringType') in (
+        if self.app_config.options.get('TicketMonitoringType') in (
                 'AllTicketChanges', 'AllPublicTicketChanges'):
-            monitoring_email = c.app.config.options.get('TicketMonitoringEmail')
+            monitoring_email = self.app_config.options.get('TicketMonitoringEmail')
             visible_changes = []
             for t_id, t in changed_tickets.items():
                 if (not t.private or
-                        c.app.config.options.get('TicketMonitoringType') ==
+                        self.app_config.options.get('TicketMonitoringType') ==
                         'AllTicketChanges'):
                     visible_changes.append(
                             (changed_tickets[t_id], jinja2.Markup(changes[t_id])))
@@ -412,16 +412,16 @@ class Globals(MappedClass):
                     destinations = [monitoring_email]))
                 mail_tasks.sendmail.post(**mail)
 
-        c.app.globals.invalidate_bin_counts()
+        self.invalidate_bin_counts()
         ThreadLocalORMSession.flush_all()
-        app = '%s/%s' % (c.project.shortname, c.app.config.options.mount_point)
+        app = '%s/%s' % (c.project.shortname, self.app_config.options.mount_point)
         count = len(tickets)
         text = 'Updated {} ticket{} in {}'.format(count, 's' if count != 1 else '', app)
         Notification.post_user(c.user, None, 'flash', text=text)
 
     def filtered_by_subscription(self, tickets, project_id=None, app_config_id=None):
         p_id = project_id if project_id else c.project._id
-        ac_id = app_config_id if app_config_id else c.app.config._id
+        ac_id = app_config_id if app_config_id else self.app_config_id
         ticket_ids = tickets.keys()
         tickets_index_id = {ticket.index_id(): t_id for t_id, ticket in tickets.iteritems()}
         subscriptions = Mailbox.query.find({
@@ -678,11 +678,11 @@ class Ticket(VersionedArtifact, ActivityObject, VotableArtifact):
 
     @property
     def monitoring_email(self):
-        return c.app.config.options.get('TicketMonitoringEmail')
+        return self.app_config.options.get('TicketMonitoringEmail')
 
     @property
     def notify_post(self):
-        monitoring_type = c.app.config.options.get('TicketMonitoringType')
+        monitoring_type = self.app_config.options.get('TicketMonitoringType')
         return monitoring_type == 'AllTicketChanges' or (
                 monitoring_type == 'AllPublicTicketChanges' and
                 not self.private)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/272bd5c3/ForgeTracker/forgetracker/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/test_app.py b/ForgeTracker/forgetracker/tests/test_app.py
index b92a72f..e6e74b8 100644
--- a/ForgeTracker/forgetracker/tests/test_app.py
+++ b/ForgeTracker/forgetracker/tests/test_app.py
@@ -15,12 +15,12 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-import datetime
 import tempfile
 import json
 import operator
 
 from nose.tools import assert_equal, assert_true
+from pylons import tmpl_context as c
 
 from allura import model as M
 from allura.tests import decorators as td
@@ -40,6 +40,10 @@ class TestBulkExport(TrackerTestController):
         ticket.discussion_thread.add_post(text='silly comment')
 
     def test_bulk_export(self):
+        # Clear out some context vars, to properly simulate how this is run from the export task
+        # Besides, core functionality shouldn't need the c context vars
+        c.app = c.project = None
+
         f = tempfile.TemporaryFile()
         self.tracker.bulk_export(f)
         f.seek(0)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/272bd5c3/ForgeTracker/forgetracker/tests/unit/test_globals_model.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/unit/test_globals_model.py b/ForgeTracker/forgetracker/tests/unit/test_globals_model.py
index 357caec..c3c0c30 100644
--- a/ForgeTracker/forgetracker/tests/unit/test_globals_model.py
+++ b/ForgeTracker/forgetracker/tests/unit/test_globals_model.py
@@ -15,18 +15,19 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+from datetime import datetime, timedelta
+
 import mock
 from nose.tools import assert_equal
-from datetime import datetime, timedelta
+from pylons import tmpl_context as c
+from ming.orm.ormsession import ThreadLocalORMSession
+from bson import ObjectId
 
 import forgetracker
 from forgetracker.model import Globals
 from forgetracker.tests.unit import TrackerTestWithModel
-from pylons import tmpl_context as c
 from allura.lib import helpers as h
 
-from ming.orm.ormsession import ThreadLocalORMSession
-
 
 class TestGlobalsModel(TrackerTestWithModel):
     def setUp(self):
@@ -41,13 +42,15 @@ class TestGlobalsModel(TrackerTestWithModel):
         assert c.app.globals != bugs_globals
 
     def test_next_ticket_number_increments(self):
-        assert Globals.next_ticket_num() == 1
-        assert Globals.next_ticket_num() == 2
+        gl = Globals()
+        assert_equal(gl.next_ticket_num(), 1)
+        assert_equal(gl.next_ticket_num(), 2)
 
     def test_ticket_numbers_are_independent(self):
-        assert Globals.next_ticket_num() == 1
-        h.set_context('test', 'doc-bugs', neighborhood='Projects')
-        assert Globals.next_ticket_num() == 1
+        with h.push_context('test', 'doc-bugs', neighborhood='Projects'):
+            assert_equal(c.app.globals.next_ticket_num(), 1)
+        with h.push_context('test', 'bugs', neighborhood='Projects'):
+            assert_equal(c.app.globals.next_ticket_num(), 1)
 
     @mock.patch('forgetracker.model.ticket.datetime')
     def test_bin_count(self, mock_dt):
@@ -133,4 +136,3 @@ def globals_with_custom_fields(custom_fields):
     c.app.globals.custom_fields = custom_fields
     ThreadLocalORMSession.flush_all()
     return c.app.globals
-

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/272bd5c3/scripts/project-import.py
----------------------------------------------------------------------
diff --git a/scripts/project-import.py b/scripts/project-import.py
index 5855da6..f4ba62f 100644
--- a/scripts/project-import.py
+++ b/scripts/project-import.py
@@ -240,7 +240,7 @@ def create_project(p, nbhd, user, options):
 
     for a in p.awards:
         M.AwardGrant(app_config_id=bson.ObjectId(),
-                tool_version=dict(neighborhood='0'), award_id=a._id,
+                award_id=a._id,
                 granted_to_project_id=project._id,
                 granted_by_neighborhood_id=nbhd._id)
     project.notifications_disabled = False


[30/50] git commit: [#3154] tweak bulk export email text & formatting

Posted by br...@apache.org.
[#3154] tweak bulk export email text & formatting


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

Branch: refs/heads/db/3154b
Commit: 43baa356bc1f36d26238c2223d0630dd1bd67728
Parents: 7375644
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Thu Aug 1 15:37:24 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:57 2013 +0000

----------------------------------------------------------------------
 Allura/allura/templates/mail/bulk_export.html | 14 ++++++++------
 Allura/allura/tests/test_tasks.py             |  4 ++--
 2 files changed, 10 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/43baa356/Allura/allura/templates/mail/bulk_export.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/mail/bulk_export.html b/Allura/allura/templates/mail/bulk_export.html
index 95ade78..e8aded1 100644
--- a/Allura/allura/templates/mail/bulk_export.html
+++ b/Allura/allura/templates/mail/bulk_export.html
@@ -17,20 +17,22 @@
        under the License.
 #}
 
-Bulk export for project {{ project.shortname }} is completed.
+The bulk export for project {{ project.shortname }} is completed.
 
-Following tools was exported:
-{% for tool in tools %}
+{% if tools %}
+The following tools were exported:
+{% for tool in tools -%}
 - {{ tool }}
 {% endfor %}
+{% endif %}
 
 {% if not_exported_tools %}
-Following tools was not exported:
-{% for tool in not_exported_tools %}
+The following tools were not exported:
+{% for tool in not_exported_tools -%}
 - {{ tool }}
 {% endfor %}
 {% endif %}
 
-Follow instructions below to get exported data.
+Follow the instructions below to get your exported data.
 
 {{ instructions }}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/43baa356/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index cd10683..c772253 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -392,8 +392,8 @@ class TestExportTasks(unittest.TestCase):
         assert_equal(len(tasks), 1)
         assert_equal(tasks[0].kwargs['subject'], 'Bulk export for project test completed')
         text = tasks[0].kwargs['text']
-        assert_in('Bulk export for project test is completed.', text)
-        assert_in('Following tools was exported:\n\n- wiki', text)
+        assert_in('The bulk export for project test is completed.', text)
+        assert_in('The following tools were exported:\n- wiki', text)
         assert_in('Sample instructions for test', text)
 
     @mock.patch('forgewiki.wiki_main.ForgeWikiApp.bulk_export')


[17/50] git commit: [#3154] ticket:394 Fix test

Posted by br...@apache.org.
[#3154] ticket:394 Fix test


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

Branch: refs/heads/db/3154b
Commit: 3e41cb88d282eb517d2a98f7350092985d3a5551
Parents: e2b56bb
Author: Igor Bondarenko <je...@gmail.com>
Authored: Tue Jul 23 14:19:03 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:55 2013 +0000

----------------------------------------------------------------------
 ForgeLink/forgelink/tests/test_app.py | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/3e41cb88/ForgeLink/forgelink/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeLink/forgelink/tests/test_app.py b/ForgeLink/forgelink/tests/test_app.py
index 2176b10..3290aa2 100644
--- a/ForgeLink/forgelink/tests/test_app.py
+++ b/ForgeLink/forgelink/tests/test_app.py
@@ -18,8 +18,11 @@
 import tempfile
 import json
 
+from nose.tools import assert_equal
+
 from allura.tests import decorators as td
 from allura import model as M
+from allura.lib import helpers as h
 from alluratest.controller import setup_basic_test
 
 
@@ -32,8 +35,9 @@ class TestBulkExport(object):
     def test_bulk_export(self):
         self.project = M.Project.query.get(shortname='test')
         self.link = self.project.app_instance('link')
+        h.set_context(self.project._id, app_config_id=self.link.config._id)
         self.link.config.options['url'] = 'http://sf.net'
         f = tempfile.TemporaryFile()
         self.link.bulk_export(f)
         f.seek(0)
-        assert json.loads(f.read())['url']=='http://sf.net'
\ No newline at end of file
+        assert_equal(json.loads(f.read())['url'], 'http://sf.net')


[18/50] git commit: [#3154] ticket:393 Fix test after merge

Posted by br...@apache.org.
[#3154] ticket:393 Fix test after merge


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

Branch: refs/heads/db/3154b
Commit: cc71ea535909695b6f2b5c8b06500c6e00d880a9
Parents: 983c9ba
Author: Igor Bondarenko <je...@gmail.com>
Authored: Wed Jul 24 13:32:26 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:56 2013 +0000

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


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/cc71ea53/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 60a1abc..06d4ede 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -363,7 +363,7 @@ class TestExportTasks(unittest.TestCase):
         export_tasks.bulk_export('test', [u'bugs', u'blog'], 'test-admin')
         assert_equal(log.info.call_count, 2)
         assert_equal(log.info.call_args_list, [
-            mock.call('Tool urls is not exportable. Skipping.'),
+            mock.call('Tool bugs is not exportable. Skipping.'),
             mock.call('Tool blog is not exportable. Skipping.')])
 
     @mock.patch('allura.tasks.export_tasks.shutil')


[34/50] git commit: [#3154] ticket:411 removed try near zip_and_cleanup

Posted by br...@apache.org.
[#3154] ticket:411 removed try near zip_and_cleanup


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

Branch: refs/heads/db/3154b
Commit: ae2d4e87db4cab4445cd2103e3b36188d76206e5
Parents: 315f269
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Tue Aug 13 15:51:39 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:58 2013 +0000

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


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/ae2d4e87/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index 0eb99e0..3e2a9af 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -72,10 +72,9 @@ def bulk_export(project_shortname, tools, username, neighborhood):
     except:
         log.error('Something went wrong during export of project metadata', exc_info=True)
 
-    try:
-        zip_and_cleanup(project)
-    except:
-        log.error('Something went wrong during zipping exported data.', exc_info=True)
+    # If that fails, we need to let it fail
+    # there won't be a valid zip file for the user to get.
+    zip_and_cleanup(project)
 
     user = M.User.by_username(username)
     if not user:


[10/50] git commit: [#3153] ticket:389 added milestones to tracker bulk_export

Posted by br...@apache.org.
[#3153] ticket:389 added milestones to tracker bulk_export


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

Branch: refs/heads/db/3154b
Commit: a7fe2403301979f53cf565d43d71c2b6865164a4
Parents: 9216776
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Tue Jul 23 20:09:29 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:55 2013 +0000

----------------------------------------------------------------------
 ForgeTracker/forgetracker/tests/test_app.py |  6 ++++-
 ForgeTracker/forgetracker/tracker_main.py   | 31 +++++++++++++++---------
 2 files changed, 24 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a7fe2403/ForgeTracker/forgetracker/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/test_app.py b/ForgeTracker/forgetracker/tests/test_app.py
index 7437e4d..a718885 100644
--- a/ForgeTracker/forgetracker/tests/test_app.py
+++ b/ForgeTracker/forgetracker/tests/test_app.py
@@ -35,7 +35,7 @@ class TestBulkExport(TrackerTestController):
         self.project = M.Project.query.get(shortname='test')
         self.tracker = self.project.app_instance('bugs')
         self.new_ticket(summary='foo', _milestone='1.0')
-        self.new_ticket(summary='bar', _milestone='1.0')
+        self.new_ticket(summary='bar', _milestone='2.0')
         ticket = TM.Ticket.query.find(dict(summary='foo')).first()
         ticket.discussion_thread.add_post(text='silly comment')
 
@@ -59,3 +59,7 @@ class TestBulkExport(TrackerTestController):
         assert_true('options' in tracker_config.keys())
         assert_true('acl' in tracker_config.keys())
         assert_equal(tracker_config['options']['mount_point'], 'bugs')
+
+        milestones = sorted(tracker['milestones'], key=operator.itemgetter('name'))
+        assert_equal(milestones[0]['name'], '1.0')
+        assert_equal(milestones[1]['name'], '2.0')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a7fe2403/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 8b34b35..02daa5b 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -420,12 +420,30 @@ class ForgeTrackerApp(Application):
                 f.write(',')
         f.write('], "tracker_config":')
         json.dump(self.config, f, cls=jsonify.GenericJSON)
+        f.write(', "milestones":')
+        milestones = self.milestones
+        json.dump(milestones, f, cls=jsonify.GenericJSON)
         f.write('}')
 
     @property
     def bins(self):
         return TM.Bin.query.find(dict(app_config_id=self.config._id)).sort('summary').all()
 
+    @property
+    def milestones(self):
+        milestones = []
+        for fld in self.globals.milestone_fields:
+            if fld.name == '_milestone':
+                for m in fld.milestones:
+                    d =  self.globals.milestone_count('%s:%s' % (fld.name, m.name))
+                    milestones.append(dict(
+                        name=m.name,
+                        due_date=m.get('due_date'),
+                        description=m.get('description'),
+                        complete=m.get('complete'),
+                        total=d['hits'],
+                        closed=d['closed']))
+        return milestones
 
 
 ### Controllers ###
@@ -614,19 +632,8 @@ class RootController(BaseController, FeedController):
     @expose('jinja:forgetracker:templates/tracker/milestones.html')
     def milestones(self, **kw):
         require_access(c.app, 'configure')
-        milestones = []
         c.date_field = W.date_field
-        for fld in c.app.globals.milestone_fields:
-            if fld.name == '_milestone':
-                for m in fld.milestones:
-                    d =  c.app.globals.milestone_count('%s:%s' % (fld.name, m.name))
-                    milestones.append(dict(
-                        name=m.name,
-                        due_date=m.get('due_date'),
-                        description=m.get('description'),
-                        complete=m.get('complete'),
-                        total=d['hits'],
-                        closed=d['closed']))
+        milestones = c.app.milestones
         return dict(milestones=milestones)
 
     @without_trailing_slash


[47/50] git commit: [#3154] revise commit 099b2c so project metadata is on AdminApp and less special handling is needed

Posted by br...@apache.org.
[#3154] revise commit 099b2c so project metadata is on AdminApp and less special handling is needed


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

Branch: refs/heads/db/3154b
Commit: 2dae15a32ed742f61b761e72d959f45d1a8e1e84
Parents: b45aa78
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Fri Aug 16 21:20:26 2013 +0000
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:26:10 2013 +0000

----------------------------------------------------------------------
 Allura/allura/ext/admin/admin_main.py         | 25 +++++++++++-----------
 Allura/allura/ext/admin/templates/export.html |  5 -----
 Allura/allura/model/project.py                |  6 +-----
 Allura/allura/tasks/export_tasks.py           | 24 +++++++++------------
 Allura/allura/tests/functional/test_admin.py  | 13 ++++-------
 5 files changed, 27 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2dae15a3/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 f763258..cbb1e2c 100644
--- a/Allura/allura/ext/admin/admin_main.py
+++ b/Allura/allura/ext/admin/admin_main.py
@@ -19,12 +19,13 @@ import logging
 from collections import defaultdict
 from datetime import datetime
 from urlparse import urlparse
+import json
 
 import pkg_resources
 from pylons import tmpl_context as c, app_globals as g
 from pylons import request
 from paste.deploy.converters import asbool
-from tg import expose, redirect, flash, validate, config
+from tg import expose, redirect, flash, validate, config, jsonify
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from webob import exc
 from bson import ObjectId
@@ -74,13 +75,13 @@ class AdminApp(Application):
     __version__ = version.__version__
     installable=False
     _installable_tools = None
-    _exportable_tools = None
     tool_label = 'admin'
     icons={
         24:'images/admin_24.png',
         32:'images/admin_32.png',
         48:'images/admin_48.png'
     }
+    exportable = True
 
     def __init__(self, project, config):
         Application.__init__(self, project, config)
@@ -105,15 +106,11 @@ class AdminApp(Application):
 
     @staticmethod
     def exportable_tools_for(project):
-        cls = AdminApp
-        tools = [project]
-        if cls._exportable_tools is None:
-            for tool in project.ordered_mounts(include_hidden=True):
-                if not tool.get('ac'):
-                    continue
-                if project.app_instance(tool['ac']).exportable:
-                    tools.append(tool['ac'])
-        return tools
+        tools = []
+        for tool in project.app_configs:
+            if project.app_instance(tool).exportable:
+                tools.append(tool)
+        return sorted(tools, key=lambda t: t.options.mount_point)
 
     def main_menu(self):
         '''Apps should provide their entries to be added to the main nav
@@ -168,6 +165,9 @@ class AdminApp(Application):
     def install(self, project):
         pass
 
+    def bulk_export(self, f):
+        json.dump(self.project, f, cls=jsonify.GenericJSON, indent=2)
+
 
 class AdminExtensionLookup(object):
 
@@ -645,8 +645,7 @@ class ProjectAdminController(BaseController):
                 redirect('export')
             if isinstance(tools, basestring):
                 tools = [tools]
-            allowed = set(t.options.mount_point for t in exportable_tools if hasattr(t, 'options'))
-            allowed.add('project')
+            allowed = set(t.options.mount_point for t in exportable_tools)
             if not set(tools).issubset(allowed):
                 flash('Wrong tools in input data', 'error')
                 redirect('export')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2dae15a3/Allura/allura/ext/admin/templates/export.html
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/templates/export.html b/Allura/allura/ext/admin/templates/export.html
index 6287be7..eff9d5a 100644
--- a/Allura/allura/ext/admin/templates/export.html
+++ b/Allura/allura/ext/admin/templates/export.html
@@ -38,13 +38,8 @@
     <form method="POST" action="">
       {% for tool in tools %}
       <div class="grid-19">
-        {% if tool.name %}
-          <input type="checkbox" name="tools" id="tool-{{ loop.index }}" value="project">
-          <label for="tool-{{ loop.index }}">{{ tool.name }}</label> <a href="{{ tool.url() }}">{{ tool.url() }}</a>
-        {% else %}
         <input type="checkbox" name="tools" id="tool-{{ loop.index }}" value="{{ tool.options.mount_point }}">
         <label for="tool-{{ loop.index }}">{{ tool.options.mount_label }}</label> <a href="{{ tool.url() }}">{{ tool.url() }}</a>
-        {% endif %}
       </div>
       {% endfor %}
       <p><div class="grid-19"><input type="submit" value="Export"></div></p>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2dae15a3/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 021bb47..95ad80f 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -17,13 +17,12 @@
 
 import os
 import logging
-import json
 from collections import Counter, OrderedDict
 from datetime import datetime
 from copy import deepcopy
 import urllib
 
-from tg import config, jsonify
+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
@@ -877,9 +876,6 @@ class Project(MappedClass, ActivityNode, ActivityObject):
         elif os.path.exists(tmpdir):
             return 'busy'
 
-    def bulk_export(self, f):
-        json.dump(self, f, cls=jsonify.GenericJSON, indent=2)
-
     def __json__(self):
         return dict(
             shortname=self.shortname,

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2dae15a3/Allura/allura/tasks/export_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tasks/export_tasks.py b/Allura/allura/tasks/export_tasks.py
index 4b30c36..b6a84ac 100644
--- a/Allura/allura/tasks/export_tasks.py
+++ b/Allura/allura/tasks/export_tasks.py
@@ -46,26 +46,22 @@ def bulk_export(project_shortname, tools, username, neighborhood):
         return
     not_exported_tools = []
     for tool in tools or []:
-        entry_to_export = None
-        if tool == 'project':
-            entry_to_export = project
-        else:
-            entry_to_export = project.app_instance(tool)
-            if not entry_to_export:
-                log.info('Can not load app for %s mount point. Skipping.' % tool)
-                not_exported_tools.append(tool)
-                continue
-            if not entry_to_export.exportable:
-                log.info('Tool %s is not exportable. Skipping.' % tool)
-                not_exported_tools.append(tool)
-                continue
+        app = project.app_instance(tool)
+        if not app:
+            log.info('Can not load app for %s mount point. Skipping.' % tool)
+            not_exported_tools.append(tool)
+            continue
+        if not app.exportable:
+            log.info('Tool %s is not exportable. Skipping.' % tool)
+            not_exported_tools.append(tool)
+            continue
         log.info('Exporting %s...' % tool)
         try:
             path = create_export_dir(project)
             temp_name = mkstemp(dir=path)[1]
             with open(temp_name, 'w') as f:
                 with h.push_context(project._id):
-                    entry_to_export.bulk_export(f)
+                    app.bulk_export(f)
             os.rename(temp_name, os.path.join(path, '%s.json' % tool))
         except:
             log.error('Something went wrong during export of %s' % tool, exc_info=True)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/2dae15a3/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 4988a8c..669f113 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -784,11 +784,8 @@ class TestExport(TestController):
     def test_exportable_tools_for(self):
         project = M.Project.query.get(shortname='test')
         exportable_tools = AdminApp.exportable_tools_for(project)
-        tools = [t.options.mount_point
-                 for t in AdminApp.exportable_tools_for(project)
-                 if hasattr(t, 'options')]
-        assert_equals(tools, [u'wiki', u'wiki2'])
-        assert_in(project, exportable_tools)
+        exportable_mount_points = [t.options.mount_point for t in exportable_tools]
+        assert_equals(exportable_mount_points, [u'admin', u'wiki', u'wiki2'])
 
     def test_access(self):
         r = self.app.get('/admin/export',
@@ -824,10 +821,8 @@ class TestExport(TestController):
         with mock.patch('allura.ext.search.search_main.SearchApp.exportable'):
             project = M.Project.query.get(shortname='test')
             exportable_tools = AdminApp.exportable_tools_for(project)
-            tools = [t.options.mount_point for t in exportable_tools
-                                           if hasattr(t, 'options')]
-            assert_equals(tools, [u'search', u'wiki', u'wiki2'])
-            assert_in(project, exportable_tools)
+            exportable_mount_points = [t.options.mount_point for t in exportable_tools]
+            assert_equals(exportable_mount_points, [u'admin', u'search', u'wiki', u'wiki2'])
 
     def test_tools_not_selected(self):
         r = self.app.post('/admin/export')


[19/50] git commit: [#3154] ticket:393 Bulk export: ForgeBlog

Posted by br...@apache.org.
[#3154]  ticket:393 Bulk export: ForgeBlog


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

Branch: refs/heads/db/3154b
Commit: 983c9ba800b1d0792bc02c100c6cf33d5ab5b781
Parents: dc81c67
Author: Yuriy Arhipov <yu...@yandex.ru>
Authored: Tue Jul 23 19:36:06 2013 +0400
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:56 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/test_tasks.py     |  9 +++--
 ForgeBlog/forgeblog/main.py           | 16 +++++++-
 ForgeBlog/forgeblog/tests/test_app.py | 62 ++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/983c9ba8/Allura/allura/tests/test_tasks.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_tasks.py b/Allura/allura/tests/test_tasks.py
index 654ed37..60a1abc 100644
--- a/Allura/allura/tests/test_tasks.py
+++ b/Allura/allura/tests/test_tasks.py
@@ -354,10 +354,13 @@ class TestExportTasks(unittest.TestCase):
             mock.call('Can not load app for blog mount point. Skipping.')])
 
     @mock.patch('allura.tasks.export_tasks.log')
-    @td.with_tool('test', 'ShortUrl', 'urls')
+    @mock.patch('allura.tasks.export_tasks.M.Project.app_instance')
+    @mock.patch('allura.tasks.export_tasks.mail_tasks')
+    @td.with_tool('test', 'Tickets', 'bugs')
     @td.with_tool('test', 'Blog', 'blog')
-    def test_bulk_export_not_exportable_tool(self, log):
-        export_tasks.bulk_export('test', [u'urls', u'blog'], 'test-admin')
+    def test_bulk_export_not_exportable_tool(self, mail_tasks, app, log):
+        app.return_value.exportable = False
+        export_tasks.bulk_export('test', [u'bugs', u'blog'], 'test-admin')
         assert_equal(log.info.call_count, 2)
         assert_equal(log.info.call_args_list, [
             mock.call('Tool urls is not exportable. Skipping.'),

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/983c9ba8/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 8bc56c0..afcc076 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -19,10 +19,11 @@
 import logging
 from datetime import datetime
 import urllib2
+import json
 
 # Non-stdlib imports
 import pymongo
-from tg import config, expose, validate, redirect, flash
+from tg import config, expose, validate, redirect, flash, jsonify
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from pylons import tmpl_context as c, app_globals as g
 from pylons import request, response
@@ -90,6 +91,7 @@ class ForgeBlogApp(Application):
     }
     ordinal=14
     installable=True
+    exportable = True
     config_options = Application.config_options
     default_external_feeds = []
     icons={
@@ -188,6 +190,16 @@ class ForgeBlogApp(Application):
         BM.BlogPostSnapshot.query.remove(dict(app_config_id=c.app.config._id))
         super(ForgeBlogApp, self).uninstall(project)
 
+    def bulk_export(self, f):
+        f.write('{"posts": [')
+        posts = BM.BlogPost.query.find(dict(app_config_id=self.config._id)).sort('timestamp', pymongo.DESCENDING)
+        count = len(posts)
+        for i, post in enumerate(posts):
+            json.dump(post, f, cls=jsonify.GenericJSON)
+            if i < (count - 1):
+                f.write(',')
+        f.write(']}')
+
 class RootController(BaseController, FeedController):
 
     def __init__(self):
@@ -507,4 +519,4 @@ class PostRestController(BaseController):
         if 'labels' in post_data:
             self.post.labels = post_data['labels'].split(',')
         self.post.commit()
-        return self.post.__json__()
\ No newline at end of file
+        return self.post.__json__()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/983c9ba8/ForgeBlog/forgeblog/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/tests/test_app.py b/ForgeBlog/forgeblog/tests/test_app.py
new file mode 100644
index 0000000..7929dab
--- /dev/null
+++ b/ForgeBlog/forgeblog/tests/test_app.py
@@ -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.
+
+#-*- python -*-
+
+import tempfile
+import json
+from nose.tools import assert_equal
+
+from allura import model as M
+from allura.lib import helpers as h
+from alluratest.controller import setup_basic_test, setup_global_objects
+from allura.tests import decorators as td
+from forgeblog import model as BM
+
+
+class TestBulkExport(object):
+
+    def setUp(self):
+        setup_basic_test()
+        setup_global_objects()
+
+    @td.with_tool('test', 'Blog', 'blog')
+    def test_bulk_export(self):
+        project = M.Project.query.get(shortname='test')
+        blog = project.app_instance('blog')
+        h.set_context('test', 'blog', neighborhood='Projects')
+        post = BM.BlogPost()
+        post.title = 'Test title'
+        post.text = 'test post'
+        post.labels = ['the firstlabel', 'the second label']
+        post.make_slug()
+        post.discussion_thread.add_post(text='test comment')
+        post2 = BM.BlogPost()
+        post2.title = 'Test2 title'
+        post2.text = 'test2 post'
+        post2.make_slug()
+
+        f = tempfile.TemporaryFile()
+        blog.bulk_export(f)
+        f.seek(0)
+        blog = json.loads(f.read())
+        assert_equal(blog['posts'][0]['title'], 'Test2 title')
+        assert_equal(blog['posts'][0]['text'], 'test2 post')
+        assert_equal(blog['posts'][1]['title'], 'Test title')
+        assert_equal(blog['posts'][1]['text'], 'test post')
+        assert_equal(blog['posts'][1]['labels'], ['the firstlabel', 'the second label'])
+        assert_equal(blog['posts'][1]['discussion_thread']['posts'][0]['text'], 'test comment')


[46/50] git commit: [#3154] ticket:411 tests for export ini option

Posted by br...@apache.org.
[#3154] ticket:411 tests for export ini option


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

Branch: refs/heads/db/3154b
Commit: 663cc9a7792380d7905d0bf7357b8fca70753851
Parents: 9293bdd
Author: Anton Kasyanov <mi...@gmail.com>
Authored: Wed Aug 14 13:22:40 2013 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Wed Aug 21 15:25:59 2013 +0000

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_admin.py | 11 +++++++++++
 1 file changed, 11 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/663cc9a7/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 9ee232f..bc16982 100644
--- a/Allura/allura/tests/functional/test_admin.py
+++ b/Allura/allura/tests/functional/test_admin.py
@@ -22,6 +22,7 @@ import pkg_resources
 import StringIO
 from contextlib import contextmanager
 
+import tg
 import PIL
 from nose.tools import assert_equals, assert_in, assert_not_in
 from ming.orm.ormsession import ThreadLocalORMSession
@@ -800,6 +801,16 @@ class TestExport(TestController):
                       extra_environ={'username': 'test-user'},
                       status=403)
 
+    def test_ini_option(self):
+        tg.config['bulk_export_enabled'] = 'false'
+        r = self.app.get('/admin/')
+        assert_not_in('Export', r)
+        r = self.app.get('/admin/export').follow()
+        assert_equals(r.request.url, 'http://localhost/admin/')
+        tg.config['bulk_export_enabled'] = 'true'
+        r = self.app.get('/admin/')
+        assert_in('Export', r)
+
     def test_export_page_contains_exportable_tools(self):
         r = self.app.get('/admin/export')
         assert_in('Wiki</label> <a href="/p/test/wiki/">/p/test/wiki/</a>', r)