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 2020/04/13 17:42:52 UTC

[allura] branch master updated (d92aa47 -> d693478)

This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git.


    from d92aa47  upgrade bleach
     new b7d7b95  [#7935] Created forum importer for allura's own export format
     new 63665be  [#7935] added annotate method
     new ecfd551  [#7935] Updated the import_tool method
     new 575ef5d  [#7935] Made minor changes
     new 90f5f0b  [#7935] Fixed errors
     new 5735e7c  [#7935] No general discussion will be created by default after the import
     new 28d7e7f  [#7935] Added missing attributes
     new e9098d2  [#7935] Cleaned up
     new 956cbc7  [#7935] Fixed bug where forums and threads are related to a wrong app
     new a733a89  [#7935] Clean up work
     new 19d6917  [#7935] Added unicode support to filenames
     new 9986f6e  [#7935] Added support for anonymous users
     new 29f1703  [#7935] Refactored annotate method
     new d044252  [#7935] Refactored annotate and get_user  method
     new cc6cba9  [#7935] Changed method name to fit naming convention
     new a96feb9  [#7935] Improved error handling of annotate method
     new 73cd363  [#7935] Added tests for discussion importer
     new cfbf6dd  [#7935] Created test for creating a general discussion
     new ecaa8d4  [#7935] Added test for unicode characters
     new 9e6ccaa  [#7935] Added tests for import_tool method
     new fe5b751  [#7935] Changed to match unit tests
     new 08dd66a  [#7935] Removed assignment of slug to posts
     new cd99e4e  [#7935] Added test for add_posts
     new bf5f5ea  [#7935] Added test for add_posts with many posts
     new a0080b6  [#7935] Added test for add_posts with unicode characters
     new a69ddf2  [#7935] Created tests for add_posts with last_edited key
     new f6d08ec  [#7935] Added test for add_posts with attachments
     new c1ce0ca  [#7935] Added test for missing keys
     new 6b92e45  [#7935] Added unicode test to test annotate_text() method
     new cc0a5f7  [#7935] Created test_index
     new 81c5034  [#7935] Added support for nested posts
     new 102bec8  [#7935] Removed some debug code from create method in the controller
     new 93600c1  [#7935] Created tests for the controller
     new 2b15be0  [#7935] Updated creation of nested posts
     new f5299e6  [#7935] Added license comment
     new 70a2cbe  [#7935] Added tests for nested posts
     new 708fb1a  [#7935] Fixed wrong test
     new d864291  [#7935] Removed debug code
     new 0460b75  [#7935] Removed commented code
     new 09bf1e7  [#7935] Removed unncecessary code
     new a79a37b  [#7935] Formatted code so it matches pep8 code style guidelines
     new 25ec9fb  [#7935] Changed comparison with None
     new 3f3174d  [#7935] Added license header
     new c018356  [#7935] Refactored get_user and annotate method into AlluraImporter class
     new b9df3ac  [#7935] Fixed tabs so alluratest.test_syntax.test_no_tabs will pass
     new bc760c8  [#7935] Extracted load json method
     new 33aac16  [#7935] Fixed wrong comparisons with None
     new d745f8a  [#7935] Deleted two newlines at the end of the file
     new 54f0e3f  [#7935] Ran python-modernize
     new d693478  [#7935] Fixed comparisons with None

The 50 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 ForgeImporters/forgeimporters/base.py              |    3 +-
 .../forgeimporters/forge/alluraImporter.py         |   59 +
 ForgeImporters/forgeimporters/forge/discussion.py  |  233 ++++
 .../forge/templates/discussion/index.html          |   15 +-
 ForgeImporters/forgeimporters/forge/tracker.py     |   23 +-
 .../forgeimporters/tests/forge/test_discussion.py  | 1395 ++++++++++++++++++++
 .../forgeimporters/tests/forge/test_tracker.py     |    4 +-
 ForgeImporters/setup.py                            |    1 +
 8 files changed, 1708 insertions(+), 25 deletions(-)
 create mode 100644 ForgeImporters/forgeimporters/forge/alluraImporter.py
 create mode 100644 ForgeImporters/forgeimporters/forge/discussion.py
 copy INSTALL.markdown => ForgeImporters/forgeimporters/forge/templates/discussion/index.html (69%)
 create mode 100644 ForgeImporters/forgeimporters/tests/forge/test_discussion.py


[allura] 26/50: [#7935] Created tests for add_posts with last_edited key

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit a69ddf2abfc0249da4bcf4e149e9282560f8eec6
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 18:05:10 2020 +0100

    [#7935] Created tests for add_posts with last_edited key
---
 .../forgeimporters/tests/forge/test_discussion.py  | 84 ++++++++++++++++++++++
 1 file changed, 84 insertions(+)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 5a73f72..feb9dfc 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -803,6 +803,90 @@ class TestDiscussionImporter(TestCase):
         post.add_multiple_attachments.assert_called_once_with([])
         
 
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'h')
+    def test_add_posts_with_last_edited(self, h, c):
+        """ This method tests if the last edited attribute of a post is correctly updated if specified """
+
+        # Test with legit timestamp
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+
+        _json = [
+            {
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "test",
+                "subject": "post with last edited",
+                "last_edited": "2020-01-29 22:47:52.951000"
+            }
+        ]
+
+        importer.add_posts(thread, _json, app)
+
+        self.assertEqual(post.last_edit_date, parse(_json[0]['last_edited']))
+
+
+        # Test with none
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+
+        _json = [
+            {
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "test",
+                "subject": "post with last edited",
+                "last_edited": None
+            }
+        ]
+
+        post.last_edit_date = '-'
+        importer.add_posts(thread, _json, app)
+
+        self.assertEqual(post.last_edit_date, '-')
+
+       
+        # Test with no last edited 
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+
+        _json = [
+            {
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "test",
+                "subject": "post with last edited",
+            }
+        ]
+
+        post.last_edit_date = '-'
+        importer.add_posts(thread, _json, app)
+
+        self.assertEqual(post.last_edit_date, '-')
+
+        
+        # Test with junk last edited 
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+
+        _json = [
+            {
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "test",
+                "subject": "post with last edited",
+                "last_edited": "asdf asd"
+            }
+        ]
+
+        try:
+            importer.add_posts(thread, _json, app)
+            self.fail("add_posts() didn't throw exception even last_edited was junk data")
+        except:
+            pass
+
+
     def __init_add_posts_tests(self):
         importer = discussion.ForgeDiscussionImporter()
 


[allura] 12/50: [#7935] Added support for anonymous users

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 9986f6e7809cce20ed234bc67544fdcfe61fe145
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Fri Feb 28 15:44:03 2020 +0100

    [#7935] Added support for anonymous users
---
 ForgeImporters/forgeimporters/forge/discussion.py | 29 ++++++++++-------------
 1 file changed, 13 insertions(+), 16 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index be575b6..304ed25 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -35,6 +35,7 @@ from allura.lib.plugin import ImportIdConverter
 from forgediscussion import utils, import_support
 from forgediscussion import model as DM
 
+
 class ForgeDiscussionImportForm(ToolImportForm):
     discussions_json = v.JsonFile(not_empty=True)
 
@@ -188,34 +189,30 @@ class ForgeDiscussionImporter(ToolImporter):
 
 
     def annotate(self, text, user, username, label=''):
-        if username and user.is_anonymous() and username != 'nobody':
+        if username and user.is_anonymous() and username != 'nobody' and username != '*anonymous':
             return '*Originally%s by:* %s\n\n%s' % (label, username, text)
         return text
 
 
     def add_posts(self, thread, posts, app):
         for post_json in posts:
-            print("Author: ", post_json["author"])
-            user = self.get_user(post_json["author"])
-            print("User", user)
+            username = post_json["author"]
+            print("Author: " + str(username))
+            user = self.get_user(username)
+            print("User: " + str(user))
             with h.push_config(c, user=user, app=app):
                 p = thread.add_post(
                         subject=post_json['subject'],
-                        text=post_json['text'], 
-                        ignore_security=True,
+                        text=self.annotate(post_json['text'], user, username, " created"),
+                        timestamp=parse(post_json["timestamp"]),
+                        ignore_security=True
                 )
 
-                if "slug" in post_json.keys():
-                    p.slug = post_json['slug']
                 if "last_edited" in post_json and post_json["last_edited"] != None:
                     print("Last edited: " + str(post_json["last_edited"]))
                     p.last_edit_date = parse(post_json["last_edited"])
-                if "timestamp" in post_json:
-                    p.timestamp = parse(post_json["timestamp"])
-
-                try:
-                    p.add_multiple_attachments([File(a['url'])
-                                                for a in post_json['attachments']])
-                except:
-                    print("Could not add attachemtns to post")
+                if "slug" in post_json.keys():
+                    p.slug = post_json['slug']
+
+                p.add_multiple_attachments([File(a["url"]) for a in post_json["attachments"]])
 


[allura] 37/50: [#7935] Fixed wrong test

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 708fb1ae8d9747d677d30bdf7dcca25667acf70d
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Thu Mar 5 17:11:45 2020 +0100

    [#7935] Fixed wrong test
---
 .../forgeimporters/tests/forge/test_discussion.py  | 24 +++++++++++-----------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index cb4e861..8d4df31 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -1066,12 +1066,12 @@ class TestDiscussionImporter(TestCase):
         # Test with author attribute missing
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
-        _json = {
+        _json = [{
             "subject": "foo",
             "text": "foo",
             "timestamp": "2020-01-29 22:42:58.478000",
             "attachments": []
-        }
+        }]
 
         self.__check_posts_exceptions(importer, thread, _json, app)
 
@@ -1079,12 +1079,12 @@ class TestDiscussionImporter(TestCase):
         # Test with subject attribute missing
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
-        _json = {
+        _json = [{
             "author": "admin1",
             "text": "foo",
             "timestamp": "2020-01-29 22:42:58.478000",
             "attachments": []
-        }
+        }]
 
         self.__check_posts_exceptions(importer, thread, _json, app)
 
@@ -1092,12 +1092,12 @@ class TestDiscussionImporter(TestCase):
         # Test with text attribute missing
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
-        _json = {
+        _json = [{
             "author": "admin1",
             "timestamp": "2020-01-29 22:42:58.478000",
             "subject": "foo",
             "attachments": []
-        }
+        }]
 
         self.__check_posts_exceptions(importer, thread, _json, app)
 
@@ -1105,12 +1105,12 @@ class TestDiscussionImporter(TestCase):
         # Test with timestamp attribute missing
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
-        _json = {
+        _json = [{
             "author": "admin1",
             "text": "foo",
             "subject": "foo",
             "attachments": []
-        }
+        }]
 
         self.__check_posts_exceptions(importer, thread, _json, app)
 
@@ -1118,12 +1118,12 @@ class TestDiscussionImporter(TestCase):
         # Test with attachments attribute missing
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
-        _json = {
+        _json = [{
             "author": "admin1",
             "text": "foo",
             "subject": "foo",
             "timestamp": "2020-01-29 22:42:58.478000"
-        }
+        }]
 
         self.__check_posts_exceptions(importer, thread, _json, app)
 
@@ -1131,7 +1131,7 @@ class TestDiscussionImporter(TestCase):
         # Test with url of attachments attribute missing
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
-        _json = {
+        _json = [{
             "author": "admin1",
             "text": "foo",
             "subject": "foo",
@@ -1142,7 +1142,7 @@ class TestDiscussionImporter(TestCase):
                     "path": "path/to/attachment"
                 }
             ]
-        }
+        }]
 
         self.__check_posts_exceptions(importer, thread, _json, app)
 


[allura] 41/50: [#7935] Formatted code so it matches pep8 code style guidelines

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit a79a37b06ed76fa85f7660306c088c6dcaad9c8c
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Sat Mar 14 00:50:01 2020 +0100

    [#7935] Formatted code so it matches pep8 code style guidelines
---
 .../forgeimporters/forge/alluraImporter.py         |  10 +-
 ForgeImporters/forgeimporters/forge/discussion.py  |  47 +++--
 .../forgeimporters/tests/forge/test_discussion.py  | 211 ++++++++++++---------
 3 files changed, 163 insertions(+), 105 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/alluraImporter.py b/ForgeImporters/forgeimporters/forge/alluraImporter.py
index a0a8670..477b4ef 100644
--- a/ForgeImporters/forgeimporters/forge/alluraImporter.py
+++ b/ForgeImporters/forgeimporters/forge/alluraImporter.py
@@ -5,6 +5,7 @@ from allura import model as M
 
 class AlluraImporter(ToolImporter):
 
+
     def get_user(self, username):
         if username is None:
             return M.User.anonymous()
@@ -14,10 +15,17 @@ class AlluraImporter(ToolImporter):
         return user
 
     def annotate(self, text, user, username, label=''):
-        if username != "" and username != None and user != None and user.is_anonymous() and username != 'nobody' and username != '*anonymous':
+        if  username != "" \
+            and username != None \
+            and user != None \
+            and user.is_anonymous() \
+            and username != 'nobody' \
+            and username != '*anonymous':
             return '*Originally%s by:* %s\n\n%s' % (label, username, text)
 
         if text == None:
             text = ""
 
         return text
+
+
diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index fdcabff..a06b65f 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -53,6 +53,7 @@ from forgediscussion import model as DM
 
 from alluraImporter import AlluraImporter
 
+
 class ForgeDiscussionImportForm(ToolImportForm):
     discussions_json = v.JsonFile(not_empty=True)
 
@@ -70,35 +71,42 @@ class ForgeDiscussionImportController(ToolImportController):
     @require_post()
     def create(self, discussions_json, mount_point, mount_label, **kw):
         if self.importer.enforce_limit(c.project):
-            save_importer_upload(c.project, 'discussions.json', json.dumps(discussions_json))
+            save_importer_upload(
+                            c.project,
+                            'discussions.json',
+                            json.dumps(discussions_json)
+                           )
             self.importer.post(mount_point=mount_point, mount_label=mount_label)
-            flash('Discussion import has begun. Your new discussion will be available when the import is complete')
-            
+            flash('Discussion import has begun. ' \
+                   + 'Your new discussion will be available ' \
+                   + 'when the import is complete'
+                 )
         else:
-            flash('There are too many imports pending at this time. Please wait and try again.', 'error')
-
+            flash('There are too many imports pending at this time. ' \
+                  + 'Please wait and try again.', 
+                  'error'
+                 )
         redirect(c.project.url() + 'admin/')
 
 
 class ForgeDiscussionImporter(AlluraImporter):
+
+
     source = 'Allura'
     target_app_ep_names = 'discussion'
     controller = ForgeDiscussionImportController
     tool_label = 'Discussion'
     tool_description = 'Import an allura discussion.'
 
-
     def __init__(self, *args, **kwargs):
         super(ForgeDiscussionImporter, self).__init__(*args, **kwargs)
 
-
     def _load_json(self, project):
         upload_path = get_importer_upload_path(project)
         full_path = os.path.join(upload_path, 'discussions.json')
         with open(full_path) as fp:
             return json.load(fp)
 
-
     def import_tool(self, project, user, mount_point=None,
                      mount_label=None, **kw):
         discussion_json = self._load_json(project)
@@ -140,7 +148,10 @@ class ForgeDiscussionImporter(AlluraImporter):
 
                     for thread_json in forum_json["threads"]:
                         thread = forum.get_discussion_thread(dict(
-                                            headers=dict(Subject=thread_json['subject'])))[0]
+                                            headers=dict(
+                                                Subject=thread_json['subject']
+                                            )
+                                        ))[0]
 
                         if "import_id" in thread_json:
                             thread.import_id = thread_json["import_id"]
@@ -150,7 +161,6 @@ class ForgeDiscussionImporter(AlluraImporter):
                     session(forum).flush(forum)
                     session(forum).expunge(forum)
 
-
                 M.AuditLog.log(
                     "import tool %s from exported Allura JSON" % (
                         app.config.options.mount_point,
@@ -169,19 +179,16 @@ class ForgeDiscussionImporter(AlluraImporter):
             finally:
                 M.session.artifact_orm_session._get().skip_mod_date = False
                                      
-
     def _clear_forums(self, app):
       forums = app.forums
       for forum in forums:
           forum.delete()
 
-
     def annotate_text(self, text, user, username):
         label = " created"
         
         return self.annotate(text, user, username, label)
 
-
     def add_posts(self, thread, posts, app):
         created_posts = []
 
@@ -209,16 +216,24 @@ class ForgeDiscussionImporter(AlluraImporter):
 
                 p = thread.add_post(
                         subject=post_json['subject'],
-                        text=self.annotate_text(post_json['text'], user, username),
+                        text=self.annotate_text(post_json['text'],
+                                                user,
+                                                username
+                                               ),
                         timestamp=timestamp,
                         ignore_security=True,
                         parent_id=parent_id
                 )
 
-                if "last_edited" in post_json and post_json["last_edited"] != None:
+                if ("last_edited" in post_json) \
+                    and (post_json["last_edited"] != None):
                     p.last_edit_date = parse(post_json["last_edited"])
 
-                p.add_multiple_attachments([File(a["url"]) for a in post_json["attachments"]])
+                p.add_multiple_attachments(
+                        [File(a["url"]) for a in post_json["attachments"]]
+                )
 
                 if slug != '': 
                     created_posts.append({ slug: p })
+
+
diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 5db983b..c37112d 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -16,7 +16,6 @@
 #       under the License.
 
 from unittest import TestCase
-
 import mock
 
 from dateutil.parser import parse
@@ -42,12 +41,10 @@ class TestDiscussionImporter(TestCase):
         self.patcher_g = mock.patch('forgeimporters.base.g', mock.MagicMock())
         self.patcher_g.start()
 
-
     def tearDown(self):
         super(TestDiscussionImporter, self).tearDown()
         self.patcher_g.stop()
 
-
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'g')
     @mock.patch.object(discussion, 'M')
@@ -55,7 +52,10 @@ class TestDiscussionImporter(TestCase):
     @mock.patch.object(discussion, 'h')
     @mock.patch.object(discussion, 'ThreadLocalORMSession')
     def test_import_tool_with_general_discussion(self, tlos, h, session, m, g, c):
-        """ This test creates a general discussion forum with one thread and one post from admin """
+        """ This test creates a general discussion forum with
+             one thread and one post from admin 
+        """
+
         importer = discussion.ForgeDiscussionImporter()
         _json = { 
             'forums': [{
@@ -75,7 +75,7 @@ class TestDiscussionImporter(TestCase):
                                 'attachments': [],
                                 'author': 'admin1',
                                 'timestamp': '2020-01-29 22:30:42.497000',
-                                'author_icon_url': 'https://secure.gravatar.com/avatar/2ba5bfa33e6faca31f7dd150960ce926?r=pg&d=https%3A%2F%2F4.xb.sf.net%2Fnf%2F0%2F_ew_%2Ftheme%2Fsftheme%2Fimages%2Fsandiego%2Ficons%2Fdefault-avatar.png',
+                                'author_icon_url': 'bla',
                                 'text': 'hi',
                                 'last_edited': None,
                                 'slug': '00aa',
@@ -107,7 +107,10 @@ class TestDiscussionImporter(TestCase):
         g.post_event = mock.Mock()
         m.AuditLog.log = mock.Mock()
 
-        importer.import_tool(project, user, mount_point='mount_point', mount_label='mount_label')
+        importer.import_tool(project, user, 
+                             mount_point='mount_point', 
+                             mount_label='mount_label'
+                            )
 
         project.install_app.assert_called_once_with(
             'discussion', 'mount_point', 'mount_label',
@@ -120,13 +123,25 @@ class TestDiscussionImporter(TestCase):
         new_forum = self.__get_forum_dict(app, forum_json)
 
         utils.create_forum.assert_called_once_with(app, new_forum=new_forum)
-        forum.get_discussion_thread(dict(headers=dict(Subject=_json["forums"][0]["threads"][0]["subject"])))
-        importer.add_posts.assert_called_once_with(thread1, _json["forums"][0]["threads"][0]["posts"], app)
+        forum.get_discussion_thread(
+              dict(
+                   headers=dict(
+                        Subject=_json["forums"][0]["threads"][0]["subject"]
+                  )))
+        importer.add_posts.assert_called_once_with(
+                                    thread1, 
+                                    _json["forums"][0]["threads"][0]["posts"],
+                                    app
+        )
 
-        m.AuditLog.log.assert_called_once_with("import tool mount_point from exported Allura JSON", project=project, user=user, url='foo')
+        m.AuditLog.log.assert_called_once_with(
+                        "import tool mount_point from exported Allura JSON",
+                        project=project,
+                        user=user,
+                        url='foo'
+                    )
         g.post_event.assert_called_once_with("project_updated")
 
-
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'g')
     @mock.patch.object(discussion, 'M')
@@ -134,7 +149,9 @@ class TestDiscussionImporter(TestCase):
     @mock.patch.object(discussion, 'h')
     @mock.patch.object(discussion, 'ThreadLocalORMSession')
     def test_import_tool_unicode(self, tlos, h, session, m, g, c):
-        """ This method tests if the import tool method supports unicode characters """
+        """ This method tests if the import tool method 
+            supports unicode characters 
+        """
         
         importer = discussion.ForgeDiscussionImporter()
 
@@ -154,7 +171,7 @@ class TestDiscussionImporter(TestCase):
                               "attachments": [],
                               "author": "admin1",
                               "timestamp": "2020-01-29 22:32:00.584000",
-                              "author_icon_url": "https://secure.gravatar.com/avatar/2ba5bfa33e6faca31f7dd150960ce926?r=pg&d=https%3A%2F%2F4.xb.sf.net%2Fnf%2F0%2F_ew_%2Ftheme%2Fsftheme%2Fimages%2Fsandiego%2Ficons%2Fdefault-avatar.png",
+                              "author_icon_url": "bla",
                               "text": "test with un\u00ef\u00e7\u00f8\u2202\u00e9 text",
                               "last_edited": None,
                               "slug": "0e0e",
@@ -190,7 +207,11 @@ class TestDiscussionImporter(TestCase):
         importer.get_user = mock.Mock(return_value=admin)
         importer.annotate_text = mock.Mock(return_value='aa')
 
-        importer.import_tool(project, user, mount_point='mount_point', mount_label='mount_label')
+        importer.import_tool(project,
+                             user,
+                             mount_point='mount_point',
+                             mount_label='mount_label'
+                            )
 
         project.install_app.assert_called_once_with(
             'discussion', 'mount_point', 'mount_label',
@@ -201,7 +222,11 @@ class TestDiscussionImporter(TestCase):
         new_forum = self.__get_forum_dict(app, forum_json)
 
         utils.create_forum.assert_called_once_with(app, new_forum=new_forum)
-        forum.get_discussion_thread.assert_called_once_with(dict(headers=dict(Subject=_json["forums"][0]["threads"][0]["subject"])))
+        forum.get_discussion_thread.assert_called_once_with(
+                    dict(
+                        headers=dict(
+                            Subject=_json["forums"][0]["threads"][0]["subject"]
+            )))
         
         importer.get_user.assert_called_once_with('admin1')
     
@@ -218,12 +243,15 @@ class TestDiscussionImporter(TestCase):
             ignore_security=True,
             parent_id=None
         )
-        importer.annotate_text.assert_called_once_with(post["text"], admin, post["author"])
+        importer.annotate_text.assert_called_once_with(
+                post["text"],
+                admin,
+                post["author"]
+        )
         p.add_multiple_attachments.assert_called_once_with([])
 
         g.post_event.assert_called_once_with('project_updated')
 
-
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'g')
     @mock.patch.object(discussion, 'M')
@@ -231,7 +259,9 @@ class TestDiscussionImporter(TestCase):
     @mock.patch.object(discussion, 'h')
     @mock.patch.object(discussion, 'ThreadLocalORMSession')
     def test_import_tool_multiple_forums(self, tlos, h, session, m, g, c):
-        """ This test tests if it is possible to create a discussion with multiple forums """
+        """ This test tests if it is possible to create 
+            a discussion with multiple forums 
+        """
 
         importer = discussion.ForgeDiscussionImporter()
 
@@ -263,7 +293,6 @@ class TestDiscussionImporter(TestCase):
                 }
             ]
         }
-
         
         importer._load_json = mock.Mock(return_value=_json)
         importer.add_posts = mock.Mock()        
@@ -307,7 +336,6 @@ class TestDiscussionImporter(TestCase):
         m.AuditLog.log.assert_called_once()
         g.post_event.assert_called_once()
 
-
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'g')
     @mock.patch.object(discussion, 'M')
@@ -354,7 +382,6 @@ class TestDiscussionImporter(TestCase):
                 ]
             }
 
-            
         importer._load_json = mock.Mock(return_value=_json)
         importer.add_posts = mock.Mock()        
         importer._clear_forums = mock.Mock()
@@ -378,7 +405,12 @@ class TestDiscussionImporter(TestCase):
 
         importer.import_tool(project, user, 'mount_point', 'mount_label')
 
-        project.install_app.assert_called_once_with('discussion', 'mount_point', 'mount_label', import_id={'source': 'Allura'})
+        project.install_app.assert_called_once_with(
+                'discussion',
+                'mount_point',
+                'mount_label',
+                import_id={'source': 'Allura'}
+        )
         h.push_config.assert_called_once_with(c, app=app)
 
         utils.create_forum.assert_called_once()
@@ -406,7 +438,6 @@ class TestDiscussionImporter(TestCase):
         m.AuditLog.log.assert_called_once()
         g.post_event.assert_called_once()
 
-
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'g')
     @mock.patch.object(discussion, 'M')
@@ -422,7 +453,7 @@ class TestDiscussionImporter(TestCase):
         import_id = "qwert258"
         _json = {
             "forums": [ {
-                "description": "Forum about anything you want to talk about.", 
+                "description": "Forum about anything you want to talk about.",
                 "shortname": "general", 
                 "name": "General Discussion",
                 "import_id": import_id,
@@ -454,7 +485,6 @@ class TestDiscussionImporter(TestCase):
         importer.import_tool(project, user, 'mount_point', 'mount_label')
         
         self.assertEqual(import_id, forum.import_id)
-        
 
         # Test without import id
         _json = {
@@ -475,7 +505,6 @@ class TestDiscussionImporter(TestCase):
 
         self.assertEqual('', forum.import_id)
 
-
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'g')
     @mock.patch.object(discussion, 'M')
@@ -533,7 +562,7 @@ class TestDiscussionImporter(TestCase):
         _json = {
             "forums": [ {
                 "description": "Forum about anything you want to talk about.", 
-                "shortname": "general", 
+                "shortname": "general",
                 "name": "General Discussion",
                 "threads": [{
                         "limit": None,
@@ -553,7 +582,6 @@ class TestDiscussionImporter(TestCase):
 
         self.assertEqual('', thread.import_id)
 
-
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'g')
     @mock.patch.object(discussion, 'M')
@@ -563,10 +591,10 @@ class TestDiscussionImporter(TestCase):
     def test_import_tool_missing_keys(self, tlos, h, session, m, g, c):
         """ This method tests if missing keys are handled correctly """
 
-        # Check if shortname missing
+        # Check when shortname missing
         _json = {
             "forums": [ {
-                "description": "Forum about anything you want to talk about.", 
+                "description": "Forum about anything you want to talk about.",
                 "name": "General Discussion",
                 "threads": []
             }]
@@ -597,9 +625,8 @@ class TestDiscussionImporter(TestCase):
         m.AuditLog.log= mock.Mock()
 
         self.__check_missing(project, user, importer, h, g, utils) 
-
         
-        # Check if description is missing
+        # Check when description is missing
         _json = {
             "forums": [ {
                 "shortname": "general",
@@ -612,8 +639,7 @@ class TestDiscussionImporter(TestCase):
         self.__check_missing(project, user, importer, h, g, utils)
         utils.create_forum.assert_not_called()
 
-
-        # Check if name is missing
+        # Check when name is missing
         _json = {
             "forums": [ {
                 "shortname": "general",
@@ -625,9 +651,8 @@ class TestDiscussionImporter(TestCase):
         importer._load_json = mock.Mock(return_value=_json)
         self.__check_missing(project, user, importer, h, g, utils)
         utils.create_forum.assert_not_called()
-
         
-        # Check if threads are missing
+        # Check when threads are missing
         _json = {
             "forums": [ {
                 "shortname": "general",
@@ -639,8 +664,7 @@ class TestDiscussionImporter(TestCase):
         importer._load_json = mock.Mock(return_value=_json)
         self.__check_missing(project, user, importer, h, g, utils)
 
-        
-        # Check if subject of threads are missing
+        # Check when subject of threads are missing
         _json = {
             "forums": [ {
                 "shortname": "general",
@@ -656,7 +680,7 @@ class TestDiscussionImporter(TestCase):
         self.__check_missing(project, user, importer, h, g, utils)
 
 
-        # Check if posts of threads are missing
+        # Check when posts of threads are missing
         _json = {
             "forums": [ {
                 "shortname": "general",
@@ -673,7 +697,6 @@ class TestDiscussionImporter(TestCase):
         
         self.assertEqual(h.make_app_admin_only.call_count, 6)
 
-
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'h')
     def test_add_posts(self, h, c):
@@ -701,12 +724,13 @@ class TestDiscussionImporter(TestCase):
                 parent_id=None
         )
         post.add_multiple_attachments.assert_called_once_with([])
-        
     
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'h')
     def test_add_posts_with_many_posts(self, h, c):
-        """ This methods tests if many posts of a thread are added to this thread """
+        """ This methods tests if many posts of 
+            a thread are added to this thread 
+        """
 
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
@@ -777,15 +801,17 @@ class TestDiscussionImporter(TestCase):
         self.assertEqual(8, h.push_config.call_count)
         self.assertEqual(8, thread.add_post.call_count)
         self.assertEqual(8, post.add_multiple_attachments.call_count)
-    
 
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'h')
     def test_add_posts_with_unicode(self, h, c):
-        """ This method tests if it is possible to add posts which contain unicode characters in subject and text """
+        """ This method tests if it is possible to add 
+            posts which contain unicode characters in subject and text
+        """
 
         importer, app, thread, user, post = self.__init_add_posts_tests()
-        importer.annotate_text.return_value = "test with un\u00ef\u00e7\u00f8\u2202\u00e9 text"
+        importer.annotate_text.return_value = "test" \
+                + " with un\u00ef\u00e7\u00f8\u2202\u00e9 text"
 
         _json = [
             {
@@ -810,11 +836,12 @@ class TestDiscussionImporter(TestCase):
         )
         post.add_multiple_attachments.assert_called_once_with([])
         
-
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'h')
     def test_add_posts_with_last_edited(self, h, c):
-        """ This method tests if the last edited attribute of a post is correctly updated if specified """
+        """ This method tests if the last edited attribute 
+            of a post is correctly updated if specified
+        """
 
         # Test with legit timestamp
         importer, app, thread, user, post = self.__init_add_posts_tests()
@@ -834,7 +861,6 @@ class TestDiscussionImporter(TestCase):
 
         self.assertEqual(post.last_edit_date, parse(_json[0]['last_edited']))
 
-
         # Test with none
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
@@ -854,7 +880,6 @@ class TestDiscussionImporter(TestCase):
 
         self.assertEqual(post.last_edit_date, '-')
 
-       
         # Test with no last edited 
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
@@ -873,7 +898,6 @@ class TestDiscussionImporter(TestCase):
 
         self.assertEqual(post.last_edit_date, '-')
 
-        
         # Test with junk last edited 
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
@@ -890,11 +914,11 @@ class TestDiscussionImporter(TestCase):
 
         try:
             importer.add_posts(thread, _json, app)
-            self.fail("add_posts() didn't throw exception even last_edited was junk data")
+            self.fail("add_posts() didn't throw exception" \
+                      + " even last_edited was junk data")
         except:
             pass
 
-
     @mock.patch.object(discussion, 'File')
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'h')
@@ -936,10 +960,9 @@ class TestDiscussionImporter(TestCase):
         self.assertEqual(File.call_args_list, [
             mock.call('http://www.foo.com/attachment0'),
             mock.call('http://www.foo.com/attachment1'),
-            mock.call('http://www.foo.com/attachment2')
+            mock.call('http://www.foo.com/attachment2'),
         ])
 
-
     @mock.patch.object(discussion, 'File')
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'h')
@@ -955,7 +978,7 @@ class TestDiscussionImporter(TestCase):
             mock.Mock(_id=2),
             mock.Mock(_id=3),
             mock.Mock(_id=4),
-            mock.Mock(_id=5)
+            mock.Mock(_id=5),
         ]
 
         _json = [
@@ -1056,12 +1079,13 @@ class TestDiscussionImporter(TestCase):
             )
         ])
 
-
     @mock.patch.object(discussion, 'File')
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'h')
     def test_add_posts_with_missing_keys(self, h, c, File):
-        """ This method checks if add_posts will throw an error if required keys are missing """
+        """ This method checks if add_posts will 
+            throw an error if required keys are missing
+        """
         
         # Test with author attribute missing
         importer, app, thread, user, post = self.__init_add_posts_tests()
@@ -1075,7 +1099,6 @@ class TestDiscussionImporter(TestCase):
 
         self.__check_posts_exceptions(importer, thread, _json, app)
 
-
         # Test with subject attribute missing
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
@@ -1088,7 +1111,6 @@ class TestDiscussionImporter(TestCase):
 
         self.__check_posts_exceptions(importer, thread, _json, app)
 
-
         # Test with text attribute missing
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
@@ -1101,7 +1123,6 @@ class TestDiscussionImporter(TestCase):
 
         self.__check_posts_exceptions(importer, thread, _json, app)
 
-
         # Test with timestamp attribute missing
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
@@ -1114,7 +1135,6 @@ class TestDiscussionImporter(TestCase):
 
         self.__check_posts_exceptions(importer, thread, _json, app)
 
-
         # Test with attachments attribute missing
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
@@ -1127,7 +1147,6 @@ class TestDiscussionImporter(TestCase):
 
         self.__check_posts_exceptions(importer, thread, _json, app)
 
-
         # Test with url of attachments attribute missing
         importer, app, thread, user, post = self.__init_add_posts_tests()
 
@@ -1146,11 +1165,11 @@ class TestDiscussionImporter(TestCase):
 
         self.__check_posts_exceptions(importer, thread, _json, app)
 
-
     def __check_posts_exceptions(self, importer, thread, posts, app):
         try:
             importer.add_posts(thread, posts, app)
-            self.fail("add_posts() didn't throw an exception even though attribute are missing")
+            self.fail("add_posts() didn't throw an "\
+                    + "exception even though attribute are missing")
         except:
             pass
 
@@ -1177,7 +1196,9 @@ class TestDiscussionImporter(TestCase):
         return importer, app, thread, user1, post
 
     def test_annotate_text_with_existing_user(self):
-        """ This test tests the annotate_text method if an existing user is passed as argument """
+        """ This test tests the annotate_text method if 
+            an existing user is passed as argument 
+        """
 
         importer = discussion.ForgeDiscussionImporter()
         
@@ -1188,9 +1209,10 @@ class TestDiscussionImporter(TestCase):
 
         self.assertEqual(importer.annotate_text('foo', user, username), 'foo')
 
-
     def test_annotate_text_with_not_existing_user(self):
-        """ This test tests the annotate_text method with a not existing user """
+        """ This test tests the annotate_text method 
+            with a not existing user
+        """
 
         importer = discussion.ForgeDiscussionImporter()
 
@@ -1203,10 +1225,13 @@ class TestDiscussionImporter(TestCase):
         text = 'foo'
 
         # Text that the method should return
-        return_text = '*Originally created by:* {username}\n\n{text}'.format(username=username, text=text)
-
-        self.assertEqual(importer.annotate_text(text, user, username), return_text)
+        return_text = '*Originally created by:* {username}\n\n{text}' \
+                .format(username=username, text=text)
 
+        self.assertEqual(
+                         importer.annotate_text(text, user, username),
+                         return_text
+                        )
 
     def test_annotate_text_with_anonymous_user(self):
         """ This test tests the annotate_text method with an anonymous user """
@@ -1221,12 +1246,19 @@ class TestDiscussionImporter(TestCase):
 
         text = 'foo'
 
-        self.assertEqual(importer.annotate_text(text, user, usernames[0]), text)
-        self.assertEqual(importer.annotate_text(text, user, usernames[1]), text)
-
+        self.assertEqual(
+                importer.annotate_text(text, user, usernames[0]),
+                text
+        )
+        self.assertEqual(
+                importer.annotate_text(text, user, usernames[1]),
+                text
+        )
         
     def test_annotate_text_with_unicode(self):
-        """ This method tests if annotate text can handle unicode characters """
+        """ This method tests if annotate text 
+            can handle unicode characters
+        """
 
         importer = discussion.ForgeDiscussionImporter()
 
@@ -1239,7 +1271,6 @@ class TestDiscussionImporter(TestCase):
         except:
             self.fail("annotate_text() can't handle unicode characters")
 
-
         # unicode in text of a not existing user
         text = "post with un\u00ef\u00e7\u00f8\u2202\u00e9"
         user = mock.Mock(is_anonymous=lambda: True)
@@ -1250,7 +1281,6 @@ class TestDiscussionImporter(TestCase):
         except:
             self.fail("annotate_text() can't handle unicode characters")
 
-
         # unicode in text of an anonymous user
         text = "post with un\u00ef\u00e7\u00f8\u2202\u00e9"
         user = mock.Mock(is_anonymous=lambda: True)
@@ -1261,9 +1291,10 @@ class TestDiscussionImporter(TestCase):
         except:
             self.fail("annotate_text() can't handle unicode characters")
 
-
     def test_annotate_text_with_junk(self):
-        """ This test tests if the annotate_text method correctly handles junk data """
+        """ This test tests if the annotate_text method
+            correctly handles junk data
+        """
 
         importer = discussion.ForgeDiscussionImporter()
 
@@ -1276,7 +1307,6 @@ class TestDiscussionImporter(TestCase):
         text = 'foo'
         self.assertEqual(importer.annotate_text(text, user, username), text)
 
-
     def __get_forum_dict(self, app, forum_json):
         new_forum = dict(
             app_config_id = app.config._id,
@@ -1292,7 +1322,6 @@ class TestDiscussionImporter(TestCase):
 
         return new_forum
 
-
     def __check_missing(self, project, user, importer, h, g, utils):
         try:       
             importer.import_tool(project, user, 'mount_point', 'mount_label')
@@ -1310,7 +1339,6 @@ class TestForgeDiscussionController(TestController, TestCase):
     
     def setUp(self):
         super(TestForgeDiscussionController, self).setUp()
-
     
     @with_discussion
     def test_index(self):
@@ -1319,27 +1347,31 @@ class TestForgeDiscussionController(TestController, TestCase):
         self.assertIsNotNone(r.html.find(attrs=dict(name="mount_label")))
         self.assertIsNotNone(r.html.find(attrs=dict(name="mount_point")))
 
-
     @with_discussion
     @mock.patch('forgeimporters.forge.discussion.save_importer_upload')
     @mock.patch('forgeimporters.base.import_tool')
     def test_create(self, import_tool, siu):
         project = M.Project.query.get(shortname='test')
         params = {
-            'discussions_json': webtest.Upload('discussions.json', b'{"key": "val"}'),
+            'discussions_json': webtest.Upload('discussions.json',
+                                               b'{"key": "val"}'),
             'mount_label': 'mylabel',
             'mount_point': 'mymount',
         }
-        r = self.app.post('/p/test/admin/ext/import/forge-discussion/create', params,
-                          status=302)
+        r = self.app.post('/p/test/admin/ext/import/forge-discussion/create',
+                          params,
+                          status=302
+                         )
         self.assertEqual(r.location, 'http://localhost/p/test/admin/')
-        siu.assert_called_once_with(project, 'discussions.json', '{"key": "val"}')
+        siu.assert_called_once_with(project,
+                                    'discussions.json',
+                                    '{"key": "val"}'
+                                    )
         self.assertEqual(
             'mymount', import_tool.post.call_args[1]['mount_point'])
         self.assertEqual(
             'mylabel', import_tool.post.call_args[1]['mount_label'])
 
-
     @with_discussion
     @mock.patch('forgeimporters.forge.discussion.save_importer_upload')
     @mock.patch('forgeimporters.base.import_tool')
@@ -1348,11 +1380,14 @@ class TestForgeDiscussionController(TestController, TestCase):
         project.set_tool_data('ForgeDiscussionImporter', pending=1)
         ThreadLocalORMSession.flush_all()
         params = {
-            'discussions_json': webtest.Upload('discussions.json', b'{"key": "val"}'),
+            'discussions_json': webtest.Upload('discussions.json',
+                                               b'{"key": "val"}'
+                                              ),
             'mount_label': 'mylabel',
             'mount_point': 'mymount',
         }
-        r = self.app.post('/p/test/admin/ext/import/forge-discussion/create', params,
+        r = self.app.post('/p/test/admin/ext/import/forge-discussion/create',
+                          params,
                           status=302).follow()
         self.assertIn('Please wait and try again', r)
         self.assertEqual(import_tool.post.call_count, 0)


[allura] 46/50: [#7935] Extracted load json method

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit bc760c86268a78118699eb2147ee2eb6f0e8f518
Author: Fahri <fa...@protonmail.ch>
AuthorDate: Fri Apr 10 16:02:25 2020 +0200

    [#7935] Extracted load json method
---
 ForgeImporters/forgeimporters/forge/alluraImporter.py | 14 ++++++++++++--
 ForgeImporters/forgeimporters/forge/discussion.py     |  7 +------
 ForgeImporters/forgeimporters/forge/tracker.py        |  7 +------
 3 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/alluraImporter.py b/ForgeImporters/forgeimporters/forge/alluraImporter.py
index 978e8bc..685447c 100644
--- a/ForgeImporters/forgeimporters/forge/alluraImporter.py
+++ b/ForgeImporters/forgeimporters/forge/alluraImporter.py
@@ -15,7 +15,13 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-from forgeimporters.base import ToolImporter
+import os
+import json
+
+from forgeimporters.base import (
+    ToolImporter,
+    get_importer_upload_path,
+)
 
 from allura import model as M   
 
@@ -45,4 +51,8 @@ class AlluraImporter(ToolImporter):
 
         return text
 
-
+    def _load_json_by_filename(self, project, filename):
+        upload_path = get_importer_upload_path(project)
+        full_path = os.path.join(upload_path, filename)
+        with open(full_path) as fp:
+            return json.load(fp)
diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 8b339c1..8192504 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -15,7 +15,6 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
-import os
 import json
 from dateutil.parser import parse
 
@@ -38,7 +37,6 @@ from forgeimporters.base import (
     ToolImportForm,
     ToolImportController,
     File,
-    get_importer_upload_path,
     save_importer_upload
 )
 
@@ -102,10 +100,7 @@ class ForgeDiscussionImporter(AlluraImporter):
         super(ForgeDiscussionImporter, self).__init__(*args, **kwargs)
 
     def _load_json(self, project):
-        upload_path = get_importer_upload_path(project)
-        full_path = os.path.join(upload_path, 'discussions.json')
-        with open(full_path) as fp:
-            return json.load(fp)
+        return self._load_json_by_filename(project, 'discussions.json')
 
     def import_tool(self, project, user, mount_point=None,
                      mount_label=None, **kw):
diff --git a/ForgeImporters/forgeimporters/forge/tracker.py b/ForgeImporters/forgeimporters/forge/tracker.py
index 07f9fa0..5716e50 100644
--- a/ForgeImporters/forgeimporters/forge/tracker.py
+++ b/ForgeImporters/forgeimporters/forge/tracker.py
@@ -17,7 +17,6 @@
 
 from __future__ import unicode_literals
 from __future__ import absolute_import
-import os
 import json
 
 import dateutil.parser
@@ -47,7 +46,6 @@ from forgeimporters.base import (
     ToolImportForm,
     ToolImportController,
     File,
-    get_importer_upload_path,
     save_importer_upload,
 )
 from forgeimporters.forge.alluraImporter import AlluraImporter
@@ -98,10 +96,7 @@ class ForgeTrackerImporter(AlluraImporter):
         self.max_ticket_num = 0
 
     def _load_json(self, project):
-        upload_path = get_importer_upload_path(project)
-        full_path = os.path.join(upload_path, 'tickets.json')
-        with open(full_path) as fp:
-            return json.load(fp)
+        return self._load_json_by_filename(project, 'tickets.json')
 
     def import_tool(self, project, user, mount_point=None,
                     mount_label=None, **kw):


[allura] 39/50: [#7935] Removed commented code

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 0460b756cdb997df9f1a05e75602e2bebb43e292
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Fri Mar 6 18:41:42 2020 +0100

    [#7935] Removed commented code
---
 ForgeImporters/forgeimporters/forge/discussion.py | 2 --
 1 file changed, 2 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 2976582..fdcabff 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -124,8 +124,6 @@ class ForgeDiscussionImporter(AlluraImporter):
                     new_forum = dict(
                                     app_config_id = app.config._id,
                                     shortname=forum_json['shortname'],
-                                    #discussion_id=forum_json.get('discussion_id', None),
-                                    #_id=forum_json.get('_id', None),
                                     description=forum_json['description'],
                                     name=forum_json['name'],
                                     create='on',


[allura] 11/50: [#7935] Added unicode support to filenames

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 19d69172a524ffa9fea8afadb71b5fefb3aba154
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Fri Feb 28 15:40:01 2020 +0100

    [#7935] Added unicode support to filenames
---
 ForgeImporters/forgeimporters/base.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index 7f2b36f..dfd8beb 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -27,6 +27,7 @@ import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 from collections import defaultdict
 import traceback
 from six.moves.urllib.parse import urlparse
+from urllib import unquote
 from datetime import datetime
 import codecs
 from six.moves import filter
@@ -628,7 +629,7 @@ class File(object):
     def __init__(self, url, filename=None):
         extractor = ProjectExtractor(None, url, parser=bytesio_parser)
         self.url = url
-        self.filename = filename or os.path.basename(urlparse(url).path)
+        self.filename = filename or unquote(os.path.basename(urlparse(url).path))
         # try to get the mime-type from the filename first, because
         # some files (e.g., attachements) may have the Content-Type header
         # forced to encourage the UA to download / save the file


[allura] 33/50: [#7935] Created tests for the controller

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 93600c127d2ab075f30cf043687a921b5bff720f
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Thu Mar 5 14:28:54 2020 +0100

    [#7935] Created tests for the controller
---
 .../forgeimporters/tests/forge/test_discussion.py  | 58 +++++++++++++++++++---
 1 file changed, 50 insertions(+), 8 deletions(-)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 020dadb..bb75321 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -22,9 +22,10 @@ import mock
 from dateutil.parser import parse
 
 from ming.odm import ThreadLocalORMSession
+import webtest
 
 from allura.tests import TestController
-from allura.tests.decorators import with_tracker
+from allura.tests.decorators import with_discussion
 
 from allura import model as M
 from forgeimporters.forge import discussion
@@ -214,7 +215,8 @@ class TestDiscussionImporter(TestCase):
             subject=post["subject"],
             text='aa',
             timestamp=parse(post["timestamp"]),
-            ignore_security=True
+            ignore_security=True,
+            parent_id=None
         )
         importer.annotate_text.assert_called_once_with(post["text"], admin, post["author"])
         p.add_multiple_attachments.assert_called_once_with([])
@@ -695,7 +697,8 @@ class TestDiscussionImporter(TestCase):
                 subject=_json[0]['subject'],
                 text='foo',
                 timestamp=parse(_json[0]['timestamp']),
-                ignore_security=True
+                ignore_security=True,
+                parent_id=None
         )
         post.add_multiple_attachments.assert_called_once_with([])
         
@@ -802,7 +805,8 @@ class TestDiscussionImporter(TestCase):
             subject=_json[0]['subject'],
             text=importer.annotate_text.return_value,
             timestamp=parse(_json[0]['timestamp']),
-            ignore_security=True
+            ignore_security=True,
+            parent_id=None
         )
         post.add_multiple_attachments.assert_called_once_with([])
         
@@ -1189,16 +1193,54 @@ class TestForgeDiscussionController(TestController, TestCase):
     
     def setUp(self):
         super(TestForgeDiscussionController, self).setUp()
-        from forgetracker.tracker_main import TrackerAdminController
-        TrackerAdminController._importer = \
+        from forgediscussion.forum_main import ForumAdminController
+        ForumAdminController._importer = \
                 discussion.ForgeDiscussionImportController(discussion.ForgeDiscussionImporter())
 
     
-    @with_tracker
+    @with_discussion
     def test_index(self):
-        r = self.app.get('/p/test/admin/bugs/_importer/')
+        r = self.app.get('/p/test/admin/ext/import/forge-discussion/')
         self.assertIsNotNone(r.html.find(attrs=dict(name="discussions_json")))
         self.assertIsNotNone(r.html.find(attrs=dict(name="mount_label")))
         self.assertIsNotNone(r.html.find(attrs=dict(name="mount_point")))
 
 
+    @with_discussion
+    @mock.patch('forgeimporters.forge.discussion.save_importer_upload')
+    @mock.patch('forgeimporters.base.import_tool')
+    def test_create(self, import_tool, siu):
+        project = M.Project.query.get(shortname='test')
+        params = {
+            'discussions_json': webtest.Upload('discussions.json', b'{"key": "val"}'),
+            'mount_label': 'mylabel',
+            'mount_point': 'mymount',
+        }
+        r = self.app.post('/p/test/admin/ext/import/forge-discussion/create', params,
+                          status=302)
+        self.assertEqual(r.location, 'http://localhost/p/test/admin/')
+        siu.assert_called_once_with(project, 'discussions.json', '{"key": "val"}')
+        self.assertEqual(
+            'mymount', import_tool.post.call_args[1]['mount_point'])
+        self.assertEqual(
+            'mylabel', import_tool.post.call_args[1]['mount_label'])
+
+
+    @with_discussion
+    @mock.patch('forgeimporters.forge.discussion.save_importer_upload')
+    @mock.patch('forgeimporters.base.import_tool')
+    def test_create_limit(self, import_tool, siu):
+        project = M.Project.query.get(shortname='test')
+        project.set_tool_data('ForgeDiscussionImporter', pending=1)
+        ThreadLocalORMSession.flush_all()
+        params = {
+            'discussions_json': webtest.Upload('discussions.json', b'{"key": "val"}'),
+            'mount_label': 'mylabel',
+            'mount_point': 'mymount',
+        }
+        r = self.app.post('/p/test/admin/ext/import/forge-discussion/create', params,
+                          status=302).follow()
+        self.assertIn('Please wait and try again', r)
+        self.assertEqual(import_tool.post.call_count, 0)
+
+


[allura] 45/50: [#7935] Fixed tabs so alluratest.test_syntax.test_no_tabs will pass

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit b9df3ac6358dac1460ec22b8de5e50ba6f7bfa95
Author: Fahri <fa...@protonmail.ch>
AuthorDate: Fri Apr 10 15:31:24 2020 +0200

    [#7935] Fixed tabs so alluratest.test_syntax.test_no_tabs will pass
---
 ForgeImporters/forgeimporters/forge/discussion.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 2d17d4e..8b339c1 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -115,8 +115,8 @@ class ForgeDiscussionImporter(AlluraImporter):
         mount_label = mount_label or 'Discussion'
 
         app = project.install_app('discussion', mount_point, mount_label, 
-			import_id={ 'source': self.source }
-		)
+            import_id={ 'source': self.source }
+        )
         ThreadLocalORMSession.flush_all()
 
         with h.push_config(c, app=app):


[allura] 25/50: [#7935] Added test for add_posts with unicode characters

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit a0080b6fd921b1e520b86047edcc8de129132180
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 17:53:51 2020 +0100

    [#7935] Added test for add_posts with unicode characters
---
 .../forgeimporters/tests/forge/test_discussion.py  | 32 ++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 2a615a9..5a73f72 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -771,6 +771,38 @@ class TestDiscussionImporter(TestCase):
         self.assertEqual(8, thread.add_post.call_count)
         self.assertEqual(8, post.add_multiple_attachments.call_count)
     
+
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'h')
+    def test_add_posts_with_unicode(self, h, c):
+        """ This method tests if it is possible to add posts which contain unicode characters in subject and text """
+
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+        importer.annotate_text.return_value = "test with un\u00ef\u00e7\u00f8\u2202\u00e9 text"
+
+        _json = [
+            {
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "test with un\u00ef\u00e7\u00f8\u2202\u00e9 text",
+                "subject": "post with un\u00ef\u00e7\u00f8\u2202\u00e9"
+            }
+        ]
+
+        importer.add_posts(thread, _json, app)
+
+        importer.get_user.assert_called_once()
+        h.push_config.assert_called_once()
+        thread.add_post.assert_called_once_with(
+            subject=_json[0]['subject'],
+            text=importer.annotate_text.return_value,
+            timestamp=parse(_json[0]['timestamp']),
+            ignore_security=True
+        )
+        post.add_multiple_attachments.assert_called_once_with([])
+        
+
     def __init_add_posts_tests(self):
         importer = discussion.ForgeDiscussionImporter()
 


[allura] 15/50: [#7935] Changed method name to fit naming convention

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit cc6cba9e974de65e27d6f1da1c660ef0667db31f
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Mon Mar 2 12:01:50 2020 +0100

    [#7935] Changed method name to fit naming convention
---
 ForgeImporters/forgeimporters/forge/discussion.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 94924f0..ffeec7c 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -178,7 +178,7 @@ class ForgeDiscussionImporter(AlluraImporter):
           forum.delete()
 
 
-    def annotateText(self, text, user, username):
+    def annotate_text(self, text, user, username):
         label = " created"
         
         return self.annotate(text, user, username, label)
@@ -193,7 +193,7 @@ class ForgeDiscussionImporter(AlluraImporter):
             with h.push_config(c, user=user, app=app):
                 p = thread.add_post(
                         subject=post_json['subject'],
-                        text=self.annotateText(post_json['text'], user, username),
+                        text=self.annotate_text(post_json['text'], user, username),
                         timestamp=parse(post_json["timestamp"]),
                         ignore_security=True
                 )


[allura] 38/50: [#7935] Removed debug code

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit d8642917c026a1f15c4ff4019fd718feda4a5f5f
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Thu Mar 5 17:52:06 2020 +0100

    [#7935] Removed debug code
---
 ForgeImporters/forgeimporters/forge/discussion.py | 21 ---------------------
 1 file changed, 21 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 8efb754..2976582 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -69,8 +69,6 @@ class ForgeDiscussionImportController(ToolImportController):
     @expose()
     @require_post()
     def create(self, discussions_json, mount_point, mount_label, **kw):
-        # TODO: delete debug output
-        #self.importer.clear_pending(c.project) # TODO: Delete this line
         if self.importer.enforce_limit(c.project):
             save_importer_upload(c.project, 'discussions.json', json.dumps(discussions_json))
             self.importer.post(mount_point=mount_point, mount_label=mount_label)
@@ -123,8 +121,6 @@ class ForgeDiscussionImporter(AlluraImporter):
 
                 for forum_json in discussion_json['forums']:
 
-                    print("forum_json: ", forum_json)
-
                     new_forum = dict(
                                     app_config_id = app.config._id,
                                     shortname=forum_json['shortname'],
@@ -139,36 +135,23 @@ class ForgeDiscussionImporter(AlluraImporter):
                                     monitoring_email=None,
                     )
 
-                    print("New Forum:", new_forum)
-
                     forum = utils.create_forum(app, new_forum=new_forum)
                     
                     if "import_id" in forum_json.keys():
-                        print("Import id for forum: " + forum_json["import_id"])
                         forum.import_id = forum_json["import_id"]
 
-                        print("Forum: " + str(forum))
-                        print("Forum import id: " + str(forum.import_id))
-
                     for thread_json in forum_json["threads"]:
                         thread = forum.get_discussion_thread(dict(
                                             headers=dict(Subject=thread_json['subject'])))[0]
 
-                        #if "_id" in thread_json:
-                        #    thread._id = thread_json["_id"]
                         if "import_id" in thread_json:
                             thread.import_id = thread_json["import_id"]
-                        #if "discussion_id" in thread_json:
-                        #    thread.discussion_id = thread_json["discussion_id"]
-
-                        print("Thread: " + str(thread))
 
                         self.add_posts(thread, thread_json['posts'], app)
 
                     session(forum).flush(forum)
                     session(forum).expunge(forum)
 
-                    print("Forum '%s' created" % (new_forum["shortname"]))
 
                 M.AuditLog.log(
                     "import tool %s from exported Allura JSON" % (
@@ -221,12 +204,9 @@ class ForgeDiscussionImporter(AlluraImporter):
                         pos = slug.rindex('/')
                         parent_slug = slug[:pos]
 
-                        print("Parent slug: " + parent_slug)
-                        
                         for cp in created_posts:
                             if cp.get(parent_slug, None) != None:
                                 parent_id = cp[parent_slug]._id
-                                print("Parent_id found")
                                 break
 
                 p = thread.add_post(
@@ -238,7 +218,6 @@ class ForgeDiscussionImporter(AlluraImporter):
                 )
 
                 if "last_edited" in post_json and post_json["last_edited"] != None:
-                    print("Last edited: " + str(post_json["last_edited"]))
                     p.last_edit_date = parse(post_json["last_edited"])
 
                 p.add_multiple_attachments([File(a["url"]) for a in post_json["attachments"]])


[allura] 24/50: [#7935] Added test for add_posts with many posts

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit bf5f5ea55db3b683382a63515b7f46a3aefb2235
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 17:38:45 2020 +0100

    [#7935] Added test for add_posts with many posts
---
 .../forgeimporters/tests/forge/test_discussion.py  | 75 ++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 535bc1c..2a615a9 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -696,6 +696,81 @@ class TestDiscussionImporter(TestCase):
         post.add_multiple_attachments.assert_called_once_with([])
         
     
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'h')
+    def test_add_posts_with_many_posts(self, h, c):
+        """ This methods tests if many posts of a thread are added to this thread """
+
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+
+        _json = [
+            {
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "foo0",
+                "subject": "Foo subject"
+            },
+            {
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "foo1",
+                "subject": "Foo subject"
+            },
+            {
+
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "foo2",
+                "subject": "Foo subject"
+            },
+            {
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "foo3",
+                "subject": "Foo subject"
+            },
+            {
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "foo4",
+                "subject": "Foo subject"
+            },
+            {
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "foo5",
+                "subject": "Foo subject"
+            },
+            {
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "foo6",
+                "subject": "Foo subject"
+            },
+            {
+                "attachments": [],
+                "author": "admin1",
+                "timestamp": "2020-01-29 22:30:42.497000",
+                "text": "foo7",
+                "subject": "Foo subject"
+            }
+        ]
+
+        
+        importer.add_posts(thread, _json, app)
+
+        self.assertEqual(8, importer.get_user.call_count)
+        self.assertEqual(8, h.push_config.call_count)
+        self.assertEqual(8, thread.add_post.call_count)
+        self.assertEqual(8, post.add_multiple_attachments.call_count)
+    
     def __init_add_posts_tests(self):
         importer = discussion.ForgeDiscussionImporter()
 


[allura] 10/50: [#7935] Clean up work

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit a733a89eff1a2894ff51d57a6377eb27d6f48999
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Fri Feb 28 11:24:56 2020 +0100

    [#7935] Clean up work
---
 ForgeImporters/forgeimporters/forge/discussion.py | 72 ++++++++++++++++-------
 1 file changed, 50 insertions(+), 22 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 7b78f32..be575b6 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -76,35 +76,36 @@ class ForgeDiscussionImporter(ToolImporter):
     tool_label = 'Discussion'
     tool_description = 'Import an allura discussion.'
 
+
     def __init__(self, *args, **kwargs):
         super(ForgeDiscussionImporter, self).__init__(*args, **kwargs)
 
+
     def _load_json(self, project):
         upload_path = get_importer_upload_path(project)
         full_path = os.path.join(upload_path, 'discussion.json')
         with open(full_path) as fp:
             return json.load(fp)
 
+
     def import_tool(self, project, user, mount_point=None,
                      mount_label=None, **kw):
         
-		print("import_tool")
-		discussion_json = self._load_json(project)
+        print("import_tool")
+        discussion_json = self._load_json(project)
 
-		mount_point = mount_point or 'discussion'
-		mount_label = mount_label or 'Discussion'
+        mount_point = mount_point or 'discussion'
+        mount_label = mount_label or 'Discussion'
 
-		app = project.install_app('discussion', mount_point, mount_label, 
+        app = project.install_app('discussion', mount_point, mount_label, 
 			import_id={ 'source': self.source }
 		)
-		ThreadLocalORMSession.flush_all()
+        ThreadLocalORMSession.flush_all()
 
         with h.push_config(c, app=app):
 
             # Deleting the forums that are created by default
-            forums = app.forums
-            for forum in forums:
-                forum.delete()
+            self.__clear_forums(app)
            
             try:
                 M.session.artifact_orm_session._get().skip_mod_date = True
@@ -116,8 +117,8 @@ class ForgeDiscussionImporter(ToolImporter):
                     new_forum = dict(
                                     app_config_id = app.config._id,
                                     shortname=forum_json['shortname'],
-                                    discussion_id=forum_json.get('discussion_id', None),
-                                    _id=forum_json.get('_id', None),
+                                    #discussion_id=forum_json.get('discussion_id', None),
+                                    #_id=forum_json.get('_id', None),
                                     description=forum_json['description'],
                                     name=forum_json['name'],
                                     create='on',
@@ -135,23 +136,47 @@ class ForgeDiscussionImporter(ToolImporter):
                         thread = forum.get_discussion_thread(dict(
                                             headers=dict(Subject=thread_json['subject'])))[0]
 
+                        #if "_id" in thread_json:
+                        #    thread._id = thread_json["_id"]
+                        if "import_id" in thread_json:
+                            thread.import_id = thread_json["import_id"]
+                        #if "discussion_id" in thread_json:
+                        #    thread.discussion_id = thread_json["discussion_id"]
+
+                        print("Thread: " + str(thread))
+
                         self.add_posts(thread, thread_json['posts'], app)
 
                     session(forum).flush(forum)
                     session(forum).expunge(forum)
 
-                    print("Forum %s created" % (new_forum["shortname"]))
+                    print("Forum '%s' created" % (new_forum["shortname"]))
 
-			g.post_event('project_updated')
-			ThreadLocalORMSession.flush_all()
-			return app
-		except Exception:
-			h.make_app_admin_only(app)
-			raise
-		finally:
-			M.session.artifact_orm_session._get().skip_mod_date = False
+                M.AuditLog.log(
+                    "import tool %s from exported Allura JSON" % (
+                        app.config.options.mount_point,
+                    ),
+                    project=project,
+                    user=user,
+                    url=app.url,
+                )
+
+                g.post_event('project_updated')
+                ThreadLocalORMSession.flush_all()
+                return app
+            except Exception:
+                h.make_app_admin_only(app)
+                raise
+            finally:
+                M.session.artifact_orm_session._get().skip_mod_date = False
                                      
 
+    def __clear_forums(self, app):
+      forums = app.forums
+      for forum in forums:
+          forum.delete()
+
+
     def get_user(self, username):
         if username is None:
             return M.User.anonymous()
@@ -178,12 +203,15 @@ class ForgeDiscussionImporter(ToolImporter):
                         subject=post_json['subject'],
                         text=post_json['text'], 
                         ignore_security=True,
-                        timestamp=parse(post_json['timestamp']),
-                        last_edited=post_json['last_edited']
                 )
 
                 if "slug" in post_json.keys():
                     p.slug = post_json['slug']
+                if "last_edited" in post_json and post_json["last_edited"] != None:
+                    print("Last edited: " + str(post_json["last_edited"]))
+                    p.last_edit_date = parse(post_json["last_edited"])
+                if "timestamp" in post_json:
+                    p.timestamp = parse(post_json["timestamp"])
 
                 try:
                     p.add_multiple_attachments([File(a['url'])


[allura] 43/50: [#7935] Added license header

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 3f3174d760ab1c0b18147b5956160083965c9bf6
Author: Fahri <fa...@protonmail.ch>
AuthorDate: Fri Apr 10 15:01:26 2020 +0200

    [#7935] Added license header
---
 ForgeImporters/forgeimporters/forge/alluraImporter.py  | 17 +++++++++++++++++
 .../forge/templates/discussion/index.html              | 18 ++++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/ForgeImporters/forgeimporters/forge/alluraImporter.py b/ForgeImporters/forgeimporters/forge/alluraImporter.py
index 059f88e..978e8bc 100644
--- a/ForgeImporters/forgeimporters/forge/alluraImporter.py
+++ b/ForgeImporters/forgeimporters/forge/alluraImporter.py
@@ -1,3 +1,20 @@
+#       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.
+
 from forgeimporters.base import ToolImporter
 
 from allura import model as M   
diff --git a/ForgeImporters/forgeimporters/forge/templates/discussion/index.html b/ForgeImporters/forgeimporters/forge/templates/discussion/index.html
index 682cf73..d046eb1 100644
--- a/ForgeImporters/forgeimporters/forge/templates/discussion/index.html
+++ b/ForgeImporters/forgeimporters/forge/templates/discussion/index.html
@@ -1,3 +1,21 @@
+{#-
+    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.
+-#}
 {% extends 'forgeimporters:templates/importer_base.html' %}
 
 {% block importer_fields %}


[allura] 05/50: [#7935] Fixed errors

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 90f5f0b4a2c4f96fd066f6cf544d73bfafdac41f
Author: Korkmatik <fa...@protonmail.ch>
AuthorDate: Sat Jan 18 12:04:24 2020 +0100

    [#7935] Fixed errors
---
 ForgeImporters/forgeimporters/forge/discussion.py | 29 +++++++++--------------
 1 file changed, 11 insertions(+), 18 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index ce81b43..7ac5831 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -3,6 +3,7 @@ import json
 from dateutil.parser import parse
 
 from tg import tmpl_context as c
+from tg import app_globals as g
 from ming.orm import session, ThreadLocalORMSession
 
 from tg import (
@@ -29,6 +30,7 @@ from allura import model as M
 from allura.lib.decorators import require_post
 from allura.lib import validators as v 
 from allura.lib import helpers as h
+from allura.lib.plugin import ImportIdConverter
 
 from forgediscussion import utils, import_support
 from forgediscussion import model as DM
@@ -89,27 +91,19 @@ class ForgeDiscussionImporter(ToolImporter):
 		print("import_tool")
 		import_id_converter = ImportIdConverter.get()
 		discussion_json = self._load_json(project)
-		discussion_json['discussion_config']['options'].pop('ordinal', None)
-		discussion_json['discussion_config']['options'].pop('mount_point', None)
-		discussion_json['discussion_config']['options'].pop('mount_label', None)
-		discussion_json['discussion_config']['options'].pop('import_id', None)
+		#discussion_json['discussion_config']['options'].pop('ordinal', None)
+		#discussion_json['discussion_config']['options'].pop('mount_point', None)
+		#discussion_json['discussion_config']['options'].pop('mount_label', None)
+		#discussion_json['discussion_config']['options'].pop('import_id', None)
 
 		mount_point = mount_point or 'discussion'
 		mount_label = mount_label or 'Discussion'
 
-		_id = discussions_json['discussion_config'].get('_id', 'undefined')
-		_open_status_names = discussions_json.get('open_status_names', 'undefined')
-		_closed_status_names = discussions_json.get('closed_status_names', 'undefined')
-
-		app = project.install_app('discussion', mount_point, mount_label,
-                    import_id={
-                        'source': self.source, 
-                        'app_config_id': _id 
-                    },
-					open_status_names=_open_status_names,
-					closed_status_names=_closed_status_names,
-					**discussion_json['discussion_config']['options']
-		)
+		#_id = discussion_json['discussion_config'].get('_id', 'undefined')
+		#_open_status_names = discussion_json.get('open_status_names', 'undefined')
+		#_closed_status_names = discussion_json.get('closed_status_names', 'undefined')
+
+		app = project.install_app('discussion', mount_point, mount_label)
 		ThreadLocalORMSession.flush_all()
        
 		try:
@@ -148,7 +142,6 @@ class ForgeDiscussionImporter(ToolImporter):
 				print("Forum %s created" % (new_forum["shortname"]))
 
 			g.post_event('project_updated')
-			app.globals.invalidate_bin_counts()
 			ThreadLocalORMSession.flush_all()
 			return app
 		except Exception:


[allura] 49/50: [#7935] Ran python-modernize

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 54f0e3f3669b04e03b9aeada9f725200fbb901a3
Author: Korkmatik <fa...@protonmail.ch>
AuthorDate: Sat Apr 11 00:16:47 2020 +0200

    [#7935] Ran python-modernize
---
 ForgeImporters/forgeimporters/base.py                        | 2 +-
 ForgeImporters/forgeimporters/forge/alluraImporter.py        | 1 +
 ForgeImporters/forgeimporters/forge/discussion.py            | 5 +++--
 ForgeImporters/forgeimporters/tests/forge/test_discussion.py | 2 ++
 4 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index e394212..7e87cc1 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -27,7 +27,7 @@ import six.moves.urllib.request, six.moves.urllib.error, six.moves.urllib.parse
 from collections import defaultdict
 import traceback
 from six.moves.urllib.parse import urlparse
-from urllib import unquote
+from six.moves.urllib.parse import unquote
 from datetime import datetime
 import codecs
 from six.moves import filter
diff --git a/ForgeImporters/forgeimporters/forge/alluraImporter.py b/ForgeImporters/forgeimporters/forge/alluraImporter.py
index d3a8c9b..fea422c 100644
--- a/ForgeImporters/forgeimporters/forge/alluraImporter.py
+++ b/ForgeImporters/forgeimporters/forge/alluraImporter.py
@@ -15,6 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+from __future__ import absolute_import
 import os
 import json
 
diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 5167648..7dc7b1c 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -15,6 +15,7 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+from __future__ import absolute_import
 import json
 from dateutil.parser import parse
 
@@ -138,7 +139,7 @@ class ForgeDiscussionImporter(AlluraImporter):
 
                     forum = utils.create_forum(app, new_forum=new_forum)
                     
-                    if "import_id" in forum_json.keys():
+                    if "import_id" in list(forum_json.keys()):
                         forum.import_id = forum_json["import_id"]
 
                     for thread_json in forum_json["threads"]:
@@ -197,7 +198,7 @@ class ForgeDiscussionImporter(AlluraImporter):
                 # For nested posts
                 parent_id = None
                 slug = ''
-                if "slug" in post_json.keys():
+                if "slug" in list(post_json.keys()):
                     slug = post_json["slug"]
 
                     if slug.count('/') >= 1:
diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 2cbc5c7..694601a 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -15,6 +15,8 @@
 #       specific language governing permissions and limitations
 #       under the License.
 
+from __future__ import absolute_import
+from __future__ import print_function
 from unittest import TestCase
 import mock
 


[allura] 14/50: [#7935] Refactored annotate and get_user method

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit d0442521eed5c64f438dffbb131927861464c445
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Fri Feb 28 19:19:28 2020 +0100

    [#7935] Refactored annotate and get_user  method
---
 .../forgeimporters/forge/alluraImporter.py         | 19 ++++++++++++++++
 ForgeImporters/forgeimporters/forge/discussion.py  | 26 ++++++----------------
 2 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/alluraImporter.py b/ForgeImporters/forgeimporters/forge/alluraImporter.py
new file mode 100644
index 0000000..bc9329f
--- /dev/null
+++ b/ForgeImporters/forgeimporters/forge/alluraImporter.py
@@ -0,0 +1,19 @@
+from forgeimporters.base import ToolImporter
+
+from allura import model as M   
+
+
+class AlluraImporter(ToolImporter):
+
+    def get_user(self, username):
+        if username is None:
+            return M.User.anonymous()
+        user = M.User.by_username(username)
+        if not user:
+            user = M.User.anonymous()
+        return user
+
+    def annotate(self, text, user, username, label=''):
+        if username and user.is_anonymous() and username != 'nobody' and username != '*anonymous':
+            return '*Originally%s by:* %s\n\n%s' % (label, username, text)
+        return text
diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 2078a87..94924f0 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -21,7 +21,6 @@ from forgeimporters.base import (
     ToolImportForm,
     ToolImportController,
     File,
-    ToolImporter,
     get_importer_upload_path,
     save_importer_upload
 )
@@ -35,6 +34,7 @@ from allura.lib.plugin import ImportIdConverter
 from forgediscussion import utils, import_support
 from forgediscussion import model as DM
 
+from alluraImporter import AlluraImporter
 
 class ForgeDiscussionImportForm(ToolImportForm):
     discussions_json = v.JsonFile(not_empty=True)
@@ -70,7 +70,7 @@ class ForgeDiscussionImportController(ToolImportController):
         redirect(c.project.url() + 'admin/')
 
 
-class ForgeDiscussionImporter(ToolImporter):
+class ForgeDiscussionImporter(AlluraImporter):
     source = 'Allura'
     target_app_ep_names = 'discussion'
     controller = ForgeDiscussionImportController
@@ -178,22 +178,10 @@ class ForgeDiscussionImporter(ToolImporter):
           forum.delete()
 
 
-    def get_user(self, username):
-        if username is None:
-            return M.User.anonymous()
-        user = M.User.by_username(username)
-        if not user:
-            print("No user with " + str(username) +  " found! (" + str(user) + ")")
-            user = M.User.anonymous()
-        return user
-
-
-    def annotate(self, text, user, username):
-        if username and user.is_anonymous() and username != 'nobody' and username != '*anonymous':
-            label = " created"
-
-            return '*Originally%s by:* %s\n\n%s' % (label, username, text)
-        return text
+    def annotateText(self, text, user, username):
+        label = " created"
+        
+        return self.annotate(text, user, username, label)
 
 
     def add_posts(self, thread, posts, app):
@@ -205,7 +193,7 @@ class ForgeDiscussionImporter(ToolImporter):
             with h.push_config(c, user=user, app=app):
                 p = thread.add_post(
                         subject=post_json['subject'],
-                        text=self.annotate(post_json['text'], user, username),
+                        text=self.annotateText(post_json['text'], user, username),
                         timestamp=parse(post_json["timestamp"]),
                         ignore_security=True
                 )


[allura] 28/50: [#7935] Added test for missing keys

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit c1ce0cacb3df75c7be23f9b35324d47139a4a724
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 18:54:24 2020 +0100

    [#7935] Added test for missing keys
---
 .../forgeimporters/tests/forge/test_discussion.py  | 98 ++++++++++++++++++++++
 1 file changed, 98 insertions(+)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 5cea6ab..5955ab5 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -932,6 +932,104 @@ class TestDiscussionImporter(TestCase):
             mock.call('http://www.foo.com/attachment2')
         ])
 
+
+    @mock.patch.object(discussion, 'File')
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'h')
+    def test_add_posts_with_missing_keys(self, h, c, File):
+        """ This method checks if add_posts will throw an error if required keys are missing """
+        
+        # Test with author attribute missing
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+
+        _json = {
+            "subject": "foo",
+            "text": "foo",
+            "timestamp": "2020-01-29 22:42:58.478000",
+            "attachments": []
+        }
+
+        self.__check_posts_exceptions(importer, thread, _json, app)
+
+
+        # Test with subject attribute missing
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+
+        _json = {
+            "author": "admin1",
+            "text": "foo",
+            "timestamp": "2020-01-29 22:42:58.478000",
+            "attachments": []
+        }
+
+        self.__check_posts_exceptions(importer, thread, _json, app)
+
+
+        # Test with text attribute missing
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+
+        _json = {
+            "author": "admin1",
+            "timestamp": "2020-01-29 22:42:58.478000",
+            "subject": "foo",
+            "attachments": []
+        }
+
+        self.__check_posts_exceptions(importer, thread, _json, app)
+
+
+        # Test with timestamp attribute missing
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+
+        _json = {
+            "author": "admin1",
+            "text": "foo",
+            "subject": "foo",
+            "attachments": []
+        }
+
+        self.__check_posts_exceptions(importer, thread, _json, app)
+
+
+        # Test with attachments attribute missing
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+
+        _json = {
+            "author": "admin1",
+            "text": "foo",
+            "subject": "foo",
+            "timestamp": "2020-01-29 22:42:58.478000"
+        }
+
+        self.__check_posts_exceptions(importer, thread, _json, app)
+
+
+        # Test with url of attachments attribute missing
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+
+        _json = {
+            "author": "admin1",
+            "text": "foo",
+            "subject": "foo",
+            "timestamp": "2020-01-29 22:42:58.478000",
+            "attachments": [
+                {
+                    "byte": 147,
+                    "path": "path/to/attachment"
+                }
+            ]
+        }
+
+        self.__check_posts_exceptions(importer, thread, _json, app)
+
+
+    def __check_posts_exceptions(self, importer, thread, posts, app):
+        try:
+            importer.add_posts(thread, posts, app)
+            self.fail("add_posts() didn't throw an exception even though attribute are missing")
+        except:
+            pass
+
     def __init_add_posts_tests(self):
         importer = discussion.ForgeDiscussionImporter()
 


[allura] 47/50: [#7935] Fixed wrong comparisons with None

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 33aac16e3eec01087244a3fad6bdf28ba3995540
Author: Korkmatik <fa...@protonmail.ch>
AuthorDate: Sat Apr 11 00:04:40 2020 +0200

    [#7935] Fixed wrong comparisons with None
---
 ForgeImporters/forgeimporters/forge/alluraImporter.py | 8 ++++----
 ForgeImporters/forgeimporters/forge/discussion.py     | 6 ++----
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/alluraImporter.py b/ForgeImporters/forgeimporters/forge/alluraImporter.py
index 685447c..d3a8c9b 100644
--- a/ForgeImporters/forgeimporters/forge/alluraImporter.py
+++ b/ForgeImporters/forgeimporters/forge/alluraImporter.py
@@ -38,15 +38,15 @@ class AlluraImporter(ToolImporter):
         return user
 
     def annotate(self, text, user, username, label=''):
-        if  username != "" \
-            and username != None \
-            and user != None \
+        if  username is not None \
+            and user is not None \
             and user.is_anonymous() \
+            and username != "" \
             and username != 'nobody' \
             and username != '*anonymous':
             return '*Originally%s by:* %s\n\n%s' % (label, username, text)
 
-        if text == None:
+        if text is None:
             text = ""
 
         return text
diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 8192504..5167648 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -205,7 +205,7 @@ class ForgeDiscussionImporter(AlluraImporter):
                         parent_slug = slug[:pos]
 
                         for cp in created_posts:
-                            if cp.get(parent_slug, None) != None:
+                            if cp.get(parent_slug, None) is not None:
                                 parent_id = cp[parent_slug]._id
                                 break
 
@@ -221,7 +221,7 @@ class ForgeDiscussionImporter(AlluraImporter):
                 )
 
                 if ("last_edited" in post_json) \
-                    and (post_json["last_edited"] != None):
+                    and (post_json["last_edited"] is not None):
                     p.last_edit_date = parse(post_json["last_edited"])
 
                 p.add_multiple_attachments(
@@ -230,5 +230,3 @@ class ForgeDiscussionImporter(AlluraImporter):
 
                 if slug != '': 
                     created_posts.append({ slug: p })
-
-


[allura] 08/50: [#7935] Cleaned up

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit e9098d2e47115d64eb043f4cf7f2f7733a5cdfad
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Thu Feb 27 12:37:35 2020 +0100

    [#7935] Cleaned up
---
 ForgeImporters/forgeimporters/forge/discussion.py | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index fb3bd74..0d256cb 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -89,7 +89,6 @@ class ForgeDiscussionImporter(ToolImporter):
                      mount_label=None, **kw):
         
 		print("import_tool")
-		import_id_converter = ImportIdConverter.get()
 		discussion_json = self._load_json(project)
 
 		mount_point = mount_point or 'discussion'
@@ -156,15 +155,17 @@ class ForgeDiscussionImporter(ToolImporter):
             return M.User.anonymous()
         user = M.User.by_username(username)
         if not user:
-            print("No user with ", username, "found! (",user,")")
+            print("No user with " + str(username) +  " found! (" + str(user) + ")")
             user = M.User.anonymous()
         return user
 
+
     def annotate(self, text, user, username, label=''):
         if username and user.is_anonymous() and username != 'nobody':
             return '*Originally%s by:* %s\n\n%s' % (label, username, text)
         return text
 
+
     def add_posts(self, thread, posts, app):
         for post_json in posts:
             print("Author: ", post_json["author"])
@@ -188,5 +189,3 @@ class ForgeDiscussionImporter(ToolImporter):
                 except:
                     print("Could not add attachemtns to post")
 
-    def process_bins(self, app, bins):
-        pass 


[allura] 16/50: [#7935] Improved error handling of annotate method

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit a96feb9fcb24d786a46a9a9e8fe1e887f40b8942
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Mon Mar 2 12:32:18 2020 +0100

    [#7935] Improved error handling of annotate method
---
 ForgeImporters/forgeimporters/forge/alluraImporter.py | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/ForgeImporters/forgeimporters/forge/alluraImporter.py b/ForgeImporters/forgeimporters/forge/alluraImporter.py
index bc9329f..a0a8670 100644
--- a/ForgeImporters/forgeimporters/forge/alluraImporter.py
+++ b/ForgeImporters/forgeimporters/forge/alluraImporter.py
@@ -14,6 +14,10 @@ class AlluraImporter(ToolImporter):
         return user
 
     def annotate(self, text, user, username, label=''):
-        if username and user.is_anonymous() and username != 'nobody' and username != '*anonymous':
+        if username != "" and username != None and user != None and user.is_anonymous() and username != 'nobody' and username != '*anonymous':
             return '*Originally%s by:* %s\n\n%s' % (label, username, text)
+
+        if text == None:
+            text = ""
+
         return text


[allura] 50/50: [#7935] Fixed comparisons with None

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit d6934789cd6c1a4b483d6f8c238bbae66026a945
Author: Korkmatik <fa...@protonmail.ch>
AuthorDate: Sat Apr 11 00:37:01 2020 +0200

    [#7935] Fixed comparisons with None
---
 ForgeImporters/forgeimporters/base.py                 | 8 ++++----
 ForgeImporters/forgeimporters/forge/alluraImporter.py | 2 +-
 ForgeImporters/forgeimporters/github/utils.py         | 2 +-
 ForgeImporters/forgeimporters/github/wiki.py          | 2 +-
 ForgeImporters/forgeimporters/tests/test_base.py      | 2 +-
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index 7e87cc1..ab18bb4 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -200,7 +200,7 @@ class ProjectExtractor(object):
         if self.url in self._page_cache:
             self.page = self._page_cache[self.url]
         else:
-            if parser == None:
+            if parser is None:
                 parser = self.parse_page
             self.page = self._page_cache[self.url] = \
                 parser(self.urlopen(self.url))
@@ -350,7 +350,7 @@ class ToolImportControllerMeta(type):
         the appropriate App for this controller's importer.
 
         """
-        if hasattr(cls, 'create') and getattr(cls.create.decoration, 'validation', None) == None:
+        if hasattr(cls, 'create') and getattr(cls.create.decoration, 'validation', None) is None:
             cls.create = validate(cls.import_form(aslist(importer.target_app)[0]),
                     error_handler=cls.index.__func__)(cls.create)
         return type.__call__(cls, importer, *args, **kw)
@@ -481,7 +481,7 @@ class ToolImporter(six.with_metaclass(ToolImporterMeta, object)):
             update={'$inc': {pending_key: 1}},
             new=True,
         )
-        return modified_project != None
+        return modified_project is not None
 
     def clear_pending(self, project):
         """
@@ -562,7 +562,7 @@ class ToolsValidator(fev.Set):
         invalid = []
         for name in value:
             importer = ToolImporter.by_name(name)
-            if importer != None and importer.source == self.source:
+            if importer is not None and importer.source == self.source:
                 valid.append(name)
             else:
                 invalid.append(name)
diff --git a/ForgeImporters/forgeimporters/forge/alluraImporter.py b/ForgeImporters/forgeimporters/forge/alluraImporter.py
index fea422c..242d6df 100644
--- a/ForgeImporters/forgeimporters/forge/alluraImporter.py
+++ b/ForgeImporters/forgeimporters/forge/alluraImporter.py
@@ -31,7 +31,7 @@ class AlluraImporter(ToolImporter):
 
 
     def get_user(self, username):
-        if username == None:
+        if username is None:
             return M.User.anonymous()
         user = M.User.by_username(username)
         if not user:
diff --git a/ForgeImporters/forgeimporters/github/utils.py b/ForgeImporters/forgeimporters/github/utils.py
index 8383de9..23cb010 100644
--- a/ForgeImporters/forgeimporters/github/utils.py
+++ b/ForgeImporters/forgeimporters/github/utils.py
@@ -28,7 +28,7 @@ class GitHubMarkdownConverter(object):
         self.code_patterns = ['```', '~~~']
 
     def convert(self, text):
-        if text == None:
+        if text is None:
             return ''
         lines = self._parse_lines(text.split('\n'))
         return '\n'.join(lines)
diff --git a/ForgeImporters/forgeimporters/github/wiki.py b/ForgeImporters/forgeimporters/github/wiki.py
index d863ef5..d96a3c1 100644
--- a/ForgeImporters/forgeimporters/github/wiki.py
+++ b/ForgeImporters/forgeimporters/github/wiki.py
@@ -407,7 +407,7 @@ class GitHubWikiImporter(ToolImporter):
             idx = [p.lower() for p in self.available_pages].index(page.lower())
         except ValueError:
             idx = None
-        if idx != None:
+        if idx is not None:
             page = self.available_pages[idx]
 
         if title:
diff --git a/ForgeImporters/forgeimporters/tests/test_base.py b/ForgeImporters/forgeimporters/tests/test_base.py
index 4f82b17..f23ee8f 100644
--- a/ForgeImporters/forgeimporters/tests/test_base.py
+++ b/ForgeImporters/forgeimporters/tests/test_base.py
@@ -106,7 +106,7 @@ def test_import_tool_failed(g, ToolImporter, format_exc):
 def ep(name, source=None, importer=None, **kw):
     mep = mock.Mock(name='mock_ep', **kw)
     mep.name = name
-    if importer != None:
+    if importer is not None:
         mep.load.return_value = importer
     else:
         mep.load.return_value.source = source


[allura] 31/50: [#7935] Added support for nested posts

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 81c50347c190c1f349b16254276222d030ec7f71
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Thu Mar 5 10:52:53 2020 +0100

    [#7935] Added support for nested posts
---
 ForgeImporters/forgeimporters/forge/discussion.py | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 3e885bd..01336bf 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -190,17 +190,33 @@ class ForgeDiscussionImporter(AlluraImporter):
 
 
     def add_posts(self, thread, posts, app):
+        prev = None
+        number_slashes = 0
+
         for post_json in posts:
             username = post_json["author"]
             print("Author: " + str(username))
             user = self.get_user(username)
             print("User: " + str(user))
             with h.push_config(c, user=user, app=app):
+                timestamp = parse(post_json['timestamp'])
+
+                # For nested posts
+                parent_id = None
+                if prev != None and "slug" in post_json.keys():
+                    count = post_json["slug"].count('/')
+                   
+                    if number_slashes < count:
+                        parent_id = prev._id
+                    
+                    number_slashes = count
+
                 p = thread.add_post(
                         subject=post_json['subject'],
                         text=self.annotate_text(post_json['text'], user, username),
-                        timestamp=parse(post_json["timestamp"]),
-                        ignore_security=True
+                        timestamp=timestamp,
+                        ignore_security=True,
+                        parent_id=parent_id
                 )
 
                 if "last_edited" in post_json and post_json["last_edited"] != None:
@@ -209,3 +225,5 @@ class ForgeDiscussionImporter(AlluraImporter):
 
                 p.add_multiple_attachments([File(a["url"]) for a in post_json["attachments"]])
 
+                prev = p
+


[allura] 22/50: [#7935] Removed assignment of slug to posts

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 08dd66a62298bd6f0d9ba7626146c951544ca5fd
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 17:28:45 2020 +0100

    [#7935] Removed assignment of slug to posts
---
 ForgeImporters/forgeimporters/forge/discussion.py | 2 --
 1 file changed, 2 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index bc29dd3..3e885bd 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -206,8 +206,6 @@ class ForgeDiscussionImporter(AlluraImporter):
                 if "last_edited" in post_json and post_json["last_edited"] != None:
                     print("Last edited: " + str(post_json["last_edited"]))
                     p.last_edit_date = parse(post_json["last_edited"])
-                if "slug" in post_json.keys():
-                    p.slug = post_json['slug']
 
                 p.add_multiple_attachments([File(a["url"]) for a in post_json["attachments"]])
 


[allura] 30/50: [#7935] Created test_index

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit cc0a5f75feca3d969b2fe9451e54cfc1d0b9c87a
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 19:14:27 2020 +0100

    [#7935] Created test_index
---
 .../forgeimporters/tests/forge/test_discussion.py   | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index dd5fd44..020dadb 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -23,6 +23,9 @@ from dateutil.parser import parse
 
 from ming.odm import ThreadLocalORMSession
 
+from allura.tests import TestController
+from allura.tests.decorators import with_tracker
+
 from allura import model as M
 from forgeimporters.forge import discussion
 from forgediscussion import utils
@@ -1181,3 +1184,21 @@ class TestDiscussionImporter(TestCase):
         g.post_event.assert_not_called()
 
 
+class TestForgeDiscussionController(TestController, TestCase):
+
+    
+    def setUp(self):
+        super(TestForgeDiscussionController, self).setUp()
+        from forgetracker.tracker_main import TrackerAdminController
+        TrackerAdminController._importer = \
+                discussion.ForgeDiscussionImportController(discussion.ForgeDiscussionImporter())
+
+    
+    @with_tracker
+    def test_index(self):
+        r = self.app.get('/p/test/admin/bugs/_importer/')
+        self.assertIsNotNone(r.html.find(attrs=dict(name="discussions_json")))
+        self.assertIsNotNone(r.html.find(attrs=dict(name="mount_label")))
+        self.assertIsNotNone(r.html.find(attrs=dict(name="mount_point")))
+
+


[allura] 44/50: [#7935] Refactored get_user and annotate method into AlluraImporter class

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit c01835684d5e5bc0f3364f7a345104f24a7abcfb
Author: Fahri <fa...@protonmail.ch>
AuthorDate: Fri Apr 10 15:11:10 2020 +0200

    [#7935] Refactored get_user and annotate method into AlluraImporter class
---
 ForgeImporters/forgeimporters/forge/discussion.py        |  2 +-
 ForgeImporters/forgeimporters/forge/tracker.py           | 16 ++--------------
 .../forgeimporters/tests/forge/test_tracker.py           |  4 +++-
 3 files changed, 6 insertions(+), 16 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index a06b65f..2d17d4e 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -51,7 +51,7 @@ from allura.lib.plugin import ImportIdConverter
 from forgediscussion import utils, import_support
 from forgediscussion import model as DM
 
-from alluraImporter import AlluraImporter
+from forgeimporters.forge.alluraImporter import AlluraImporter
 
 
 class ForgeDiscussionImportForm(ToolImportForm):
diff --git a/ForgeImporters/forgeimporters/forge/tracker.py b/ForgeImporters/forgeimporters/forge/tracker.py
index a893230..07f9fa0 100644
--- a/ForgeImporters/forgeimporters/forge/tracker.py
+++ b/ForgeImporters/forgeimporters/forge/tracker.py
@@ -50,6 +50,7 @@ from forgeimporters.base import (
     get_importer_upload_path,
     save_importer_upload,
 )
+from forgeimporters.forge.alluraImporter import AlluraImporter
 from io import open
 
 
@@ -86,7 +87,7 @@ class ForgeTrackerImportController(ToolImportController):
         redirect(c.project.url() + 'admin/')
 
 
-class ForgeTrackerImporter(ToolImporter):
+class ForgeTrackerImporter(AlluraImporter):
     source = 'Allura'
     target_app_ep_names = 'tickets'
     controller = ForgeTrackerImportController
@@ -186,19 +187,6 @@ class ForgeTrackerImporter(ToolImporter):
         finally:
             M.session.artifact_orm_session._get().skip_mod_date = False
 
-    def get_user(self, username):
-        if username == None:
-            return M.User.anonymous()
-        user = M.User.by_username(username)
-        if not user:
-            user = M.User.anonymous()
-        return user
-
-    def annotate(self, text, user, username, label=''):
-        if username and user.is_anonymous() and username != 'nobody':
-            return '*Originally%s by:* %s\n\n%s' % (label, username, text)
-        return text
-
     def process_comments(self, ticket, comments):
         for comment_json in comments:
             user = self.get_user(comment_json['author'])
diff --git a/ForgeImporters/forgeimporters/tests/forge/test_tracker.py b/ForgeImporters/forgeimporters/tests/forge/test_tracker.py
index 1e094ab..4ad72f8 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_tracker.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_tracker.py
@@ -30,6 +30,8 @@ from allura.tests.decorators import with_tracker
 from allura import model as M
 from forgeimporters.forge import tracker
 
+from forgeimporters.forge import alluraImporter
+
 
 class TestTrackerImporter(TestCase):
 
@@ -245,7 +247,7 @@ class TestTrackerImporter(TestCase):
         h.make_app_admin_only.assert_called_once_with(
             project.install_app.return_value)
 
-    @mock.patch.object(tracker, 'M')
+    @mock.patch.object(alluraImporter, 'M')
     def test_get_user(self, M):
         importer = tracker.ForgeTrackerImporter()
         M.User.anonymous.return_value = 'anon'


[allura] 36/50: [#7935] Added tests for nested posts

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 70a2cbed3c17a90ff18d610b49fe689de580aa1b
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Thu Mar 5 17:09:42 2020 +0100

    [#7935] Added tests for nested posts
---
 .../forgeimporters/tests/forge/test_discussion.py  | 117 +++++++++++++++++++++
 1 file changed, 117 insertions(+)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index bb75321..cb4e861 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -943,6 +943,123 @@ class TestDiscussionImporter(TestCase):
     @mock.patch.object(discussion, 'File')
     @mock.patch.object(discussion, 'c')
     @mock.patch.object(discussion, 'h')
+    def test_add_posts_nested_posts(self, h, c, File):
+        """ This method tests if nested posts were handled correctly """
+
+        # Test with author attribute missing
+        importer, app, _, user, post = self.__init_add_posts_tests()
+        thread = mock.Mock()
+        thread.add_post.side_effect=[ 
+            mock.Mock(_id=0),
+            mock.Mock(_id=1),
+            mock.Mock(_id=2),
+            mock.Mock(_id=3),
+            mock.Mock(_id=4),
+            mock.Mock(_id=5)
+        ]
+
+        _json = [
+            {
+              "attachments": [], 
+              "author": "admin1", 
+              "timestamp": "2020-01-29 22:39:31.483000", 
+              "text": "hi", 
+              "slug": "0d1d", 
+              "subject": "topic with lots of replies"
+            }, 
+            {
+              "attachments": [], 
+              "author": "admin1", 
+              "timestamp": "2020-01-29 22:39:43.525000", 
+              "text": "hello", 
+              "slug": "0d1d/d421", 
+              "subject": "topic with lots of replies"
+            }, 
+            {
+              "attachments": [], 
+              "author": "admin1", 
+              "timestamp": "2020-01-29 22:39:50.086000", 
+              "text": "goodbye", 
+              "slug": "0d1d/d421/f37d", 
+              "subject": "topic with lots of replies"
+            }, 
+            {
+              "attachments": [], 
+              "author": "admin1", 
+              "timestamp": "2020-01-29 22:42:13.740000", 
+              "text": "hi again", 
+              "slug": "012f", 
+              "subject": "topic with lots of replies"
+            }, 
+            {
+              "attachments": [], 
+              "author": "user02", 
+              "timestamp": "2020-01-29 22:42:51.645000", 
+              "text": "hi there", 
+              "slug": "012f/211a", 
+              "subject": "topic with lots of replies"
+            }, 
+            {
+              "attachments": [], 
+              "author": "user02", 
+              "timestamp": "2020-01-29 22:42:58.478000", 
+              "text": "hi here", 
+              "slug": "0d1d/00a0", 
+              "subject": "topic with lots of replies"
+            }
+         ]
+
+        importer.add_posts(thread, _json, app)
+
+        thread.add_post.assert_has_calls([
+            mock.call(
+                subject=_json[0]['subject'],
+                text='foo',
+                timestamp=parse(_json[0]['timestamp']),
+                ignore_security=True,
+                parent_id=None
+            ),
+            mock.call(
+                subject=_json[1]['subject'],
+                text='foo',
+                timestamp=parse(_json[1]['timestamp']),
+                ignore_security=True,
+                parent_id=0
+            ),
+            mock.call(
+                subject=_json[2]['subject'],
+                text='foo',
+                timestamp=parse(_json[2]['timestamp']),
+                ignore_security=True,
+                parent_id=1
+            ),
+            mock.call(
+                subject=_json[3]['subject'],
+                text='foo',
+                timestamp=parse(_json[3]['timestamp']),
+                ignore_security=True,
+                parent_id=None
+            ),
+            mock.call(
+                subject=_json[4]['subject'],
+                text='foo',
+                timestamp=parse(_json[4]['timestamp']),
+                ignore_security=True,
+                parent_id=3
+            ),
+            mock.call(
+                subject=_json[5]['subject'],
+                text='foo',
+                timestamp=parse(_json[5]['timestamp']),
+                ignore_security=True,
+                parent_id=0
+            )
+        ])
+
+
+    @mock.patch.object(discussion, 'File')
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'h')
     def test_add_posts_with_missing_keys(self, h, c, File):
         """ This method checks if add_posts will throw an error if required keys are missing """
         


[allura] 42/50: [#7935] Changed comparison with None

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 25ec9fbf016eebb059d07ee9d3e47ee8fda393f8
Author: Fahri <fa...@protonmail.ch>
AuthorDate: Fri Apr 10 14:58:14 2020 +0200

    [#7935] Changed comparison with None
---
 ForgeImporters/forgeimporters/base.py                 | 8 ++++----
 ForgeImporters/forgeimporters/forge/alluraImporter.py | 2 +-
 ForgeImporters/forgeimporters/forge/tracker.py        | 2 +-
 ForgeImporters/forgeimporters/github/utils.py         | 2 +-
 ForgeImporters/forgeimporters/github/wiki.py          | 2 +-
 ForgeImporters/forgeimporters/tests/test_base.py      | 2 +-
 6 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index dfd8beb..e394212 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -200,7 +200,7 @@ class ProjectExtractor(object):
         if self.url in self._page_cache:
             self.page = self._page_cache[self.url]
         else:
-            if parser is None:
+            if parser == None:
                 parser = self.parse_page
             self.page = self._page_cache[self.url] = \
                 parser(self.urlopen(self.url))
@@ -350,7 +350,7 @@ class ToolImportControllerMeta(type):
         the appropriate App for this controller's importer.
 
         """
-        if hasattr(cls, 'create') and getattr(cls.create.decoration, 'validation', None) is None:
+        if hasattr(cls, 'create') and getattr(cls.create.decoration, 'validation', None) == None:
             cls.create = validate(cls.import_form(aslist(importer.target_app)[0]),
                     error_handler=cls.index.__func__)(cls.create)
         return type.__call__(cls, importer, *args, **kw)
@@ -481,7 +481,7 @@ class ToolImporter(six.with_metaclass(ToolImporterMeta, object)):
             update={'$inc': {pending_key: 1}},
             new=True,
         )
-        return modified_project is not None
+        return modified_project != None
 
     def clear_pending(self, project):
         """
@@ -562,7 +562,7 @@ class ToolsValidator(fev.Set):
         invalid = []
         for name in value:
             importer = ToolImporter.by_name(name)
-            if importer is not None and importer.source == self.source:
+            if importer != None and importer.source == self.source:
                 valid.append(name)
             else:
                 invalid.append(name)
diff --git a/ForgeImporters/forgeimporters/forge/alluraImporter.py b/ForgeImporters/forgeimporters/forge/alluraImporter.py
index 477b4ef..059f88e 100644
--- a/ForgeImporters/forgeimporters/forge/alluraImporter.py
+++ b/ForgeImporters/forgeimporters/forge/alluraImporter.py
@@ -7,7 +7,7 @@ class AlluraImporter(ToolImporter):
 
 
     def get_user(self, username):
-        if username is None:
+        if username == None:
             return M.User.anonymous()
         user = M.User.by_username(username)
         if not user:
diff --git a/ForgeImporters/forgeimporters/forge/tracker.py b/ForgeImporters/forgeimporters/forge/tracker.py
index b5825ab..a893230 100644
--- a/ForgeImporters/forgeimporters/forge/tracker.py
+++ b/ForgeImporters/forgeimporters/forge/tracker.py
@@ -187,7 +187,7 @@ class ForgeTrackerImporter(ToolImporter):
             M.session.artifact_orm_session._get().skip_mod_date = False
 
     def get_user(self, username):
-        if username is None:
+        if username == None:
             return M.User.anonymous()
         user = M.User.by_username(username)
         if not user:
diff --git a/ForgeImporters/forgeimporters/github/utils.py b/ForgeImporters/forgeimporters/github/utils.py
index 23cb010..8383de9 100644
--- a/ForgeImporters/forgeimporters/github/utils.py
+++ b/ForgeImporters/forgeimporters/github/utils.py
@@ -28,7 +28,7 @@ class GitHubMarkdownConverter(object):
         self.code_patterns = ['```', '~~~']
 
     def convert(self, text):
-        if text is None:
+        if text == None:
             return ''
         lines = self._parse_lines(text.split('\n'))
         return '\n'.join(lines)
diff --git a/ForgeImporters/forgeimporters/github/wiki.py b/ForgeImporters/forgeimporters/github/wiki.py
index d96a3c1..d863ef5 100644
--- a/ForgeImporters/forgeimporters/github/wiki.py
+++ b/ForgeImporters/forgeimporters/github/wiki.py
@@ -407,7 +407,7 @@ class GitHubWikiImporter(ToolImporter):
             idx = [p.lower() for p in self.available_pages].index(page.lower())
         except ValueError:
             idx = None
-        if idx is not None:
+        if idx != None:
             page = self.available_pages[idx]
 
         if title:
diff --git a/ForgeImporters/forgeimporters/tests/test_base.py b/ForgeImporters/forgeimporters/tests/test_base.py
index f23ee8f..4f82b17 100644
--- a/ForgeImporters/forgeimporters/tests/test_base.py
+++ b/ForgeImporters/forgeimporters/tests/test_base.py
@@ -106,7 +106,7 @@ def test_import_tool_failed(g, ToolImporter, format_exc):
 def ep(name, source=None, importer=None, **kw):
     mep = mock.Mock(name='mock_ep', **kw)
     mep.name = name
-    if importer is not None:
+    if importer != None:
         mep.load.return_value = importer
     else:
         mep.load.return_value.source = source


[allura] 20/50: [#7935] Added tests for import_tool method

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 9e6ccaacd772fb1f8a9afa4e36a4432659289be7
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 16:54:26 2020 +0100

    [#7935] Added tests for import_tool method
---
 .../forgeimporters/tests/forge/test_discussion.py  | 507 ++++++++++++++++++++-
 1 file changed, 485 insertions(+), 22 deletions(-)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 9526ffc..26af2c9 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -30,6 +30,7 @@ from forgediscussion import utils
 
 class TestDiscussionImporter(TestCase):
 
+
     def setUp(self):
         super(TestDiscussionImporter, self).setUp()
 
@@ -111,17 +112,8 @@ class TestDiscussionImporter(TestCase):
         h.push_config.assert_called_once_with(c, app=app)
 
         forum_json = _json['forums'][0]
-        new_forum = dict(
-            app_config_id = app.config._id,
-            shortname=forum_json['shortname'],
-            description=forum_json['description'],
-            name=forum_json['name'],
-            create='on',
-            parent='',
-            members_only=False,
-            anon_posts=False,
-            monitoring_email=None
-        )
+        new_forum = self.__get_forum_dict(app, forum_json)
+
         utils.create_forum.assert_called_once_with(app, new_forum=new_forum)
         forum.get_discussion_thread(dict(headers=dict(Subject=_json["forums"][0]["threads"][0]["subject"])))
         importer.add_posts.assert_called_once_with(thread1, _json["forums"][0]["threads"][0]["posts"], app)
@@ -201,17 +193,8 @@ class TestDiscussionImporter(TestCase):
         )
 
         forum_json = _json["forums"][0]
-        new_forum = dict(
-             app_config_id = app.config._id,
-             shortname=forum_json['shortname'],
-             description=forum_json['description'],
-             name=forum_json['name'],
-             create='on',
-             parent='',
-             members_only=False,
-             anon_posts=False,
-             monitoring_email=None
-        )
+        new_forum = self.__get_forum_dict(app, forum_json)
+
         utils.create_forum.assert_called_once_with(app, new_forum=new_forum)
         forum.get_discussion_thread.assert_called_once_with(dict(headers=dict(Subject=_json["forums"][0]["threads"][0]["subject"])))
         
@@ -235,6 +218,468 @@ class TestDiscussionImporter(TestCase):
         g.post_event.assert_called_once_with('project_updated')
 
 
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'g')
+    @mock.patch.object(discussion, 'M')
+    @mock.patch.object(discussion, 'session')
+    @mock.patch.object(discussion, 'h')
+    @mock.patch.object(discussion, 'ThreadLocalORMSession')
+    def test_import_tool_multiple_forums(self, tlos, h, session, m, g, c):
+        """ This test tests if it is possible to create a discussion with multiple forums """
+
+        importer = discussion.ForgeDiscussionImporter()
+
+        _json = {
+            "forums": [
+                {
+                    "shortname": "general",
+                    "description": "Forum about anything you want to talk about.", 
+                    "name": "General Discussion",
+                    "threads": []    
+                },
+                {
+                    "shortname": "dev",
+                    "description": "Forum for Devs.", 
+                    "name": "Developers' Corner",
+                    "threads": []
+                },
+                {
+                    "shortname": "announcements",
+                    "description": "Announcements are posted here", 
+                    "name": "Announcements",
+                    "threads": []
+                },
+                {
+                    "shortname": "cc",
+                    "description": "Forum about improvements of our codebase", 
+                    "name": "Clean Code",
+                    "threads": []
+                }
+            ]
+        }
+
+        
+        importer._load_json = mock.Mock(return_value=_json)
+        importer.add_posts = mock.Mock()        
+        importer._clear_forums = mock.Mock()
+
+        project, user = mock.Mock(), mock.Mock()
+        app = project.install_app.return_value
+        app.config.options.mount_point = 'mount_point'
+        app.config.options.import_id = { 'source': 'Allura' }
+        app.config.options.get = lambda *a: getattr(app.config.options, *a)
+        app.url = 'foo'
+        app.forums = []
+
+        utils.create_forum = mock.Mock()
+        forum = mock.Mock()
+        utils.create_forum.return_value = forum
+
+        g.post_event = mock.Mock()
+        m.AuditLog.log = mock.Mock()
+
+        importer.import_tool(project, user, 'mount_point', 'mount_label')
+
+        h.push_config.assert_called_once_with(c, app=app)
+        importer._clear_forums.assert_called_once_with(app)
+
+        forum0 = self.__get_forum_dict(app, _json['forums'][0])
+        forum1 = self.__get_forum_dict(app, _json['forums'][1])
+        forum2 = self.__get_forum_dict(app, _json['forums'][2])
+        forum3 = self.__get_forum_dict(app, _json['forums'][3])
+ 
+        utils.create_forum.assert_has_calls([
+            mock.call(app, new_forum=forum0),
+            mock.call(app, new_forum=forum1),
+            mock.call(app, new_forum=forum2),
+            mock.call(app, new_forum=forum3)
+        ])
+
+        forum.get_discussion_thread.assert_not_called()
+        importer.add_posts.assert_not_called()
+
+        m.AuditLog.log.assert_called_once()
+        g.post_event.assert_called_once()
+
+
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'g')
+    @mock.patch.object(discussion, 'M')
+    @mock.patch.object(discussion, 'session')
+    @mock.patch.object(discussion, 'h')
+    @mock.patch.object(discussion, 'ThreadLocalORMSession')
+    def test_import_tool_multiple_threads(self, tlos, h, session, m, g, c):
+        """ This method tests if import_tool can handle multiple threads """
+
+        importer = discussion.ForgeDiscussionImporter()
+
+        _json = {
+            "forums": [ {
+                "description": "Forum about anything you want to talk about.", 
+                "shortname": "general", 
+                "name": "General Discussion",
+                "threads": [
+                        {
+                            "page": None,
+                            "subject": "Thread0",
+                            "posts": []
+                        },
+                        {
+                            "page": None,
+                            "subject": "Thread1",
+                            "posts": []
+                        },
+                        {
+                            "page": None,
+                            "subject": "Thread2",
+                            "posts": []
+                        },
+                        {
+                            "page": None,
+                            "subject": "Thread3",
+                            "posts": []
+                        },
+                        {
+                            "page": None,
+                            "subject": "Thread4",
+                            "posts": []
+                        }
+                    ]}
+                ]
+            }
+
+            
+        importer._load_json = mock.Mock(return_value=_json)
+        importer.add_posts = mock.Mock()        
+        importer._clear_forums = mock.Mock()
+
+        project, user = mock.Mock(), mock.Mock()
+        app = project.install_app.return_value
+        app.config.options.mount_point = 'mount_point'
+        app.config.options.import_id = { 'source': 'Allura' }
+        app.config.options.get = lambda *a: getattr(app.config.options, *a)
+        app.url = 'foo'
+        app.forums = []
+
+        utils.create_forum = mock.Mock()
+        forum = mock.Mock()
+        forum.get_discussion_thread.return_value = (mock.Mock(), mock.Mock())
+
+        utils.create_forum.return_value = forum
+
+        g.post_event = mock.Mock()
+        m.AuditLog.log= mock.Mock()
+
+        importer.import_tool(project, user, 'mount_point', 'mount_label')
+
+        project.install_app.assert_called_once_with('discussion', 'mount_point', 'mount_label', import_id={'source': 'Allura'})
+        h.push_config.assert_called_once_with(c, app=app)
+
+        utils.create_forum.assert_called_once()
+
+        thread_json = _json["forums"][0]["threads"]
+        forum.get_discussion_thread.assert_has_calls([
+            mock.call(dict(
+                headers=dict(Subject=thread_json[0]["subject"])
+            )),
+            mock.call(dict(
+                headers=dict(Subject=thread_json[1]["subject"])
+            )),
+            mock.call(dict(
+                headers=dict(Subject=thread_json[2]["subject"])
+            )),
+            mock.call(dict(
+                headers=dict(Subject=thread_json[3]["subject"])
+            )),
+            mock.call(dict(
+                headers=dict(Subject=thread_json[4]["subject"])
+            ))
+        ])
+
+        self.assertEqual(importer.add_posts.call_count, 5)
+        m.AuditLog.log.assert_called_once()
+        g.post_event.assert_called_once()
+
+
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'g')
+    @mock.patch.object(discussion, 'M')
+    @mock.patch.object(discussion, 'session')
+    @mock.patch.object(discussion, 'h')
+    @mock.patch.object(discussion, 'ThreadLocalORMSession')
+    def test_import_tool_forum_import_id(self, tlos, h, session, m, g, c):
+        """ This method tests if an import id is added to a forum """
+        
+        importer = discussion.ForgeDiscussionImporter()
+
+        # Test with import id
+        import_id = "qwert258"
+        _json = {
+            "forums": [ {
+                "description": "Forum about anything you want to talk about.", 
+                "shortname": "general", 
+                "name": "General Discussion",
+                "import_id": import_id,
+                "threads": []
+                }]
+        }
+
+        importer._load_json = mock.Mock(return_value=_json)
+        importer.add_posts = mock.Mock()        
+        importer._clear_forums = mock.Mock()
+
+        project, user = mock.Mock(), mock.Mock()
+        app = project.install_app.return_value
+        app.config.options.mount_point = 'mount_point'
+        app.config.options.import_id = { 'source': 'Allura' }
+        app.config.options.get = lambda *a: getattr(app.config.options, *a)
+        app.url = 'foo'
+        app.forums = []
+
+        forum = mock.Mock()
+        utils.create_forum = mock.Mock(return_value=forum)
+        forum.get_discussion_thread.return_value = (mock.Mock(), mock.Mock())
+
+        utils.create_forum.return_value = forum
+
+        g.post_event = mock.Mock()
+        m.AuditLog.log= mock.Mock()
+       
+        importer.import_tool(project, user, 'mount_point', 'mount_label')
+        
+        self.assertEqual(import_id, forum.import_id)
+        
+
+        # Test without import id
+        _json = {
+            "forums": [ {
+                "description": "Forum about anything you want to talk about.", 
+                "shortname": "general", 
+                "name": "General Discussion",
+                "threads": []
+            }]
+        }
+
+        importer._load_json = mock.Mock(return_value=_json)
+        forum = mock.Mock()
+        forum.import_id = ''
+        utils.create_forum(return_value=forum)
+
+        importer.import_tool(project, user, 'mount_point', 'mount_label')
+
+        self.assertEqual('', forum.import_id)
+
+
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'g')
+    @mock.patch.object(discussion, 'M')
+    @mock.patch.object(discussion, 'session')
+    @mock.patch.object(discussion, 'h')
+    @mock.patch.object(discussion, 'ThreadLocalORMSession')
+    def test_import_tool_thread_import_id(self, tlos, h, session, m, g, c):
+        """ This method tests if an import id is assigned to a thread """
+
+        importer = discussion.ForgeDiscussionImporter()
+
+        # Test with import id
+        import_id = "qwert123"
+        _json = {
+            "forums": [ {
+                "description": "Forum about anything you want to talk about.", 
+                "shortname": "general", 
+                "name": "General Discussion",
+                "threads": [{
+                        "limit": None,
+                        "posts": [],
+                        "subject": "Thread",
+                        "import_id": import_id
+                    }]
+                }]
+        }
+
+        importer._load_json = mock.Mock(return_value=_json)
+        importer.add_posts = mock.Mock()        
+        importer._clear_forums = mock.Mock()
+
+        project, user = mock.Mock(), mock.Mock()
+        app = project.install_app.return_value
+        app.config.options.mount_point = 'mount_point'
+        app.config.options.import_id = { 'source': 'Allura' }
+        app.config.options.get = lambda *a: getattr(app.config.options, *a)
+        app.url = 'foo'
+        app.forums = []
+
+        forum = mock.Mock()
+        utils.create_forum = mock.Mock(return_value=forum)
+        thread = mock.Mock()
+        forum.get_discussion_thread.return_value = (thread, mock.Mock())
+
+        utils.create_forum.return_value = forum
+
+        g.post_event = mock.Mock()
+        m.AuditLog.log= mock.Mock()
+       
+        importer.import_tool(project, user, 'mount_point', 'mount_label')
+
+        self.assertEqual(import_id, thread.import_id)
+
+        # Test with no import id 
+        _json = {
+            "forums": [ {
+                "description": "Forum about anything you want to talk about.", 
+                "shortname": "general", 
+                "name": "General Discussion",
+                "threads": [{
+                        "limit": None,
+                        "posts": [],
+                        "subject": "Thread",
+                    }]
+                }]
+        }
+
+        importer._load_json = mock.Mock(return_value=_json)
+        thread = mock.Mock()
+        thread.import_id = ''
+        
+        forum.get_discussion_thread.return_value = (thread, mock.Mock())
+        
+        importer.import_tool(project, user, 'mount_point', 'mount_label')
+
+        self.assertEqual('', thread.import_id)
+
+
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'g')
+    @mock.patch.object(discussion, 'M')
+    @mock.patch.object(discussion, 'session')
+    @mock.patch.object(discussion, 'h')
+    @mock.patch.object(discussion, 'ThreadLocalORMSession')
+    def test_import_tool_missing_keys(self, tlos, h, session, m, g, c):
+        """ This method tests if missing keys are handled correctly """
+
+        # Check if shortname missing
+        _json = {
+            "forums": [ {
+                "description": "Forum about anything you want to talk about.", 
+                "name": "General Discussion",
+                "threads": []
+            }]
+        }
+
+        importer = discussion.ForgeDiscussionImporter()
+        importer._load_json = mock.Mock(return_value=_json)
+        
+        u = mock.Mock(_id=123, is_anonymous=lambda: False)
+        importer.get_user = mock.Mock(return_value=u)
+
+        project, user = mock.Mock(), mock.Mock()
+        app = project.install_app.return_value
+        app.config.options.mount_point = 'mount_point'
+        app.config.options.import_id = { 'source': 'Allura' }
+        app.config.options.get = lambda *a: getattr(app.config.options, *a)
+        app.url = 'foo'
+        app.forums = []
+
+        forum = mock.Mock()
+        utils.create_forum = mock.Mock(return_value=forum)
+        thread = mock.Mock()
+        forum.get_discussion_thread.return_value = (thread, mock.Mock())
+
+        utils.create_forum.return_value = forum
+
+        g.post_event = mock.Mock()
+        m.AuditLog.log= mock.Mock()
+
+        self.__check_missing(project, user, importer, h, g, utils) 
+
+        
+        # Check if description is missing
+        _json = {
+            "forums": [ {
+                "shortname": "general",
+                "name": "General Discussion",
+                "threads": []
+            }]
+        }
+
+        importer._load_json = mock.Mock(return_value=_json)
+        self.__check_missing(project, user, importer, h, g, utils)
+        utils.create_forum.assert_not_called()
+
+
+        # Check if name is missing
+        _json = {
+            "forums": [ {
+                "shortname": "general",
+                "description": "Description of forum",
+                "threads": []
+            }]
+        }
+
+        importer._load_json = mock.Mock(return_value=_json)
+        self.__check_missing(project, user, importer, h, g, utils)
+        utils.create_forum.assert_not_called()
+
+        
+        # Check if threads are missing
+        _json = {
+            "forums": [ {
+                "shortname": "general",
+                "description": "Description of forum",
+                "name": "General Discussion"
+            }]
+        }
+
+        importer._load_json = mock.Mock(return_value=_json)
+        self.__check_missing(project, user, importer, h, g, utils)
+
+        
+        # Check if subject of threads are missing
+        _json = {
+            "forums": [ {
+                "shortname": "general",
+                "description": "Description of forum",
+                "name": "General Discussion",
+                "threads": [{
+                   "posts": [] 
+                }]
+            }]
+        }
+
+        importer._load_json = mock.Mock(return_value=_json)
+        self.__check_missing(project, user, importer, h, g, utils)
+
+
+        # Check if posts of threads are missing
+        _json = {
+            "forums": [ {
+                "shortname": "general",
+                "description": "Description of forum",
+                "name": "General Discussion",
+                "threads": [{
+                    "subject": "Thread"
+                }]
+            }]
+        }
+
+        importer._load_json = mock.Mock(return_value=_json)
+        self.__check_missing(project, user, importer, h, g, utils)
+        
+        self.assertEqual(h.make_app_admin_only.call_count, 6)
+
+
+    def __check_missing(self, project, user, importer, h, g, utils):
+        try:       
+            importer.import_tool(project, user, 'mount_point', 'mount_label')
+            self.fail("import_tool() didn't raise Exception")
+        except Exception:
+            pass
+       
+        print("after try except")
+ 
+        g.post_event.assert_not_called()
+
+
     def test_annotate_text_with_existing_user(self):
         """ This test tests the annotate_text method if an existing user is passed as argument """
 
@@ -297,3 +742,21 @@ class TestDiscussionImporter(TestCase):
 
         text = 'foo'
         self.assertEqual(importer.annotate_text(text, user, username), text)
+
+
+    def __get_forum_dict(self, app, forum_json):
+        new_forum = dict(
+            app_config_id = app.config._id,
+            shortname=forum_json['shortname'],
+            description=forum_json['description'],
+            name=forum_json['name'],
+            create='on',
+            parent='',
+            members_only=False,
+            anon_posts=False,
+            monitoring_email=None
+        )
+
+        return new_forum
+
+


[allura] 48/50: [#7935] Deleted two newlines at the end of the file

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit d745f8af027353accb3daf0336b771aa38193106
Author: Korkmatik <fa...@protonmail.ch>
AuthorDate: Sat Apr 11 00:06:51 2020 +0200

    [#7935] Deleted two newlines at the end of the file
---
 ForgeImporters/forgeimporters/tests/forge/test_discussion.py | 2 --
 1 file changed, 2 deletions(-)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index c37112d..2cbc5c7 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -1391,5 +1391,3 @@ class TestForgeDiscussionController(TestController, TestCase):
                           status=302).follow()
         self.assertIn('Please wait and try again', r)
         self.assertEqual(import_tool.post.call_count, 0)
-
-


[allura] 18/50: [#7935] Created test for creating a general discussion

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit cfbf6dd6a0943e9ad68c17331ba41c6e849842e1
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 10:38:54 2020 +0100

    [#7935] Created test for creating a general discussion
---
 .../forgeimporters/tests/forge/test_discussion.py  | 92 ++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 661525d..161f518 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -19,8 +19,12 @@ from unittest import TestCase
 
 import mock
 
+from ming.odm import ThreadLocalORMSession
+
 from allura import model as M
 from forgeimporters.forge import discussion
+from forgediscussion import utils
+
 
 class TestDiscussionImporter(TestCase):
 
@@ -36,6 +40,94 @@ class TestDiscussionImporter(TestCase):
         self.patcher_g.stop()
 
 
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'g')
+    @mock.patch.object(discussion, 'M')
+    @mock.patch.object(discussion, 'session')
+    @mock.patch.object(discussion, 'h')
+    @mock.patch.object(discussion, 'ThreadLocalORMSession')
+    def test_import_tool_with_general_discussion(self, tlos, h, session, m, g, c):
+        """ This test creates a general discussion forum with one thread and one post from admin """
+        importer = discussion.ForgeDiscussionImporter()
+        _json = { 
+            'forums': [{
+                'shortname': 'general',
+                '_id': '538f7240f697c62562ed9e6f',
+                'description': 'Forum about anything you want to talk about.',
+                'name': 'General Discussion',
+                'threads': [
+                    {
+                        'limit': None,
+                        'discussion_id': '538f7240f697c62562ed9e6f',
+                        '_id': 'ef260a33d2',
+                        'page': None,
+                        'subject': 'Thread1',
+                        'posts': [
+                            {
+                                'attachments': [],
+                                'author': 'admin1',
+                                'timestamp': '2020-01-29 22:30:42.497000',
+                                'author_icon_url': 'https://secure.gravatar.com/avatar/2ba5bfa33e6faca31f7dd150960ce926?r=pg&d=https%3A%2F%2F4.xb.sf.net%2Fnf%2F0%2F_ew_%2Ftheme%2Fsftheme%2Fimages%2Fsandiego%2Ficons%2Fdefault-avatar.png',
+                                'text': 'hi',
+                                'last_edited': None,
+                                'slug': '00aa',
+                                'subject':  'A post'
+                            }
+                        ]
+                    }
+                ]
+            }]
+        }
+        importer._load_json = mock.Mock(return_value=_json)
+
+        admin = mock.Mock(_id=1, is_anonymous=lambda: False)
+        importer.get_user = mock.Mock(side_effect=[ admin ])
+
+        project, user = mock.Mock(), mock.Mock()
+        app = project.install_app.return_value
+        app.config.options.mount_point = 'mount_point'
+        app.config.options.import_id = { 'source': 'Allura' }
+        app.config.options.get = lambda *a: getattr(app.config.options, *a)
+        app.url = 'foo'
+        app.forums = []
+        utils.create_forum = mock.Mock()
+        forum = mock.Mock()
+        thread1 = mock.Mock()
+        forum.get_discussion_thread.return_value = (thread1, mock.Mock())
+        utils.create_forum.return_value = forum
+        importer.add_posts = mock.Mock()
+        g.post_event = mock.Mock()
+        m.AuditLog.log = mock.Mock()
+
+        importer.import_tool(project, user, mount_point='mount_point', mount_label='mount_label')
+
+        project.install_app.assert_called_once_with(
+            'discussion', 'mount_point', 'mount_label',
+            import_id={ 'source': 'Allura' }
+        )
+
+        h.push_config.assert_called_once_with(c, app=app)
+
+        forum_json = _json['forums'][0]
+        new_forum = dict(
+            app_config_id = app.config._id,
+            shortname=forum_json['shortname'],
+            description=forum_json['description'],
+            name=forum_json['name'],
+            create='on',
+            parent='',
+            members_only=False,
+            anon_posts=False,
+            monitoring_email=None
+        )
+        utils.create_forum.assert_called_once_with(app, new_forum=new_forum)
+        forum.get_discussion_thread(dict(headers=dict(Subject=_json["forums"][0]["threads"][0]["subject"])))
+        importer.add_posts.assert_called_once_with(thread1, _json["forums"][0]["threads"][0]["posts"], app)
+
+        m.AuditLog.log.assert_called_once_with("import tool mount_point from exported Allura JSON", project=project, user=user, url='foo')
+        g.post_event.assert_called_once_with("project_updated")
+
+
     def test_annotate_text_with_existing_user(self):
         """ This test tests the annotate_text method if an existing user is passed as argument """
 


[allura] 23/50: [#7935] Added test for add_posts

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit cd99e4e00cf3d380d3c66851bdf4df864b8b5ba4
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 17:29:31 2020 +0100

    [#7935] Added test for add_posts
---
 .../forgeimporters/tests/forge/test_discussion.py  | 70 ++++++++++++++++++----
 1 file changed, 60 insertions(+), 10 deletions(-)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 26af2c9..535bc1c 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -668,17 +668,55 @@ class TestDiscussionImporter(TestCase):
         self.assertEqual(h.make_app_admin_only.call_count, 6)
 
 
-    def __check_missing(self, project, user, importer, h, g, utils):
-        try:       
-            importer.import_tool(project, user, 'mount_point', 'mount_label')
-            self.fail("import_tool() didn't raise Exception")
-        except Exception:
-            pass
-       
-        print("after try except")
- 
-        g.post_event.assert_not_called()
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'h')
+    def test_add_posts(self, h, c):
+        """ This methods tests if a post is correctly added to a thread """
 
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+
+        _json = [ {
+            "attachments": [],
+            "author": "admin1",
+            "timestamp": "2020-01-29 22:30:42.497000",
+            "text": "foo",
+            "subject": "Foo subject"
+        }]
+
+        importer.add_posts(thread, _json, app)
+
+        importer.get_user.assert_called_once_with('admin1')
+        h.push_config.assert_called_once_with(c, user=user, app=app)
+        thread.add_post.assert_called_once_with(
+                subject=_json[0]['subject'],
+                text='foo',
+                timestamp=parse(_json[0]['timestamp']),
+                ignore_security=True
+        )
+        post.add_multiple_attachments.assert_called_once_with([])
+        
+    
+    def __init_add_posts_tests(self):
+        importer = discussion.ForgeDiscussionImporter()
+
+        user1 = mock.Mock(_id=1, is_anonymous=lambda: False)
+
+        importer.get_user = mock.Mock(return_value=user1)
+        importer.annotate_text = mock.Mock(return_value='foo')
+
+        project, user = mock.Mock(), mock.Mock()
+        app = project.install_app.return_value
+        app.config.options.mount_point = 'mount_point'
+        app.config.options.import_id = { 'source': 'Allura' }
+        app.config.options.get = lambda *a: getattr(app.config.options, *a)
+        app.url = 'foo'
+        app.forums = []
+
+        thread = mock.Mock()
+        post = mock.Mock()
+        thread.add_post.return_value = post
+
+        return importer, app, thread, user1, post
 
     def test_annotate_text_with_existing_user(self):
         """ This test tests the annotate_text method if an existing user is passed as argument """
@@ -760,3 +798,15 @@ class TestDiscussionImporter(TestCase):
         return new_forum
 
 
+    def __check_missing(self, project, user, importer, h, g, utils):
+        try:       
+            importer.import_tool(project, user, 'mount_point', 'mount_label')
+            self.fail("import_tool() didn't raise Exception")
+        except Exception:
+            pass
+       
+        print("after try except")
+ 
+        g.post_event.assert_not_called()
+
+


[allura] 01/50: [#7935] Created forum importer for allura's own export format

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit b7d7b95683fe128548c530d03a4c60c5fba8f245
Author: Korkmatik <fa...@protonmail.ch>
AuthorDate: Sat Dec 21 22:05:33 2019 +0100

    [#7935] Created forum importer for allura's own export format
---
 ForgeImporters/forgeimporters/forge/discussion.py  | 182 +++++++++++++++++++++
 .../forge/templates/discussion/index.html          |  11 ++
 ForgeImporters/setup.py                            |   1 +
 3 files changed, 194 insertions(+)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
new file mode 100644
index 0000000..754f1d9
--- /dev/null
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -0,0 +1,182 @@
+import os
+import json
+from dateutil.parser import parse
+
+from tg import tmpl_context as c
+from ming.orm import session, ThreadLocalORMSession
+
+from tg import (
+    expose,
+    flash,
+    redirect
+)
+
+from tg.decorators import (
+    with_trailing_slash,
+    without_trailing_slash
+)
+
+from forgeimporters.base import (
+    ToolImportForm,
+    ToolImportController,
+    File,
+    ToolImporter,
+    get_importer_upload_path,
+    save_importer_upload
+)
+
+from allura import model as M   
+from allura.lib.decorators import require_post
+from allura.lib import validators as v 
+from allura.lib import helpers as h
+
+from forgediscussion import utils, import_support
+from forgediscussion import model as DM
+
+class ForgeDiscussionImportForm(ToolImportForm):
+    discussions_json = v.JsonFile(not_empty=True)
+
+
+class ForgeDiscussionImportController(ToolImportController):
+    import_form = ForgeDiscussionImportForm
+
+    @with_trailing_slash
+    @expose('jinja:forgeimporters.forge:templates/discussion/index.html')
+    def index(self, **kw):
+        return dict(importer=self.importer, target_app=self.target_app)
+
+    @without_trailing_slash
+    @expose()
+    @require_post()
+    def create(self, discussions_json, mount_point, mount_label, **kw):
+        # TODO: delete debug output
+        if self.importer.enforce_limit(c.project):
+            print("import 1")
+            save_importer_upload(c.project, 'discussion.json', json.dumps(discussions_json))
+            print("import 2")
+            self.importer.post(mount_point=mount_point, mount_label=mount_label)
+            print("import 3")
+            flash('Discussion import has begun. Your new discussion will be available when the import is complete')
+            
+        else:
+            print("import limit")
+            flash('There are too many imports pending at this time. Please wait and try again.', 'error')
+        print("import none	")
+
+        redirect(c.project.url() + 'admin/')
+
+
+class ForgeDiscussionImporter(ToolImporter):
+    source = 'Allura'
+    target_app_ep_names = 'discussion'
+    controller = ForgeDiscussionImportController
+    tool_label = 'Discussion'
+    tool_description = 'Import an allura discussion.'
+
+    def __init__(self, *args, **kwargs):
+        super(ForgeDiscussionImporter, self).__init__(*args, **kwargs)
+
+    def _load_json(self, project):
+        upload_path = get_importer_upload_path(project)
+        full_path = os.path.join(upload_path, 'discussion.json')
+        with open(full_path) as fp:
+            return json.load(fp)
+
+    def import_tool(self, project, user, mount_point=None,
+                     mount_label=None, **kw):
+        print("import_tool")
+        #import_id_converter = ImportIdConverter.get()
+        discussion_json = self._load_json(project)
+        
+        mount_point = mount_point or 'discussion'
+
+
+        #_id = forum_json['_id']
+        _id = 'undefined'
+
+        app = project.install_app('discussion', mount_point, mount_label,
+                    import_id={'source': self.source, 'app_config_id': _id }
+        )
+        ThreadLocalORMSession.flush_all()
+       
+        try:
+            M.session.artifact_orm_session._get().skip_mod_date = True
+
+            for forum_json in discussion_json['forums']:
+
+                print("forum_json: ", forum_json)
+
+                new_forum = dict(
+                    shortname=forum_json['shortname'],
+                    _id=forum_json['_id'],
+                    description=forum_json['description'],
+                    name=forum_json['name'],
+                    create='on',
+                    parent='',
+                    members_only=False,
+                    anon_posts=False,
+                    monitoring_email=None
+               ) 
+
+                print(new_forum)
+
+                forum = utils.create_forum(app, new_forum=new_forum)
+
+                for thread_json in forum_json["threads"]:
+                    #thread = DM.ForumThread(
+                    #    _id=thread_json['_id'],
+                    #    discussion_id=thread_json['discussion_id'],
+                    #    subject=thread_json['subject']
+                    #)
+                    thread = forum.get_discussion_thread(dict(
+                                headers=dict(Subject=thread_json['subject'])))[0]
+
+                    self.add_posts(
+                        thread, thread_json['posts'])
+
+                session(forum).flush(forum)
+                session(forum).expunge(forum)
+
+                #perform_import(discussion_json, user)
+
+                print("Forum %s created" % (new_forum["shortname"]))
+
+            return app
+        except Exception:
+            h.make_app_admin_only(app)
+            raise
+                                     
+
+    def get_user(self, username):
+        if username is None:
+            return M.User.anonymous()
+        user = M.User.by_username(username)
+        if not user:
+            print("No user with ", username, "found! (",user,")")
+            user = M.User.anonymous()
+        return user
+
+    def annotate(self, text, user, username, label=''):
+        pass
+
+    def add_posts(self, thread, posts):
+        for post_json in posts:
+            print("Author: ", post_json["author"])
+            user = self.get_user(post_json["author"])
+            print("User", user)
+            with h.push_config(c, user=user):
+                p = thread.add_post(
+                        subject=post_json['subject'],
+                        text=post_json['text'], 
+                        ignore_security=True,
+                        timestamp=parse(post_json['timestamp'])
+                )
+
+                try:
+                    p.add_multiple_attachments([File(a['url'])
+                                                for a in post_json['attachments']])
+                except:
+                    print("Could not add attachemtns to post")
+
+    def process_bins(self, app, bins):
+        pass 
diff --git a/ForgeImporters/forgeimporters/forge/templates/discussion/index.html b/ForgeImporters/forgeimporters/forge/templates/discussion/index.html
new file mode 100644
index 0000000..682cf73
--- /dev/null
+++ b/ForgeImporters/forgeimporters/forge/templates/discussion/index.html
@@ -0,0 +1,11 @@
+{% extends 'forgeimporters:templates/importer_base.html' %}
+
+{% block importer_fields %}
+    <div>
+        <label for="discussions_json">Discussions JSON
+            <br><small>JSON file exported from Allura</small>
+        </label>
+        <input name="discussions_json" type="file" />
+        {{ error('tickets_json') }}
+    </div>
+{% endblock %}
diff --git a/ForgeImporters/setup.py b/ForgeImporters/setup.py
index adae23d..99c11de 100644
--- a/ForgeImporters/setup.py
+++ b/ForgeImporters/setup.py
@@ -45,6 +45,7 @@ setup(name='ForgeImporters',
       github-repo = forgeimporters.github.code:GitHubRepoImporter
       trac-tickets = forgeimporters.trac.tickets:TracTicketImporter
       forge-tracker = forgeimporters.forge.tracker:ForgeTrackerImporter
+      forge-discussion = forgeimporters.forge.discussion:ForgeDiscussionImporter
 
       [allura.admin]
       importers = forgeimporters.base:ImportAdminExtension


[allura] 34/50: [#7935] Updated creation of nested posts

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 2b15be09163bd9271cdd52fb5afe073b41dc4552
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Thu Mar 5 16:13:23 2020 +0100

    [#7935] Updated creation of nested posts
---
 ForgeImporters/forgeimporters/forge/discussion.py | 34 +++++++++++++----------
 1 file changed, 20 insertions(+), 14 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 661aeb0..24ee5af 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -79,7 +79,7 @@ class ForgeDiscussionImporter(AlluraImporter):
 
     def _load_json(self, project):
         upload_path = get_importer_upload_path(project)
-        full_path = os.path.join(upload_path, 'discussion.json')
+        full_path = os.path.join(upload_path, 'discussions.json')
         with open(full_path) as fp:
             return json.load(fp)
 
@@ -185,26 +185,32 @@ class ForgeDiscussionImporter(AlluraImporter):
 
 
     def add_posts(self, thread, posts, app):
-        prev = None
-        number_slashes = 0
+        created_posts = []
 
         for post_json in posts:
             username = post_json["author"]
-            print("Author: " + str(username))
             user = self.get_user(username)
-            print("User: " + str(user))
+
             with h.push_config(c, user=user, app=app):
                 timestamp = parse(post_json['timestamp'])
 
                 # For nested posts
                 parent_id = None
-                if prev != None and "slug" in post_json.keys():
-                    count = post_json["slug"].count('/')
-                   
-                    if number_slashes < count:
-                        parent_id = prev._id
-                    
-                    number_slashes = count
+                slug = ''
+                if "slug" in post_json.keys():
+                    slug = post_json["slug"]
+
+                    if slug.count('/') >= 1:
+                        pos = slug.rindex('/')
+                        parent_slug = slug[:pos]
+
+                        print("Parent slug: " + parent_slug)
+                        
+                        for cp in created_posts:
+                            if cp.get(parent_slug, None) != None:
+                                parent_id = cp[parent_slug]._id
+                                print("Parent_id found")
+                                break
 
                 p = thread.add_post(
                         subject=post_json['subject'],
@@ -220,5 +226,5 @@ class ForgeDiscussionImporter(AlluraImporter):
 
                 p.add_multiple_attachments([File(a["url"]) for a in post_json["attachments"]])
 
-                prev = p
-
+                if slug != '': 
+                    created_posts.append({ slug: p })


[allura] 09/50: [#7935] Fixed bug where forums and threads are related to a wrong app

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 956cbc78a632ff15bd214cdac0f6f3401126a2ce
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Thu Feb 27 15:10:18 2020 +0100

    [#7935] Fixed bug where forums and threads are related to a wrong app
---
 ForgeImporters/forgeimporters/forge/discussion.py | 82 ++++++++++++-----------
 1 file changed, 42 insertions(+), 40 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 0d256cb..7b78f32 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -99,46 +99,48 @@ class ForgeDiscussionImporter(ToolImporter):
 		)
 		ThreadLocalORMSession.flush_all()
 
-		# Deleting the forums that are created by default
-		forums = app.forums
-		for forum in forums:
-			forum.delete()
-       
-		try:
-			M.session.artifact_orm_session._get().skip_mod_date = True
-
-			for forum_json in discussion_json['forums']:
-
-				print("forum_json: ", forum_json)
-
-				new_forum = dict(
-                    			app_config_id = app.config._id,
-                    			shortname=forum_json['shortname'],
-                                discussion_id=forum_json.get('discussion_id', None),
-                    			_id=forum_json.get('_id', None),
-                    			description=forum_json['description'],
-                    			name=forum_json['name'],
-                    			create='on',
-                    			parent='',
-                    			members_only=False,
-                    			anon_posts=False,
-                    			monitoring_email=None,
-				)
-
-				print("New Forum:", new_forum)
-
-				forum = utils.create_forum(app, new_forum=new_forum)
-
-				for thread_json in forum_json["threads"]:
-					thread = forum.get_discussion_thread(dict(
-                                		headers=dict(Subject=thread_json['subject'])))[0]
-
-					self.add_posts(thread, thread_json['posts'], app)
-
-				session(forum).flush(forum)
-				session(forum).expunge(forum)
-
-				print("Forum %s created" % (new_forum["shortname"]))
+        with h.push_config(c, app=app):
+
+            # Deleting the forums that are created by default
+            forums = app.forums
+            for forum in forums:
+                forum.delete()
+           
+            try:
+                M.session.artifact_orm_session._get().skip_mod_date = True
+
+                for forum_json in discussion_json['forums']:
+
+                    print("forum_json: ", forum_json)
+
+                    new_forum = dict(
+                                    app_config_id = app.config._id,
+                                    shortname=forum_json['shortname'],
+                                    discussion_id=forum_json.get('discussion_id', None),
+                                    _id=forum_json.get('_id', None),
+                                    description=forum_json['description'],
+                                    name=forum_json['name'],
+                                    create='on',
+                                    parent='',
+                                    members_only=False,
+                                    anon_posts=False,
+                                    monitoring_email=None,
+                    )
+
+                    print("New Forum:", new_forum)
+
+                    forum = utils.create_forum(app, new_forum=new_forum)
+
+                    for thread_json in forum_json["threads"]:
+                        thread = forum.get_discussion_thread(dict(
+                                            headers=dict(Subject=thread_json['subject'])))[0]
+
+                        self.add_posts(thread, thread_json['posts'], app)
+
+                    session(forum).flush(forum)
+                    session(forum).expunge(forum)
+
+                    print("Forum %s created" % (new_forum["shortname"]))
 
 			g.post_event('project_updated')
 			ThreadLocalORMSession.flush_all()


[allura] 27/50: [#7935] Added test for add_posts with attachments

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit f6d08ecd38c3c21548efb31d4870e0274cdf02db
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 18:42:22 2020 +0100

    [#7935] Added test for add_posts with attachments
---
 .../forgeimporters/tests/forge/test_discussion.py  | 45 ++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index feb9dfc..5cea6ab 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -26,6 +26,7 @@ from ming.odm import ThreadLocalORMSession
 from allura import model as M
 from forgeimporters.forge import discussion
 from forgediscussion import utils
+from forgeimporters.base import File
 
 
 class TestDiscussionImporter(TestCase):
@@ -887,6 +888,50 @@ class TestDiscussionImporter(TestCase):
             pass
 
 
+    @mock.patch.object(discussion, 'File')
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'h')
+    def test_add_posts_with_attachments(self, h, c, File):
+        """ This method checks if add_posts supports posts with attachment """
+
+        importer, app, thread, user, post = self.__init_add_posts_tests()
+        File.side_effect = ['a1', 'a2', 'a3']
+
+        _json = [
+            {
+                "attachments": [
+                    {
+                        "url": "http://www.foo.com/attachment0",
+                        "path": "path/to/attachment0",
+                        "bytes": 145 
+                    },
+                    {
+                        "url": "http://www.foo.com/attachment1",
+                        "path": "path/to/attachment1",
+                        "bytes": 184
+                    },
+                    {
+                        "url": "http://www.foo.com/attachment2",
+                        "path": "path/to/attachment2",
+                        "bytes": 145 
+                    },
+                ],
+                "author": "user02",
+                "timestamp": "2020-01-29 22:42:58.478000",
+                "text": "asdf as",
+                "subject": "topic with attachments"
+            }
+        ]
+
+        importer.add_posts(thread, _json, app)
+
+        post.add_multiple_attachments.assert_called_once()
+        self.assertEqual(File.call_args_list, [
+            mock.call('http://www.foo.com/attachment0'),
+            mock.call('http://www.foo.com/attachment1'),
+            mock.call('http://www.foo.com/attachment2')
+        ])
+
     def __init_add_posts_tests(self):
         importer = discussion.ForgeDiscussionImporter()
 


[allura] 04/50: [#7935] Made minor changes

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 575ef5dca3e5795a0ebe89a7002c803b34533a36
Author: Korkmatik <fa...@protonmail.ch>
AuthorDate: Fri Jan 17 23:49:02 2020 +0100

    [#7935] Made minor changes
---
 ForgeImporters/forgeimporters/forge/discussion.py | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 62187fc..ce81b43 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -95,14 +95,17 @@ class ForgeDiscussionImporter(ToolImporter):
 		discussion_json['discussion_config']['options'].pop('import_id', None)
 
 		mount_point = mount_point or 'discussion'
+		mount_label = mount_label or 'Discussion'
 
-
-		_id = discussions_json.get('_id', 'undefined')
+		_id = discussions_json['discussion_config'].get('_id', 'undefined')
 		_open_status_names = discussions_json.get('open_status_names', 'undefined')
 		_closed_status_names = discussions_json.get('closed_status_names', 'undefined')
 
 		app = project.install_app('discussion', mount_point, mount_label,
-                    import_id={'source': self.source, 'app_config_id': _id },
+                    import_id={
+                        'source': self.source, 
+                        'app_config_id': _id 
+                    },
 					open_status_names=_open_status_names,
 					closed_status_names=_closed_status_names,
 					**discussion_json['discussion_config']['options']
@@ -117,6 +120,7 @@ class ForgeDiscussionImporter(ToolImporter):
 				print("forum_json: ", forum_json)
 
 				new_forum = dict(
+                    app_config_id = app.config._id,
                     shortname=forum_json['shortname'],
                     _id=forum_json.get('_id', ''),
                     description=forum_json['description'],
@@ -125,7 +129,7 @@ class ForgeDiscussionImporter(ToolImporter):
                     parent='',
                     members_only=False,
                     anon_posts=False,
-                    monitoring_email=None
+                    monitoring_email=None,
 				) 
 
 				print(new_forum)
@@ -136,21 +140,22 @@ class ForgeDiscussionImporter(ToolImporter):
 					thread = forum.get_discussion_thread(dict(
                                 headers=dict(Subject=thread_json['subject'])))[0]
 
-					self.add_posts(thread, thread_json['posts'])
+					self.add_posts(thread, thread_json['posts'], app)
 
 				session(forum).flush(forum)
 				session(forum).expunge(forum)
 
-                #perform_import(discussion_json, user)
-
 				print("Forum %s created" % (new_forum["shortname"]))
 
 			g.post_event('project_updated')
 			app.globals.invalidate_bin_counts()
+			ThreadLocalORMSession.flush_all()
 			return app
 		except Exception:
 			h.make_app_admin_only(app)
 			raise
+		finally:
+			M.session.artifact_orm_session._get().skip_mod_date = False
                                      
 
     def get_user(self, username):
@@ -167,12 +172,12 @@ class ForgeDiscussionImporter(ToolImporter):
             return '*Originally%s by:* %s\n\n%s' % (label, username, text)
         return text
 
-    def add_posts(self, thread, posts):
+    def add_posts(self, thread, posts, app):
         for post_json in posts:
             print("Author: ", post_json["author"])
             user = self.get_user(post_json["author"])
             print("User", user)
-            with h.push_config(c, user=user):
+            with h.push_config(c, user=user, app=app):
                 p = thread.add_post(
                         subject=post_json['subject'],
                         text=post_json['text'], 


[allura] 03/50: [#7935] Updated the import_tool method

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit ecfd5514f9ac8c010bdfbcdcca1eed2d8d88ecb1
Author: Korkmatik <fa...@protonmail.ch>
AuthorDate: Sun Dec 22 15:22:01 2019 +0100

    [#7935] Updated the import_tool method
---
 ForgeImporters/forgeimporters/forge/discussion.py | 73 +++++++++++++----------
 1 file changed, 42 insertions(+), 31 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index aa7ec3c..62187fc 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -85,29 +85,38 @@ class ForgeDiscussionImporter(ToolImporter):
 
     def import_tool(self, project, user, mount_point=None,
                      mount_label=None, **kw):
-        print("import_tool")
-        #import_id_converter = ImportIdConverter.get()
-        discussion_json = self._load_json(project)
         
-        mount_point = mount_point or 'discussion'
-
-
-        #_id = forum_json['_id']
-        _id = 'undefined'
-
-        app = project.install_app('discussion', mount_point, mount_label,
-                    import_id={'source': self.source, 'app_config_id': _id }
-        )
-        ThreadLocalORMSession.flush_all()
+		print("import_tool")
+		import_id_converter = ImportIdConverter.get()
+		discussion_json = self._load_json(project)
+		discussion_json['discussion_config']['options'].pop('ordinal', None)
+		discussion_json['discussion_config']['options'].pop('mount_point', None)
+		discussion_json['discussion_config']['options'].pop('mount_label', None)
+		discussion_json['discussion_config']['options'].pop('import_id', None)
+
+		mount_point = mount_point or 'discussion'
+
+
+		_id = discussions_json.get('_id', 'undefined')
+		_open_status_names = discussions_json.get('open_status_names', 'undefined')
+		_closed_status_names = discussions_json.get('closed_status_names', 'undefined')
+
+		app = project.install_app('discussion', mount_point, mount_label,
+                    import_id={'source': self.source, 'app_config_id': _id },
+					open_status_names=_open_status_names,
+					closed_status_names=_closed_status_names,
+					**discussion_json['discussion_config']['options']
+		)
+		ThreadLocalORMSession.flush_all()
        
-        try:
-            M.session.artifact_orm_session._get().skip_mod_date = True
+		try:
+			M.session.artifact_orm_session._get().skip_mod_date = True
 
-            for forum_json in discussion_json['forums']:
+			for forum_json in discussion_json['forums']:
 
-                print("forum_json: ", forum_json)
+				print("forum_json: ", forum_json)
 
-                new_forum = dict(
+				new_forum = dict(
                     shortname=forum_json['shortname'],
                     _id=forum_json.get('_id', ''),
                     description=forum_json['description'],
@@ -117,29 +126,31 @@ class ForgeDiscussionImporter(ToolImporter):
                     members_only=False,
                     anon_posts=False,
                     monitoring_email=None
-               ) 
+				) 
 
-                print(new_forum)
+				print(new_forum)
 
-                forum = utils.create_forum(app, new_forum=new_forum)
+				forum = utils.create_forum(app, new_forum=new_forum)
 
-                for thread_json in forum_json["threads"]:
-                    thread = forum.get_discussion_thread(dict(
+				for thread_json in forum_json["threads"]:
+					thread = forum.get_discussion_thread(dict(
                                 headers=dict(Subject=thread_json['subject'])))[0]
 
-                    self.add_posts(thread, thread_json['posts'])
+					self.add_posts(thread, thread_json['posts'])
 
-                session(forum).flush(forum)
-                session(forum).expunge(forum)
+				session(forum).flush(forum)
+				session(forum).expunge(forum)
 
                 #perform_import(discussion_json, user)
 
-                print("Forum %s created" % (new_forum["shortname"]))
+				print("Forum %s created" % (new_forum["shortname"]))
 
-            return app
-        except Exception:
-            h.make_app_admin_only(app)
-            raise
+			g.post_event('project_updated')
+			app.globals.invalidate_bin_counts()
+			return app
+		except Exception:
+			h.make_app_admin_only(app)
+			raise
                                      
 
     def get_user(self, username):


[allura] 40/50: [#7935] Removed unncecessary code

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 09bf1e787b8fa56d2c573483b406190184eefa53
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Fri Mar 6 18:42:34 2020 +0100

    [#7935] Removed unncecessary code
---
 ForgeImporters/forgeimporters/tests/forge/test_discussion.py | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 8d4df31..5db983b 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -1310,9 +1310,6 @@ class TestForgeDiscussionController(TestController, TestCase):
     
     def setUp(self):
         super(TestForgeDiscussionController, self).setUp()
-        from forgediscussion.forum_main import ForumAdminController
-        ForumAdminController._importer = \
-                discussion.ForgeDiscussionImportController(discussion.ForgeDiscussionImporter())
 
     
     @with_discussion


[allura] 17/50: [#7935] Added tests for discussion importer

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 73cd3633fad2b42e1d12f507d61b529b53bc78dc
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Mon Mar 2 12:32:48 2020 +0100

    [#7935] Added tests for discussion importer
---
 .../forgeimporters/tests/forge/test_discussion.py  | 100 +++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
new file mode 100644
index 0000000..661525d
--- /dev/null
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -0,0 +1,100 @@
+#       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.
+
+from unittest import TestCase
+
+import mock
+
+from allura import model as M
+from forgeimporters.forge import discussion
+
+class TestDiscussionImporter(TestCase):
+
+    def setUp(self):
+        super(TestDiscussionImporter, self).setUp()
+
+        self.patcher_g = mock.patch('forgeimporters.base.g', mock.MagicMock())
+        self.patcher_g.start()
+
+
+    def tearDown(self):
+        super(TestDiscussionImporter, self).tearDown()
+        self.patcher_g.stop()
+
+
+    def test_annotate_text_with_existing_user(self):
+        """ This test tests the annotate_text method if an existing user is passed as argument """
+
+        importer = discussion.ForgeDiscussionImporter()
+        
+        # Creating a mock of an existing user
+        user = mock.Mock(_id=1)
+        user.is_anonymous.return_value = False
+        username = "testUser123"
+
+        self.assertEqual(importer.annotate_text('foo', user, username), 'foo')
+
+
+    def test_annotate_text_with_not_existing_user(self):
+        """ This test tests the annotate_text method with a not existing user """
+
+        importer = discussion.ForgeDiscussionImporter()
+
+        # Creating a not existing user
+        user = mock.Mock(_id=1)
+        user.is_anonymous.return_value = True
+        username = "NotAAlluraUser"
+
+        # Text of the post
+        text = 'foo'
+
+        # Text that the method should return
+        return_text = '*Originally created by:* {username}\n\n{text}'.format(username=username, text=text)
+
+        self.assertEqual(importer.annotate_text(text, user, username), return_text)
+
+
+    def test_annotate_text_with_anonymous_user(self):
+        """ This test tests the annotate_text method with an anonymous user """
+
+        importer = discussion.ForgeDiscussionImporter()
+
+        # Creating an anonymous user
+        user = mock.Mock(_id=1)
+        user.is_anonymous.return_value = True
+
+        usernames = ['nobody', '*anonymous']
+
+        text = 'foo'
+
+        self.assertEqual(importer.annotate_text(text, user, usernames[0]), text)
+        self.assertEqual(importer.annotate_text(text, user, usernames[1]), text)
+
+        
+    def test_annotate_text_with_junk(self):
+        """ This test tests if the annotate_text method correctly handles junk data """
+
+        importer = discussion.ForgeDiscussionImporter()
+
+        user = None
+        text = None
+        username = None
+
+        self.assertEqual(importer.annotate_text(text, user, username), '')
+
+        text = 'foo'
+        self.assertEqual(importer.annotate_text(text, user, username), text)


[allura] 32/50: [#7935] Removed some debug code from create method in the controller

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 102bec86c5d10039edb7dced3445ac5beb129f3e
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Thu Mar 5 14:28:13 2020 +0100

    [#7935] Removed some debug code from create method in the controller
---
 ForgeImporters/forgeimporters/forge/discussion.py | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 01336bf..661aeb0 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -53,19 +53,14 @@ class ForgeDiscussionImportController(ToolImportController):
     @require_post()
     def create(self, discussions_json, mount_point, mount_label, **kw):
         # TODO: delete debug output
-        self.importer.clear_pending(c.project) # TODO: Delete this line
+        #self.importer.clear_pending(c.project) # TODO: Delete this line
         if self.importer.enforce_limit(c.project):
-            print("import 1")
-            save_importer_upload(c.project, 'discussion.json', json.dumps(discussions_json))
-            print("import 2")
+            save_importer_upload(c.project, 'discussions.json', json.dumps(discussions_json))
             self.importer.post(mount_point=mount_point, mount_label=mount_label)
-            print("import 3")
             flash('Discussion import has begun. Your new discussion will be available when the import is complete')
             
         else:
-            print("import limit")
             flash('There are too many imports pending at this time. Please wait and try again.', 'error')
-        print("import none	")
 
         redirect(c.project.url() + 'admin/')
 


[allura] 19/50: [#7935] Added test for unicode characters

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit ecaa8d442b97ed8295733f0eb493981073ee9d02
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 13:02:10 2020 +0100

    [#7935] Added test for unicode characters
---
 .../forgeimporters/tests/forge/test_discussion.py  | 107 +++++++++++++++++++++
 1 file changed, 107 insertions(+)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 161f518..9526ffc 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -19,6 +19,8 @@ from unittest import TestCase
 
 import mock
 
+from dateutil.parser import parse
+
 from ming.odm import ThreadLocalORMSession
 
 from allura import model as M
@@ -128,6 +130,111 @@ class TestDiscussionImporter(TestCase):
         g.post_event.assert_called_once_with("project_updated")
 
 
+    @mock.patch.object(discussion, 'c')
+    @mock.patch.object(discussion, 'g')
+    @mock.patch.object(discussion, 'M')
+    @mock.patch.object(discussion, 'session')
+    @mock.patch.object(discussion, 'h')
+    @mock.patch.object(discussion, 'ThreadLocalORMSession')
+    def test_import_tool_unicode(self, tlos, h, session, m, g, c):
+        """ This method tests if the import tool method supports unicode characters """
+        
+        importer = discussion.ForgeDiscussionImporter()
+
+        # Creating the json to test for
+        _json = {
+            "forums": [{
+                "shortname": "general",
+                "_id": "538f7240f697c62562ed9e6f",
+                "description": "Forum about anything you want to talk about.",
+                "name": "General Discussion",
+                "threads": [{
+                          "limit": None,
+                          "discussion_id": "538f7240f697c62562ed9e6f",
+                          "_id": "88983164e3",
+                          "posts": [
+                            {
+                              "attachments": [],
+                              "author": "admin1",
+                              "timestamp": "2020-01-29 22:32:00.584000",
+                              "author_icon_url": "https://secure.gravatar.com/avatar/2ba5bfa33e6faca31f7dd150960ce926?r=pg&d=https%3A%2F%2F4.xb.sf.net%2Fnf%2F0%2F_ew_%2Ftheme%2Fsftheme%2Fimages%2Fsandiego%2Ficons%2Fdefault-avatar.png",
+                              "text": "test with un\u00ef\u00e7\u00f8\u2202\u00e9 text",
+                              "last_edited": None,
+                              "slug": "0e0e",
+                              "subject": "post with un\u00ef\u00e7\u00f8\u2202\u00e9"
+                            }
+                          ],
+                          "page": None,
+                          "subject": "post with un\u00ef\u00e7\u00f8\u2202\u00e9"
+                }]
+            }]
+        }
+
+        importer._load_json = mock.Mock(return_value=_json)
+        
+        project, user = mock.Mock(), mock.Mock()
+        app = project.install_app.return_value
+        app.config.options.mount_point = 'mount_point'
+        app.config.options.import_id = { 'source': 'Allura' }
+        app.config.options.get = lambda *a: getattr(app.config.options, *a)
+        app.url = 'foo'
+        app.forums = []
+        utils.create_forum = mock.Mock()
+        forum = mock.Mock()
+        thread1 = mock.Mock()
+        p = mock.Mock()
+        thread1.add_post = mock.Mock(return_value=p)
+        forum.get_discussion_thread.return_value = (thread1, mock.Mock())
+        utils.create_forum.return_value = forum
+        g.post_event = mock.Mock()
+        m.AuditLog.log = mock.Mock()
+        admin = mock.Mock(is_anonymous=lambda: False)
+        admin._id = 1
+        importer.get_user = mock.Mock(return_value=admin)
+        importer.annotate_text = mock.Mock(return_value='aa')
+
+        importer.import_tool(project, user, mount_point='mount_point', mount_label='mount_label')
+
+        project.install_app.assert_called_once_with(
+            'discussion', 'mount_point', 'mount_label',
+            import_id={ 'source': 'Allura' }
+        )
+
+        forum_json = _json["forums"][0]
+        new_forum = dict(
+             app_config_id = app.config._id,
+             shortname=forum_json['shortname'],
+             description=forum_json['description'],
+             name=forum_json['name'],
+             create='on',
+             parent='',
+             members_only=False,
+             anon_posts=False,
+             monitoring_email=None
+        )
+        utils.create_forum.assert_called_once_with(app, new_forum=new_forum)
+        forum.get_discussion_thread.assert_called_once_with(dict(headers=dict(Subject=_json["forums"][0]["threads"][0]["subject"])))
+        
+        importer.get_user.assert_called_once_with('admin1')
+    
+        self.assertEqual(h.push_config.call_args_list, [
+            mock.call(c, app=app),
+            mock.call(c, user=admin, app=app)
+        ])
+
+        post = _json["forums"][0]["threads"][0]["posts"][0]
+        thread1.add_post.assert_called_once_with(
+            subject=post["subject"],
+            text='aa',
+            timestamp=parse(post["timestamp"]),
+            ignore_security=True
+        )
+        importer.annotate_text.assert_called_once_with(post["text"], admin, post["author"])
+        p.add_multiple_attachments.assert_called_once_with([])
+
+        g.post_event.assert_called_once_with('project_updated')
+
+
     def test_annotate_text_with_existing_user(self):
         """ This test tests the annotate_text method if an existing user is passed as argument """
 


[allura] 06/50: [#7935] No general discussion will be created by default after the import

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 5735e7c69c33f1b371d6bc13d0862fe9842517bc
Author: Korkmatik <fa...@protonmail.ch>
AuthorDate: Sat Jan 18 12:35:51 2020 +0100

    [#7935] No general discussion will be created by default after the import
---
 ForgeImporters/forgeimporters/forge/discussion.py | 45 +++++++++++------------
 1 file changed, 22 insertions(+), 23 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 7ac5831..688c7b2 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -91,20 +91,19 @@ class ForgeDiscussionImporter(ToolImporter):
 		print("import_tool")
 		import_id_converter = ImportIdConverter.get()
 		discussion_json = self._load_json(project)
-		#discussion_json['discussion_config']['options'].pop('ordinal', None)
-		#discussion_json['discussion_config']['options'].pop('mount_point', None)
-		#discussion_json['discussion_config']['options'].pop('mount_label', None)
-		#discussion_json['discussion_config']['options'].pop('import_id', None)
 
 		mount_point = mount_point or 'discussion'
 		mount_label = mount_label or 'Discussion'
 
-		#_id = discussion_json['discussion_config'].get('_id', 'undefined')
-		#_open_status_names = discussion_json.get('open_status_names', 'undefined')
-		#_closed_status_names = discussion_json.get('closed_status_names', 'undefined')
-
-		app = project.install_app('discussion', mount_point, mount_label)
+		app = project.install_app('discussion', mount_point, mount_label, 
+			import_id={ 'source': self.source }
+		)
 		ThreadLocalORMSession.flush_all()
+
+		# Deleting the forums that are created by default
+		forums = app.forums
+		for forum in forums:
+			forum.delete()
        
 		try:
 			M.session.artifact_orm_session._get().skip_mod_date = True
@@ -114,25 +113,25 @@ class ForgeDiscussionImporter(ToolImporter):
 				print("forum_json: ", forum_json)
 
 				new_forum = dict(
-                    app_config_id = app.config._id,
-                    shortname=forum_json['shortname'],
-                    _id=forum_json.get('_id', ''),
-                    description=forum_json['description'],
-                    name=forum_json['name'],
-                    create='on',
-                    parent='',
-                    members_only=False,
-                    anon_posts=False,
-                    monitoring_email=None,
-				) 
-
-				print(new_forum)
+                    			app_config_id = app.config._id,
+                    			shortname=forum_json['shortname'],
+                    			_id=forum_json.get('_id', ''),
+                    			description=forum_json['description'],
+                    			name=forum_json['name'],
+                    			create='on',
+                    			parent='',
+                    			members_only=False,
+                    			anon_posts=False,
+                    			monitoring_email=None,
+				)
+
+				print("New Forum:", new_forum)
 
 				forum = utils.create_forum(app, new_forum=new_forum)
 
 				for thread_json in forum_json["threads"]:
 					thread = forum.get_discussion_thread(dict(
-                                headers=dict(Subject=thread_json['subject'])))[0]
+                                		headers=dict(Subject=thread_json['subject'])))[0]
 
 					self.add_posts(thread, thread_json['posts'], app)
 


[allura] 13/50: [#7935] Refactored annotate method

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 29f170340ce076e0b93aac259fee08c48a9489ae
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Fri Feb 28 19:00:01 2020 +0100

    [#7935] Refactored annotate method
---
 ForgeImporters/forgeimporters/forge/discussion.py | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 304ed25..2078a87 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -188,8 +188,10 @@ class ForgeDiscussionImporter(ToolImporter):
         return user
 
 
-    def annotate(self, text, user, username, label=''):
+    def annotate(self, text, user, username):
         if username and user.is_anonymous() and username != 'nobody' and username != '*anonymous':
+            label = " created"
+
             return '*Originally%s by:* %s\n\n%s' % (label, username, text)
         return text
 
@@ -203,7 +205,7 @@ class ForgeDiscussionImporter(ToolImporter):
             with h.push_config(c, user=user, app=app):
                 p = thread.add_post(
                         subject=post_json['subject'],
-                        text=self.annotate(post_json['text'], user, username, " created"),
+                        text=self.annotate(post_json['text'], user, username),
                         timestamp=parse(post_json["timestamp"]),
                         ignore_security=True
                 )


[allura] 07/50: [#7935] Added missing attributes

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 28d7e7fb64088ffcf669ff3c01f70efad4cfeb97
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Thu Jan 30 14:33:44 2020 +0100

    [#7935] Added missing attributes
---
 ForgeImporters/forgeimporters/forge/discussion.py | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 688c7b2..fb3bd74 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -115,7 +115,8 @@ class ForgeDiscussionImporter(ToolImporter):
 				new_forum = dict(
                     			app_config_id = app.config._id,
                     			shortname=forum_json['shortname'],
-                    			_id=forum_json.get('_id', ''),
+                                discussion_id=forum_json.get('discussion_id', None),
+                    			_id=forum_json.get('_id', None),
                     			description=forum_json['description'],
                     			name=forum_json['name'],
                     			create='on',
@@ -174,9 +175,13 @@ class ForgeDiscussionImporter(ToolImporter):
                         subject=post_json['subject'],
                         text=post_json['text'], 
                         ignore_security=True,
-                        timestamp=parse(post_json['timestamp'])
+                        timestamp=parse(post_json['timestamp']),
+                        last_edited=post_json['last_edited']
                 )
 
+                if "slug" in post_json.keys():
+                    p.slug = post_json['slug']
+
                 try:
                     p.add_multiple_attachments([File(a['url'])
                                                 for a in post_json['attachments']])


[allura] 35/50: [#7935] Added license comment

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit f5299e6931234f78b5b2777be2f0bdade4e9565b
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Thu Mar 5 16:20:59 2020 +0100

    [#7935] Added license comment
---
 ForgeImporters/forgeimporters/forge/discussion.py | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 24ee5af..8efb754 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -1,3 +1,20 @@
+#       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 os
 import json
 from dateutil.parser import parse


[allura] 21/50: [#7935] Changed to match unit tests

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit fe5b75127315cb3183a5d23ebc02ca8ce54872f9
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 16:56:44 2020 +0100

    [#7935] Changed to match unit tests
---
 ForgeImporters/forgeimporters/forge/discussion.py | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index ffeec7c..bc29dd3 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -91,8 +91,6 @@ class ForgeDiscussionImporter(AlluraImporter):
 
     def import_tool(self, project, user, mount_point=None,
                      mount_label=None, **kw):
-        
-        print("import_tool")
         discussion_json = self._load_json(project)
 
         mount_point = mount_point or 'discussion'
@@ -106,7 +104,7 @@ class ForgeDiscussionImporter(AlluraImporter):
         with h.push_config(c, app=app):
 
             # Deleting the forums that are created by default
-            self.__clear_forums(app)
+            self._clear_forums(app)
            
             try:
                 M.session.artifact_orm_session._get().skip_mod_date = True
@@ -132,6 +130,13 @@ class ForgeDiscussionImporter(AlluraImporter):
                     print("New Forum:", new_forum)
 
                     forum = utils.create_forum(app, new_forum=new_forum)
+                    
+                    if "import_id" in forum_json.keys():
+                        print("Import id for forum: " + forum_json["import_id"])
+                        forum.import_id = forum_json["import_id"]
+
+                        print("Forum: " + str(forum))
+                        print("Forum import id: " + str(forum.import_id))
 
                     for thread_json in forum_json["threads"]:
                         thread = forum.get_discussion_thread(dict(
@@ -172,7 +177,7 @@ class ForgeDiscussionImporter(AlluraImporter):
                 M.session.artifact_orm_session._get().skip_mod_date = False
                                      
 
-    def __clear_forums(self, app):
+    def _clear_forums(self, app):
       forums = app.forums
       for forum in forums:
           forum.delete()


[allura] 29/50: [#7935] Added unicode test to test annotate_text() method

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 6b92e458c85a0748c500379e48d0678a92a65500
Author: Fahri Korkmaz <f....@codesys.com>
AuthorDate: Wed Mar 4 19:03:03 2020 +0100

    [#7935] Added unicode test to test annotate_text() method
---
 .../forgeimporters/tests/forge/test_discussion.py  | 37 ++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
index 5955ab5..dd5fd44 100644
--- a/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
+++ b/ForgeImporters/forgeimporters/tests/forge/test_discussion.py
@@ -1101,6 +1101,43 @@ class TestDiscussionImporter(TestCase):
         self.assertEqual(importer.annotate_text(text, user, usernames[1]), text)
 
         
+    def test_annotate_text_with_unicode(self):
+        """ This method tests if annotate text can handle unicode characters """
+
+        importer = discussion.ForgeDiscussionImporter()
+
+        # unicode in text of an existing user
+        text = "post with un\u00ef\u00e7\u00f8\u2202\u00e9"
+        user = mock.Mock(_id=1, is_anonymous=lambda: False)
+        username = "username1"
+        try:
+            importer.annotate_text(text, user, username)
+        except:
+            self.fail("annotate_text() can't handle unicode characters")
+
+
+        # unicode in text of a not existing user
+        text = "post with un\u00ef\u00e7\u00f8\u2202\u00e9"
+        user = mock.Mock(is_anonymous=lambda: True)
+        username = "user2"
+
+        try:
+            importer.annotate_text(text, user, username)
+        except:
+            self.fail("annotate_text() can't handle unicode characters")
+
+
+        # unicode in text of an anonymous user
+        text = "post with un\u00ef\u00e7\u00f8\u2202\u00e9"
+        user = mock.Mock(is_anonymous=lambda: True)
+        username = "*anonymous"
+
+        try:
+            importer.annotate_text(text, user, username)
+        except:
+            self.fail("annotate_text() can't handle unicode characters")
+
+
     def test_annotate_text_with_junk(self):
         """ This test tests if the annotate_text method correctly handles junk data """
 


[allura] 02/50: [#7935] added annotate method

Posted by br...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

brondsem pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git

commit 63665beaf454489161a5857d1c0bdd38770d0c9e
Author: Korkmatik <fa...@protonmail.ch>
AuthorDate: Sun Dec 22 00:51:37 2019 +0100

    [#7935] added annotate method
---
 ForgeImporters/forgeimporters/forge/discussion.py | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/ForgeImporters/forgeimporters/forge/discussion.py b/ForgeImporters/forgeimporters/forge/discussion.py
index 754f1d9..aa7ec3c 100644
--- a/ForgeImporters/forgeimporters/forge/discussion.py
+++ b/ForgeImporters/forgeimporters/forge/discussion.py
@@ -50,6 +50,7 @@ class ForgeDiscussionImportController(ToolImportController):
     @require_post()
     def create(self, discussions_json, mount_point, mount_label, **kw):
         # TODO: delete debug output
+        self.importer.clear_pending(c.project) # TODO: Delete this line
         if self.importer.enforce_limit(c.project):
             print("import 1")
             save_importer_upload(c.project, 'discussion.json', json.dumps(discussions_json))
@@ -108,7 +109,7 @@ class ForgeDiscussionImporter(ToolImporter):
 
                 new_forum = dict(
                     shortname=forum_json['shortname'],
-                    _id=forum_json['_id'],
+                    _id=forum_json.get('_id', ''),
                     description=forum_json['description'],
                     name=forum_json['name'],
                     create='on',
@@ -123,16 +124,10 @@ class ForgeDiscussionImporter(ToolImporter):
                 forum = utils.create_forum(app, new_forum=new_forum)
 
                 for thread_json in forum_json["threads"]:
-                    #thread = DM.ForumThread(
-                    #    _id=thread_json['_id'],
-                    #    discussion_id=thread_json['discussion_id'],
-                    #    subject=thread_json['subject']
-                    #)
                     thread = forum.get_discussion_thread(dict(
                                 headers=dict(Subject=thread_json['subject'])))[0]
 
-                    self.add_posts(
-                        thread, thread_json['posts'])
+                    self.add_posts(thread, thread_json['posts'])
 
                 session(forum).flush(forum)
                 session(forum).expunge(forum)
@@ -157,7 +152,9 @@ class ForgeDiscussionImporter(ToolImporter):
         return user
 
     def annotate(self, text, user, username, label=''):
-        pass
+        if username and user.is_anonymous() and username != 'nobody':
+            return '*Originally%s by:* %s\n\n%s' % (label, username, text)
+        return text
 
     def add_posts(self, thread, posts):
         for post_json in posts: