allura-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hei...@apache.org
Subject [7/9] allura git commit: [#8051] ticket:895 Add ability to export attachments in ForgeBlog, add tests
Date Tue, 08 Mar 2016 21:35:16 GMT
[#8051] ticket:895 Add ability to export attachments in ForgeBlog, add tests


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

Branch: refs/heads/master
Commit: 1097cfa71c4a7eada4f8508fe3c41355b5ecccd5
Parents: 51096ed
Author: Denis Kotov <deniskkotov@gmail.com>
Authored: Fri Jan 29 00:24:51 2016 +0200
Committer: Heith Seewald <heiths@gmail.com>
Committed: Tue Mar 8 14:11:57 2016 -0500

----------------------------------------------------------------------
 Allura/allura/app.py                            |  2 +-
 ForgeBlog/forgeblog/main.py                     | 32 ++++++++++++++-
 ForgeBlog/forgeblog/model/blog.py               |  4 +-
 ForgeBlog/forgeblog/tests/test_app.py           | 41 ++++++++++++++++++++
 ForgeDiscussion/forgediscussion/forum_main.py   |  2 +-
 .../forgediscussion/tests/test_app.py           | 33 ++++++++++++++++
 ForgeTracker/forgetracker/tests/test_app.py     | 34 +++++++++++++++-
 ForgeTracker/forgetracker/tracker_main.py       |  2 +-
 ForgeWiki/forgewiki/tests/test_app.py           | 25 ++++++------
 ForgeWiki/forgewiki/wiki_main.py                |  2 +-
 10 files changed, 153 insertions(+), 24 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/1097cfa7/Allura/allura/app.py
----------------------------------------------------------------------
diff --git a/Allura/allura/app.py b/Allura/allura/app.py
index f32637b..6098337 100644
--- a/Allura/allura/app.py
+++ b/Allura/allura/app.py
@@ -758,7 +758,7 @@ class Application(object):
             'mount_label': self.config.options.mount_label
         }
 
-    def get_attachemnt_path(self, path='', *args):
+    def get_attachment_export_path(self, path='', *args):
         return os.path.join(path, self.config.options.mount_point, *args)
 
 

http://git-wip-us.apache.org/repos/asf/allura/blob/1097cfa7/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 98482ce..c733584 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -19,6 +19,7 @@
 import logging
 import urllib2
 import json
+import os
 
 # Non-stdlib imports
 import pymongo
@@ -38,6 +39,7 @@ from ming.orm import session
 from allura.app import Application, SitemapEntry, ConfigOption
 from allura.app import DefaultAdminController
 from allura.lib import helpers as h
+from allura.lib.utils import JSONForExport
 from allura.lib.search import search_app
 from allura.lib.decorators import require_post
 from allura.lib.security import has_access, require_access
@@ -207,13 +209,39 @@ class ForgeBlogApp(Application):
 
     def bulk_export(self, f, export_path='', with_attachments=False):
         f.write('{"posts": [')
-        posts = BM.BlogPost.query.find(dict(app_config_id=self.config._id))
+        posts = list(BM.BlogPost.query.find(dict(app_config_id=self.config._id)))
+        if with_attachments:
+            GenericJSON = JSONForExport
+            self.export_attachments(posts, export_path)
+        else:
+            GenericJSON = jsonify.GenericJSON
         for i, post in enumerate(posts):
             if i > 0:
                 f.write(',')
-            json.dump(post, f, cls=jsonify.GenericJSON, indent=2)
+            json.dump(post, f, cls=GenericJSON, indent=2)
         f.write(']}')
 
+    def export_attachments(self, articles, export_path):
+        for article in articles:
+            attachment_path = self.get_attachment_export_path(export_path, str(article._id))
+            if not os.path.exists(attachment_path):
+                os.makedirs(attachment_path)
+            for post in article.discussion_thread.query_posts(status='ok'):
+                post_path = os.path.join(
+                    attachment_path,
+                    article.discussion_thread._id,
+                    post.slug
+                )
+                if not os.path.exists(post_path):
+                    os.makedirs(post_path)
+                for attachment in post.attachments:
+                    path = os.path.join(
+                        post_path,
+                        attachment.filename
+                    )
+                    with open(path, 'w') as fl:
+                        fl.write(attachment.rfile().read())
+
 
 class RootController(BaseController, FeedController):
 

http://git-wip-us.apache.org/repos/asf/allura/blob/1097cfa7/ForgeBlog/forgeblog/model/blog.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/model/blog.py b/ForgeBlog/forgeblog/model/blog.py
index 818e207..ef76bfc 100644
--- a/ForgeBlog/forgeblog/model/blog.py
+++ b/ForgeBlog/forgeblog/model/blog.py
@@ -288,8 +288,8 @@ class BlogPost(M.VersionedArtifact, ActivityObject):
             subject='%s discussion' % post.title)
         return post
 
-    def __json__(self, posts_limit=None):
-        return dict(super(BlogPost, self).__json__(posts_limit=posts_limit),
+    def __json__(self, posts_limit=None, is_export=False):
+        return dict(super(BlogPost, self).__json__(posts_limit=posts_limit, is_export=is_export),
                     author=self.author().username,
                     title=self.title,
                     url=h.absurl('/rest' + self.url()),

http://git-wip-us.apache.org/repos/asf/allura/blob/1097cfa7/ForgeBlog/forgeblog/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/tests/test_app.py b/ForgeBlog/forgeblog/tests/test_app.py
index bab8f22..313f074 100644
--- a/ForgeBlog/forgeblog/tests/test_app.py
+++ b/ForgeBlog/forgeblog/tests/test_app.py
@@ -19,15 +19,19 @@
 
 import tempfile
 import json
+import os
 
 from nose.tools import assert_equal
 from pylons import tmpl_context as c
+from cStringIO import StringIO
+from ming.orm import ThreadLocalORMSession
 
 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
+from cgi import FieldStorage
 
 
 class TestBulkExport(object):
@@ -72,3 +76,40 @@ class TestBulkExport(object):
                      ['the firstlabel', 'the second label'])
         assert_equal(blog['posts'][1]['discussion_thread']
                      ['posts'][0]['text'], 'test comment')
+
+    @td.with_tool('test', 'Blog', 'blog')
+    def test_export_with_attachments(self):
+        project = M.Project.query.get(shortname='test')
+        blog = project.app_instance('blog')
+        with h.push_context('test', 'blog', neighborhood='Projects'):
+            post = BM.BlogPost.new(
+                title='Test title',
+                text='test post',
+                labels=['the firstlabel', 'the second label'],
+                delete=None
+            )
+            ThreadLocalORMSession.flush_all()
+            test_file1 = FieldStorage()
+            test_file1.name = 'file_info'
+            test_file1.filename = 'test_file'
+            test_file1.file = StringIO('test file1\n')
+            p = post.discussion_thread.add_post(text='test comment')
+            p.add_multiple_attachments(test_file1)
+            ThreadLocalORMSession.flush_all()
+        f = tempfile.TemporaryFile()
+        temp_dir = tempfile.mkdtemp()
+        blog.bulk_export(f, temp_dir, True)
+        f.seek(0)
+        blog = json.loads(f.read())
+        blog['posts'] = sorted(
+            blog['posts'], key=lambda x: x['title'], reverse=True)
+
+        file_path = 'blog/{}/{}/{}/test_file'.format(
+            post._id,
+            post.discussion_thread._id,
+            list(post.discussion_thread.post_class().query.find())[0].slug
+        )
+        print blog['posts'][0]['discussion_thread']['posts'][0]
+        assert_equal(blog['posts'][0]['discussion_thread']['posts'][0]
+                     ['attachments'][0]['path'], file_path)
+        assert os.path.exists(os.path.join(temp_dir, file_path))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/1097cfa7/ForgeDiscussion/forgediscussion/forum_main.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py
index 5d584e8..3502191 100644
--- a/ForgeDiscussion/forgediscussion/forum_main.py
+++ b/ForgeDiscussion/forgediscussion/forum_main.py
@@ -254,7 +254,7 @@ class ForgeDiscussionApp(Application):
 
     def export_attachments(self, threads, export_path):
         for thread in threads:
-            attachment_path = self.get_attachemnt_path(export_path, str(thread.artifact._id),
thread._id)
+            attachment_path = self.get_attachment_export_path(export_path, str(thread.artifact._id),
thread._id)
             if not os.path.exists(attachment_path):
                 os.makedirs(attachment_path)
             for post in thread.query_posts(status='ok'):

http://git-wip-us.apache.org/repos/asf/allura/blob/1097cfa7/ForgeDiscussion/forgediscussion/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/test_app.py b/ForgeDiscussion/forgediscussion/tests/test_app.py
index 76f2071..39df2f0 100644
--- a/ForgeDiscussion/forgediscussion/tests/test_app.py
+++ b/ForgeDiscussion/forgediscussion/tests/test_app.py
@@ -21,12 +21,17 @@
 
 import tempfile
 import json
+import os
 
 from nose.tools import assert_equal
 from pylons import tmpl_context as c
+from cStringIO import StringIO
+from ming.orm import ThreadLocalORMSession
+from cgi import FieldStorage
 
 from allura import model as M
 from forgediscussion.tests.functional.test_rest import TestDiscussionApiBase
+from forgediscussion.model.forum import Forum
 
 
 class TestBulkExport(TestDiscussionApiBase):
@@ -60,3 +65,31 @@ class TestBulkExport(TestDiscussionApiBase):
         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')
+
+    def test_export_with_attachments(self):
+        project = M.Project.query.get(shortname='test')
+        discussion = project.app_instance('discussion')
+        post = Forum.query.get(shortname='general').sorted_threads[0].first_post
+        test_file1 = FieldStorage()
+        test_file1.name = 'file_info'
+        test_file1.filename = 'test_file'
+        test_file1.file = StringIO('test file1\n')
+        post.add_attachment(test_file1)
+        ThreadLocalORMSession.flush_all()
+
+        f = tempfile.TemporaryFile()
+        temp_dir = tempfile.mkdtemp()
+        discussion.bulk_export(f, temp_dir, True)
+        f.seek(0)
+        discussion = json.loads(f.read())
+        forums = sorted(discussion['forums'], key=lambda x: x['name'])
+        threads = sorted(forums[0]['threads'], key=lambda x: x['subject'])
+        file_path = os.path.join(
+            'discussion',
+            str(post.discussion_id),
+            str(post.thread_id),
+            post.slug,
+            'test_file'
+        )
+        assert_equal(threads[0]['posts'][0]['attachments'][0]['path'], file_path)
+        os.path.exists(file_path)

http://git-wip-us.apache.org/repos/asf/allura/blob/1097cfa7/ForgeTracker/forgetracker/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/test_app.py b/ForgeTracker/forgetracker/tests/test_app.py
index 94d593b..707a094 100644
--- a/ForgeTracker/forgetracker/tests/test_app.py
+++ b/ForgeTracker/forgetracker/tests/test_app.py
@@ -18,9 +18,13 @@
 import tempfile
 import json
 import operator
+import os
 
 from nose.tools import assert_equal, assert_true
 from pylons import tmpl_context as c
+from cgi import FieldStorage
+from cStringIO import StringIO
+from ming.orm import ThreadLocalORMSession
 
 from allura import model as M
 from allura.tests import decorators as td
@@ -37,8 +41,15 @@ class TestBulkExport(TrackerTestController):
         self.tracker = self.project.app_instance('bugs')
         self.new_ticket(summary='foo', _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')
+        self.ticket = TM.Ticket.query.find(dict(summary='foo')).first()
+        self.post = self.ticket.discussion_thread.add_post(text='silly comment')
+        ThreadLocalORMSession.flush_all()
+        test_file1 = FieldStorage()
+        test_file1.name = 'file_info'
+        test_file1.filename = 'test_file'
+        test_file1.file = StringIO('test file1\n')
+        self.post.add_attachment(test_file1)
+        ThreadLocalORMSession.flush_all()
 
     def test_bulk_export(self):
         # Clear out some context vars, to properly simulate how this is run from the export
task
@@ -72,3 +83,22 @@ class TestBulkExport(TrackerTestController):
         saved_bins_summaries = [bin['summary']
                                 for bin in tracker['saved_bins']]
         assert_true('Closed Tickets' in saved_bins_summaries)
+
+    def test_export_with_attachments(self):
+
+        f = tempfile.TemporaryFile()
+        temp_dir = tempfile.mkdtemp()
+        self.tracker.bulk_export(f, temp_dir, True)
+        f.seek(0)
+        tracker = json.loads(f.read())
+        tickets = sorted(tracker['tickets'],
+                         key=operator.itemgetter('summary'))
+        file_path = os.path.join(
+            'bugs',
+            str(self.ticket._id),
+            str(self.post.thread_id),
+            self.post.slug,
+            'test_file'
+        )
+        assert_equal(tickets[1]['discussion_thread']['posts'][0]['attachments'][0]['path'],
file_path)
+        os.path.exists(file_path)

http://git-wip-us.apache.org/repos/asf/allura/blob/1097cfa7/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 8dafa4c..a046243 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -516,7 +516,7 @@ class ForgeTrackerApp(Application):
 
     def export_attachments(self, tickets, export_path):
         for ticket in tickets:
-            attachment_path = self.get_attachemnt_path(export_path, str(ticket._id))
+            attachment_path = self.get_attachment_export_path(export_path, str(ticket._id))
             if not os.path.exists(attachment_path):
                 os.makedirs(attachment_path)
             for attachment in ticket.attachments:

http://git-wip-us.apache.org/repos/asf/allura/blob/1097cfa7/ForgeWiki/forgewiki/tests/test_app.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/test_app.py b/ForgeWiki/forgewiki/tests/test_app.py
index f6c2b48..5ffb690 100644
--- a/ForgeWiki/forgewiki/tests/test_app.py
+++ b/ForgeWiki/forgewiki/tests/test_app.py
@@ -24,12 +24,12 @@ import os
 from cStringIO import StringIO
 from nose.tools import assert_equal
 from pylons import tmpl_context as c
+from ming.orm import ThreadLocalORMSession
 
 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
-from ming.orm import session, ThreadLocalORMSession
 
 
 class TestBulkExport(object):
@@ -89,11 +89,11 @@ class TestBulkExport(object):
         assert_equal(len(pages[2]['discussion_thread']['posts']), 0)
 
     def add_page_with_attachmetns(self):
-        page = WM.Page.upsert('ZTest_title')
-        page.text = 'test_text'
-        page.mod_date = datetime.datetime(2013, 7, 5)
-        page.labels = ['test_label1', 'test_label2']
-        page.attach('test_file', StringIO('test string'))
+        self.page = WM.Page.upsert('ZTest_title')
+        self.page.text = 'test_text'
+        self.page.mod_date = datetime.datetime(2013, 7, 5)
+        self.page.labels = ['test_label1', 'test_label2']
+        self.page.attach('test_file', StringIO('test string'))
         ThreadLocalORMSession.flush_all()
 
     def test_bulk_export_with_attachmetns(self):
@@ -105,12 +105,9 @@ class TestBulkExport(object):
         wiki = json.loads(f.read())
         pages = sorted(wiki['pages'], key=operator.itemgetter('title'))
 
-        assert pages[3]['attachments'][0]['path'] == 'wiki/ZTest_title/test_file'
-        assert os.path.exists(os.path.join(temp_dir, 'wiki', 'A New Hope'))
-        assert os.path.exists(os.path.join(temp_dir, 'wiki', 'Return of the Jedi'))
-        assert os.path.exists(os.path.join(temp_dir, 'wiki', 'The Empire Strikes Back'))
-        assert os.path.exists(os.path.join(temp_dir, 'wiki', 'ZTest_title', 'test_file'))
-        with open(os.path.join(temp_dir, 'wiki', 'ZTest_title', 'test_file')) as fl:
+        assert pages[3]['attachments'][0]['path'] == 'wiki/{}/test_file'.format(self.page._id)
+        assert os.path.exists(os.path.join(temp_dir, 'wiki', str(self.page._id), 'test_file'))
+        with open(os.path.join(temp_dir, 'wiki', str(self.page._id), 'test_file')) as fl:
             assert fl.read() == 'test string'
 
     def test_bulk_export_without_attachments(self):
@@ -123,5 +120,5 @@ class TestBulkExport(object):
         pages = sorted(wiki['pages'], key=operator.itemgetter('title'))
 
         assert pages[3]['attachments'][0].get('path', None) is None
-        assert pages[3]['attachments'][0]['url'] != 'wiki/ZTest_title/test_file'
-        assert not os.path.exists(os.path.join(temp_dir, 'wiki', 'ZTest_title', 'test_file'))
\ No newline at end of file
+        assert pages[3]['attachments'][0]['url'] != 'wiki/{}/test_file'.format(self.page._id)
+        assert not os.path.exists(os.path.join(temp_dir, 'wiki', str(self.page._id), 'test_file'))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/1097cfa7/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 2a24130..e865d5c 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -357,7 +357,7 @@ The wiki uses [Markdown](%s) syntax.
 
     def export_attachments(self, pages, export_path):
         for page in pages:
-            attachment_path = self.get_attachemnt_path(export_path, str(page._id))
+            attachment_path = self.get_attachment_export_path(export_path, str(page._id))
             if not os.path.exists(attachment_path):
                 os.makedirs(attachment_path)
             for attachment in page.attachments:


Mime
View raw message