You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by je...@apache.org on 2015/07/13 12:44:05 UTC

[01/29] allura git commit: [#4020] set compress=False on jquery ui css files that have relative image references in them

Repository: allura
Updated Branches:
  refs/heads/ib/7685 0fca2c85c -> c1a103d29 (forced update)


[#4020] set compress=False on jquery ui css files that have relative image references in them


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

Branch: refs/heads/ib/7685
Commit: 6991e5103b56a443c2bc7abf9a8205323e607aac
Parents: 664bd19
Author: Dave Brondsema <db...@slashdotmedia.com>
Authored: Wed Jul 1 21:57:17 2015 +0000
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Jul 3 14:10:19 2015 +0300

----------------------------------------------------------------------
 Allura/allura/ext/admin/widgets.py       | 2 +-
 Allura/allura/lib/widgets/form_fields.py | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/6991e510/Allura/allura/ext/admin/widgets.py
----------------------------------------------------------------------
diff --git a/Allura/allura/ext/admin/widgets.py b/Allura/allura/ext/admin/widgets.py
index 0f7d33d..de8046f 100644
--- a/Allura/allura/ext/admin/widgets.py
+++ b/Allura/allura/ext/admin/widgets.py
@@ -167,7 +167,7 @@ class FeaturesField(ew.CompoundField):
     fields = [ew.TextField(name='feature', attrs={'style': 'width:89%'})]
 
     def resources(self):
-        yield ew.CSSLink('allura/css/smoothness/jquery-ui-1.8.4.custom.css')
+        yield ew.CSSLink('allura/css/smoothness/jquery-ui-1.8.4.custom.css', compress=False)  # compress will also serve from a different location, breaking image refs
 
 
 class MetadataAdmin(ff.AdminForm):

http://git-wip-us.apache.org/repos/asf/allura/blob/6991e510/Allura/allura/lib/widgets/form_fields.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/form_fields.py b/Allura/allura/lib/widgets/form_fields.py
index 77665f9..da4d98a 100644
--- a/Allura/allura/lib/widgets/form_fields.py
+++ b/Allura/allura/lib/widgets/form_fields.py
@@ -483,7 +483,7 @@ class DateField(JQueryMixin, ew.TextField):
     def resources(self):
         for r in super(DateField, self).resources():
             yield r
-        yield ew.CSSLink('css/jquery.ui.datepicker.css')
+        yield ew.CSSLink('css/jquery.ui.datepicker.css', compress=False)  # compress will also serve from a different location, breaking image refs
 
 
 class FieldCluster(ew.CompoundField):


[17/29] allura git commit: [#7903] ticket:818 Mention small letters in username validation error

Posted by je...@apache.org.
[#7903] ticket:818 Mention small letters in username validation error


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

Branch: refs/heads/ib/7685
Commit: 338f454a951a50beae137776625987e5a6c1e84b
Parents: 5b29187
Author: Igor Bondarenko <je...@gmail.com>
Authored: Wed Jul 8 13:47:16 2015 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Jul 9 21:33:40 2015 +0000

----------------------------------------------------------------------
 Allura/allura/lib/widgets/forms.py                  | 4 ++--
 Allura/allura/tests/functional/test_auth.py         | 7 +++++--
 Allura/allura/tests/functional/test_neighborhood.py | 6 +++---
 3 files changed, 10 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/338f454a/Allura/allura/lib/widgets/forms.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/forms.py b/Allura/allura/lib/widgets/forms.py
index f523208..cfbad2c 100644
--- a/Allura/allura/lib/widgets/forms.py
+++ b/Allura/allura/lib/widgets/forms.py
@@ -56,7 +56,7 @@ class NeighborhoodProjectShortNameValidator(fev.FancyValidator):
     def _validate_shortname(self, shortname, neighborhood, state):
         if not h.re_project_name.match(shortname):
             raise forge_exc.ProjectShortnameInvalid(
-                'Please use only letters, numbers, and dashes 3-15 characters long.',
+                'Please use only small letters, numbers, and dashes 3-15 characters long.',
                 shortname, state)
 
     def _validate_allowed(self, shortname, neighborhood, state):
@@ -747,7 +747,7 @@ class RegistrationForm(ForgeForm):
             validator=fev.Regex(
                 h.re_project_name))
         username.validator._messages['invalid'] = (
-            'Usernames must include only letters, numbers, and dashes.'
+            'Usernames must include only small letters, numbers, and dashes.'
             ' They must also start with a letter and be at least 3 characters'
             ' long.')
         fields = [

http://git-wip-us.apache.org/repos/asf/allura/blob/338f454a/Allura/allura/tests/functional/test_auth.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_auth.py b/Allura/allura/tests/functional/test_auth.py
index 4522dd8..388be1a 100644
--- a/Allura/allura/tests/functional/test_auth.py
+++ b/Allura/allura/tests/functional/test_auth.py
@@ -670,9 +670,12 @@ class TestAuth(TestController):
         r = self.app.get('/auth/create_account')
         assert 'Create an Account' in r
         r = self.app.post('/auth/save_new',
-                          params=dict(username='aaa', pw='123',
+                          params=dict(username='AAA', pw='123',
                                       _session_id=self.app.cookies['_session_id']))
-        assert 'Enter a value 6 characters long or more' in r
+        assert_in('Enter a value 6 characters long or more', r)
+        assert_in('Usernames must include only small letters, numbers, '
+                  'and dashes. They must also start with a letter and be '
+                  'at least 3 characters long.', r)
         r = self.app.post(
             '/auth/save_new',
             params=dict(

http://git-wip-us.apache.org/repos/asf/allura/blob/338f454a/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 5d0d3ac..f87e9ea 100644
--- a/Allura/allura/tests/functional/test_neighborhood.py
+++ b/Allura/allura/tests/functional/test_neighborhood.py
@@ -509,7 +509,7 @@ class TestNeighborhood(TestController):
                           antispam=True,
                           extra_environ=dict(username='root'))
         assert r.html.find('div', {'class': 'error'}
-                           ).string == 'Please use only letters, numbers, and dashes 3-15 characters long.'
+                           ).string == 'Please use only small letters, numbers, and dashes 3-15 characters long.'
         r = self.app.post('/adobe/register',
                           params=dict(
                               project_unixname='mymoz', project_name='My Moz',
@@ -524,7 +524,7 @@ class TestNeighborhood(TestController):
                           antispam=True,
                           extra_environ=dict(username='root'))
         assert r.html.find('div', {'class': 'error'}
-                           ).string == 'Please use only letters, numbers, and dashes 3-15 characters long.'
+                           ).string == 'Please use only small letters, numbers, and dashes 3-15 characters long.'
         r = self.app.post('/p/register',
                           params=dict(
                               project_unixname='test', project_name='Tester',
@@ -834,7 +834,7 @@ class TestNeighborhood(TestController):
             r = self.app.get(
                 '/p/check_names?neighborhood=Projects&project_unixname=%s' % name)
             assert_equal(
-                r.json, {'project_unixname': 'Please use only letters, numbers, and dashes 3-15 characters long.'})
+                r.json, {'project_unixname': 'Please use only small letters, numbers, and dashes 3-15 characters long.'})
         r = self.app.get(
             '/p/check_names?neighborhood=Projects&project_unixname=mymoz')
         assert_equal(r.json, {})


[10/29] allura git commit: [#6373] add more client script documentation

Posted by je...@apache.org.
[#6373] add more client script documentation


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

Branch: refs/heads/ib/7685
Commit: 848355c61831a4e9a5d02f6964d867ab9fc80c3e
Parents: 3189602
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Jul 8 15:59:52 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jul 8 17:00:50 2015 -0400

----------------------------------------------------------------------
 Allura/docs/getting_started/administration.rst | 31 ++++++++++---
 scripts/new_ticket.py                          | 48 ++++++++++++---------
 scripts/wiki-copy.py                           |  3 +-
 scripts/wiki-post.py                           |  2 +-
 4 files changed, 54 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/848355c6/Allura/docs/getting_started/administration.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/administration.rst b/Allura/docs/getting_started/administration.rst
index 1a2084f..c0b23e2 100644
--- a/Allura/docs/getting_started/administration.rst
+++ b/Allura/docs/getting_started/administration.rst
@@ -233,16 +233,33 @@ Requires running: :command:`pip install suds` first. ::
 Client Scripts
 ==============
 
-Allura includes some client scripts that use Allura APIs and do not have to be run
-from an Allura server.  They do require various python packages to be installed
-and possibly a local Allura codebase set up.
+Allura includes some client scripts that demonstrate use of the Allura REST API and do not have to be run
+from an Allura environment.  They do require some python packages to be installed, though.
 
-One such script is `wiki-copy.py` which reads the wiki pages from one Allura wiki
-instance and uploads them to another Allura wiki instance.  It can be run as:
 
-.. code-block:: console
+wiki-copy.py
+------------
+
+.. program-output:: python ../../scripts/wiki-copy.py --help | sed 's/Usage: /Usage: python scripts\//'
+    :shell:
+
+
+new_ticket.py
+-------------
+
+Illustrates creating a new ticket, using the simple OAuth Bearer token.
+
+.. argparse::
+    :file: ../../scripts/new_ticket.py
+    :func: get_parser
+    :prog: python scripts/new_ticket.py
+
+
+wiki-post.py
+------------
 
-    $ python scripts/wiki-copy.py --help
+.. program-output:: python ../../scripts/wiki-post.py --help | sed 's/Usage: /Usage: python scripts\//'
+    :shell:
 
 
 Site Notifications

http://git-wip-us.apache.org/repos/asf/allura/blob/848355c6/scripts/new_ticket.py
----------------------------------------------------------------------
diff --git a/scripts/new_ticket.py b/scripts/new_ticket.py
index 9b23328..924f9d2 100755
--- a/scripts/new_ticket.py
+++ b/scripts/new_ticket.py
@@ -22,32 +22,38 @@ import requests
 from pprint import pprint
 
 
-def get_opts():
+def get_parser():
     parser = argparse.ArgumentParser(
         description='Post a new ticket using the API')
     parser.add_argument('project', help='Project shortname')
     parser.add_argument('mount_point', help='Tracker mount point')
-    parser.add_argument('-H', '--host', default='sourceforge.net')
-    opts = parser.parse_args()
+    parser.add_argument('-H', '--host', default='sourceforge.net', help='Base domain')
+    return parser
+
+
+def get_opts():
+    opts = get_parser().parse_args()
     opts.url = 'https://{}/rest/p/{}/{}/new'.format(opts.host,
                                                     opts.project, opts.mount_point)
     return opts
 
-opts = get_opts()
-access_token = raw_input('Access (bearer) token: ')
-summary = raw_input('Summary: ')
-print 'Description (C-d to end):'
-print '-----------------------------------------------'
-description = sys.stdin.read()
-print '-----------------------------------------------'
-
-r = requests.post(opts.url, params={
-    'access_token': access_token,
-    'ticket_form.summary': summary,
-    'ticket_form.description': description,
-})
-if r.status_code == 200:
-    print 'Ticket created at: %s' % r.url
-    pprint(r.json())
-else:
-    print 'Error [%s]:\n%s' % (r.status_code, r.text)
+
+if __name__ == '__main__':
+    opts = get_opts()
+    access_token = raw_input('Access (bearer) token: ')
+    summary = raw_input('Summary: ')
+    print 'Description (C-d to end):'
+    print '-----------------------------------------------'
+    description = sys.stdin.read()
+    print '-----------------------------------------------'
+
+    r = requests.post(opts.url, params={
+        'access_token': access_token,
+        'ticket_form.summary': summary,
+        'ticket_form.description': description,
+    })
+    if r.status_code == 200:
+        print 'Ticket created at: %s' % r.url
+        pprint(r.json())
+    else:
+        print 'Error [%s]:\n%s' % (r.status_code, r.text)

http://git-wip-us.apache.org/repos/asf/allura/blob/848355c6/scripts/wiki-copy.py
----------------------------------------------------------------------
diff --git a/scripts/wiki-copy.py b/scripts/wiki-copy.py
index 0692852..26304cb 100644
--- a/scripts/wiki-copy.py
+++ b/scripts/wiki-copy.py
@@ -30,7 +30,8 @@ import oauth2 as oauth
 
 
 def main():
-    op = OptionParser(usage='usage: %prog [options]')
+    op = OptionParser(usage='usage: %prog [options]',
+                      description='Reads the wiki pages from one Allura wiki instance and uploads them to another Allura wiki instance.')
     op.add_option('-f', '--from-wiki', action='store', dest='from_wiki',
                   help='URL of wiki API to copy from like http://fromserver.com/rest/p/test/wiki/')
     op.add_option('-t', '--to-wiki', action='store', dest='to_wiki',

http://git-wip-us.apache.org/repos/asf/allura/blob/848355c6/scripts/wiki-post.py
----------------------------------------------------------------------
diff --git a/scripts/wiki-post.py b/scripts/wiki-post.py
index 7e16bb1..2a6fb40 100755
--- a/scripts/wiki-post.py
+++ b/scripts/wiki-post.py
@@ -85,7 +85,7 @@ class Signer(object):
 
 def main():
     usage = 'usage: %prog [options] [PageName [file]]'
-    op = OptionParser(usage=usage)
+    op = OptionParser(usage=usage, description='Use a markdown file to create/update a wiki page')
     op.add_option('-c', '--config', metavar='CONFIG')
     op.add_option('-t', '--token', metavar='TOKEN')
     op.add_option('', '--anon', action='store_true')


[07/29] allura git commit: [#6373] document common admin scripts

Posted by je...@apache.org.
[#6373] document common admin scripts


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

Branch: refs/heads/ib/7685
Commit: acd50e8d8e1cb00a5413f6a9caa227b401ff12b4
Parents: 93a1ecc
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Jul 1 12:49:45 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jul 8 17:00:48 2015 -0400

----------------------------------------------------------------------
 Allura/allura/scripts/disable_users.py         |   3 +
 Allura/allura/scripts/refreshrepo.py           |   4 +
 Allura/allura/scripts/reindex_projects.py      |   6 +-
 Allura/allura/scripts/reindex_users.py         |   6 +-
 Allura/docs/conf.py                            |   3 +-
 Allura/docs/getting_started/administration.rst | 126 +++++++++++++++++---
 requirements.txt                               |   1 +
 scripts/create-allura-sitemap.py               |   7 +-
 scripts/publicize-neighborhood.py              |   9 +-
 scripts/scrub-allura-data.py                   |  13 +-
 10 files changed, 151 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/acd50e8d/Allura/allura/scripts/disable_users.py
----------------------------------------------------------------------
diff --git a/Allura/allura/scripts/disable_users.py b/Allura/allura/scripts/disable_users.py
index 7eeef33..ed93833 100644
--- a/Allura/allura/scripts/disable_users.py
+++ b/Allura/allura/scripts/disable_users.py
@@ -66,5 +66,8 @@ class DisableUsers(ScriptTask):
         return parser
 
 
+def get_parser():
+    return DisableUsers.parser()
+
 if __name__ == '__main__':
     DisableUsers.main()

http://git-wip-us.apache.org/repos/asf/allura/blob/acd50e8d/Allura/allura/scripts/refreshrepo.py
----------------------------------------------------------------------
diff --git a/Allura/allura/scripts/refreshrepo.py b/Allura/allura/scripts/refreshrepo.py
index a336b0d..fbec016 100644
--- a/Allura/allura/scripts/refreshrepo.py
+++ b/Allura/allura/scripts/refreshrepo.py
@@ -194,6 +194,10 @@ class RefreshRepo(ScriptTask):
         return parser
 
 
+def get_parser():
+    return RefreshRepo.parser()
+
+
 if __name__ == '__main__':
     faulthandler.enable()
     RefreshRepo.main()

http://git-wip-us.apache.org/repos/asf/allura/blob/acd50e8d/Allura/allura/scripts/reindex_projects.py
----------------------------------------------------------------------
diff --git a/Allura/allura/scripts/reindex_projects.py b/Allura/allura/scripts/reindex_projects.py
index 89c447e..0f8f3be 100644
--- a/Allura/allura/scripts/reindex_projects.py
+++ b/Allura/allura/scripts/reindex_projects.py
@@ -87,7 +87,7 @@ class ReindexProjects(ScriptTask):
 
     @classmethod
     def parser(cls):
-        parser = argparse.ArgumentParser(description='Reindex all projects')
+        parser = argparse.ArgumentParser(description='Reindex all project records into Solr (for searching)')
         parser.add_argument('-n', '--nbhd', action='store', default='', dest='nbhd',
                             help='Restrict reindex to a particular neighborhood, e.g. /p/.')
         parser.add_argument(
@@ -109,5 +109,9 @@ class ReindexProjects(ScriptTask):
         return parser
 
 
+def get_parser():
+    return ReindexProjects.parser()
+
+
 if __name__ == '__main__':
     ReindexProjects.main()

http://git-wip-us.apache.org/repos/asf/allura/blob/acd50e8d/Allura/allura/scripts/reindex_users.py
----------------------------------------------------------------------
diff --git a/Allura/allura/scripts/reindex_users.py b/Allura/allura/scripts/reindex_users.py
index 8a0762b..e2acd3b 100644
--- a/Allura/allura/scripts/reindex_users.py
+++ b/Allura/allura/scripts/reindex_users.py
@@ -73,7 +73,7 @@ class ReindexUsers(ScriptTask):
 
     @classmethod
     def parser(cls):
-        parser = argparse.ArgumentParser(description='Reindex all users')
+        parser = argparse.ArgumentParser(description='Reindex all users into Solr (for searching)')
         parser.add_argument('--dry-run', action='store_true', dest='dry_run',
                             default=False, help='Log names of projects that would be reindexed, '
                             'but do not perform the actual reindex.')
@@ -85,5 +85,9 @@ class ReindexUsers(ScriptTask):
         return parser
 
 
+def get_parser():
+    return ReindexUsers.parser()
+
+
 if __name__ == '__main__':
     ReindexUsers.main()

http://git-wip-us.apache.org/repos/asf/allura/blob/acd50e8d/Allura/docs/conf.py
----------------------------------------------------------------------
diff --git a/Allura/docs/conf.py b/Allura/docs/conf.py
index c201b9c..4c55afa 100644
--- a/Allura/docs/conf.py
+++ b/Allura/docs/conf.py
@@ -41,6 +41,7 @@ import os
 
 extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx',
               'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.ifconfig']
+extensions += ['sphinxarg.ext']
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
@@ -56,7 +57,7 @@ master_doc = 'index'
 
 # General information about the project.
 project = 'Apache Allura'
-copyright = '2012-2014 The Apache Software Foundation'
+copyright = '2012-2015 The Apache Software Foundation'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the

http://git-wip-us.apache.org/repos/asf/allura/blob/acd50e8d/Allura/docs/getting_started/administration.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/administration.rst b/Allura/docs/getting_started/administration.rst
index 4410f55..0b03728 100644
--- a/Allura/docs/getting_started/administration.rst
+++ b/Allura/docs/getting_started/administration.rst
@@ -19,13 +19,19 @@
 Administration
 **************
 
+.. contents::
+   :local:
+
 Commands, Scripts, and Tasks
-----------------------------
+============================
+
+Overview
+--------
 
-Allura has many `paster` commands and `paster` scripts that can be run from the
-server commandline to administrate Allura.  There are also tasks that can be
-run through the `taskd` system.  New tasks can be submitted via the web at
-/nf/admin/task_manager  Some paster commands and scripts have been set up
+Allura has many commands and scripts that can be run from the server commandline to
+administrate Allura.  There are also tasks that can be run through the `taskd` system
+in the background.  These tasks can be submitted via the web at
+http://MYSITE/nf/admin/task_manager  Some paster scripts have been set up
 so that they are runnable as tasks too, giving you the convenience of starting
 them through the web and letting `taskd` execute them, rather than from a server
 shell.
@@ -42,30 +48,116 @@ Commands can be discovered and run via the `paster` command when you are in the
      paster create-neighborhood development.ini myneighborhood myuser ...
 
 
-Scripts are in the `scripts/` directory and run via `paster script`.  An extra
-`--` is required to separate script arguments from paster arguments.  Example::
+Scripts are in the `scripts/` directory and run slightly differently, via `paster script`.  An extra
+:kbd:`--` is required to separate script arguments from paster arguments.  Example::
 
      paster script development.ini ../scripts/create-allura-sitemap.py -- --help
     ... help output ...
 
      paster script development.ini ../scripts/create-allura-sitemap.py -- -u 100
 
-TODO:   explain important scripts, commands
-
-Tasks can be run via the web interface at /nf/admin/task_manager  You must know
-the full task name, e.g. `allura.tasks.admin_tasks.install_app`  You can
+Tasks can be run via the web interface at http://MYSITE/nf/admin/task_manager  You must know
+the full task name, e.g. :code:`allura.tasks.admin_tasks.install_app`  You can
 optionally provide a username and project and app which will get set on the
 current context (`c`).  You should specify what args and kwargs will be passed
-as parameters to the task.  They are specified in JSON format on the form.
+as parameters to the task.  They are specified in JSON format on the form.  If you are
+running a script via this interface, the `args/kwargs` JSON should be like::
+
+    {
+        "args": ["--foo --bar baz"],
+        "kwargs": {}
+    }
 
 See the listing of :mod:`some available tasks <allura.tasks.admin_tasks>`.
 
-TODO: explain how to run scripttasks and commandtasks
+Available scripts and tasks are:
 
+disable_users.py
+----------------
 
-Client Scripts
+*Can be run as a background task using task name:* :code:`allura.scripts.disable_users.DisableUsers`
+
+.. argparse::
+    :module: allura.scripts.disable_users
+    :func: get_parser
+    :prog: paster script development.ini allura/scripts/disable_users.py --
+
+refreshrepo.py
 --------------
 
+*Can be run as a background task using task name:* :code:`allura.scripts.refreshrepo.RefreshRepo`
+
+.. argparse::
+    :module: allura.scripts.refreshrepo
+    :func: get_parser
+    :prog: paster script development.ini allura/scripts/refreshrepo.py --
+
+reindex_projects.py
+-------------------
+
+*Can be run as a background task using task name:* :code:`allura.scripts.reindex_projects.ReindexProjects`
+
+.. argparse::
+    :module: allura.scripts.reindex_projects
+    :func: get_parser
+    :prog: paster script development.ini allura/scripts/reindex_projects.py --
+
+reindex_users.py
+----------------
+
+*Can be run as a background task using task name:* :code:`allura.scripts.reindex_users.ReindexUsers`
+
+.. argparse::
+    :module: allura.scripts.reindex_users
+    :func: get_parser
+    :prog: paster script development.ini allura/scripts/reindex_users.py --
+
+create-allura-sitemap.py
+------------------------
+
+*Cannot currently be run as a background task.*
+
+.. argparse::
+    :file: ../../scripts/create-allura-sitemap.py
+    :func: parser
+    :prog: paster script development.ini ../scripts/create-allura-sitemap.py --
+
+publicize-neighborhood.py
+-------------------------
+
+*Cannot currently be run as a background task.*
+
+.. argparse::
+    :file: ../../scripts/publicize-neighborhood.py
+    :func: parser
+    :prog: paster script development.ini ../scripts/publicize-neighborhood.py --
+
+scrub-allura-data.py
+--------------------
+
+*Cannot currently be run as a background task.*
+
+.. argparse::
+    :file: ../../scripts/scrub-allura-data.py
+    :func: parser
+    :prog: paster script development.ini ../scripts/scrub-allura-data.py --
+
+teamforge-import.py
+-------------------
+
+*Cannot currently be run as a background task.*
+
+Extract data from a TeamForge site (via its web API), and import directly into Allura.  There are some hard-coded
+and extra functions in this script, which should be removed or updated before being used again.
+Requires running: :command:`pip install suds` first. ::
+
+    usage: paster script development.ini ../scripts/teamforge-import.py -- --help
+
+
+
+Client Scripts
+==============
+
 Allura includes some client scripts that use Allura APIs and do not have to be run
 from an Allura server.  They do require various python packages to be installed
 and possibly a local Allura codebase set up.
@@ -79,7 +171,7 @@ instance and uploads them to another Allura wiki instance.  It can be run as:
 
 
 Site Notifications
-------------------
+==================
 
 Allura has support for site-wide notifications that appear below the site header,
 but there is currently no UI for managing them.  They can easily be inserted via
@@ -101,7 +193,7 @@ no notification will be shown.
 
 
 Using Projects and Tools
-------------------------
+========================
 
 We currently don't have any further documentation for basic operations of managing
 users, projects, and tools on Allura.  However, SourceForge has help docs that cover
@@ -110,6 +202,6 @@ that this documentation also covers some SourceForge features that are not part
 
 
 Public API Documentation
-------------------------
+========================
 
 Allura's web api is currently documented at https://sourceforge.net/p/forge/documentation/Allura%20API/

http://git-wip-us.apache.org/repos/asf/allura/blob/acd50e8d/requirements.txt
----------------------------------------------------------------------
diff --git a/requirements.txt b/requirements.txt
index fffb91d..80eda02 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -79,4 +79,5 @@ WebTest==1.4.0
 testfixtures==3.0.0
 q==2.3
 WebError==0.10.3
+-e git://github.com/brondsem/sphinx-argparse.git#egg=sphinx-argparse   # pending merge requests
 sphinx-rtd-theme==0.1.6

http://git-wip-us.apache.org/repos/asf/allura/blob/acd50e8d/scripts/create-allura-sitemap.py
----------------------------------------------------------------------
diff --git a/scripts/create-allura-sitemap.py b/scripts/create-allura-sitemap.py
index f39b2a6..29220d1 100644
--- a/scripts/create-allura-sitemap.py
+++ b/scripts/create-allura-sitemap.py
@@ -142,7 +142,7 @@ def main(options):
             f.write(sitemap_index_content)
 
 
-def parse_options():
+def parser():
     import argparse
     class Validate(argparse.Action):
         def __call__(self, parser, namespace, value, option_string=None):
@@ -165,8 +165,11 @@ def parse_options():
     parser.add_argument('-n', '--neighborhood', dest='neighborhood',
                          help="URL prefix of excluded neighborhood(s)",
                          default=None, nargs='*')
+    return parser
+
+def parse_options():
+    return parser().parse_args()
 
-    return parser.parse_args()
 
 if __name__ == '__main__':
     sys.exit(main(parse_options()))

http://git-wip-us.apache.org/repos/asf/allura/blob/acd50e8d/scripts/publicize-neighborhood.py
----------------------------------------------------------------------
diff --git a/scripts/publicize-neighborhood.py b/scripts/publicize-neighborhood.py
index c32d384..9cc6494 100644
--- a/scripts/publicize-neighborhood.py
+++ b/scripts/publicize-neighborhood.py
@@ -70,7 +70,7 @@ def main(options):
     return 0
 
 
-def parse_options():
+def parser():
     import argparse
     parser = argparse.ArgumentParser(
         description='Make all projects in a neighborhood public.')
@@ -81,7 +81,12 @@ def parse_options():
                         help='Run in test mode (no updates will be applied).')
     parser.add_argument('--log', dest='log_level', default='INFO',
                         help='Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL).')
-    return parser.parse_args()
+    return parser
+
+
+def parse_options():
+    return parser().parse_args()
+
 
 if __name__ == '__main__':
     sys.exit(main(parse_options()))

http://git-wip-us.apache.org/repos/asf/allura/blob/acd50e8d/scripts/scrub-allura-data.py
----------------------------------------------------------------------
diff --git a/scripts/scrub-allura-data.py b/scripts/scrub-allura-data.py
index c0e0828..211cfdc 100644
--- a/scripts/scrub-allura-data.py
+++ b/scripts/scrub-allura-data.py
@@ -134,16 +134,23 @@ def main(options):
     return 0
 
 
-def parse_options():
+def parser():
     import argparse
     parser = argparse.ArgumentParser(
-        description='Removes private data from the Allura MongoDB.')
+        description='Removes private data from the Allura MongoDB.  DO NOT RUN THIS on your main database.  '
+                    'This is intended to be used on a copy of your database, to prepare it for sharing with others.'
+    )
     parser.add_argument('--dry-run', dest='dry_run', default=False,
                         action='store_true',
                         help='Run in test mode (no updates will be applied).')
     parser.add_argument('--log', dest='log_level', default='INFO',
                         help='Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL).')
-    return parser.parse_args()
+    return parser
+
+
+def parse_options():
+    return parser().parse_args()
+
 
 if __name__ == '__main__':
     sys.exit(main(parse_options()))


[09/29] allura git commit: [#6373] write some docs about admin webpages

Posted by je...@apache.org.
[#6373] write some docs about admin webpages


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

Branch: refs/heads/ib/7685
Commit: b253cdd4d28532623b4a7e7681d4dc04141123df
Parents: 848355c
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Jul 8 16:56:45 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jul 8 17:00:50 2015 -0400

----------------------------------------------------------------------
 Allura/docs/getting_started/administration.rst | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/b253cdd4/Allura/docs/getting_started/administration.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/administration.rst b/Allura/docs/getting_started/administration.rst
index c0b23e2..d9044b1 100644
--- a/Allura/docs/getting_started/administration.rst
+++ b/Allura/docs/getting_started/administration.rst
@@ -22,6 +22,25 @@ Administration
 .. contents::
    :local:
 
+
+Site Admin Interface
+====================
+
+Allura has an admin interface at http://MYSITE/nf/admin/  You must be an admin of the
+`/p/allura` project on the site to access it.  If you want to use another project to control
+admin access, change the :code:`site_admin_project` setting in :file:`development.ini`.
+
+The admin interface allows you to:
+
+* View newly registered projects
+* Search for projects
+* View neighborhood total stats
+* Search for users, view user details, update user status, email address, and reset their password
+* View background task statuses, and submit new background tasks
+* Manage "trove" categories (for user skill choices)
+* Subscriber a user to an artifact
+* Reclone a repository
+
 Commands, Scripts, and Tasks
 ============================
 


[12/29] allura git commit: [#6373] move Client Scripts section below Public API

Posted by je...@apache.org.
[#6373] move Client Scripts section below Public API


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

Branch: refs/heads/ib/7685
Commit: 2842760f68c2230adbd0f0f6f5bec69786b1334f
Parents: b253cdd
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Jul 8 16:57:04 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jul 8 17:00:51 2015 -0400

----------------------------------------------------------------------
 Allura/docs/getting_started/administration.rst | 66 ++++++++++-----------
 1 file changed, 33 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/2842760f/Allura/docs/getting_started/administration.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/administration.rst b/Allura/docs/getting_started/administration.rst
index d9044b1..abbe814 100644
--- a/Allura/docs/getting_started/administration.rst
+++ b/Allura/docs/getting_started/administration.rst
@@ -248,39 +248,6 @@ Requires running: :command:`pip install suds` first. ::
     usage: paster script development.ini ../scripts/teamforge-import.py -- --help
 
 
-
-Client Scripts
-==============
-
-Allura includes some client scripts that demonstrate use of the Allura REST API and do not have to be run
-from an Allura environment.  They do require some python packages to be installed, though.
-
-
-wiki-copy.py
-------------
-
-.. program-output:: python ../../scripts/wiki-copy.py --help | sed 's/Usage: /Usage: python scripts\//'
-    :shell:
-
-
-new_ticket.py
--------------
-
-Illustrates creating a new ticket, using the simple OAuth Bearer token.
-
-.. argparse::
-    :file: ../../scripts/new_ticket.py
-    :func: get_parser
-    :prog: python scripts/new_ticket.py
-
-
-wiki-post.py
-------------
-
-.. program-output:: python ../../scripts/wiki-post.py --help | sed 's/Usage: /Usage: python scripts\//'
-    :shell:
-
-
 Site Notifications
 ==================
 
@@ -311,9 +278,42 @@ users, projects, and tools on Allura.  However, SourceForge has help docs that c
 these functions https://sourceforge.net/p/forge/documentation/Docs%20Home/  Note
 that this documentation also covers some SourceForge features that are not part of Allura.
 
+
 .. _public_api:
 
 Public API Documentation
 ========================
 
 Allura's web api is currently documented at https://sourceforge.net/p/forge/documentation/Allura%20API/
+
+
+Client Scripts
+==============
+
+Allura includes some client scripts that demonstrate use of the Allura REST API and do not have to be run
+from an Allura environment.  They do require some python packages to be installed, though.
+
+
+wiki-copy.py
+------------
+
+.. program-output:: python ../../scripts/wiki-copy.py --help | sed 's/Usage: /Usage: python scripts\//'
+    :shell:
+
+
+new_ticket.py
+-------------
+
+Illustrates creating a new ticket, using the simple OAuth Bearer token.
+
+.. argparse::
+    :file: ../../scripts/new_ticket.py
+    :func: get_parser
+    :prog: python scripts/new_ticket.py
+
+
+wiki-post.py
+------------
+
+.. program-output:: python ../../scripts/wiki-post.py --help | sed 's/Usage: /Usage: python scripts\//'
+    :shell:
\ No newline at end of file


[28/29] allura git commit: [#7685] ticket:819 Use ajax requests in subscription icons

Posted by je...@apache.org.
[#7685] ticket:819 Use ajax requests in subscription icons


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

Branch: refs/heads/ib/7685
Commit: 19b9fef51bcc1c9dd49f84d59052c09964bc2609
Parents: 25ae621
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 10 18:03:02 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Jul 10 18:45:28 2015 +0300

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py         |  7 +-
 .../lib/widgets/resources/js/subscriptions.js   | 99 ++++++++++++++++++++
 Allura/allura/lib/widgets/subscriptions.py      |  7 +-
 Allura/allura/templates/widgets/subscribe.html  | 44 ++++-----
 ForgeBlog/forgeblog/main.py                     | 11 ++-
 .../forgediscussion/controllers/forum.py        |  7 +-
 ForgeTracker/forgetracker/tracker_main.py       | 14 ++-
 ForgeWiki/forgewiki/wiki_main.py                |  7 +-
 8 files changed, 158 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/19b9fef5/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 0178723..2b9ae89 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -688,7 +688,7 @@ class TreeBrowser(BaseController, DispatchIndex):
             self._path + '/' + next,
             self), rest
 
-    @expose()
+    @expose('json:')
     @require_post()
     @validate(subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None, **kw):
@@ -696,7 +696,10 @@ class TreeBrowser(BaseController, DispatchIndex):
             M.Mailbox.subscribe()
         elif unsubscribe:
             M.Mailbox.unsubscribe()
-        redirect(request.referer)
+        return {
+            'status': 'ok',
+            'subscribed': M.Mailbox.subscribed(),
+        }
 
 
 class FileBrowser(BaseController):

http://git-wip-us.apache.org/repos/asf/allura/blob/19b9fef5/Allura/allura/lib/widgets/resources/js/subscriptions.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/subscriptions.js b/Allura/allura/lib/widgets/resources/js/subscriptions.js
new file mode 100644
index 0000000..c03bbeb
--- /dev/null
+++ b/Allura/allura/lib/widgets/resources/js/subscriptions.js
@@ -0,0 +1,99 @@
+/*
+       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.
+*/
+
+var dom = React.createElement;
+
+/* top-level form state */
+var state = {
+  'thing': 'tool',
+  'subscribed': false,
+  'url': '',
+  'icon': {}
+};
+
+SubscriptionForm = React.createClass({
+
+  render: function() {
+    var action = this.props.subscribed ? "Unsubscribe from" : "Subscribe to";
+    var title = action + ' this ' + this.props.thing;
+    var link_opts = {
+      className: this.props.subscribed ? 'active' : '',
+      href: '#',
+      title: title,
+      onClick: this.handleClick
+    };
+    var icon_opts = {
+      'data-icon': this.props.icon.char,
+      className: 'ico ' + this.props.icon.css,
+      title: title
+    };
+    return dom('a', link_opts, dom('b', icon_opts));
+  },
+
+  handleClick: function() {
+    var url = this.props.url;
+    var csrf = $.cookie('_session_id');
+    var data = {_session_id: csrf};
+    if (this.props.subscribed) {
+      data.unsubscribe = true;
+    } else {
+      data.subscribe = true;
+    }
+    set_state({in_progress: true});
+    /*
+     * TODO:
+     * - show 'in-progress' status to user somehow
+     * - handle errors (show to the user in some kind of popup/flash?)
+     * - If user is subscribed to the whole tool and she tries to subsribe to
+     *   the artifact she will not be subscribed, so nothing will change in the
+     *   UI and it's confusing. We need to show some information message in
+     *   such case
+     */
+    $.post(url, data, function(resp) {
+      if (resp.status == 'ok') {
+        set_state({subscribed: resp.subscribed});
+      }
+    }).always(function() {
+      set_state({in_progress: false});
+    });
+    return false;
+  }
+
+});
+
+function set_state(new_state) {
+  /* Set state and re-render entire UI */
+  for (var key in new_state) {
+    state[key] = new_state[key];
+  }
+  render(state);
+}
+
+function render(state) {
+  var props = {};
+  for (var key in state) { props[key] = state[key]; }
+  React.render(
+    dom(SubscriptionForm, props),
+    document.getElementById('subscription-form')
+  );
+}
+
+$(function() {
+  set_state(document.SUBSCRIPTION_OPTIONS);
+});

http://git-wip-us.apache.org/repos/asf/allura/blob/19b9fef5/Allura/allura/lib/widgets/subscriptions.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/subscriptions.py b/Allura/allura/lib/widgets/subscriptions.py
index dec1274..c8d3dcd 100644
--- a/Allura/allura/lib/widgets/subscriptions.py
+++ b/Allura/allura/lib/widgets/subscriptions.py
@@ -75,7 +75,7 @@ class SubscribeForm(ew.SimpleForm):
     defaults = dict(
         ew.SimpleForm.defaults,
         thing='tool',
-        style='text',
+        style='icon',
         tool_subscribed=False,
         value=None)
 
@@ -86,3 +86,8 @@ class SubscribeForm(ew.SimpleForm):
 
     def from_python(self, value, state):
         return value
+
+    def resources(self):
+        for r in super(SubscribeForm, self).resources():
+            yield r
+        yield ew.JSLink('js/subscriptions.js')

http://git-wip-us.apache.org/repos/asf/allura/blob/19b9fef5/Allura/allura/templates/widgets/subscribe.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/subscribe.html b/Allura/allura/templates/widgets/subscribe.html
index 5154eb7..1361a9c 100644
--- a/Allura/allura/templates/widgets/subscribe.html
+++ b/Allura/allura/templates/widgets/subscribe.html
@@ -17,28 +17,24 @@
        under the License.
 -#}
 {% import 'allura:templates/jinja_master/lib.html' as lib with context %}
-{% if value %}
-  {% if style == 'icon' %}
-    <form action="{{action}}" id="subscribe_form" style="display:inline;" method="POST">
-      {{lib.csrf_token()}}
-      <input type="hidden" name="unsubscribe" value="1">
-      <a href="#" class="artifact_unsubscribe active" title="Unsubscribe from this {{thing}}" onclick="$('#subscribe_form').submit(); return false;"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Unsubscribe from this {{thing}}"></b></a>
-    </form>
-  {% else %}
-    You are currently subscribed to this {{thing}}.
-    <br/>
-    {{fields['unsubscribe'].display()}}
-  {% endif %}
-{% else %}
-  {% if style == 'icon' %}
-    <form action="{{action}}" id="subscribe_form" style="display:inline;" method="POST">
-      {{lib.csrf_token()}}
-      <input type="hidden" name="subscribe" value="1">
-      <a href="#" class="artifact_subscribe" title="Subscribe to this {{thing}}" onclick="$('#subscribe_form').submit(); return false;"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Subscribe to this {{thing}}"></b></a>
-    </form>
-  {% else %}
-    You are currently not subscribed to this {{thing}}.
-    <br/>
-    {{fields['subscribe'].display()}}
-  {% endif %}
+
+{% do g.register_forge_js('js/react.min.js', location='head_js') %}
+{% for blob in g.resource_manager.emit('head_js') %}
+{% if 'react.min.js' in blob %}
+  {{ blob }}
 {% endif %}
+{% endfor %}
+
+<div id="subscription-form" style="display: inline;">{# see subscription.js #}</div>
+
+<script>
+  document.SUBSCRIPTION_OPTIONS = {
+    "thing": "{{thing}}",
+    "subscribed": {{"true" if value else "false"}},
+    "url": "{{action}}",
+    "icon": {
+      "char": "{{g.icons['mail'].char}}",
+      "css": "{{g.icons['mail'].css}}"
+    }
+  };
+</script>

http://git-wip-us.apache.org/repos/asf/allura/blob/19b9fef5/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 9007f87..adfc172 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -322,8 +322,10 @@ class PostController(BaseController, FeedController):
         version = kw.pop('version', None)
         post = self._get_version(version)
         base_post = self.post
+        subscribed = M.Mailbox.subscribed(artifact=self.post)
         return dict(post=post, base_post=base_post,
-                    page=page, limit=limit, count=post_count)
+                    page=page, limit=limit, count=post_count,
+                    subscribed=subscribed)
 
     @expose('jinja:forgeblog:templates/blog/edit_post.html')
     @without_trailing_slash
@@ -375,7 +377,7 @@ class PostController(BaseController, FeedController):
         self.post.commit()
         redirect('.')
 
-    @expose()
+    @expose('json:')
     @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None, **kw):
@@ -383,7 +385,10 @@ class PostController(BaseController, FeedController):
             self.post.subscribe(type='direct')
         elif unsubscribe:
             self.post.unsubscribe()
-        redirect(h.really_unicode(request.referer).encode('utf-8'))
+        return {
+            'status': 'ok',
+            'subscribed': M.Mailbox.subscribed(artifact=self.post),
+        }
 
     def get_feed(self, project, app, user):
         """Return a :class:`allura.controllers.feed.FeedArgs` object describing

http://git-wip-us.apache.org/repos/asf/allura/blob/19b9fef5/ForgeDiscussion/forgediscussion/controllers/forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/forum.py b/ForgeDiscussion/forgediscussion/controllers/forum.py
index 94fe6d9..b915823 100644
--- a/ForgeDiscussion/forgediscussion/controllers/forum.py
+++ b/ForgeDiscussion/forgediscussion/controllers/forum.py
@@ -122,7 +122,7 @@ class ForumController(DiscussionController):
     def deleted(self):
         return dict()
 
-    @expose()
+    @expose('json:')
     @require_post()
     @validate(W.subscribe_form)
     def subscribe_to_forum(self, subscribe=None, unsubscribe=None, shortname=None, **kw):
@@ -130,7 +130,10 @@ class ForumController(DiscussionController):
             self.discussion.subscribe(type='direct')
         elif unsubscribe:
             self.discussion.unsubscribe()
-        redirect(h.really_unicode(request.referer).encode('utf-8'))
+        return {
+            'status': 'ok',
+            'subscribed': M.Mailbox.subscribed(artifact=self.discussion),
+        }
 
 
 class ForumThreadController(ThreadController):

http://git-wip-us.apache.org/repos/asf/allura/blob/19b9fef5/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index c3a83e6..0049957 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1090,7 +1090,7 @@ class RootController(BaseController, FeedController):
             dates=dates,
         )
 
-    @expose()
+    @expose('json:')
     @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None):
@@ -1098,7 +1098,10 @@ class RootController(BaseController, FeedController):
             M.Mailbox.subscribe(type='direct')
         elif unsubscribe:
             M.Mailbox.unsubscribe()
-        redirect(request.referer)
+        return {
+            'status': 'ok',
+            'subscribed': M.Mailbox.subscribed(),
+        }
 
 
 class BinController(BaseController):
@@ -1520,7 +1523,7 @@ class TicketController(BaseController, FeedController):
         c.app.globals.invalidate_bin_counts()
         redirect('.')
 
-    @expose()
+    @expose('json:')
     @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None):
@@ -1528,7 +1531,10 @@ class TicketController(BaseController, FeedController):
             self.ticket.subscribe(type='direct')
         elif unsubscribe:
             self.ticket.unsubscribe()
-        redirect(request.referer)
+        return {
+            'status': 'ok',
+            'subscribed': M.Mailbox.subscribed(artifact=self.ticket),
+        }
 
     @expose('json:')
     @require_post()

http://git-wip-us.apache.org/repos/asf/allura/blob/19b9fef5/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 229a348..9fca1c2 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -737,7 +737,7 @@ class PageController(BaseController, FeedController):
         self.page.add_multiple_attachments(file_info)
         redirect(request.referer)
 
-    @expose()
+    @expose('json:')
     @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None, **kw):
@@ -747,7 +747,10 @@ class PageController(BaseController, FeedController):
             self.page.subscribe(type='direct')
         elif unsubscribe:
             self.page.unsubscribe()
-        redirect(request.referer)
+        return {
+            'status': 'ok',
+            'subscribed': M.Mailbox.subscribed(artifact=self.page),
+        }
 
 
 class WikiAttachmentController(ac.AttachmentController):


[23/29] allura git commit: [#7685] ticket:802 Fixed test

Posted by je...@apache.org.
[#7685] ticket:802 Fixed test


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

Branch: refs/heads/ib/7685
Commit: dc19b4b3f12d2e09c566a1cf3f08c9082a0efec2
Parents: a6617a8
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Mon Jun 29 14:01:55 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Jul 10 15:59:00 2015 +0300

----------------------------------------------------------------------
 ForgeTracker/forgetracker/tests/functional/test_root.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/dc19b4b3/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 0e47f68..4bc64d9 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -840,7 +840,7 @@ class TestFunctionalController(TrackerTestController):
         }, upload_files=[upload]).follow()
         assert file_name in ticket_editor, ticket_editor.showbrowser()
         req = self.app.get('/bugs/1/')
-        file_link = req.html.findAll('form')[3].findAll('a')[6]
+        file_link = req.html.findAll('form')[2].findAll('a')[6]
         assert_equal(file_link.string, file_name)
         self.app.post(str(file_link['href']), {
             'delete': 'True'


[11/29] allura git commit: [#6373] delete scripts that are no longer needed. Rename to clarify a few

Posted by je...@apache.org.
[#6373] delete scripts that are no longer needed.  Rename to clarify a few


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

Branch: refs/heads/ib/7685
Commit: 3189602c97b6c04414b60cbf1cfaf82893dc2437
Parents: c95885e
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Jul 8 15:59:29 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jul 8 17:00:50 2015 -0400

----------------------------------------------------------------------
 scripts/allura_import.py                     | 119 ------------------
 scripts/import_trove_categories.py           |  48 -------
 scripts/open_relay.py                        |  89 -------------
 scripts/prep-scm-sandbox.py                  |  94 --------------
 scripts/prepare-allura-tickets-for-import.py | 147 ----------------------
 scripts/recover-user-databases.py            |  72 -----------
 scripts/setup-scm-server.py                  | 127 -------------------
 scripts/trac_export_wiki.py                  |  56 +++++++++
 scripts/trac_import.py                       | 119 ++++++++++++++++++
 scripts/wiki-export.py                       |  56 ---------
 10 files changed, 175 insertions(+), 752 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/3189602c/scripts/allura_import.py
----------------------------------------------------------------------
diff --git a/scripts/allura_import.py b/scripts/allura_import.py
deleted file mode 100644
index d4e51fd..0000000
--- a/scripts/allura_import.py
+++ /dev/null
@@ -1,119 +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 json
-from optparse import OptionParser
-
-from allura.lib.import_api import AlluraImportApiClient
-from tracwikiimporter.scripts.wiki_from_trac.loaders import import_wiki
-
-
-def main():
-    optparser, options, args = parse_options()
-
-    import_options = {}
-    for s in options.import_opts:
-        k, v = s.split('=', 1)
-        if v == 'false':
-            v = False
-        import_options[k] = v
-
-    user_map = {}
-    if options.user_map_file:
-        f = open(options.user_map_file)
-        try:
-            user_map = json.load(f)
-            if type(user_map) is not type({}):
-                raise ValueError
-            for k, v in user_map.iteritems():
-                print k, v
-                if not isinstance(k, basestring) or not isinstance(v, basestring):
-                    raise ValueError
-        except ValueError:
-            optparser.error(
-                '--user-map should specify JSON file with format {"original_user": "sf_user", ...}')
-        finally:
-            f.close()
-
-    import_options['user_map'] = user_map
-
-    cli = AlluraImportApiClient(options.base_url, options.token, options.verbose)
-    doc_txt = open(args[0]).read()
-
-    if options.forum:
-        import_forum(cli, options.project, options.forum, user_map, doc_txt,
-                     validate=options.validate, neighborhood=options.neighborhood)
-    elif options.wiki:
-        import_wiki(cli, options.project, options.wiki, options, doc_txt)
-
-
-
-def import_forum(cli, project, tool, user_map, doc_txt, validate=True,
-        neighborhood='p'):
-    url = '/rest/{neighborhood}/{project}/{tool}'.format(
-            neighborhood=neighborhood,
-            project=project,
-            tool=tool,
-            )
-    if validate:
-        url += '/validate_import'
-        print cli.call(url, doc=doc_txt, user_map=json.dumps(user_map))
-    else:
-        url += '/perform_import'
-        print cli.call(url, doc=doc_txt, user_map=json.dumps(user_map))
-
-
-def parse_options():
-    optparser = OptionParser(usage='''%prog [options] <JSON dump>
-
-Import project data dump in JSON format into an Allura project.''')
-    optparser.add_option('-t', '--token', dest='token',
-                         help='OAuth bearer token (generate at /auth/oauth/)')
-    optparser.add_option('-p', '--project', dest='project',
-                         help='Project to import to')
-    optparser.add_option('-n', '--neighborhood', dest='neighborhood',
-                         help="URL prefix of destination neighborhood (default is 'p')",
-                         default='p')
-    optparser.add_option('-f', '--forum', dest='forum',
-                         help='Forum tool to import to')
-    optparser.add_option('-w', '--wiki', dest='wiki',
-                         help='Wiki tool to import to')
-    optparser.add_option('-u', '--base-url', dest='base_url',
-                         default='https://sourceforge.net', help='Base Allura URL (%default)')
-    optparser.add_option('-o', dest='import_opts',
-                         default=[], action='append', help='Specify import option(s)', metavar='opt=val')
-    optparser.add_option('--user-map', dest='user_map_file',
-                         help='Map original users to SF.net users', metavar='JSON_FILE')
-    optparser.add_option('--validate', dest='validate',
-                         action='store_true', help='Validate import data')
-    optparser.add_option('-v', '--verbose', dest='verbose',
-                         action='store_true', help='Verbose operation')
-    optparser.add_option('-c', '--continue', dest='cont',
-                         action='store_true', help='Continue import into existing tracker')
-    options, args = optparser.parse_args()
-    if len(args) != 1:
-        optparser.error("Wrong number of arguments")
-    if not options.token:
-        optparser.error("OAuth bearer token is required")
-    if not options.project:
-        optparser.error("Target project is required")
-    options.neighborhood = options.neighborhood.strip('/')
-    return optparser, options, args
-
-
-if __name__ == '__main__':
-    main()

http://git-wip-us.apache.org/repos/asf/allura/blob/3189602c/scripts/import_trove_categories.py
----------------------------------------------------------------------
diff --git a/scripts/import_trove_categories.py b/scripts/import_trove_categories.py
deleted file mode 100644
index 123a56c..0000000
--- a/scripts/import_trove_categories.py
+++ /dev/null
@@ -1,48 +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 config
-
-from ming.orm import session
-
-import sfx
-from allura import model as M
-from allura.lib import helpers as h
-from sfx.model import tables as T
-
-log = logging.getLogger(__name__)
-
-
-def main():
-    sfx.middleware.configure_databases(h.config_with_prefix(config, 'sfx.'))
-    topic_trove = T.trove_cat.select(
-        T.trove_cat.c.shortname == 'topic').execute().fetchone()
-    M.ProjectCategory.query.remove()
-    for t in T.trove_cat.select(
-            T.trove_cat.c.parent == topic_trove.trove_cat_id).execute():
-        parent = M.ProjectCategory(
-            name=t.shortname, label=t.fullname, description=t.description)
-        for tt in T.trove_cat.select(
-                T.trove_cat.c.parent == t.trove_cat_id).execute():
-            M.ProjectCategory(parent_id=parent._id,
-                              name=tt.shortname, label=tt.fullname, description=tt.description)
-    session(M.ProjectCategory).flush()
-
-if __name__ == '__main__':
-    main()

http://git-wip-us.apache.org/repos/asf/allura/blob/3189602c/scripts/open_relay.py
----------------------------------------------------------------------
diff --git a/scripts/open_relay.py b/scripts/open_relay.py
deleted file mode 100644
index ba21862..0000000
--- a/scripts/open_relay.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/env python
-
-#       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
-import os
-import smtpd
-import smtplib
-import asyncore
-from ConfigParser import ConfigParser
-
-log = logging.getLogger(__name__)
-
-
-def main():
-    cp = ConfigParser()
-    log.info('Read config from: %s',
-             cp.read([os.path.join(os.environ['HOME'], '.open_relay.ini')]))
-    host = cp.get('open_relay', 'host')
-    port = cp.getint('open_relay', 'port')
-    ssl = cp.getboolean('open_relay', 'ssl')
-    tls = cp.getboolean('open_relay', 'tls')
-    username = cp.get('open_relay', 'username')
-    password = cp.get('open_relay', 'password')
-    smtp_client = MailClient(host,
-                             port,
-                             ssl, tls,
-                             username, password)
-    MailServer(('0.0.0.0', 8826), None,
-               smtp_client=smtp_client)
-    asyncore.loop()
-
-
-class MailClient(object):
-
-    def __init__(self, host, port, ssl, tls, username, password):
-        self.host, self.port, self.ssl, self.tls, self.username, self.password = \
-            host, port, ssl, tls, username, password
-        self._client = None
-        self._connect()
-
-    def sendmail(self, mailfrom, rcpttos, data):
-        if str(mailfrom) == 'None':
-            mailfrom = rcpttos[0]
-        log.info('Sending mail to %s' % rcpttos)
-        log.info('Sending mail from %s' % mailfrom)
-        try:
-            self._client.sendmail(mailfrom, rcpttos, data)
-        except:
-            self._connect()
-            self._client.sendmail(mailfrom, rcpttos, data)
-
-    def _connect(self):
-        if self.ssl:
-            self._client = smtplib.SMTP_SSL(self.host, int(self.port))
-        else:
-            self._client = smtplib.SMTP(self.host, int(self.port))
-        if self.tls:
-            self._client.starttls()
-        if self.username:
-            self._client.login(self.username, self.password)
-
-
-class MailServer(smtpd.SMTPServer):
-
-    def __init__(self, *args, **kwargs):
-        self._client = kwargs.pop('smtp_client')
-        smtpd.SMTPServer.__init__(self, *args, **kwargs)
-
-    def process_message(self, peer, mailfrom, rcpttos, data):
-        self._client.sendmail(mailfrom, rcpttos, data)
-
-if __name__ == '__main__':
-    main()

http://git-wip-us.apache.org/repos/asf/allura/blob/3189602c/scripts/prep-scm-sandbox.py
----------------------------------------------------------------------
diff --git a/scripts/prep-scm-sandbox.py b/scripts/prep-scm-sandbox.py
deleted file mode 100644
index 414280f..0000000
--- a/scripts/prep-scm-sandbox.py
+++ /dev/null
@@ -1,94 +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 os
-import string
-
-HOME = os.environ['HOME']
-
-USERS = ['user%.2d' % i for i in range(1, 21)]
-USERS += [
-    'admin1', 'admin2',
-    'dovethunder', 'dovetail', 'dovestream', 'dovetree', 'dovespangle',
-    'dovemeade', 'dovestar', 'dovebuyer', 'dovesomething', 'dovesweet', 'dovewood']
-SSH_CONFIG = '%s/.ssh/config' % HOME
-LDIF_FILE = '%s/users.ldif' % HOME
-KEYFILE = '%s/.ssh/allura_rsa' % HOME
-
-
-def main():
-
-    # Generate ssh key for SCM login
-    os.system('cp %s %s.bak' % (SSH_CONFIG, SSH_CONFIG))
-    with open(SSH_CONFIG) as fp:
-        lines = fp.readlines()
-    new_lines = [
-        SSH_TMPL.substitute(
-            sb_host=sb_host,
-            sb=sb,
-            veid='%d0%.2d' % (sb_host, sb))
-        for sb_host in 5, 6, 7, 9
-        for sb in range(99)]
-    new_lines = '\n'.join(new_lines)
-    found_star = False
-    with open(SSH_CONFIG, 'w') as fp:
-        for line in lines:
-            if not found_star and line.startswith('Host *'):
-                print >> fp, new_lines
-                found_star = True
-            print >> fp, line.rstrip()
-        if not found_star:
-            print >> fp, new_lines
-    os.system("ssh-keygen -t rsa -b 2048 -N '' -f %s" % KEYFILE)
-
-    # Generate ldif
-    pubkey = open(KEYFILE + '.pub').read()
-    with open(LDIF_FILE, 'w') as fp:
-        for user in USERS:
-            print >> fp, LDIF_TMPL.substitute(
-                user=user, pubkey=pubkey)
-
-    # Update LDAP
-    assert 0 == os.system('/usr/local/sbin/ldaptool modify -v -f %s' %
-                          LDIF_FILE)
-
-SSH_TMPL = string.Template('''
-Host hg*-$veid hg*-${veid}.sb.sf.net
-  Hostname 10.58.${sb_host}.${sb}
-  Port 17
-  IdentityFile ~/.ssh/allura_rsa
-
-Host svn*-$veid svn*-${veid}.sb.sf.net
-  Hostname 10.58.${sb_host}.${sb}
-  Port 16
-  IdentityFile ~/.ssh/allura_rsa
-
-Host git*-$veid git*-${veid}.sb.sf.net
-  Hostname 10.58.${sb_host}.${sb}
-  Port 23
-  IdentityFile ~/.ssh/allura_rsa
-''')
-
-LDIF_TMPL = string.Template('''
-dn: cn=$user,ou=users,dc=sf,dc=net
-changetype: modify
-add: sshPublicKey
-sshPublicKey: $pubkey
-''')
-
-if __name__ == '__main__':
-    main()

http://git-wip-us.apache.org/repos/asf/allura/blob/3189602c/scripts/prepare-allura-tickets-for-import.py
----------------------------------------------------------------------
diff --git a/scripts/prepare-allura-tickets-for-import.py b/scripts/prepare-allura-tickets-for-import.py
deleted file mode 100644
index dc6a695..0000000
--- a/scripts/prepare-allura-tickets-for-import.py
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/usr/bin/env python
-#       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 itertools import tee, izip, chain
-import json
-import git
-from collections import Counter
-
-'''
-This script is for one-time conversion of Allura's own tickets from SourceForge
-host to forge-allura.apache.org hosting
-
-Change path variables here:
-'''
-
-filename = "/var/local/allura/tickets.json"  # Absolute path to exported tickets.json
-output = "/var/local/allura/updated_tickets.json"  # Absolute path to the output
-ticket_list = "/var/local/allura/ticket_ids.list"
-top_usernames = "/var/local/allura/top_usernames.list"
-gitrepository = "/var/local/allura"  # Path to allura repository
-g = git.Git(gitrepository)
-
-reviews = ['code-review', 'design-review']
-
-with open(filename, 'r') as json_file:
-    data = json.loads(json_file.read())
-
-
-def pairwise(iterable):
-    """s -> (s0,s1), (s1,s2), (s2, s3), ..."""
-    a, b = tee(iterable)
-    next(b, None)
-    return izip(a, b)
-
-
-tags = ['asf_release_1.0.0', 'asf_release_1.0.0-RC1', 'asf_release_1.0.1', 'asf_release_1.1.0', 'HEAD']
-
-tag_log = dict()
-for tag1, tag2 in pairwise(tags):
-    log = g.log('%s...%s' % (tag1, tag2), '--pretty=oneline')
-    tag_log[tag2] = log
-
-ticket_tag = dict()
-tickets = data.pop('tickets')
-for ticket in tickets:
-    for key, value in tag_log.iteritems():
-        if "[#%s]" % ticket['ticket_num'] in value:
-            ticket_tag[ticket['ticket_num']] = key
-            continue
-
-data.pop('milestones', None)
-data.pop('saved_bins', None)
-
-updated = []
-for ticket in tickets:
-    if not ticket['private'] or ticket['ticket_num'] == 6054:
-        if ticket['status'] in reviews:
-            ticket['status'] = 'review'
-
-        milestone = ticket_tag.get(ticket['ticket_num'], None)
-        if not milestone:
-            if ticket['status'] == 'closed':
-                milestone = tags[0]
-        ticket['custom_fields']['_milestone'] = milestone if milestone and milestone != 'HEAD' else 'unreleased'
-        if '_size' in ticket['custom_fields'].keys():
-            size = ticket['custom_fields']['_size']
-            if size:
-                ticket['labels'].append("sf-%d" % int(size))
-            ticket['custom_fields'].pop('_size', None)
-
-        if '_qa' in ticket['custom_fields'].keys():
-            ticket['custom_fields']['_reviewer'] = ticket['custom_fields']['_qa']
-            ticket['custom_fields'].pop('_qa', None)
-        updated.append(ticket)
-tags[-1] = 'unreleased'
-
-data['tickets'] = updated
-
-# Remove milestones from the list
-custom_fields = filter(lambda d: d.get('name') not in ['_milestone', 'name', '_size', '_qa'], data['custom_fields'])
-data['custom_fields'] = custom_fields
-
-milestones = {
-    "milestones": [
-        dict(name=milestone_name,
-             old_name=milestone_name,
-             default=False,
-             complete=False,
-             due_date="",
-             description="")
-        for milestone_name in tags
-    ],
-    "name": "_milestone",
-    "show_in_search": False,
-    "label": "Milestone",
-    "type": "milestone",
-    "options": ""
-}
-data['custom_fields'].append(milestones)
-data['custom_fields'].append({
-    "show_in_search": True,
-    "label": "Reviewer",
-    "type": "user",
-    "options": "",
-    "name": "_reviewer"
-})
-data['milestones'] = milestones
-data['saved_bins'] = []
-
-# Count top used usernames
-
-assigned_to = [ticket.get('assigned_to', None) for ticket in updated]
-reported_by = [ticket.get('reported_by', None) for ticket in updated]
-reviewed_by = [ticket['custom_fields'].get('_reviewer', None) for ticket in updated]
-
-posts = [ticket['discussion_thread']['posts'] for ticket in updated]
-
-post_authors = [post.get('author', None) for post in list(chain(*posts))]
-
-usernames = filter(lambda x: bool(x), chain(assigned_to, reported_by, reviewed_by, post_authors))
-
-top_users = Counter(usernames).most_common(50)
-
-with open(output, 'w') as outfile:
-    json.dump(data, outfile, indent=2)
-
-with open(ticket_list, 'w') as outfile:
-    outfile.write('\n'.join(sorted([str(ticket['ticket_num']) for ticket in updated])))
-
-with open(top_usernames, 'w') as outfile:
-    lines = ["%s - %s" % (username, frequency) for username, frequency in top_users]
-    outfile.write('\n'.join(lines))
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/3189602c/scripts/recover-user-databases.py
----------------------------------------------------------------------
diff --git a/scripts/recover-user-databases.py b/scripts/recover-user-databases.py
deleted file mode 100644
index 5abf6f3..0000000
--- a/scripts/recover-user-databases.py
+++ /dev/null
@@ -1,72 +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 sys
-import logging
-
-from ming.orm import session
-
-from allura import model as M
-
-log = logging.getLogger(__name__)
-
-IGNORED_COLLECTIONS = [
-    '_flyway_migration_info',
-    'user',
-    'config',
-    'system.indexes']
-
-
-def main():
-    conn = M.session.main_doc_session.bind.conn
-    n = M.Neighborhood.query.get(url_prefix='/u/')
-    for p in M.Project.query.find(dict(neighborhood_id=n._id)):
-        if not p.database_configured:
-            continue
-        if not p.shortname.startswith('u/'):
-            continue
-        log.info('Checking to see if %s is configured...', p.database)
-        db = conn[p.database]
-        if is_unconfigured(db):
-            if sys.argv[-1] == 'test':
-                log.info('... it is not, so I would drop it.')
-                continue
-            log.info('... it is not, so dropping it.')
-            conn.drop_database(p.database)
-            p.database_configured = False
-            session(p).flush()
-        else:
-            log.info('... it is.')
-
-
-def is_unconfigured(db):
-    # Check for data in collections other than those we pre-fill with data
-    for collection_name in db.collection_names():
-        if collection_name in IGNORED_COLLECTIONS:
-            continue
-        collection = db[collection_name]
-        if collection.count():
-            log.info('...%s has data', collection_name)
-            return False
-    # DB is configured if it has more than profile/admin/search tools installed
-    if db.config.count() != 3:
-        log.info('...has %d tools', db.config.count())
-        return False
-    return True
-
-if __name__ == '__main__':
-    main()

http://git-wip-us.apache.org/repos/asf/allura/blob/3189602c/scripts/setup-scm-server.py
----------------------------------------------------------------------
diff --git a/scripts/setup-scm-server.py b/scripts/setup-scm-server.py
deleted file mode 100644
index 050122c..0000000
--- a/scripts/setup-scm-server.py
+++ /dev/null
@@ -1,127 +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 os
-import string
-from tempfile import mkstemp
-from ConfigParser import ConfigParser, NoOptionError
-
-config = ConfigParser()
-
-
-def main():
-    config.read('.setup-scm-cache')
-    if not config.has_section('scm'):
-        config.add_section('scm')
-    domain = get_value('domain', 'dc=example,dc=com')
-    if config.get('start slapd', 'y') == 'y':
-        run('service slapd start')
-    if config.get('add base ldap schemas', 'y') == 'y':
-        run('ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/cosine.ldif')
-        run('ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/nis.ldif')
-        run('ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/inetorgperson.ldif')
-    secret = config.get('admin password', 'secret')
-    if config.get('add backend ldif', 'y') == 'y':
-        add_ldif(backend_ldif, domain=domain, secret=secret)
-    if config.get('add frontend ldif', 'y') == 'y':
-        add_ldif(frontend_ldif, domain=domain, secret=secret)
-
-
-def get_value(key, default):
-    try:
-        value = config.get('scm', key)
-    except NoOptionError:
-        value = raw_input('%s? [%s]' % key, default)
-        if not value:
-            value = default
-        config.set('scm', key, value)
-    return value
-
-
-def run(command):
-    rc = os.system(command)
-    assert rc == 0
-    return rc
-
-
-def add_ldif(template, **values):
-    fd, name = mkstemp()
-    os.write(fd, template.substitute(values))
-    os.close(fd)
-    run('ldapadd -Y EXTERNAL -H ldapi:/// -f %s' % name)
-    os.remove(name)
-
-backend_ldif = string.Template('''
-# Load dynamic backend modules
-dn: cn=module,cn=config
-objectClass: olcModuleList
-cn: module
-olcModulepath: /usr/lib/ldap
-olcModuleload: back_hdb
-
-# Database settings
-dn: olcDatabase=hdb,cn=config
-objectClass: olcDatabaseConfig
-objectClass: olcHdbConfig
-olcDatabase: {1}hdb
-olcSuffix: $domain
-olcDbDirectory: /var/lib/ldap
-olcRootDN: cn=admin,$domain
-olcRootPW: $secret
-olcDbConfig: set_cachesize 0 2097152 0
-olcDbConfig: set_lk_max_objects 1500
-olcDbConfig: set_lk_max_locks 1500
-olcDbConfig: set_lk_max_lockers 1500
-olcDbIndex: objectClass eq
-olcLastMod: TRUE
-olcDbCheckpoint: 512 30
-olcAccess: to attrs=userPassword by dn="cn=admin,$domain" write by anonymous auth by self write by * none
-olcAccess: to attrs=shadowLastChange by self write by * read
-olcAccess: to dn.base="" by * read
-olcAccess: to * by dn="cn=admin,$domain" write by * read
-
-''')
-
-frontend_ldif = string.Template('''
-# Create top-level object in domain
-dn: $domain
-objectClass: top
-objectClass: dcObject
-objectclass: organization
-o: SCM Host Organization
-dc: SCM
-description: SCM Host Server
-
-# Admin user.
-dn: cn=admin,$domain
-objectClass: simpleSecurityObject
-objectClass: organizationalRole
-cn: admin
-description: LDAP administrator
-userPassword: $secret
-
-dn: ou=people,$domain
-objectClass: organizationalUnit
-ou: people
-
-dn: ou=groups,$domain
-objectClass: organizationalUnit
-ou: groups
-''')
-
-if __name__ == '__main__':
-    main()

http://git-wip-us.apache.org/repos/asf/allura/blob/3189602c/scripts/trac_export_wiki.py
----------------------------------------------------------------------
diff --git a/scripts/trac_export_wiki.py b/scripts/trac_export_wiki.py
new file mode 100755
index 0000000..025d3ca
--- /dev/null
+++ b/scripts/trac_export_wiki.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+
+#       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 sys
+from optparse import OptionParser
+
+from tracwikiimporter.scripts.wiki_from_trac.extractors import WikiExporter
+
+
+def parse_options():
+    parser = OptionParser(
+        usage='%prog <Trac URL>\n\nExport wiki pages from a trac instance')
+
+    parser.add_option('-o', '--out-file', dest='out_filename',
+                      help='Write to file (default stdout)')
+    parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
+                      help='Verbose operation')
+    parser.add_option('-c', '--converter', dest='converter',
+                      default='html2text',
+                      help='Converter to use on wiki text. '
+                           'Available options: html2text (default) or regex')
+    options, args = parser.parse_args()
+    if len(args) != 1:
+        parser.error('Wrong number of arguments.')
+    converters = ['html2text', 'regex']
+    if options.converter not in converters:
+        parser.error('Wrong converter. Available options: ' +
+                     ', '.join(converters))
+    return options, args
+
+
+if __name__ == '__main__':
+    options, args = parse_options()
+    exporter = WikiExporter(args[0], options)
+
+    out = sys.stdout
+    if options.out_filename:
+        out = open(options.out_filename, 'w')
+
+    exporter.export(out)

http://git-wip-us.apache.org/repos/asf/allura/blob/3189602c/scripts/trac_import.py
----------------------------------------------------------------------
diff --git a/scripts/trac_import.py b/scripts/trac_import.py
new file mode 100644
index 0000000..d4e51fd
--- /dev/null
+++ b/scripts/trac_import.py
@@ -0,0 +1,119 @@
+#       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 json
+from optparse import OptionParser
+
+from allura.lib.import_api import AlluraImportApiClient
+from tracwikiimporter.scripts.wiki_from_trac.loaders import import_wiki
+
+
+def main():
+    optparser, options, args = parse_options()
+
+    import_options = {}
+    for s in options.import_opts:
+        k, v = s.split('=', 1)
+        if v == 'false':
+            v = False
+        import_options[k] = v
+
+    user_map = {}
+    if options.user_map_file:
+        f = open(options.user_map_file)
+        try:
+            user_map = json.load(f)
+            if type(user_map) is not type({}):
+                raise ValueError
+            for k, v in user_map.iteritems():
+                print k, v
+                if not isinstance(k, basestring) or not isinstance(v, basestring):
+                    raise ValueError
+        except ValueError:
+            optparser.error(
+                '--user-map should specify JSON file with format {"original_user": "sf_user", ...}')
+        finally:
+            f.close()
+
+    import_options['user_map'] = user_map
+
+    cli = AlluraImportApiClient(options.base_url, options.token, options.verbose)
+    doc_txt = open(args[0]).read()
+
+    if options.forum:
+        import_forum(cli, options.project, options.forum, user_map, doc_txt,
+                     validate=options.validate, neighborhood=options.neighborhood)
+    elif options.wiki:
+        import_wiki(cli, options.project, options.wiki, options, doc_txt)
+
+
+
+def import_forum(cli, project, tool, user_map, doc_txt, validate=True,
+        neighborhood='p'):
+    url = '/rest/{neighborhood}/{project}/{tool}'.format(
+            neighborhood=neighborhood,
+            project=project,
+            tool=tool,
+            )
+    if validate:
+        url += '/validate_import'
+        print cli.call(url, doc=doc_txt, user_map=json.dumps(user_map))
+    else:
+        url += '/perform_import'
+        print cli.call(url, doc=doc_txt, user_map=json.dumps(user_map))
+
+
+def parse_options():
+    optparser = OptionParser(usage='''%prog [options] <JSON dump>
+
+Import project data dump in JSON format into an Allura project.''')
+    optparser.add_option('-t', '--token', dest='token',
+                         help='OAuth bearer token (generate at /auth/oauth/)')
+    optparser.add_option('-p', '--project', dest='project',
+                         help='Project to import to')
+    optparser.add_option('-n', '--neighborhood', dest='neighborhood',
+                         help="URL prefix of destination neighborhood (default is 'p')",
+                         default='p')
+    optparser.add_option('-f', '--forum', dest='forum',
+                         help='Forum tool to import to')
+    optparser.add_option('-w', '--wiki', dest='wiki',
+                         help='Wiki tool to import to')
+    optparser.add_option('-u', '--base-url', dest='base_url',
+                         default='https://sourceforge.net', help='Base Allura URL (%default)')
+    optparser.add_option('-o', dest='import_opts',
+                         default=[], action='append', help='Specify import option(s)', metavar='opt=val')
+    optparser.add_option('--user-map', dest='user_map_file',
+                         help='Map original users to SF.net users', metavar='JSON_FILE')
+    optparser.add_option('--validate', dest='validate',
+                         action='store_true', help='Validate import data')
+    optparser.add_option('-v', '--verbose', dest='verbose',
+                         action='store_true', help='Verbose operation')
+    optparser.add_option('-c', '--continue', dest='cont',
+                         action='store_true', help='Continue import into existing tracker')
+    options, args = optparser.parse_args()
+    if len(args) != 1:
+        optparser.error("Wrong number of arguments")
+    if not options.token:
+        optparser.error("OAuth bearer token is required")
+    if not options.project:
+        optparser.error("Target project is required")
+    options.neighborhood = options.neighborhood.strip('/')
+    return optparser, options, args
+
+
+if __name__ == '__main__':
+    main()

http://git-wip-us.apache.org/repos/asf/allura/blob/3189602c/scripts/wiki-export.py
----------------------------------------------------------------------
diff --git a/scripts/wiki-export.py b/scripts/wiki-export.py
deleted file mode 100755
index 025d3ca..0000000
--- a/scripts/wiki-export.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python
-
-#       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 sys
-from optparse import OptionParser
-
-from tracwikiimporter.scripts.wiki_from_trac.extractors import WikiExporter
-
-
-def parse_options():
-    parser = OptionParser(
-        usage='%prog <Trac URL>\n\nExport wiki pages from a trac instance')
-
-    parser.add_option('-o', '--out-file', dest='out_filename',
-                      help='Write to file (default stdout)')
-    parser.add_option('-v', '--verbose', dest='verbose', action='store_true',
-                      help='Verbose operation')
-    parser.add_option('-c', '--converter', dest='converter',
-                      default='html2text',
-                      help='Converter to use on wiki text. '
-                           'Available options: html2text (default) or regex')
-    options, args = parser.parse_args()
-    if len(args) != 1:
-        parser.error('Wrong number of arguments.')
-    converters = ['html2text', 'regex']
-    if options.converter not in converters:
-        parser.error('Wrong converter. Available options: ' +
-                     ', '.join(converters))
-    return options, args
-
-
-if __name__ == '__main__':
-    options, args = parse_options()
-    exporter = WikiExporter(args[0], options)
-
-    out = sys.stdout
-    if options.out_filename:
-        out = open(options.out_filename, 'w')
-
-    exporter.export(out)


[06/29] allura git commit: [#6373] cross link our different APIs

Posted by je...@apache.org.
[#6373] cross link our different APIs


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

Branch: refs/heads/ib/7685
Commit: be3845c3d60e2c42e7040067590745db0c052fa2
Parents: acd50e8
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Jul 7 16:34:18 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jul 8 17:00:48 2015 -0400

----------------------------------------------------------------------
 Allura/docs/api/index.rst                      | 4 ++++
 Allura/docs/getting_started/administration.rst | 1 +
 2 files changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/be3845c3/Allura/docs/api/index.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/api/index.rst b/Allura/docs/api/index.rst
index 2103410..451972a 100644
--- a/Allura/docs/api/index.rst
+++ b/Allura/docs/api/index.rst
@@ -19,6 +19,10 @@
 Allura API
 **********
 
+This documents the python classes available to Allura tools and extensions.
+
+If you are looking for the web REST API, see :ref:`public_api`
+
 
 .. toctree::
     :maxdepth: 3

http://git-wip-us.apache.org/repos/asf/allura/blob/be3845c3/Allura/docs/getting_started/administration.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/administration.rst b/Allura/docs/getting_started/administration.rst
index 0b03728..e8952b9 100644
--- a/Allura/docs/getting_started/administration.rst
+++ b/Allura/docs/getting_started/administration.rst
@@ -200,6 +200,7 @@ users, projects, and tools on Allura.  However, SourceForge has help docs that c
 these functions https://sourceforge.net/p/forge/documentation/Docs%20Home/  Note
 that this documentation also covers some SourceForge features that are not part of Allura.
 
+.. _public_api:
 
 Public API Documentation
 ========================


[21/29] allura git commit: [#7685] ticket:802 Fixed subscription to whole wiki

Posted by je...@apache.org.
[#7685] ticket:802 Fixed subscription to whole wiki


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

Branch: refs/heads/ib/7685
Commit: 5ea0ba1a4953f18d19ede311f76db6d5dfaac617
Parents: d08f814
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Thu Jul 2 16:26:09 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Jul 10 15:59:00 2015 +0300

----------------------------------------------------------------------
 ForgeWiki/forgewiki/templates/wiki/page_view.html | 12 +++++++++++-
 ForgeWiki/forgewiki/wiki_main.py                  |  4 +++-
 2 files changed, 14 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/5ea0ba1a/ForgeWiki/forgewiki/templates/wiki/page_view.html
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/templates/wiki/page_view.html b/ForgeWiki/forgewiki/templates/wiki/page_view.html
index 7289f23..7a6135e 100644
--- a/ForgeWiki/forgewiki/templates/wiki/page_view.html
+++ b/ForgeWiki/forgewiki/templates/wiki/page_view.html
@@ -116,12 +116,22 @@
       {% endif %}
   {% endif %}
   {{c.confirmation.display(content='')}}
+  {% if not c.user.is_anonymous() %}
+    <form action="{{c.app.url}}subscribe" id="wiki_subscribe_form" style="display:none;" method="POST">
+      {{lib.csrf_token()}}
+      {% if c.subscribed %}
+        <input type="hidden" name="unsubscribe" value="1">
+      {% else %}
+        <input type="hidden" name="subscribe" value="1">
+      {% endif %}
+    </form>
+  {% endif %}
 {% endblock %}
 
 {% block wiki_extra_js %}
   <script type="text/javascript">
     $('a[href$="#toggle-subscribe"]').click(function() {
-      $('#subscribe_form').submit();
+      $('#wiki_subscribe_form').submit();
       return false;
     })
   </script>

http://git-wip-us.apache.org/repos/asf/allura/blob/5ea0ba1a/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 229b217..c2bcb16 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -249,7 +249,7 @@ The wiki uses [Markdown](%s) syntax.
             subscribe_title = '{}{}'.format(
                 subscribe_action.capitalize(),
                 '' if subscribed else ' to wiki')
-            subscribe_url = '{}#toggle-subscribe'.format(self.url, subscribe_action)
+            subscribe_url = '#toggle-subscribe'.format(self.url)
             links += [SitemapEntry(''),
                       SitemapEntry(subscribe_title, subscribe_url, ui_icon=g.icons['mail'])]
         if not admin_menu:
@@ -483,6 +483,8 @@ class PageController(BaseController, FeedController):
         if self.page is not None:
             self.attachment = WikiAttachmentsController(self.page)
         c.create_page_lightbox = W.create_page_lightbox
+        if not c.user.is_anonymous():
+            c.subscribed = M.Mailbox.subscribed()
 
     def _check_security(self):
         if self.page:


[03/29] allura git commit: [#7899] ticket:812 Add test for format=raw and fix unicode error

Posted by je...@apache.org.
[#7899] ticket:812 Add test for format=raw and fix unicode error


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

Branch: refs/heads/ib/7685
Commit: ffba7216b9a07bf5a1418180b771662f522e6c44
Parents: fdefe42
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Jul 6 16:13:50 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 6 16:13:50 2015 +0300

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py         |  2 +-
 .../tests/functional/test_controllers.py        | 37 ++++++++++++++++++--
 2 files changed, 35 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/ffba7216/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index e9f051d..f8b0834 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -739,7 +739,7 @@ class FileBrowser(BaseController):
             response.content_encoding = content_encoding
         response.headers.add(
             'Content-Disposition',
-            'attachment;filename="%s"' % filename.encode('utf-8'))
+            'attachment;filename="%s"' % filename)
         return iter(self._blob)
 
     def diff(self, commit, fmt=None, **kw):

http://git-wip-us.apache.org/repos/asf/allura/blob/ffba7216/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 917f765..b84cd5a 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -1,3 +1,5 @@
+# coding: utf-8
+
 #       Licensed to the Apache Software Foundation (ASF) under one
 #       or more contributor license agreements.  See the NOTICE file
 #       distributed with this work for additional information
@@ -78,6 +80,18 @@ class _TestCase(TestController):
 
 class TestRootController(_TestCase):
 
+
+    @with_tool('test', 'Git', 'weird-chars', 'WeirdChars', type='git')
+    def _setup_weird_chars_repo(self):
+        h.set_context('test', 'weird-chars', neighborhood='Projects')
+        repo_dir = pkg_resources.resource_filename(
+            'forgegit', 'tests/data')
+        c.app.repo.fs_path = repo_dir
+        c.app.repo.status = 'ready'
+        c.app.repo.name = 'weird-chars.git'
+        ThreadLocalORMSession.flush_all()
+        c.app.repo.refresh()
+
     def test_status(self):
         resp = self.app.get('/src-git/status')
         d = json.loads(resp.body)
@@ -164,11 +178,11 @@ class TestRootController(_TestCase):
     def test_tags(self):
         self.app.get('/src-git/ref/master~/tags/')
 
-    def _get_ci(self):
-        r = self.app.get('/src-git/ref/master/')
+    def _get_ci(self, repo='/p/test/src-git/'):
+        r = self.app.get(repo + 'ref/master/')
         resp = r.follow()
         for tag in resp.html.findAll('a'):
-            if tag['href'].startswith('/p/test/src-git/ci/'):
+            if tag['href'].startswith(repo + 'ci/'):
                 href = tag['href']
                 if href.endswith('tree/'):
                     href = href[:-5]
@@ -241,6 +255,23 @@ class TestRootController(_TestCase):
         assert '<span id="l1" class="code_block">' in resp
         assert 'var hash = window.location.hash.substring(1);' in resp
 
+    def test_file_raw(self):
+        self._setup_weird_chars_repo()
+        ci = self._get_ci(repo='/p/test/weird-chars/')
+        url = ci + 'tree/' + h.urlquote(u'привіт.txt') + '?format=raw'
+        resp = self.app.get(url)
+        assert_in(u'Привіт!\nWhich means Hello!', resp.body.decode('utf-8'))
+        assert_equal(
+            resp.headers.get('Content-Disposition').decode('utf-8'),
+            u'attachment;filename="привіт.txt"')
+
+        url = ci + 'tree/' + h.urlquote(u'with space.txt') + '?format=raw'
+        resp = self.app.get(url)
+        assert_in(u'with space', resp.body.decode('utf-8'))
+        assert_equal(
+            resp.headers.get('Content-Disposition').decode('utf-8'),
+            u'attachment;filename="with space.txt"')
+
     def test_invalid_file(self):
         ci = self._get_ci()
         self.app.get(ci + 'tree/READMEz', status=404)


[13/29] allura git commit: [#6373] Fix a typo

Posted by je...@apache.org.
[#6373] Fix a typo


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

Branch: refs/heads/ib/7685
Commit: 91e883f2dcb14d478ba7497db6923278c97d52bc
Parents: 2842760
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 9 11:31:24 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Thu Jul 9 11:31:24 2015 +0300

----------------------------------------------------------------------
 Allura/docs/getting_started/administration.rst | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/91e883f2/Allura/docs/getting_started/administration.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/administration.rst b/Allura/docs/getting_started/administration.rst
index abbe814..2b49c4e 100644
--- a/Allura/docs/getting_started/administration.rst
+++ b/Allura/docs/getting_started/administration.rst
@@ -38,7 +38,7 @@ The admin interface allows you to:
 * Search for users, view user details, update user status, email address, and reset their password
 * View background task statuses, and submit new background tasks
 * Manage "trove" categories (for user skill choices)
-* Subscriber a user to an artifact
+* Subscribe a user to an artifact
 * Reclone a repository
 
 Commands, Scripts, and Tasks
@@ -316,4 +316,4 @@ wiki-post.py
 ------------
 
 .. program-output:: python ../../scripts/wiki-post.py --help | sed 's/Usage: /Usage: python scripts\//'
-    :shell:
\ No newline at end of file
+    :shell:


[18/29] allura git commit: [#7916] better handling of user-projects that have different names than the usernames

Posted by je...@apache.org.
[#7916] better handling of user-projects that have different names than the usernames


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

Branch: refs/heads/ib/7685
Commit: 48d7c563f8ad72f0f72fbeae8002fbbc1b9e2a51
Parents: 338f454
Author: Dave Brondsema <da...@brondsema.net>
Authored: Thu Jul 9 15:21:48 2015 -0400
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Jul 10 14:19:04 2015 +0300

----------------------------------------------------------------------
 Allura/allura/controllers/project.py                |  9 +++++----
 Allura/allura/tests/functional/test_user_profile.py | 13 +++++++++++++
 2 files changed, 18 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/48d7c563/Allura/allura/controllers/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/project.py b/Allura/allura/controllers/project.py
index 195115f..4526e62 100644
--- a/Allura/allura/controllers/project.py
+++ b/Allura/allura/controllers/project.py
@@ -105,10 +105,11 @@ class NeighborhoodController(object):
             # create user-project if it is missing
             user = M.User.query.get(username=pname, disabled=False, pending=False)
             if user:
-                project = self.neighborhood.register_project(
-                    plugin.AuthenticationProvider.get(
-                        request).user_project_shortname(user),
-                    user=user, user_project=True)
+                project = user.private_project()
+                if project.shortname != self.prefix + pname:
+                    # might be different URL than the URL requested
+                    # e.g. if username isn't valid project name and user_project_shortname() converts the name
+                    redirect(project.url())
         if project is None:
             # look for neighborhood tools matching the URL
             project = self.neighborhood.neighborhood_project

http://git-wip-us.apache.org/repos/asf/allura/blob/48d7c563/Allura/allura/tests/functional/test_user_profile.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_user_profile.py b/Allura/allura/tests/functional/test_user_profile.py
index ffdde56..4425ace 100644
--- a/Allura/allura/tests/functional/test_user_profile.py
+++ b/Allura/allura/tests/functional/test_user_profile.py
@@ -53,6 +53,19 @@ class TestUserProfile(TestController):
         assert p is not None and p.is_user_project
         response = self.app.get('/u/test-user/profile/', status=404)
 
+    def test_differing_profile_proj_shortname(self):
+        User.upsert('foo_bar')
+
+        # default auth provider's user_project_shortname() converts _ to - for the project name
+        response = self.app.get('/u/foo_bar/profile/', status=302)
+        assert_equal(response.location, 'http://localhost/u/foo-bar/')
+
+        # unfortunately this doesn't work because the default auth provider's user_by_project_shortname()
+        # doesn't try converting back (and it probably shouldn't since you could get multiple users with conflicting proj names)
+        # at least this works with other auth providers that have a more complete implementation of both
+        # user_project_shortname() and user_by_project_shortname()
+        #self.app.get('/u/foo-bar/profile/')
+
     @td.with_user_project('test-admin')
     @td.with_wiki
     def test_feed(self):


[29/29] allura git commit: [#7685] ticket:819 Fix tests failing due to new markup

Posted by je...@apache.org.
[#7685] ticket:819 Fix tests failing due to new markup


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

Branch: refs/heads/ib/7685
Commit: c1a103d29130f95b12eb27f70a86810f6e4ea4aa
Parents: 19b9fef
Author: Igor Bondarenko <je...@gmail.com>
Authored: Mon Jul 13 12:32:15 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 13 12:32:15 2015 +0300

----------------------------------------------------------------------
 AlluraTest/alluratest/controller.py             | 16 ++++++++++++
 .../tests/functional/test_controllers.py        | 26 +++++++++++---------
 .../forgetracker/tests/functional/test_root.py  | 25 ++++++++++---------
 .../forgewiki/tests/functional/test_rest.py     |  2 +-
 .../forgewiki/tests/functional/test_root.py     |  2 --
 5 files changed, 44 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c1a103d2/AlluraTest/alluratest/controller.py
----------------------------------------------------------------------
diff --git a/AlluraTest/alluratest/controller.py b/AlluraTest/alluratest/controller.py
index 4a8f983..5a61ab7 100644
--- a/AlluraTest/alluratest/controller.py
+++ b/AlluraTest/alluratest/controller.py
@@ -18,6 +18,7 @@
 """Unit and functional test suite for allura."""
 import os
 import urllib
+import json
 
 import mock
 import beaker.session
@@ -169,6 +170,21 @@ class TestController(object):
         "Extract webflash content from response."
         return urllib.unquote(response.cookies_set.get('webflash', ''))
 
+    def subscription_options(self, response):
+        """
+        Extract subscription options to be passed to React SubscriptionForm
+        component from the <script> tag
+        """
+        script = None
+        for s in response.html.findAll('script'):
+            if s.getText().strip().startswith('document.SUBSCRIPTION_OPTIONS'):
+                script = s
+                break
+        assert script is not None, 'subscription options not found'
+        _, json_dict = script.getText().split('=')
+        json_dict = json_dict.strip(' ;')
+        return json.loads(json_dict)
+
 
 class TestRestApiBase(TestController):
 

http://git-wip-us.apache.org/repos/asf/allura/blob/c1a103d2/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index 20bfc1b..7f6bf88 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -349,30 +349,32 @@ class TestRootController(_TestCase):
         assert not M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get(ci + 'tree/',
                          extra_environ={'username': str(user.username)})
-        link = r.html.find('a', 'artifact_subscribe')
-        assert link is not None, r.html
+        opts = self.subscription_options(r)
+        assert_equal(opts['subscribed'], False)
 
         # subscribe
-        self.app.post(str(ci + 'tree/subscribe'),
-                      {'subscribe': True},
-                      extra_environ={'username': str(user.username)}).follow()
+        r = self.app.post(str(ci + 'tree/subscribe'),
+                          {'subscribe': True},
+                          extra_environ={'username': str(user.username)})
+        assert_equal(r.json, {'status': 'ok', 'subscribed': True})
         # user is subscribed
         assert M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get(ci + 'tree/',
                          extra_environ={'username': str(user.username)})
-        inp = r.html.find('input', {'type': 'hidden', 'name': 'unsubscribe'})
-        assert inp is not None
+        opts = self.subscription_options(r)
+        assert_equal(opts['subscribed'], True)
 
         # unsubscribe
-        self.app.post(str(ci + 'tree/subscribe'),
-                     {'unsubscribe': True},
-                     extra_environ={'username': str(user.username)}).follow()
+        r = self.app.post(str(ci + 'tree/subscribe'),
+                          {'unsubscribe': True},
+                          extra_environ={'username': str(user.username)})
+        assert_equal(r.json, {'status': 'ok', 'subscribed': False})
         # user is not subscribed
         assert not M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get(ci + 'tree/',
                          extra_environ={'username': str(user.username)})
-        inp = r.html.find('input', {'type': 'hidden', 'name': 'subscribe'})
-        assert inp is not None
+        opts = self.subscription_options(r)
+        assert_equal(opts['subscribed'], False)
 
     def test_timezone(self):
         ci = self._get_ci()

http://git-wip-us.apache.org/repos/asf/allura/blob/c1a103d2/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 4bc64d9..0c57808 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -294,7 +294,8 @@ class TestFunctionalController(TrackerTestController):
         summary = 'test new ticket'
         ticket_view = self.new_ticket(summary=summary).follow()
         assert_true(summary in ticket_view)
-        assert 'class="artifact_subscribe' in ticket_view
+        opts = self.subscription_options(ticket_view)
+        assert_equal(opts['subscribed'], False)
 
     def test_labels(self):
         ticket_view = self.new_ticket(summary='summary', labels="test label").follow()
@@ -840,7 +841,7 @@ class TestFunctionalController(TrackerTestController):
         }, upload_files=[upload]).follow()
         assert file_name in ticket_editor, ticket_editor.showbrowser()
         req = self.app.get('/bugs/1/')
-        file_link = req.html.findAll('form')[2].findAll('a')[6]
+        file_link = req.html.findAll('form')[1].findAll('a')[6]
         assert_equal(file_link.string, file_name)
         self.app.post(str(file_link['href']), {
             'delete': 'True'
@@ -882,7 +883,7 @@ class TestFunctionalController(TrackerTestController):
         ticket_editor = self.app.post('/bugs/1/update_ticket', {
             'summary': 'zzz'
         }, upload_files=[upload]).follow()
-        download = self.app.get(str(ticket_editor.html.findAll('form')[2].findAll('a')[7]['href']))
+        download = self.app.get(str(ticket_editor.html.findAll('form')[1].findAll('a')[7]['href']))
         assert_equal(download.body, file_data)
 
     def test_two_attachments(self):
@@ -1239,7 +1240,7 @@ class TestFunctionalController(TrackerTestController):
         # Test edit ticket form
         self.new_ticket(summary='Test ticket')
         response = self.app.get('/bugs/1/')
-        form = response.forms[2]
+        form = response.forms[1]
         assert_equal(
             form['ticket_form.custom_fields._priority'].value, 'normal')
         assert_equal(form['ticket_form.custom_fields._category'].value, '')
@@ -1247,9 +1248,9 @@ class TestFunctionalController(TrackerTestController):
         form['ticket_form.custom_fields._priority'] = 'urgent'
         form['ticket_form.custom_fields._category'] = 'bugs'
         error_form = form.submit()
-        assert_equal(error_form.forms[2]['ticket_form.custom_fields._priority'].value,
+        assert_equal(error_form.forms[1]['ticket_form.custom_fields._priority'].value,
                      'urgent')
-        assert_equal(error_form.forms[2]['ticket_form.custom_fields._category'].value,
+        assert_equal(error_form.forms[1]['ticket_form.custom_fields._category'].value,
                      'bugs')
 
     def test_new_ticket_validation(self):
@@ -1269,7 +1270,7 @@ class TestFunctionalController(TrackerTestController):
         # set a summary, submit, and check for success
         error_form.forms[1]['ticket_form.summary'] = summary
         success = error_form.forms[1].submit().follow().html
-        assert success.findAll('form')[2].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
+        assert success.findAll('form')[1].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
         assert success.find('input', {'name': 'ticket_form.summary'})['value'] == summary
 
     def test_edit_ticket_validation(self):
@@ -1280,7 +1281,7 @@ class TestFunctionalController(TrackerTestController):
         # check that existing form is valid
         assert response.html.find('input', {'name': 'ticket_form.summary'})['value'] == old_summary
         assert not response.html.find('div', {'class': 'error'})
-        form = response.forms[2]
+        form = response.forms[1]
         # try submitting with no summary set and check for error message
         form['ticket_form.summary'] = ""
         error_form = form.submit()
@@ -1289,11 +1290,11 @@ class TestFunctionalController(TrackerTestController):
         assert error_message.string == 'You must provide a Title'
         assert error_message.findPreviousSibling('input').get('name') == 'ticket_form.summary'
         # set a summary, submit, and check for success
-        error_form.forms[2]['ticket_form.summary'] = new_summary
-        r = error_form.forms[2].submit()
+        error_form.forms[1]['ticket_form.summary'] = new_summary
+        r = error_form.forms[1].submit()
         assert r.status_int == 302, r.showbrowser()
         success = r.follow().html
-        assert success.findAll('form')[2].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
+        assert success.findAll('form')[1].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
         assert success.find('input', {'name': 'ticket_form.summary'})['value'] == new_summary
 
     def test_home(self):
@@ -2700,7 +2701,7 @@ class TestCustomUserField(TrackerTestController):
     def test_change_user_field(self):
         kw = {'custom_fields._code_review': ''}
         r = self.new_ticket(summary='test custom fields', **kw).follow()
-        f = r.forms[2]
+        f = r.forms[1]
         # Populate ProjectUserCombo's select with option we want.
         # This is a workaround for tests,
         # in real enviroment this is populated via ajax.

http://git-wip-us.apache.org/repos/asf/allura/blob/c1a103d2/ForgeWiki/forgewiki/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_rest.py b/ForgeWiki/forgewiki/tests/functional/test_rest.py
index a2b58ae..6a5de3b 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_rest.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_rest.py
@@ -42,7 +42,7 @@ class TestWikiApi(TestRestApiBase):
 
     def test_get_page(self):
         r = self.app.get('/p/test/wiki/Home/')
-        discussion_url = r.html.findAll('form')[3]['action'][:-4]
+        discussion_url = r.html.findAll('form')[2]['action'][:-4]
         content = file(__file__).read()
         self.app.post('/wiki/Home/attach',
                       upload_files=[('file_info', 'test_root.py', content)])

http://git-wip-us.apache.org/repos/asf/allura/blob/c1a103d2/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index dafb74f..3f69d89 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -258,8 +258,6 @@ class TestRootController(TestController):
                 'labels': '',
                 'viewable_by-0.id': 'all'})
         self.app.post('/wiki/tést/revert', params=dict(version='1'))
-        response = self.app.get('/wiki/tést/')
-        assert 'Subscribe' in response
         response = self.app.get('/wiki/tést/diff?v1=0&v2=0')
         assert 'tést' in response
         d = dict(title='testdiff', text="""**Optionally**, you may also want to remove all the unused accounts that have accumulated (one was created for *every* logged in SF-user who has visited your MediaWiki hosted app):


[24/29] allura git commit: [#7685] ticket:802 Add trailing slash to discussion controller

Posted by je...@apache.org.
[#7685] ticket:802 Add trailing slash to discussion controller


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

Branch: refs/heads/ib/7685
Commit: 25ae621920ac6344ad431498102cbb55274159ad
Parents: be2190a
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 3 12:53:50 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Jul 10 15:59:00 2015 +0300

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


http://git-wip-us.apache.org/repos/asf/allura/blob/25ae6219/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 13fe436..b329b01 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -89,6 +89,7 @@ class DiscussionController(BaseController, FeedController):
         if not hasattr(self, 'moderate'):
             self.moderate = ModerationController(self)
 
+    @with_trailing_slash
     @expose('jinja:allura:templates/discussion/index.html')
     def index(self, threads=None, limit=None, page=0, count=0, **kw):
         c.discussion = self.W.discussion


[08/29] allura git commit: [#6373] wrap output so it doesn't create horizontal scrolls

Posted by je...@apache.org.
[#6373] wrap output so it doesn't create horizontal scrolls


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

Branch: refs/heads/ib/7685
Commit: c95885e05991618a2597482ea31820de65c3dde7
Parents: 1be5974
Author: Dave Brondsema <da...@brondsema.net>
Authored: Wed Jul 8 10:28:44 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jul 8 17:00:49 2015 -0400

----------------------------------------------------------------------
 Allura/docs/getting_started/administration.rst | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c95885e0/Allura/docs/getting_started/administration.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/administration.rst b/Allura/docs/getting_started/administration.rst
index b199277..1a2084f 100644
--- a/Allura/docs/getting_started/administration.rst
+++ b/Allura/docs/getting_started/administration.rst
@@ -77,7 +77,8 @@ Available scripts and commands are:
 create-neighborhood
 -------------------
 
-.. program-output:: paster create-neighborhood development.ini --help
+.. program-output:: paster create-neighborhood development.ini --help | fmt -s -w 95
+   :shell:
 
 
 ensure_index
@@ -101,13 +102,15 @@ reindex
 set-neighborhood-features
 -------------------------
 
-.. program-output:: paster set-neighborhood-features development.ini --help
+.. program-output:: paster set-neighborhood-features development.ini --help | fmt -s -w 95
+   :shell:
 
 
 set-tool-access
 ---------------
 
-.. program-output:: paster set-tool-access development.ini --help
+.. program-output:: paster set-tool-access development.ini --help | fmt -s -w 95
+   :shell:
 
 
 taskd
@@ -119,7 +122,8 @@ taskd
 taskd_cleanup
 -------------
 
-.. program-output:: paster taskd_cleanup development.ini --help
+.. program-output:: paster taskd_cleanup development.ini --help | fmt -s -w 95
+   :shell:
 
 
 pull-rss-feeds


[05/29] allura git commit: [#6373] use sphinxcontrib.programoutput to document paster commands. Improve some usage help text

Posted by je...@apache.org.
[#6373] use sphinxcontrib.programoutput to document paster commands.  Improve some usage help text


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

Branch: refs/heads/ib/7685
Commit: 1be597416d002b2c5f93af47a4b2d4290e1cb2d0
Parents: be3845c
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Jul 7 18:10:13 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Wed Jul 8 17:00:48 2015 -0400

----------------------------------------------------------------------
 Allura/allura/command/show_models.py           |  4 +-
 Allura/allura/command/taskd_cleanup.py         |  2 +-
 Allura/docs/conf.py                            |  1 +
 Allura/docs/getting_started/administration.rst | 73 ++++++++++++++++++++-
 ForgeBlog/forgeblog/command/rssfeeds.py        |  2 +-
 ForgeChat/forgechat/command.py                 |  2 +-
 requirements.txt                               |  1 +
 scripts/create-allura-sitemap.py               |  2 +-
 8 files changed, 80 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/1be59741/Allura/allura/command/show_models.py
----------------------------------------------------------------------
diff --git a/Allura/allura/command/show_models.py b/Allura/allura/command/show_models.py
index d941e9e..89a2a88 100644
--- a/Allura/allura/command/show_models.py
+++ b/Allura/allura/command/show_models.py
@@ -53,7 +53,7 @@ class ReindexCommand(base.Command):
     min_args = 1
     max_args = 1
     usage = '<ini file>'
-    summary = 'Reindex and re-shortlink all artifacts'
+    summary = 'Reindex into solr and re-shortlink all artifacts'
     parser = base.Command.standard_parser(verbose=True)
     parser.add_option('-p', '--project', dest='project',  default=None,
                       help='project to reindex')
@@ -203,7 +203,7 @@ class EnsureIndexCommand(base.Command):
     min_args = 1
     max_args = 1
     usage = '[<ini file>]'
-    summary = 'Run ensure_index on all mongo objects'
+    summary = 'Create all the Mongo indexes specified by Ming models, drop any unspecified indexes.'
     parser = base.Command.standard_parser(verbose=True)
 
     def command(self):

http://git-wip-us.apache.org/repos/asf/allura/blob/1be59741/Allura/allura/command/taskd_cleanup.py
----------------------------------------------------------------------
diff --git a/Allura/allura/command/taskd_cleanup.py b/Allura/allura/command/taskd_cleanup.py
index 47d09bf..a796e6c 100644
--- a/Allura/allura/command/taskd_cleanup.py
+++ b/Allura/allura/command/taskd_cleanup.py
@@ -27,7 +27,7 @@ import base
 
 
 class TaskdCleanupCommand(base.Command):
-    summary = 'Tasks cleanup command'
+    summary = 'Tasks cleanup command.  Determines which taskd processes are handling tasks, and what has been dropped or got hung.'
     parser = base.Command.standard_parser(verbose=True)
     parser.add_option('-k', '--kill-stuck-taskd',
                       dest='kill', action='store_true',

http://git-wip-us.apache.org/repos/asf/allura/blob/1be59741/Allura/docs/conf.py
----------------------------------------------------------------------
diff --git a/Allura/docs/conf.py b/Allura/docs/conf.py
index 4c55afa..aa69905 100644
--- a/Allura/docs/conf.py
+++ b/Allura/docs/conf.py
@@ -42,6 +42,7 @@ import os
 extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx',
               'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.ifconfig']
 extensions += ['sphinxarg.ext']
+extensions += ['sphinxcontrib.programoutput']
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']

http://git-wip-us.apache.org/repos/asf/allura/blob/1be59741/Allura/docs/getting_started/administration.rst
----------------------------------------------------------------------
diff --git a/Allura/docs/getting_started/administration.rst b/Allura/docs/getting_started/administration.rst
index e8952b9..b199277 100644
--- a/Allura/docs/getting_started/administration.rst
+++ b/Allura/docs/getting_started/administration.rst
@@ -70,7 +70,71 @@ running a script via this interface, the `args/kwargs` JSON should be like::
 
 See the listing of :mod:`some available tasks <allura.tasks.admin_tasks>`.
 
-Available scripts and tasks are:
+
+Available scripts and commands are:
+
+
+create-neighborhood
+-------------------
+
+.. program-output:: paster create-neighborhood development.ini --help
+
+
+ensure_index
+------------
+
+.. program-output:: paster ensure_index development.ini --help
+
+
+ircbot
+------
+
+.. program-output:: paster ircbot development.ini --help
+
+
+reindex
+-------
+
+.. program-output:: paster reindex development.ini --help
+
+
+set-neighborhood-features
+-------------------------
+
+.. program-output:: paster set-neighborhood-features development.ini --help
+
+
+set-tool-access
+---------------
+
+.. program-output:: paster set-tool-access development.ini --help
+
+
+taskd
+-----
+
+.. program-output:: paster taskd development.ini --help
+
+
+taskd_cleanup
+-------------
+
+.. program-output:: paster taskd_cleanup development.ini --help
+
+
+pull-rss-feeds
+--------------
+
+Blog tools may optionally be configured to fetch external RSS feeds.  If that is in place, this command should
+be used to fetch all those rss feeds and convert new entries into blog posts.
+
+Requires `html2text`, a GPL library.
+
+::
+
+    cd ../ForgeBlog
+    paster pull-rss-feeds development.ini --help
+
 
 disable_users.py
 ----------------
@@ -82,6 +146,7 @@ disable_users.py
     :func: get_parser
     :prog: paster script development.ini allura/scripts/disable_users.py --
 
+
 refreshrepo.py
 --------------
 
@@ -92,6 +157,7 @@ refreshrepo.py
     :func: get_parser
     :prog: paster script development.ini allura/scripts/refreshrepo.py --
 
+
 reindex_projects.py
 -------------------
 
@@ -102,6 +168,7 @@ reindex_projects.py
     :func: get_parser
     :prog: paster script development.ini allura/scripts/reindex_projects.py --
 
+
 reindex_users.py
 ----------------
 
@@ -112,6 +179,7 @@ reindex_users.py
     :func: get_parser
     :prog: paster script development.ini allura/scripts/reindex_users.py --
 
+
 create-allura-sitemap.py
 ------------------------
 
@@ -122,6 +190,7 @@ create-allura-sitemap.py
     :func: parser
     :prog: paster script development.ini ../scripts/create-allura-sitemap.py --
 
+
 publicize-neighborhood.py
 -------------------------
 
@@ -132,6 +201,7 @@ publicize-neighborhood.py
     :func: parser
     :prog: paster script development.ini ../scripts/publicize-neighborhood.py --
 
+
 scrub-allura-data.py
 --------------------
 
@@ -142,6 +212,7 @@ scrub-allura-data.py
     :func: parser
     :prog: paster script development.ini ../scripts/scrub-allura-data.py --
 
+
 teamforge-import.py
 -------------------
 

http://git-wip-us.apache.org/repos/asf/allura/blob/1be59741/ForgeBlog/forgeblog/command/rssfeeds.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/command/rssfeeds.py b/ForgeBlog/forgeblog/command/rssfeeds.py
index 7771a5c..42b5edd 100644
--- a/ForgeBlog/forgeblog/command/rssfeeds.py
+++ b/ForgeBlog/forgeblog/command/rssfeeds.py
@@ -46,7 +46,7 @@ html2text.BODY_WIDTH = 0
 
 
 class RssFeedsCommand(base.BlogCommand):
-    summary = 'Rss feed client'
+    summary = 'Fetch external rss feeds for all Blog tools, and convert new feed entries into blog posts'
     parser = base.BlogCommand.standard_parser(verbose=True)
     parser.add_option('-a', '--appid', dest='appid', default='',
                       help='application id')

http://git-wip-us.apache.org/repos/asf/allura/blob/1be59741/ForgeChat/forgechat/command.py
----------------------------------------------------------------------
diff --git a/ForgeChat/forgechat/command.py b/ForgeChat/forgechat/command.py
index 6af2eaa..da2faf8 100644
--- a/ForgeChat/forgechat/command.py
+++ b/ForgeChat/forgechat/command.py
@@ -43,7 +43,7 @@ class IRCBotCommand(allura.command.Command):
     min_args = 1
     max_args = 1
     usage = '<ini file>'
-    summary = 'Connect to all configured IRC servers and relay messages'
+    summary = 'For the ForgeChat tool.  Connect to all configured IRC servers and relay messages'
     parser = command.Command.standard_parser(verbose=True)
     parser.add_option('-c', '--context', dest='context',
                       help=('The context of the message (path to the project'

http://git-wip-us.apache.org/repos/asf/allura/blob/1be59741/requirements.txt
----------------------------------------------------------------------
diff --git a/requirements.txt b/requirements.txt
index 80eda02..77581e2 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -81,3 +81,4 @@ q==2.3
 WebError==0.10.3
 -e git://github.com/brondsem/sphinx-argparse.git#egg=sphinx-argparse   # pending merge requests
 sphinx-rtd-theme==0.1.6
+sphinxcontrib-programoutput==0.8
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/1be59741/scripts/create-allura-sitemap.py
----------------------------------------------------------------------
diff --git a/scripts/create-allura-sitemap.py b/scripts/create-allura-sitemap.py
index 29220d1..9ab8f38 100644
--- a/scripts/create-allura-sitemap.py
+++ b/scripts/create-allura-sitemap.py
@@ -16,7 +16,7 @@
 #       under the License.
 
 """
-Generate Allura sitemap xml files.
+Generate Allura sitemap xml files.  You will need to configure your webserver to serve the files.
 
 This takes a while to run on a prod-sized data set. There are a couple of
 things that would make it faster, if we need/want to.


[22/29] allura git commit: [#7685] ticket:802 Subsribe via POST in wiki sidebar

Posted by je...@apache.org.
[#7685] ticket:802 Subsribe via POST in wiki sidebar


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

Branch: refs/heads/ib/7685
Commit: 1287e6e44adea3182a32693326167ac0a4be1c82
Parents: 16971ed
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Thu Jun 25 14:24:05 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Jul 10 15:59:00 2015 +0300

----------------------------------------------------------------------
 ForgeWiki/forgewiki/templates/wiki/page_view.html | 10 +++++++++-
 ForgeWiki/forgewiki/wiki_main.py                  |  2 +-
 2 files changed, 10 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/1287e6e4/ForgeWiki/forgewiki/templates/wiki/page_view.html
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/templates/wiki/page_view.html b/ForgeWiki/forgewiki/templates/wiki/page_view.html
index 0420ecf..7289f23 100644
--- a/ForgeWiki/forgewiki/templates/wiki/page_view.html
+++ b/ForgeWiki/forgewiki/templates/wiki/page_view.html
@@ -116,5 +116,13 @@
       {% endif %}
   {% endif %}
   {{c.confirmation.display(content='')}}
-
 {% endblock %}
+
+{% block wiki_extra_js %}
+  <script type="text/javascript">
+    $('a[href$="#toggle-subscribe"]').click(function() {
+      $('#subscribe_form').submit();
+      return false;
+    })
+  </script>
+{% endblock wiki_extra_js %}

http://git-wip-us.apache.org/repos/asf/allura/blob/1287e6e4/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 7899ffa..229b217 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -249,7 +249,7 @@ The wiki uses [Markdown](%s) syntax.
             subscribe_title = '{}{}'.format(
                 subscribe_action.capitalize(),
                 '' if subscribed else ' to wiki')
-            subscribe_url = '{}subscribe?{}=True'.format(self.url, subscribe_action)
+            subscribe_url = '{}#toggle-subscribe'.format(self.url, subscribe_action)
             links += [SitemapEntry(''),
                       SitemapEntry(subscribe_title, subscribe_url, ui_icon=g.icons['mail'])]
         if not admin_menu:


[25/29] allura git commit: [#7685] ticket:802 Added @with_trailing_slash to discussion thread controller

Posted by je...@apache.org.
[#7685] ticket:802 Added @with_trailing_slash to discussion thread controller


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

Branch: refs/heads/ib/7685
Commit: 5881b296b863fab4b61afa3f931fc8175d54a619
Parents: 5ea0ba1
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Thu Jul 2 16:32:16 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Jul 10 15:59:00 2015 +0300

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/5881b296/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 28cfcb6..13fe436 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -20,6 +20,7 @@ from datetime import datetime
 import logging
 
 from tg import expose, redirect, validate, request, flash
+from tg.decorators import with_trailing_slash
 from pylons import tmpl_context as c, app_globals as g
 from webob import exc
 
@@ -182,6 +183,7 @@ class ThreadController(BaseController, FeedController):
         id = unquote(id)
         return self.PostController(self._discussion_controller, self.thread, id), remainder
 
+    @with_trailing_slash
     @expose('jinja:allura:templates/discussion/thread.html')
     def index(self, limit=None, page=0, count=0, **kw):
         c.thread = self.W.thread


[14/29] allura git commit: [#7880] ticket:809 Send notification after moderator approves message

Posted by je...@apache.org.
[#7880] ticket:809 Send notification after moderator approves message


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

Branch: refs/heads/ib/7685
Commit: c084480011662111d94d1d5bc81cb2b5583fcad5
Parents: 91e883f
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 2 14:23:47 2015 +0300
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Thu Jul 9 13:51:47 2015 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py |  8 ++------
 Allura/allura/model/discuss.py       | 27 +++++++++++++++++++++------
 Allura/allura/model/notification.py  | 14 ++++++++------
 3 files changed, 31 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c0844800/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 568ca5a..28cfcb6 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -359,7 +359,7 @@ class PostController(BaseController):
             self.post.spam()
         elif kw.pop('approve', None):
             if self.post.status != 'ok':
-                self.post.approve(notify=False)
+                self.post.approve()
                 g.spam_checker.submit_ham(
                     self.post.text, artifact=self.post, user=c.user)
                 self.post.thread.post_to_feed(self.post)
@@ -478,13 +478,9 @@ class ModerationController(BaseController):
                     elif spam and posted.status != 'spam':
                         posted.spam()
                     elif approve and posted.status != 'ok':
-                        posted.status = 'ok'
+                        posted.approve()
                         g.spam_checker.submit_ham(
                             posted.text, artifact=posted, user=c.user)
-                        posted.thread.last_post_date = max(
-                            posted.thread.last_post_date,
-                            posted.mod_date)
-                        posted.thread.num_replies += 1
                         posted.thread.post_to_feed(posted)
         redirect(request.referer)
 

http://git-wip-us.apache.org/repos/asf/allura/blob/c0844800/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index 326a140..a704da7 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -714,16 +714,31 @@ class Post(Message, VersionedArtifact, ActivityObject):
                                        related_nodes=[self.app_config.project],
                                        tags=['comment'])
 
-    def notify(self, file_info=None, check_dup=False, notification_text=None):
+    def notify(self, file_info=None, notification_text=None):
         if self.project.notifications_disabled:
             return  # notifications disabled for entire project
         artifact = self.thread.artifact or self.thread
-        n = Notification.query.get(
-            _id=artifact.url() + self._id) if check_dup else None
+        msg_id = artifact.url() + self._id
+        notification_params = dict(
+            post=self,
+            text=notification_text,
+            file_info=file_info)
+        n = Notification.query.get(_id=msg_id)
+        if n and 'Moderation action required' in n.subject:
+            # Existing notification for this artifact is for moderators only,
+            # this means artifact was not auto approved, and all the
+            # subscribers did not receive notification. Now, moderator approved
+            # artifact/post, so we should re-send actual notification
+            msg_id = u'approved-' + msg_id
+            n = Notification.query.get(_id=msg_id)
+            if n:
+                # 'approved' notification also exists, re-send
+                n.fire_notification_task(artifact, 'message')
+            else:
+                # 'approved' notification does not exist, create
+                notification_params['message_id'] = msg_id
         if not n:
-            n = Notification.post(artifact, 'message',
-                                  post=self, text=notification_text,
-                                  file_info=file_info)
+            n = Notification.post(artifact, 'message', **notification_params)
         if not n:
             return
         if (hasattr(artifact, "monitoring_email")

http://git-wip-us.apache.org/repos/asf/allura/blob/c0844800/Allura/allura/model/notification.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index 4241c42..ca1a850 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -110,15 +110,18 @@ class Notification(MappedClass):
     @classmethod
     def post(cls, artifact, topic, **kw):
         '''Create a notification and  send the notify message'''
-        import allura.tasks.notification_tasks
         n = cls._make_notification(artifact, topic, **kw)
         if n:
             # make sure notification is flushed in time for task to process it
             session(n).flush(n)
-            allura.tasks.notification_tasks.notify.post(
-                n._id, artifact.index_id(), topic)
+            n.fire_notification_task(artifact, topic)
         return n
 
+    def fire_notification_task(self, artifact, topic):
+        import allura.tasks.notification_tasks
+        allura.tasks.notification_tasks.notify.post(
+            self._id, artifact.index_id(), topic)
+
     @classmethod
     def post_user(cls, user, artifact, topic, **kw):
         '''Create a notification and deliver directly to a user's flash
@@ -168,10 +171,9 @@ class Notification(MappedClass):
             if post.parent_id and not subject.lower().startswith('re:'):
                 subject = 'Re: ' + subject
             author = post.author()
-            msg_id = artifact.url() + post._id
+            msg_id = kwargs.get('message_id') or artifact.url() + post._id
             parent_msg_id = artifact.url() + \
-                post.parent_id if post.parent_id else artifact.message_id(
-                )
+                post.parent_id if post.parent_id else artifact.message_id()
             d = dict(
                 _id=msg_id,
                 from_address=str(


[19/29] allura git commit: [#7685] ticket:802 Submit subscription request via POST

Posted by je...@apache.org.
[#7685] ticket:802 Submit subscription request via POST


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

Branch: refs/heads/ib/7685
Commit: 16971ed1b91f61a76ad18702023652957fcd60bf
Parents: 48d7c56
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Wed Jun 24 23:39:53 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Jul 10 15:58:59 2015 +0300

----------------------------------------------------------------------
 Allura/allura/templates/widgets/subscribe.html       | 13 +++++++++++--
 ForgeBlog/forgeblog/main.py                          |  1 +
 ForgeDiscussion/forgediscussion/controllers/forum.py |  1 +
 ForgeTracker/forgetracker/tracker_main.py            |  2 ++
 ForgeWiki/forgewiki/wiki_main.py                     |  2 ++
 5 files changed, 17 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/16971ed1/Allura/allura/templates/widgets/subscribe.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/subscribe.html b/Allura/allura/templates/widgets/subscribe.html
index a88c7e4..5154eb7 100644
--- a/Allura/allura/templates/widgets/subscribe.html
+++ b/Allura/allura/templates/widgets/subscribe.html
@@ -16,9 +16,14 @@
        specific language governing permissions and limitations
        under the License.
 -#}
+{% import 'allura:templates/jinja_master/lib.html' as lib with context %}
 {% if value %}
   {% if style == 'icon' %}
-    <a href="{{action}}?unsubscribe=True" class="artifact_unsubscribe active" title="Unsubscribe from this {{thing}}"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Unsubscribe from this {{thing}}"></b></a>
+    <form action="{{action}}" id="subscribe_form" style="display:inline;" method="POST">
+      {{lib.csrf_token()}}
+      <input type="hidden" name="unsubscribe" value="1">
+      <a href="#" class="artifact_unsubscribe active" title="Unsubscribe from this {{thing}}" onclick="$('#subscribe_form').submit(); return false;"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Unsubscribe from this {{thing}}"></b></a>
+    </form>
   {% else %}
     You are currently subscribed to this {{thing}}.
     <br/>
@@ -26,7 +31,11 @@
   {% endif %}
 {% else %}
   {% if style == 'icon' %}
-    <a href="{{action}}?subscribe=True" class="artifact_subscribe" title="Subscribe to this {{thing}}"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Subscribe to this {{thing}}"></b></a>
+    <form action="{{action}}" id="subscribe_form" style="display:inline;" method="POST">
+      {{lib.csrf_token()}}
+      <input type="hidden" name="subscribe" value="1">
+      <a href="#" class="artifact_subscribe" title="Subscribe to this {{thing}}" onclick="$('#subscribe_form').submit(); return false;"><b data-icon="{{g.icons['mail'].char}}" class="ico {{g.icons['mail'].css}}" title="Subscribe to this {{thing}}"></b></a>
+    </form>
   {% else %}
     You are currently not subscribed to this {{thing}}.
     <br/>

http://git-wip-us.apache.org/repos/asf/allura/blob/16971ed1/ForgeBlog/forgeblog/main.py
----------------------------------------------------------------------
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index edfe1f0..9007f87 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -376,6 +376,7 @@ class PostController(BaseController, FeedController):
         redirect('.')
 
     @expose()
+    @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None, **kw):
         if subscribe:

http://git-wip-us.apache.org/repos/asf/allura/blob/16971ed1/ForgeDiscussion/forgediscussion/controllers/forum.py
----------------------------------------------------------------------
diff --git a/ForgeDiscussion/forgediscussion/controllers/forum.py b/ForgeDiscussion/forgediscussion/controllers/forum.py
index 67dbea3..94fe6d9 100644
--- a/ForgeDiscussion/forgediscussion/controllers/forum.py
+++ b/ForgeDiscussion/forgediscussion/controllers/forum.py
@@ -123,6 +123,7 @@ class ForumController(DiscussionController):
         return dict()
 
     @expose()
+    @require_post()
     @validate(W.subscribe_form)
     def subscribe_to_forum(self, subscribe=None, unsubscribe=None, shortname=None, **kw):
         if subscribe:

http://git-wip-us.apache.org/repos/asf/allura/blob/16971ed1/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 68b1a0c..c3a83e6 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1091,6 +1091,7 @@ class RootController(BaseController, FeedController):
         )
 
     @expose()
+    @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None):
         if subscribe:
@@ -1520,6 +1521,7 @@ class TicketController(BaseController, FeedController):
         redirect('.')
 
     @expose()
+    @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None):
         if subscribe:

http://git-wip-us.apache.org/repos/asf/allura/blob/16971ed1/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index cfaec31..7899ffa 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -464,6 +464,7 @@ class RootController(BaseController, DispatchIndex, FeedController):
         return dict(example=MARKDOWN_EXAMPLE)
 
     @expose()
+    @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None):
         if subscribe:
@@ -735,6 +736,7 @@ class PageController(BaseController, FeedController):
         redirect(request.referer)
 
     @expose()
+    @require_post()
     @validate(W.subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None, **kw):
         if not self.page:


[04/29] allura git commit: Let `paster shell` work, avoiding https redirect

Posted by je...@apache.org.
Let `paster shell` work, avoiding https redirect


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

Branch: refs/heads/ib/7685
Commit: 93a1ecc1fae394f3350b5eefc957c9ab4976b996
Parents: ffba721
Author: Dave Brondsema <da...@brondsema.net>
Authored: Tue Jul 7 17:58:50 2015 -0400
Committer: Dave Brondsema <da...@brondsema.net>
Committed: Tue Jul 7 17:58:50 2015 -0400

----------------------------------------------------------------------
 Allura/development.ini | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/93a1ecc1/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index c3325ed..02d3e9f 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -233,7 +233,8 @@ webhook.repo_push.max_hooks = {"git": 3, "hg": 3, "svn": 3}
 ; If you set force_ssl.logged_in, you probably want some URLs to be ssl when logged out:
 ;force_ssl.pattern = ^/auth|^/[a-z0-9-]+/import_project/  ; import_project uses a login overlay
 ; And to permit some URLs to be accessed over http anyway:
-;no_redirect.pattern = ^/nf/\d+/_(ew|static)_/|^/rest/|^/nf/tool_icon_css|^/auth/refresh_repo
+;    /_test_vars is used when running `paster shell`
+;no_redirect.pattern = ^/nf/\d+/_(ew|static)_/|^/rest/|^/nf/tool_icon_css|^/auth/refresh_repo|^/_test_vars
 
 
 ; Set the locations of some static resources.  ("ew" stands for EasyWidgets library)


[16/29] allura git commit: [#7909] ticket:817 Use dashes when suggesting project shortnames

Posted by je...@apache.org.
[#7909] ticket:817 Use dashes when suggesting project shortnames


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

Branch: refs/heads/ib/7685
Commit: 5b29187b73d2934ba633ecc4f8e20766d234df58
Parents: 8376fe2
Author: Igor Bondarenko <je...@gmail.com>
Authored: Wed Jul 8 13:21:55 2015 +0300
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Jul 9 21:20:52 2015 +0000

----------------------------------------------------------------------
 Allura/allura/lib/plugin.py                         | 3 ++-
 Allura/allura/tests/functional/test_neighborhood.py | 4 ++--
 Allura/allura/tests/test_plugin.py                  | 5 ++++-
 3 files changed, 8 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/5b29187b/Allura/allura/lib/plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/plugin.py b/Allura/allura/lib/plugin.py
index 3fc5e87..be69b29 100644
--- a/Allura/allura/lib/plugin.py
+++ b/Allura/allura/lib/plugin.py
@@ -685,7 +685,8 @@ class ProjectRegistrationProvider(object):
         Example: "My Great Project" -> "mygreatproject"
 
         """
-        return re.sub("[^A-Za-z0-9]", "", project_name).lower()
+        name = re.sub("[^A-Za-z0-9]", " ", project_name).lower()
+        return '-'.join(name.split())
 
     def rate_limit(self, user, neighborhood):
         """Check the various config-defined project registration rate

http://git-wip-us.apache.org/repos/asf/allura/blob/5b29187b/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 593671d..5d0d3ac 100644
--- a/Allura/allura/tests/functional/test_neighborhood.py
+++ b/Allura/allura/tests/functional/test_neighborhood.py
@@ -825,9 +825,9 @@ class TestNeighborhood(TestController):
 
     def test_name_suggest(self):
         r = self.app.get('/p/suggest_name?project_name=My+Moz')
-        assert_equal(r.json, dict(suggested_name='mymoz'))
+        assert_equal(r.json, dict(suggested_name='my-moz'))
         r = self.app.get('/p/suggest_name?project_name=Te%st!')
-        assert_equal(r.json, dict(suggested_name='test'))
+        assert_equal(r.json, dict(suggested_name='te-st'))
 
     def test_name_check(self):
         for name in ('My+Moz', 'Te%st!', 'ab', 'a' * 16):

http://git-wip-us.apache.org/repos/asf/allura/blob/5b29187b/Allura/allura/tests/test_plugin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/test_plugin.py b/Allura/allura/tests/test_plugin.py
index 64b9695..2b8b039 100644
--- a/Allura/allura/tests/test_plugin.py
+++ b/Allura/allura/tests/test_plugin.py
@@ -67,8 +67,11 @@ class TestProjectRegistrationProvider(object):
 
     def test_suggest_name(self):
         f = self.provider.suggest_name
+        assert_equals(f('Foo Bar', Mock()), 'foo-bar')
         assert_equals(f('A More Than Fifteen Character Name', Mock()),
-                      'amorethanfifteencharactername')
+                      'a-more-than-fifteen-character-name')
+        assert_equals(f('foo! bar?.. the great!!', Mock()),
+                      'foo-bar-the-great')
 
     @patch('allura.model.Project')
     def test_shortname_validator(self, Project):


[15/29] allura git commit: [#7880] ticket:809 Fix test for moderation controller

Posted by je...@apache.org.
[#7880] ticket:809 Fix test for moderation controller


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

Branch: refs/heads/ib/7685
Commit: 8376fe296734e62403f25b8ee51f747e2bd2bfd8
Parents: c084480
Author: Igor Bondarenko <je...@gmail.com>
Authored: Thu Jul 2 15:56:43 2015 +0300
Committer: Heith Seewald <hs...@slashdotmedia.com>
Committed: Thu Jul 9 13:51:48 2015 +0000

----------------------------------------------------------------------
 .../controllers/test_discussion_moderation_controller.py |  1 +
 Allura/allura/tests/unit/patches.py                      | 11 ++++++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/8376fe29/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py b/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py
index 5f88b0a..58c98ef 100644
--- a/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py
+++ b/Allura/allura/tests/unit/controllers/test_discussion_moderation_controller.py
@@ -28,6 +28,7 @@ from allura.tests.unit import patches
 
 class TestWhenModerating(WithDatabase):
     patches = [patches.fake_app_patch,
+               patches.fake_user_patch,
                patches.fake_redirect_patch,
                patches.fake_request_patch,
                patches.disable_notifications_patch]

http://git-wip-us.apache.org/repos/asf/allura/blob/8376fe29/Allura/allura/tests/unit/patches.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/patches.py b/Allura/allura/tests/unit/patches.py
index 41cb403..afd5758 100644
--- a/Allura/allura/tests/unit/patches.py
+++ b/Allura/allura/tests/unit/patches.py
@@ -18,7 +18,11 @@
 from mock import Mock, patch
 from pylons import tmpl_context as c
 
-from allura.tests.unit.factories import create_project, create_app_config
+from allura.tests.unit.factories import (
+    create_project,
+    create_app_config,
+    create_user,
+)
 
 
 def fake_app_patch(test_case):
@@ -31,6 +35,11 @@ def fake_app_patch(test_case):
     return patch.object(c, 'app', app, create=True)
 
 
+def fake_user_patch(test_case):
+    user = create_user(username='my_user')
+    return patch.object(c, 'user', user, create=True)
+
+
 def project_app_loading_patch(test_case):
     test_case.fake_app = Mock()
     test_case.project_app_instance_function = Mock()


[20/29] allura git commit: [#7685] ticket:802 Require POST for repository subscription

Posted by je...@apache.org.
[#7685] ticket:802 Require POST for repository subscription


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

Branch: refs/heads/ib/7685
Commit: d08f8147735f0ce46587766e5fb9ffb80c7a2212
Parents: dc19b4b
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Thu Jul 2 14:29:12 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Jul 10 15:59:00 2015 +0300

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


http://git-wip-us.apache.org/repos/asf/allura/blob/d08f8147/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index f8b0834..0178723 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -689,6 +689,7 @@ class TreeBrowser(BaseController, DispatchIndex):
             self), rest
 
     @expose()
+    @require_post()
     @validate(subscribe_form)
     def subscribe(self, subscribe=None, unsubscribe=None, **kw):
         if subscribe:


[02/29] allura git commit: [#7899] ticket:808 Fixed downloading repo files with spaces

Posted by je...@apache.org.
[#7899] ticket:808 Fixed downloading repo files with spaces


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

Branch: refs/heads/ib/7685
Commit: fdefe42fb654ca105d05c302a351edf0a49f9d4d
Parents: 6991e51
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Sun Jun 28 13:18:02 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Mon Jul 6 15:12:34 2015 +0300

----------------------------------------------------------------------
 Allura/allura/controllers/repository.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/fdefe42f/Allura/allura/controllers/repository.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 4c9cb83..e9f051d 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -738,7 +738,8 @@ class FileBrowser(BaseController):
             response.headers['Content-Encoding'] = ''
             response.content_encoding = content_encoding
         response.headers.add(
-            'Content-Disposition', 'attachment;filename=' + filename)
+            'Content-Disposition',
+            'attachment;filename="%s"' % filename.encode('utf-8'))
         return iter(self._blob)
 
     def diff(self, commit, fmt=None, **kw):


[26/29] allura git commit: [#7685] ticket:802 Use post in SCM subscription test and fix format call

Posted by je...@apache.org.
[#7685] ticket:802 Use post in SCM subscription test and fix format call


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

Branch: refs/heads/ib/7685
Commit: be2190ac8dcdcb6b543c9385046fb6c3d3f0674e
Parents: 5881b29
Author: Igor Bondarenko <je...@gmail.com>
Authored: Fri Jul 3 12:45:13 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Jul 10 15:59:00 2015 +0300

----------------------------------------------------------------------
 .../forgegit/tests/functional/test_controllers.py   | 16 +++++++++-------
 ForgeWiki/forgewiki/wiki_main.py                    |  2 +-
 2 files changed, 10 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/be2190ac/ForgeGit/forgegit/tests/functional/test_controllers.py
----------------------------------------------------------------------
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index b84cd5a..20bfc1b 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -353,24 +353,26 @@ class TestRootController(_TestCase):
         assert link is not None, r.html
 
         # subscribe
-        self.app.get(ci + 'tree/subscribe?subscribe=True',
-                     extra_environ={'username': str(user.username)}).follow()
+        self.app.post(str(ci + 'tree/subscribe'),
+                      {'subscribe': True},
+                      extra_environ={'username': str(user.username)}).follow()
         # user is subscribed
         assert M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get(ci + 'tree/',
                          extra_environ={'username': str(user.username)})
-        link = r.html.find('a', 'artifact_unsubscribe active')
-        assert link is not None, r.html
+        inp = r.html.find('input', {'type': 'hidden', 'name': 'unsubscribe'})
+        assert inp is not None
 
         # unsubscribe
-        self.app.get(ci + 'tree/subscribe?unsubscribe=True',
+        self.app.post(str(ci + 'tree/subscribe'),
+                     {'unsubscribe': True},
                      extra_environ={'username': str(user.username)}).follow()
         # user is not subscribed
         assert not M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get(ci + 'tree/',
                          extra_environ={'username': str(user.username)})
-        link = r.html.find('a', 'artifact_subscribe')
-        assert link is not None, r.html
+        inp = r.html.find('input', {'type': 'hidden', 'name': 'subscribe'})
+        assert inp is not None
 
     def test_timezone(self):
         ci = self._get_ci()

http://git-wip-us.apache.org/repos/asf/allura/blob/be2190ac/ForgeWiki/forgewiki/wiki_main.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index c2bcb16..229a348 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -249,7 +249,7 @@ The wiki uses [Markdown](%s) syntax.
             subscribe_title = '{}{}'.format(
                 subscribe_action.capitalize(),
                 '' if subscribed else ' to wiki')
-            subscribe_url = '#toggle-subscribe'.format(self.url)
+            subscribe_url = '{}#toggle-subscribe'.format(self.url)
             links += [SitemapEntry(''),
                       SitemapEntry(subscribe_title, subscribe_url, ui_icon=g.icons['mail'])]
         if not admin_menu:


[27/29] allura git commit: [#7685] ticket:802 Fixed tests

Posted by je...@apache.org.
[#7685] ticket:802 Fixed tests


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

Branch: refs/heads/ib/7685
Commit: a6617a866057c3eb9b51ac27b7d641ceaca8fc2f
Parents: 1287e6e
Author: Aleksey 'LXj' Alekseyev <go...@gmail.com>
Authored: Sat Jun 27 22:53:54 2015 +0300
Committer: Igor Bondarenko <je...@gmail.com>
Committed: Fri Jul 10 15:59:00 2015 +0300

----------------------------------------------------------------------
 .../tests/functional/test_forum.py              |  2 +-
 .../forgetracker/tests/functional/test_root.py  | 22 ++++++++++----------
 .../forgewiki/tests/functional/test_rest.py     |  2 +-
 .../forgewiki/tests/functional/test_root.py     | 16 +++++++-------
 4 files changed, 21 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/a6617a86/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 9c5397f..ae91bf0 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -576,7 +576,7 @@ class TestForum(TestController):
             if field.has_key('name') and 'subscription' not in field['name']:
                 params[field['name']] = field.has_key('value') and field['value'] or ''
         self.app.post(str(subscribe_url), params=params)
-        self.app.get('/discussion/general/subscribe_to_forum?subscribe=True')
+        self.app.post('/discussion/general/subscribe_to_forum', {'subscribe': True})
         f = thread.html.find('div', {'class': 'row reply_post_form'}).find('form')
         rep_url = f.get('action')
         params = dict()

http://git-wip-us.apache.org/repos/asf/allura/blob/a6617a86/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 122d707..0e47f68 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -840,7 +840,7 @@ class TestFunctionalController(TrackerTestController):
         }, upload_files=[upload]).follow()
         assert file_name in ticket_editor, ticket_editor.showbrowser()
         req = self.app.get('/bugs/1/')
-        file_link = req.html.findAll('form')[1].findAll('a')[6]
+        file_link = req.html.findAll('form')[3].findAll('a')[6]
         assert_equal(file_link.string, file_name)
         self.app.post(str(file_link['href']), {
             'delete': 'True'
@@ -882,7 +882,7 @@ class TestFunctionalController(TrackerTestController):
         ticket_editor = self.app.post('/bugs/1/update_ticket', {
             'summary': 'zzz'
         }, upload_files=[upload]).follow()
-        download = self.app.get(str(ticket_editor.html.findAll('form')[1].findAll('a')[7]['href']))
+        download = self.app.get(str(ticket_editor.html.findAll('form')[2].findAll('a')[7]['href']))
         assert_equal(download.body, file_data)
 
     def test_two_attachments(self):
@@ -1239,7 +1239,7 @@ class TestFunctionalController(TrackerTestController):
         # Test edit ticket form
         self.new_ticket(summary='Test ticket')
         response = self.app.get('/bugs/1/')
-        form = response.forms[1]
+        form = response.forms[2]
         assert_equal(
             form['ticket_form.custom_fields._priority'].value, 'normal')
         assert_equal(form['ticket_form.custom_fields._category'].value, '')
@@ -1247,9 +1247,9 @@ class TestFunctionalController(TrackerTestController):
         form['ticket_form.custom_fields._priority'] = 'urgent'
         form['ticket_form.custom_fields._category'] = 'bugs'
         error_form = form.submit()
-        assert_equal(error_form.forms[1]['ticket_form.custom_fields._priority'].value,
+        assert_equal(error_form.forms[2]['ticket_form.custom_fields._priority'].value,
                      'urgent')
-        assert_equal(error_form.forms[1]['ticket_form.custom_fields._category'].value,
+        assert_equal(error_form.forms[2]['ticket_form.custom_fields._category'].value,
                      'bugs')
 
     def test_new_ticket_validation(self):
@@ -1269,7 +1269,7 @@ class TestFunctionalController(TrackerTestController):
         # set a summary, submit, and check for success
         error_form.forms[1]['ticket_form.summary'] = summary
         success = error_form.forms[1].submit().follow().html
-        assert success.findAll('form')[1].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
+        assert success.findAll('form')[2].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
         assert success.find('input', {'name': 'ticket_form.summary'})['value'] == summary
 
     def test_edit_ticket_validation(self):
@@ -1280,7 +1280,7 @@ class TestFunctionalController(TrackerTestController):
         # check that existing form is valid
         assert response.html.find('input', {'name': 'ticket_form.summary'})['value'] == old_summary
         assert not response.html.find('div', {'class': 'error'})
-        form = response.forms[1]
+        form = response.forms[2]
         # try submitting with no summary set and check for error message
         form['ticket_form.summary'] = ""
         error_form = form.submit()
@@ -1289,11 +1289,11 @@ class TestFunctionalController(TrackerTestController):
         assert error_message.string == 'You must provide a Title'
         assert error_message.findPreviousSibling('input').get('name') == 'ticket_form.summary'
         # set a summary, submit, and check for success
-        error_form.forms[1]['ticket_form.summary'] = new_summary
-        r = error_form.forms[1].submit()
+        error_form.forms[2]['ticket_form.summary'] = new_summary
+        r = error_form.forms[2].submit()
         assert r.status_int == 302, r.showbrowser()
         success = r.follow().html
-        assert success.findAll('form')[1].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
+        assert success.findAll('form')[2].get('action') == '/p/test/bugs/1/update_ticket_from_widget'
         assert success.find('input', {'name': 'ticket_form.summary'})['value'] == new_summary
 
     def test_home(self):
@@ -2700,7 +2700,7 @@ class TestCustomUserField(TrackerTestController):
     def test_change_user_field(self):
         kw = {'custom_fields._code_review': ''}
         r = self.new_ticket(summary='test custom fields', **kw).follow()
-        f = r.forms[1]
+        f = r.forms[2]
         # Populate ProjectUserCombo's select with option we want.
         # This is a workaround for tests,
         # in real enviroment this is populated via ajax.

http://git-wip-us.apache.org/repos/asf/allura/blob/a6617a86/ForgeWiki/forgewiki/tests/functional/test_rest.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_rest.py b/ForgeWiki/forgewiki/tests/functional/test_rest.py
index 6a5de3b..a2b58ae 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_rest.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_rest.py
@@ -42,7 +42,7 @@ class TestWikiApi(TestRestApiBase):
 
     def test_get_page(self):
         r = self.app.get('/p/test/wiki/Home/')
-        discussion_url = r.html.findAll('form')[2]['action'][:-4]
+        discussion_url = r.html.findAll('form')[3]['action'][:-4]
         content = file(__file__).read()
         self.app.post('/wiki/Home/attach',
                       upload_files=[('file_info', 'test_root.py', content)])

http://git-wip-us.apache.org/repos/asf/allura/blob/a6617a86/ForgeWiki/forgewiki/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index aea9028..dafb74f 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -754,24 +754,24 @@ class TestRootController(TestController):
         # user is not subscribed
         assert not M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get('/p/test/wiki/Home/', extra_environ={'username': str(user.username)})
-        link = r.html.find('a', {'href': '/p/test/wiki/subscribe?subscribe=True'})
-        assert link is not None
+        inp = r.html.find('input', {'type': 'hidden', 'name': 'subscribe'})
+        assert inp is not None
         # subscribe
-        self.app.get('/p/test/wiki/subscribe?subscribe=True',
+        self.app.post('/p/test/wiki/subscribe', {'subscribe': True},
                      extra_environ={'username': str(user.username)}).follow()
         # user is subscribed
         assert M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get('/p/test/wiki/Home/', extra_environ={'username': str(user.username)})
-        link = r.html.find('a', {'href': '/p/test/wiki/subscribe?unsubscribe=True'})
-        assert link is not None
+        inp = r.html.find('input', {'type': 'hidden', 'name': 'unsubscribe'})
+        assert inp is not None
         # unsubscribe
-        self.app.get('/p/test/wiki/subscribe?unsubscribe=True',
+        self.app.post('/p/test/wiki/subscribe', {'unsubscribe': True},
                      extra_environ={'username': str(user.username)}).follow()
         # user is not subscribed
         assert not M.Mailbox.subscribed(user_id=user._id)
         r = self.app.get('/p/test/wiki/Home/', extra_environ={'username': str(user.username)})
-        link = r.html.find('a', {'href': '/p/test/wiki/subscribe?subscribe=True'})
-        assert link is not None
+        inp = r.html.find('input', {'type': 'hidden', 'name': 'subscribe'})
+        assert inp is not None
 
     def test_rate_limit_new_page(self):
         # Set rate limit to unlimit