Return-Path: X-Original-To: apmail-incubator-allura-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-allura-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8079A104A4 for ; Mon, 26 Aug 2013 14:00:55 +0000 (UTC) Received: (qmail 59108 invoked by uid 500); 26 Aug 2013 14:00:54 -0000 Delivered-To: apmail-incubator-allura-commits-archive@incubator.apache.org Received: (qmail 58626 invoked by uid 500); 26 Aug 2013 14:00:49 -0000 Mailing-List: contact allura-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: allura-dev@incubator.apache.org Delivered-To: mailing list allura-commits@incubator.apache.org Received: (qmail 57661 invoked by uid 99); 26 Aug 2013 14:00:41 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 26 Aug 2013 14:00:41 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id F23558C5496; Mon, 26 Aug 2013 14:00:40 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: tvansteenburgh@apache.org To: allura-commits@incubator.apache.org Date: Mon, 26 Aug 2013 14:00:55 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [16/50] git commit: [#3154] ticket:393 Bulk export: ForgeBlog [#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/b2ae1d0d Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/b2ae1d0d Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/b2ae1d0d Branch: refs/heads/tv/6595 Commit: b2ae1d0d87c4114cd6d95dcd19f35b5c15644c38 Parents: c618a01 Author: Yuriy Arhipov Authored: Tue Jul 23 19:36:06 2013 +0400 Committer: Dave Brondsema Committed: Thu Aug 22 20:04:42 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/b2ae1d0d/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/b2ae1d0d/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/b2ae1d0d/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')