You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by he...@apache.org on 2016/01/27 21:22:15 UTC

[01/50] allura git commit: [#8020] ticket:874 added filter to discussion moderation; added test for filtering [Forced Update!]

Repository: allura
Updated Branches:
  refs/heads/hs/8035 13c657ba5 -> 53baa3ab7 (forced update)


[#8020] ticket:874 added filter to discussion moderation; added test for filtering


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

Branch: refs/heads/hs/8035
Commit: 070769498ae13e9563676462dafc5b0b7ae91483
Parents: 2dd2ff0
Author: DeV1doR <de...@ukr.net>
Authored: Wed Dec 9 20:27:29 2015 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:03:17 2016 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py            |  7 +++++-
 Allura/allura/lib/widgets/discuss.py            |  2 ++
 .../allura/templates/discussion/moderate.html   |  2 +-
 .../tests/functional/test_forum.py              | 25 ++++++++++++++++++++
 4 files changed, 34 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/07076949/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index c22e772..9812a98 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -35,6 +35,7 @@ from allura.lib.decorators import require_post
 from allura.lib.security import require_access
 
 from allura.lib.widgets import discuss as DW
+from allura.model.auth import User
 from .attachments import AttachmentsController, AttachmentController
 from .feed import FeedArgs, FeedController
 
@@ -427,6 +428,7 @@ class ModerationController(BaseController):
         page = kw.pop('page', 0)
         limit = kw.pop('limit', 50)
         status = kw.pop('status', 'pending')
+        username = kw.pop('username', None)
         flag = kw.pop('flag', None)
         c.post_filter = WidgetConfig.post_filter
         c.moderate_posts = WidgetConfig.moderate_posts
@@ -437,6 +439,9 @@ class ModerationController(BaseController):
             query['status'] = status
         if flag:
             query['flags'] = {'$gte': int(flag)}
+        if username:
+            filtered_user = User.query.get(username=username)
+            query['author_id'] = getattr(filtered_user, '_id', None)
         q = self.PostModel.query.find(query)
         count = q.count()
         limit, page, start = g.handle_paging(limit, page or 0, default=50)
@@ -446,7 +451,7 @@ class ModerationController(BaseController):
         pages = (count // limit) + 1
         return dict(discussion=self.discussion,
                     posts=q, page=page, limit=limit,
-                    status=status, flag=flag,
+                    status=status, flag=flag, username=username,
                     pgnum=pgnum, pages=pages)
 
     @h.vardec

http://git-wip-us.apache.org/repos/asf/allura/blob/07076949/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index e5ab85c..9d0955f 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -123,6 +123,8 @@ class PostFilter(ff.ForgeForm):
                         label='Show posts with at least "n" flags',
                         css_class='text',
                         if_missing=0),
+            ew.InputField(name='username',
+                          label='Show post filtered by (username)'),
             ew.SubmitButton(label='Filter Posts')
         ])
     ]

http://git-wip-us.apache.org/repos/asf/allura/blob/07076949/Allura/allura/templates/discussion/moderate.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/discussion/moderate.html b/Allura/allura/templates/discussion/moderate.html
index b5f2e22..81f0c18 100644
--- a/Allura/allura/templates/discussion/moderate.html
+++ b/Allura/allura/templates/discussion/moderate.html
@@ -34,6 +34,6 @@ Moderation Queue
   <a href="?status={{status}}&amp;flag={{flag}}&amp;page={{page-limit}}">Previous Page</a>
   <a href="?status={{status}}&amp;flag={{flag}}&amp;page={{page+limit}}">Next Page</a>
 </div>
-{{c.post_filter.display(action=discussion.url()+'moderate', value=dict(status=status, flag=flag))}}
+{{c.post_filter.display(action=discussion.url()+'moderate', value=dict(status=status, flag=flag, username=username))}}
 {{c.moderate_posts.display(value=dict(posts=posts), action=discussion.url()+'moderate/save_moderation')}}
 {% endblock %}

http://git-wip-us.apache.org/repos/asf/allura/blob/07076949/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index 5c6a180..0fafe71 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -408,6 +408,31 @@ class TestForum(TestController):
             'delete': 'Delete Marked'})
         _check()
 
+    def test_user_filter(self):
+        username = 'test_username1'
+        r = self.app.get(
+            '/discussion/testforum/moderate?username=%s' % username)
+        input_field = r.html.fieldset.find('input', {'value': username})
+        assert input_field is not None
+
+        username = 341
+        r = self.app.get(
+            '/discussion/testforum/moderate?username=%s' % username)
+        input_field = r.html.fieldset.find('input', {'value': username})
+        assert input_field is not None
+
+        username = 123.43523
+        r = self.app.get(
+            '/discussion/testforum/moderate?username=%s' % username)
+        input_field = r.html.fieldset.find('input', {'value': username})
+        assert input_field is not None
+
+        username = None
+        r = self.app.get(
+            '/discussion/testforum/moderate?username=%s' % username)
+        input_field = r.html.fieldset.find('input', {'value': username})
+        assert input_field is None
+
     def test_posting(self):
         r = self.app.get('/discussion/create_topic/')
         f = r.html.find('form', {'action': '/p/test/discussion/save_new_topic'})


[25/50] allura git commit: [#8035] ESLINT FIX: max-len

Posted by he...@apache.org.
[#8035] ESLINT FIX: max-len


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

Branch: refs/heads/hs/8035
Commit: 8ad36858fc517d8279fb3785dcd62592750ffa4f
Parents: a865796
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 17:37:38 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:27 2016 -0500

----------------------------------------------------------------------
 .eslintrc                                |  6 ++----
 Allura/allura/public/nf/js/navbar.es6.js | 17 ++++++++++++++---
 2 files changed, 16 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/8ad36858/.eslintrc
----------------------------------------------------------------------
diff --git a/.eslintrc b/.eslintrc
index f3fb796..a66f2fa 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,9 +1,7 @@
 {
   "rules": {
-    "indent": [
-      2,
-      4
-    ]
+    "max-len": [1, 119, 4],
+    "indent": [2, 4]
   },
   "globals": {
     "ReactDOM": true,

http://git-wip-us.apache.org/repos/asf/allura/blob/8ad36858/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index ed8aa6d..b1a0eb3 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -142,7 +142,11 @@ var GroupingThreshold = React.createClass({
               <label htmlFor='threshold-input'>Grouping Threshold</label>
                 <ToolTip targetSelector="#threshold-input" position="top" contentAsHTML={true}/>
                 <input type='number' name='threshold-input' id="threshold-input"
-                       title='When you have multiple tools of the same type, <u>this number</u> determines if they will fit in the navigation bar or be grouped into a dropdown.'
+
+                       title='When you have multiple tools of the same type,\
+                             <u>this number</u> determines if they will fit in the navigation \
+                             bar or be grouped into a dropdown.'
+
                        value={ this.state.value }
                        onChange={ this.handleChange }
                        min='1' max='50'/>
@@ -317,8 +321,15 @@ var AdminNav = React.createClass({
                 options={ item.admin_options }
             />;
             if (subMenu) {
-                childOptionsOpen = _.contains(_.pluck(item.children, 'mount_point'), this.props.currentOptionMenu.tool);
-                tool_list.push(<NavBarItemWithSubMenu key={_.uniqueId()} tool={core_item} subMenu={subMenu} childOptionsOpen={childOptionsOpen}/>);
+                childOptionsOpen = _.contains(_.pluck(item.children, 'mount_point'),
+                    this.props.currentOptionMenu.tool);
+
+                tool_list.push(<NavBarItemWithSubMenu
+                    key={_.uniqueId()}
+                    tool={core_item}
+                    subMenu={subMenu}
+                    childOptionsOpen={childOptionsOpen}
+                />);
             } else {
                 tool_list.push(core_item);
             }


[45/50] allura git commit: [#8035] Separate .eslintrc into configs for ES5 and ES6

Posted by he...@apache.org.
[#8035] Separate .eslintrc into configs for ES5 and ES6


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

Branch: refs/heads/hs/8035
Commit: b4f0ae43a8c0445aa72374fa3251280ae206a759
Parents: 5cc34c0
Author: Heith Seewald <he...@gmail.com>
Authored: Tue Jan 26 11:35:35 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:32 2016 -0500

----------------------------------------------------------------------
 .eslintignore-es5 |  2 ++
 .eslintignore-es6 |  1 +
 .eslintrc-es5     | 42 ++++++++++++++++++++++++++++++++++++++++++
 .eslintrc-es6     | 39 +++++++++++++++++++++++++++++++++++++++
 package.json      |  4 +++-
 5 files changed, 87 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/b4f0ae43/.eslintignore-es5
----------------------------------------------------------------------
diff --git a/.eslintignore-es5 b/.eslintignore-es5
new file mode 100644
index 0000000..8dfa7af
--- /dev/null
+++ b/.eslintignore-es5
@@ -0,0 +1,2 @@
+Allura/allura/public/nf/js/build
+**/*es6.js
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/b4f0ae43/.eslintignore-es6
----------------------------------------------------------------------
diff --git a/.eslintignore-es6 b/.eslintignore-es6
new file mode 100644
index 0000000..ddff5f8
--- /dev/null
+++ b/.eslintignore-es6
@@ -0,0 +1 @@
+Allura/allura/public/nf/js/build

http://git-wip-us.apache.org/repos/asf/allura/blob/b4f0ae43/.eslintrc-es5
----------------------------------------------------------------------
diff --git a/.eslintrc-es5 b/.eslintrc-es5
new file mode 100644
index 0000000..493b774
--- /dev/null
+++ b/.eslintrc-es5
@@ -0,0 +1,42 @@
+{
+  "rules": {
+    "indent": [2, 4],
+    "no-unused-vars": [2, {"vars": "all", "args": "none"}],
+    "no-console": 0,
+    "semi": [2, "always"],
+    "eqeqeq": 2,
+    "block-scoped-var": 2,
+    "consistent-return": 2,
+    // specify curly brace conventions for all control statements
+    "curly": [2, "all"],
+    // require default case in switch statements
+    "default-case": 2,
+    // disallow use of eval()
+    "no-eval": 2,
+    // disallow adding to native types
+    "no-extend-native": 2,
+    // disallow use of eval()-like methods
+    "no-implied-eval": 2,
+    // disallow this keywords outside of classes or class-like objects
+    "no-invalid-this": 2,
+    // disallow creation of functions within loops
+    "no-loop-func": 2,
+    // disallow declaring the same variable more then once
+    "no-redeclare": 2,
+    // disallow use of the with statement
+    "no-with": 2,
+    // require use of the second argument for parseInt()
+    "radix": 2
+  },
+  "globals": {
+
+  },
+  "parser": "esprima-fb",
+  "env": {
+    "browser": true,
+    "jquery": true
+  },
+  "extends": "eslint:recommended",
+  "plugins": [
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/b4f0ae43/.eslintrc-es6
----------------------------------------------------------------------
diff --git a/.eslintrc-es6 b/.eslintrc-es6
new file mode 100644
index 0000000..455b95a
--- /dev/null
+++ b/.eslintrc-es6
@@ -0,0 +1,39 @@
+{
+  "rules": {
+    "max-len": [1, 119, 4],
+    "indent": [2, 4],
+    "jsx-quotes": [0],
+    "quotes": [0],
+    "operator-linebreak": [2, "before", { "overrides": { "?": "after", "&&": "after" } }],
+    "require-jsdoc": [2, {"require": {
+        "FunctionDeclaration": true,
+        "MethodDefinition": false,
+        "ClassDeclaration": false
+      }
+    }],
+    "no-inline-comments": 0,
+    "comma-dangle": 0
+  },
+  "globals": {
+    "ReactDOM": true,
+    "React": true,
+    "$": true,
+    "window": true,
+    "_": true,
+    "ReactReorderable": true
+  },
+  "parser": "babel-eslint",
+  "env": {
+    "es6": true,
+    "browser": true
+  },
+  "extends": "google",
+  "ecmaFeatures": {
+    "jsx": true,
+    "forOf": true,
+    "experimentalObjectRestSpread": true
+  },
+  "plugins": [
+    "react"
+  ]
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/b4f0ae43/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 1f12ff5..3ae1bc9 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,9 @@
     "watch": "broccoli-timepiece Allura/allura/public/nf/js/build/",
     "env": "env",
     "eslint": "eslint",
-    "lint": "eslint Allura/allura/public/nf/js/*.es6.js || true"
+    "lint-es5": "eslint -c .eslintrc-es5  --ignore-path .eslintignore-es5 Allura/allura/public/**/*.js || true",
+    "lint-es6": "eslint -c .eslintrc-es6  --ignore-path .eslintignore-es6 Allura/allura/public/**/*.es6.js || true",
+    "lint": "npm run lint-es5 && npm run lint-es6"
   },
   "repository": {
     "type": "git",


[17/50] allura git commit: [#8044] ticket:889 Add notification to raml doc

Posted by he...@apache.org.
[#8044] ticket:889 Add notification to raml doc


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

Branch: refs/heads/hs/8035
Commit: af8bd6e52a09ad0e370fa1dea86458f51541981a
Parents: e73efd1
Author: Denis Kotov <de...@gmail.com>
Authored: Fri Jan 22 01:54:10 2016 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:37:38 2016 -0500

----------------------------------------------------------------------
 Allura/docs/api-rest/api.raml | 8 ++++++++
 1 file changed, 8 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/af8bd6e5/Allura/docs/api-rest/api.raml
----------------------------------------------------------------------
diff --git a/Allura/docs/api-rest/api.raml b/Allura/docs/api-rest/api.raml
index 4514a2e..6326978 100755
--- a/Allura/docs/api-rest/api.raml
+++ b/Allura/docs/api-rest/api.raml
@@ -35,6 +35,14 @@ documentation:
   - title: API Overview
     content: !include docs.md
 
+/notification:
+  description: |
+    Get current Site Notification
+  uriParameters:
+    cookie:
+      description: site-notification cookie value
+      example: "56a111736c4ff90011b9f932-1-False"
+
 /{neighborhood}:
     description: |
       Neighborhoods are groups of logically related projects, which have the same default options.


[44/50] allura git commit: [#8035] ESLINT FIX: radix

Posted by he...@apache.org.
[#8035] ESLINT FIX: radix


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

Branch: refs/heads/hs/8035
Commit: 5cc34c0cc8392795ad297ad3a6c2c85a343454ad
Parents: a8f7b1d
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 19:56:18 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:32 2016 -0500

----------------------------------------------------------------------
 Allura/allura/public/nf/js/navbar.es6.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/5cc34c0c/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index ffaa371..f82ee97 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -575,7 +575,7 @@ var Main = React.createClass({
                     <GroupingThreshold
                         onUpdateThreshold={ this.onUpdateThreshold }
                         isHidden={ this.state.visible }
-                        initialValue={ parseInt(this.state.data.grouping_threshold) }/> }
+                        initialValue={ parseInt(this.state.data.grouping_threshold, 10) }/> }
                 </div>
                 <ToggleAdminButton
                     handleButtonPush={ this.handleToggleAdmin }


[24/50] allura git commit: [#8054] delete Google Code importers and tests

Posted by he...@apache.org.
[#8054] delete Google Code importers and tests


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

Branch: refs/heads/hs/8035
Commit: b956fe30b11639df2cb68374eae5b221fa72e88c
Parents: c5b6ce5
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Jan 26 13:58:43 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 13:42:50 2016 -0500

----------------------------------------------------------------------
 ForgeImporters/docs/importers/google.rst        |  30 -
 .../forgeimporters/google/__init__.py           | 449 --------------
 ForgeImporters/forgeimporters/google/code.py    | 154 -----
 ForgeImporters/forgeimporters/google/project.py |  68 ---
 ForgeImporters/forgeimporters/google/tasks.py   |  39 --
 .../google/templates/code/index.html            |  31 -
 .../google/templates/project.html               |  68 ---
 .../google/templates/tracker/index.html         |  27 -
 .../forgeimporters/google/tests/__init__.py     |  16 -
 .../forgeimporters/google/tests/test_code.py    | 146 -----
 .../forgeimporters/google/tests/test_init.py    | 130 ----
 ForgeImporters/forgeimporters/google/tracker.py | 224 -------
 .../tests/data/google/empty-issue.html          | 306 ----------
 .../data/google/test-issue-first-page.html      | 548 -----------------
 .../tests/data/google/test-issue-prev-page.html | 431 -------------
 .../tests/data/google/test-issue.html           | 535 ----------------
 .../forgeimporters/tests/google/__init__.py     |  16 -
 .../tests/google/functional/__init__.py         |  16 -
 .../tests/google/functional/test_tracker.py     | 316 ----------
 .../tests/google/test_extractor.py              | 607 -------------------
 .../forgeimporters/tests/google/test_tasks.py   |  33 -
 .../forgeimporters/tests/google/test_tracker.py | 336 ----------
 22 files changed, 4526 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/docs/importers/google.rst
----------------------------------------------------------------------
diff --git a/ForgeImporters/docs/importers/google.rst b/ForgeImporters/docs/importers/google.rst
deleted file mode 100644
index 5ed7306..0000000
--- a/ForgeImporters/docs/importers/google.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-..     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.
-
-Google Code
-===========
-
-This importer imports projects and tools from Google Code.
-
-:mod:`forgeimporters.google`
-----------------------------
-
-.. autoclass:: forgeimporters.google.project.GoogleCodeProjectImporter
-   :members:
-
-.. autoclass:: forgeimporters.google.tracker.GoogleCodeTrackerImporter
-   :members:

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/__init__.py b/ForgeImporters/forgeimporters/google/__init__.py
deleted file mode 100644
index 302544e..0000000
--- a/ForgeImporters/forgeimporters/google/__init__.py
+++ /dev/null
@@ -1,449 +0,0 @@
-#       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 re
-import urllib
-from urllib2 import HTTPError
-from urlparse import urlparse, urljoin, parse_qs
-from collections import defaultdict
-import logging
-import os
-
-import requests
-from BeautifulSoup import BeautifulSoup
-from formencode import validators as fev
-
-from allura.lib import helpers as h
-from allura import model as M
-from forgeimporters.base import ProjectExtractor
-from forgeimporters.base import File
-
-
-log = logging.getLogger(__name__)
-
-
-def _as_text(node, chunks=None):
-    """
-    Similar to node.text, but preserves whitespace around tags,
-    and converts <br/>s to \n.
-    """
-    if chunks is None:
-        chunks = []
-    for n in node:
-        if isinstance(n, basestring):
-            chunks.append(n)
-        elif n.name == 'br':
-            chunks.append('\n')
-        else:
-            _as_text(n, chunks)
-    return ''.join(chunks)
-
-
-def _as_markdown(tag, project_name):
-    fragments = []
-    for fragment in tag:
-        if getattr(fragment, 'name', None) == 'a':
-            href = urlparse(fragment['href'])
-            qs = parse_qs(href.query)
-            gc_link = not href.netloc or href.netloc == 'code.google.com'
-            path_parts = href.path.split('/')
-            target_project = None
-            if gc_link:
-                if len(path_parts) >= 5 and path_parts[1] == 'a':
-                    target_project = '/'.join(path_parts[1:5])
-                elif len(path_parts) >= 3:
-                    target_project = path_parts[2]
-            internal_link = target_project == project_name
-            if gc_link and internal_link and 'id' in qs:
-                # rewrite issue 123 project-internal issue links
-                fragment = '[%s](#%s)' % (fragment.text, qs['id'][0])
-            elif gc_link and internal_link and 'r' in qs:
-                # rewrite r123 project-internal revision links
-                fragment = '[r%s]' % qs['r'][0]
-            elif gc_link:
-                # preserve GC-internal links (probably issue PROJECT:123
-                # inter-project issue links)
-                fragment = '[%s](%s)' % (
-                    h.plain2markdown(
-                        fragment.text, preserve_multiple_spaces=True, has_html_entities=True),
-                    # possibly need to adjust this URL for /a/ hosted domain URLs,
-                    # but it seems fragment['href'] always starts with / so it replaces the given path
-                    urljoin('https://code.google.com/p/%s/issues/' %
-                            project_name, fragment['href']),
-                )
-            else:
-                # convert all other links to Markdown syntax
-                fragment = '[%s](%s)' % (fragment.text, fragment['href'])
-        elif getattr(fragment, 'name', None) == 'i':
-            # preserve styling of "(No comment was entered for this change.)"
-            # messages
-            fragment = '*%s*' % h.plain2markdown(fragment.text,
-                                                 preserve_multiple_spaces=True, has_html_entities=True)
-        elif getattr(fragment, 'name', None) == 'b':
-            # preserve styling of issue template
-            fragment = '**%s**' % h.plain2markdown(fragment.text,
-                                                   preserve_multiple_spaces=True, has_html_entities=True)
-        elif getattr(fragment, 'name', None) == 'br':
-            # preserve forced line-breaks
-            fragment = '\n'
-        else:
-            # convert all others to plain MD
-            fragment = h.plain2markdown(
-                unicode(fragment), preserve_multiple_spaces=True, has_html_entities=True)
-        fragments.append(fragment)
-    return ''.join(fragments).strip()
-
-
-def csv_parser(page):
-    lines = page.readlines()
-    if not lines:
-        return []
-    # skip CSV header
-    lines = lines[1:]
-    # skip "next page here" info footer
-    if not lines[-1].startswith('"'):
-        lines.pop()
-    # remove CSV wrapping (quotes, commas, newlines)
-    return [line.strip('",\n') for line in lines]
-
-
-class GoogleCodeProjectNameValidator(fev.FancyValidator):
-    not_empty = True
-    messages = {
-        'invalid': 'Please enter a project URL, or a project name containing '
-                   'only letters, numbers, and dashes.',
-        'unavailable': 'This project is unavailable for import',
-    }
-
-    def _to_python(self, value, state=None):
-        project_name_re = re.compile(r'^[a-z0-9][a-z0-9-]{,61}$')
-        if project_name_re.match(value):
-            # just a name
-            project_name = value
-        else:
-            # try as a URL
-            project_name = None
-            project_name_simple = None
-            url = urlparse(value.strip())
-            if url.netloc.endswith('.googlecode.com'):
-                project_name = url.netloc.split('.')[0]
-            elif url.netloc == 'code.google.com':
-                path_parts = url.path.lstrip('/').split('/')
-                if len(path_parts) >= 2 and path_parts[0] == 'p':
-                    project_name = path_parts[1]
-                elif len(path_parts) >= 4 and path_parts[0] == 'a' and path_parts[2] == 'p':
-                    project_name_simple = path_parts[3]
-                    project_name = '/'.join(path_parts[0:4])
-
-            if not project_name_simple:
-                project_name_simple = project_name
-
-            if not project_name or not project_name_re.match(project_name_simple):
-                raise fev.Invalid(self.message('invalid', state), value, state)
-
-        if not GoogleCodeProjectExtractor(project_name).check_readable():
-            raise fev.Invalid(self.message('unavailable', state), value, state)
-        return project_name
-
-
-def split_project_name(project_name):
-    '''
-    For hosted projects, the project_name includes the hosted domain.  Split, like:
-
-    :param str project_name: "a/eclipselabs.org/p/restclient-tool"
-    :return: ``("/a/eclipselabs.org", "restclient-tool")``
-    '''
-    if project_name.startswith('a/'):
-        hosted_domain_prefix = '/a/' + project_name.split('/')[1]
-        project_name = project_name.split('/')[3]
-    else:
-        hosted_domain_prefix = ''
-        project_name = project_name
-    return hosted_domain_prefix, project_name
-
-
-class GoogleCodeProjectExtractor(ProjectExtractor):
-    BASE_URL = 'http://code.google.com'
-    RE_REPO_TYPE = re.compile(r'(svn|hg|git)')
-
-    PAGE_MAP = {
-        'project_info': BASE_URL + '{hosted_domain_prefix}/p/{project_name}/',
-        'source_browse': BASE_URL + '{hosted_domain_prefix}/p/{project_name}/source/browse/',
-        'issues_csv': BASE_URL + '{hosted_domain_prefix}/p/{project_name}/issues/csv?can=1&colspec=ID&sort=ID&start={start}',
-        'issue': BASE_URL + '{hosted_domain_prefix}/p/{project_name}/issues/detail?id={issue_id}',
-    }
-
-    LICENSE_MAP = defaultdict(lambda: 'Other/Proprietary License', {
-        'Apache License 2.0': 'Apache License V2.0',
-        'Artistic License/GPL': 'Artistic License',
-        'Eclipse Public License 1.0': 'Eclipse Public License',
-        'GNU GPL v2': 'GNU General Public License version 2.0 (GPLv2)',
-        'GNU GPL v3': 'GNU General Public License version 3.0 (GPLv3)',
-        'GNU Lesser GPL': 'GNU Library or Lesser General Public License version 2.0 (LGPLv2)',
-        'MIT License': 'MIT License',
-        'Mozilla Public License 1.1': 'Mozilla Public License 1.1 (MPL 1.1)',
-        'New BSD License': 'BSD License',
-        'Other Open Source': 'Open Software License',
-    })
-
-    DEFAULT_ICON = 'http://www.gstatic.com/codesite/ph/images/defaultlogo.png'
-
-    def get_page_url(self, page_name, **kw):
-        # override, to handle hosted domains
-        hosted_domain_prefix, project_name = split_project_name(self.project_name)
-        return self.PAGE_MAP[page_name].format(
-            project_name=urllib.quote(project_name),
-            hosted_domain_prefix=hosted_domain_prefix,
-            **kw)
-
-    def check_readable(self):
-        resp = requests.head(self.get_page_url('project_info'))
-        return resp.status_code == 200
-
-    def get_short_description(self, project):
-        page = self.get_page('project_info')
-        project.short_description = page.find(
-            itemprop='description').text.strip()
-
-    def get_icon(self, project):
-        page = self.get_page('project_info')
-        icon_url = urljoin(self.url, page.find(itemprop='image').get('src'))
-        if icon_url == self.DEFAULT_ICON:
-            return
-        icon_name = urllib.unquote(urlparse(icon_url).path).split('/')[-1]
-        icon = File(icon_url, icon_name)
-        filetype = icon.type
-        # work around Google Code giving us bogus file type
-        if filetype.startswith('text/html'):
-            filetype = 'image/png'
-        M.ProjectFile.save_image(
-            icon_name, icon.file, filetype,
-            square=True, thumbnail_size=(48, 48),
-            thumbnail_meta={'project_id': project._id, 'category': 'icon'})
-
-    def get_license(self, project):
-        page = self.get_page('project_info')
-        license = page.find(text='Code license').findNext().find(
-            'a').text.strip()
-        trove = M.TroveCategory.query.get(fullname=self.LICENSE_MAP[license])
-        project.trove_license.append(trove._id)
-
-    def get_repo_type(self):
-        page = self.get_page('source_browse')
-        repo_type = page.find(id="crumb_root")
-        if not repo_type:
-            raise Exception("Couldn't detect repo type: no #crumb_root in "
-                            "{0}".format(self.url))
-        re_match = self.RE_REPO_TYPE.match(repo_type.text.lower())
-        if re_match:
-            return re_match.group(0)
-        else:
-            raise Exception("Unknown repo type: {0}".format(repo_type.text))
-
-    @classmethod
-    def iter_issues(cls, project_name):
-        """
-        Iterate over all issues for a project,
-        using paging to keep the responses reasonable.
-        """
-        extractor = cls(project_name)
-        issue_ids = extractor.get_issue_ids(start=0)
-        while issue_ids:
-            for issue_id in sorted(issue_ids):
-                try:
-                    yield (int(issue_id), cls(project_name, 'issue', issue_id=issue_id))
-                except HTTPError as e:
-                    if e.code == 404:
-                        log.warn('Unable to load GC issue: %s #%s: %s: %s',
-                                 project_name, issue_id, e, e.url)
-                        continue
-                    else:
-                        raise
-            # get any new issues that were created while importing
-            # (jumping back a few in case some were deleted and new ones added)
-            new_ids = extractor.get_issue_ids(start=len(issue_ids) - 10)
-            issue_ids = new_ids - issue_ids
-
-    def get_issue_ids(self, start=0):
-        limit = 100
-
-        issue_ids = set()
-        page = self.get_page('issues_csv', parser=csv_parser, start=start)
-        while page:
-            if len(page) <= 0:
-                return
-            issue_ids.update(page)
-            start += limit
-            page = self.get_page('issues_csv', parser=csv_parser, start=start)
-        return issue_ids
-
-    def get_issue_summary(self):
-        text = self.page.find(id='issueheader').findAll(
-            'td', limit=2)[1].span.text.strip()
-        bs = BeautifulSoup(text, convertEntities=BeautifulSoup.HTML_ENTITIES)
-        return bs.text
-
-    def get_issue_description(self):
-        return _as_markdown(self.page.find(id='hc0').pre, self.project_name)
-
-    def get_issue_created_date(self):
-        return self.page.find(id='hc0').find('span', 'date').get('title')
-
-    def get_issue_mod_date(self):
-        comments = list(self.iter_comments())
-        if comments:
-            last_update = comments[-1]
-            return last_update.created_date
-        else:
-            return self.get_issue_created_date()
-
-    def get_issue_creator(self):
-        a = self.page.find(id='hc0').find(True, 'userlink')
-        return UserLink(a)
-
-    def get_issue_status(self):
-        tag = self.page.find(id='issuemeta').find(
-            'th', text=re.compile('Status:')).findNext().span
-        if tag:
-            return tag.text.strip()
-        else:
-            return ''
-
-    def get_issue_owner(self):
-        tag = self.page.find(id='issuemeta').find(
-            'th', text=re.compile('Owner:')).findNext().find(True, 'userlink')
-        if tag:
-            return UserLink(tag)
-        else:
-            return None
-
-    def get_issue_labels(self):
-        label_nodes = self.page.find(id='issuemeta').findAll('a', 'label')
-        return [_as_text(l) for l in label_nodes]
-
-    def get_issue_attachments(self):
-        return _get_attachments(self.page.find(id='hc0'))
-
-    def get_issue_stars(self):
-        stars_re = re.compile(r'(\d+) (person|people) starred this issue')
-        stars = self.page.find(id='issueheader').find(text=stars_re)
-        if stars:
-            return int(stars_re.search(stars).group(1))
-        return 0
-
-    def iter_comments(self):
-        # first, get all pages if there are multiple pages of comments
-        looking_for_comment_pages = True
-        comment_page_urls = [self.url]
-        while looking_for_comment_pages:
-            first_comment = self.page.find('div', 'vt issuecomment')
-            looking_for_comment_pages = False
-            if first_comment and 'cursor_off' not in first_comment['class']:
-                # this is not a real comment, just forward/back links
-                for link in first_comment.findAll('a'):
-                    if link.text.startswith('Older'):
-                        prev_comments_page = urljoin(self.url, link['href'])
-                        comment_page_urls.insert(0, prev_comments_page)
-                        looking_for_comment_pages = True
-                        self.get_page(prev_comments_page)  # prep for next iteration of loop
-
-        # then go through those to get the actual comments
-        for comment_page_url in comment_page_urls:
-            self.get_page(comment_page_url)
-            # regular comments have cursor_off class
-            for comment in self.page.findAll('div', 'cursor_off vt issuecomment'):
-                yield Comment(comment, self.project_name)
-
-
-
-
-
-class UserLink(object):
-
-    def __init__(self, tag):
-        self.name = tag.text.strip()
-        if tag.get('href'):
-            self.url = urljoin(
-                GoogleCodeProjectExtractor.BASE_URL, tag.get('href'))
-        else:
-            self.url = None
-
-    def __str__(self):
-        if self.url:
-            return '[{name}]({url})'.format(name=self.name, url=self.url)
-        else:
-            return self.name
-
-
-def _get_attachments(tag):
-    attachment_links = tag.find('div', 'attachments')
-    if attachment_links:
-        attachments = []
-        for a in attachment_links.findAll('a', text='Download'):
-            url = a.parent.get('href')
-            try:
-                attachment = Attachment(url)
-            except Exception:
-                log.exception('Could not get attachment: %s', url)
-            else:
-                attachments.append(attachment)
-        return attachments
-    else:
-        return []
-
-
-class Comment(object):
-
-    def __init__(self, tag, project_name):
-        self.author = UserLink(
-            tag.find('span', 'author').find(True, 'userlink'))
-        self.created_date = tag.find('span', 'date').get('title')
-        self.body = _as_markdown(tag.find('pre'), project_name)
-        self._get_updates(tag)
-        self.attachments = _get_attachments(tag)
-
-    def _get_updates(self, tag):
-        _updates = tag.find('div', 'updates')
-        self.updates = {
-            b.text: b.nextSibling.strip()
-            for b in _updates.findAll('b')} if _updates else {}
-
-    @property
-    def annotated_text(self):
-        text = (
-            u'*Originally posted by:* {author}\n'
-            u'\n'
-            u'{body}\n'
-            u'\n'
-            u'{updates}'
-        ).format(
-            author=self.author,
-            body=self.body,
-            updates='\n'.join(
-                '**%s** %s' % (k, v)
-                for k, v in self.updates.items()
-            ),
-        )
-        return text
-
-
-class Attachment(File):
-
-    def __init__(self, url):
-        url = urljoin(GoogleCodeProjectExtractor.BASE_URL, url)
-        filename = parse_qs(urlparse(url).query)['name'][0]
-        super(Attachment, self).__init__(url, filename)

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/code.py b/ForgeImporters/forgeimporters/google/code.py
deleted file mode 100644
index 6a3f43c..0000000
--- a/ForgeImporters/forgeimporters/google/code.py
+++ /dev/null
@@ -1,154 +0,0 @@
-#       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 urllib2
-
-import formencode as fe
-from formencode import validators as fev
-
-from pylons import tmpl_context as c
-from pylons import app_globals as g
-from tg import (
-    expose,
-    flash,
-    redirect,
-)
-from tg.decorators import (
-    with_trailing_slash,
-    without_trailing_slash,
-)
-
-from allura.lib import validators as v
-from allura.lib.decorators import require_post
-from allura import model as M
-
-from forgeimporters.base import (
-    ToolImporter,
-    ToolImportController,
-)
-from forgeimporters.google import GoogleCodeProjectExtractor
-from forgeimporters.google import GoogleCodeProjectNameValidator
-from forgeimporters.google import split_project_name
-
-REPO_URLS = {
-    'svn': 'http://{project_name}.googlecode.com/svn/',
-    'svn-hosted': 'http://svn.codespot.com{hosted_domain_prefix}/{project_name}/',
-    'git': 'https://code.google.com{hosted_domain_prefix}/p/{project_name}/',
-    'hg': 'https://code.google.com{hosted_domain_prefix}/p/{project_name}/',
-}
-
-
-def get_repo_url(project_name, type_):
-    hosted_domain_prefix, project_name = split_project_name(project_name)
-    if hosted_domain_prefix and type_ == 'svn':
-        type_ = 'svn-hosted'
-    return REPO_URLS[type_].format(project_name=project_name,
-                                   hosted_domain_prefix=hosted_domain_prefix)
-
-
-class GoogleRepoImportForm(fe.schema.Schema):
-    gc_project_name = GoogleCodeProjectNameValidator()
-    mount_point = fev.UnicodeString()
-    mount_label = fev.UnicodeString()
-
-    def __init__(self, *args):
-        pass
-
-    def _to_python(self, value, state):
-        value = super(self.__class__, self)._to_python(value, state)
-
-        gc_project_name = value['gc_project_name']
-        mount_point = value['mount_point']
-        try:
-            repo_type = GoogleCodeProjectExtractor(
-                gc_project_name).get_repo_type()
-        except urllib2.HTTPError as e:
-            if e.code == 404:
-                msg = 'No such project'
-            else:
-                msg = str(e)
-            msg = 'gc_project_name:' + msg
-            raise fe.Invalid(msg, value, state)
-        except Exception:
-            raise
-        tool_class = g.entry_points['tool'][repo_type]
-        try:
-            value['mount_point'] = v.MountPointValidator(
-                tool_class).to_python(mount_point)
-        except fe.Invalid as e:
-            raise fe.Invalid('mount_point:' + str(e), value, state)
-        return value
-
-
-class GoogleRepoImportController(ToolImportController):
-    import_form = GoogleRepoImportForm
-
-    @with_trailing_slash
-    @expose('jinja:forgeimporters.google:templates/code/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, gc_project_name, mount_point, mount_label, **kw):
-        if self.importer.enforce_limit(c.project):
-            self.importer.post(
-                project_name=gc_project_name,
-                mount_point=mount_point,
-                mount_label=mount_label)
-            flash('Repo import has begun. Your new repo 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')
-        redirect(c.project.url() + 'admin/')
-
-
-class GoogleRepoImporter(ToolImporter):
-    target_app_ep_names = ('git', 'hg', 'svn')
-    source = 'Google Code'
-    controller = GoogleRepoImportController
-    tool_label = 'Source Code'
-    tool_description = 'Import your primary SVN, Git, or Hg repo from Google Code'
-
-    def import_tool(self, project, user, project_name=None, mount_point=None,
-                    mount_label=None, **kw):
-        """ Import a Google Code repo into a new SVN, Git, or Hg Allura tool.
-
-        """
-        extractor = GoogleCodeProjectExtractor(project_name, 'source_browse')
-        repo_type = extractor.get_repo_type()
-        repo_url = get_repo_url(project_name, repo_type)
-        app = project.install_app(
-            repo_type,
-            mount_point=mount_point or 'code',
-            mount_label=mount_label or 'Code',
-            init_from_url=repo_url,
-            import_id={
-                'source': self.source,
-                'project_name': project_name,
-            }
-        )
-        M.AuditLog.log(
-            'import tool %s from %s on %s' % (
-                app.config.options.mount_point,
-                project_name, self.source,
-            ), project=project, user=user, url=app.url)
-        g.post_event('project_updated')
-        return app

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/project.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/project.py b/ForgeImporters/forgeimporters/google/project.py
deleted file mode 100644
index 9ffade1..0000000
--- a/ForgeImporters/forgeimporters/google/project.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#       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 logging
-
-from tg import expose, validate
-from tg.decorators import with_trailing_slash
-
-from allura.lib.decorators import require_post
-
-from forgeimporters import base
-from forgeimporters.google import tasks
-from forgeimporters.google import GoogleCodeProjectNameValidator
-
-
-log = logging.getLogger(__name__)
-
-
-class GoogleCodeProjectForm(base.ProjectImportForm):
-    project_name = GoogleCodeProjectNameValidator()
-
-
-class GoogleCodeProjectImporter(base.ProjectImporter):
-
-    """
-    Project importer for Google Code.
-
-    This imports project metadata, including summary, icon, and license,
-    as well as providing the UI for importing individual tools during project
-    import.
-    """
-    source = 'Google Code'
-    process_validator = GoogleCodeProjectForm(source)
-    index_template = 'jinja:forgeimporters.google:templates/project.html'
-
-    def after_project_create(self, project, **kw):
-        project.set_tool_data('google-code', project_name=project.name)
-        tasks.import_project_info.post(project.name)
-
-    @with_trailing_slash
-    @expose(index_template)
-    def index(self, **kw):
-        return super(self.__class__, self).index(**kw)
-
-    @require_post()
-    @expose()
-    @validate(process_validator, error_handler=index)
-    def process(self, **kw):
-        return super(self.__class__, self).process(**kw)
-
-    @expose('json:')
-    @validate(process_validator)
-    def check_names(self, **kw):
-        return super(self.__class__, self).check_names(**kw)

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/tasks.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tasks.py b/ForgeImporters/forgeimporters/google/tasks.py
deleted file mode 100644
index b0cb76f..0000000
--- a/ForgeImporters/forgeimporters/google/tasks.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#       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 pylons import tmpl_context as c
-from pylons import app_globals as g
-
-from ming.orm import ThreadLocalORMSession
-
-from allura.lib.decorators import task
-
-from forgeimporters.base import ImportErrorHandler
-from forgeimporters.google import GoogleCodeProjectExtractor
-
-
-@task
-def import_project_info(project_name):
-    from forgeimporters.google.project import GoogleCodeProjectImporter
-    importer = GoogleCodeProjectImporter(None)
-    with ImportErrorHandler(importer, project_name, c.project) as handler:
-        extractor = GoogleCodeProjectExtractor(project_name, 'project_info')
-        extractor.get_short_description(c.project)
-        extractor.get_icon(c.project)
-        extractor.get_license(c.project)
-        ThreadLocalORMSession.flush_all()
-        g.post_event('project_updated')

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/templates/code/index.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/templates/code/index.html b/ForgeImporters/forgeimporters/google/templates/code/index.html
deleted file mode 100644
index e2cef0c..0000000
--- a/ForgeImporters/forgeimporters/google/templates/code/index.html
+++ /dev/null
@@ -1,31 +0,0 @@
-{#-
-       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 title %}
-{{c.project.name}} / Import your repo from Google Code
-{% endblock %}
-
-{% block importer_fields %}
-<div>
-  <label for="gc_project_name">Google Code project name (as it appears in a URL)</label>
-  <input name="gc_project_name" value="{{ c.form_values['gc_project_name'] }}" />
-  {{ error('gc_project_name') }}
-</div>
-{% endblock %}

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/templates/project.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/templates/project.html b/ForgeImporters/forgeimporters/google/templates/project.html
deleted file mode 100644
index a00c0dd..0000000
--- a/ForgeImporters/forgeimporters/google/templates/project.html
+++ /dev/null
@@ -1,68 +0,0 @@
-{#-
-       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/project_base.html' %}
-
-{% block extra_js %}
-    {{super()}}
-    <script type="text/javascript">
-        function suggest_name() {  // overrides base suggest_names
-            var $project_shortname = $('#project_shortname');
-            if (!manual) {
-                var name_or_url = $('#project_name').val().replace(/\s/g, '').toLowerCase();
-                name_or_url = name_or_url.replace(/\/$/, '');  // strip any trailing slash
-                var a = $('<a>', {href: name_or_url})[0];  // leverage DOM to parse URL
-                var project_name;
-                var old_style = a.hostname.match(/^(.*)\.googlecode\.com$/);
-                if (old_style) {
-                    project_name = old_style[1];
-                } else {
-                    var parts = a.pathname.split('/');
-                    project_name = parts.pop();
-                }
-                $project_shortname.val(project_name);
-            }
-            $project_shortname.trigger('change');
-        }
-    </script>
-{% endblock %}
-
-{% block project_fields %}
-    <div class="grid-7">
-        <label>Google Project Name or URL</label>
-    </div>
-    <div class="grid-10">
-        <input id="project_name" name="project_name" value="{{c.form_values['project_name']}}" autofocus/>
-        <div id="project_name_error" class="error{% if not c.form_errors['project_name'] %} hidden{% endif %}">
-            {{c.form_errors['project_name']}}
-        </div>
-    </div>
-
-    <div class="grid-7" style="clear:left">
-        <label>{{config.site_name}} URL Name</label>
-    </div>
-    <div class="grid-10">
-        <input id="project_shortname" name="project_shortname" value="{{c.form_values['project_shortname']}}"/>
-        <div id="project_shortname_error" class="error{% if not c.form_errors['project_shortname'] %} hidden{% endif %}">
-            {{c.form_errors['project_shortname']}}
-        </div>
-        <div id="project-url">
-            http://{{request.environ['HTTP_HOST']}}{{importer.neighborhood.url()}}<span id="url-fragment">{{c.form_values['project_shortname']}}</span>
-        </div>
-    </div>
-{% endblock %}

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/templates/tracker/index.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/templates/tracker/index.html b/ForgeImporters/forgeimporters/google/templates/tracker/index.html
deleted file mode 100644
index 08d0084..0000000
--- a/ForgeImporters/forgeimporters/google/templates/tracker/index.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{#-
-       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 %}
-<div>
-  <label for="gc_project_name">Google Code project name (as it appears in a URL)</label>
-  <input name="gc_project_name" value="{{ c.form_values['gc_project_name'] }}" />
-  {{ error('gc_project_name') }}
-</div>
-{% endblock %}

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/tests/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tests/__init__.py b/ForgeImporters/forgeimporters/google/tests/__init__.py
deleted file mode 100644
index 144e298..0000000
--- a/ForgeImporters/forgeimporters/google/tests/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#       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.

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/tests/test_code.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tests/test_code.py b/ForgeImporters/forgeimporters/google/tests/test_code.py
deleted file mode 100644
index 1b6cacc..0000000
--- a/ForgeImporters/forgeimporters/google/tests/test_code.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#       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
-from mock import Mock, patch
-from ming.odm import ThreadLocalORMSession
-
-from allura.tests import TestController
-from allura import model as M
-
-
-# important to be distinct from 'test' which ForgeSVN uses, so that the
-# tests can run in parallel and not clobber each other
-test_project_with_repo = 'test2'
-
-
-from forgeimporters.google.code import (
-    get_repo_url,
-    GoogleRepoImporter,
-)
-
-
-class TestGetRepoUrl(TestCase):
-
-    def test_svn(self):
-        r = get_repo_url('projname', 'svn')
-        self.assertEqual(r, 'http://projname.googlecode.com/svn/')
-
-    def test_git(self):
-        r = get_repo_url('projname', 'git')
-        self.assertEqual(r, 'https://code.google.com/p/projname/')
-
-    def test_hg(self):
-        r = get_repo_url('projname', 'hg')
-        self.assertEqual(r, 'https://code.google.com/p/projname/')
-
-    def test_svn_hosted(self):
-        r = get_repo_url('a/eclipselabs.org/p/projname', 'svn')
-        self.assertEqual(r, 'http://svn.codespot.com/a/eclipselabs.org/projname/')
-
-    def test_git_hosted(self):
-        r = get_repo_url('a/eclipselabs.org/p/projname', 'git')
-        self.assertEqual(r, 'https://code.google.com/a/eclipselabs.org/p/projname/')
-
-    def test_hg_hosted(self):
-        r = get_repo_url('a/eclipselabs.org/p/projname', 'hg')
-        self.assertEqual(r, 'https://code.google.com/a/eclipselabs.org/p/projname/')
-
-
-class TestGoogleRepoImporter(TestCase):
-
-    def _make_project(self, gc_proj_name=None):
-        project = Mock()
-        project.get_tool_data.side_effect = lambda *args: gc_proj_name
-        return project
-
-    @patch('forgeimporters.google.code.g')
-    @patch('forgeimporters.google.code.M')
-    @patch('forgeimporters.google.code.GoogleCodeProjectExtractor')
-    @patch('forgeimporters.google.code.get_repo_url')
-    def test_import_tool_happy_path(self, get_repo_url, gcpe, M, g):
-        gcpe.return_value.get_repo_type.return_value = 'git'
-        get_repo_url.return_value = 'http://remote/clone/url/'
-        p = self._make_project(gc_proj_name='myproject')
-        u = Mock(name='c.user')
-        app = p.install_app.return_value
-        app.config.options.mount_point = 'code'
-        app.url = 'foo'
-        GoogleRepoImporter().import_tool(p, u, project_name='project_name')
-        get_repo_url.assert_called_once_with('project_name', 'git')
-        p.install_app.assert_called_once_with('git',
-                                              mount_point='code',
-                                              mount_label='Code',
-                                              init_from_url='http://remote/clone/url/',
-                                              import_id={
-                                                  'source': 'Google Code',
-                                                  'project_name': 'project_name',
-                                              },
-                                              )
-        M.AuditLog.log.assert_called_once_with(
-            'import tool code from project_name on Google Code',
-            project=p, user=u, url='foo')
-        g.post_event.assert_called_once_with('project_updated')
-
-
-class TestGoogleRepoImportController(TestController, TestCase):
-
-    def test_index(self):
-        r = self.app.get(
-            '/p/{}/admin/ext/import/google-code-repo/'.format(test_project_with_repo))
-        self.assertIsNotNone(r.html.find(attrs=dict(name="gc_project_name")))
-        self.assertIsNotNone(r.html.find(attrs=dict(name="mount_label")))
-        self.assertIsNotNone(r.html.find(attrs=dict(name="mount_point")))
-
-    @patch('forgeimporters.google.code.GoogleCodeProjectExtractor')
-    @patch('forgeimporters.base.import_tool')
-    def test_create(self, import_tool, extractor):
-        extractor.return_value.get_repo_type.return_value = 'git'
-        params = dict(gc_project_name='poop',
-                      mount_label='mylabel',
-                      mount_point='mymount',
-                      )
-        r = self.app.post(
-            '/p/{}/admin/ext/import/google-code-repo/create'.format(test_project_with_repo),
-            params,
-            status=302)
-        self.assertEqual(
-            r.location, 'http://localhost/p/{}/admin/'.format(test_project_with_repo))
-        self.assertEqual(
-            u'mymount', import_tool.post.call_args[1]['mount_point'])
-        self.assertEqual(
-            u'mylabel', import_tool.post.call_args[1]['mount_label'])
-        self.assertEqual(
-            u'poop', import_tool.post.call_args[1]['project_name'])
-
-    @patch('forgeimporters.google.code.GoogleCodeProjectExtractor')
-    @patch('forgeimporters.base.import_tool')
-    def test_create_limit(self, import_tool, extractor):
-        extractor.return_value.get_repo_type.return_value = 'git'
-        project = M.Project.query.get(shortname=test_project_with_repo)
-        project.set_tool_data('GoogleRepoImporter', pending=1)
-        ThreadLocalORMSession.flush_all()
-        params = dict(gc_project_name='poop',
-                      mount_label='mylabel',
-                      mount_point='mymount',
-                      )
-        r = self.app.post(
-            '/p/{}/admin/ext/import/google-code-repo/create'.format(test_project_with_repo),
-            params,
-            status=302).follow()
-        self.assertIn('Please wait and try again', r)
-        self.assertEqual(import_tool.post.call_count, 0)

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/tests/test_init.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tests/test_init.py b/ForgeImporters/forgeimporters/google/tests/test_init.py
deleted file mode 100644
index 37bf4c2..0000000
--- a/ForgeImporters/forgeimporters/google/tests/test_init.py
+++ /dev/null
@@ -1,130 +0,0 @@
-#       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 nose.tools import assert_equal
-from mock import patch
-from formencode.validators import Invalid
-from BeautifulSoup import BeautifulSoup
-from IPython.testing.decorators import skipif, module_not_available
-
-from allura.tests import decorators as td
-from forgeimporters.google import GoogleCodeProjectNameValidator, GoogleCodeProjectExtractor
-from forgeimporters.google import _as_markdown
-
-
-class TestGoogleCodeProjectNameValidator(object):
-
-    def setUp(self):
-        self.readable_patcher = patch.object(GoogleCodeProjectExtractor, 'check_readable')
-        self.readable_mock = self.readable_patcher.start()
-        self.readable_mock.return_value = True
-
-    def tearDown(self):
-        self.readable_patcher.stop()
-
-    def test_simple(self):
-        assert_equal(
-            GoogleCodeProjectNameValidator()._to_python('gmapcatcher'),
-            'gmapcatcher'
-        )
-
-    def test_code_dot_google(self):
-        assert_equal(
-            GoogleCodeProjectNameValidator()._to_python('http://code.google.com/p/gmapcatcher/'),
-            'gmapcatcher'
-        )
-        assert_equal(
-            GoogleCodeProjectNameValidator()._to_python('https://code.google.com/p/gmapcatcher/'),
-            'gmapcatcher'
-        )
-
-    def test_googlecode_com(self):
-        assert_equal(
-            GoogleCodeProjectNameValidator()._to_python('http://gmapcatcher.googlecode.com/'),
-            'gmapcatcher'
-        )
-        assert_equal(
-            GoogleCodeProjectNameValidator()._to_python('https://gmapcatcher.googlecode.com/'),
-            'gmapcatcher'
-        )
-
-    def test_not_readable(self):
-        self.readable_mock.return_value = False
-        with td.raises(Invalid):
-            GoogleCodeProjectNameValidator()._to_python('gmapcatcher')
-
-    def test_invalid(self):
-        with td.raises(Invalid):
-            GoogleCodeProjectNameValidator()._to_python('http://code.google.com/')
-        with td.raises(Invalid):
-            GoogleCodeProjectNameValidator()._to_python('http://foobar.com/p/gmapcatcher')
-        with td.raises(Invalid):
-            GoogleCodeProjectNameValidator()._to_python('http://code.google.com/p/asdf_asdf')
-        with td.raises(Invalid):
-            GoogleCodeProjectNameValidator()._to_python('http://code.google.com/x/y/z')
-
-    def test_hosted_domain(self):
-        assert_equal(
-            GoogleCodeProjectNameValidator()._to_python('https://code.google.com/a/eclipselabs.org/p/restclient-tool'),
-            'a/eclipselabs.org/p/restclient-tool'
-        )
-        with td.raises(Invalid):
-            GoogleCodeProjectNameValidator()._to_python('http://code.google.com/a/eclipselabs.org/bogus')
-
-
-class Test_as_markdown(object):
-
-    # this is covered by functional tests (useing test-issue.html)
-    # but adding some unit tests for easier verification of hosted domain link rewriting
-
-    def test_link_within_proj(self):
-        html = BeautifulSoup('''<pre>Foo: <a href="/p/myproj/issues/detail?id=1">issue 1</a></pre>''')
-        assert_equal(
-            _as_markdown(html.first(), 'myproj'),
-            'Foo: [issue 1](#1)'
-        )
-
-    @skipif(module_not_available('html2text'))
-    def test_link_other_proj_has_html2text(self):
-        html = BeautifulSoup('''<pre>Foo: <a href="/p/other-project/issues/detail?id=1">issue other-project:1</a></pre>''')
-        assert_equal(
-            _as_markdown(html.first(), 'myproj'),
-            'Foo: [issue other-project:1](https://code.google.com/p/other-project/issues/detail?id=1)'
-        )
-
-    @td.without_module('html2text')
-    def test_link_other_proj_no_html2text(self):
-        # without html2text, the dash in other-project doesn't get escaped right
-        html = BeautifulSoup('''<pre>Foo: <a href="/p/other-project/issues/detail?id=1">issue other-project:1</a></pre>''')
-        assert_equal(
-            _as_markdown(html.first(), 'myproj'),
-            'Foo: [issue other\\-project:1](https://code.google.com/p/other-project/issues/detail?id=1)'
-        )
-
-    def test_link_hosted_domain_within_proj(self):
-        html = BeautifulSoup('''<pre>Foo: <a href="/a/eclipselabs.org/p/myproj/issues/detail?id=1">issue 1</a></pre>''')
-        assert_equal(
-            _as_markdown(html.first(), 'a/eclipselabs.org/p/myproj'),
-            'Foo: [issue 1](#1)'
-        )
-
-    def test_link_hosted_domain_other_proj(self):
-        html = BeautifulSoup('''<pre>Foo: <a href="/a/eclipselabs.org/p/other-proj/issues/detail?id=1">issue 1</a></pre>''')
-        assert_equal(
-            _as_markdown(html.first(), 'a/eclipselabs.org/p/myproj'),
-            'Foo: [issue 1](https://code.google.com/a/eclipselabs.org/p/other-proj/issues/detail?id=1)'
-        )

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/google/tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/google/tracker.py b/ForgeImporters/forgeimporters/google/tracker.py
deleted file mode 100644
index 7873aa6..0000000
--- a/ForgeImporters/forgeimporters/google/tracker.py
+++ /dev/null
@@ -1,224 +0,0 @@
-#       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 collections import defaultdict
-
-from pylons import tmpl_context as c
-from pylons import app_globals as g
-from ming.orm import session, ThreadLocalORMSession
-import dateutil.parser
-
-from tg import (
-    expose,
-    flash,
-    redirect,
-)
-from tg.decorators import (
-    with_trailing_slash,
-    without_trailing_slash,
-)
-
-from allura.lib import helpers as h
-from allura.lib.plugin import ImportIdConverter
-from allura.lib.decorators import require_post
-from allura import model as M
-
-from forgetracker import model as TM
-from forgeimporters.google import GoogleCodeProjectExtractor
-from forgeimporters.google import GoogleCodeProjectNameValidator
-from forgeimporters.base import (
-    ToolImporter,
-    ToolImportForm,
-    ToolImportController,
-)
-
-
-class GoogleCodeTrackerImportForm(ToolImportForm):
-    gc_project_name = GoogleCodeProjectNameValidator()
-
-
-class GoogleCodeTrackerImportController(ToolImportController):
-    import_form = GoogleCodeTrackerImportForm
-
-    @with_trailing_slash
-    @expose('jinja:forgeimporters.google:templates/tracker/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, gc_project_name, mount_point, mount_label, **kw):
-        if self.importer.enforce_limit(c.project):
-            self.importer.post(
-                project_name=gc_project_name,
-                mount_point=mount_point,
-                mount_label=mount_label,
-            )
-            flash('Ticket import has begun. Your new tracker 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')
-        redirect(c.project.url() + 'admin/')
-
-
-class GoogleCodeTrackerImporter(ToolImporter):
-    source = 'Google Code'
-    target_app_ep_names = 'tickets'
-    controller = GoogleCodeTrackerImportController
-    tool_label = 'Issues'
-    tool_description = 'Import your public tickets from Google Code'
-
-    field_types = defaultdict(lambda: 'string',
-                              milestone='milestone',
-                              priority='select',
-                              type='select',
-                              )
-
-    def __init__(self, *args, **kwargs):
-        super(GoogleCodeTrackerImporter, self).__init__(*args, **kwargs)
-        self.open_milestones = set()
-        self.custom_fields = {}
-        self.max_ticket_num = 0
-
-    def import_tool(self, project, user, project_name, mount_point=None,
-                    mount_label=None, **kw):
-        import_id_converter = ImportIdConverter.get()
-        app = project.install_app('tickets', mount_point, mount_label,
-                                  EnableVoting=True,
-                                  open_status_names='New Accepted Started',
-                                  closed_status_names='Fixed Verified Invalid Duplicate WontFix Done',
-                                  import_id={
-                                      'source': self.source,
-                                      'project_name': project_name,
-                                  },
-                                  )
-        ThreadLocalORMSession.flush_all()
-        try:
-            M.session.artifact_orm_session._get().skip_mod_date = True
-            with h.push_config(c, user=M.User.anonymous(), app=app):
-                for ticket_num, issue in GoogleCodeProjectExtractor.iter_issues(project_name):
-                    self.max_ticket_num = max(ticket_num, self.max_ticket_num)
-                    ticket = TM.Ticket(
-                        app_config_id=app.config._id,
-                        custom_fields=dict(),
-                        ticket_num=ticket_num,
-                        import_id=import_id_converter.expand(ticket_num, app))
-                    self.process_fields(ticket, issue)
-                    self.process_labels(ticket, issue)
-                    self.process_comments(ticket, issue)
-                    session(ticket).flush(ticket)
-                    session(ticket).expunge(ticket)
-                app.globals.custom_fields = self.postprocess_custom_fields()
-                app.globals.last_ticket_num = self.max_ticket_num
-                ThreadLocalORMSession.flush_all()
-            M.AuditLog.log(
-                'import tool %s from %s on %s' % (
-                    app.config.options.mount_point,
-                    project_name, self.source,
-                ),
-                project=project,
-                user=user,
-                url=app.url,
-            )
-            g.post_event('project_updated')
-            app.globals.invalidate_bin_counts()
-            return app
-        except Exception:
-            h.make_app_admin_only(app)
-            raise
-        finally:
-            M.session.artifact_orm_session._get().skip_mod_date = False
-
-    def custom_field(self, name):
-        if name not in self.custom_fields:
-            self.custom_fields[name] = {
-                'type': self.field_types[name.lower()],
-                'label': name,
-                'name': u'_%s' % name.lower(),
-                'options': set(),
-            }
-        return self.custom_fields[name]
-
-    def process_fields(self, ticket, issue):
-        ticket.summary = issue.get_issue_summary()
-        ticket.status = issue.get_issue_status()
-        ticket.created_date = dateutil.parser.parse(
-            issue.get_issue_created_date())
-        ticket.mod_date = dateutil.parser.parse(issue.get_issue_mod_date())
-        ticket.votes_up = issue.get_issue_stars()
-        ticket.votes = issue.get_issue_stars()
-        owner = issue.get_issue_owner()
-        if owner:
-            owner_line = '*Originally owned by:* {owner}\n'.format(owner=owner)
-        else:
-            owner_line = ''
-        ticket.description = (
-            u'*Originally created by:* {creator}\n'
-            u'{owner}'
-            u'\n'
-            u'{body}').format(
-            creator=issue.get_issue_creator(),
-            owner=owner_line,
-            body=issue.get_issue_description(),
-        )
-        ticket.add_multiple_attachments(issue.get_issue_attachments())
-
-    def process_labels(self, ticket, issue):
-        labels = set()
-        custom_fields = defaultdict(set)
-        for label in issue.get_issue_labels():
-            if u'-' in label:
-                name, value = label.split(u'-', 1)
-                cf = self.custom_field(name)
-                cf['options'].add(value)
-                custom_fields[cf['name']].add(value)
-                if cf['name'] == '_milestone' and ticket.status in c.app.globals.open_status_names:
-                    self.open_milestones.add(value)
-            else:
-                labels.add(label)
-        ticket.labels = list(labels)
-        ticket.custom_fields = {n: u', '.join(sorted(v))
-                                for n, v in custom_fields.iteritems()}
-
-    def process_comments(self, ticket, issue):
-        for comment in issue.iter_comments():
-            p = ticket.discussion_thread.add_post(
-                text=comment.annotated_text,
-                ignore_security=True,
-                timestamp=dateutil.parser.parse(comment.created_date),
-            )
-            p.add_multiple_attachments(comment.attachments)
-
-    def postprocess_custom_fields(self):
-        custom_fields = []
-        for name, field in self.custom_fields.iteritems():
-            if field['name'] == '_milestone':
-                field['milestones'] = [{
-                    'name': milestone,
-                    'due_date': None,
-                    'complete': milestone not in self.open_milestones,
-                } for milestone in sorted(field['options'])]
-                field['options'] = ''
-            elif field['type'] == 'select':
-                field['options'] = ' '.join(field['options'])
-            else:
-                field['options'] = ''
-            custom_fields.append(field)
-        return custom_fields

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/data/google/empty-issue.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/data/google/empty-issue.html b/ForgeImporters/forgeimporters/tests/data/google/empty-issue.html
deleted file mode 100644
index b2eef20..0000000
--- a/ForgeImporters/forgeimporters/tests/data/google/empty-issue.html
+++ /dev/null
@@ -1,306 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
-<meta name="ROBOTS" content="NOARCHIVE" />
-<link rel="icon" type="image/vnd.microsoft.icon" href="http://www.gstatic.com/codesite/ph/images/phosting.ico" />
-<script type="text/javascript">
-
-
-
-
- var codesite_token = null;
-
-
- var CS_env = {"assetHostPath":"http://www.gstatic.com/codesite/ph","projectHomeUrl":"/p/allura-google-importer","relativeBaseUrl":"","domainName":null,"projectName":"allura-google-importer","loggedInUserEmail":null,"profileUrl":null,"token":null,"assetVersionPath":"http://www.gstatic.com/codesite/ph/3783617020303179221"};
- var _gaq = _gaq || [];
- _gaq.push(
- ['siteTracker._setAccount', 'UA-18071-1'],
- ['siteTracker._trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
- })();
-
- </script>
-<title>Issue 5 -
- allura-google-importer -
-
- Empty Issue -
- Import Google Code projects to an Allura forge - Google Project Hosting
- </title>
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/core.css" />
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/ph_detail.css" />
-<!--[if IE]>
- <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/d_ie.css" >
-<![endif]-->
-<style type="text/css">
- .menuIcon.off { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -42px }
- .menuIcon.on { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -28px }
- .menuIcon.down { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 0; }
-
-
- .attachments { width:33%; border-top:2px solid #999; padding-top: 3px; margin-left: .7em;}
- .attachments table { margin-bottom: 0.75em; }
- .attachments table tr td { padding: 0; margin: 0; font-size: 95%; }
- .preview { border: 2px solid #c3d9ff; padding: 1px; }
- .preview:hover { border: 2px solid blue; }
- .label { white-space: nowrap; }
- .derived { font-style:italic }
- .cursor_on .author {
- background: url(http://www.gstatic.com/codesite/ph/images/show-arrow.gif) no-repeat 2px;
- }
- .hiddenform {
- display: none;
- }
-
-
- </style>
-</head>
-<body class="t3">
-<script type="text/javascript">
- window.___gcfg = {lang: 'en'};
- (function()
- {var po = document.createElement("script");
- po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
- var s = document.getElementsByTagName("script")[0];
- s.parentNode.insertBefore(po, s);
- })();
-</script>
-<div class="headbg">
-<div id="gaia">
-<span>
-<a href="#" id="projects-dropdown" onclick="return false;"><u>My favorites</u> <small>&#9660;</small></a>
- | <a href="https://www.google.com/accounts/ServiceLogin?service=code&amp;ltmpl=phosting&amp;continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D5&amp;followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D5" onclick="_CS_click('/gb/ph/signin');"><u>Sign in</u></a>
-</span>
-</div>
-<div class="gbh" style="left: 0pt;"></div>
-<div class="gbh" style="right: 0pt;"></div>
-<div style="height: 1px"></div>
-<!--[if lte IE 7]>
-<div style="text-align:center;">
-Your version of Internet Explorer is not supported. Try a browser that
-contributes to open source, such as <a href="http://www.firefox.com">Firefox</a>,
-<a href="http://www.google.com/chrome">Google Chrome</a>, or
-<a href="http://code.google.com/chrome/chromeframe/">Google Chrome Frame</a>.
-</div>
-<![endif]-->
-<table style="padding:0px; margin: 0px 0px 10px 0px; width:100%" cellpadding="0" cellspacing="0" itemscope="itemscope" itemtype="http://schema.org/CreativeWork">
-<tr style="height: 58px;">
-<td id="plogo">
-<link itemprop="url" href="/p/allura-google-importer" />
-<a href="/p/allura-google-importer/">
-<img src="/p/allura-google-importer/logo?cct=1374769571" alt="Logo" itemprop="image" />
-</a>
-</td>
-<td style="padding-left: 0.5em">
-<div id="pname">
-<a href="/p/allura-google-importer/"><span itemprop="name">allura-google-importer</span></a>
-</div>
-<div id="psum">
-<a id="project_summary_link" href="/p/allura-google-importer/"><span itemprop="description">Import Google Code projects to an Allura forge</span></a>
-</div>
-</td>
-<td style="white-space:nowrap;text-align:right; vertical-align:bottom;">
-<form action="/hosting/search">
-<input size="30" name="q" value="" type="text" />
-<input type="submit" name="projectsearch" value="Search projects" />
-</form>
-</td></tr>
-</table>
-</div>
-<div id="mt" class="gtb">
-<a href="/p/allura-google-importer/" class="tab ">Project&nbsp;Home</a>
-<a href="/p/allura-google-importer/wiki/TestPage?tm=6" class="tab ">Wiki</a>
-<a href="/p/allura-google-importer/issues/list" class="tab active">Issues</a>
-<a href="/p/allura-google-importer/source/checkout" class="tab ">Source</a>
-<div class="gtbc"></div>
-</div>
-<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0" class="st">
-<tr>
-<td class="subt">
-<div class="issueDetail">
-<div class="isf">
-<span class="inIssueEntry">
-<a class="buttonify" href="entry" onclick="return _newIssuePrompt();">New issue</a>
-</span> &nbsp;
-
- <span class="inIssueList">
-<span>Search</span>
-</span><form action="list" method="GET" style="display:inline">
-<select id="can" name="can">
-<option disabled="disabled">Search within:</option>
-<option value="1">&nbsp;All issues</option>
-<option value="2" selected="selected">&nbsp;Open issues</option>
-<option value="6">&nbsp;New issues</option>
-<option value="7">&nbsp;Issues to verify</option>
-</select>
-<span>for</span>
-<span id="qq"><input type="text" size="38" id="searchq" name="q" value="" autocomplete="off" onkeydown="_blurOnEsc(event)" /></span>
-<span id="search_colspec"><input type="hidden" name="colspec" value="ID Type Status Priority Milestone Owner Summary" /></span>
-<input type="hidden" name="cells" value="tiles" />
-<input type="submit" value="Search" />
-</form>
- &nbsp;
- <span class="inIssueAdvSearch">
-<a href="advsearch">Advanced search</a>
-</span> &nbsp;
- <span class="inIssueSearchTips">
-<a href="searchtips">Search tips</a>
-</span> &nbsp;
- <span class="inIssueSubscriptions">
-<a href="/p/allura-google-importer/issues/subscriptions">Subscriptions</a>
-</span>
-</div>
-</div>
-</td>
-<td align="right" valign="top" class="bevel-right"></td>
-</tr>
-</table>
-<script type="text/javascript">
- var cancelBubble = false;
- function _go(url) { document.location = url; }
-</script>
-<div id="maincol">
-<div id="color_control" class="">
-<div id="issueheader">
-<table cellpadding="0" cellspacing="0" width="100%"><tbody>
-<tr>
-<td class="vt h3" nowrap="nowrap" style="padding:0 5px">
-
-
- Issue <a href="detail?id=5">5</a>:
- </td>
-<td width="90%" class="vt">
-<span class="h3">Empty Issue</span>
-</td>
-<td>
-<div class="pagination">
-<a href="../../allura-google-importer/issues/detail?id=4" title="Prev">&lsaquo; Prev</a>
- 5 of 5
-
- </div>
-</td>
-</tr>
-<tr>
-<td></td>
-<td nowrap="nowrap">
-
-
- 1 person starred this issue and may be notified of changes.
-
-
-
- </td>
-<td align="center" nowrap="nowrap">
-<a href="http://code.google.com/p/allura-google-importer/issues/list?cursor=allura-google-importer%3A5">Back to list</a>
-</td>
-</tr>
-</tbody></table>
-</div>
-<table width="100%" cellpadding="0" cellspacing="0" border="0" class="issuepage" id="meta-container">
-<tbody class="collapse">
-<tr>
-<td id="issuemeta">
-<div id="meta-float">
-<table cellspacing="0" cellpadding="0">
-<tr><th align="left">Status:&nbsp;</th>
-<td width="100%">
-
-
- ----
-
-
- </td>
-</tr>
-<tr><th align="left">Owner:&nbsp;</th><td>
-
-
- ----
-
-
- </td>
-</tr>
-<tr><td colspan="2">
-</td></tr>
-</table>
-<div class="rel_issues">
-</div>
-<br /><br />
-<div style="white-space:nowrap"><a href="https://www.google.com/accounts/ServiceLogin?service=code&amp;ltmpl=phosting&amp;continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D5&amp;followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D5">Sign in</a> to add a comment</div>
-</div>&nbsp;
- </td>
-<td class="vt issuedescription" width="100%" id="cursorarea">
-<div class="cursor_off vt issuedescription" id="hc0">
-<div class="author">
-<span class="role_label">Project Member</span>
- Reported by
-
-
- <span class="userlink">john...@gmail.com</span>,
- <span class="date" title="Thu Aug  8 14:56:23 2013">Today (15 minutes ago)</span>
-</div>
-<pre>
-Empty
-</pre>
-</div>
-</td>
-</tr>
-<tr>
-<td></td>
-<td class="vt issuecomment">
-<span class="indicator">&#9658;</span> <a href="https://www.google.com/accounts/ServiceLogin?service=code&amp;ltmpl=phosting&amp;continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D5&amp;followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D5">Sign in</a> to add a comment
- </td>
-</tr>
-</tbody>
-</table>
-<br />
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/dit_scripts.js"></script>
-</div>
-<form name="delcom" action="delComment.do?q=&amp;can=2&amp;groupby=&amp;sort=&amp;colspec=ID+Type+Status+Priority+Milestone+Owner+Summary" method="POST">
-<input type="hidden" name="sequence_num" value="" />
-<input type="hidden" name="mode" value="" />
-<input type="hidden" name="id" value="5" />
-<input type="hidden" name="token" value="" />
-</form>
-<div id="helparea"></div>
-<script type="text/javascript">
- _onload();
- function delComment(sequence_num, delete_mode) {
- var f = document.forms["delcom"];
- f.sequence_num.value = sequence_num;
- f.mode.value = delete_mode;
-
- f.submit();
- return false;
- }
-
- _floatMetadata();
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/kibbles.js"></script>
-<script type="text/javascript">
- _setupKibblesOnDetailPage(
- 'http://code.google.com/p/allura-google-importer/issues/list?cursor\x3dallura-google-importer%3A5',
- '/p/allura-google-importer/issues/entry',
- '../../allura-google-importer/issues/detail?id\x3d4',
- '',
- '', 'allura-google-importer', 5,
- false, false, codesite_token);
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/ph_core.js"></script>
-</div>
-<div id="footer" dir="ltr">
-<div class="text">
-<a href="/projecthosting/terms.html">Terms</a> -
- <a href="http://www.google.com/privacy.html">Privacy</a> -
- <a href="/p/support/">Project Hosting Help</a>
-</div>
-</div>
-<div class="hostedBy" style="margin-top: -20px;">
-<span style="vertical-align: top;">Powered by <a href="http://code.google.com/projecthosting/">Google Project Hosting</a></span>
-</div>
-</body>
-</html>


[41/50] allura git commit: [#8035] ESLINT FIX: no-implicit-coercion

Posted by he...@apache.org.
[#8035] ESLINT FIX: no-implicit-coercion


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

Branch: refs/heads/hs/8035
Commit: 77529db6f8e86ef3a2ac8c2d9c15eb58ff32ac00
Parents: fbb0147
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 19:32:34 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:31 2016 -0500

----------------------------------------------------------------------
 Allura/allura/public/nf/js/navbar.es6.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/77529db6/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index d83f1f0..23f9313 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -139,7 +139,7 @@ var GroupingThreshold = React.createClass({
     render: function() {
         return (
             <div>
-                { !!this.props.isHidden &&
+                { !Boolean(this.props.isHidden) &&
                 <div id='threshold-config'>
             <span>
               <label htmlFor='threshold-input'>Grouping Threshold</label>


[35/50] allura git commit: [#8035] ESLINT FIX: space-before-function-paren

Posted by he...@apache.org.
[#8035] ESLINT FIX: space-before-function-paren


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

Branch: refs/heads/hs/8035
Commit: 5e861dec104787a1bce3c5e4efe8dbda615fa883
Parents: 0ce56fc
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 18:21:09 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:29 2016 -0500

----------------------------------------------------------------------
 Allura/allura/public/nf/js/context-menu.es6.js |  4 ++--
 Allura/allura/public/nf/js/navbar.es6.js       | 14 +++++++-------
 2 files changed, 9 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/5e861dec/Allura/allura/public/nf/js/context-menu.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/context-menu.es6.js b/Allura/allura/public/nf/js/context-menu.es6.js
index 710387d..58d213d 100644
--- a/Allura/allura/public/nf/js/context-menu.es6.js
+++ b/Allura/allura/public/nf/js/context-menu.es6.js
@@ -38,7 +38,7 @@ class ContextMenu extends React.Component {
     componentWillMount() {
         let _this = this;
         var mount_point;
-        $('body').on('click.contextMenu', function (evt) {
+        $('body').on('click.contextMenu', function(evt) {
             /* the :not filter should've worked as a 2nd param to .on() instead of this,
              but clicks in the page gutter were being delayed for some reason */
             if ($(evt.target).is(':not(.contextMenu)')) {
@@ -67,7 +67,7 @@ class ContextMenu extends React.Component {
             <div className="contextMenu">
                 <ToolTip targetSelector='#top_nav_admin .contextMenu a'/>
                 <ul>{
-                    this.props.items.map(function (o, i) {
+                    this.props.items.map(function(o, i) {
                         return (<li key={i}>
                             <a href={o.href}
                                className={_this.props.classes.concat([o.className]).join(' ')}

http://git-wip-us.apache.org/repos/asf/allura/blob/5e861dec/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index 0ea3cb5..1055d43 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -209,7 +209,7 @@ var ToggleAddNewTool = React.createClass({
             visible: !this.state.visible
         });
     },
-    render: function () {
+    render: function() {
         return (
             <div>
                 <a onClick={ this.handleToggle } className="add-tool-toggle">
@@ -286,7 +286,7 @@ var AdminNav = React.createClass({
         onOptionClick: React.PropTypes.func.isRequired
     },
 
-    buildMenu: function (items, isSubMenu=false) {
+    buildMenu: function(items, isSubMenu=false) {
         var _this = this;
         var [tools, anchoredTools, endTools] = [[], [], []];
         var subMenu;
@@ -358,14 +358,14 @@ var AdminNav = React.createClass({
         );
     },
 
-    render: function () {
+    render: function() {
         var tools = this.buildMenu(this.props.tools);
         return <div>{tools}</div>;
     }
 });
 
 var NavBarItemWithSubMenu = React.createClass({
-    render: function () {
+    render: function() {
         return (
             <div className={"tb-item-container" + (this.props.childOptionsOpen ? " child-options-open" : "")}>
                 { this.props.tool }
@@ -385,7 +385,7 @@ var NavBarItemWithSubMenu = React.createClass({
  * @constructor
  */
 var AdminItemGroup = React.createClass({
-    render: function () {
+    render: function() {
         return (
             <div className="tb-item-grouper">
                 {this.props.children}
@@ -459,7 +459,7 @@ var Main = React.createClass({
         });
     },
 
-    handleShowOptionMenu: function (mount_point) {
+    handleShowOptionMenu: function(mount_point) {
         this.setState({
             currentOptionMenu: {
                 tool: mount_point
@@ -504,7 +504,7 @@ var Main = React.createClass({
             type: 'POST',
             url: url,
             data: params,
-            success: function () {
+            success: function() {
                 $('#messages').notify('Tool order updated',
                     {
                         status: 'confirm',


[05/50] allura git commit: [#8020] ticket:875 updated jquery for render; updated logic with undo; updated test

Posted by he...@apache.org.
[#8020] ticket:875 updated jquery for render; updated logic with undo; updated test


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

Branch: refs/heads/hs/8035
Commit: bf73398657928320e4e6dad1e40f0136a8162223
Parents: f763703
Author: DeV1doR <de...@ukr.net>
Authored: Sat Dec 12 17:18:08 2015 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:03:18 2016 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py            |  4 +++-
 Allura/allura/lib/widgets/discuss.py            | 24 ++++++++++++++++----
 .../allura/templates/widgets/post_widget.html   |  1 +
 Allura/allura/tests/functional/test_discuss.py  |  9 +++++++-
 4 files changed, 31 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/bf733986/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 36cc494..92b1169 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -356,7 +356,9 @@ class PostController(BaseController):
         elif kw.pop('spam', None):
             self.post.spam()
         elif kw.pop('undo', None):
-            self.post.status = 'pending'
+            prev_status = kw.pop('prev_status', None)
+            if prev_status:
+                self.post.status = prev_status
         elif kw.pop('approve', None):
             if self.post.status != 'ok':
                 self.post.approve()

http://git-wip-us.apache.org/repos/asf/allura/blob/bf733986/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index c56e2cd..4d83070 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -341,23 +341,37 @@ class Post(HierWidget):
                             }
                             else if (mod == 'Spam'){
                                 spam_block_display($(post), 'none');
-                                $(post).find('.spam-present').show();
                             }
                             else if (mod == 'Undo'){
                                 spam_block_display($(post), 'block');
-                                $(post).find('.spam-present').hide();
-                                $(post).find('.options a').eq(0).hide();
                             }
                         }
                     });
                 });
 
                 function spam_block_display($post, display_type) {
-                    $post.find('.display_post').css(
-                        'display', display_type);
+                    var post_block = $post.find('.display_post');
+                    post_block.css('display', display_type);
+
+                    var attach_block = $post.find('.add_attachment_form').next();
+                    if (attach_block.attr('class') == undefined) {
+                        attach_block.css('display', display_type);
+                    }
+
                     $.each($post.find('.options').children(), function() {
                         $(this).css('display', display_type);
+                        if (
+                            $(this).hasClass('reply_post') &&
+                            $post.find('input[name="prev_status"]').attr('value') == 'pending'
+                        ) {
+                            $(this).hide();
+                        }
                     });
+                    if (display_type == 'none') {
+                        $post.find('.spam-present').show();
+                    } else {
+                        $post.find('.spam-present').hide();
+                    }
                 }
 
                 function get_cm($elem) { return $('.CodeMirror', $elem)[0].CodeMirror; }

http://git-wip-us.apache.org/repos/asf/allura/blob/bf733986/Allura/allura/templates/widgets/post_widget.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/post_widget.html b/Allura/allura/templates/widgets/post_widget.html
index 2695c2b..6b8622d 100644
--- a/Allura/allura/templates/widgets/post_widget.html
+++ b/Allura/allura/templates/widgets/post_widget.html
@@ -49,6 +49,7 @@
           {% if h.has_access(value, 'moderate')() %}
           <form method="POST" action="{{value.url()+'moderate'}}">
             <input type="hidden" name="undo" value="True"/>
+            <input type="hidden" name="prev_status" value="{{value.status}}">
             <a href="" class="moderate_post little_link"><span>Undo</span></a>
             {{lib.csrf_token()}}
           </form>

http://git-wip-us.apache.org/repos/asf/allura/blob/bf733986/Allura/allura/tests/functional/test_discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 47218c8..719e57a 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -212,10 +212,17 @@ class TestDiscuss(TestDiscussBase):
         r = self._make_post('Test post')
         post_link = str(
             r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])
-        self.app.post(post_link + 'moderate', params=dict(undo='undo'))
+
+        self.app.post(post_link + 'moderate', params=dict(
+            undo='undo', prev_status='pending'))
         post = M.Post.query.find().first()
         assert post.status == 'pending'
 
+        self.app.post(post_link + 'moderate', params=dict(
+            undo='undo', prev_status='ok'))
+        post = M.Post.query.find().first()
+        assert post.status == 'ok'
+
     @patch.object(M.Thread, 'is_spam')
     def test_feed_does_not_include_comments_held_for_moderation(self, is_spam):
         is_spam.return_value = True


[36/50] allura git commit: [#8035] ESLINT FIX: no-multiple-empty-lines

Posted by he...@apache.org.
[#8035] ESLINT FIX: no-multiple-empty-lines


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

Branch: refs/heads/hs/8035
Commit: 8a131ab73ad28bae1f98eb7b521b952a0e524990
Parents: 29d313d
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 18:35:56 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:30 2016 -0500

----------------------------------------------------------------------
 Allura/allura/public/nf/js/context-menu.es6.js | 1 -
 Allura/allura/public/nf/js/navbar.es6.js       | 1 -
 Allura/allura/public/nf/js/tooltip.es6.js      | 1 -
 3 files changed, 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/8a131ab7/Allura/allura/public/nf/js/context-menu.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/context-menu.es6.js b/Allura/allura/public/nf/js/context-menu.es6.js
index 58d213d..ec5b68d 100644
--- a/Allura/allura/public/nf/js/context-menu.es6.js
+++ b/Allura/allura/public/nf/js/context-menu.es6.js
@@ -19,7 +19,6 @@
 /* eslint camelcase: 0 */
 'use strict';
 
-
 class ContextMenu extends React.Component {
     constructor(props) {
         super(props);

http://git-wip-us.apache.org/repos/asf/allura/blob/8a131ab7/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index a7266ae..585d004 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -379,7 +379,6 @@ var NavBarItemWithSubMenu = React.createClass({
     }
 });
 
-
 /**
  * The NavBar when in "Admin" mode.
  * @constructor

http://git-wip-us.apache.org/repos/asf/allura/blob/8a131ab7/Allura/allura/public/nf/js/tooltip.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/tooltip.es6.js b/Allura/allura/public/nf/js/tooltip.es6.js
index 87a865d..95f7188 100644
--- a/Allura/allura/public/nf/js/tooltip.es6.js
+++ b/Allura/allura/public/nf/js/tooltip.es6.js
@@ -54,7 +54,6 @@ class ToolTip extends React.Component {
         theme: 'tooltipster-light'
     };
 
-
     componentDidMount() {
         var _this = this;
         $(this.props.targetSelector).tooltipster({


[15/50] allura git commit: [#8044] ticket:891 Add url parameter to notification API, change notification API test

Posted by he...@apache.org.
[#8044] ticket:891 Add url parameter to notification API, change notification API test


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

Branch: refs/heads/hs/8035
Commit: 62cbf93216e98f421ed0573ef13186ffaeafd8ed
Parents: af8bd6e
Author: Denis Kotov <de...@gmail.com>
Authored: Sat Jan 23 14:48:42 2016 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:37:38 2016 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/rest.py           | 17 +++++++----------
 Allura/allura/lib/plugin.py                 |  8 ++++----
 Allura/allura/tests/functional/test_rest.py | 13 +++++++++++--
 3 files changed, 22 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/62cbf932/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index ef09398..70a9ffd 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -90,17 +90,14 @@ class RestController(object):
         return summary
 
     @expose('json:')
-    def notification(self, cookie='', **kw):
+    def notification(self, cookie='', url='', **kw):
         c.api_token = self._authenticate_request()
-        if c.api_token:
-            r = g.theme._get_site_notification(
-                user=c.api_token.user,
-                site_notification_cookie_value=cookie
-            )
-        else:
-            r = g.theme._get_site_notification(
-                site_notification_cookie_value=cookie
-            )
+        user = c.api_token.user if c.api_token else c.user
+        r = g.theme._get_site_notification(
+            url=url,
+            user=user,
+            site_notification_cookie_value=cookie
+        )
         if r:
             return dict(notification=r[0], cookie=r[1])
         return {}

http://git-wip-us.apache.org/repos/asf/allura/blob/62cbf932/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 6ae6eb0..dffd1fa 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -1310,20 +1310,19 @@ class ThemeProvider(object):
         else:
             return app.icon_url(size)
 
-    def _get_site_notification(self, user=None, site_notification_cookie_value=''):
-        from pylons import request
+    def _get_site_notification(self, url='', user=None, site_notification_cookie_value=''):
         from allura.model.notification import SiteNotification
         note = SiteNotification.current()
         if note is None:
             return None
-        if note.user_role and (not user or user.is_anonymous()):
+        if note.user_role and user.is_anonymous():
             return None
         if note.user_role:
             projects = user.my_projects_by_role_name(note.user_role)
             if len(projects) == 0 or len(projects) == 1 and projects[0].is_user_project:
                 return None
 
-        if note.page_regex and re.search(note.page_regex, request.path_qs) is None:
+        if note.page_regex and re.search(note.page_regex, url) is None:
             return None
         if note.page_tool_type and (c.app is None or c.app.config.tool_name.lower() != note.page_tool_type.lower()):
             return None
@@ -1345,6 +1344,7 @@ class ThemeProvider(object):
         from pylons import request, response
 
         r = self._get_site_notification(
+            request.path_qs,
             c.user,
             request.cookies.get('site-notification', '')
         )

http://git-wip-us.apache.org/repos/asf/allura/blob/62cbf932/Allura/allura/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py
index 0ff0526..3ec58f6 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -387,17 +387,26 @@ class TestRestHome(TestRestApiBase):
 
     @mock.patch('allura.lib.plugin.ThemeProvider._get_site_notification')
     def test_notification(self, _get_site_notification):
+        user = M.User.by_username('test-admin')
         note = M.SiteNotification()
         cookie = '{}-1-False'.format(note._id)
         g.theme._get_site_notification = mock.Mock(return_value=(note, cookie))
 
-        r = self.app.get('/rest/notification')
+        r = self.app.get('/rest/notification?url=test_url&cookie=test_cookie')
+        g.theme._get_site_notification.assert_called_once_with(
+            url='test_url',
+            site_notification_cookie_value='test_cookie',
+            user=user
+        )
 
         assert r.status_int == 200
-        print r.json
         assert r.json['cookie'] == cookie
         assert r.json['notification'] == note.__json__()
 
+        g.theme._get_site_notification = mock.Mock(return_value=None)
+        r = self.app.get('/rest/notification')
+        assert r.json == {}
+
 
 
 class TestDoap(TestRestApiBase):


[28/50] allura git commit: [#8035] ESLINT FIX: no-undef

Posted by he...@apache.org.
[#8035] ESLINT FIX: no-undef


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

Branch: refs/heads/hs/8035
Commit: a865796d558c2ddfc4ee4486d1aca8c4b385ba26
Parents: 24d21ad
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 17:23:37 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:27 2016 -0500

----------------------------------------------------------------------
 .eslintrc | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/a865796d/.eslintrc
----------------------------------------------------------------------
diff --git a/.eslintrc b/.eslintrc
index 2ba7869..f3fb796 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -7,6 +7,7 @@
   },
   "globals": {
     "ReactDOM": true,
+    "React": true,
     "$": true,
     "window": true,
     "_": true,


[48/50] allura git commit: [#8035] Update default eslint rules to xo/browser

Posted by he...@apache.org.
[#8035] Update default eslint rules to xo/browser


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

Branch: refs/heads/hs/8035
Commit: 03f02e77b74307f6bc9843b81ad510a5186a26fd
Parents: 817d26f
Author: Heith Seewald <he...@gmail.com>
Authored: Tue Jan 26 15:06:56 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:33 2016 -0500

----------------------------------------------------------------------
 .eslintrc-es6                            | 7 +++++--
 Allura/allura/public/nf/js/navbar.es6.js | 1 -
 package.json                             | 2 +-
 3 files changed, 6 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/03f02e77/.eslintrc-es6
----------------------------------------------------------------------
diff --git a/.eslintrc-es6 b/.eslintrc-es6
index b91ed8f..4427a53 100644
--- a/.eslintrc-es6
+++ b/.eslintrc-es6
@@ -4,6 +4,7 @@
     "indent": [2, 4],
     "jsx-quotes": [0],
     "quotes": [0],
+    "space-before-function-paren": [2, "never"],
     "operator-linebreak": [2, "before", { "overrides": { "?": "after", "&&": "after" } }],
     "require-jsdoc": [2, {"require": {
         "FunctionDeclaration": true,
@@ -29,11 +30,13 @@
   "env": {
     "es6": true,
     "jquery": true,
-    "browser": true
+    "browser": true,
+    "node": false
   },
-  "extends": "google",
+  "extends": "xo/browser",
   "ecmaFeatures": {
     "jsx": true,
+    "modules": false,
     "forOf": true,
     "blockBindings": true,
     "arrowFunctions": true,

http://git-wip-us.apache.org/repos/asf/allura/blob/03f02e77/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index ab7bbb5..d52ccec 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -17,7 +17,6 @@
        under the License.
 */
 /* eslint camelcase: 0 */
-/* eslint no-unused-vars: [2, {"args": "none", "varsIgnorePattern": "Main"}] */
 'use strict';
 
 /**

http://git-wip-us.apache.org/repos/asf/allura/blob/03f02e77/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 3ae1bc9..8b238b0 100644
--- a/package.json
+++ b/package.json
@@ -31,7 +31,7 @@
     "broccoli-timepiece": "^0.3.0",
     "broccoli-uglify-js": "^0.1.3",
     "eslint": "^1.10.3",
-    "eslint-config-google": "^0.3.0",
+    "eslint-config-xo": "^0.9.2",
     "eslint-plugin-html": "^1.2.0",
     "eslint-plugin-react": "^3.15.0",
     "esprima-fb": "^15001.1001.0-dev-harmony-fb"


[12/50] allura git commit: [#8044] ticket:889 Added rest api for get_site_notification

Posted by he...@apache.org.
[#8044] ticket:889 Added rest api for get_site_notification

* Added RestController.notification, SiteNotification.__json__
* Changed ThemeProvider.get_site_notification
* Added new tests


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

Branch: refs/heads/hs/8035
Commit: e8e7b93ae4d9a11f4cfc652c9532a6609bf25019
Parents: 3ccbb5d
Author: Denis Kotov <de...@gmail.com>
Authored: Tue Jan 19 23:11:25 2016 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:37:37 2016 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/rest.py              | 10 +++++++
 Allura/allura/lib/plugin.py                    | 14 ++++++++--
 Allura/allura/model/__init__.py                |  4 +--
 Allura/allura/model/notification.py            | 11 ++++++++
 Allura/allura/tests/functional/test_rest.py    | 13 +++++++++
 Allura/allura/tests/model/test_notification.py | 31 +++++++++++++++++++++
 Allura/allura/tests/test_plugin.py             | 31 +++++++++++++++++++++
 7 files changed, 109 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/e8e7b93a/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index a8a98fd..c091874 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -89,6 +89,16 @@ class RestController(object):
             summary['site_stats'] = stats
         return summary
 
+    @expose('json:')
+    def notification(self, cookie=None):
+        c.api_token = self._authenticate_request()
+        if c.api_token:
+            c.user = c.api_token.user
+        r = g.theme.get_site_notification(is_api=True, api_cookie=cookie)
+        if r:
+            return dict(notification=r[0], cookie=r[1])
+        return {}
+
     @expose()
     def _lookup(self, name, *remainder):
         c.api_token = self._authenticate_request()

http://git-wip-us.apache.org/repos/asf/allura/blob/e8e7b93a/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index cf833c1..e1653d9 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -1310,7 +1310,7 @@ class ThemeProvider(object):
         else:
             return app.icon_url(size)
 
-    def get_site_notification(self):
+    def get_site_notification(self, is_api=None, api_cookie=None):
         from pylons import request, response
         from allura.model.notification import SiteNotification
         note = SiteNotification.current()
@@ -1328,7 +1328,11 @@ class ThemeProvider(object):
         if note.page_tool_type and (c.app is None or c.app.config.tool_name.lower() != note.page_tool_type.lower()):
             return None
 
-        cookie = request.cookies.get('site-notification', '').split('-')
+        cookie = api_cookie
+        if not cookie:
+            cookie = request.cookies.get('site-notification', '')
+        cookie = cookie.split('-')
+
         if len(cookie) == 3 and cookie[0] == str(note._id):
             views = asint(cookie[1]) + 1
             closed = asbool(cookie[2])
@@ -1337,9 +1341,13 @@ class ThemeProvider(object):
             closed = False
         if closed or note.impressions > 0 and views > note.impressions:
             return None
+
+        set_cookie = '-'.join(map(str, [note._id, views, closed]))
+        if is_api:
+            return note, set_cookie
         response.set_cookie(
             'site-notification',
-            '-'.join(map(str, [note._id, views, closed])),
+            set_cookie,
             max_age=timedelta(days=365))
         return note
 

http://git-wip-us.apache.org/repos/asf/allura/blob/e8e7b93a/Allura/allura/model/__init__.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/__init__.py b/Allura/allura/model/__init__.py
index cb817b4..a69e7c9 100644
--- a/Allura/allura/model/__init__.py
+++ b/Allura/allura/model/__init__.py
@@ -29,7 +29,7 @@ from .attachments import BaseAttachment
 from .auth import AuthGlobals, User, ProjectRole, EmailAddress, OldProjectRole
 from .auth import AuditLog, audit_log, AlluraUserProperty
 from .filesystem import File
-from .notification import Notification, Mailbox
+from .notification import Notification, Mailbox, SiteNotification
 from .repository import Repository, RepositoryImplementation
 from .repository import MergeRequest, GitLikeTree
 from .stats import Stats
@@ -60,4 +60,4 @@ __all__ = [
     'OAuthRequestToken', 'OAuthAccessToken', 'MonQTask', 'Webhook', 'ACE', 'ACL', 'EVERYONE', 'ALL_PERMISSIONS',
     'DENY_ALL', 'MarkdownCache', 'main_doc_session', 'main_orm_session', 'project_doc_session', 'project_orm_session',
     'artifact_orm_session', 'repository_orm_session', 'task_orm_session', 'ArtifactSessionExtension', 'repository',
-    'repo_refresh', ]
+    'repo_refresh', 'SiteNotification']

http://git-wip-us.apache.org/repos/asf/allura/blob/e8e7b93a/Allura/allura/model/notification.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index dfde847..a513795 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -720,6 +720,17 @@ class SiteNotification(MappedClass):
     page_regex = FieldProperty(str, if_missing=None)
     page_tool_type = FieldProperty(str, if_missing=None)
 
+    def __json__(self):
+        return dict(
+            _id=str(self._id),
+            content=self.content,
+            active=self.active,
+            impressions=self.impressions,
+            user_role=self.user_role if self.user_role else '',
+            page_regex=self.page_regex if self.page_regex else '',
+            page_tool_type=self.page_tool_type if self.page_tool_type else ''
+        )
+
     @classmethod
     def current(cls):
         note = cls.query.find({'active': True}).sort('_id', -1).limit(1).first()

http://git-wip-us.apache.org/repos/asf/allura/blob/e8e7b93a/Allura/allura/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py
index 90b71ed..6f95c05 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -385,6 +385,19 @@ class TestRestHome(TestRestApiBase):
         self.app.post('/rest/p/test/wiki/NewPage', headers={'Origin': 'http://bad.com/'},
                       status=401)
 
+    @mock.patch('allura.lib.plugin.ThemeProvider.get_site_notification')
+    def test_notification(self, get_site_notification):
+        note = M.SiteNotification()
+        cookie = '{}-1-False'.format(note._id)
+        g.theme.get_site_notification = mock.Mock(return_value=(note, cookie))
+
+        r = self.app.get('/rest/notification')
+
+        assert r.status_int == 200
+        assert r.json['cookie'] == cookie
+        assert r.json['notification'] == note.__json__()
+
+
 
 class TestDoap(TestRestApiBase):
     validate_skip = True

http://git-wip-us.apache.org/repos/asf/allura/blob/e8e7b93a/Allura/allura/tests/model/test_notification.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_notification.py b/Allura/allura/tests/model/test_notification.py
index ac7ca3e..869a704 100644
--- a/Allura/allura/tests/model/test_notification.py
+++ b/Allura/allura/tests/model/test_notification.py
@@ -475,6 +475,37 @@ class TestSubscriptionTypes(unittest.TestCase):
         assert_equal(count, 1)
 
 
+class TestSiteNotification(unittest.TestCase):
+    def setUp(self):
+        self.note = M.SiteNotification(
+            active=True,
+            impressions=0,
+            content='test',
+            page_regex='',
+            page_tool_type='',
+            user_role=''
+        )
+
+    def test_json_type(self):
+        note_json = self.note.__json__()
+        assert isinstance(note_json, dict)
+
+    def test_json_keys(self):
+        keys = self.note.__json__().keys()
+        assert 'active' in keys
+        assert 'impressions' in keys
+        assert 'content' in keys
+        assert 'page_regex' in keys
+        assert 'page_tool_type' in keys
+        assert 'user_role' in keys
+
+    def test_json_values_if_missing(self):
+        note_json = self.note.__json__()
+        assert note_json['page_regex'] is ''
+        assert note_json['page_tool_type'] is ''
+        assert note_json['user_role'] is ''
+
+
 def _clear_subscriptions():
         M.Mailbox.query.remove({})
 

http://git-wip-us.apache.org/repos/asf/allura/blob/e8e7b93a/Allura/allura/tests/test_plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_plugin.py b/Allura/allura/tests/test_plugin.py
index 0441f18..4f65c23 100644
--- a/Allura/allura/tests/test_plugin.py
+++ b/Allura/allura/tests/test_plugin.py
@@ -489,6 +489,37 @@ class TestThemeProvider(object):
         request.path_qs = 'ttt'
         assert_is(ThemeProvider().get_site_notification(), None)
 
+    @patch('allura.model.notification.SiteNotification')
+    def test_get_site_notification_with_is_api(self, SiteNotification):
+        note = SiteNotification.current.return_value
+        note._id = 'test_id'
+        note.user_role = None
+        note.page_regex = None
+        note.page_tool_type = None
+        get_note = ThemeProvider().get_site_notification(is_api=True)
+
+        assert isinstance(get_note, tuple)
+        assert len(get_note) is 2
+        assert get_note[0] is note
+        assert get_note[1] == 'test_id-1-False'
+
+    @patch('allura.model.notification.SiteNotification')
+    @patch('pylons.request')
+    def test_get_site_notifications_with_api_cookie(self, request, SiteNotification):
+        note = SiteNotification.current.return_value
+        note._id = 'test_id'
+        note.user_role = None
+        note.page_regex = None
+        note.page_tool_type = None
+        request.cookies = {}
+        get_note = ThemeProvider().get_site_notification(
+            is_api=True,
+            api_cookie='test_id-1-False'
+        )
+
+        assert get_note[0] is note
+        assert get_note[1] == 'test_id-2-False'
+
 
 class TestLocalAuthenticationProvider(object):
 


[42/50] allura git commit: [#8035] ESLINT FIX: indent, block-scoped-var

Posted by he...@apache.org.
[#8035] ESLINT FIX: indent, block-scoped-var


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

Branch: refs/heads/hs/8035
Commit: 2fa2ce341c12eece8e48cff9154e87651ff3c995
Parents: 77529db
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 19:44:56 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:31 2016 -0500

----------------------------------------------------------------------
 .eslintrc                                | 3 ++-
 Allura/allura/public/nf/js/navbar.es6.js | 6 +++---
 2 files changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/2fa2ce34/.eslintrc
----------------------------------------------------------------------
diff --git a/.eslintrc b/.eslintrc
index e58bfe1..455b95a 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -11,7 +11,8 @@
         "ClassDeclaration": false
       }
     }],
-    "no-inline-comments": 0
+    "no-inline-comments": 0,
+    "comma-dangle": 0
   },
   "globals": {
     "ReactDOM": true,

http://git-wip-us.apache.org/repos/asf/allura/blob/2fa2ce34/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index 23f9313..52493bc 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -171,7 +171,7 @@ var NormalNavItem = React.createClass({
         url: React.PropTypes.string.isRequired,
         classes: React.PropTypes.string
     },
-  mixins: [React.addons.PureRenderMixin],
+    mixins: [React.addons.PureRenderMixin],
     render: function() {
         return (
             <li key={`tb-norm-${_.uniqueId()}`}>
@@ -291,7 +291,7 @@ var AdminNav = React.createClass({
         var [tools, anchoredTools, endTools] = [[], [], []];
         var subMenu;
         var childOptionsOpen;
-
+        var _handle;
         for (let item of items) {
             if (item.children) {
                 subMenu = this.buildMenu(item.children, true);
@@ -299,7 +299,7 @@ var AdminNav = React.createClass({
                 subMenu = null;
             }
 
-            var _handle = isSubMenu ? "draggable-handle-sub" : 'draggable-handle';
+            _handle = isSubMenu ? "draggable-handle-sub" : 'draggable-handle';
             var toolList;
             var isAnchored;
             if (item.mount_point === 'admin') {


[39/50] allura git commit: [#8035] ESLINT FIX: block-spacing, no-inline-comments

Posted by he...@apache.org.
[#8035] ESLINT FIX: block-spacing, no-inline-comments


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

Branch: refs/heads/hs/8035
Commit: fbb0147fd248b2ad295126788fbf8ee8fa8548ef
Parents: 5fa9548
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 19:25:59 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:30 2016 -0500

----------------------------------------------------------------------
 .eslintrc                                      | 5 +++--
 Allura/allura/public/nf/js/context-menu.es6.js | 1 -
 2 files changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/fbb0147f/.eslintrc
----------------------------------------------------------------------
diff --git a/.eslintrc b/.eslintrc
index 835cf29..e58bfe1 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -9,8 +9,9 @@
         "FunctionDeclaration": true,
         "MethodDefinition": false,
         "ClassDeclaration": false
-    }
-  }]
+      }
+    }],
+    "no-inline-comments": 0
   },
   "globals": {
     "ReactDOM": true,

http://git-wip-us.apache.org/repos/asf/allura/blob/fbb0147f/Allura/allura/public/nf/js/context-menu.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/context-menu.es6.js b/Allura/allura/public/nf/js/context-menu.es6.js
index 1762ffb..4c2958d 100644
--- a/Allura/allura/public/nf/js/context-menu.es6.js
+++ b/Allura/allura/public/nf/js/context-menu.es6.js
@@ -41,7 +41,6 @@ class ContextMenu extends React.Component {
             /* the :not filter should've worked as a 2nd param to .on() instead of this,
              but clicks in the page gutter were being delayed for some reason */
             if ($(evt.target).is(':not(.contextMenu)')) {
-
                 /* if clicking directly onto another gear, set it directly.
                  this is necessary since sometimes our jquery events seem to interfere with the react event
                  that is supposed to handle this kind of thing */


[26/50] allura git commit: [#8035] Update eslintrc to include plugins

Posted by he...@apache.org.
[#8035] Update eslintrc to include plugins


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

Branch: refs/heads/hs/8035
Commit: 24d21ad86985184ef11a771835df796bea169ef2
Parents: b8e8f9f
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 15:45:44 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:27 2016 -0500

----------------------------------------------------------------------
 .eslintrc | 51 +++++++++++++++++++--------------------------------
 1 file changed, 19 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/24d21ad8/.eslintrc
----------------------------------------------------------------------
diff --git a/.eslintrc b/.eslintrc
index 493b774..2ba7869 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,42 +1,29 @@
 {
   "rules": {
-    "indent": [2, 4],
-    "no-unused-vars": [2, {"vars": "all", "args": "none"}],
-    "no-console": 0,
-    "semi": [2, "always"],
-    "eqeqeq": 2,
-    "block-scoped-var": 2,
-    "consistent-return": 2,
-    // specify curly brace conventions for all control statements
-    "curly": [2, "all"],
-    // require default case in switch statements
-    "default-case": 2,
-    // disallow use of eval()
-    "no-eval": 2,
-    // disallow adding to native types
-    "no-extend-native": 2,
-    // disallow use of eval()-like methods
-    "no-implied-eval": 2,
-    // disallow this keywords outside of classes or class-like objects
-    "no-invalid-this": 2,
-    // disallow creation of functions within loops
-    "no-loop-func": 2,
-    // disallow declaring the same variable more then once
-    "no-redeclare": 2,
-    // disallow use of the with statement
-    "no-with": 2,
-    // require use of the second argument for parseInt()
-    "radix": 2
+    "indent": [
+      2,
+      4
+    ]
   },
   "globals": {
-
+    "ReactDOM": true,
+    "$": true,
+    "window": true,
+    "_": true,
+    "ReactReorderable": true
   },
-  "parser": "esprima-fb",
+  "parser": "babel-eslint",
   "env": {
-    "browser": true,
-    "jquery": true
+    "es6": true,
+    "browser": true
+  },
+  "extends": "google",
+  "ecmaFeatures": {
+    "jsx": true,
+    "forOf": true,
+    "experimentalObjectRestSpread": true
   },
-  "extends": "eslint:recommended",
   "plugins": [
+    "react"
   ]
 }
\ No newline at end of file


[23/50] allura git commit: [#8054] delete Google Code importers and tests

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/data/google/test-issue-first-page.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/data/google/test-issue-first-page.html b/ForgeImporters/forgeimporters/tests/data/google/test-issue-first-page.html
deleted file mode 100644
index 4fc25eb..0000000
--- a/ForgeImporters/forgeimporters/tests/data/google/test-issue-first-page.html
+++ /dev/null
@@ -1,548 +0,0 @@
-<!DOCTYPE html>
-<!--
-
-An issue with a link to another page of comments (google paginates after 500 comments, we simulate with less)
-test-issue-prev-page.html is the test file for that other page of comments
-
--->
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
-<meta name="ROBOTS" content="NOARCHIVE" />
-<link rel="icon" type="image/vnd.microsoft.icon" href="http://www.gstatic.com/codesite/ph/images/phosting.ico" />
-<script type="text/javascript">
-
-
-
-
- var codesite_token = null;
-
-
- var CS_env = {"loggedInUserEmail":null,"relativeBaseUrl":"","projectHomeUrl":"/p/allura-google-importer","assetVersionPath":"http://www.gstatic.com/codesite/ph/3783617020303179221","assetHostPath":"http://www.gstatic.com/codesite/ph","domainName":null,"projectName":"allura-google-importer","token":null,"profileUrl":null};
- var _gaq = _gaq || [];
- _gaq.push(
- ['siteTracker._setAccount', 'UA-18071-1'],
- ['siteTracker._trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
- })();
-
- </script>
-<title>Issue 6 -
- allura-google-importer -
-
- Test Issue -
- Import Google Code projects to an Allura forge - Google Project Hosting
- </title>
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/core.css" />
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/ph_detail.css" />
-<!--[if IE]>
- <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/d_ie.css" >
-<![endif]-->
-<style type="text/css">
- .menuIcon.off { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -42px }
- .menuIcon.on { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -28px }
- .menuIcon.down { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 0; }
-
-
- .attachments { width:33%; border-top:2px solid #999; padding-top: 3px; margin-left: .7em;}
- .attachments table { margin-bottom: 0.75em; }
- .attachments table tr td { padding: 0; margin: 0; font-size: 95%; }
- .preview { border: 2px solid #c3d9ff; padding: 1px; }
- .preview:hover { border: 2px solid blue; }
- .label { white-space: nowrap; }
- .derived { font-style:italic }
- .cursor_on .author {
- background: url(http://www.gstatic.com/codesite/ph/images/show-arrow.gif) no-repeat 2px;
- }
- .hiddenform {
- display: none;
- }
-
-
- </style>
-</head>
-<body class="t3">
-<script type="text/javascript">
- window.___gcfg = {lang: 'en'};
- (function()
- {var po = document.createElement("script");
- po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
- var s = document.getElementsByTagName("script")[0];
- s.parentNode.insertBefore(po, s);
- })();
-</script>
-<div class="headbg">
-<div id="gaia">
-<span>
-<a href="#" id="projects-dropdown" onclick="return false;"><u>My favorites</u> <small>&#9660;</small></a>
- | <a href="https://www.google.com/accounts/ServiceLogin?service=code&amp;ltmpl=phosting&amp;continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&amp;followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6" onclick="_CS_click('/gb/ph/signin');"><u>Sign in</u></a>
-</span>
-</div>
-<div class="gbh" style="left: 0pt;"></div>
-<div class="gbh" style="right: 0pt;"></div>
-<div style="height: 1px"></div>
-<!--[if lte IE 7]>
-<div style="text-align:center;">
-Your version of Internet Explorer is not supported. Try a browser that
-contributes to open source, such as <a href="http://www.firefox.com">Firefox</a>,
-<a href="http://www.google.com/chrome">Google Chrome</a>, or
-<a href="http://code.google.com/chrome/chromeframe/">Google Chrome Frame</a>.
-</div>
-<![endif]-->
-<table style="padding:0px; margin: 0px 0px 10px 0px; width:100%" cellpadding="0" cellspacing="0" itemscope="itemscope" itemtype="http://schema.org/CreativeWork">
-<tr style="height: 58px;">
-<td id="plogo">
-<link itemprop="url" href="/p/allura-google-importer" />
-<a href="/p/allura-google-importer/">
-<img src="/p/allura-google-importer/logo?cct=1374769571" alt="Logo" itemprop="image" />
-</a>
-</td>
-<td style="padding-left: 0.5em">
-<div id="pname">
-<a href="/p/allura-google-importer/"><span itemprop="name">allura-google-importer</span></a>
-</div>
-<div id="psum">
-<a id="project_summary_link" href="/p/allura-google-importer/"><span itemprop="description">Import Google Code projects to an Allura forge</span></a>
-</div>
-</td>
-<td style="white-space:nowrap;text-align:right; vertical-align:bottom;">
-<form action="/hosting/search">
-<input size="30" name="q" value="" type="text" />
-<input type="submit" name="projectsearch" value="Search projects" />
-</form>
-</td></tr>
-</table>
-</div>
-<div id="mt" class="gtb">
-<a href="/p/allura-google-importer/" class="tab ">Project&nbsp;Home</a>
-<a href="/p/allura-google-importer/wiki/TestPage?tm=6" class="tab ">Wiki</a>
-<a href="/p/allura-google-importer/issues/list" class="tab active">Issues</a>
-<a href="/p/allura-google-importer/source/checkout" class="tab ">Source</a>
-<div class="gtbc"></div>
-</div>
-<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0" class="st">
-<tr>
-<td class="subt">
-<div class="issueDetail">
-<div class="isf">
-<span class="inIssueEntry">
-<a class="buttonify" href="entry" onclick="return _newIssuePrompt();">New issue</a>
-</span> &nbsp;
-
- <span class="inIssueList">
-<span>Search</span>
-</span><form action="list" method="GET" style="display:inline">
-<select id="can" name="can">
-<option disabled="disabled">Search within:</option>
-<option value="1">&nbsp;All issues</option>
-<option value="2" selected="selected">&nbsp;Open issues</option>
-<option value="6">&nbsp;New issues</option>
-<option value="7">&nbsp;Issues to verify</option>
-</select>
-<span>for</span>
-<span id="qq"><input type="text" size="38" id="searchq" name="q" value="" autocomplete="off" onkeydown="_blurOnEsc(event)" /></span>
-<span id="search_colspec"><input type="hidden" name="colspec" value="ID Type Status Priority Milestone Owner Summary" /></span>
-<input type="hidden" name="cells" value="tiles" />
-<input type="submit" value="Search" />
-</form>
- &nbsp;
- <span class="inIssueAdvSearch">
-<a href="advsearch">Advanced search</a>
-</span> &nbsp;
- <span class="inIssueSearchTips">
-<a href="searchtips">Search tips</a>
-</span> &nbsp;
- <span class="inIssueSubscriptions">
-<a href="/p/allura-google-importer/issues/subscriptions">Subscriptions</a>
-</span>
-</div>
-</div>
-</td>
-<td align="right" valign="top" class="bevel-right"></td>
-</tr>
-</table>
-<script type="text/javascript">
- var cancelBubble = false;
- function _go(url) { document.location = url; }
-</script>
-<div id="maincol">
-<div id="color_control" class="">
-<div id="issueheader">
-<table cellpadding="0" cellspacing="0" width="100%"><tbody>
-<tr>
-<td class="vt h3" nowrap="nowrap" style="padding:0 5px">
-
-
- Issue <a href="detail?id=6">6</a>:
- </td>
-<td width="90%" class="vt">
-<span class="h3">Test &quot;Issue&quot;</span>
-</td>
-<td>
-<div class="pagination">
-<a href="../../allura-google-importer/issues/detail?id=5" title="Prev">&lsaquo; Prev</a>
- 6 of 6
-
- </div>
-</td>
-</tr>
-<tr>
-<td></td>
-<td nowrap="nowrap">
-
-
- 1 person starred this issue and may be notified of changes.
-
-
-
- </td>
-<td align="center" nowrap="nowrap">
-<a href="http://code.google.com/p/allura-google-importer/issues/list?cursor=allura-google-importer%3A6">Back to list</a>
-</td>
-</tr>
-</tbody></table>
-</div>
-<table width="100%" cellpadding="0" cellspacing="0" border="0" class="issuepage" id="meta-container">
-<tbody class="collapse">
-<tr>
-<td id="issuemeta">
-<div id="meta-float">
-<table cellspacing="0" cellpadding="0">
-<tr><th align="left">Status:&nbsp;</th>
-<td width="100%">
-<span title="Work on this issue has begun">Started</span>
-</td>
-</tr>
-<tr><th align="left">Owner:&nbsp;</th><td>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a>
-</td>
-</tr>
-<tr><td colspan="2">
-<div style="padding-top:2px">
-<a href="list?q=label:Type-Defect" title="Report of a software defect" class="label"><b>Type-</b>Defect</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Priority-Medium" title="Normal priority" class="label"><b>Priority-</b>Medium</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Milestone-Release1.0" title="All essential functionality working" class="label"><b>Milestone-</b>Release1.0</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-All" title="Affects all operating systems" class="label"><b>OpSys-</b>All</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Component-Logic" title="Issue relates to application logic" class="label"><b>Component-</b>Logic</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Performance" title="Performance issue" class="label">Performance</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Security" title="Security risk to users" class="label">Security</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-Windows" title="Affects Windows users" class="label"><b>OpSys-</b>Windows</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-OSX" title="Affects Mac OS X users" class="label"><b>OpSys-</b>OSX</a>
-</div>
-</td></tr>
-</table>
-<div class="rel_issues">
-</div>
-<br /><br />
-<div style="white-space:nowrap"><a href="https://www.google.com/accounts/ServiceLogin?service=code&amp;ltmpl=phosting&amp;continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&amp;followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6">Sign in</a> to add a comment</div>
-</div>&nbsp;
- </td>
-<td class="vt issuedescription" width="100%" id="cursorarea">
-<div class="cursor_off vt issuedescription" id="hc0">
-<div class="author">
-<span class="role_label">Project Member</span>
- Reported by
-
-
- <a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a>,
- <span class="date" title="Thu Aug  8 15:33:52 2013">Today (3 minutes ago)</span>
-</div>
-<pre>
-Test *Issue* for testing
-
-  1. Test List
-  2. Item
-
-**Testing**
-
- * Test list 2
- * Item
-
-# Test Section
-
-    p = source.test_issue.post()
-    p.count = p.count *5 #* 6
-    if p.count &gt; 5:
-        print "Not &lt; 5 &amp; != 5"
-
-References: <a href="/p/allura-google-importer/issues/detail?id=1">issue 1</a>, <a href="/p/allura-google-importer/source/detail?r=2">r2</a>
-
-That's all
-
-
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000000&amp;name=at1.txt&amp;token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at1.txt</b>
-<br />
- 13 bytes
-
-
- &nbsp; <a href="../../allura-google-importer/issues/attachmentText?id=7&amp;aid=70000000&amp;name=at1.txt&amp;token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255" target="_blank">View</a>
-
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000000&amp;name=at1.txt&amp;token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255">Download</a>
-</td>
-</tr>
-</table>
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&amp;name=&amp;token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b></b>
-<br />
- 0 bytes
-
-
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&amp;name=&amp;token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">Download</a>
-</td>
-</tr>
-</table>
-</div>
-</div>
-
- <div class="vt issuecomment" width="100%" style="background:#e5ecf9; padding:2px .7em; margin:0; border:0">
-Showing comments 3 - 6
-of 6
- &nbsp; <a href="detail?id=1769&amp;cnum=500&amp;cstart=2">Older <b>&rsaquo;</b></a>
- </div>
-
-<div class="cursor_off vt issuecomment" id="hc1">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug  8 15:35:15 2013">
- Today (2 minutes ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c1" href="/p/allura-google-importer/issues/detail?id=6#c1">#1</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Test *comment* is a comment
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60001000&amp;name=&amp;token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at2.txt</b>
-<br />
- 13 bytes
-
-
- &nbsp; <a href="../../allura-google-importer/issues/attachmentText?id=6&amp;aid=60001000&amp;name=at2.txt&amp;token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667" target="_blank">View</a>
-
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60001000&amp;name=at2.txt&amp;token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667">Download</a>
-</td>
-</tr>
-</table>
-</div>
-<div class="updates">
-<div class="round4"></div>
-<div class="round2"></div>
-<div class="round1"></div>
-<div class="box-inner">
-<b>Status:</b>
- Started
-
- <br />
-<b>Labels:</b>
- -OpSys-Linux OpSys-Windows
-
- <br />
-</div>
-<div class="round1"></div>
-<div class="round2"></div>
-<div class="round4"></div>
-</div>
-</div>
-<div class="cursor_off vt issuecomment" id="hc2">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug  8 15:35:34 2013">
- Today (1 minute ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c2" href="/p/allura-google-importer/issues/detail?id=6#c2">#2</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Another comment with references: <a href="/p/allura-google-importer/issues/detail?id=2">issue 2</a>, <a href="/p/allura-google-importer/source/detail?r=1">r1</a>
-</pre>
-</div>
-<div class="cursor_off vt issuecomment" id="hc3">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug  8 15:36:39 2013">
- Today (moments ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c3" href="/p/allura-google-importer/issues/detail?id=6#c3">#3</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Last comment
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003000&amp;name=at4.txt&amp;token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at4.txt</b>
-<br />
- 13 bytes
-
-
- &nbsp; <a href="../../allura-google-importer/issues/attachmentText?id=6&amp;aid=60003000&amp;name=at4.txt&amp;token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667" target="_blank">View</a>
-
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003000&amp;name=at4.txt&amp;token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667">Download</a>
-</td>
-</tr>
-</table>
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003001&amp;name=at1.txt&amp;token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at1.txt</b>
-<br />
- 13 bytes
-
-
- &nbsp; <a href="../../allura-google-importer/issues/attachmentText?id=6&amp;aid=60003001&amp;name=at1.txt&amp;token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667" target="_blank">View</a>
-
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003001&amp;name=at1.txt&amp;token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667">Download</a>
-</td>
-</tr>
-</table>
-</div>
-</div>
-<div class="cursor_off vt issuecomment" id="hc4">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug  8 15:36:57 2013">
- Today (moments ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c4" href="/p/allura-google-importer/issues/detail?id=6#c4">#4</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Oh, I forgot one (with an inter-project reference to <a href="/p/other-project/issues/detail?id=1">issue other-project:1</a>)
-</pre>
-<div class="updates">
-<div class="round4"></div>
-<div class="round2"></div>
-<div class="round1"></div>
-<div class="box-inner">
-<b>Labels:</b>
- OpSys-OSX
-
- <br />
-</div>
-<div class="round1"></div>
-<div class="round2"></div>
-<div class="round4"></div>
-</div>
-</div>
-
-<div class="vt issuecomment" width="100%" style="background:#e5ecf9; padding:2px .7em; margin:0">
-Showing comments 3 - 6
-of 6
- &nbsp; <a href="detail?id=1769&amp;cnum=500&amp;cstart=2">Older <b>&rsaquo;</b></a>
-</div>
-
-</td>
-</tr>
-<tr>
-<td></td>
-<td class="vt issuecomment">
-<span class="indicator">&#9658;</span> <a href="https://www.google.com/accounts/ServiceLogin?service=code&amp;ltmpl=phosting&amp;continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&amp;followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6">Sign in</a> to add a comment
- </td>
-</tr>
-</tbody>
-</table>
-<br />
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/dit_scripts.js"></script>
-</div>
-<form name="delcom" action="delComment.do?q=&amp;can=2&amp;groupby=&amp;sort=&amp;colspec=ID+Type+Status+Priority+Milestone+Owner+Summary" method="POST">
-<input type="hidden" name="sequence_num" value="" />
-<input type="hidden" name="mode" value="" />
-<input type="hidden" name="id" value="6" />
-<input type="hidden" name="token" value="" />
-</form>
-<div id="helparea"></div>
-<script type="text/javascript">
- _onload();
- function delComment(sequence_num, delete_mode) {
- var f = document.forms["delcom"];
- f.sequence_num.value = sequence_num;
- f.mode.value = delete_mode;
-
- f.submit();
- return false;
- }
-
- _floatMetadata();
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/kibbles.js"></script>
-<script type="text/javascript">
- _setupKibblesOnDetailPage(
- 'http://code.google.com/p/allura-google-importer/issues/list?cursor\x3dallura-google-importer%3A6',
- '/p/allura-google-importer/issues/entry',
- '../../allura-google-importer/issues/detail?id\x3d5',
- '',
- '', 'allura-google-importer', 6,
- false, false, codesite_token);
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/ph_core.js"></script>
-</div>
-<div id="footer" dir="ltr">
-<div class="text">
-<a href="/projecthosting/terms.html">Terms</a> -
- <a href="http://www.google.com/privacy.html">Privacy</a> -
- <a href="/p/support/">Project Hosting Help</a>
-</div>
-</div>
-<div class="hostedBy" style="margin-top: -20px;">
-<span style="vertical-align: top;">Powered by <a href="http://code.google.com/projecthosting/">Google Project Hosting</a></span>
-</div>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/data/google/test-issue-prev-page.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/data/google/test-issue-prev-page.html b/ForgeImporters/forgeimporters/tests/data/google/test-issue-prev-page.html
deleted file mode 100644
index 62a3b23..0000000
--- a/ForgeImporters/forgeimporters/tests/data/google/test-issue-prev-page.html
+++ /dev/null
@@ -1,431 +0,0 @@
-<!DOCTYPE html>
-<!--
-
-This is the second page of previous comments, that goes with test-issue-first-page.html
-
--->
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
-<meta name="ROBOTS" content="NOARCHIVE" />
-<link rel="icon" type="image/vnd.microsoft.icon" href="http://www.gstatic.com/codesite/ph/images/phosting.ico" />
-<script type="text/javascript">
-
-
-
-
- var codesite_token = null;
-
-
- var CS_env = {"loggedInUserEmail":null,"relativeBaseUrl":"","projectHomeUrl":"/p/allura-google-importer","assetVersionPath":"http://www.gstatic.com/codesite/ph/3783617020303179221","assetHostPath":"http://www.gstatic.com/codesite/ph","domainName":null,"projectName":"allura-google-importer","token":null,"profileUrl":null};
- var _gaq = _gaq || [];
- _gaq.push(
- ['siteTracker._setAccount', 'UA-18071-1'],
- ['siteTracker._trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
- })();
-
- </script>
-<title>Issue 6 -
- allura-google-importer -
-
- Test Issue -
- Import Google Code projects to an Allura forge - Google Project Hosting
- </title>
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/core.css" />
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/ph_detail.css" />
-<!--[if IE]>
- <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/d_ie.css" >
-<![endif]-->
-<style type="text/css">
- .menuIcon.off { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -42px }
- .menuIcon.on { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -28px }
- .menuIcon.down { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 0; }
-
-
- .attachments { width:33%; border-top:2px solid #999; padding-top: 3px; margin-left: .7em;}
- .attachments table { margin-bottom: 0.75em; }
- .attachments table tr td { padding: 0; margin: 0; font-size: 95%; }
- .preview { border: 2px solid #c3d9ff; padding: 1px; }
- .preview:hover { border: 2px solid blue; }
- .label { white-space: nowrap; }
- .derived { font-style:italic }
- .cursor_on .author {
- background: url(http://www.gstatic.com/codesite/ph/images/show-arrow.gif) no-repeat 2px;
- }
- .hiddenform {
- display: none;
- }
-
-
- </style>
-</head>
-<body class="t3">
-<script type="text/javascript">
- window.___gcfg = {lang: 'en'};
- (function()
- {var po = document.createElement("script");
- po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
- var s = document.getElementsByTagName("script")[0];
- s.parentNode.insertBefore(po, s);
- })();
-</script>
-<div class="headbg">
-<div id="gaia">
-<span>
-<a href="#" id="projects-dropdown" onclick="return false;"><u>My favorites</u> <small>&#9660;</small></a>
- | <a href="https://www.google.com/accounts/ServiceLogin?service=code&amp;ltmpl=phosting&amp;continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&amp;followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6" onclick="_CS_click('/gb/ph/signin');"><u>Sign in</u></a>
-</span>
-</div>
-<div class="gbh" style="left: 0pt;"></div>
-<div class="gbh" style="right: 0pt;"></div>
-<div style="height: 1px"></div>
-<!--[if lte IE 7]>
-<div style="text-align:center;">
-Your version of Internet Explorer is not supported. Try a browser that
-contributes to open source, such as <a href="http://www.firefox.com">Firefox</a>,
-<a href="http://www.google.com/chrome">Google Chrome</a>, or
-<a href="http://code.google.com/chrome/chromeframe/">Google Chrome Frame</a>.
-</div>
-<![endif]-->
-<table style="padding:0px; margin: 0px 0px 10px 0px; width:100%" cellpadding="0" cellspacing="0" itemscope="itemscope" itemtype="http://schema.org/CreativeWork">
-<tr style="height: 58px;">
-<td id="plogo">
-<link itemprop="url" href="/p/allura-google-importer" />
-<a href="/p/allura-google-importer/">
-<img src="/p/allura-google-importer/logo?cct=1374769571" alt="Logo" itemprop="image" />
-</a>
-</td>
-<td style="padding-left: 0.5em">
-<div id="pname">
-<a href="/p/allura-google-importer/"><span itemprop="name">allura-google-importer</span></a>
-</div>
-<div id="psum">
-<a id="project_summary_link" href="/p/allura-google-importer/"><span itemprop="description">Import Google Code projects to an Allura forge</span></a>
-</div>
-</td>
-<td style="white-space:nowrap;text-align:right; vertical-align:bottom;">
-<form action="/hosting/search">
-<input size="30" name="q" value="" type="text" />
-<input type="submit" name="projectsearch" value="Search projects" />
-</form>
-</td></tr>
-</table>
-</div>
-<div id="mt" class="gtb">
-<a href="/p/allura-google-importer/" class="tab ">Project&nbsp;Home</a>
-<a href="/p/allura-google-importer/wiki/TestPage?tm=6" class="tab ">Wiki</a>
-<a href="/p/allura-google-importer/issues/list" class="tab active">Issues</a>
-<a href="/p/allura-google-importer/source/checkout" class="tab ">Source</a>
-<div class="gtbc"></div>
-</div>
-<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0" class="st">
-<tr>
-<td class="subt">
-<div class="issueDetail">
-<div class="isf">
-<span class="inIssueEntry">
-<a class="buttonify" href="entry" onclick="return _newIssuePrompt();">New issue</a>
-</span> &nbsp;
-
- <span class="inIssueList">
-<span>Search</span>
-</span><form action="list" method="GET" style="display:inline">
-<select id="can" name="can">
-<option disabled="disabled">Search within:</option>
-<option value="1">&nbsp;All issues</option>
-<option value="2" selected="selected">&nbsp;Open issues</option>
-<option value="6">&nbsp;New issues</option>
-<option value="7">&nbsp;Issues to verify</option>
-</select>
-<span>for</span>
-<span id="qq"><input type="text" size="38" id="searchq" name="q" value="" autocomplete="off" onkeydown="_blurOnEsc(event)" /></span>
-<span id="search_colspec"><input type="hidden" name="colspec" value="ID Type Status Priority Milestone Owner Summary" /></span>
-<input type="hidden" name="cells" value="tiles" />
-<input type="submit" value="Search" />
-</form>
- &nbsp;
- <span class="inIssueAdvSearch">
-<a href="advsearch">Advanced search</a>
-</span> &nbsp;
- <span class="inIssueSearchTips">
-<a href="searchtips">Search tips</a>
-</span> &nbsp;
- <span class="inIssueSubscriptions">
-<a href="/p/allura-google-importer/issues/subscriptions">Subscriptions</a>
-</span>
-</div>
-</div>
-</td>
-<td align="right" valign="top" class="bevel-right"></td>
-</tr>
-</table>
-<script type="text/javascript">
- var cancelBubble = false;
- function _go(url) { document.location = url; }
-</script>
-<div id="maincol">
-<div id="color_control" class="">
-<div id="issueheader">
-<table cellpadding="0" cellspacing="0" width="100%"><tbody>
-<tr>
-<td class="vt h3" nowrap="nowrap" style="padding:0 5px">
-
-
- Issue <a href="detail?id=6">6</a>:
- </td>
-<td width="90%" class="vt">
-<span class="h3">Test &quot;Issue&quot;</span>
-</td>
-<td>
-<div class="pagination">
-<a href="../../allura-google-importer/issues/detail?id=5" title="Prev">&lsaquo; Prev</a>
- 6 of 6
-
- </div>
-</td>
-</tr>
-<tr>
-<td></td>
-<td nowrap="nowrap">
-
-
- 1 person starred this issue and may be notified of changes.
-
-
-
- </td>
-<td align="center" nowrap="nowrap">
-<a href="http://code.google.com/p/allura-google-importer/issues/list?cursor=allura-google-importer%3A6">Back to list</a>
-</td>
-</tr>
-</tbody></table>
-</div>
-<table width="100%" cellpadding="0" cellspacing="0" border="0" class="issuepage" id="meta-container">
-<tbody class="collapse">
-<tr>
-<td id="issuemeta">
-<div id="meta-float">
-<table cellspacing="0" cellpadding="0">
-<tr><th align="left">Status:&nbsp;</th>
-<td width="100%">
-<span title="Work on this issue has begun">Started</span>
-</td>
-</tr>
-<tr><th align="left">Owner:&nbsp;</th><td>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a>
-</td>
-</tr>
-<tr><td colspan="2">
-<div style="padding-top:2px">
-<a href="list?q=label:Type-Defect" title="Report of a software defect" class="label"><b>Type-</b>Defect</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Priority-Medium" title="Normal priority" class="label"><b>Priority-</b>Medium</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Milestone-Release1.0" title="All essential functionality working" class="label"><b>Milestone-</b>Release1.0</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-All" title="Affects all operating systems" class="label"><b>OpSys-</b>All</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Component-Logic" title="Issue relates to application logic" class="label"><b>Component-</b>Logic</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Performance" title="Performance issue" class="label">Performance</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Security" title="Security risk to users" class="label">Security</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-Windows" title="Affects Windows users" class="label"><b>OpSys-</b>Windows</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-OSX" title="Affects Mac OS X users" class="label"><b>OpSys-</b>OSX</a>
-</div>
-</td></tr>
-</table>
-<div class="rel_issues">
-</div>
-<br /><br />
-<div style="white-space:nowrap"><a href="https://www.google.com/accounts/ServiceLogin?service=code&amp;ltmpl=phosting&amp;continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&amp;followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6">Sign in</a> to add a comment</div>
-</div>&nbsp;
- </td>
-<td class="vt issuedescription" width="100%" id="cursorarea">
-<div class="cursor_off vt issuedescription" id="hc0">
-<div class="author">
-<span class="role_label">Project Member</span>
- Reported by
-
-
- <a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a>,
- <span class="date" title="Thu Aug  8 15:33:52 2013">Today (3 minutes ago)</span>
-</div>
-<pre>
-Test *Issue* for testing
-
-  1. Test List
-  2. Item
-
-**Testing**
-
- * Test list 2
- * Item
-
-# Test Section
-
-    p = source.test_issue.post()
-    p.count = p.count *5 #* 6
-    if p.count &gt; 5:
-        print "Not &lt; 5 &amp; != 5"
-
-References: <a href="/p/allura-google-importer/issues/detail?id=1">issue 1</a>, <a href="/p/allura-google-importer/source/detail?r=2">r2</a>
-
-That's all
-
-
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000000&amp;name=at1.txt&amp;token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at1.txt</b>
-<br />
- 13 bytes
-
-
- &nbsp; <a href="../../allura-google-importer/issues/attachmentText?id=7&amp;aid=70000000&amp;name=at1.txt&amp;token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255" target="_blank">View</a>
-
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000000&amp;name=at1.txt&amp;token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255">Download</a>
-</td>
-</tr>
-</table>
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&amp;name=&amp;token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b></b>
-<br />
- 0 bytes
-
-
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&amp;name=&amp;token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">Download</a>
-</td>
-</tr>
-</table>
-</div>
-</div>
-
- <div class="vt issuecomment" width="100%" style="background:#e5ecf9; padding:2px .7em; margin:0; border:0">
- <a href="detail?id=1769&amp;cnum=500&amp;cstart=502">Newer <b>&rsaquo;</b></a>
- &nbsp;
-Showing comments 1 - 2
-of 6
- </div>
-
-<div class="cursor_off vt issuecomment" id="hc1">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug  8 15:34:01 2013">
- Today (3 minutes ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c1" href="/p/allura-google-importer/issues/detail?id=6#c1">#1</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Simple comment
-</pre>
-</div>
-<div class="cursor_off vt issuecomment" id="hc2">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug  8 15:34:09 2013">
- Today (3 minutes ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c2" href="/p/allura-google-importer/issues/detail?id=6#c2">#2</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Boring comment
-</pre>
-</div>
-
-<div class="vt issuecomment" width="100%" style="background:#e5ecf9; padding:2px .7em; margin:0">
- <a href="detail?id=1769&amp;cnum=500&amp;cstart=502">Newer <b>&rsaquo;</b></a>
- &nbsp;
-Showing comments 1 - 2
-of 6
-</div>
-
-</td>
-</tr>
-<tr>
-<td></td>
-<td class="vt issuecomment">
-<span class="indicator">&#9658;</span> <a href="https://www.google.com/accounts/ServiceLogin?service=code&amp;ltmpl=phosting&amp;continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&amp;followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6">Sign in</a> to add a comment
- </td>
-</tr>
-</tbody>
-</table>
-<br />
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/dit_scripts.js"></script>
-</div>
-<form name="delcom" action="delComment.do?q=&amp;can=2&amp;groupby=&amp;sort=&amp;colspec=ID+Type+Status+Priority+Milestone+Owner+Summary" method="POST">
-<input type="hidden" name="sequence_num" value="" />
-<input type="hidden" name="mode" value="" />
-<input type="hidden" name="id" value="6" />
-<input type="hidden" name="token" value="" />
-</form>
-<div id="helparea"></div>
-<script type="text/javascript">
- _onload();
- function delComment(sequence_num, delete_mode) {
- var f = document.forms["delcom"];
- f.sequence_num.value = sequence_num;
- f.mode.value = delete_mode;
-
- f.submit();
- return false;
- }
-
- _floatMetadata();
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/kibbles.js"></script>
-<script type="text/javascript">
- _setupKibblesOnDetailPage(
- 'http://code.google.com/p/allura-google-importer/issues/list?cursor\x3dallura-google-importer%3A6',
- '/p/allura-google-importer/issues/entry',
- '../../allura-google-importer/issues/detail?id\x3d5',
- '',
- '', 'allura-google-importer', 6,
- false, false, codesite_token);
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/ph_core.js"></script>
-</div>
-<div id="footer" dir="ltr">
-<div class="text">
-<a href="/projecthosting/terms.html">Terms</a> -
- <a href="http://www.google.com/privacy.html">Privacy</a> -
- <a href="/p/support/">Project Hosting Help</a>
-</div>
-</div>
-<div class="hostedBy" style="margin-top: -20px;">
-<span style="vertical-align: top;">Powered by <a href="http://code.google.com/projecthosting/">Google Project Hosting</a></span>
-</div>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/data/google/test-issue.html
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/data/google/test-issue.html b/ForgeImporters/forgeimporters/tests/data/google/test-issue.html
deleted file mode 100644
index 59507a9..0000000
--- a/ForgeImporters/forgeimporters/tests/data/google/test-issue.html
+++ /dev/null
@@ -1,535 +0,0 @@
-<!DOCTYPE html>
-<!--
-
-Just a regular single-page issue
-
--->
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
-<meta name="ROBOTS" content="NOARCHIVE" />
-<link rel="icon" type="image/vnd.microsoft.icon" href="http://www.gstatic.com/codesite/ph/images/phosting.ico" />
-<script type="text/javascript">
-
-
-
-
- var codesite_token = null;
-
-
- var CS_env = {"loggedInUserEmail":null,"relativeBaseUrl":"","projectHomeUrl":"/p/allura-google-importer","assetVersionPath":"http://www.gstatic.com/codesite/ph/3783617020303179221","assetHostPath":"http://www.gstatic.com/codesite/ph","domainName":null,"projectName":"allura-google-importer","token":null,"profileUrl":null};
- var _gaq = _gaq || [];
- _gaq.push(
- ['siteTracker._setAccount', 'UA-18071-1'],
- ['siteTracker._trackPageview']);
-
- (function() {
- var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
- ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
- (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
- })();
-
- </script>
-<title>Issue 6 -
- allura-google-importer -
-
- Test Issue -
- Import Google Code projects to an Allura forge - Google Project Hosting
- </title>
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/core.css" />
-<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/ph_detail.css" />
-<!--[if IE]>
- <link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/3783617020303179221/css/d_ie.css" >
-<![endif]-->
-<style type="text/css">
- .menuIcon.off { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -42px }
- .menuIcon.on { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -28px }
- .menuIcon.down { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 0; }
-
-
- .attachments { width:33%; border-top:2px solid #999; padding-top: 3px; margin-left: .7em;}
- .attachments table { margin-bottom: 0.75em; }
- .attachments table tr td { padding: 0; margin: 0; font-size: 95%; }
- .preview { border: 2px solid #c3d9ff; padding: 1px; }
- .preview:hover { border: 2px solid blue; }
- .label { white-space: nowrap; }
- .derived { font-style:italic }
- .cursor_on .author {
- background: url(http://www.gstatic.com/codesite/ph/images/show-arrow.gif) no-repeat 2px;
- }
- .hiddenform {
- display: none;
- }
-
-
- </style>
-</head>
-<body class="t3">
-<script type="text/javascript">
- window.___gcfg = {lang: 'en'};
- (function()
- {var po = document.createElement("script");
- po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
- var s = document.getElementsByTagName("script")[0];
- s.parentNode.insertBefore(po, s);
- })();
-</script>
-<div class="headbg">
-<div id="gaia">
-<span>
-<a href="#" id="projects-dropdown" onclick="return false;"><u>My favorites</u> <small>&#9660;</small></a>
- | <a href="https://www.google.com/accounts/ServiceLogin?service=code&amp;ltmpl=phosting&amp;continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&amp;followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6" onclick="_CS_click('/gb/ph/signin');"><u>Sign in</u></a>
-</span>
-</div>
-<div class="gbh" style="left: 0pt;"></div>
-<div class="gbh" style="right: 0pt;"></div>
-<div style="height: 1px"></div>
-<!--[if lte IE 7]>
-<div style="text-align:center;">
-Your version of Internet Explorer is not supported. Try a browser that
-contributes to open source, such as <a href="http://www.firefox.com">Firefox</a>,
-<a href="http://www.google.com/chrome">Google Chrome</a>, or
-<a href="http://code.google.com/chrome/chromeframe/">Google Chrome Frame</a>.
-</div>
-<![endif]-->
-<table style="padding:0px; margin: 0px 0px 10px 0px; width:100%" cellpadding="0" cellspacing="0" itemscope="itemscope" itemtype="http://schema.org/CreativeWork">
-<tr style="height: 58px;">
-<td id="plogo">
-<link itemprop="url" href="/p/allura-google-importer" />
-<a href="/p/allura-google-importer/">
-<img src="/p/allura-google-importer/logo?cct=1374769571" alt="Logo" itemprop="image" />
-</a>
-</td>
-<td style="padding-left: 0.5em">
-<div id="pname">
-<a href="/p/allura-google-importer/"><span itemprop="name">allura-google-importer</span></a>
-</div>
-<div id="psum">
-<a id="project_summary_link" href="/p/allura-google-importer/"><span itemprop="description">Import Google Code projects to an Allura forge</span></a>
-</div>
-</td>
-<td style="white-space:nowrap;text-align:right; vertical-align:bottom;">
-<form action="/hosting/search">
-<input size="30" name="q" value="" type="text" />
-<input type="submit" name="projectsearch" value="Search projects" />
-</form>
-</td></tr>
-</table>
-</div>
-<div id="mt" class="gtb">
-<a href="/p/allura-google-importer/" class="tab ">Project&nbsp;Home</a>
-<a href="/p/allura-google-importer/wiki/TestPage?tm=6" class="tab ">Wiki</a>
-<a href="/p/allura-google-importer/issues/list" class="tab active">Issues</a>
-<a href="/p/allura-google-importer/source/checkout" class="tab ">Source</a>
-<div class="gtbc"></div>
-</div>
-<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0" class="st">
-<tr>
-<td class="subt">
-<div class="issueDetail">
-<div class="isf">
-<span class="inIssueEntry">
-<a class="buttonify" href="entry" onclick="return _newIssuePrompt();">New issue</a>
-</span> &nbsp;
-
- <span class="inIssueList">
-<span>Search</span>
-</span><form action="list" method="GET" style="display:inline">
-<select id="can" name="can">
-<option disabled="disabled">Search within:</option>
-<option value="1">&nbsp;All issues</option>
-<option value="2" selected="selected">&nbsp;Open issues</option>
-<option value="6">&nbsp;New issues</option>
-<option value="7">&nbsp;Issues to verify</option>
-</select>
-<span>for</span>
-<span id="qq"><input type="text" size="38" id="searchq" name="q" value="" autocomplete="off" onkeydown="_blurOnEsc(event)" /></span>
-<span id="search_colspec"><input type="hidden" name="colspec" value="ID Type Status Priority Milestone Owner Summary" /></span>
-<input type="hidden" name="cells" value="tiles" />
-<input type="submit" value="Search" />
-</form>
- &nbsp;
- <span class="inIssueAdvSearch">
-<a href="advsearch">Advanced search</a>
-</span> &nbsp;
- <span class="inIssueSearchTips">
-<a href="searchtips">Search tips</a>
-</span> &nbsp;
- <span class="inIssueSubscriptions">
-<a href="/p/allura-google-importer/issues/subscriptions">Subscriptions</a>
-</span>
-</div>
-</div>
-</td>
-<td align="right" valign="top" class="bevel-right"></td>
-</tr>
-</table>
-<script type="text/javascript">
- var cancelBubble = false;
- function _go(url) { document.location = url; }
-</script>
-<div id="maincol">
-<div id="color_control" class="">
-<div id="issueheader">
-<table cellpadding="0" cellspacing="0" width="100%"><tbody>
-<tr>
-<td class="vt h3" nowrap="nowrap" style="padding:0 5px">
-
-
- Issue <a href="detail?id=6">6</a>:
- </td>
-<td width="90%" class="vt">
-<span class="h3">Test &quot;Issue&quot;</span>
-</td>
-<td>
-<div class="pagination">
-<a href="../../allura-google-importer/issues/detail?id=5" title="Prev">&lsaquo; Prev</a>
- 6 of 6
-
- </div>
-</td>
-</tr>
-<tr>
-<td></td>
-<td nowrap="nowrap">
-
-
- 1 person starred this issue and may be notified of changes.
-
-
-
- </td>
-<td align="center" nowrap="nowrap">
-<a href="http://code.google.com/p/allura-google-importer/issues/list?cursor=allura-google-importer%3A6">Back to list</a>
-</td>
-</tr>
-</tbody></table>
-</div>
-<table width="100%" cellpadding="0" cellspacing="0" border="0" class="issuepage" id="meta-container">
-<tbody class="collapse">
-<tr>
-<td id="issuemeta">
-<div id="meta-float">
-<table cellspacing="0" cellpadding="0">
-<tr><th align="left">Status:&nbsp;</th>
-<td width="100%">
-<span title="Work on this issue has begun">Started</span>
-</td>
-</tr>
-<tr><th align="left">Owner:&nbsp;</th><td>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a>
-</td>
-</tr>
-<tr><td colspan="2">
-<div style="padding-top:2px">
-<a href="list?q=label:Type-Defect" title="Report of a software defect" class="label"><b>Type-</b>Defect</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Priority-Medium" title="Normal priority" class="label"><b>Priority-</b>Medium</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Milestone-Release1.0" title="All essential functionality working" class="label"><b>Milestone-</b>Release1.0</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-All" title="Affects all operating systems" class="label"><b>OpSys-</b>All</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Component-Logic" title="Issue relates to application logic" class="label"><b>Component-</b>Logic</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Performance" title="Performance issue" class="label">Performance</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:Security" title="Security risk to users" class="label">Security</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-Windows" title="Affects Windows users" class="label"><b>OpSys-</b>Windows</a>
-</div>
-<div style="padding-top:2px">
-<a href="list?q=label:OpSys-OSX" title="Affects Mac OS X users" class="label"><b>OpSys-</b>OSX</a>
-</div>
-</td></tr>
-</table>
-<div class="rel_issues">
-</div>
-<br /><br />
-<div style="white-space:nowrap"><a href="https://www.google.com/accounts/ServiceLogin?service=code&amp;ltmpl=phosting&amp;continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&amp;followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6">Sign in</a> to add a comment</div>
-</div>&nbsp;
- </td>
-<td class="vt issuedescription" width="100%" id="cursorarea">
-<div class="cursor_off vt issuedescription" id="hc0">
-<div class="author">
-<span class="role_label">Project Member</span>
- Reported by
-
-
- <a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a>,
- <span class="date" title="Thu Aug  8 15:33:52 2013">Today (3 minutes ago)</span>
-</div>
-<pre>
-Test *Issue* for testing
-
-  1. Test List
-  2. Item
-
-**Testing**
-
- * Test list 2
- * Item
-
-# Test Section
-
-    p = source.test_issue.post()
-    p.count = p.count *5 #* 6
-    if p.count &gt; 5:
-        print "Not &lt; 5 &amp; != 5"
-
-References: <a href="/p/allura-google-importer/issues/detail?id=1">issue 1</a>, <a href="/p/allura-google-importer/source/detail?r=2">r2</a>
-
-That's all
-
-
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000000&amp;name=at1.txt&amp;token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at1.txt</b>
-<br />
- 13 bytes
-
-
- &nbsp; <a href="../../allura-google-importer/issues/attachmentText?id=7&amp;aid=70000000&amp;name=at1.txt&amp;token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255" target="_blank">View</a>
-
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000000&amp;name=at1.txt&amp;token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255">Download</a>
-</td>
-</tr>
-</table>
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&amp;name=&amp;token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b></b>
-<br />
- 0 bytes
-
-
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=70000001&amp;name=&amp;token=C9Hn4s1-g38hlSggRGo65VZM1ys%3A1376059941255">Download</a>
-</td>
-</tr>
-</table>
-</div>
-</div>
-
-<div class="cursor_off vt issuecomment" id="hc1">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug  8 15:35:15 2013">
- Today (2 minutes ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c1" href="/p/allura-google-importer/issues/detail?id=6#c1">#1</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Test *comment* is a comment
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60001000&amp;name=&amp;token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at2.txt</b>
-<br />
- 13 bytes
-
-
- &nbsp; <a href="../../allura-google-importer/issues/attachmentText?id=6&amp;aid=60001000&amp;name=at2.txt&amp;token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667" target="_blank">View</a>
-
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60001000&amp;name=at2.txt&amp;token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667">Download</a>
-</td>
-</tr>
-</table>
-</div>
-<div class="updates">
-<div class="round4"></div>
-<div class="round2"></div>
-<div class="round1"></div>
-<div class="box-inner">
-<b>Status:</b>
- Started
-
- <br />
-<b>Labels:</b>
- -OpSys-Linux OpSys-Windows
-
- <br />
-</div>
-<div class="round1"></div>
-<div class="round2"></div>
-<div class="round4"></div>
-</div>
-</div>
-<div class="cursor_off vt issuecomment" id="hc2">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug  8 15:35:34 2013">
- Today (1 minute ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c2" href="/p/allura-google-importer/issues/detail?id=6#c2">#2</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Another comment with references: <a href="/p/allura-google-importer/issues/detail?id=2">issue 2</a>, <a href="/p/allura-google-importer/source/detail?r=1">r1</a>
-</pre>
-</div>
-<div class="cursor_off vt issuecomment" id="hc3">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug  8 15:36:39 2013">
- Today (moments ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c3" href="/p/allura-google-importer/issues/detail?id=6#c3">#3</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Last comment
-</pre>
-<div class="attachments">
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003000&amp;name=at4.txt&amp;token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at4.txt</b>
-<br />
- 13 bytes
-
-
- &nbsp; <a href="../../allura-google-importer/issues/attachmentText?id=6&amp;aid=60003000&amp;name=at4.txt&amp;token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667" target="_blank">View</a>
-
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003000&amp;name=at4.txt&amp;token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667">Download</a>
-</td>
-</tr>
-</table>
-<table cellspacing="3" cellpadding="2" border="0">
-<tr><td width="20">
-<a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003001&amp;name=at1.txt&amp;token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667">
-<img width="15" height="15" src="http://www.gstatic.com/codesite/ph/images/paperclip.gif" border="0" />
-</a>
-</td>
-<td style="min-width:16em" valign="top">
-<b>at1.txt</b>
-<br />
- 13 bytes
-
-
- &nbsp; <a href="../../allura-google-importer/issues/attachmentText?id=6&amp;aid=60003001&amp;name=at1.txt&amp;token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667" target="_blank">View</a>
-
- &nbsp; <a href="//allura-google-importer.googlecode.com/issues/attachment?aid=60003001&amp;name=at1.txt&amp;token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667">Download</a>
-</td>
-</tr>
-</table>
-</div>
-</div>
-<div class="cursor_off vt issuecomment" id="hc4">
-<div style="float:right; margin-right:.3em; text-align:right">
-<span class="date" title="Thu Aug  8 15:36:57 2013">
- Today (moments ago)
- </span>
-</div>
-<span class="author">
-<span class="role_label">Project Member</span>
-<a name="c4" href="/p/allura-google-importer/issues/detail?id=6#c4">#4</a>
-<a class="userlink" href="/u/101557263855536553789/">john...@gmail.com</a></span>
-<pre>
-Oh, I forgot one (with an inter-project reference to <a href="/p/other-project/issues/detail?id=1">issue other-project:1</a>)
-</pre>
-<div class="updates">
-<div class="round4"></div>
-<div class="round2"></div>
-<div class="round1"></div>
-<div class="box-inner">
-<b>Labels:</b>
- OpSys-OSX
-
- <br />
-</div>
-<div class="round1"></div>
-<div class="round2"></div>
-<div class="round4"></div>
-</div>
-</div>
-
-</td>
-</tr>
-<tr>
-<td></td>
-<td class="vt issuecomment">
-<span class="indicator">&#9658;</span> <a href="https://www.google.com/accounts/ServiceLogin?service=code&amp;ltmpl=phosting&amp;continue=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6&amp;followup=http%3A%2F%2Fcode.google.com%2Fp%2Fallura-google-importer%2Fissues%2Fdetail%3Fid%3D6">Sign in</a> to add a comment
- </td>
-</tr>
-</tbody>
-</table>
-<br />
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/dit_scripts.js"></script>
-</div>
-<form name="delcom" action="delComment.do?q=&amp;can=2&amp;groupby=&amp;sort=&amp;colspec=ID+Type+Status+Priority+Milestone+Owner+Summary" method="POST">
-<input type="hidden" name="sequence_num" value="" />
-<input type="hidden" name="mode" value="" />
-<input type="hidden" name="id" value="6" />
-<input type="hidden" name="token" value="" />
-</form>
-<div id="helparea"></div>
-<script type="text/javascript">
- _onload();
- function delComment(sequence_num, delete_mode) {
- var f = document.forms["delcom"];
- f.sequence_num.value = sequence_num;
- f.mode.value = delete_mode;
-
- f.submit();
- return false;
- }
-
- _floatMetadata();
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/kibbles.js"></script>
-<script type="text/javascript">
- _setupKibblesOnDetailPage(
- 'http://code.google.com/p/allura-google-importer/issues/list?cursor\x3dallura-google-importer%3A6',
- '/p/allura-google-importer/issues/entry',
- '../../allura-google-importer/issues/detail?id\x3d5',
- '',
- '', 'allura-google-importer', 6,
- false, false, codesite_token);
-</script>
-<script type="text/javascript" src="http://www.gstatic.com/codesite/ph/3783617020303179221/js/ph_core.js"></script>
-</div>
-<div id="footer" dir="ltr">
-<div class="text">
-<a href="/projecthosting/terms.html">Terms</a> -
- <a href="http://www.google.com/privacy.html">Privacy</a> -
- <a href="/p/support/">Project Hosting Help</a>
-</div>
-</div>
-<div class="hostedBy" style="margin-top: -20px;">
-<span style="vertical-align: top;">Powered by <a href="http://code.google.com/projecthosting/">Google Project Hosting</a></span>
-</div>
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/google/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/__init__.py b/ForgeImporters/forgeimporters/tests/google/__init__.py
deleted file mode 100644
index 144e298..0000000
--- a/ForgeImporters/forgeimporters/tests/google/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#       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.

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/google/functional/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/functional/__init__.py b/ForgeImporters/forgeimporters/tests/google/functional/__init__.py
deleted file mode 100644
index 144e298..0000000
--- a/ForgeImporters/forgeimporters/tests/google/functional/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#       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.

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
deleted file mode 100644
index 938d1c7..0000000
--- a/ForgeImporters/forgeimporters/tests/google/functional/test_tracker.py
+++ /dev/null
@@ -1,316 +0,0 @@
-#       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 pkg_resources
-from datetime import datetime
-
-from BeautifulSoup import BeautifulSoup
-import mock
-from pylons import tmpl_context as c
-from IPython.testing.decorators import module_not_available, skipif
-from datadiff.tools import assert_equal
-
-from alluratest.controller import setup_basic_test
-from allura.tests.decorators import without_module
-from allura import model as M
-from forgetracker import model as TM
-from forgeimporters import base
-from forgeimporters import google
-import forgeimporters.google.tracker
-
-
-class TestGCTrackerImporter(TestCase):
-
-    def _make_extractor(self, html):
-        with mock.patch.object(base.h, 'urlopen') as urlopen:
-            urlopen.return_value = ''
-            extractor = google.GoogleCodeProjectExtractor(
-                'allura-google-importer', 'project_info')
-        extractor.page = BeautifulSoup(html)
-        extractor.url = "http://test/issue/?id=1"
-        # iter_comments will make more get_page() calls but we don't want the real thing to run an mess up the .page
-        # and .url attributes, make it a no-op which works with these tests (since its just the same page being
-        # fetched really)
-        extractor.get_page = lambda *a, **kw: ''
-        return extractor
-
-    def _make_ticket(self, issue, issue_id=1):
-        self.assertIsNone(self.project.app_instance('test-issue'))
-        with mock.patch.object(base.h, 'urlopen') as urlopen,\
-                mock.patch.object(google.tracker, 'GoogleCodeProjectExtractor') as GPE,\
-                mock.patch.object(google.tracker.M, 'AuditLog') as AL,\
-                mock.patch('forgetracker.tasks.update_bin_counts') as ubc:
-            urlopen.side_effect = lambda req, **kw: mock.Mock(
-                read=req.get_full_url,
-                info=lambda: {'content-type': 'text/plain'})
-            GPE.iter_issues.return_value = [(issue_id, issue)]
-            gti = google.tracker.GoogleCodeTrackerImporter()
-            gti.import_tool(self.project, self.user,
-                            'test-issue-project', mount_point='test-issue')
-        c.app = self.project.app_instance('test-issue')
-        query = TM.Ticket.query.find({'app_config_id': c.app.config._id})
-        self.assertEqual(query.count(), 1)
-        ticket = query.all()[0]
-        return ticket
-
-    def setUp(self, *a, **kw):
-        super(TestGCTrackerImporter, self).setUp(*a, **kw)
-        setup_basic_test()
-        self.empty_issue = self._make_extractor(
-            open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/empty-issue.html')).read())
-        self.test_issue = self._make_extractor(
-            open(pkg_resources.resource_filename('forgeimporters', 'tests/data/google/test-issue.html')).read())
-        c.project = self.project = M.Project.query.get(shortname='test')
-        c.user = self.user = M.User.query.get(username='test-admin')
-
-    def test_empty_issue(self):
-        ticket = self._make_ticket(self.empty_issue)
-        self.assertEqual(ticket.summary, 'Empty Issue')
-        self.assertEqual(ticket.description,
-                         '*Originally created by:* john...@gmail.com\n\nEmpty')
-        self.assertEqual(ticket.status, '')
-        self.assertEqual(ticket.milestone, '')
-        self.assertEqual(ticket.custom_fields, {})
-        assert c.app.config.options.get('EnableVoting')
-        open_bin = TM.Bin.query.get(
-            summary='Open Tickets', app_config_id=c.app.config._id)
-        self.assertItemsEqual(open_bin.terms.split(' && '), [
-            '!status:Fixed',
-            '!status:Verified',
-            '!status:Invalid',
-            '!status:Duplicate',
-            '!status:WontFix',
-            '!status:Done',
-        ])
-        closed_bin = TM.Bin.query.get(
-            summary='Closed Tickets', app_config_id=c.app.config._id)
-        self.assertItemsEqual(closed_bin.terms.split(' or '), [
-            'status:Fixed',
-            'status:Verified',
-            'status:Invalid',
-            'status:Duplicate',
-            'status:WontFix',
-            'status:Done',
-        ])
-
-    @without_module('html2text')
-    def test_issue_basic_fields(self):
-        anon = M.User.anonymous()
-        ticket = self._make_ticket(self.test_issue)
-        self.assertEqual(ticket.reported_by, anon)
-        self.assertIsNone(ticket.assigned_to_id)
-        self.assertEqual(ticket.summary, 'Test "Issue"')
-        assert_equal(ticket.description,
-                     '*Originally created by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
-                     '*Originally owned by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
-                     '\n'
-                     'Test \\*Issue\\* for testing\n'
-                     '\n'
-                     '&nbsp; 1\\. Test List\n'
-                     '&nbsp; 2\\. Item\n'
-                     '\n'
-                     '\\*\\*Testing\\*\\*\n'
-                     '\n'
-                     ' \\* Test list 2\n'
-                     ' \\* Item\n'
-                     '\n'
-                     '\\# Test Section\n'
-                     '\n'
-                     '&nbsp;&nbsp;&nbsp; p = source\\.test\\_issue\\.post\\(\\)\n'
-                     '&nbsp;&nbsp;&nbsp; p\\.count = p\\.count \\*5 \\#\\* 6\n'
-                     '&nbsp;&nbsp;&nbsp; if p\\.count &gt; 5:\n'
-                     '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Not &lt; 5 &amp; \\!= 5"\n'
-                     '\n'
-                     'References: [issue 1](#1), [r2]\n'
-                     '\n'
-                     'That\'s all'
-                     )
-        self.assertEqual(ticket.status, 'Started')
-        self.assertEqual(ticket.created_date, datetime(2013, 8, 8, 15, 33, 52))
-        self.assertEqual(ticket.mod_date, datetime(2013, 8, 8, 15, 36, 57))
-        self.assertEqual(ticket.custom_fields, {
-            '_priority': 'Medium',
-            '_opsys': 'All, OSX, Windows',
-            '_component': 'Logic',
-            '_type': 'Defect',
-            '_milestone': 'Release1.0'
-        })
-        self.assertEqual(ticket.labels, ['Performance', 'Security'])
-        self.assertEqual(ticket.votes_up, 1)
-        self.assertEqual(ticket.votes, 1)
-
-    def test_import_id(self):
-        ticket = self._make_ticket(self.test_issue, issue_id=6)
-        self.assertEqual(ticket.app.config.options.import_id, {
-            'source': 'Google Code',
-            'project_name': 'test-issue-project',
-        })
-        self.assertEqual(ticket.ticket_num, 6)
-        self.assertEqual(ticket.import_id, {
-            'source': 'Google Code',
-            'project_name': 'test-issue-project',
-            'source_id': 6,
-        })
-
-    @skipif(module_not_available('html2text'))
-    def test_html2text_escaping(self):
-        ticket = self._make_ticket(self.test_issue)
-        assert_equal(ticket.description,
-                     '*Originally created by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
-                     '*Originally owned by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
-                     '\n'
-                     'Test \\*Issue\\* for testing\n'
-                     '\n'
-                     '&nbsp; 1. Test List\n'
-                     '&nbsp; 2. Item\n'
-                     '\n'
-                     '\\*\\*Testing\\*\\*\n'
-                     '\n'
-                     ' \\* Test list 2\n'
-                     ' \\* Item\n'
-                     '\n'
-                     '\\# Test Section\n'
-                     '\n'
-                     '&nbsp;&nbsp;&nbsp; p = source.test\\_issue.post\\(\\)\n'
-                     '&nbsp;&nbsp;&nbsp; p.count = p.count \\*5 \\#\\* 6\n'
-                     '&nbsp;&nbsp;&nbsp; if p.count &gt; 5:\n'
-                     '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Not &lt; 5 &amp; \\!= 5"\n'
-                     '\n'
-                     'References: [issue 1](#1), [r2]\n'
-                     '\n'
-                     'That\'s all'
-                     )
-
-    def _assert_attachments(self, actual, *expected):
-        self.assertEqual(len(actual), len(expected))
-        atts = set((a.filename, a.content_type, a.rfile().read())
-                   for a in actual)
-        self.assertEqual(atts, set(expected))
-
-    def test_attachments(self):
-        ticket = self._make_ticket(self.test_issue)
-        self._assert_attachments(ticket.attachments,
-                                 ('at1.txt', 'text/plain',
-                                  'http://allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255'),
-                                 )
-
-    @without_module('html2text')
-    def test_comments(self):
-        anon = M.User.anonymous()
-        ticket = self._make_ticket(self.test_issue)
-        actual_comments = ticket.discussion_thread.find_posts()
-        expected_comments = [
-            {
-                'timestamp': datetime(2013, 8, 8, 15, 35, 15),
-                'text': (
-                    '*Originally posted by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
-                    '\n'
-                    'Test \\*comment\\* is a comment\n'
-                    '\n'
-                    '**Labels:** -OpSys-Linux OpSys-Windows\n'
-                    '**Status:** Started'
-                ),
-                'attachments': [
-                    ('at2.txt', 'text/plain',
-                     'http://allura-google-importer.googlecode.com/issues/attachment?aid=60001000&name=at2.txt&token=JOSo4duwaN2FCKZrwYOQ-nx9r7U%3A1376001446667'),
-                ],
-            },
-            {
-                'timestamp': datetime(2013, 8, 8, 15, 35, 34),
-                'text': (
-                    '*Originally posted by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
-                    '\n'
-                    'Another comment with references: [issue 2](#2), [r1]\n\n'
-                ),
-            },
-            {
-                'timestamp': datetime(2013, 8, 8, 15, 36, 39),
-                'text': (
-                    '*Originally posted by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
-                    '\n'
-                    'Last comment\n\n'
-                ),
-                'attachments': [
-                    ('at4.txt', 'text/plain',
-                     'http://allura-google-importer.googlecode.com/issues/attachment?aid=60003000&name=at4.txt&token=6Ny2zYHmV6b82dqxyoiH6HUYoC4%3A1376001446667'),
-                    ('at1.txt', 'text/plain',
-                     'http://allura-google-importer.googlecode.com/issues/attachment?aid=60003001&name=at1.txt&token=NS8aMvWsKzTAPuY2kniJG5aLzPg%3A1376001446667'),
-                ],
-            },
-            {
-                'timestamp': datetime(2013, 8, 8, 15, 36, 57),
-                'text': (
-                    '*Originally posted by:* [john...@gmail.com](http://code.google.com/u/101557263855536553789/)\n'
-                    '\n'
-                    'Oh, I forgot one \\(with an inter\\-project reference to [issue other\\-project:1](https://code.google.com/p/other-project/issues/detail?id=1)\\)\n'
-                    '\n'
-                    '**Labels:** OpSys-OSX'
-                ),
-            },
-        ]
-        self.assertEqual(len(actual_comments), len(expected_comments))
-        for actual, expected in zip(actual_comments, expected_comments):
-            self.assertEqual(actual.author(), anon)
-            self.assertEqual(actual.timestamp, expected['timestamp'])
-            self.assertEqual(actual.text, expected['text'])
-            if 'attachments' in expected:
-                self._assert_attachments(
-                    actual.attachments, *expected['attachments'])
-
-    def test_globals(self):
-        globals = self._make_ticket(self.test_issue, issue_id=6).globals
-        self.assertEqual(globals.open_status_names, 'New Accepted Started')
-        self.assertEqual(globals.closed_status_names,
-                         'Fixed Verified Invalid Duplicate WontFix Done')
-        self.assertEqual(globals.last_ticket_num, 6)
-        self.assertItemsEqual(globals.custom_fields, [
-            {
-                'label': 'Milestone',
-                'name': '_milestone',
-                'type': 'milestone',
-                'options': '',
-                'milestones': [
-                    {'name': 'Release1.0', 'due_date':
-                     None, 'complete': False},
-                ],
-            },
-            {
-                'label': 'Type',
-                'name': '_type',
-                'type': 'select',
-                'options': 'Defect',
-            },
-            {
-                'label': 'Priority',
-                'name': '_priority',
-                'type': 'select',
-                'options': 'Medium',
-            },
-            {
-                'label': 'OpSys',
-                'name': '_opsys',
-                'type': 'string',
-                'options': '',
-            },
-            {
-                'label': 'Component',
-                'name': '_component',
-                'type': 'string',
-                'options': '',
-            },
-        ])


[07/50] allura git commit: [#8020] ticket:874 added tests for moderation

Posted by he...@apache.org.
[#8020] ticket:874 added tests for moderation


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

Branch: refs/heads/hs/8035
Commit: ba44f08fba273e5fcf28d515b31652c818fcc357
Parents: 0707694
Author: DeV1doR <de...@ukr.net>
Authored: Thu Dec 10 19:22:04 2015 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:03:18 2016 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py            |  4 +--
 Allura/allura/lib/widgets/discuss.py            |  2 +-
 Allura/allura/tests/functional/test_discuss.py  | 36 ++++++++++++++++++++
 .../tests/functional/test_forum.py              | 12 -------
 4 files changed, 39 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/ba44f08f/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 9812a98..89d4545 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -440,8 +440,8 @@ class ModerationController(BaseController):
         if flag:
             query['flags'] = {'$gte': int(flag)}
         if username:
-            filtered_user = User.query.get(username=username)
-            query['author_id'] = getattr(filtered_user, '_id', None)
+            filtered_user = User.by_username(username)
+            query['author_id'] = filtered_user._id if filtered_user else None
         q = self.PostModel.query.find(query)
         count = q.count()
         limit, page, start = g.handle_paging(limit, page or 0, default=50)

http://git-wip-us.apache.org/repos/asf/allura/blob/ba44f08f/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index 9d0955f..a8e475d 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -124,7 +124,7 @@ class PostFilter(ff.ForgeForm):
                         css_class='text',
                         if_missing=0),
             ew.InputField(name='username',
-                          label='Show post filtered by (username)'),
+                          label='Show post filtered by username'),
             ew.SubmitButton(label='Filter Posts')
         ])
     ]

http://git-wip-us.apache.org/repos/asf/allura/blob/ba44f08f/Allura/allura/tests/functional/test_discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index fb8a08b..d70664b 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -172,6 +172,42 @@ class TestDiscuss(TestDiscussBase):
         assert M.Post.query.find().count() == 1
         assert M.Post.query.find({'deleted': False}).count() == 0
 
+    def test_user_filter(self):
+        r = self._make_post('Test post')
+        post_link = str(
+            r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])
+        self.app.post(post_link + 'moderate', params=dict(spam='spam'))
+        post = M.Post.query.find().first()
+        post_username = post.author().username
+        moderate_link = '/p/test/wiki/_discuss/moderate'
+
+        # no filter
+        r_no_filtered = self.app.get(
+            moderate_link,
+            params=dict(
+                status=post.status
+            ))
+        assert r_no_filtered.html.tbody.findAll('tr') != []
+
+        # filter with existing user
+        r_filtered = self.app.get(
+            moderate_link,
+            params=dict(
+                username=post_username,
+                status=post.status
+            ))
+        assert r_filtered.html.tbody.findAll('tr') != []
+        assert post_username in r_filtered.html.tbody.findAll('td')[-5].string
+
+        # filter without existing user
+        r_bad_filtered = self.app.get(
+            moderate_link,
+            params=dict(
+                username='bad_filtered_user',
+                status=post.status
+            ))
+        assert r_bad_filtered.html.tbody.findAll('tr') == []
+
     @patch.object(M.Thread, 'is_spam')
     def test_feed_does_not_include_comments_held_for_moderation(self, is_spam):
         is_spam.return_value = True

http://git-wip-us.apache.org/repos/asf/allura/blob/ba44f08f/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index 0fafe71..566db32 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -415,18 +415,6 @@ class TestForum(TestController):
         input_field = r.html.fieldset.find('input', {'value': username})
         assert input_field is not None
 
-        username = 341
-        r = self.app.get(
-            '/discussion/testforum/moderate?username=%s' % username)
-        input_field = r.html.fieldset.find('input', {'value': username})
-        assert input_field is not None
-
-        username = 123.43523
-        r = self.app.get(
-            '/discussion/testforum/moderate?username=%s' % username)
-        input_field = r.html.fieldset.find('input', {'value': username})
-        assert input_field is not None
-
         username = None
         r = self.app.get(
             '/discussion/testforum/moderate?username=%s' % username)


[21/50] allura git commit: [#8054] edit few files for Google Code importer removal

Posted by he...@apache.org.
[#8054] edit few files for Google Code importer removal


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

Branch: refs/heads/hs/8035
Commit: d4dda57713baa3525ef6efb089688a1597a4c78f
Parents: b956fe3
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Jan 26 13:59:03 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 13:42:50 2016 -0500

----------------------------------------------------------------------
 Allura/development.ini                | 6 +++---
 Allura/docs/development/extending.rst | 6 +++---
 ForgeImporters/setup.py               | 3 ---
 rat-excludes.txt                      | 4 ----
 4 files changed, 6 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/d4dda577/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 930f7f3..e890cd7 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -357,8 +357,8 @@ importer_upload_path = /tmp/importer_upload/{nbhd}/{project}
 ; To disable any plugin, tool, importer, etc from being available, you can use the disable_entry_points config option.
 ; Specify the keys and values as they are declared in the tool's "setup.py" file.
 ; Examples:
-;disable_entry_points.importers = google-code-tracker, google-code-repo
-;disable_entry_points.allura.project_importers = google-code
+;disable_entry_points.allura.importers = github-tracker, github-wiki, github-repo
+;disable_entry_points.allura.project_importers = github
 
 ; Importers specifically, can be left enabled but not linked to.  You have to know the URL to use it.  Example:
 ;hidden_importers = trac-tickets
@@ -371,7 +371,7 @@ importer_upload_path = /tmp/importer_upload/{nbhd}/{project}
 
 ; If your site has docs about specific importers, you can add them here and
 ; they'll appear on the import forms
-;doc.url.importers.Google Code = http://...
+;doc.url.importers.GitHub = http://...
 
 ; List of oauth API keys permitted to use special forum import API
 ; (should be converted to newer importer system)

http://git-wip-us.apache.org/repos/asf/allura/blob/d4dda577/Allura/docs/development/extending.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/development/extending.rst b/Allura/docs/development/extending.rst
index e45b1c2..3132838 100644
--- a/Allura/docs/development/extending.rst
+++ b/Allura/docs/development/extending.rst
@@ -50,12 +50,12 @@ A listing of available 3rd-party extensions is at https://forge-allura.apache.or
 
 To disable any Allura entry point, simply add an entry in your ``.ini`` config file
 with names and values corresponding to entry points defined in any ``setup.py`` file.
-For example if you have ForgeImporter set up, but want to disable the google code importers:
+For example if you have ForgeImporter set up, but want to disable the GitHub importers:
 
 .. code-block:: ini
 
-    disable_entry_points.allura.project_importers = google-code
-    disable_entry_points.allura.importers = google-code-tracker, google-code-repo
+    disable_entry_points.allura.project_importers = github
+    disable_entry_points.allura.importers = github-tracker, github-wiki, github-repo
 
 Other entry points are used to provide ``paster`` commands and ``easy_widget`` configuration,
 which are not part of Allura but are used by Allura.

http://git-wip-us.apache.org/repos/asf/allura/blob/d4dda577/ForgeImporters/setup.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/setup.py b/ForgeImporters/setup.py
index 4d5f866..2ad2726 100644
--- a/ForgeImporters/setup.py
+++ b/ForgeImporters/setup.py
@@ -34,14 +34,11 @@ setup(name='ForgeImporters',
       entry_points="""
       # -*- Entry points: -*-
       [allura.project_importers]
-      google-code = forgeimporters.google.project:GoogleCodeProjectImporter
       trac = forgeimporters.trac.project:TracProjectImporter
       github = forgeimporters.github.project:GitHubProjectImporter
 
       [allura.importers]
       github-tracker = forgeimporters.github.tracker:GitHubTrackerImporter
-      google-code-tracker = forgeimporters.google.tracker:GoogleCodeTrackerImporter
-      google-code-repo = forgeimporters.google.code:GoogleRepoImporter
       github-wiki = forgeimporters.github.wiki:GitHubWikiImporter
       github-repo = forgeimporters.github.code:GitHubRepoImporter
       trac-tickets = forgeimporters.trac.tickets:TracTicketImporter

http://git-wip-us.apache.org/repos/asf/allura/blob/d4dda577/rat-excludes.txt
----------------------------------------------------------------------
diff --git a/rat-excludes.txt b/rat-excludes.txt
index 2771188..2e0d026 100644
--- a/rat-excludes.txt
+++ b/rat-excludes.txt
@@ -58,10 +58,6 @@ CHANGES
 ForgeGit/forgegit/data/post-receive_tmpl
 ForgeImporters/docs/make.bat
 ForgeImporters/docs/Makefile
-ForgeImporters/forgeimporters/tests/data/google/empty-issue.html
-ForgeImporters/forgeimporters/tests/data/google/test-issue-first-page.html
-ForgeImporters/forgeimporters/tests/data/google/test-issue-prev-page.html
-ForgeImporters/forgeimporters/tests/data/google/test-issue.html
 ForgeImporters/forgeimporters/trac/tests/data/test-list.csv
 ForgeImporters/forgeimporters/trac/tests/data/test-list.html
 ForgeSVN/forgesvn/tests/data/


[37/50] allura git commit: [#8035] ESLINT FIX: no-unused-var

Posted by he...@apache.org.
[#8035] ESLINT FIX: no-unused-var


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

Branch: refs/heads/hs/8035
Commit: 085fbb7f040a85fcc698ab4831b4b5db2be7567a
Parents: 8a131ab
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 18:43:29 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:30 2016 -0500

----------------------------------------------------------------------
 Allura/allura/public/nf/js/context-menu.es6.js | 2 ++
 Allura/allura/public/nf/js/navbar.es6.js       | 7 +++++--
 Allura/allura/public/nf/js/tooltip.es6.js      | 2 ++
 3 files changed, 9 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/085fbb7f/Allura/allura/public/nf/js/context-menu.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/context-menu.es6.js b/Allura/allura/public/nf/js/context-menu.es6.js
index ec5b68d..1762ffb 100644
--- a/Allura/allura/public/nf/js/context-menu.es6.js
+++ b/Allura/allura/public/nf/js/context-menu.es6.js
@@ -78,3 +78,5 @@ class ContextMenu extends React.Component {
         );
     }
 }
+
+module.exports(ContextMenu);

http://git-wip-us.apache.org/repos/asf/allura/blob/085fbb7f/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index 585d004..2d0201e 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -17,6 +17,7 @@
        under the License.
 */
 /* eslint camelcase: 0 */
+/* exported Main */
 'use strict';
 
 /**
@@ -109,7 +110,7 @@ var NavBarItem = React.createClass({
         );
     },
 
-    handleOptionClick: function(event) {
+    handleOptionClick: function() {
         this.props.onOptionClick(this.props.mount_point);
     }
 });
@@ -244,7 +245,7 @@ var NormalNavBar = React.createClass({
         ).isRequired
     },
 
-    buildMenu: function(item, i) {
+    buildMenu: function(item) {
         let classes = window.location.pathname.startsWith(item.url) ? 'active-nav-link' : '';
 
         var subMenu;
@@ -588,3 +589,5 @@ var Main = React.createClass({
         );
     }
 });
+
+module.exports(Main);

http://git-wip-us.apache.org/repos/asf/allura/blob/085fbb7f/Allura/allura/public/nf/js/tooltip.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/tooltip.es6.js b/Allura/allura/public/nf/js/tooltip.es6.js
index 95f7188..f24fc16 100644
--- a/Allura/allura/public/nf/js/tooltip.es6.js
+++ b/Allura/allura/public/nf/js/tooltip.es6.js
@@ -75,3 +75,5 @@ class ToolTip extends React.Component {
     }
 }
 
+module.exports(ToolTip);
+


[13/50] allura git commit: [#8044] remove unnecessary c.app check, since the c.app.config usage is moved out of this function now

Posted by he...@apache.org.
[#8044] remove unnecessary c.app check, since the c.app.config usage is moved out of this function now


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

Branch: refs/heads/hs/8035
Commit: 5adc337eb4fffd14f8c6a7f33c4bf4840d67f8b2
Parents: 1ec256c
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Jan 27 12:37:09 2016 -0500
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:37:38 2016 -0500

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


http://git-wip-us.apache.org/repos/asf/allura/blob/5adc337e/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index e76c53c..1c65a10 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -1324,7 +1324,7 @@ class ThemeProvider(object):
 
         if note.page_regex and re.search(note.page_regex, url) is None:
             return None
-        if note.page_tool_type and (c.app is None or tool_name.lower() != note.page_tool_type.lower()):
+        if note.page_tool_type and tool_name.lower() != note.page_tool_type.lower():
             return None
 
         cookie = site_notification_cookie_value.split('-')


[34/50] allura git commit: [#8035] ESLINT FIX: semi

Posted by he...@apache.org.
[#8035] ESLINT FIX: semi


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

Branch: refs/heads/hs/8035
Commit: 0ce56fc9bc5999f29f7639233fee4159445dd6f4
Parents: 03f750c
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 18:16:58 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:29 2016 -0500

----------------------------------------------------------------------
 Allura/allura/public/nf/js/context-menu.es6.js | 4 ++--
 Allura/allura/public/nf/js/navbar.es6.js       | 4 ++--
 Allura/allura/public/nf/js/tooltip.es6.js      | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/0ce56fc9/Allura/allura/public/nf/js/context-menu.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/context-menu.es6.js b/Allura/allura/public/nf/js/context-menu.es6.js
index 96ab2e1..710387d 100644
--- a/Allura/allura/public/nf/js/context-menu.es6.js
+++ b/Allura/allura/public/nf/js/context-menu.es6.js
@@ -72,10 +72,10 @@ class ContextMenu extends React.Component {
                             <a href={o.href}
                                className={_this.props.classes.concat([o.className]).join(' ')}
                                title={o.tooltip}>{o.text}</a>
-                        </li>)
+                        </li>);
                     })}
                 </ul>
             </div>
-        )
+        );
     }
 }

http://git-wip-us.apache.org/repos/asf/allura/blob/0ce56fc9/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index 4570872..0ea3cb5 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -223,7 +223,7 @@ var ToggleAddNewTool = React.createClass({
                     items={this.props.installableTools} />
                 }
             </div>
-        )
+        );
     }
 });
 
@@ -563,7 +563,7 @@ var Main = React.createClass({
 
         var max_tool_count = _.chain(this.state.data.menu)
                              .map((item) => {
-                                 return item.children ? _.pluck(item.children, 'tool_name') : item.tool_name
+                                 return item.children ? _.pluck(item.children, 'tool_name') : item.tool_name;
                              })
                              .flatten()
                              .countBy()

http://git-wip-us.apache.org/repos/asf/allura/blob/0ce56fc9/Allura/allura/public/nf/js/tooltip.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/tooltip.es6.js b/Allura/allura/public/nf/js/tooltip.es6.js
index fea6471..87a865d 100644
--- a/Allura/allura/public/nf/js/tooltip.es6.js
+++ b/Allura/allura/public/nf/js/tooltip.es6.js
@@ -68,7 +68,7 @@ class ToolTip extends React.Component {
             multiple: _this.props.multiple,
             iconCloning: false,
             maxWidth: _this.props.maxWidth
-        })
+        });
     }
 
     render() {


[33/50] allura git commit: [#8035] ESLINT FIX: operator-linebreak

Posted by he...@apache.org.
[#8035] ESLINT FIX: operator-linebreak


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

Branch: refs/heads/hs/8035
Commit: c2e894cf1576b26ae4bd93b8bf759ab68139958c
Parents: 5e861de
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 18:33:22 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:29 2016 -0500

----------------------------------------------------------------------
 .eslintrc                                |  3 ++-
 Allura/allura/public/nf/js/navbar.es6.js | 12 ++++++------
 2 files changed, 8 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c2e894cf/.eslintrc
----------------------------------------------------------------------
diff --git a/.eslintrc b/.eslintrc
index b42eb66..ff25e9d 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -3,7 +3,8 @@
     "max-len": [1, 119, 4],
     "indent": [2, 4],
     "jsx-quotes": [0],
-    "quotes": [0]
+    "quotes": [0],
+    "operator-linebreak": [2, "before", { "overrides": { "?": "after", "&&": "after" } }]
   },
   "globals": {
     "ReactDOM": true,

http://git-wip-us.apache.org/repos/asf/allura/blob/c2e894cf/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index 1055d43..818bb3e 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -98,13 +98,13 @@ var NavBarItem = React.createClass({
                         {this.props.name}
                     </span>
                 </a>
-                {this.props.currentOptionMenu.tool
-                && this.props.currentOptionMenu.tool === this.props.mount_point
-                && <ContextMenu
+                {this.props.currentOptionMenu.tool &&
+                this.props.currentOptionMenu.tool === this.props.mount_point &&
+                <ContextMenu
                     {...this.props}
-                        items={this.props.options}
-                        onOptionClick={this.props.onOptionClick}
-                    /> }
+                    items={this.props.options}
+                    onOptionClick={this.props.onOptionClick}
+                /> }
             </div>
         );
     },


[43/50] allura git commit: [#8035] ESLINT FIX: arrow-parens

Posted by he...@apache.org.
[#8035] ESLINT FIX: arrow-parens


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

Branch: refs/heads/hs/8035
Commit: c29d9e21cbca1e1f9c786fc4febc9ad5880828ed
Parents: 2fa2ce3
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 19:47:24 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:31 2016 -0500

----------------------------------------------------------------------
 Allura/allura/public/nf/js/navbar.es6.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c29d9e21/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index 52493bc..44e2caf 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -530,7 +530,7 @@ var Main = React.createClass({
 
     render: function() {
         var _this = this;
-        var navBarSwitch = (showAdmin) => {
+        var navBarSwitch = showAdmin => {
             if (showAdmin) {
                 return (
                     <AdminNav


[47/50] allura git commit: [#8035] Add jsx/react rules for eslint

Posted by he...@apache.org.
[#8035] Add jsx/react rules for eslint


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

Branch: refs/heads/hs/8035
Commit: 53baa3ab7c0e2dd39b1cdb5720e21bd4a1244ce6
Parents: 03f02e7
Author: Heith Seewald <he...@gmail.com>
Authored: Tue Jan 26 15:13:28 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:33 2016 -0500

----------------------------------------------------------------------
 .eslintrc-es6                            |   9 +-
 Allura/allura/public/nf/js/navbar.es6.js | 183 +++++++++++++++-----------
 package.json                             |   5 +-
 3 files changed, 113 insertions(+), 84 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/53baa3ab/.eslintrc-es6
----------------------------------------------------------------------
diff --git a/.eslintrc-es6 b/.eslintrc-es6
index 4427a53..9079414 100644
--- a/.eslintrc-es6
+++ b/.eslintrc-es6
@@ -17,11 +17,16 @@
       "args": "none"
     }],
     "no-inline-comments": 0,
-    "comma-dangle": 0
+    "comma-dangle": 0,
+    "vars-on-top": 2,
+    "react/jsx-indent-props": 0,
+   "react/jsx-curly-spacing": [2, "never"],
+   "react/jsx-closing-bracket-location": 0
   },
   "globals": {
     "ReactDOM": true,
     "React": true,
+    "ToolTip": true,
     "$": true,
     "window": true,
     "_": true,
@@ -33,7 +38,7 @@
     "browser": true,
     "node": false
   },
-  "extends": "xo/browser",
+  "extends":  ["xo/browser", "xo-react"],
   "ecmaFeatures": {
     "jsx": true,
     "modules": false,

http://git-wip-us.apache.org/repos/asf/allura/blob/53baa3ab/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index d52ccec..5c76e19 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -17,6 +17,7 @@
        under the License.
 */
 /* eslint camelcase: 0 */
+/* globals ContextMenu ToolTip */
 'use strict';
 
 /**
@@ -30,7 +31,7 @@ var _getProjectUrl = function(rest = true) {
     var nbhd_proj;
     var identClasses = document.getElementById('page-body').className.split(' ');
     var basePath = rest ? '/rest/' : '/';
-    for (var cls of identClasses) {
+    for (let cls of identClasses) {
         if (cls.indexOf('project-') === 0) {
             proj = cls.slice('project-'.length);
         }
@@ -65,45 +66,48 @@ var NavBarItem = React.createClass({
         name: React.PropTypes.string.isRequired,
         url: React.PropTypes.string.isRequired,
         currentOptionMenu: React.PropTypes.object,
+        isGrouper: React.PropTypes.bool,
+        mount_point: React.PropTypes.string,
         onOptionClick: React.PropTypes.func.isRequired,
         options: React.PropTypes.array,
+        handleType: React.PropTypes.string,
         is_anchored: React.PropTypes.bool
     },
 
     render: function() {
         var divClasses = "tb-item tb-item-edit";
+        var spanClasses = this.props.handleType + " ordinal-item";
+
         if (this.props.is_anchored) {
             divClasses += " anchored";
         }
-        var spanClasses = this.props.handleType + " ordinal-item";
         if (this.props.isGrouper) {
             spanClasses += " toolbar-grouper";
         }
 
         return (
-            <div className={ divClasses }>
-                <ToolTip targetSelector=".anchored .draggable-handle" position="top"
-                         theme="tooltipster-default" delay={250}/>
-                <ToolTip targetSelector=".anchored .draggable-handle-sub" position="right"
-                         theme="tooltipster-default" delay={250}/>
+            <div className={divClasses}>
+                <ToolTip targetSelector=".anchored .draggable-handle"
+                         position="top"
+                         theme="tooltipster-default"
+                         delay={250}/>
+                <ToolTip targetSelector=".anchored .draggable-handle-sub"
+                         position="right"
+                         theme="tooltipster-default"
+                         delay={250}/>
                 <a>
-                    {!_.isEmpty(this.props.options) && <i className='config-tool fa fa-cog'
-                                                          onClick={this.handleOptionClick}> </i>}
+                    {!_.isEmpty(this.props.options) &&
+                    <i className='config-tool fa fa-cog' onClick={this.handleOptionClick}> </i>}
                     <span
                         className={spanClasses}
                         data-mount-point={this.props.mount_point}
-                        title={this.props.is_anchored ? 'This item cannot be moved.' : ''}
-                        >
+                        title={this.props.is_anchored ? 'This item cannot be moved.' : ''}>
                         {this.props.name}
                     </span>
                 </a>
                 {this.props.currentOptionMenu.tool &&
                 this.props.currentOptionMenu.tool === this.props.mount_point &&
-                <ContextMenu
-                    {...this.props}
-                    items={this.props.options}
-                    onOptionClick={this.props.onOptionClick}
-                /> }
+                <ContextMenu {...this.props} items={this.props.options} onOptionClick={this.props.onOptionClick}/>}
             </div>
         );
     },
@@ -120,7 +124,9 @@ var NavBarItem = React.createClass({
  */
 var GroupingThreshold = React.createClass({
     propTypes: {
-        initialValue: React.PropTypes.number.isRequired
+        initialValue: React.PropTypes.number.isRequired,
+        isHidden: React.PropTypes.bool,
+        onUpdateThreshold: React.PropTypes.func
     },
     getInitialState: function() {
         return {
@@ -138,22 +144,21 @@ var GroupingThreshold = React.createClass({
     render: function() {
         return (
             <div>
-                { !Boolean(!this.props.isHidden) &&
+                {!Boolean(!this.props.isHidden) &&
                 <div id='threshold-config'>
             <span>
               <label htmlFor='threshold-input'>Grouping Threshold</label>
-                <ToolTip targetSelector="#threshold-input" position="top" contentAsHTML={true}/>
+                <ToolTip targetSelector="#threshold-input" position="top" contentAsHTML/>
                 <input type='number' name='threshold-input' id="threshold-input"
-
                        title='When you have multiple tools of the same type,\
                              <u>this number</u> determines if they will fit in the navigation \
                              bar or be grouped into a dropdown.'
-
-                       value={ this.state.value }
-                       onChange={ this.handleChange }
-                       min='1' max='50'/>
+                       value={this.state.value}
+                       onChange={this.handleChange}
+                       min='1' max='50'
+                />
               </span>
-                </div> }
+                </div>}
             </div>
         );
     }
@@ -168,14 +173,15 @@ var NormalNavItem = React.createClass({
     propTypes: {
         name: React.PropTypes.string.isRequired,
         url: React.PropTypes.string.isRequired,
+        children: React.PropTypes.object,
         classes: React.PropTypes.string
     },
     mixins: [React.addons.PureRenderMixin],
     render: function() {
         return (
             <li key={`tb-norm-${_.uniqueId()}`}>
-                <a href={ this.props.url } className={ this.props.classes }>
-                    { this.props.name }
+                <a href={this.props.url} className={this.props.classes}>
+                    {this.props.name}
                 </a>
                 {this.props.children}
             </li>
@@ -211,15 +217,16 @@ var ToggleAddNewTool = React.createClass({
     render: function() {
         return (
             <div>
-                <a onClick={ this.handleToggle } className="add-tool-toggle">
+                <a onClick={this.handleToggle} className="add-tool-toggle">
                     Add New...
                 </a>
                 {this.state.visible &&
-                <ContextMenu
-                    {...this.props}
-                    classes={['admin_modal']}
-                    onOptionClick={this.handleToggle}
-                    items={this.props.installableTools} />
+                    <ContextMenu
+                        {...this.props}
+                        classes={['admin_modal']}
+                        onOptionClick={this.handleToggle}
+                        items={this.props.installableTools}
+                    />
                 }
             </div>
         );
@@ -265,7 +272,7 @@ var NormalNavBar = React.createClass({
             <ul
                 id="normal-nav-bar"
                 className="dropdown">
-                { listItems }
+                {listItems}
                 <li id="add-tool-container">
                     <ToggleAddNewTool installableTools={this.props.installableTools}/>
                 </li>
@@ -282,6 +289,13 @@ var AdminNav = React.createClass({
     propTypes: {
         tools: React.PropTypes.arrayOf(ToolsPropType),
         currentOptionMenu: React.PropTypes.object,
+        installableTools: React.PropTypes.arrayOf(
+            React.PropTypes.shape({
+                text: React.PropTypes.string.isRequired,
+                href: React.PropTypes.string,
+                tooltip: React.PropTypes.string
+            })
+        ),
         onOptionClick: React.PropTypes.func.isRequired
     },
 
@@ -291,6 +305,8 @@ var AdminNav = React.createClass({
         var subMenu;
         var childOptionsOpen;
         var _handle;
+        var toolList;
+        var isAnchored;
         for (let item of items) {
             if (item.children) {
                 subMenu = this.buildMenu(item.children, true);
@@ -299,8 +315,6 @@ var AdminNav = React.createClass({
             }
 
             _handle = isSubMenu ? "draggable-handle-sub" : 'draggable-handle';
-            var toolList;
-            var isAnchored;
             if (item.mount_point === 'admin') {
                 // force admin to end, just like 'Project.sitemap()' does
                 toolList = endTools;
@@ -312,17 +326,17 @@ var AdminNav = React.createClass({
                 toolList = tools;
                 isAnchored = false;
             }
-            var coreItem = <NavBarItem
+            let coreItem = (<NavBarItem
                 {..._this.props}
-                mount_point={ item.mount_point }
-                name={ item.name }
+                mount_point={item.mount_point}
+                name={item.name}
                 handleType={_handle}
                 isGrouper={item.children && item.children.length > 0}
-                url={ item.url }
-                key={ 'tb-item-' + _.uniqueId() }
-                is_anchored={ isAnchored }
-                options={ item.admin_options }
-            />;
+                url={item.url}
+                key={'tb-item-' + _.uniqueId()}
+                is_anchored={isAnchored}
+                options={item.admin_options}
+            />);
             if (subMenu) {
                 childOptionsOpen = _.contains(_.pluck(item.children, 'mount_point'),
                     this.props.currentOptionMenu.tool);
@@ -340,17 +354,17 @@ var AdminNav = React.createClass({
 
         return (
             <div className='react-drag'>
-                { anchoredTools }
+                {anchoredTools}
                 <ReactReorderable
-                    key={ 'reorder-' + _.uniqueId() }
+                    key={'reorder-' + _.uniqueId()}
                     handle={"." + _handle}
-                    mode={ isSubMenu ? 'list' : 'grid' }
-                    onDragStart={ _this.props.onToolDragStart }
-                    onDrop={ _this.props.onToolReorder }>
-                    { tools }
+                    mode={isSubMenu ? 'list' : 'grid'}
+                    onDragStart={_this.props.onToolDragStart}
+                    onDrop={_this.props.onToolReorder}>
+                    {tools}
                 </ReactReorderable>
-                { endTools }
-                { !isSubMenu && <div id="add-tool-container" className="unlocked-container">
+                {endTools}
+                {!isSubMenu && <div id="add-tool-container" className="unlocked-container">
                     <ToggleAddNewTool installableTools={this.props.installableTools}/>
                 </div>}
             </div>
@@ -364,10 +378,15 @@ var AdminNav = React.createClass({
 });
 
 var NavBarItemWithSubMenu = React.createClass({
+    propTypes: {
+        subMenu: React.PropTypes.arrayOf(ToolsPropType),
+        childOptionsOpen: React.PropTypes.string,
+        tool: React.PropTypes.objectOf(ToolsPropType)
+    },
     render: function() {
         return (
             <div className={"tb-item-container" + (this.props.childOptionsOpen ? " child-options-open" : "")}>
-                { this.props.tool }
+                {this.props.tool}
                 {this.props.subMenu &&
                 <AdminItemGroup key={_.uniqueId()}>
                     {this.props.subMenu}
@@ -383,6 +402,9 @@ var NavBarItemWithSubMenu = React.createClass({
  * @constructor
  */
 var AdminItemGroup = React.createClass({
+    propTypes: {
+        children: React.PropTypes.object
+    },
     render: function() {
         return (
             <div className="tb-item-grouper">
@@ -399,13 +421,14 @@ var AdminItemGroup = React.createClass({
  */
 var ToggleAdminButton = React.createClass({
     propTypes: {
+        handleButtonPush: React.PropTypes.func,
         visible: React.PropTypes.bool
     },
     render: function() {
         var classes = this.props.visible ? 'fa fa-unlock' : 'fa fa-lock';
         return (
-            <button id='toggle-admin-btn' onClick={ this.props.handleButtonPush } className='admin-toolbar-right'>
-                <i className={ classes }> </i>
+            <button id='toggle-admin-btn' onClick={this.props.handleButtonPush} className='admin-toolbar-right'>
+                <i className={classes}> </i>
             </button>
         );
     }
@@ -488,14 +511,14 @@ var Main = React.createClass({
     onToolReorder: function() {
         $('.react-drag.dragging').removeClass('dragging');
 
-        var params = {_session_id: $.cookie('_session_id')};
-        var toolNodes = $(ReactDOM.findDOMNode(this)).find('span.ordinal-item').not(".toolbar-grouper");
-        for (var i = 0; i < toolNodes.length; i++) {
+        let params = {_session_id: $.cookie('_session_id')};
+        let toolNodes = $(ReactDOM.findDOMNode(this)).find('span.ordinal-item').not(".toolbar-grouper");
+        for (let i = 0; i < toolNodes.length; i++) {
             params[i] = toolNodes[i].dataset.mountPoint;
         }
 
-        var _this = this;
-        var url = _getProjectUrl() + '/admin/mount_order';
+        let _this = this;
+        let url = _getProjectUrl() + '/admin/mount_order';
         $.ajax({
             type: 'POST',
             url: url,
@@ -532,24 +555,24 @@ var Main = React.createClass({
         var navBarSwitch = showAdmin => {
             var navbar;
             if (showAdmin) {
-                navbar = <AdminNav
-                    tools={ _this.state.data.menu }
-                    installableTools={ _this.state.data.installable_tools }
-                    data={ _this.state.data }
-                    onToolReorder={ _this.onToolReorder }
-                    onToolDragStart={ _this.onToolDragStart }
-                    editMode={ _this.state.visible }
-                    currentOptionMenu={ _this.state.currentOptionMenu }
-                    onOptionClick={ _this.handleShowOptionMenu }
+                navbar = (<AdminNav
+                    tools={_this.state.data.menu}
+                    installableTools={_this.state.data.installable_tools}
+                    data={_this.state.data}
+                    onToolReorder={_this.onToolReorder}
+                    onToolDragStart={_this.onToolDragStart}
+                    editMode={_this.state.visible}
+                    currentOptionMenu={_this.state.currentOptionMenu}
+                    onOptionClick={_this.handleShowOptionMenu}
                     currentToolOptions={this.state.currentToolOptions}
-                />;
+                />);
             } else {
-                navbar = <div>
+                navbar = (<div>
                     <NormalNavBar
-                        items={ _this.state.data.menu }
-                        installableTools={ _this.state.data.installable_tools }
+                        items={_this.state.data.menu}
+                        installableTools={_this.state.data.installable_tools}
                     />
-                </div>;
+                </div>);
             }
             return navbar;
         };
@@ -568,17 +591,17 @@ var Main = React.createClass({
 
         return (
             <div>
-                { navBar }
+                {navBar}
                 <div id='bar-config'>
                     {show_grouping_threshold &&
                     <GroupingThreshold
-                        onUpdateThreshold={ this.onUpdateThreshold }
-                        isHidden={ this.state.visible }
-                        initialValue={ parseInt(this.state.data.grouping_threshold, 10) }/> }
+                        onUpdateThreshold={this.onUpdateThreshold}
+                        isHidden={this.state.visible}
+                        initialValue={parseInt(this.state.data.grouping_threshold, 10)}/>}
                 </div>
                 <ToggleAdminButton
-                    handleButtonPush={ this.handleToggleAdmin }
-                    visible={ this.state.visible }/>
+                    handleButtonPush={this.handleToggleAdmin}
+                    visible={this.state.visible}/>
             </div>
         );
     }

http://git-wip-us.apache.org/repos/asf/allura/blob/53baa3ab/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 8b238b0..a0e9ec3 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,7 @@
     "eslint": "eslint",
     "lint-es5": "eslint -c .eslintrc-es5  --ignore-path .eslintignore-es5 Allura/allura/public/**/*.js || true",
     "lint-es6": "eslint -c .eslintrc-es6  --ignore-path .eslintignore-es6 Allura/allura/public/**/*.es6.js || true",
-    "lint": "npm run lint-es5 && npm run lint-es6"
+    "lint": "npm run lint5 && npm run lint6"
   },
   "repository": {
     "type": "git",
@@ -32,8 +32,9 @@
     "broccoli-uglify-js": "^0.1.3",
     "eslint": "^1.10.3",
     "eslint-config-xo": "^0.9.2",
+    "eslint-config-xo-react": "^0.3.0",
     "eslint-plugin-html": "^1.2.0",
-    "eslint-plugin-react": "^3.15.0",
+    "eslint-plugin-react": "^3.16.1",
     "esprima-fb": "^15001.1001.0-dev-harmony-fb"
   }
 }


[06/50] allura git commit: [#8020] ticket:875 added test for undo; added text when spam clicking occured at ticket post page

Posted by he...@apache.org.
[#8020] ticket:875 added test for undo; added text when spam clicking occured at ticket post page


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

Branch: refs/heads/hs/8035
Commit: 63740ee2139eb3ef41d3fd3cbb065b7817c78140
Parents: ba44f08
Author: DeV1doR <de...@ukr.net>
Authored: Fri Dec 11 13:56:05 2015 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:03:18 2016 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py             |  2 ++
 Allura/allura/lib/widgets/discuss.py             | 17 +++++++++++++++--
 Allura/allura/nf/allura/css/site_style.css       |  6 ++++++
 Allura/allura/templates/widgets/post_widget.html | 12 +++++++++++-
 Allura/allura/tests/functional/test_discuss.py   |  8 ++++++++
 5 files changed, 42 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/63740ee2/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 89d4545..36cc494 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -355,6 +355,8 @@ class PostController(BaseController):
             self.post.delete()
         elif kw.pop('spam', None):
             self.post.spam()
+        elif kw.pop('undo', None):
+            self.post.status = 'pending'
         elif kw.pop('approve', None):
             if self.post.status != 'ok':
                 self.post.approve()

http://git-wip-us.apache.org/repos/asf/allura/blob/63740ee2/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index a8e475d..6503d5b 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -339,13 +339,26 @@ class Post(HierWidget):
                                 $('a.reply_post, a.shortlink, form.moderate_spam, form.moderate_approve', post).toggle();
                                 $('div.moderate', post).removeClass('moderate');
                             }
-                            else if (mod === 'Spam'){
-                                $(post).remove();
+                            else if (mod == 'Spam'){
+                                spam_block_display($(post), 'none');
+                                $(post).find('.spam-present').show();
+                            }
+                            else if (mod == 'Undo'){
+                                spam_block_display($(post), 'block');
+                                $(post).find('.spam-present').hide();
                             }
                         }
                     });
                 });
 
+                function spam_block_display($post, display_type) {
+                    $post.find('.display_post').css(
+                        'display', display_type);
+                    $.each($post.find('.options').children(), function() {
+                        $(this).css('display', display_type);
+                    });
+                }
+
                 function get_cm($elem) { return $('.CodeMirror', $elem)[0].CodeMirror; }
 
                 if($('a.edit_post', post)){

http://git-wip-us.apache.org/repos/asf/allura/blob/63740ee2/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index c0ddbd0..5dd347d 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -3428,3 +3428,9 @@ fieldset.preferences legend {
 .ui-autocomplete {
   z-index: 10; /* so autocomplete of tags or username is always over markdown editor components */
 }
+.spam-present {
+  display: none;
+}
+.spam-text {
+  float: left;
+}

http://git-wip-us.apache.org/repos/asf/allura/blob/63740ee2/Allura/allura/templates/widgets/post_widget.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/post_widget.html b/Allura/allura/templates/widgets/post_widget.html
index 096e829..a8aa822 100644
--- a/Allura/allura/templates/widgets/post_widget.html
+++ b/Allura/allura/templates/widgets/post_widget.html
@@ -43,7 +43,17 @@
       </div>
       {% set pending = value.status == 'pending' %}
       {% set moderator = h.has_access(value, 'moderator')() %}
-      <div class="grid-14" style="width: {{indent == 0 and 525 or (indent <= 40 and 515-indent*10 or 65)}}px">
+      <div class="grid-14 post-content" style="width: {{indent == 0 and 525 or (indent <= 40 and 515-indent*10 or 65)}}px">
+        <div class="spam-present">
+          <span class="spam-text">Comment has been marked as spam.&nbsp;</span>
+          <form method="POST" action="{{value.url()+'moderate'}}">
+            <input type="hidden" name="undo" value="True"/>
+            <a href="" class="moderate_post little_link"><span>Undo</span></a>
+            {{lib.csrf_token()}}
+          </form>
+          <br>
+          <span class="spam-text">You can see all comments posted by this user&nbsp;</span><a href="/p/test/tickets/_discuss/moderate">here</a>
+        </div>
         <div class="display_post{% if pending and moderator %} moderate{% endif %}">
           {% if pending and not moderator %}
             <b>Post awaiting moderation.</b>

http://git-wip-us.apache.org/repos/asf/allura/blob/63740ee2/Allura/allura/tests/functional/test_discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index d70664b..47218c8 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -208,6 +208,14 @@ class TestDiscuss(TestDiscussBase):
             ))
         assert r_bad_filtered.html.tbody.findAll('tr') == []
 
+    def test_undo(self):
+        r = self._make_post('Test post')
+        post_link = str(
+            r.html.find('div', {'class': 'edit_post_form reply'}).find('form')['action'])
+        self.app.post(post_link + 'moderate', params=dict(undo='undo'))
+        post = M.Post.query.find().first()
+        assert post.status == 'pending'
+
     @patch.object(M.Thread, 'is_spam')
     def test_feed_does_not_include_comments_held_for_moderation(self, is_spam):
         is_spam.return_value = True


[30/50] allura git commit: [#8035] ESLINT FIX: camelcase (add file override for api-heavy files)

Posted by he...@apache.org.
[#8035] ESLINT FIX: camelcase  (add file override for api-heavy files)


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

Branch: refs/heads/hs/8035
Commit: d4102f9de522d871703012957aaba23fa0c4dcef
Parents: fe237de
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 18:04:21 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:28 2016 -0500

----------------------------------------------------------------------
 Allura/allura/public/nf/js/context-menu.es6.js |  1 +
 Allura/allura/public/nf/js/navbar.es6.js       | 31 +++++++++++----------
 2 files changed, 17 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/d4102f9d/Allura/allura/public/nf/js/context-menu.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/context-menu.es6.js b/Allura/allura/public/nf/js/context-menu.es6.js
index 7572fb3..96ab2e1 100644
--- a/Allura/allura/public/nf/js/context-menu.es6.js
+++ b/Allura/allura/public/nf/js/context-menu.es6.js
@@ -16,6 +16,7 @@
  specific language governing permissions and limitations
  under the License.
  */
+/* eslint camelcase: 0 */
 'use strict';
 
 

http://git-wip-us.apache.org/repos/asf/allura/blob/d4102f9d/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index b1a0eb3..ee356a4 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -16,6 +16,7 @@
        specific language governing permissions and limitations
        under the License.
 */
+/* eslint camelcase: 0 */
 'use strict';
 
 /**
@@ -285,7 +286,7 @@ var AdminNav = React.createClass({
 
     buildMenu: function (items, isSubMenu=false) {
         var _this = this;
-        var [tools, anchored_tools, end_tools] = [[], [], []];
+        var [tools, anchoredTools, endTools] = [[], [], []];
         var subMenu, childOptionsOpen;
 
         for (let item of items) {
@@ -297,19 +298,19 @@ var AdminNav = React.createClass({
 
             var _handle = isSubMenu ? "draggable-handle-sub" : 'draggable-handle';
 
-            var tool_list, is_anchored;
+            var toolList, isAnchored;
             if (item.mount_point === 'admin') {
                 // force admin to end, just like 'Project.sitemap()' does
-                tool_list = end_tools;
-                is_anchored = true;
+                toolList = endTools;
+                isAnchored = true;
             } else if (item.is_anchored) {
-                tool_list = anchored_tools;
-                is_anchored = true;
+                toolList = anchoredTools;
+                isAnchored = true;
             } else {
-                tool_list = tools;
-                is_anchored = false;
+                toolList = tools;
+                isAnchored = false;
             }
-            var core_item = <NavBarItem
+            var coreItem = <NavBarItem
                 {..._this.props}
                 mount_point={ item.mount_point }
                 name={ item.name }
@@ -317,27 +318,27 @@ var AdminNav = React.createClass({
                 isGrouper={item.children && item.children.length > 0}
                 url={ item.url }
                 key={ 'tb-item-' + _.uniqueId() }
-                is_anchored={ is_anchored }
+                is_anchored={ isAnchored }
                 options={ item.admin_options }
             />;
             if (subMenu) {
                 childOptionsOpen = _.contains(_.pluck(item.children, 'mount_point'),
                     this.props.currentOptionMenu.tool);
 
-                tool_list.push(<NavBarItemWithSubMenu
+                toolList.push(<NavBarItemWithSubMenu
                     key={_.uniqueId()}
-                    tool={core_item}
+                    tool={coreItem}
                     subMenu={subMenu}
                     childOptionsOpen={childOptionsOpen}
                 />);
             } else {
-                tool_list.push(core_item);
+                toolList.push(coreItem);
             }
         }
 
         return (
             <div className='react-drag'>
-                { anchored_tools }
+                { anchoredTools }
                 <ReactReorderable
                     key={ 'reorder-' + _.uniqueId() }
                     handle={"." + _handle}
@@ -346,7 +347,7 @@ var AdminNav = React.createClass({
                     onDrop={ _this.props.onToolReorder }>
                     { tools }
                 </ReactReorderable>
-                { end_tools }
+                { endTools }
                 { !isSubMenu && <div id="add-tool-container" className="unlocked-container">
                     <ToggleAddNewTool installableTools={this.props.installableTools}/>
                 </div>}


[09/50] allura git commit: [#8020] ticket:866 Add Thread.update_stats() to functions which change Post status

Posted by he...@apache.org.
[#8020] ticket:866 Add Thread.update_stats() to functions which change Post status


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

Branch: refs/heads/hs/8035
Commit: 31396ee6b96e18e5c4f0bc918d561b64f7ea32b9
Parents: 2121b5c
Author: Denis Kotov <de...@gmail.com>
Authored: Wed Jan 20 18:03:07 2016 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:08:16 2016 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py         |  4 +--
 Allura/allura/model/discuss.py               | 16 +++++++++---
 Allura/allura/tests/model/test_discussion.py | 30 ++++++++++++++++++-----
 3 files changed, 37 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/31396ee6/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index e28a780..9cb5f37 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -356,14 +356,12 @@ class PostController(BaseController):
             self.post.spam()
         elif kw.pop('undo', None):
             prev_status = kw.pop('prev_status', None)
-            if prev_status:
-                self.post.status = prev_status
+            self.post.undo(prev_status)
         elif kw.pop('approve', None):
             if self.post.status != 'ok':
                 self.post.approve()
                 g.spam_checker.submit_ham(self.post.text, artifact=self.post, user=self.post.author())
                 self.post.thread.post_to_feed(self.post)
-        self.thread.update_stats()
         return dict(result='success')
 
     @h.vardec

http://git-wip-us.apache.org/repos/asf/allura/blob/31396ee6/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index df753e8..e3e6527 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -265,7 +265,8 @@ class Thread(Artifact, ActivityObject):
         """Helper function to avoid code duplication."""
         p = self.post(**kw)
         p.commit(update_stats=False)
-        self.num_replies += 1
+        session(self).flush(self)
+        self.update_stats()
         if not self.first_post:
             self.first_post_id = p._id
         self.post_to_feed(p)
@@ -343,7 +344,7 @@ class Thread(Artifact, ActivityObject):
 
     def update_stats(self):
         self.num_replies = self.post_class().query.find(
-            dict(thread_id=self._id, status='ok', deleted=False)).count() - 1
+            dict(thread_id=self._id, status='ok', deleted=False)).count()
 
     @property
     def last_post(self):
@@ -701,7 +702,7 @@ class Post(Message, VersionedArtifact, ActivityObject):
     def delete(self):
         self.deleted = True
         session(self).flush(self)
-        self.thread.num_replies = max(0, self.thread.num_replies - 1)
+        self.thread.update_stats()
 
     def approve(self, file_info=None, notify=True, notification_text=None):
         if self.status == 'ok':
@@ -769,8 +770,15 @@ class Post(Message, VersionedArtifact, ActivityObject):
 
     def spam(self):
         self.status = 'spam'
-        self.thread.num_replies = max(0, self.thread.num_replies - 1)
         g.spam_checker.submit_spam(self.text, artifact=self, user=self.author())
+        session(self).flush(self)
+        self.thread.update_stats()
+
+    def undo(self, prev_status):
+        if prev_status in ('ok', 'pending'):
+            self.status = prev_status
+            session(self).flush(self)
+            self.thread.update_stats()
 
 
 class DiscussionAttachment(BaseAttachment):

http://git-wip-us.apache.org/repos/asf/allura/blob/31396ee6/Allura/allura/tests/model/test_discussion.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index c94f2a6..7b15c1d 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -114,7 +114,8 @@ def test_thread_methods():
     assert '_id' in jsn
     assert_equals(len(jsn['posts']), 3)
     (p.approve() for p in (p0, p1))
-    assert t.num_replies == 2
+    ThreadLocalORMSession.flush_all()
+    assert t.num_replies == 3
     t.spam()
     assert t.num_replies == 0
     ThreadLocalORMSession.flush_all()
@@ -165,13 +166,14 @@ def test_post_methods():
     assert jsn["thread_id"] == t._id
 
     (p.approve() for p in (p, p2))
-    assert t.num_replies == 1
-    p2.spam()
-    assert t.num_replies == 0
+    ThreadLocalORMSession.flush_all()
+    assert t.num_replies == 2
     p.spam()
-    assert t.num_replies == 0
+    assert t.num_replies == 1
+    p.undo('ok')
+    assert t.num_replies == 2
     p.delete()
-    assert t.num_replies == 0
+    assert t.num_replies == 1
 
 
 @with_setup(setUp, tearDown)
@@ -325,6 +327,21 @@ def test_post_delete():
 
 
 @with_setup(setUp, tearDown)
+def test_post_undo():
+    d = M.Discussion(shortname='test', name='test')
+    t = M.Thread.new(discussion_id=d._id, subject='Test Thread')
+    p = t.post('This is a post')
+    t.post('This is a post2')
+    t.post('This is a post3')
+    ThreadLocalORMSession.flush_all()
+    assert t.num_replies == 3
+    p.spam()
+    assert t.num_replies == 2
+    p.undo('ok')
+    assert t.num_replies == 3
+
+
+@with_setup(setUp, tearDown)
 def test_post_permission_check():
     d = M.Discussion(shortname='test', name='test')
     t = M.Thread.new(discussion_id=d._id, subject='Test Thread')
@@ -519,6 +536,7 @@ def test_post_count():
 def test_spam_num_replies(spam_checker):
     d = M.Discussion(shortname='test', name='test')
     t = M.Thread(discussion_id=d._id, subject='Test Thread', num_replies=2)
+    M.Post(discussion_id=d._id, thread_id=t._id, status='ok')
     p1 = M.Post(discussion_id=d._id, thread_id=t._id, status='spam')
     p1.spam()
     assert_equal(t.num_replies, 1)


[10/50] allura git commit: [#8020] ticket:866 add flush in test

Posted by he...@apache.org.
[#8020] ticket:866 add flush in test


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

Branch: refs/heads/hs/8035
Commit: 3ccbb5d4c123a5e0c302bae00bbe0aeebdee3df2
Parents: 31396ee
Author: Denis Kotov <de...@gmail.com>
Authored: Wed Jan 20 21:45:51 2016 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:08:19 2016 -0500

----------------------------------------------------------------------
 Allura/allura/tests/model/test_discussion.py | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/3ccbb5d4/Allura/allura/tests/model/test_discussion.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/model/test_discussion.py b/Allura/allura/tests/model/test_discussion.py
index 7b15c1d..2ff36f4 100644
--- a/Allura/allura/tests/model/test_discussion.py
+++ b/Allura/allura/tests/model/test_discussion.py
@@ -537,6 +537,7 @@ def test_spam_num_replies(spam_checker):
     d = M.Discussion(shortname='test', name='test')
     t = M.Thread(discussion_id=d._id, subject='Test Thread', num_replies=2)
     M.Post(discussion_id=d._id, thread_id=t._id, status='ok')
+    ThreadLocalORMSession.flush_all()
     p1 = M.Post(discussion_id=d._id, thread_id=t._id, status='spam')
     p1.spam()
     assert_equal(t.num_replies, 1)


[38/50] allura git commit: [#8035] ESLINT FIX: require-jsdoc, valid-jsdoc

Posted by he...@apache.org.
[#8035] ESLINT FIX: require-jsdoc, valid-jsdoc


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

Branch: refs/heads/hs/8035
Commit: 5fa95485b19e4178163123e44ff2ae2bc3aba7af
Parents: 085fbb7
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 19:18:12 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:30 2016 -0500

----------------------------------------------------------------------
 .eslintrc                                |  8 +++++++-
 Allura/allura/public/nf/js/navbar.es6.js | 27 ++++++++++++---------------
 2 files changed, 19 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/5fa95485/.eslintrc
----------------------------------------------------------------------
diff --git a/.eslintrc b/.eslintrc
index ff25e9d..835cf29 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -4,7 +4,13 @@
     "indent": [2, 4],
     "jsx-quotes": [0],
     "quotes": [0],
-    "operator-linebreak": [2, "before", { "overrides": { "?": "after", "&&": "after" } }]
+    "operator-linebreak": [2, "before", { "overrides": { "?": "after", "&&": "after" } }],
+    "require-jsdoc": [2, {"require": {
+        "FunctionDeclaration": true,
+        "MethodDefinition": false,
+        "ClassDeclaration": false
+    }
+  }]
   },
   "globals": {
     "ReactDOM": true,

http://git-wip-us.apache.org/repos/asf/allura/blob/5fa95485/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index 2d0201e..d83f1f0 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -21,18 +21,17 @@
 'use strict';
 
 /**
- * Gets the current project url.
-
- * @constructor
- * @param {bool} rest - Return a "rest" version of the url.
- * @returns {string}
- */
-function _getProjectUrl(rest = true) {
+* Gets the current project url.
+* @param {boolean} rest - Return a "rest" version of the url.
+* @returns {string} - Project Url
+*/
+var _getProjectUrl = function(rest = true) {
     var nbhd;
     var proj;
     var nbhd_proj;
-    var ident_classes = document.getElementById('page-body').className.split(' ');
-    for (var cls of ident_classes) {
+    var identClasses = document.getElementById('page-body').className.split(' ');
+    var basePath = rest ? '/rest/' : '/';
+    for (var cls of identClasses) {
         if (cls.indexOf('project-') === 0) {
             proj = cls.slice('project-'.length);
         }
@@ -43,8 +42,8 @@ function _getProjectUrl(rest = true) {
     } else {
         nbhd_proj = `${nbhd}/${proj}`;
     }
-    return (rest ? '/rest/' : '/') + nbhd_proj;
-}
+    return basePath + nbhd_proj;
+};
 
 const ToolsPropType = React.PropTypes.shape({
     mount_point: React.PropTypes.string,
@@ -469,8 +468,8 @@ var Main = React.createClass({
 
     /**
      * Handles the changing of the NavBars grouping threshold.
-
-     * @param {object} event
+     * @param {object} event Fired when the threshold changes
+     * @return {boolean} False
      */
     onUpdateThreshold: function(event) {
         var thres = event.target.value;
@@ -486,8 +485,6 @@ var Main = React.createClass({
 
     /**
      * Handles the sending and updating tool ordinals.
-
-     * @param {array} data - Array of tools
      */
     onToolReorder: function() {
         $('.react-drag.dragging').removeClass('dragging');


[40/50] allura git commit: [#8035] ESLINT FIX: no-else-return

Posted by he...@apache.org.
[#8035] ESLINT FIX: no-else-return


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

Branch: refs/heads/hs/8035
Commit: a8f7b1d4b8c2546259119ee4cbb378a57f9b6573
Parents: c29d9e2
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 19:52:56 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:31 2016 -0500

----------------------------------------------------------------------
 Allura/allura/public/nf/js/navbar.es6.js | 40 +++++++++++++--------------
 1 file changed, 19 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/a8f7b1d4/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index 44e2caf..ffaa371 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -531,35 +531,33 @@ var Main = React.createClass({
     render: function() {
         var _this = this;
         var navBarSwitch = showAdmin => {
+            var navbar;
             if (showAdmin) {
-                return (
-                    <AdminNav
-                        tools={ _this.state.data.menu }
+                navbar = <AdminNav
+                    tools={ _this.state.data.menu }
+                    installableTools={ _this.state.data.installable_tools }
+                    data={ _this.state.data }
+                    onToolReorder={ _this.onToolReorder }
+                    onToolDragStart={ _this.onToolDragStart }
+                    editMode={ _this.state.visible }
+                    currentOptionMenu={ _this.state.currentOptionMenu }
+                    onOptionClick={ _this.handleShowOptionMenu }
+                    currentToolOptions={this.state.currentToolOptions}
+                />;
+            } else {
+                navbar = <div>
+                    <NormalNavBar
+                        items={ _this.state.data.menu }
                         installableTools={ _this.state.data.installable_tools }
-                        data={ _this.state.data }
-                        onToolReorder={ _this.onToolReorder }
-                        onToolDragStart={ _this.onToolDragStart }
-                        editMode={ _this.state.visible }
-                        currentOptionMenu={ _this.state.currentOptionMenu }
-                        onOptionClick={ _this.handleShowOptionMenu }
-                        currentToolOptions={this.state.currentToolOptions}
                     />
-                );
-            } else {
-                return (
-                    <div>
-                        <NormalNavBar
-                            items={ _this.state.data.menu }
-                            installableTools={ _this.state.data.installable_tools }
-                            />
-                    </div>
-                );
+                </div>;
             }
+            return navbar;
         };
         var navBar = navBarSwitch(this.state.visible);
 
         var max_tool_count = _.chain(this.state.data.menu)
-                             .map((item) => {
+                             .map(item => {
                                  return item.children ? _.pluck(item.children, 'tool_name') : item.tool_name;
                              })
                              .flatten()


[27/50] allura git commit: [#8035] Add eslint deps

Posted by he...@apache.org.
[#8035] Add eslint deps


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

Branch: refs/heads/hs/8035
Commit: b8e8f9fdea3ffb7ac22b751f3abac1120a46addb
Parents: eabfc16
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 15:44:22 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:27 2016 -0500

----------------------------------------------------------------------
 package.json | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/b8e8f9fd/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 3b27d67..1f12ff5 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,9 @@
     "test": "echo \"Error: no test specified\" && exit 1",
     "build": "rm -rf Allura/allura/public/nf/js/build/; broccoli build Allura/allura/public/nf/js/build/",
     "watch": "broccoli-timepiece Allura/allura/public/nf/js/build/",
-    "eslint": "eslint"
+    "env": "env",
+    "eslint": "eslint",
+    "lint": "eslint Allura/allura/public/nf/js/*.es6.js || true"
   },
   "repository": {
     "type": "git",
@@ -17,6 +19,7 @@
   "license": "Apache-2.0",
   "//": "When broccoli-babel-transpiler moves to babel 6, we'll need to add babel-plugin-transform-class-properties to our deps",
   "devDependencies": {
+    "babel-eslint": "^5.0.0-beta6",
     "broccoli": "^0.16.8",
     "broccoli-babel-transpiler": "^5.4.5",
     "broccoli-cli": "^1.0.0",
@@ -26,7 +29,9 @@
     "broccoli-timepiece": "^0.3.0",
     "broccoli-uglify-js": "^0.1.3",
     "eslint": "^1.10.3",
+    "eslint-config-google": "^0.3.0",
     "eslint-plugin-html": "^1.2.0",
+    "eslint-plugin-react": "^3.15.0",
     "esprima-fb": "^15001.1001.0-dev-harmony-fb"
   }
 }


[18/50] allura git commit: [#8044] fix RAML syntax

Posted by he...@apache.org.
[#8044] fix RAML syntax


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

Branch: refs/heads/hs/8035
Commit: 14ccf22b4690fa0dcc1f72a651c9178fc48d3b4c
Parents: 5adc337
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Jan 27 12:42:34 2016 -0500
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:42:34 2016 -0500

----------------------------------------------------------------------
 Allura/docs/api-rest/api.raml | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/14ccf22b/Allura/docs/api-rest/api.raml
----------------------------------------------------------------------
diff --git a/Allura/docs/api-rest/api.raml b/Allura/docs/api-rest/api.raml
index 9c50d9d..68d8a0f 100755
--- a/Allura/docs/api-rest/api.raml
+++ b/Allura/docs/api-rest/api.raml
@@ -740,13 +740,14 @@ documentation:
 /notification:
   description: |
     Get current Site Notification
-  uriParameters:
-    cookie:
-      description: site-notification cookie value
-      example: "56a111736c4ff90011b9f932-1-False"
-    url:
-      description: page where must be shown notification
-      example: "/p/test-project"
-    tool_name:
-      description: tool's name which used on page
-      exaple: "Git"
\ No newline at end of file
+  get:
+    queryParameters:
+      cookie:
+        description: site-notification cookie value
+        example: "56a111736c4ff90011b9f932-1-False"
+      url:
+        description: page where notification will be shown
+        example: "/p/test-project"
+      tool_name:
+        description: tool's name for current page
+        example: "Git"
\ No newline at end of file


[08/50] allura git commit: [#8020] ticket:875 updated widget

Posted by he...@apache.org.
[#8020] ticket:875 updated widget


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

Branch: refs/heads/hs/8035
Commit: f7637031a7ed3ea491386e057a079dd8cda3e75c
Parents: 63740ee
Author: DeV1doR <de...@ukr.net>
Authored: Fri Dec 11 15:14:57 2015 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:03:18 2016 -0500

----------------------------------------------------------------------
 Allura/allura/lib/widgets/discuss.py             | 1 +
 Allura/allura/templates/widgets/post_widget.html | 4 +++-
 2 files changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/f7637031/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index 6503d5b..c56e2cd 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -346,6 +346,7 @@ class Post(HierWidget):
                             else if (mod == 'Undo'){
                                 spam_block_display($(post), 'block');
                                 $(post).find('.spam-present').hide();
+                                $(post).find('.options a').eq(0).hide();
                             }
                         }
                     });

http://git-wip-us.apache.org/repos/asf/allura/blob/f7637031/Allura/allura/templates/widgets/post_widget.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/post_widget.html b/Allura/allura/templates/widgets/post_widget.html
index a8aa822..2695c2b 100644
--- a/Allura/allura/templates/widgets/post_widget.html
+++ b/Allura/allura/templates/widgets/post_widget.html
@@ -46,13 +46,15 @@
       <div class="grid-14 post-content" style="width: {{indent == 0 and 525 or (indent <= 40 and 515-indent*10 or 65)}}px">
         <div class="spam-present">
           <span class="spam-text">Comment has been marked as spam.&nbsp;</span>
+          {% if h.has_access(value, 'moderate')() %}
           <form method="POST" action="{{value.url()+'moderate'}}">
             <input type="hidden" name="undo" value="True"/>
             <a href="" class="moderate_post little_link"><span>Undo</span></a>
             {{lib.csrf_token()}}
           </form>
+          {% endif %}
           <br>
-          <span class="spam-text">You can see all comments posted by this user&nbsp;</span><a href="/p/test/tickets/_discuss/moderate">here</a>
+          <span class="spam-text">You can see all comments posted by this user&nbsp;</span><a href="/p/test/tickets/_discuss/moderate?username={{value.author().username}}&status=spam">here</a>
         </div>
         <div class="display_post{% if pending and moderator %} moderate{% endif %}">
           {% if pending and not moderator %}


[04/50] allura git commit: [#8020] ticket:875 updated rendering of spam block; changed notification text and redirect here link

Posted by he...@apache.org.
[#8020] ticket:875 updated rendering of spam block; changed notification text and redirect here link


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

Branch: refs/heads/hs/8035
Commit: 0778b7adecf9ad558bbe56143670f513e811676e
Parents: bf73398
Author: DeV1doR <de...@ukr.net>
Authored: Mon Dec 21 18:15:56 2015 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:03:18 2016 -0500

----------------------------------------------------------------------
 Allura/allura/lib/widgets/discuss.py            | 34 +++++++-------------
 Allura/allura/nf/allura/css/site_style.css      |  1 +
 .../allura/templates/widgets/post_widget.html   | 26 +++++++--------
 3 files changed, 25 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/0778b7ad/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index 4d83070..d343969 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -340,37 +340,25 @@ class Post(HierWidget):
                                 $('div.moderate', post).removeClass('moderate');
                             }
                             else if (mod == 'Spam'){
-                                spam_block_display($(post), 'none');
+                                spam_block_display($(post), 'show_spam');
                             }
                             else if (mod == 'Undo'){
-                                spam_block_display($(post), 'block');
+                                spam_block_display($(post), 'hide_spam');
                             }
                         }
                     });
                 });
 
                 function spam_block_display($post, display_type) {
-                    var post_block = $post.find('.display_post');
-                    post_block.css('display', display_type);
-
-                    var attach_block = $post.find('.add_attachment_form').next();
-                    if (attach_block.attr('class') == undefined) {
-                        attach_block.css('display', display_type);
-                    }
-
-                    $.each($post.find('.options').children(), function() {
-                        $(this).css('display', display_type);
-                        if (
-                            $(this).hasClass('reply_post') &&
-                            $post.find('input[name="prev_status"]').attr('value') == 'pending'
-                        ) {
-                            $(this).hide();
-                        }
-                    });
-                    if (display_type == 'none') {
-                        $post.find('.spam-present').show();
-                    } else {
-                        $post.find('.spam-present').hide();
+                    var spam_block = $post.find('.info.grid-15.spam-present');
+                    var row = $post.find('.row').eq(0);
+
+                    if (display_type == 'show_spam') {
+                        spam_block.show();
+                        row.hide();
+                    } else if (display_type == 'hide_spam') {
+                        spam_block.hide();
+                        row.show();
                     }
                 }
 

http://git-wip-us.apache.org/repos/asf/allura/blob/0778b7ad/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index 5dd347d..885d948 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -3430,6 +3430,7 @@ fieldset.preferences legend {
 }
 .spam-present {
   display: none;
+  margin-left: 75px;
 }
 .spam-text {
   float: left;

http://git-wip-us.apache.org/repos/asf/allura/blob/0778b7ad/Allura/allura/templates/widgets/post_widget.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/post_widget.html b/Allura/allura/templates/widgets/post_widget.html
index 6b8622d..4d388ee 100644
--- a/Allura/allura/templates/widgets/post_widget.html
+++ b/Allura/allura/templates/widgets/post_widget.html
@@ -29,6 +29,19 @@
 
 <div>
   <div id="{{value.slug}}" class="discussion-post">
+    {% if h.has_access(value, 'moderate')() %}
+    <div class="info grid-15 spam-present">
+      <span class="spam-text">Comment has been marked as spam.&nbsp;</span>
+      <form method="POST" action="{{value.url()+'moderate'}}">
+        <input type="hidden" name="undo" value="True"/>
+        <input type="hidden" name="prev_status" value="{{value.status}}">
+        <a href="" class="moderate_post little_link"><span>Undo</span></a>
+        {{lib.csrf_token()}}
+      </form>
+      <br>
+      <span class="spam-text">You can see all pending comments posted by this user&nbsp;</span><a href="/p/test/tickets/_discuss/moderate?username={{value.author().username}}&status=pending">here</a>
+    </div>
+    {% endif %}
     <div class="row">
       <div class="grid-2 tcenter gravatar">
        <p class="gravatar">
@@ -44,19 +57,6 @@
       {% set pending = value.status == 'pending' %}
       {% set moderator = h.has_access(value, 'moderator')() %}
       <div class="grid-14 post-content" style="width: {{indent == 0 and 525 or (indent <= 40 and 515-indent*10 or 65)}}px">
-        <div class="spam-present">
-          <span class="spam-text">Comment has been marked as spam.&nbsp;</span>
-          {% if h.has_access(value, 'moderate')() %}
-          <form method="POST" action="{{value.url()+'moderate'}}">
-            <input type="hidden" name="undo" value="True"/>
-            <input type="hidden" name="prev_status" value="{{value.status}}">
-            <a href="" class="moderate_post little_link"><span>Undo</span></a>
-            {{lib.csrf_token()}}
-          </form>
-          {% endif %}
-          <br>
-          <span class="spam-text">You can see all comments posted by this user&nbsp;</span><a href="/p/test/tickets/_discuss/moderate?username={{value.author().username}}&status=spam">here</a>
-        </div>
         <div class="display_post{% if pending and moderator %} moderate{% endif %}">
           {% if pending and not moderator %}
             <b>Post awaiting moderation.</b>


[31/50] allura git commit: [#8035] ESLINT FIX: one-var

Posted by he...@apache.org.
[#8035] ESLINT FIX: one-var


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

Branch: refs/heads/hs/8035
Commit: 03f750c647b34b10f55614e16149523425438e7e
Parents: d4102f9
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 18:12:23 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:28 2016 -0500

----------------------------------------------------------------------
 Allura/allura/public/nf/js/navbar.es6.js | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/03f750c6/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index ee356a4..4570872 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -27,7 +27,9 @@
  * @returns {string}
  */
 function _getProjectUrl(rest = true) {
-    var nbhd, proj, nbhd_proj;
+    var nbhd;
+    var proj;
+    var nbhd_proj;
     var ident_classes = document.getElementById('page-body').className.split(' ');
     for (var cls of ident_classes) {
         if (cls.indexOf('project-') === 0) {
@@ -287,7 +289,8 @@ var AdminNav = React.createClass({
     buildMenu: function (items, isSubMenu=false) {
         var _this = this;
         var [tools, anchoredTools, endTools] = [[], [], []];
-        var subMenu, childOptionsOpen;
+        var subMenu;
+        var childOptionsOpen;
 
         for (let item of items) {
             if (item.children) {
@@ -297,8 +300,8 @@ var AdminNav = React.createClass({
             }
 
             var _handle = isSubMenu ? "draggable-handle-sub" : 'draggable-handle';
-
-            var toolList, isAnchored;
+            var toolList;
+            var isAnchored;
             if (item.mount_point === 'admin') {
                 // force admin to end, just like 'Project.sitemap()' does
                 toolList = endTools;


[29/50] allura git commit: [#8035] ESLINT FIX: quotes, jsx-quotes

Posted by he...@apache.org.
[#8035] ESLINT FIX: quotes, jsx-quotes


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

Branch: refs/heads/hs/8035
Commit: fe237def8aec75925f4da8c493635d5f0de6ba61
Parents: 8ad3685
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 17:44:54 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:28 2016 -0500

----------------------------------------------------------------------
 .eslintrc | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/fe237def/.eslintrc
----------------------------------------------------------------------
diff --git a/.eslintrc b/.eslintrc
index a66f2fa..b42eb66 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -1,7 +1,9 @@
 {
   "rules": {
     "max-len": [1, 119, 4],
-    "indent": [2, 4]
+    "indent": [2, 4],
+    "jsx-quotes": [0],
+    "quotes": [0]
   },
   "globals": {
     "ReactDOM": true,


[49/50] allura git commit: [#8035] Fix Inverted grouping threshold box

Posted by he...@apache.org.
[#8035] Fix Inverted grouping threshold box


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

Branch: refs/heads/hs/8035
Commit: 817d26fd1f038741c29730154334871b8afa2f3e
Parents: c563deb
Author: Heith Seewald <he...@gmail.com>
Authored: Tue Jan 26 14:19:53 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:33 2016 -0500

----------------------------------------------------------------------
 Allura/allura/public/nf/js/navbar.es6.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/817d26fd/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index d027602..ab7bbb5 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -139,7 +139,7 @@ var GroupingThreshold = React.createClass({
     render: function() {
         return (
             <div>
-                { !Boolean(this.props.isHidden) &&
+                { !Boolean(!this.props.isHidden) &&
                 <div id='threshold-config'>
             <span>
               <label htmlFor='threshold-input'>Grouping Threshold</label>


[02/50] allura git commit: [#8020] remove dead 'flag' code (long long ago non-moderators could help flag things as spam). This is separate from the moderator's flag as spam option, and from thread-level flags (e.g. sticky)

Posted by he...@apache.org.
[#8020] remove dead 'flag' code (long long ago non-moderators could help flag things as spam).  This is separate from the moderator's flag as spam option, and from thread-level flags (e.g. sticky)


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

Branch: refs/heads/hs/8035
Commit: 2121b5cbbc632308d41578df4370f4df6bf3e8fb
Parents: 8bdaa38
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Jan 6 13:28:58 2016 -0500
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:03:18 2016 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py            | 12 ----------
 Allura/allura/lib/widgets/discuss.py            | 15 ------------
 Allura/allura/model/discuss.py                  |  3 ---
 Allura/allura/templates/widgets/flag_post.html  | 24 --------------------
 .../templates/widgets/moderate_posts.html       |  2 --
 Allura/docs/api-rest/examples/discussion.json   |  2 --
 Allura/docs/api-rest/schemas/discussion.json    |  4 ----
 .../forgediscussion/controllers/forum.py        |  1 -
 8 files changed, 63 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/2121b5cb/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 92b1169..e28a780 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -62,7 +62,6 @@ class WidgetConfig(object):
     edit_post = DW.EditPost()
     moderate_thread = DW.ModerateThread()
     moderate_post = DW.ModeratePost()
-    flag_post = DW.FlagPost()
     post_filter = DW.PostFilter()
     moderate_posts = DW.ModeratePosts()
     # Other widgets
@@ -370,17 +369,6 @@ class PostController(BaseController):
     @h.vardec
     @expose()
     @require_post()
-    @validate(pass_validator, error_handler=error_handler)
-    def flag(self, **kw):
-        self.W.flag_post.to_python(kw, None)
-        if c.user._id not in self.post.flagged_by:
-            self.post.flagged_by.append(c.user._id)
-            self.post.flags += 1
-        redirect(request.referer)
-
-    @h.vardec
-    @expose()
-    @require_post()
     def attach(self, file_info=None):
         require_access(self.post, 'moderate')
         self.post.add_multiple_attachments(file_info)

http://git-wip-us.apache.org/repos/asf/allura/blob/2121b5cb/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index d343969..0e24d5b 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -54,13 +54,6 @@ class ModeratePost(ew.SimpleForm):
         submit_text=None)
 
 
-class FlagPost(ew.SimpleForm):
-    template = 'jinja:allura:templates/widgets/flag_post.html'
-    defaults = dict(
-        ew.SimpleForm.defaults,
-        submit_text=None)
-
-
 class AttachPost(ff.ForgeForm):
     defaults = dict(
         ff.ForgeForm.defaults,
@@ -119,10 +112,6 @@ class PostFilter(ff.ForgeForm):
                                   label='Pending moderation'),
                         ew.Option(py_value='ok', label='Ok')],
                     if_missing='pending'),
-            ew.IntField(name='flag',
-                        label='Show posts with at least "n" flags',
-                        css_class='text',
-                        if_missing=0),
             ew.InputField(name='username',
                           label='Show post filtered by username'),
             ew.SubmitButton(label='Filter Posts')
@@ -317,10 +306,6 @@ class Post(HierWidget):
             $('div.discussion-post').each(function () {
                 var post = this;
                 $('.submit', post).button();
-                $('.flag_post', post).click(function (evt) {
-                    evt.preventDefault();
-                    this.parentNode.submit();
-                });
                 $('.moderate_post', post).click(function(e){
                     e.preventDefault();
                     var mod = $(this).text();

http://git-wip-us.apache.org/repos/asf/allura/blob/2121b5cb/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index 291f554..df753e8 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -484,8 +484,6 @@ class Post(Message, VersionedArtifact, ActivityObject):
     subject = FieldProperty(schema.Deprecated)
     status = FieldProperty(schema.OneOf('ok', 'pending', 'spam',
                                         if_missing='pending'))
-    flagged_by = FieldProperty([schema.ObjectId])
-    flags = FieldProperty(int, if_missing=0)
     last_edit_date = FieldProperty(datetime, if_missing=None)
     last_edit_by_id = AlluraUserProperty()
     edit_count = FieldProperty(int, if_missing=0)
@@ -506,7 +504,6 @@ class Post(Message, VersionedArtifact, ActivityObject):
             subject=self.subject,
             status=self.status,
             text=self.text,
-            flagged_by=map(str, self.flagged_by),
             timestamp=self.timestamp,
             last_edited=self.last_edit_date,
             author_id=str(author._id),

http://git-wip-us.apache.org/repos/asf/allura/blob/2121b5cb/Allura/allura/templates/widgets/flag_post.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/flag_post.html b/Allura/allura/templates/widgets/flag_post.html
deleted file mode 100644
index 64a7d6e..0000000
--- a/Allura/allura/templates/widgets/flag_post.html
+++ /dev/null
@@ -1,24 +0,0 @@
-{#-
-       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 'allura:templates/jinja_master/lib.html' as lib with context %}
-<form method="POST" action="{{action}}">
-    <input type="hidden" name="delete" value="True"/>
-    {{ g.icons['flag'].render(show_title=True, extra_css='flag_post') }}
-    {{lib.csrf_token()}}
-</form>

http://git-wip-us.apache.org/repos/asf/allura/blob/2121b5cb/Allura/allura/templates/widgets/moderate_posts.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/moderate_posts.html b/Allura/allura/templates/widgets/moderate_posts.html
index 7a81e1e..6a73669 100644
--- a/Allura/allura/templates/widgets/moderate_posts.html
+++ b/Allura/allura/templates/widgets/moderate_posts.html
@@ -32,7 +32,6 @@
         <th><a href="#">[x]</a></th>
         <th>Timestamp</th>
         <th>Status</th>
-        <th>Flags?</th>
         <th>Author</th>
         <th>Subject</th>
         <th>Text</th>
@@ -49,7 +48,6 @@
           </td>
           <td>{{h.ago(post.timestamp)}}</td>
           <td>{{post.status}}</td>
-          <td>{{post.flags}}</td>
           {% set author = post.author() %}
           <td>{{author.display_name}} ({{author.username}})</td>
           <td>{{post.thread.subject or '(no subject)'}}</td>

http://git-wip-us.apache.org/repos/asf/allura/blob/2121b5cb/Allura/docs/api-rest/examples/discussion.json
----------------------------------------------------------------------
diff --git a/Allura/docs/api-rest/examples/discussion.json b/Allura/docs/api-rest/examples/discussion.json
index 128269b..51fa7fb 100755
--- a/Allura/docs/api-rest/examples/discussion.json
+++ b/Allura/docs/api-rest/examples/discussion.json
@@ -8,7 +8,6 @@
       "shortname": "devs",
       "_id": "55ad23c34d21224d82656add",
       "last_post": {
-        "flagged_by": [],
         "status": "ok",
         "last_edited": "2015-07-20 16:39:53.290000",
         "author": "root",
@@ -29,7 +28,6 @@
       "shortname": "general",
       "_id": "5568f6684d212236d1eaed07",
       "last_post": {
-        "flagged_by": [],
         "status": "ok",
         "last_edited": null,
         "author": "root",

http://git-wip-us.apache.org/repos/asf/allura/blob/2121b5cb/Allura/docs/api-rest/schemas/discussion.json
----------------------------------------------------------------------
diff --git a/Allura/docs/api-rest/schemas/discussion.json b/Allura/docs/api-rest/schemas/discussion.json
index 8f62a2f..5a66073 100755
--- a/Allura/docs/api-rest/schemas/discussion.json
+++ b/Allura/docs/api-rest/schemas/discussion.json
@@ -36,10 +36,6 @@
                         "type": "object", 
                         "id": "last_post", 
                         "properties": {
-                            "flagged_by": {
-                                "type": "array", 
-                                "id": "flagged_by"
-                            }, 
                             "status": {
                                 "type": "string", 
                                 "id": "status"

http://git-wip-us.apache.org/repos/asf/allura/blob/2121b5cb/ForgeDiscussion/forgediscussion/controllers/forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/forum.py b/ForgeDiscussion/forgediscussion/controllers/forum.py
index ba1f366..bb0fa33 100644
--- a/ForgeDiscussion/forgediscussion/controllers/forum.py
+++ b/ForgeDiscussion/forgediscussion/controllers/forum.py
@@ -60,7 +60,6 @@ class WidgetConfig(object):
     subscribe_form = SubscribeForm()
     edit_post = DW.EditPost(show_subject=True)
     moderate_thread = FW.ModerateThread()
-    flag_post = DW.FlagPost()
     post_filter = DW.PostFilter()
     moderate_posts = DW.ModeratePosts()
     # Other widgets


[14/50] allura git commit: [#8044] ticket:891 Add tool_name parameter to notification API, change API documentation

Posted by he...@apache.org.
[#8044] ticket:891 Add tool_name parameter to notification API, change API documentation


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

Branch: refs/heads/hs/8035
Commit: 1ec256c5033618836b96719b43d59817cd27e084
Parents: 62cbf93
Author: Denis Kotov <de...@gmail.com>
Authored: Sat Jan 23 19:26:48 2016 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:37:38 2016 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/rest.py           |  3 ++-
 Allura/allura/lib/plugin.py                 |  9 +++++----
 Allura/allura/tests/functional/test_rest.py |  7 ++++---
 Allura/docs/api-rest/api.raml               | 24 +++++++++++++++---------
 4 files changed, 26 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/1ec256c5/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index 70a9ffd..915517c 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -90,12 +90,13 @@ class RestController(object):
         return summary
 
     @expose('json:')
-    def notification(self, cookie='', url='', **kw):
+    def notification(self, cookie='', url='', tool_name='', **kw):
         c.api_token = self._authenticate_request()
         user = c.api_token.user if c.api_token else c.user
         r = g.theme._get_site_notification(
             url=url,
             user=user,
+            tool_name=tool_name,
             site_notification_cookie_value=cookie
         )
         if r:

http://git-wip-us.apache.org/repos/asf/allura/blob/1ec256c5/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index dffd1fa..e76c53c 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -1310,12 +1310,12 @@ class ThemeProvider(object):
         else:
             return app.icon_url(size)
 
-    def _get_site_notification(self, url='', user=None, site_notification_cookie_value=''):
+    def _get_site_notification(self, url='', user=None, tool_name='', site_notification_cookie_value=''):
         from allura.model.notification import SiteNotification
         note = SiteNotification.current()
         if note is None:
             return None
-        if note.user_role and user.is_anonymous():
+        if note.user_role and (not user or user.is_anonymous()):
             return None
         if note.user_role:
             projects = user.my_projects_by_role_name(note.user_role)
@@ -1324,7 +1324,7 @@ class ThemeProvider(object):
 
         if note.page_regex and re.search(note.page_regex, url) is None:
             return None
-        if note.page_tool_type and (c.app is None or c.app.config.tool_name.lower() != note.page_tool_type.lower()):
+        if note.page_tool_type and (c.app is None or tool_name.lower() != note.page_tool_type.lower()):
             return None
 
         cookie = site_notification_cookie_value.split('-')
@@ -1342,10 +1342,11 @@ class ThemeProvider(object):
 
     def get_site_notification(self):
         from pylons import request, response
-
+        tool_name = c.app.config.tool_name if c.app else ''
         r = self._get_site_notification(
             request.path_qs,
             c.user,
+            tool_name,
             request.cookies.get('site-notification', '')
         )
         if not r:

http://git-wip-us.apache.org/repos/asf/allura/blob/1ec256c5/Allura/allura/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py
index 3ec58f6..91cf40f 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -392,11 +392,12 @@ class TestRestHome(TestRestApiBase):
         cookie = '{}-1-False'.format(note._id)
         g.theme._get_site_notification = mock.Mock(return_value=(note, cookie))
 
-        r = self.app.get('/rest/notification?url=test_url&cookie=test_cookie')
+        r = self.app.get('/rest/notification?url=test_url&cookie=test_cookie&tool_name=test_tool')
         g.theme._get_site_notification.assert_called_once_with(
             url='test_url',
-            site_notification_cookie_value='test_cookie',
-            user=user
+            user=user,
+            tool_name='test_tool',
+            site_notification_cookie_value='test_cookie'
         )
 
         assert r.status_int == 200

http://git-wip-us.apache.org/repos/asf/allura/blob/1ec256c5/Allura/docs/api-rest/api.raml
----------------------------------------------------------------------
diff --git a/Allura/docs/api-rest/api.raml b/Allura/docs/api-rest/api.raml
index 6326978..9c50d9d 100755
--- a/Allura/docs/api-rest/api.raml
+++ b/Allura/docs/api-rest/api.raml
@@ -35,14 +35,6 @@ documentation:
   - title: API Overview
     content: !include docs.md
 
-/notification:
-  description: |
-    Get current Site Notification
-  uriParameters:
-    cookie:
-      description: site-notification cookie value
-      example: "56a111736c4ff90011b9f932-1-False"
-
 /{neighborhood}:
     description: |
       Neighborhoods are groups of logically related projects, which have the same default options.
@@ -743,4 +735,18 @@ documentation:
           example: !include examples/userProfile.json,
           schema: !include schemas/userProfile.json
         }
-      }
\ No newline at end of file
+      }
+
+/notification:
+  description: |
+    Get current Site Notification
+  uriParameters:
+    cookie:
+      description: site-notification cookie value
+      example: "56a111736c4ff90011b9f932-1-False"
+    url:
+      description: page where must be shown notification
+      example: "/p/test-project"
+    tool_name:
+      description: tool's name which used on page
+      exaple: "Git"
\ No newline at end of file


[03/50] allura git commit: [#8020] ticket:875 Replace hardcoded link to moderatation page

Posted by he...@apache.org.
[#8020] ticket:875 Replace hardcoded link to moderatation page


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

Branch: refs/heads/hs/8035
Commit: 8bdaa386880a3b991cbb2c360d85843e85ad2c1f
Parents: 0778b7a
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Dec 24 14:44:50 2015 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:03:18 2016 -0500

----------------------------------------------------------------------
 Allura/allura/templates/widgets/post_widget.html | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/8bdaa386/Allura/allura/templates/widgets/post_widget.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/post_widget.html b/Allura/allura/templates/widgets/post_widget.html
index 4d388ee..8c614d4 100644
--- a/Allura/allura/templates/widgets/post_widget.html
+++ b/Allura/allura/templates/widgets/post_widget.html
@@ -39,7 +39,8 @@
         {{lib.csrf_token()}}
       </form>
       <br>
-      <span class="spam-text">You can see all pending comments posted by this user&nbsp;</span><a href="/p/test/tickets/_discuss/moderate?username={{value.author().username}}&status=pending">here</a>
+      <span class="spam-text">You can see all pending comments posted by this user&nbsp;</span>
+      <a href="{{value.thread.discussion.url()}}moderate?username={{value.author().username}}&status=pending">here</a>
     </div>
     {% endif %}
     <div class="row">


[19/50] allura git commit: Return 404 instead of error, if accessing unavailable import_project url

Posted by he...@apache.org.
Return 404 instead of error, if accessing unavailable import_project url


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

Branch: refs/heads/hs/8035
Commit: c5b6ce55f5aaf86bb7f5e926c0ff4ab2986f3ea1
Parents: 14ccf22
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Jan 26 13:42:15 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 13:39:49 2016 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/project.py                | 3 +++
 Allura/allura/tests/functional/test_neighborhood.py | 8 ++++++++
 2 files changed, 11 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c5b6ce55/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 1742372..6e02609 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -1006,5 +1006,8 @@ class ProjectImporterController(object):
 
     @expose()
     def _lookup(self, source, *rest):
+        # iter_entry_points is a generator with 0 or 1 items, so a loop is the easiest way to handle
         for ep in iter_entry_points('allura.project_importers', source):
             return ep.load()(self.neighborhood), rest
+
+        raise exc.HTTPNotFound

http://git-wip-us.apache.org/repos/asf/allura/blob/c5b6ce55/Allura/allura/tests/functional/test_neighborhood.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_neighborhood.py b/Allura/allura/tests/functional/test_neighborhood.py
index b97a7c8..a7609df 100644
--- a/Allura/allura/tests/functional/test_neighborhood.py
+++ b/Allura/allura/tests/functional/test_neighborhood.py
@@ -1087,3 +1087,11 @@ class TestPhoneVerificationOnProjectRegistration(TestController):
             iframe = overlay.find('iframe')
             assert_equal(header.getText(), 'Phone Verification Required')
             assert_equal(iframe.get('src'), '/p/phone_verification_fragment')
+
+
+class TestProjectImport(TestController):
+
+    def test_not_found(self):
+        self.app.get('/p/import_project/asdf/', status=404)
+
+    # positive tests exist within ForgeImporter package


[20/50] allura git commit: [#8054] remove a docstring Google Code reference

Posted by he...@apache.org.
[#8054] remove a docstring Google Code reference


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

Branch: refs/heads/hs/8035
Commit: eabfc16b1a5f5d728c16da2b054f80f4d23c3b8a
Parents: d4dda57
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Jan 27 13:34:47 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 13:42:50 2016 -0500

----------------------------------------------------------------------
 ForgeImporters/forgeimporters/base.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/eabfc16b/ForgeImporters/forgeimporters/base.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/base.py b/ForgeImporters/forgeimporters/base.py
index 25399ea..32be2bd 100644
--- a/ForgeImporters/forgeimporters/base.py
+++ b/ForgeImporters/forgeimporters/base.py
@@ -420,7 +420,7 @@ class ToolImporter(object):
        `source` value of the :class:`ProjectImporter` for this importer to
        be discovered during full-project imports.  E.g.::
 
-            source = 'Google Code'
+            source = 'GitHub'
 
     .. py:attribute:: controller
 


[11/50] allura git commit: [#8044] ticket:889 Add kwargs to notification api

Posted by he...@apache.org.
[#8044] ticket:889 Add kwargs to notification api


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

Branch: refs/heads/hs/8035
Commit: 192010517ff09417ff38adabf51e8b1bf60399a9
Parents: e8e7b93
Author: Denis Kotov <de...@gmail.com>
Authored: Wed Jan 20 12:27:56 2016 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:37:37 2016 -0500

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


http://git-wip-us.apache.org/repos/asf/allura/blob/19201051/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index c091874..83c67f8 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -90,7 +90,7 @@ class RestController(object):
         return summary
 
     @expose('json:')
-    def notification(self, cookie=None):
+    def notification(self, cookie=None, **kw):
         c.api_token = self._authenticate_request()
         if c.api_token:
             c.user = c.api_token.user


[16/50] allura git commit: [#8044] ticket:889 Move main logic in _get_site_notification

Posted by he...@apache.org.
[#8044] ticket:889 Move main logic in _get_site_notification


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

Branch: refs/heads/hs/8035
Commit: e73efd1df38e555697c9da6df327f71b7b646d7e
Parents: 1920105
Author: Denis Kotov <de...@gmail.com>
Authored: Fri Jan 22 01:08:18 2016 +0200
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jan 27 12:37:38 2016 -0500

----------------------------------------------------------------------
 Allura/allura/controllers/rest.py           | 12 +++++++---
 Allura/allura/lib/plugin.py                 | 29 +++++++++++++++---------
 Allura/allura/tests/functional/test_rest.py |  7 +++---
 Allura/allura/tests/test_plugin.py          |  9 ++++----
 4 files changed, 35 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/e73efd1d/Allura/allura/controllers/rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/rest.py b/Allura/allura/controllers/rest.py
index 83c67f8..ef09398 100644
--- a/Allura/allura/controllers/rest.py
+++ b/Allura/allura/controllers/rest.py
@@ -90,11 +90,17 @@ class RestController(object):
         return summary
 
     @expose('json:')
-    def notification(self, cookie=None, **kw):
+    def notification(self, cookie='', **kw):
         c.api_token = self._authenticate_request()
         if c.api_token:
-            c.user = c.api_token.user
-        r = g.theme.get_site_notification(is_api=True, api_cookie=cookie)
+            r = g.theme._get_site_notification(
+                user=c.api_token.user,
+                site_notification_cookie_value=cookie
+            )
+        else:
+            r = g.theme._get_site_notification(
+                site_notification_cookie_value=cookie
+            )
         if r:
             return dict(notification=r[0], cookie=r[1])
         return {}

http://git-wip-us.apache.org/repos/asf/allura/blob/e73efd1d/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index e1653d9..6ae6eb0 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -1310,16 +1310,16 @@ class ThemeProvider(object):
         else:
             return app.icon_url(size)
 
-    def get_site_notification(self, is_api=None, api_cookie=None):
-        from pylons import request, response
+    def _get_site_notification(self, user=None, site_notification_cookie_value=''):
+        from pylons import request
         from allura.model.notification import SiteNotification
         note = SiteNotification.current()
         if note is None:
             return None
-        if note.user_role and c.user.is_anonymous():
+        if note.user_role and (not user or user.is_anonymous()):
             return None
         if note.user_role:
-            projects = c.user.my_projects_by_role_name(note.user_role)
+            projects = user.my_projects_by_role_name(note.user_role)
             if len(projects) == 0 or len(projects) == 1 and projects[0].is_user_project:
                 return None
 
@@ -1328,11 +1328,7 @@ class ThemeProvider(object):
         if note.page_tool_type and (c.app is None or c.app.config.tool_name.lower() != note.page_tool_type.lower()):
             return None
 
-        cookie = api_cookie
-        if not cookie:
-            cookie = request.cookies.get('site-notification', '')
-        cookie = cookie.split('-')
-
+        cookie = site_notification_cookie_value.split('-')
         if len(cookie) == 3 and cookie[0] == str(note._id):
             views = asint(cookie[1]) + 1
             closed = asbool(cookie[2])
@@ -1343,8 +1339,19 @@ class ThemeProvider(object):
             return None
 
         set_cookie = '-'.join(map(str, [note._id, views, closed]))
-        if is_api:
-            return note, set_cookie
+        return note, set_cookie
+
+    def get_site_notification(self):
+        from pylons import request, response
+
+        r = self._get_site_notification(
+            c.user,
+            request.cookies.get('site-notification', '')
+        )
+        if not r:
+            return None
+        note, set_cookie = r
+
         response.set_cookie(
             'site-notification',
             set_cookie,

http://git-wip-us.apache.org/repos/asf/allura/blob/e73efd1d/Allura/allura/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_rest.py b/Allura/allura/tests/functional/test_rest.py
index 6f95c05..0ff0526 100644
--- a/Allura/allura/tests/functional/test_rest.py
+++ b/Allura/allura/tests/functional/test_rest.py
@@ -385,15 +385,16 @@ class TestRestHome(TestRestApiBase):
         self.app.post('/rest/p/test/wiki/NewPage', headers={'Origin': 'http://bad.com/'},
                       status=401)
 
-    @mock.patch('allura.lib.plugin.ThemeProvider.get_site_notification')
-    def test_notification(self, get_site_notification):
+    @mock.patch('allura.lib.plugin.ThemeProvider._get_site_notification')
+    def test_notification(self, _get_site_notification):
         note = M.SiteNotification()
         cookie = '{}-1-False'.format(note._id)
-        g.theme.get_site_notification = mock.Mock(return_value=(note, cookie))
+        g.theme._get_site_notification = mock.Mock(return_value=(note, cookie))
 
         r = self.app.get('/rest/notification')
 
         assert r.status_int == 200
+        print r.json
         assert r.json['cookie'] == cookie
         assert r.json['notification'] == note.__json__()
 

http://git-wip-us.apache.org/repos/asf/allura/blob/e73efd1d/Allura/allura/tests/test_plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_plugin.py b/Allura/allura/tests/test_plugin.py
index 4f65c23..1cbd686 100644
--- a/Allura/allura/tests/test_plugin.py
+++ b/Allura/allura/tests/test_plugin.py
@@ -490,13 +490,13 @@ class TestThemeProvider(object):
         assert_is(ThemeProvider().get_site_notification(), None)
 
     @patch('allura.model.notification.SiteNotification')
-    def test_get_site_notification_with_is_api(self, SiteNotification):
+    def test_get__site_notification(self, SiteNotification):
         note = SiteNotification.current.return_value
         note._id = 'test_id'
         note.user_role = None
         note.page_regex = None
         note.page_tool_type = None
-        get_note = ThemeProvider().get_site_notification(is_api=True)
+        get_note = ThemeProvider()._get_site_notification()
 
         assert isinstance(get_note, tuple)
         assert len(get_note) is 2
@@ -512,9 +512,8 @@ class TestThemeProvider(object):
         note.page_regex = None
         note.page_tool_type = None
         request.cookies = {}
-        get_note = ThemeProvider().get_site_notification(
-            is_api=True,
-            api_cookie='test_id-1-False'
+        get_note = ThemeProvider()._get_site_notification(
+            site_notification_cookie_value='test_id-1-False'
         )
 
         assert get_note[0] is note


[50/50] allura git commit: [#8035] Remove unused .eslintrc

Posted by he...@apache.org.
[#8035] Remove unused .eslintrc


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

Branch: refs/heads/hs/8035
Commit: c563deb3598b7720bac9c0f8d454282c4e15ce61
Parents: d474150
Author: Heith Seewald <he...@gmail.com>
Authored: Tue Jan 26 14:10:23 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:33 2016 -0500

----------------------------------------------------------------------
 .eslintrc | 39 ---------------------------------------
 1 file changed, 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c563deb3/.eslintrc
----------------------------------------------------------------------
diff --git a/.eslintrc b/.eslintrc
deleted file mode 100644
index 455b95a..0000000
--- a/.eslintrc
+++ /dev/null
@@ -1,39 +0,0 @@
-{
-  "rules": {
-    "max-len": [1, 119, 4],
-    "indent": [2, 4],
-    "jsx-quotes": [0],
-    "quotes": [0],
-    "operator-linebreak": [2, "before", { "overrides": { "?": "after", "&&": "after" } }],
-    "require-jsdoc": [2, {"require": {
-        "FunctionDeclaration": true,
-        "MethodDefinition": false,
-        "ClassDeclaration": false
-      }
-    }],
-    "no-inline-comments": 0,
-    "comma-dangle": 0
-  },
-  "globals": {
-    "ReactDOM": true,
-    "React": true,
-    "$": true,
-    "window": true,
-    "_": true,
-    "ReactReorderable": true
-  },
-  "parser": "babel-eslint",
-  "env": {
-    "es6": true,
-    "browser": true
-  },
-  "extends": "google",
-  "ecmaFeatures": {
-    "jsx": true,
-    "forOf": true,
-    "experimentalObjectRestSpread": true
-  },
-  "plugins": [
-    "react"
-  ]
-}
\ No newline at end of file


[32/50] allura git commit: [#8035] ESLINT FIX: space-infix-ops

Posted by he...@apache.org.
[#8035] ESLINT FIX: space-infix-ops


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

Branch: refs/heads/hs/8035
Commit: 29d313d350c5a9a9e8223739ba6be100aa50077e
Parents: c2e894c
Author: Heith Seewald <he...@gmail.com>
Authored: Thu Jan 21 18:34:22 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:29 2016 -0500

----------------------------------------------------------------------
 Allura/allura/public/nf/js/navbar.es6.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/29d313d3/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index 818bb3e..a7266ae 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -286,7 +286,7 @@ var AdminNav = React.createClass({
         onOptionClick: React.PropTypes.func.isRequired
     },
 
-    buildMenu: function(items, isSubMenu=false) {
+    buildMenu: function(items, isSubMenu = false) {
         var _this = this;
         var [tools, anchoredTools, endTools] = [[], [], []];
         var subMenu;


[46/50] allura git commit: [#8035] ESLINT FIX: no-unused-var (allow unused function params)

Posted by he...@apache.org.
[#8035] ESLINT FIX: no-unused-var  (allow unused function params)


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

Branch: refs/heads/hs/8035
Commit: d474150f4b79614757985dea5bc514eb5c52a5a9
Parents: b4f0ae4
Author: Heith Seewald <he...@gmail.com>
Authored: Tue Jan 26 14:09:18 2016 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Wed Jan 27 15:21:32 2016 -0500

----------------------------------------------------------------------
 .eslintrc-es6                                  | 10 +++-
 Allura/allura/public/nf/js/context-menu.es6.js | 20 ++++----
 Allura/allura/public/nf/js/navbar.es6.js       |  6 +--
 Allura/allura/public/nf/js/tooltip.es6.js      | 54 ++++++++++-----------
 4 files changed, 46 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/d474150f/.eslintrc-es6
----------------------------------------------------------------------
diff --git a/.eslintrc-es6 b/.eslintrc-es6
index 455b95a..b91ed8f 100644
--- a/.eslintrc-es6
+++ b/.eslintrc-es6
@@ -11,6 +11,10 @@
         "ClassDeclaration": false
       }
     }],
+    "no-unused-vars": [2, {
+      "vars": "local",
+      "args": "none"
+    }],
     "no-inline-comments": 0,
     "comma-dangle": 0
   },
@@ -22,15 +26,19 @@
     "_": true,
     "ReactReorderable": true
   },
-  "parser": "babel-eslint",
   "env": {
     "es6": true,
+    "jquery": true,
     "browser": true
   },
   "extends": "google",
   "ecmaFeatures": {
     "jsx": true,
     "forOf": true,
+    "blockBindings": true,
+    "arrowFunctions": true,
+    "classes": true,
+    "defaultParams": true,
     "experimentalObjectRestSpread": true
   },
   "plugins": [

http://git-wip-us.apache.org/repos/asf/allura/blob/d474150f/Allura/allura/public/nf/js/context-menu.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/context-menu.es6.js b/Allura/allura/public/nf/js/context-menu.es6.js
index 4c2958d..c03d699 100644
--- a/Allura/allura/public/nf/js/context-menu.es6.js
+++ b/Allura/allura/public/nf/js/context-menu.es6.js
@@ -24,16 +24,6 @@ class ContextMenu extends React.Component {
         super(props);
     }
 
-    static propTypes = {
-        classes: React.PropTypes.array,
-        items: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
-        onOptionClick: React.PropTypes.func.isRequired
-    };
-
-    static defaultProps = {
-        classes: []
-    };
-
     componentWillMount() {
         let _this = this;
         var mount_point;
@@ -78,4 +68,12 @@ class ContextMenu extends React.Component {
     }
 }
 
-module.exports(ContextMenu);
+ContextMenu.propTypes = {
+    classes: React.PropTypes.array,
+    items: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
+    onOptionClick: React.PropTypes.func.isRequired
+};
+
+ContextMenu.defaultProps = {
+    classes: []
+};

http://git-wip-us.apache.org/repos/asf/allura/blob/d474150f/Allura/allura/public/nf/js/navbar.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/navbar.es6.js b/Allura/allura/public/nf/js/navbar.es6.js
index f82ee97..d027602 100644
--- a/Allura/allura/public/nf/js/navbar.es6.js
+++ b/Allura/allura/public/nf/js/navbar.es6.js
@@ -17,13 +17,13 @@
        under the License.
 */
 /* eslint camelcase: 0 */
-/* exported Main */
+/* eslint no-unused-vars: [2, {"args": "none", "varsIgnorePattern": "Main"}] */
 'use strict';
 
 /**
 * Gets the current project url.
 * @param {boolean} rest - Return a "rest" version of the url.
-* @returns {string} - Project Url
+* @return {string} - Project Url
 */
 var _getProjectUrl = function(rest = true) {
     var nbhd;
@@ -584,5 +584,3 @@ var Main = React.createClass({
         );
     }
 });
-
-module.exports(Main);

http://git-wip-us.apache.org/repos/asf/allura/blob/d474150f/Allura/allura/public/nf/js/tooltip.es6.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/tooltip.es6.js b/Allura/allura/public/nf/js/tooltip.es6.js
index f24fc16..b76a15c 100644
--- a/Allura/allura/public/nf/js/tooltip.es6.js
+++ b/Allura/allura/public/nf/js/tooltip.es6.js
@@ -16,8 +16,8 @@
        specific language governing permissions and limitations
        under the License.
 */
-'use strict';
 
+/* exported ToolTip */
 /**
  * React Tooltip (tooltipster) Base class
 
@@ -28,32 +28,6 @@ class ToolTip extends React.Component {
         super(props);
     }
 
-    static propTypes = {
-        targetSelector: React.PropTypes.string.isRequired,
-        animation: React.PropTypes.string,
-        speed: React.PropTypes.number,
-        position: React.PropTypes.string,
-        contentAsHTML: React.PropTypes.bool,
-        delay: React.PropTypes.number,
-        theme: React.PropTypes.string,
-        maxWidth: React.PropTypes.number,
-        trigger: React.PropTypes.string,
-        multiple: React.PropTypes.bool,
-    };
-
-    static defaultProps = {
-        animation: 'fade',
-        speed: 150,
-        delay: 0,
-        maxWidth: 300,
-        multiple: true,
-        contentAsHTML: false,
-        position: 'left',
-        trigger: 'hover',
-        classes: [],
-        theme: 'tooltipster-light'
-    };
-
     componentDidMount() {
         var _this = this;
         $(this.props.targetSelector).tooltipster({
@@ -75,5 +49,29 @@ class ToolTip extends React.Component {
     }
 }
 
-module.exports(ToolTip);
+ToolTip.propTypes = {
+    targetSelector: React.PropTypes.string.isRequired,
+    animation: React.PropTypes.string,
+    speed: React.PropTypes.number,
+    position: React.PropTypes.string,
+    contentAsHTML: React.PropTypes.bool,
+    delay: React.PropTypes.number,
+    theme: React.PropTypes.string,
+    maxWidth: React.PropTypes.number,
+    trigger: React.PropTypes.string,
+    multiple: React.PropTypes.bool,
+};
+
+ToolTip.defaultProps = {
+    animation: 'fade',
+    speed: 150,
+    delay: 0,
+    maxWidth: 300,
+    multiple: true,
+    contentAsHTML: false,
+    position: 'left',
+    trigger: 'hover',
+    classes: [],
+    theme: 'tooltipster-light'
+};
 


[22/50] allura git commit: [#8054] delete Google Code importers and tests

Posted by he...@apache.org.
http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/google/test_extractor.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_extractor.py b/ForgeImporters/forgeimporters/tests/google/test_extractor.py
deleted file mode 100644
index 72a7d6c..0000000
--- a/ForgeImporters/forgeimporters/tests/google/test_extractor.py
+++ /dev/null
@@ -1,607 +0,0 @@
-#       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 pkg_resources
-from urllib2 import HTTPError
-
-import mock
-from datadiff.tools import assert_equal
-from IPython.testing.decorators import skipif, module_not_available
-from BeautifulSoup import BeautifulSoup
-
-from allura.tests.decorators import without_module
-from forgeimporters import google
-from forgeimporters import base
-
-
-class TestGoogleCodeProjectExtractor(TestCase):
-
-    def setUp(self):
-        self._p_urlopen = mock.patch.object(base.ProjectExtractor, 'urlopen')
-        self._p_soup = mock.patch.object(base, 'BeautifulSoup')
-        self.urlopen = self._p_urlopen.start()
-        self.soup = self._p_soup.start()
-        self.project = mock.Mock(name='project')
-        self.project.get_tool_data.return_value = 'my-project'
-
-    def tearDown(self):
-        for patcher in ('_p_urlopen', '_p_soup'):
-            try:
-                getattr(self, patcher).stop()
-            except RuntimeError as e:
-                if 'unstarted patcher' in str(e):
-                    pass  # test case might stop them early
-                else:
-                    raise
-
-    def test_init(self):
-        extractor = google.GoogleCodeProjectExtractor(
-            'my-project', 'project_info')
-
-        self.urlopen.assert_called_once_with(
-            'http://code.google.com/p/my-project/')
-        self.soup.assert_called_once_with(self.urlopen.return_value, convertEntities=self.soup.HTML_ENTITIES)
-        self.assertEqual(extractor.page, self.soup.return_value)
-
-    def test_get_page(self):
-        extractor = google.GoogleCodeProjectExtractor(
-            'my-project', 'project_info')
-        self.assertEqual(1, self.urlopen.call_count)
-        page = extractor.get_page('project_info')
-        self.assertEqual(1, self.urlopen.call_count)
-        self.assertEqual(
-            page, extractor._page_cache['http://code.google.com/p/my-project/'])
-        page = extractor.get_page('project_info')
-        self.assertEqual(1, self.urlopen.call_count)
-        self.assertEqual(
-            page, extractor._page_cache['http://code.google.com/p/my-project/'])
-        page = extractor.get_page('source_browse')
-        self.assertEqual(2, self.urlopen.call_count)
-        self.assertEqual(
-            page, extractor._page_cache['http://code.google.com/p/my-project/source/browse/'])
-        parser = mock.Mock(return_value='parsed')
-        page = extractor.get_page('url', parser=parser)
-        self.assertEqual(page, 'parsed')
-        self.assertEqual(page, extractor._page_cache['url'])
-
-    def test_get_page_url(self):
-        extractor = google.GoogleCodeProjectExtractor('my-project')
-        self.assertEqual(extractor.get_page_url('project_info'),
-                         'http://code.google.com/p/my-project/')
-
-    def test_get_page_url_hosted(self):
-        extractor = google.GoogleCodeProjectExtractor('a/eclipselabs.org/p/restclient-tool')
-        self.assertEqual(extractor.get_page_url('project_info'),
-                         'http://code.google.com/a/eclipselabs.org/p/restclient-tool/')
-
-    def test_get_short_description(self):
-        extractor = google.GoogleCodeProjectExtractor(
-            'my-project', 'project_info')
-        extractor.page.find.return_value.text = 'My Super Project'
-
-        extractor.get_short_description(self.project)
-
-        extractor.page.find.assert_called_once_with(itemprop='description')
-        self.assertEqual(self.project.short_description, 'My Super Project')
-
-    @mock.patch.object(google, 'File')
-    @mock.patch.object(google, 'M')
-    def test_get_icon(self, M, File):
-        File.return_value.type = 'image/png'
-        File.return_value.file = 'data'
-        extractor = google.GoogleCodeProjectExtractor(
-            'my-project', 'project_info')
-        extractor.page.find.return_value.get.return_value = 'http://example.com/foo/bar/my-logo.png'
-
-        extractor.get_icon(self.project)
-
-        extractor.page.find.assert_called_once_with(itemprop='image')
-        File.assert_called_once_with(
-            'http://example.com/foo/bar/my-logo.png', 'my-logo.png')
-        M.ProjectFile.save_image.assert_called_once_with(
-            'my-logo.png', 'data', 'image/png', square=True,
-            thumbnail_size=(48, 48), thumbnail_meta={
-                'project_id': self.project._id, 'category': 'icon'})
-
-    @mock.patch.object(google, 'M')
-    def test_get_license(self, M):
-        self.project.trove_license = []
-        extractor = google.GoogleCodeProjectExtractor(
-            'my-project', 'project_info')
-        extractor.page.find.return_value.findNext.return_value.find.return_value.text = '  New BSD License  '
-        trove = M.TroveCategory.query.get.return_value
-
-        extractor.get_license(self.project)
-
-        extractor.page.find.assert_called_once_with(text='Code license')
-        extractor.page.find.return_value.findNext.assert_called_once_with()
-        extractor.page.find.return_value.findNext.return_value.find.assert_called_once_with(
-            'a')
-        self.assertEqual(self.project.trove_license, [trove._id])
-        M.TroveCategory.query.get.assert_called_once_with(
-            fullname='BSD License')
-
-        M.TroveCategory.query.get.reset_mock()
-        extractor.page.find.return_value.findNext.return_value.find.return_value.text = 'non-existant license'
-        extractor.get_license(self.project)
-        M.TroveCategory.query.get.assert_called_once_with(
-            fullname='Other/Proprietary License')
-
-    def _make_extractor(self, html):
-        with mock.patch.object(base.ProjectExtractor, 'urlopen'):
-            extractor = google.GoogleCodeProjectExtractor('allura-google-importer')
-        extractor.page = BeautifulSoup(html)
-        extractor.get_page = lambda pagename: extractor.page
-        extractor.url = "http://test/source/browse"
-        return extractor
-
-    def test_get_repo_type_happy_path(self):
-        extractor = self._make_extractor(
-            '<span id="crumb_root">\nsvn/&nbsp;</span>')
-        self.assertEqual('svn', extractor.get_repo_type())
-
-    def test_get_repo_type_no_crumb_root(self):
-        extractor = self._make_extractor('')
-        with self.assertRaises(Exception) as cm:
-            extractor.get_repo_type()
-        self.assertEqual(str(cm.exception),
-                         "Couldn't detect repo type: no #crumb_root in "
-                         "http://test/source/browse")
-
-    def test_get_repo_type_unknown_repo_type(self):
-        extractor = self._make_extractor(
-            '<span id="crumb_root">cvs</span>')
-        with self.assertRaises(Exception) as cm:
-            extractor.get_repo_type()
-        self.assertEqual(str(cm.exception), "Unknown repo type: cvs")
-
-    def test_empty_issue(self):
-        empty_issue = open(pkg_resources.resource_filename(
-            'forgeimporters', 'tests/data/google/empty-issue.html')).read()
-        gpe = self._make_extractor(empty_issue)
-        self.assertIsNone(gpe.get_issue_owner())
-        self.assertEqual(gpe.get_issue_status(), '')
-        self.assertEqual(gpe.get_issue_attachments(), [])
-        self.assertEqual(list(gpe.iter_comments()), [])
-        self.assertEqual(gpe.get_issue_mod_date(), 'Thu Aug  8 14:56:23 2013')
-
-    @without_module('html2text')
-    def test_get_issue_basic_fields(self):
-        test_issue = open(pkg_resources.resource_filename(
-            'forgeimporters', 'tests/data/google/test-issue.html')).read()
-        gpe = self._make_extractor(test_issue)
-
-        self.assertEqual(gpe.get_issue_creator().name, 'john...@gmail.com')
-        self.assertEqual(gpe.get_issue_creator().url,
-                         'http://code.google.com/u/101557263855536553789/')
-        self.assertEqual(gpe.get_issue_owner().name, 'john...@gmail.com')
-        self.assertEqual(gpe.get_issue_owner().url,
-                         'http://code.google.com/u/101557263855536553789/')
-        self.assertEqual(gpe.get_issue_status(), 'Started')
-        self._p_soup.stop()
-        self.assertEqual(gpe.get_issue_summary(), 'Test "Issue"')
-        assert_equal(gpe.get_issue_description(),
-                     'Test \\*Issue\\* for testing\n'
-                     '\n'
-                     '&nbsp; 1\\. Test List\n'
-                     '&nbsp; 2\\. Item\n'
-                     '\n'
-                     '\\*\\*Testing\\*\\*\n'
-                     '\n'
-                     ' \\* Test list 2\n'
-                     ' \\* Item\n'
-                     '\n'
-                     '\\# Test Section\n'
-                     '\n'
-                     '&nbsp;&nbsp;&nbsp; p = source\\.test\\_issue\\.post\\(\\)\n'
-                     '&nbsp;&nbsp;&nbsp; p\\.count = p\\.count \\*5 \\#\\* 6\n'
-                     '&nbsp;&nbsp;&nbsp; if p\\.count &gt; 5:\n'
-                     '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Not &lt; 5 &amp; \\!= 5"\n'
-                     '\n'
-                     'References: [issue 1](#1), [r2]\n'
-                     '\n'
-                     'That\'s all'
-                     )
-        self.assertEqual(gpe.get_issue_created_date(),
-                         'Thu Aug  8 15:33:52 2013')
-        self.assertEqual(gpe.get_issue_stars(), 1)
-
-    @skipif(module_not_available('html2text'))
-    def test_get_issue_basic_fields_html2text(self):
-        test_issue = open(pkg_resources.resource_filename(
-            'forgeimporters', 'tests/data/google/test-issue.html')).read()
-        gpe = self._make_extractor(test_issue)
-        self.assertEqual(gpe.get_issue_creator().name, 'john...@gmail.com')
-        self.assertEqual(gpe.get_issue_creator().url,
-                         'http://code.google.com/u/101557263855536553789/')
-        self.assertEqual(gpe.get_issue_owner().name, 'john...@gmail.com')
-        self.assertEqual(gpe.get_issue_owner().url,
-                         'http://code.google.com/u/101557263855536553789/')
-        self.assertEqual(gpe.get_issue_status(), 'Started')
-        self._p_soup.stop()
-        self.assertEqual(gpe.get_issue_summary(), 'Test "Issue"')
-        assert_equal(gpe.get_issue_description(),
-                     'Test \\*Issue\\* for testing\n'
-                     '\n'
-                     '&nbsp; 1. Test List\n'
-                     '&nbsp; 2. Item\n'
-                     '\n'
-                     '\\*\\*Testing\\*\\*\n'
-                     '\n'
-                     ' \\* Test list 2\n'
-                     ' \\* Item\n'
-                     '\n'
-                     '\\# Test Section\n'
-                     '\n'
-                     '&nbsp;&nbsp;&nbsp; p = source.test\\_issue.post\\(\\)\n'
-                     '&nbsp;&nbsp;&nbsp; p.count = p.count \\*5 \\#\\* 6\n'
-                     '&nbsp;&nbsp;&nbsp; if p.count &gt; 5:\n'
-                     '&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Not &lt; 5 &amp; \\!= 5"\n'
-                     '\n'
-                     'References: [issue 1](#1), [r2]\n'
-                     '\n'
-                     'That\'s all'
-                     )
-        self.assertEqual(gpe.get_issue_created_date(),
-                         'Thu Aug  8 15:33:52 2013')
-        self.assertEqual(gpe.get_issue_stars(), 1)
-
-    def test_get_issue_summary(self):
-        html = u"""
-        <div id="issueheader">
-            <table>
-                <tbody>
-                    <tr>
-                        <td></td>
-                        <td><span>%s</span></td>
-                    </tr>
-                </tbody>
-            </table>
-        </div>
-        """
-        gpe = self._make_extractor(html % u'')
-        self.assertEqual(gpe.get_issue_summary(), u'')
-        gpe = self._make_extractor(html % u'My Summary')
-        self.assertEqual(gpe.get_issue_summary(), u'My Summary')
-
-    def test_get_issue_labels(self):
-        test_issue = open(pkg_resources.resource_filename(
-            'forgeimporters', 'tests/data/google/test-issue.html')).read()
-        gpe = self._make_extractor(test_issue)
-        self.assertEqual(gpe.get_issue_labels(), [
-            'Type-Defect',
-            'Priority-Medium',
-            'Milestone-Release1.0',
-            'OpSys-All',
-            'Component-Logic',
-            'Performance',
-            'Security',
-            'OpSys-Windows',
-            'OpSys-OSX',
-        ])
-
-    @mock.patch.object(base, 'StringIO')
-    def test_get_issue_attachments(self, StringIO):
-        self.urlopen.return_value.info.return_value = {
-            'content-type': 'text/plain; foo'}
-        test_issue = open(pkg_resources.resource_filename(
-            'forgeimporters', 'tests/data/google/test-issue.html')).read()
-        gpe = self._make_extractor(test_issue)
-        attachments = gpe.get_issue_attachments()
-        self.assertEqual(len(attachments), 1)
-        self.assertEqual(attachments[0].filename, 'at1.txt')
-        self.assertEqual(attachments[0].url,
-                         'http://allura-google-importer.googlecode.com/issues/attachment?aid=70000000&name=at1.txt'
-                         '&token=3REU1M3JUUMt0rJUg7ldcELt6LA%3A1376059941255')
-        self.assertEqual(attachments[0].type, 'text/plain')
-
-    def test_get_issue_ids(self):
-        extractor = google.GoogleCodeProjectExtractor(None)
-        extractor.get_page = mock.Mock(side_effect=((1, 2, 3), (2, 3, 4), ()))
-        self.assertItemsEqual(extractor.get_issue_ids(start=10), (1, 2, 3, 4))
-        self.assertEqual(extractor.get_page.call_count, 3)
-        extractor.get_page.assert_has_calls([
-            mock.call('issues_csv', parser=google.csv_parser, start=10),
-            mock.call('issues_csv', parser=google.csv_parser, start=110),
-            mock.call('issues_csv', parser=google.csv_parser, start=210),
-        ])
-
-    @mock.patch.object(google.GoogleCodeProjectExtractor, 'get_page')
-    @mock.patch.object(google.GoogleCodeProjectExtractor, 'get_issue_ids')
-    def test_iter_issue_ids(self, get_issue_ids, get_page):
-        get_issue_ids.side_effect = [set([1, 2]), set([2, 3, 4])]
-        issue_ids = [i for i,
-                     e in list(google.GoogleCodeProjectExtractor.iter_issues('foo'))]
-        self.assertEqual(issue_ids, [1, 2, 3, 4])
-        get_issue_ids.assert_has_calls([
-            mock.call(start=0),
-            mock.call(start=-8),
-        ])
-
-    @mock.patch.object(google.GoogleCodeProjectExtractor, '__init__')
-    @mock.patch.object(google.GoogleCodeProjectExtractor, 'get_issue_ids')
-    def test_iter_issue_ids_raises(self, get_issue_ids, __init__):
-        get_issue_ids.side_effect = [set([1, 2, 3, 4, 5])]
-        __init__.side_effect = [
-            None,
-            None,
-            # should skip but keep going
-            HTTPError('fourohfour', 404, 'fourohfour', {}, mock.Mock()),
-            None,
-            # should be re-raised
-            HTTPError('fubar', 500, 'fubar', {}, mock.Mock()),
-            None,
-        ]
-        issue_ids = []
-        try:
-            for issue_id, extractor in google.GoogleCodeProjectExtractor.iter_issues('foo'):
-                issue_ids.append(issue_id)
-        except HTTPError as e:
-            self.assertEqual(e.code, 500)
-        else:
-            assert False, 'Missing expected raised exception'
-        self.assertEqual(issue_ids, [1, 3])
-
-    @mock.patch.object(google.requests, 'head')
-    def test_check_readable(self, head):
-        head.return_value.status_code = 200
-        assert google.GoogleCodeProjectExtractor('my-project').check_readable()
-        head.return_value.status_code = 404
-        assert not google.GoogleCodeProjectExtractor('my-project').check_readable()
-
-
-class TestWithSetupForComments(TestCase):
-    # The main test suite did too much patching for how we want these tests to work
-    # These tests use iter_comments and 2 HTML pages of comments.
-
-    def _create_extractor(self):
-        test_issue = open(pkg_resources.resource_filename(
-            'forgeimporters', 'tests/data/google/test-issue-first-page.html')).read()
-        test_issue_older = open(pkg_resources.resource_filename(
-            'forgeimporters', 'tests/data/google/test-issue-prev-page.html')).read()
-
-        class LocalTestExtractor(google.GoogleCodeProjectExtractor):
-            def urlopen(self, url, **kw):
-                return self.urlopen_results.pop(0)
-
-            def setup_urlopen_results(self, results):
-                self.urlopen_results = results
-
-        gpe = LocalTestExtractor('allura-google-importer')
-        gpe.setup_urlopen_results([test_issue, test_issue_older])
-
-        return gpe
-
-    def test_get_issue_mod_date(self):
-        gpe = self._create_extractor()
-        gpe.get_page('detail?id=6')
-        self.assertEqual(gpe.get_issue_mod_date(), 'Thu Aug  8 15:36:57 2013')
-
-    @without_module('html2text')
-    @mock.patch.object(base, 'StringIO')
-    def test_iter_comments(self, StringIO):
-        gpe = self._create_extractor()
-        gpe.get_page('detail?id=6')
-
-        with mock.patch.object(base.ProjectExtractor, 'urlopen'):  # for attachments, which end up using a different Extractor urlopen
-            comments = list(gpe.iter_comments())
-
-        self.assertEqual(len(comments), 6)
-        expected = [
-            {
-                'author.name': 'john...@gmail.com',
-                'author.url': 'http://code.google.com/u/101557263855536553789/',
-                'created_date': 'Thu Aug  8 15:34:01 2013',
-                'body': 'Simple comment',
-                'updates': {},
-                'attachments': [],
-            },
-            {
-                'author.name': 'john...@gmail.com',
-                'author.url': 'http://code.google.com/u/101557263855536553789/',
-                'created_date': 'Thu Aug  8 15:34:09 2013',
-                'body': 'Boring comment',
-                'updates': {},
-                'attachments': [],
-            },
-            {
-                'author.name': 'john...@gmail.com',
-                'author.url': 'http://code.google.com/u/101557263855536553789/',
-                'created_date': 'Thu Aug  8 15:35:15 2013',
-                'body': 'Test \\*comment\\* is a comment',
-                'updates': {'Status:': 'Started', 'Labels:': '-OpSys-Linux OpSys-Windows'},
-                'attachments': ['at2.txt'],
-            },
-            {
-                'author.name': 'john...@gmail.com',
-                'author.url': 'http://code.google.com/u/101557263855536553789/',
-                'created_date': 'Thu Aug  8 15:35:34 2013',
-                'body': 'Another comment with references: [issue 2](#2), [r1]',
-                'updates': {},
-                'attachments': [],
-            },
-            {
-                'author.name': 'john...@gmail.com',
-                'author.url': 'http://code.google.com/u/101557263855536553789/',
-                'created_date': 'Thu Aug  8 15:36:39 2013',
-                'body': 'Last comment',
-                'updates': {},
-                'attachments': ['at4.txt', 'at1.txt'],
-            },
-            {
-                'author.name': 'john...@gmail.com',
-                'author.url': 'http://code.google.com/u/101557263855536553789/',
-                'created_date': 'Thu Aug  8 15:36:57 2013',
-                'body': 'Oh, I forgot one \\(with an inter\\-project reference to '
-                        '[issue other\\-project:1](https://code.google.com/p/other-project/issues/detail?id=1)\\)',
-                'updates': {'Labels:': 'OpSys-OSX'},
-                'attachments': [],
-            },
-        ]
-        for actual, expected in zip(comments, expected):
-            self.assertEqual(actual.author.name, expected['author.name'])
-            self.assertEqual(actual.author.url, expected['author.url'])
-            self.assertEqual(actual.created_date, expected['created_date'])
-            self.assertEqual(actual.body, expected['body'])
-            self.assertEqual(actual.updates, expected['updates'])
-            self.assertEqual(
-                [a.filename for a in actual.attachments], expected['attachments'])
-
-    @skipif(module_not_available('html2text'))
-    @mock.patch.object(base, 'StringIO')
-    def test_iter_comments_html2text(self, StringIO):
-        gpe = self._create_extractor()
-        gpe.get_page('detail?id=6')
-
-        with mock.patch.object(base.ProjectExtractor, 'urlopen'):  # for attachments, which end up using a different Extractor urlopen
-            comments = list(gpe.iter_comments())
-
-        self.assertEqual(len(comments), 6)
-        expected = [
-            {
-                'author.name': 'john...@gmail.com',
-                'author.url': 'http://code.google.com/u/101557263855536553789/',
-                'created_date': 'Thu Aug  8 15:34:01 2013',
-                'body': 'Simple comment',
-                'updates': {},
-                'attachments': [],
-            },
-            {
-                'author.name': 'john...@gmail.com',
-                'author.url': 'http://code.google.com/u/101557263855536553789/',
-                'created_date': 'Thu Aug  8 15:34:09 2013',
-                'body': 'Boring comment',
-                'updates': {},
-                'attachments': [],
-            },
-            {
-                'author.name': 'john...@gmail.com',
-                'author.url': 'http://code.google.com/u/101557263855536553789/',
-                'created_date': 'Thu Aug  8 15:35:15 2013',
-                'body': 'Test \\*comment\\* is a comment',
-                'updates': {'Status:': 'Started', 'Labels:': '-OpSys-Linux OpSys-Windows'},
-                'attachments': ['at2.txt'],
-            },
-            {
-                'author.name': 'john...@gmail.com',
-                'author.url': 'http://code.google.com/u/101557263855536553789/',
-                'created_date': 'Thu Aug  8 15:35:34 2013',
-                'body': 'Another comment with references: [issue 2](#2), [r1]',
-                'updates': {},
-                'attachments': [],
-            },
-            {
-                'author.name': 'john...@gmail.com',
-                'author.url': 'http://code.google.com/u/101557263855536553789/',
-                'created_date': 'Thu Aug  8 15:36:39 2013',
-                'body': 'Last comment',
-                'updates': {},
-                'attachments': ['at4.txt', 'at1.txt'],
-            },
-            {
-                'author.name': 'john...@gmail.com',
-                'author.url': 'http://code.google.com/u/101557263855536553789/',
-                'created_date': 'Thu Aug  8 15:36:57 2013',
-                'body': 'Oh, I forgot one \\(with an inter-project reference to '
-                        '[issue other-project:1](https://code.google.com/p/other-project/issues/detail?id=1)\\)',
-                'updates': {'Labels:': 'OpSys-OSX'},
-                'attachments': [],
-            },
-        ]
-        for actual, expected in zip(comments, expected):
-            self.assertEqual(actual.author.name, expected['author.name'])
-            self.assertEqual(actual.author.url, expected['author.url'])
-            self.assertEqual(actual.created_date, expected['created_date'])
-            self.assertEqual(actual.body, expected['body'])
-            self.assertEqual(actual.updates, expected['updates'])
-            self.assertEqual(
-                [a.filename for a in actual.attachments], expected['attachments'])
-
-
-class TestUserLink(TestCase):
-
-    def test_plain(self):
-        tag = mock.Mock()
-        tag.text.strip.return_value = 'name'
-        tag.get.return_value = None
-        link = google.UserLink(tag)
-        self.assertEqual(str(link), 'name')
-
-    def test_linked(self):
-        tag = mock.Mock()
-        tag.text.strip.return_value = 'name'
-        tag.get.return_value = '/p/project'
-        link = google.UserLink(tag)
-        self.assertEqual(str(link), '[name](http://code.google.com/p/project)')
-
-
-class TestComment(TestCase):
-    html = """
-    <div class="cursor_off vt issuecomment" id="hc2">
-     <div style="float:right; margin-right:.3em; text-align:right">
-     <span class="date" title="Tue Jun 25 03:20:09 2013">
-     Jun 25, 2013
-     </span>
-     </div>
-     <span class="author">
-     <span class="role_label">Project Member</span>
-     <a name="c2" href="/p/pychess/issues/detail?id=267#c2">#2</a>
-     <a class="userlink" href="/u/gbtami/">gbtami</a></span>
-    <pre><i>(No comment was entered for this change.)</i>
-    </pre>
-     <div class="updates">
-     <div class="round4"></div>
-     <div class="round2"></div>
-     <div class="round1"></div>
-     <div class="box-inner">
-     <b>Summary:</b>
-     Make PyChess keyboard accessible
-     <span class="oldvalue">
-     (was: Make PyChess keyboard accecible)
-     </span>
-     <br>
-     <b>Status:</b>
-     Accepted
-     <br>
-     </div>
-     <div class="round1"></div>
-     <div class="round2"></div>
-     <div class="round4"></div>
-     </div>
-    </div>
-    """
-
-    def test_init(self):
-        from BeautifulSoup import BeautifulSoup
-        html = BeautifulSoup(self.html)
-        comment = google.Comment(html.find('div', 'issuecomment'), 'pychess')
-        self.assertEqual(comment.updates, {
-            u'Summary:': u'Make PyChess keyboard accessible',
-            u'Status:': u'Accepted',
-        })
-
-
-class TestAsMarkdown(TestCase):
-
-    def soup(self, tag):
-        return BeautifulSoup(u'<pre>%s</pre>' % tag).first()
-
-    def test_unicode(self):
-        tag = self.soup(u'\ua000 foo <a href="http://example.com/">bar</a>')
-        res = google._as_markdown(tag, 'pn')
-        self.assertEqual(res, u'\ua000 foo [bar](http://example.com/)')

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/google/test_tasks.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_tasks.py b/ForgeImporters/forgeimporters/tests/google/test_tasks.py
deleted file mode 100644
index 01bab68..0000000
--- a/ForgeImporters/forgeimporters/tests/google/test_tasks.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#       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 mock
-
-from ...google import tasks
-
-
-@mock.patch.object(tasks, 'GoogleCodeProjectExtractor')
-@mock.patch.object(tasks, 'ThreadLocalORMSession')
-@mock.patch.object(tasks, 'c')
-def test_import_project_info(c, session, gpe):
-    c.project = mock.Mock(name='project')
-    tasks.import_project_info('my-project')
-    gpe.assert_called_once_with('my-project', 'project_info')
-    gpe.return_value.get_short_description.assert_called_once_with(c.project)
-    gpe.return_value.get_icon.assert_called_once_with(c.project)
-    gpe.return_value.get_license.assert_called_once_with(c.project)
-    session.flush_all.assert_called_once_with()

http://git-wip-us.apache.org/repos/asf/allura/blob/b956fe30/ForgeImporters/forgeimporters/tests/google/test_tracker.py
----------------------------------------------------------------------
diff --git a/ForgeImporters/forgeimporters/tests/google/test_tracker.py b/ForgeImporters/forgeimporters/tests/google/test_tracker.py
deleted file mode 100644
index e8f12bb..0000000
--- a/ForgeImporters/forgeimporters/tests/google/test_tracker.py
+++ /dev/null
@@ -1,336 +0,0 @@
-#       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 datetime import datetime
-from unittest import TestCase
-
-import mock
-from mock import patch
-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.google import tracker
-
-
-class TestTrackerImporter(TestCase):
-
-    @mock.patch.object(tracker, 'g')
-    @mock.patch.object(tracker, 'c')
-    @mock.patch.object(tracker, 'ThreadLocalORMSession')
-    @mock.patch.object(tracker, 'session')
-    @mock.patch.object(tracker, 'M')
-    @mock.patch.object(tracker, 'TM')
-    @mock.patch.object(tracker, 'GoogleCodeProjectExtractor')
-    def test_import_tool(self, gpe, TM, M, session, tlos, c, g):
-        importer = tracker.GoogleCodeTrackerImporter()
-        importer.process_fields = mock.Mock()
-        importer.process_labels = mock.Mock()
-        importer.process_comments = mock.Mock()
-        importer.postprocess_custom_fields = 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': 'Google Code',
-            'project_name': 'project_name',
-        }
-        app.config.options.get = lambda *a: getattr(app.config.options, *a)
-        app.url = 'foo'
-        issues = gpe.iter_issues.return_value = [
-            (50, mock.Mock()), (100, mock.Mock())]
-        tickets = TM.Ticket.side_effect = [mock.Mock(), mock.Mock()]
-
-        importer.import_tool(project, user, project_name='project_name',
-                             mount_point='mount_point', mount_label='mount_label')
-
-        project.install_app.assert_called_once_with(
-            'tickets', 'mount_point', 'mount_label',
-            EnableVoting=True,
-            open_status_names='New Accepted Started',
-            closed_status_names='Fixed Verified Invalid Duplicate WontFix Done',
-            import_id={
-                'source': 'Google Code',
-                'project_name': 'project_name',
-            }
-        )
-        gpe.iter_issues.assert_called_once_with('project_name')
-        self.assertEqual(importer.process_fields.call_args_list, [
-            mock.call(tickets[0], issues[0][1]),
-            mock.call(tickets[1], issues[1][1]),
-        ])
-        self.assertEqual(importer.process_labels.call_args_list, [
-            mock.call(tickets[0], issues[0][1]),
-            mock.call(tickets[1], issues[1][1]),
-        ])
-        self.assertEqual(importer.process_comments.call_args_list, [
-            mock.call(tickets[0], issues[0][1]),
-            mock.call(tickets[1], issues[1][1]),
-        ])
-        self.assertEqual(tlos.flush_all.call_args_list, [
-            mock.call(),
-            mock.call(),
-        ])
-        self.assertEqual(session.return_value.flush.call_args_list, [
-            mock.call(tickets[0]),
-            mock.call(tickets[1]),
-        ])
-        self.assertEqual(session.return_value.expunge.call_args_list, [
-            mock.call(tickets[0]),
-            mock.call(tickets[1]),
-        ])
-        self.assertEqual(app.globals.last_ticket_num, 100)
-        M.AuditLog.log.assert_called_once_with(
-            'import tool mount_point from project_name on Google Code',
-            project=project, user=user, url='foo')
-        g.post_event.assert_called_once_with('project_updated')
-        app.globals.invalidate_bin_counts.assert_called_once_with()
-
-    @mock.patch.object(tracker, 'ThreadLocalORMSession')
-    @mock.patch.object(tracker, 'M')
-    @mock.patch.object(tracker, 'h')
-    def test_import_tool_failure(self, h, M, ThreadLocalORMSession):
-        h.push_config.side_effect = ValueError
-        project = mock.Mock()
-        user = mock.Mock()
-
-        importer = tracker.GoogleCodeTrackerImporter()
-        self.assertRaises(
-            ValueError, importer.import_tool, project, user, project_name='project_name',
-            mount_point='mount_point', mount_label='mount_label')
-
-        h.make_app_admin_only.assert_called_once_with(
-            project.install_app.return_value)
-
-    def test_custom_fields(self):
-        importer = tracker.GoogleCodeTrackerImporter()
-        importer.custom_fields = {}
-        importer.custom_field('Foo')
-        importer.custom_field('Milestone')
-        importer.custom_field('Priority')
-        importer.custom_field('Type')
-        self.assertEqual(importer.custom_fields, {
-            'Foo': {
-                'type': 'string',
-                'label': 'Foo',
-                'name': '_foo',
-                'options': set(),
-            },
-            'Milestone': {
-                'type': 'milestone',
-                'label': 'Milestone',
-                'name': '_milestone',
-                'options': set(),
-            },
-            'Priority': {
-                'type': 'select',
-                'label': 'Priority',
-                'name': '_priority',
-                'options': set(),
-            },
-            'Type': {
-                'type': 'select',
-                'label': 'Type',
-                'name': '_type',
-                'options': set(),
-            },
-        })
-        importer.custom_fields = {'Foo': {}}
-        importer.custom_field('Foo')
-        self.assertEqual(importer.custom_fields, {'Foo': {}})
-
-    def test_process_fields(self):
-        ticket = mock.Mock()
-        issue = mock.Mock(
-            get_issue_summary=lambda: 'summary',
-            get_issue_description=lambda: 'my *description* fool',
-            get_issue_status=lambda: 'status',
-            get_issue_created_date=lambda: 'created_date',
-            get_issue_mod_date=lambda: 'mod_date',
-            get_issue_creator=lambda: 'creator',
-            get_issue_owner=lambda: 'owner',
-        )
-        importer = tracker.GoogleCodeTrackerImporter()
-        with mock.patch.object(tracker, 'dateutil') as dt:
-            dt.parser.parse.side_effect = lambda s: s
-            importer.process_fields(ticket, issue)
-            self.assertEqual(ticket.summary, 'summary')
-            self.assertEqual(ticket.description,
-                             '*Originally created by:* creator\n*Originally owned by:* owner\n\nmy *description* fool')
-            self.assertEqual(ticket.status, 'status')
-            self.assertEqual(ticket.created_date, 'created_date')
-            self.assertEqual(ticket.mod_date, 'mod_date')
-            self.assertEqual(dt.parser.parse.call_args_list, [
-                mock.call('created_date'),
-                mock.call('mod_date'),
-            ])
-
-    def test_process_labels(self):
-        ticket = mock.Mock(custom_fields={}, labels=[])
-        issue = mock.Mock(get_issue_labels=lambda:
-                          ['Foo-Bar', 'Baz', 'Foo-Qux'])
-        importer = tracker.GoogleCodeTrackerImporter()
-        importer.custom_field = mock.Mock(
-            side_effect=lambda n: {'name': '_%s' % n.lower(), 'options': set()})
-        importer.process_labels(ticket, issue)
-        self.assertEqual(ticket.labels, ['Baz'])
-        self.assertEqual(ticket.custom_fields, {'_foo': 'Bar, Qux'})
-
-    def test_process_comments(self):
-        def _author(n):
-            a = mock.Mock()
-            a.name = 'author%s' % n
-            a.link = 'author%s_link' % n
-            return a
-        ticket = mock.Mock()
-        issue = mock.Mock()
-        comments = issue.iter_comments.return_value = [
-            mock.Mock(
-                author=_author(1),
-                body='text1',
-                annotated_text='annotated1',
-                attachments='attachments1',
-                created_date='Mon Jul 15 00:00:00 2013',
-            ),
-            mock.Mock(
-                author=_author(2),
-                body='text2',
-                annotated_text='annotated2',
-                attachments='attachments2',
-                created_date='Mon Jul 16 00:00:00 2013',
-            ),
-        ]
-        comments[0].updates.items.return_value = [
-            ('Foo:', 'Bar'), ('Baz:', 'Qux')]
-        comments[1].updates.items.return_value = []
-        posts = ticket.discussion_thread.add_post.side_effect = [
-            mock.Mock(),
-            mock.Mock(),
-        ]
-        importer = tracker.GoogleCodeTrackerImporter()
-        importer.process_comments(ticket, issue)
-        self.assertEqual(ticket.discussion_thread.add_post.call_args_list[0], mock.call(
-            text='annotated1',
-            timestamp=datetime(2013, 7, 15),
-            ignore_security=True,
-        ))
-        posts[0].add_multiple_attachments.assert_called_once_with(
-            'attachments1')
-        self.assertEqual(ticket.discussion_thread.add_post.call_args_list[1], mock.call(
-            text='annotated2',
-            timestamp=datetime(2013, 7, 16),
-            ignore_security=True,
-        ))
-        posts[1].add_multiple_attachments.assert_called_once_with(
-            'attachments2')
-
-    @mock.patch.object(tracker, 'c')
-    def test_postprocess_custom_fields(self, c):
-        importer = tracker.GoogleCodeTrackerImporter()
-        importer.open_milestones = set(['m2', 'm3'])
-        importer.custom_fields = {
-            'Foo': {
-                'name': '_foo',
-                'type': 'string',
-                'options': set(['foo', 'bar']),
-            },
-            'Milestone': {
-                'name': '_milestone',
-                'type': 'milestone',
-                'options': set(['m3', 'm1', 'm2']),
-            },
-            'Priority': {
-                'name': '_priority',
-                'type': 'select',
-                'options': set(['foo', 'bar']),
-            },
-        }
-        custom_fields = importer.postprocess_custom_fields()
-        self.assertItemsEqual(custom_fields, [
-            {
-                'name': '_foo',
-                'type': 'string',
-                'options': '',
-            },
-            {
-                'name': '_milestone',
-                'type': 'milestone',
-                'options': '',
-                'milestones': [
-                        {'name': 'm1', 'due_date': None, 'complete': True},
-                    {'name': 'm2', 'due_date': None, 'complete': False},
-                    {'name': 'm3', 'due_date': None, 'complete': False},
-                ],
-            },
-            {
-                'name': '_priority',
-                'type': 'select',
-                'options': 'foo bar',
-            },
-        ])
-
-
-class TestGoogleCodeTrackerImportController(TestController, TestCase):
-
-    def setUp(self):
-        """Mount Google Code importer on the Tracker admin controller"""
-        super(TestGoogleCodeTrackerImportController, self).setUp()
-        from forgetracker.tracker_main import TrackerAdminController
-        TrackerAdminController._importer = \
-                tracker.GoogleCodeTrackerImportController(
-                        tracker.GoogleCodeTrackerImporter())
-
-    @with_tracker
-    def test_index(self):
-        r = self.app.get('/p/test/admin/bugs/_importer/')
-        self.assertIsNotNone(r.html.find(attrs=dict(name="gc_project_name")))
-        self.assertIsNotNone(r.html.find(attrs=dict(name="mount_label")))
-        self.assertIsNotNone(r.html.find(attrs=dict(name="mount_point")))
-
-    @with_tracker
-    @patch('forgeimporters.base.import_tool')
-    def test_create(self, import_tool):
-        params = dict(gc_project_name='test',
-                      mount_label='mylabel',
-                      mount_point='mymount',
-                      )
-        r = self.app.post('/p/test/admin/bugs/_importer/create', params,
-                          status=302)
-        self.assertEqual(r.location, 'http://localhost/p/test/admin/')
-        self.assertEqual(
-            u'mymount', import_tool.post.call_args[1]['mount_point'])
-        self.assertEqual(
-            u'mylabel', import_tool.post.call_args[1]['mount_label'])
-        self.assertEqual(
-            u'test', import_tool.post.call_args[1]['project_name'])
-
-    @with_tracker
-    @patch('forgeimporters.base.import_tool')
-    def test_create_limit(self, import_tool):
-        project = M.Project.query.get(shortname='test')
-        project.set_tool_data('GoogleCodeTrackerImporter', pending=1)
-        ThreadLocalORMSession.flush_all()
-        params = dict(gc_project_name='test',
-                      mount_label='mylabel',
-                      mount_point='mymount',
-                      )
-        r = self.app.post('/p/test/admin/bugs/_importer/create', params,
-                          status=302).follow()
-        self.assertIn('Please wait and try again', r)
-        self.assertEqual(import_tool.post.call_count, 0)