##// END OF EJS Templates
updated docs on every controller
marcink -
r861:fd2ea6ce beta
parent child Browse files
Show More
@@ -1,104 +1,105 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 package.rhodecode.controllers.admin.ldap_settings
3 rhodecode.controllers.admin.ldap_settings
4 ~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 ldap controller for RhodeCode
6 ldap controller for RhodeCode
7
7 :created_on: Nov 26, 2010
8 :created_on: Nov 26, 2010
8 :author: marcink
9 :author: marcink
9 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
10 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
11 """
12 """
12 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
13 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
14 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
15 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
16 #
17 #
17 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # GNU General Public License for more details.
21 # GNU General Public License for more details.
21 #
22 #
22 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
23 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
24 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
26 import logging
27 import logging
27 import formencode
28 import formencode
28 import traceback
29 import traceback
29
30
30 from formencode import htmlfill
31 from formencode import htmlfill
31
32
32 from pylons import request, response, session, tmpl_context as c, url
33 from pylons import request, response, session, tmpl_context as c, url
33 from pylons.controllers.util import abort, redirect
34 from pylons.controllers.util import abort, redirect
34 from pylons.i18n.translation import _
35 from pylons.i18n.translation import _
35
36
36 from rhodecode.lib.base import BaseController, render
37 from rhodecode.lib.base import BaseController, render
37 from rhodecode.lib import helpers as h
38 from rhodecode.lib import helpers as h
38 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
39 from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
39 from rhodecode.lib.auth_ldap import LdapImportError
40 from rhodecode.lib.auth_ldap import LdapImportError
40 from rhodecode.model.settings import SettingsModel
41 from rhodecode.model.settings import SettingsModel
41 from rhodecode.model.forms import LdapSettingsForm
42 from rhodecode.model.forms import LdapSettingsForm
42 from sqlalchemy.exc import DatabaseError
43 from sqlalchemy.exc import DatabaseError
43
44
44 log = logging.getLogger(__name__)
45 log = logging.getLogger(__name__)
45
46
46
47
47
48
48 class LdapSettingsController(BaseController):
49 class LdapSettingsController(BaseController):
49
50
50 @LoginRequired()
51 @LoginRequired()
51 @HasPermissionAllDecorator('hg.admin')
52 @HasPermissionAllDecorator('hg.admin')
52 def __before__(self):
53 def __before__(self):
53 c.admin_user = session.get('admin_user')
54 c.admin_user = session.get('admin_user')
54 c.admin_username = session.get('admin_username')
55 c.admin_username = session.get('admin_username')
55 super(LdapSettingsController, self).__before__()
56 super(LdapSettingsController, self).__before__()
56
57
57 def index(self):
58 def index(self):
58 defaults = SettingsModel().get_ldap_settings()
59 defaults = SettingsModel().get_ldap_settings()
59
60
60 return htmlfill.render(
61 return htmlfill.render(
61 render('admin/ldap/ldap.html'),
62 render('admin/ldap/ldap.html'),
62 defaults=defaults,
63 defaults=defaults,
63 encoding="UTF-8",
64 encoding="UTF-8",
64 force_defaults=True,)
65 force_defaults=True,)
65
66
66 def ldap_settings(self):
67 def ldap_settings(self):
67 """POST ldap create and store ldap settings"""
68 """POST ldap create and store ldap settings"""
68
69
69 settings_model = SettingsModel()
70 settings_model = SettingsModel()
70 _form = LdapSettingsForm()()
71 _form = LdapSettingsForm()()
71
72
72 try:
73 try:
73 form_result = _form.to_python(dict(request.POST))
74 form_result = _form.to_python(dict(request.POST))
74 try:
75 try:
75
76
76 for k, v in form_result.items():
77 for k, v in form_result.items():
77 if k.startswith('ldap_'):
78 if k.startswith('ldap_'):
78 setting = settings_model.get(k)
79 setting = settings_model.get(k)
79 setting.app_settings_value = v
80 setting.app_settings_value = v
80 self.sa.add(setting)
81 self.sa.add(setting)
81
82
82 self.sa.commit()
83 self.sa.commit()
83 h.flash(_('Ldap settings updated successfully'),
84 h.flash(_('Ldap settings updated successfully'),
84 category='success')
85 category='success')
85 except (DatabaseError,):
86 except (DatabaseError,):
86 raise
87 raise
87 except LdapImportError:
88 except LdapImportError:
88 h.flash(_('Unable to activate ldap. The "python-ldap" library '
89 h.flash(_('Unable to activate ldap. The "python-ldap" library '
89 'is missing.'), category='warning')
90 'is missing.'), category='warning')
90
91
91 except formencode.Invalid, errors:
92 except formencode.Invalid, errors:
92
93
93 return htmlfill.render(
94 return htmlfill.render(
94 render('admin/ldap/ldap.html'),
95 render('admin/ldap/ldap.html'),
95 defaults=errors.value,
96 defaults=errors.value,
96 errors=errors.error_dict or {},
97 errors=errors.error_dict or {},
97 prefix_error=False,
98 prefix_error=False,
98 encoding="UTF-8")
99 encoding="UTF-8")
99 except Exception:
100 except Exception:
100 log.error(traceback.format_exc())
101 log.error(traceback.format_exc())
101 h.flash(_('error occurred during update of ldap settings'),
102 h.flash(_('error occurred during update of ldap settings'),
102 category='error')
103 category='error')
103
104
104 return redirect(url('ldap_home'))
105 return redirect(url('ldap_home'))
@@ -1,47 +1,54 b''
1 #!/usr/bin/env python
1 # -*- coding: utf-8 -*-
2 # encoding: utf-8
2 """
3 # branches controller for pylons
3 rhodecode.controllers.branches
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 #
5
6 branches controller for rhodecode
7
8 :created_on: Apr 21, 2010
9 :author: marcink
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
6 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
10 #
17 #
11 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
21 # GNU General Public License for more details.
15 #
22 #
16 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
20 """
27
21 Created on April 21, 2010
28 import logging
22 branches controller for pylons
29
23 @author: marcink
24 """
25 from pylons import tmpl_context as c
30 from pylons import tmpl_context as c
31
26 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
32 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
27 from rhodecode.lib.base import BaseController, render
33 from rhodecode.lib.base import BaseController, render
28 from rhodecode.lib.utils import OrderedDict
34 from rhodecode.lib.utils import OrderedDict
29 from rhodecode.model.scm import ScmModel
35 from rhodecode.model.scm import ScmModel
30 import logging
36
31 log = logging.getLogger(__name__)
37 log = logging.getLogger(__name__)
32
38
33 class BranchesController(BaseController):
39 class BranchesController(BaseController):
34
40
35 @LoginRequired()
41 @LoginRequired()
36 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', 'repository.admin')
42 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
43 'repository.admin')
37 def __before__(self):
44 def __before__(self):
38 super(BranchesController, self).__before__()
45 super(BranchesController, self).__before__()
39
46
40 def index(self):
47 def index(self):
41 hg_model = ScmModel()
48 hg_model = ScmModel()
42 c.repo_info = hg_model.get_repo(c.repo_name)
49 c.repo_info = hg_model.get_repo(c.repo_name)
43 c.repo_branches = OrderedDict()
50 c.repo_branches = OrderedDict()
44 for name, hash_ in c.repo_info.branches.items():
51 for name, hash_ in c.repo_info.branches.items():
45 c.repo_branches[name] = c.repo_info.get_changeset(hash_)
52 c.repo_branches[name] = c.repo_info.get_changeset(hash_)
46
53
47 return render('branches/branches.html')
54 return render('branches/branches.html')
@@ -1,99 +1,106 b''
1 #!/usr/bin/env python
1 # -*- coding: utf-8 -*-
2 # encoding: utf-8
2 """
3 # changelog controller for pylons
3 rhodecode.controllers.changelog
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 #
5
6 changelog controller for rhodecode
7
8 :created_on: Apr 21, 2010
9 :author: marcink
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
6 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
10 #
17 #
11 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
21 # GNU General Public License for more details.
15 #
22 #
16 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
20 """
27
21 Created on April 21, 2010
28 import logging
22 changelog controller for pylons
23 @author: marcink
24 """
25
29
26 try:
30 try:
27 import json
31 import json
28 except ImportError:
32 except ImportError:
29 #python 2.5 compatibility
33 #python 2.5 compatibility
30 import simplejson as json
34 import simplejson as json
35
31 from mercurial.graphmod import colored, CHANGESET, revisions as graph_rev
36 from mercurial.graphmod import colored, CHANGESET, revisions as graph_rev
32 from pylons import request, session, tmpl_context as c
37 from pylons import request, session, tmpl_context as c
38
33 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
39 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
34 from rhodecode.lib.base import BaseController, render
40 from rhodecode.lib.base import BaseController, render
35 from rhodecode.model.scm import ScmModel
41 from rhodecode.model.scm import ScmModel
42
36 from webhelpers.paginate import Page
43 from webhelpers.paginate import Page
37 import logging
44
38 log = logging.getLogger(__name__)
45 log = logging.getLogger(__name__)
39
46
40 class ChangelogController(BaseController):
47 class ChangelogController(BaseController):
41
48
42 @LoginRequired()
49 @LoginRequired()
43 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
50 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
44 'repository.admin')
51 'repository.admin')
45 def __before__(self):
52 def __before__(self):
46 super(ChangelogController, self).__before__()
53 super(ChangelogController, self).__before__()
47
54
48 def index(self):
55 def index(self):
49 limit = 100
56 limit = 100
50 default = 20
57 default = 20
51 if request.params.get('size'):
58 if request.params.get('size'):
52 try:
59 try:
53 int_size = int(request.params.get('size'))
60 int_size = int(request.params.get('size'))
54 except ValueError:
61 except ValueError:
55 int_size = default
62 int_size = default
56 int_size = int_size if int_size <= limit else limit
63 int_size = int_size if int_size <= limit else limit
57 c.size = int_size
64 c.size = int_size
58 session['changelog_size'] = c.size
65 session['changelog_size'] = c.size
59 session.save()
66 session.save()
60 else:
67 else:
61 c.size = int(session.get('changelog_size', default))
68 c.size = int(session.get('changelog_size', default))
62
69
63 changesets = ScmModel().get_repo(c.repo_name)
70 changesets = ScmModel().get_repo(c.repo_name)
64
71
65 p = int(request.params.get('page', 1))
72 p = int(request.params.get('page', 1))
66 c.total_cs = len(changesets)
73 c.total_cs = len(changesets)
67 c.pagination = Page(changesets, page=p, item_count=c.total_cs,
74 c.pagination = Page(changesets, page=p, item_count=c.total_cs,
68 items_per_page=c.size)
75 items_per_page=c.size)
69
76
70 self._graph(changesets, c.size, p)
77 self._graph(changesets, c.size, p)
71
78
72 return render('changelog/changelog.html')
79 return render('changelog/changelog.html')
73
80
74
81
75 def _graph(self, repo, size, p):
82 def _graph(self, repo, size, p):
76 revcount = size
83 revcount = size
77 if not repo.revisions or repo.alias == 'git':
84 if not repo.revisions or repo.alias == 'git':
78 c.jsdata = json.dumps([])
85 c.jsdata = json.dumps([])
79 return
86 return
80
87
81 max_rev = repo.revisions[-1]
88 max_rev = repo.revisions[-1]
82
89
83 offset = 1 if p == 1 else ((p - 1) * revcount + 1)
90 offset = 1 if p == 1 else ((p - 1) * revcount + 1)
84
91
85 rev_start = repo.revisions[(-1 * offset)]
92 rev_start = repo.revisions[(-1 * offset)]
86
93
87 revcount = min(max_rev, revcount)
94 revcount = min(max_rev, revcount)
88 rev_end = max(0, rev_start - revcount)
95 rev_end = max(0, rev_start - revcount)
89 dag = graph_rev(repo.repo, rev_start, rev_end)
96 dag = graph_rev(repo.repo, rev_start, rev_end)
90
97
91 c.dag = tree = list(colored(dag))
98 c.dag = tree = list(colored(dag))
92 data = []
99 data = []
93 for (id, type, ctx, vtx, edges) in tree:
100 for (id, type, ctx, vtx, edges) in tree:
94 if type != CHANGESET:
101 if type != CHANGESET:
95 continue
102 continue
96 data.append(('', vtx, edges))
103 data.append(('', vtx, edges))
97
104
98 c.jsdata = json.dumps(data)
105 c.jsdata = json.dumps(data)
99
106
@@ -1,80 +1,86 b''
1 #!/usr/bin/env python
1 # -*- coding: utf-8 -*-
2 # encoding: utf-8
2 """
3 # feed controller for pylons
3 rhodecode.controllers.feed
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Feed controller for rhodecode
7
8 :created_on: Apr 23, 2010
9 :author: marcink
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
6 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
10 #
17 #
11 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
21 # GNU General Public License for more details.
15 #
22 #
16 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
20 """
27
21 Created on April 23, 2010
28
22 feed controller for pylons
29 import logging
23 @author: marcink
30
24 """
31 from pylons import url, response
25 from pylons import tmpl_context as c, url, response
32 from rhodecode.lib.base import BaseController
26 from rhodecode.lib.base import BaseController, render
27 from rhodecode.model.scm import ScmModel
33 from rhodecode.model.scm import ScmModel
28 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
34 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
29 import logging
35
30 log = logging.getLogger(__name__)
36 log = logging.getLogger(__name__)
31
37
32 class FeedController(BaseController):
38 class FeedController(BaseController):
33
39
34 #secure it or not ?
40 #secure it or not ?
35 def __before__(self):
41 def __before__(self):
36 super(FeedController, self).__before__()
42 super(FeedController, self).__before__()
37 #common values for feeds
43 #common values for feeds
38 self.description = 'Changes on %s repository'
44 self.description = 'Changes on %s repository'
39 self.title = "%s feed"
45 self.title = "%s feed"
40 self.language = 'en-us'
46 self.language = 'en-us'
41 self.ttl = "5"
47 self.ttl = "5"
42 self.feed_nr = 10
48 self.feed_nr = 10
43
49
44 def atom(self, repo_name):
50 def atom(self, repo_name):
45 """Produce an atom-1.0 feed via feedgenerator module"""
51 """Produce an atom-1.0 feed via feedgenerator module"""
46 feed = Atom1Feed(title=self.title % repo_name,
52 feed = Atom1Feed(title=self.title % repo_name,
47 link=url('summary_home', repo_name=repo_name, qualified=True),
53 link=url('summary_home', repo_name=repo_name, qualified=True),
48 description=self.description % repo_name,
54 description=self.description % repo_name,
49 language=self.language,
55 language=self.language,
50 ttl=self.ttl)
56 ttl=self.ttl)
51
57
52 changesets = ScmModel().get_repo(repo_name)
58 changesets = ScmModel().get_repo(repo_name)
53
59
54 for cs in changesets[:self.feed_nr]:
60 for cs in changesets[:self.feed_nr]:
55 feed.add_item(title=cs.message,
61 feed.add_item(title=cs.message,
56 link=url('changeset_home', repo_name=repo_name,
62 link=url('changeset_home', repo_name=repo_name,
57 revision=cs.raw_id, qualified=True),
63 revision=cs.raw_id, qualified=True),
58 description=str(cs.date))
64 description=str(cs.date))
59
65
60 response.content_type = feed.mime_type
66 response.content_type = feed.mime_type
61 return feed.writeString('utf-8')
67 return feed.writeString('utf-8')
62
68
63
69
64 def rss(self, repo_name):
70 def rss(self, repo_name):
65 """Produce an rss2 feed via feedgenerator module"""
71 """Produce an rss2 feed via feedgenerator module"""
66 feed = Rss201rev2Feed(title=self.title % repo_name,
72 feed = Rss201rev2Feed(title=self.title % repo_name,
67 link=url('summary_home', repo_name=repo_name, qualified=True),
73 link=url('summary_home', repo_name=repo_name, qualified=True),
68 description=self.description % repo_name,
74 description=self.description % repo_name,
69 language=self.language,
75 language=self.language,
70 ttl=self.ttl)
76 ttl=self.ttl)
71
77
72 changesets = ScmModel().get_repo(repo_name)
78 changesets = ScmModel().get_repo(repo_name)
73 for cs in changesets[:self.feed_nr]:
79 for cs in changesets[:self.feed_nr]:
74 feed.add_item(title=cs.message,
80 feed.add_item(title=cs.message,
75 link=url('changeset_home', repo_name=repo_name,
81 link=url('changeset_home', repo_name=repo_name,
76 revision=cs.raw_id, qualified=True),
82 revision=cs.raw_id, qualified=True),
77 description=str(cs.date))
83 description=str(cs.date))
78
84
79 response.content_type = feed.mime_type
85 response.content_type = feed.mime_type
80 return feed.writeString('utf-8')
86 return feed.writeString('utf-8')
@@ -1,58 +1,66 b''
1 #!/usr/bin/env python
1 # -*- coding: utf-8 -*-
2 # encoding: utf-8
2 """
3 # hg controller for pylons
3 rhodecode.controllers.home
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~
5 #
5
6 Home controller for Rhodecode
7
8 :created_on: Feb 18, 2010
9 :author: marcink
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
6 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
10 #
17 #
11 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
21 # GNU General Public License for more details.
15 #
22 #
16 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
20 """
27
21 Created on February 18, 2010
28 import logging
22 hg controller for pylons
23 @author: marcink
24 """
25 from operator import itemgetter
29 from operator import itemgetter
30
26 from pylons import tmpl_context as c, request
31 from pylons import tmpl_context as c, request
32
27 from rhodecode.lib.auth import LoginRequired
33 from rhodecode.lib.auth import LoginRequired
28 from rhodecode.lib.base import BaseController, render
34 from rhodecode.lib.base import BaseController, render
29 from rhodecode.model.scm import ScmModel
35 from rhodecode.model.scm import ScmModel
30 import logging
36
31 log = logging.getLogger(__name__)
37 log = logging.getLogger(__name__)
32
38
33 class HomeController(BaseController):
39 class HomeController(BaseController):
34
40
35 @LoginRequired()
41 @LoginRequired()
36 def __before__(self):
42 def __before__(self):
37 super(HomeController, self).__before__()
43 super(HomeController, self).__before__()
38
44
39 def index(self):
45 def index(self):
40 sortables = ['name', 'description', 'last_change', 'tip', 'contact']
46 sortables = ['name', 'description', 'last_change', 'tip', 'contact']
41 current_sort = request.GET.get('sort', 'name')
47 current_sort = request.GET.get('sort', 'name')
42 current_sort_slug = current_sort.replace('-', '')
48 current_sort_slug = current_sort.replace('-', '')
43
49
44 if current_sort_slug not in sortables:
50 if current_sort_slug not in sortables:
45 c.sort_by = 'name'
51 c.sort_by = 'name'
46 current_sort_slug = c.sort_by
52 current_sort_slug = c.sort_by
47 else:
53 else:
48 c.sort_by = current_sort
54 c.sort_by = current_sort
49 c.sort_slug = current_sort_slug
55 c.sort_slug = current_sort_slug
50 cached_repo_list = ScmModel().get_repos()
56 cached_repo_list = ScmModel().get_repos()
51
57
52 sort_key = current_sort_slug + '_sort'
58 sort_key = current_sort_slug + '_sort'
53 if c.sort_by.startswith('-'):
59 if c.sort_by.startswith('-'):
54 c.repos_list = sorted(cached_repo_list, key=itemgetter(sort_key), reverse=True)
60 c.repos_list = sorted(cached_repo_list, key=itemgetter(sort_key),
61 reverse=True)
55 else:
62 else:
56 c.repos_list = sorted(cached_repo_list, key=itemgetter(sort_key), reverse=False)
63 c.repos_list = sorted(cached_repo_list, key=itemgetter(sort_key),
64 reverse=False)
57
65
58 return render('/index.html')
66 return render('/index.html')
@@ -1,93 +1,97 b''
1 #!/usr/bin/env python
1 # -*- coding: utf-8 -*-
2 # encoding: utf-8
2 """
3 # journal controller for pylons
3 rhodecode.controllers.journal
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 #
5
6 Journal controller for pylons
7
8 :created_on: Nov 21, 2010
9 :author: marcink
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
6 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
10 #
17 #
11 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
21 # GNU General Public License for more details.
15 #
22 #
16 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
20 """
27
21 Created on November 21, 2010
28 import logging
22 journal controller for pylons
29 from sqlalchemy import or_
23 @author: marcink
24 """
25
30
26 from pylons import request, response, session, tmpl_context as c, url
31 from pylons import request, response, session, tmpl_context as c, url
27 from pylons.controllers.util import abort, redirect
32
28 from rhodecode.lib.auth import LoginRequired, NotAnonymous
33 from rhodecode.lib.auth import LoginRequired, NotAnonymous
29 from rhodecode.lib.base import BaseController, render
34 from rhodecode.lib.base import BaseController, render
30 from rhodecode.lib.helpers import get_token
35 from rhodecode.lib.helpers import get_token
31 from rhodecode.model.db import UserLog, UserFollowing
36 from rhodecode.model.db import UserLog, UserFollowing
32 from rhodecode.model.scm import ScmModel
37 from rhodecode.model.scm import ScmModel
33 from sqlalchemy import or_
38
34 import logging
39 from paste.httpexceptions import HTTPInternalServerError
35 from paste.httpexceptions import HTTPInternalServerError, HTTPNotFound
36
40
37 log = logging.getLogger(__name__)
41 log = logging.getLogger(__name__)
38
42
39 class JournalController(BaseController):
43 class JournalController(BaseController):
40
44
41
45
42 @LoginRequired()
46 @LoginRequired()
43 @NotAnonymous()
47 @NotAnonymous()
44 def __before__(self):
48 def __before__(self):
45 super(JournalController, self).__before__()
49 super(JournalController, self).__before__()
46
50
47 def index(self):
51 def index(self):
48 # Return a rendered template
52 # Return a rendered template
49
53
50 c.following = self.sa.query(UserFollowing)\
54 c.following = self.sa.query(UserFollowing)\
51 .filter(UserFollowing.user_id == c.rhodecode_user.user_id).all()
55 .filter(UserFollowing.user_id == c.rhodecode_user.user_id).all()
52
56
53 repo_ids = [x.follows_repository.repo_id for x in c.following
57 repo_ids = [x.follows_repository.repo_id for x in c.following
54 if x.follows_repository is not None]
58 if x.follows_repository is not None]
55 user_ids = [x.follows_user.user_id for x in c.following
59 user_ids = [x.follows_user.user_id for x in c.following
56 if x.follows_user is not None]
60 if x.follows_user is not None]
57
61
58 c.journal = self.sa.query(UserLog)\
62 c.journal = self.sa.query(UserLog)\
59 .filter(or_(
63 .filter(or_(
60 UserLog.repository_id.in_(repo_ids),
64 UserLog.repository_id.in_(repo_ids),
61 UserLog.user_id.in_(user_ids),
65 UserLog.user_id.in_(user_ids),
62 ))\
66 ))\
63 .order_by(UserLog.action_date.desc())\
67 .order_by(UserLog.action_date.desc())\
64 .limit(20)\
68 .limit(20)\
65 .all()
69 .all()
66 return render('/journal.html')
70 return render('/journal.html')
67
71
68 def toggle_following(self):
72 def toggle_following(self):
69
73
70 if request.POST.get('auth_token') == get_token():
74 if request.POST.get('auth_token') == get_token():
71 scm_model = ScmModel()
75 scm_model = ScmModel()
72
76
73 user_id = request.POST.get('follows_user_id')
77 user_id = request.POST.get('follows_user_id')
74 if user_id:
78 if user_id:
75 try:
79 try:
76 scm_model.toggle_following_user(user_id,
80 scm_model.toggle_following_user(user_id,
77 c.rhodecode_user.user_id)
81 c.rhodecode_user.user_id)
78 return 'ok'
82 return 'ok'
79 except:
83 except:
80 raise HTTPInternalServerError()
84 raise HTTPInternalServerError()
81
85
82 repo_id = request.POST.get('follows_repo_id')
86 repo_id = request.POST.get('follows_repo_id')
83 if repo_id:
87 if repo_id:
84 try:
88 try:
85 scm_model.toggle_following_repo(repo_id,
89 scm_model.toggle_following_repo(repo_id,
86 c.rhodecode_user.user_id)
90 c.rhodecode_user.user_id)
87 return 'ok'
91 return 'ok'
88 except:
92 except:
89 raise HTTPInternalServerError()
93 raise HTTPInternalServerError()
90
94
91
95
92
96
93 raise HTTPInternalServerError()
97 raise HTTPInternalServerError()
@@ -1,146 +1,152 b''
1 #!/usr/bin/env python
1 # -*- coding: utf-8 -*-
2 # encoding: utf-8
2 """
3 # login controller for pylons
3 rhodecode.controllers.login
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 #
5
6 Login controller for rhodeocode
7
8 :created_on: Apr 22, 2010
9 :author: marcink
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
6 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
10 #
17 #
11 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
21 # GNU General Public License for more details.
15 #
22 #
16 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
20
27
21 """
28 import logging
22 Created on April 22, 2010
29 import formencode
23 login controller for pylons
30
24 @author: marcink
25 """
26 from formencode import htmlfill
31 from formencode import htmlfill
32
33 from pylons.i18n.translation import _
34 from pylons.controllers.util import abort, redirect
27 from pylons import request, response, session, tmpl_context as c, url
35 from pylons import request, response, session, tmpl_context as c, url
28 from pylons.controllers.util import abort, redirect
36
37 import rhodecode.lib.helpers as h
29 from rhodecode.lib.auth import AuthUser, HasPermissionAnyDecorator
38 from rhodecode.lib.auth import AuthUser, HasPermissionAnyDecorator
30 from rhodecode.lib.base import BaseController, render
39 from rhodecode.lib.base import BaseController, render
31 import rhodecode.lib.helpers as h
32 from pylons.i18n.translation import _
33 from rhodecode.model.forms import LoginForm, RegisterForm, PasswordResetForm
40 from rhodecode.model.forms import LoginForm, RegisterForm, PasswordResetForm
34 from rhodecode.model.user import UserModel
41 from rhodecode.model.user import UserModel
35 import formencode
42
36 import logging
37
43
38 log = logging.getLogger(__name__)
44 log = logging.getLogger(__name__)
39
45
40 class LoginController(BaseController):
46 class LoginController(BaseController):
41
47
42 def __before__(self):
48 def __before__(self):
43 super(LoginController, self).__before__()
49 super(LoginController, self).__before__()
44
50
45 def index(self):
51 def index(self):
46 #redirect if already logged in
52 #redirect if already logged in
47 c.came_from = request.GET.get('came_from', None)
53 c.came_from = request.GET.get('came_from', None)
48
54
49 if c.rhodecode_user.is_authenticated \
55 if c.rhodecode_user.is_authenticated \
50 and c.rhodecode_user.username != 'default':
56 and c.rhodecode_user.username != 'default':
51
57
52 return redirect(url('home'))
58 return redirect(url('home'))
53
59
54 if request.POST:
60 if request.POST:
55 #import Login Form validator class
61 #import Login Form validator class
56 login_form = LoginForm()
62 login_form = LoginForm()
57 try:
63 try:
58 c.form_result = login_form.to_python(dict(request.POST))
64 c.form_result = login_form.to_python(dict(request.POST))
59 username = c.form_result['username']
65 username = c.form_result['username']
60 user = UserModel().get_by_username(username, case_insensitive=True)
66 user = UserModel().get_by_username(username, case_insensitive=True)
61 auth_user = AuthUser()
67 auth_user = AuthUser()
62 auth_user.username = user.username
68 auth_user.username = user.username
63 auth_user.is_authenticated = True
69 auth_user.is_authenticated = True
64 auth_user.is_admin = user.admin
70 auth_user.is_admin = user.admin
65 auth_user.user_id = user.user_id
71 auth_user.user_id = user.user_id
66 auth_user.name = user.name
72 auth_user.name = user.name
67 auth_user.lastname = user.lastname
73 auth_user.lastname = user.lastname
68 session['rhodecode_user'] = auth_user
74 session['rhodecode_user'] = auth_user
69 session.save()
75 session.save()
70 log.info('user %s is now authenticated', username)
76 log.info('user %s is now authenticated', username)
71
77
72 user.update_lastlogin()
78 user.update_lastlogin()
73
79
74 if c.came_from:
80 if c.came_from:
75 return redirect(c.came_from)
81 return redirect(c.came_from)
76 else:
82 else:
77 return redirect(url('home'))
83 return redirect(url('home'))
78
84
79 except formencode.Invalid, errors:
85 except formencode.Invalid, errors:
80 return htmlfill.render(
86 return htmlfill.render(
81 render('/login.html'),
87 render('/login.html'),
82 defaults=errors.value,
88 defaults=errors.value,
83 errors=errors.error_dict or {},
89 errors=errors.error_dict or {},
84 prefix_error=False,
90 prefix_error=False,
85 encoding="UTF-8")
91 encoding="UTF-8")
86
92
87 return render('/login.html')
93 return render('/login.html')
88
94
89 @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate',
95 @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate',
90 'hg.register.manual_activate')
96 'hg.register.manual_activate')
91 def register(self):
97 def register(self):
92 user_model = UserModel()
98 user_model = UserModel()
93 c.auto_active = False
99 c.auto_active = False
94 for perm in user_model.get_by_username('default', cache=False).user_perms:
100 for perm in user_model.get_by_username('default', cache=False).user_perms:
95 if perm.permission.permission_name == 'hg.register.auto_activate':
101 if perm.permission.permission_name == 'hg.register.auto_activate':
96 c.auto_active = True
102 c.auto_active = True
97 break
103 break
98
104
99 if request.POST:
105 if request.POST:
100
106
101 register_form = RegisterForm()()
107 register_form = RegisterForm()()
102 try:
108 try:
103 form_result = register_form.to_python(dict(request.POST))
109 form_result = register_form.to_python(dict(request.POST))
104 form_result['active'] = c.auto_active
110 form_result['active'] = c.auto_active
105 user_model.create_registration(form_result)
111 user_model.create_registration(form_result)
106 h.flash(_('You have successfully registered into rhodecode'),
112 h.flash(_('You have successfully registered into rhodecode'),
107 category='success')
113 category='success')
108 return redirect(url('login_home'))
114 return redirect(url('login_home'))
109
115
110 except formencode.Invalid, errors:
116 except formencode.Invalid, errors:
111 return htmlfill.render(
117 return htmlfill.render(
112 render('/register.html'),
118 render('/register.html'),
113 defaults=errors.value,
119 defaults=errors.value,
114 errors=errors.error_dict or {},
120 errors=errors.error_dict or {},
115 prefix_error=False,
121 prefix_error=False,
116 encoding="UTF-8")
122 encoding="UTF-8")
117
123
118 return render('/register.html')
124 return render('/register.html')
119
125
120 def password_reset(self):
126 def password_reset(self):
121 user_model = UserModel()
127 user_model = UserModel()
122 if request.POST:
128 if request.POST:
123
129
124 password_reset_form = PasswordResetForm()()
130 password_reset_form = PasswordResetForm()()
125 try:
131 try:
126 form_result = password_reset_form.to_python(dict(request.POST))
132 form_result = password_reset_form.to_python(dict(request.POST))
127 user_model.reset_password(form_result)
133 user_model.reset_password(form_result)
128 h.flash(_('Your new password was sent'),
134 h.flash(_('Your new password was sent'),
129 category='success')
135 category='success')
130 return redirect(url('login_home'))
136 return redirect(url('login_home'))
131
137
132 except formencode.Invalid, errors:
138 except formencode.Invalid, errors:
133 return htmlfill.render(
139 return htmlfill.render(
134 render('/password_reset.html'),
140 render('/password_reset.html'),
135 defaults=errors.value,
141 defaults=errors.value,
136 errors=errors.error_dict or {},
142 errors=errors.error_dict or {},
137 prefix_error=False,
143 prefix_error=False,
138 encoding="UTF-8")
144 encoding="UTF-8")
139
145
140 return render('/password_reset.html')
146 return render('/password_reset.html')
141
147
142 def logout(self):
148 def logout(self):
143 session['rhodecode_user'] = AuthUser()
149 session['rhodecode_user'] = AuthUser()
144 session.save()
150 session.save()
145 log.info('Logging out and setting user as Empty')
151 log.info('Logging out and setting user as Empty')
146 redirect(url('home'))
152 redirect(url('home'))
@@ -1,113 +1,120 b''
1 #!/usr/bin/env python
1 # -*- coding: utf-8 -*-
2 # encoding: utf-8
2 """
3 # search controller for pylons
3 rhodecode.controllers.search
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 #
5
6 Search controller for rhodecode
7
8 :created_on: Aug 7, 2010
9 :author: marcink
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
6 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
10 #
17 #
11 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
21 # GNU General Public License for more details.
15 #
22 #
16 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
20 """
27 import logging
21 Created on Aug 7, 2010
28 import traceback
22 search controller for pylons
29
23 @author: marcink
30 from pylons.i18n.translation import _
24 """
25 from pylons import request, response, config, session, tmpl_context as c, url
31 from pylons import request, response, config, session, tmpl_context as c, url
26 from pylons.controllers.util import abort, redirect
32 from pylons.controllers.util import abort, redirect
33
27 from rhodecode.lib.auth import LoginRequired
34 from rhodecode.lib.auth import LoginRequired
28 from rhodecode.lib.base import BaseController, render
35 from rhodecode.lib.base import BaseController, render
29 from rhodecode.lib.indexers import SCHEMA, IDX_NAME, ResultWrapper
36 from rhodecode.lib.indexers import SCHEMA, IDX_NAME, ResultWrapper
37
30 from webhelpers.paginate import Page
38 from webhelpers.paginate import Page
31 from webhelpers.util import update_params
39 from webhelpers.util import update_params
32 from pylons.i18n.translation import _
40
33 from whoosh.index import open_dir, EmptyIndexError
41 from whoosh.index import open_dir, EmptyIndexError
34 from whoosh.qparser import QueryParser, QueryParserError
42 from whoosh.qparser import QueryParser, QueryParserError
35 from whoosh.query import Phrase
43 from whoosh.query import Phrase
36 import logging
37 import traceback
38
44
39 log = logging.getLogger(__name__)
45 log = logging.getLogger(__name__)
40
46
41 class SearchController(BaseController):
47 class SearchController(BaseController):
42
48
43 @LoginRequired()
49 @LoginRequired()
44 def __before__(self):
50 def __before__(self):
45 super(SearchController, self).__before__()
51 super(SearchController, self).__before__()
46
52
47 def index(self, search_repo=None):
53 def index(self, search_repo=None):
48 c.repo_name = search_repo
54 c.repo_name = search_repo
49 c.formated_results = []
55 c.formated_results = []
50 c.runtime = ''
56 c.runtime = ''
51 c.cur_query = request.GET.get('q', None)
57 c.cur_query = request.GET.get('q', None)
52 c.cur_type = request.GET.get('type', 'source')
58 c.cur_type = request.GET.get('type', 'source')
53 c.cur_search = search_type = {'content':'content',
59 c.cur_search = search_type = {'content':'content',
54 'commit':'content',
60 'commit':'content',
55 'path':'path',
61 'path':'path',
56 'repository':'repository'}\
62 'repository':'repository'}\
57 .get(c.cur_type, 'content')
63 .get(c.cur_type, 'content')
58
64
59
65
60 if c.cur_query:
66 if c.cur_query:
61 cur_query = c.cur_query.lower()
67 cur_query = c.cur_query.lower()
62
68
63 if c.cur_query:
69 if c.cur_query:
64 p = int(request.params.get('page', 1))
70 p = int(request.params.get('page', 1))
65 highlight_items = set()
71 highlight_items = set()
66 try:
72 try:
67 idx = open_dir(config['app_conf']['index_dir']
73 idx = open_dir(config['app_conf']['index_dir']
68 , indexname=IDX_NAME)
74 , indexname=IDX_NAME)
69 searcher = idx.searcher()
75 searcher = idx.searcher()
70
76
71 qp = QueryParser(search_type, schema=SCHEMA)
77 qp = QueryParser(search_type, schema=SCHEMA)
72 if c.repo_name:
78 if c.repo_name:
73 cur_query = u'repository:%s %s' % (c.repo_name, cur_query)
79 cur_query = u'repository:%s %s' % (c.repo_name, cur_query)
74 try:
80 try:
75 query = qp.parse(unicode(cur_query))
81 query = qp.parse(unicode(cur_query))
76
82
77 if isinstance(query, Phrase):
83 if isinstance(query, Phrase):
78 highlight_items.update(query.words)
84 highlight_items.update(query.words)
79 else:
85 else:
80 for i in query.all_terms():
86 for i in query.all_terms():
81 if i[0] == 'content':
87 if i[0] == 'content':
82 highlight_items.add(i[1])
88 highlight_items.add(i[1])
83
89
84 matcher = query.matcher(searcher)
90 matcher = query.matcher(searcher)
85
91
86 log.debug(query)
92 log.debug(query)
87 log.debug(highlight_items)
93 log.debug(highlight_items)
88 results = searcher.search(query)
94 results = searcher.search(query)
89 res_ln = len(results)
95 res_ln = len(results)
90 c.runtime = '%s results (%.3f seconds)' \
96 c.runtime = '%s results (%.3f seconds)' \
91 % (res_ln, results.runtime)
97 % (res_ln, results.runtime)
92
98
93 def url_generator(**kw):
99 def url_generator(**kw):
94 return update_params("?q=%s&type=%s" \
100 return update_params("?q=%s&type=%s" \
95 % (c.cur_query, c.cur_search), **kw)
101 % (c.cur_query, c.cur_search), **kw)
96
102
97 c.formated_results = Page(
103 c.formated_results = Page(
98 ResultWrapper(search_type, searcher, matcher,
104 ResultWrapper(search_type, searcher, matcher,
99 highlight_items),
105 highlight_items),
100 page=p, item_count=res_ln,
106 page=p, item_count=res_ln,
101 items_per_page=10, url=url_generator)
107 items_per_page=10, url=url_generator)
102
108
103
109
104 except QueryParserError:
110 except QueryParserError:
105 c.runtime = _('Invalid search query. Try quoting it.')
111 c.runtime = _('Invalid search query. Try quoting it.')
106 searcher.close()
112 searcher.close()
107 except (EmptyIndexError, IOError):
113 except (EmptyIndexError, IOError):
108 log.error(traceback.format_exc())
114 log.error(traceback.format_exc())
109 log.error('Empty Index data')
115 log.error('Empty Index data')
110 c.runtime = _('There is no index to search in. Please run whoosh indexer')
116 c.runtime = _('There is no index to search in. '
117 'Please run whoosh indexer')
111
118
112 # Return a rendered template
119 # Return a rendered template
113 return render('/search/search.html')
120 return render('/search/search.html')
@@ -1,178 +1,184 b''
1 #!/usr/bin/env python
1 # -*- coding: utf-8 -*-
2 # encoding: utf-8
2 """
3 # settings controller for pylons
3 rhodecode.controllers.settings
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 #
5
6 Settings controller for rhodecode
7
8 :created_on: Jun 30, 2010
9 :author: marcink
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
6 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
10 #
17 #
11 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
21 # GNU General Public License for more details.
15 #
22 #
16 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
20 """
27
21 Created on June 30, 2010
28 import logging
22 settings controller for pylons
29 import traceback
23 @author: marcink
30
24 """
31 import formencode
25 from formencode import htmlfill
32 from formencode import htmlfill
33
26 from pylons import tmpl_context as c, request, url
34 from pylons import tmpl_context as c, request, url
27 from pylons.controllers.util import redirect
35 from pylons.controllers.util import redirect
28 from pylons.i18n.translation import _
36 from pylons.i18n.translation import _
37
38 import rhodecode.lib.helpers as h
29 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator
39 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAllDecorator
30 from rhodecode.lib.base import BaseController, render
40 from rhodecode.lib.base import BaseController, render
31 from rhodecode.lib.utils import invalidate_cache, action_logger
41 from rhodecode.lib.utils import invalidate_cache, action_logger
32 from rhodecode.model.forms import RepoSettingsForm, RepoForkForm
42 from rhodecode.model.forms import RepoSettingsForm, RepoForkForm
33 from rhodecode.model.repo import RepoModel
43 from rhodecode.model.repo import RepoModel
34 import formencode
35 import logging
36 import rhodecode.lib.helpers as h
37 import traceback
38
44
39 log = logging.getLogger(__name__)
45 log = logging.getLogger(__name__)
40
46
41 class SettingsController(BaseController):
47 class SettingsController(BaseController):
42
48
43 @LoginRequired()
49 @LoginRequired()
44 @HasRepoPermissionAllDecorator('repository.admin')
50 @HasRepoPermissionAllDecorator('repository.admin')
45 def __before__(self):
51 def __before__(self):
46 super(SettingsController, self).__before__()
52 super(SettingsController, self).__before__()
47
53
48 def index(self, repo_name):
54 def index(self, repo_name):
49 repo_model = RepoModel()
55 repo_model = RepoModel()
50 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
56 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
51 if not repo:
57 if not repo:
52 h.flash(_('%s repository is not mapped to db perhaps'
58 h.flash(_('%s repository is not mapped to db perhaps'
53 ' it was created or renamed from the file system'
59 ' it was created or renamed from the file system'
54 ' please run the application again'
60 ' please run the application again'
55 ' in order to rescan repositories') % repo_name,
61 ' in order to rescan repositories') % repo_name,
56 category='error')
62 category='error')
57
63
58 return redirect(url('home'))
64 return redirect(url('home'))
59 defaults = c.repo_info.get_dict()
65 defaults = c.repo_info.get_dict()
60 defaults.update({'user':c.repo_info.user.username})
66 defaults.update({'user':c.repo_info.user.username})
61 c.users_array = repo_model.get_users_js()
67 c.users_array = repo_model.get_users_js()
62
68
63 for p in c.repo_info.repo_to_perm:
69 for p in c.repo_info.repo_to_perm:
64 defaults.update({'perm_%s' % p.user.username:
70 defaults.update({'perm_%s' % p.user.username:
65 p.permission.permission_name})
71 p.permission.permission_name})
66
72
67 return htmlfill.render(
73 return htmlfill.render(
68 render('settings/repo_settings.html'),
74 render('settings/repo_settings.html'),
69 defaults=defaults,
75 defaults=defaults,
70 encoding="UTF-8",
76 encoding="UTF-8",
71 force_defaults=False
77 force_defaults=False
72 )
78 )
73
79
74 def update(self, repo_name):
80 def update(self, repo_name):
75 repo_model = RepoModel()
81 repo_model = RepoModel()
76 changed_name = repo_name
82 changed_name = repo_name
77 _form = RepoSettingsForm(edit=True, old_data={'repo_name':repo_name})()
83 _form = RepoSettingsForm(edit=True, old_data={'repo_name':repo_name})()
78 try:
84 try:
79 form_result = _form.to_python(dict(request.POST))
85 form_result = _form.to_python(dict(request.POST))
80 repo_model.update(repo_name, form_result)
86 repo_model.update(repo_name, form_result)
81 invalidate_cache('get_repo_cached_%s' % repo_name)
87 invalidate_cache('get_repo_cached_%s' % repo_name)
82 h.flash(_('Repository %s updated successfully' % repo_name),
88 h.flash(_('Repository %s updated successfully' % repo_name),
83 category='success')
89 category='success')
84 changed_name = form_result['repo_name']
90 changed_name = form_result['repo_name']
85 action_logger(self.rhodecode_user, 'user_updated_repo',
91 action_logger(self.rhodecode_user, 'user_updated_repo',
86 changed_name, '', self.sa)
92 changed_name, '', self.sa)
87 except formencode.Invalid, errors:
93 except formencode.Invalid, errors:
88 c.repo_info = repo_model.get_by_repo_name(repo_name)
94 c.repo_info = repo_model.get_by_repo_name(repo_name)
89 c.users_array = repo_model.get_users_js()
95 c.users_array = repo_model.get_users_js()
90 errors.value.update({'user':c.repo_info.user.username})
96 errors.value.update({'user':c.repo_info.user.username})
91 return htmlfill.render(
97 return htmlfill.render(
92 render('settings/repo_settings.html'),
98 render('settings/repo_settings.html'),
93 defaults=errors.value,
99 defaults=errors.value,
94 errors=errors.error_dict or {},
100 errors=errors.error_dict or {},
95 prefix_error=False,
101 prefix_error=False,
96 encoding="UTF-8")
102 encoding="UTF-8")
97 except Exception:
103 except Exception:
98 log.error(traceback.format_exc())
104 log.error(traceback.format_exc())
99 h.flash(_('error occurred during update of repository %s') \
105 h.flash(_('error occurred during update of repository %s') \
100 % repo_name, category='error')
106 % repo_name, category='error')
101
107
102 return redirect(url('repo_settings_home', repo_name=changed_name))
108 return redirect(url('repo_settings_home', repo_name=changed_name))
103
109
104
110
105
111
106 def delete(self, repo_name):
112 def delete(self, repo_name):
107 """DELETE /repos/repo_name: Delete an existing item"""
113 """DELETE /repos/repo_name: Delete an existing item"""
108 # Forms posted to this method should contain a hidden field:
114 # Forms posted to this method should contain a hidden field:
109 # <input type="hidden" name="_method" value="DELETE" />
115 # <input type="hidden" name="_method" value="DELETE" />
110 # Or using helpers:
116 # Or using helpers:
111 # h.form(url('repo_settings_delete', repo_name=ID),
117 # h.form(url('repo_settings_delete', repo_name=ID),
112 # method='delete')
118 # method='delete')
113 # url('repo_settings_delete', repo_name=ID)
119 # url('repo_settings_delete', repo_name=ID)
114
120
115 repo_model = RepoModel()
121 repo_model = RepoModel()
116 repo = repo_model.get_by_repo_name(repo_name)
122 repo = repo_model.get_by_repo_name(repo_name)
117 if not repo:
123 if not repo:
118 h.flash(_('%s repository is not mapped to db perhaps'
124 h.flash(_('%s repository is not mapped to db perhaps'
119 ' it was moved or renamed from the filesystem'
125 ' it was moved or renamed from the filesystem'
120 ' please run the application again'
126 ' please run the application again'
121 ' in order to rescan repositories') % repo_name,
127 ' in order to rescan repositories') % repo_name,
122 category='error')
128 category='error')
123
129
124 return redirect(url('home'))
130 return redirect(url('home'))
125 try:
131 try:
126 action_logger(self.rhodecode_user, 'user_deleted_repo',
132 action_logger(self.rhodecode_user, 'user_deleted_repo',
127 repo_name, '', self.sa)
133 repo_name, '', self.sa)
128 repo_model.delete(repo)
134 repo_model.delete(repo)
129 invalidate_cache('get_repo_cached_%s' % repo_name)
135 invalidate_cache('get_repo_cached_%s' % repo_name)
130 h.flash(_('deleted repository %s') % repo_name, category='success')
136 h.flash(_('deleted repository %s') % repo_name, category='success')
131 except Exception:
137 except Exception:
132 h.flash(_('An error occurred during deletion of %s') % repo_name,
138 h.flash(_('An error occurred during deletion of %s') % repo_name,
133 category='error')
139 category='error')
134
140
135 return redirect(url('home'))
141 return redirect(url('home'))
136
142
137 def fork(self, repo_name):
143 def fork(self, repo_name):
138 repo_model = RepoModel()
144 repo_model = RepoModel()
139 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
145 c.repo_info = repo = repo_model.get_by_repo_name(repo_name)
140 if not repo:
146 if not repo:
141 h.flash(_('%s repository is not mapped to db perhaps'
147 h.flash(_('%s repository is not mapped to db perhaps'
142 ' it was created or renamed from the file system'
148 ' it was created or renamed from the file system'
143 ' please run the application again'
149 ' please run the application again'
144 ' in order to rescan repositories') % repo_name,
150 ' in order to rescan repositories') % repo_name,
145 category='error')
151 category='error')
146
152
147 return redirect(url('home'))
153 return redirect(url('home'))
148
154
149 return render('settings/repo_fork.html')
155 return render('settings/repo_fork.html')
150
156
151
157
152
158
153 def fork_create(self, repo_name):
159 def fork_create(self, repo_name):
154 repo_model = RepoModel()
160 repo_model = RepoModel()
155 c.repo_info = repo_model.get_by_repo_name(repo_name)
161 c.repo_info = repo_model.get_by_repo_name(repo_name)
156 _form = RepoForkForm(old_data={'repo_type':c.repo_info.repo_type})()
162 _form = RepoForkForm(old_data={'repo_type':c.repo_info.repo_type})()
157 form_result = {}
163 form_result = {}
158 try:
164 try:
159 form_result = _form.to_python(dict(request.POST))
165 form_result = _form.to_python(dict(request.POST))
160 form_result.update({'repo_name':repo_name})
166 form_result.update({'repo_name':repo_name})
161 repo_model.create_fork(form_result, c.rhodecode_user)
167 repo_model.create_fork(form_result, c.rhodecode_user)
162 h.flash(_('forked %s repository as %s') \
168 h.flash(_('forked %s repository as %s') \
163 % (repo_name, form_result['fork_name']),
169 % (repo_name, form_result['fork_name']),
164 category='success')
170 category='success')
165 action_logger(self.rhodecode_user,
171 action_logger(self.rhodecode_user,
166 'user_forked_repo:%s' % form_result['fork_name'],
172 'user_forked_repo:%s' % form_result['fork_name'],
167 repo_name, '', self.sa)
173 repo_name, '', self.sa)
168 except formencode.Invalid, errors:
174 except formencode.Invalid, errors:
169 c.new_repo = errors.value['fork_name']
175 c.new_repo = errors.value['fork_name']
170 r = render('settings/repo_fork.html')
176 r = render('settings/repo_fork.html')
171
177
172 return htmlfill.render(
178 return htmlfill.render(
173 r,
179 r,
174 defaults=errors.value,
180 defaults=errors.value,
175 errors=errors.error_dict or {},
181 errors=errors.error_dict or {},
176 prefix_error=False,
182 prefix_error=False,
177 encoding="UTF-8")
183 encoding="UTF-8")
178 return redirect(url('home'))
184 return redirect(url('home'))
@@ -1,49 +1,56 b''
1 #!/usr/bin/env python
1 # -*- coding: utf-8 -*-
2 # encoding: utf-8
2 """
3 # shortlog controller for pylons
3 rhodecode.controllers.shortlog
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Shortlog controller for rhodecode
7
8 :created_on: Apr 18, 2010
9 :author: marcink
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
6 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
10 #
17 #
11 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
21 # GNU General Public License for more details.
15 #
22 #
16 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
20 """
27
21 Created on April 18, 2010
28 import logging
22 shortlog controller for pylons
29
23 @author: marcink
24 """
25 from pylons import tmpl_context as c, request
30 from pylons import tmpl_context as c, request
31
32 from webhelpers.paginate import Page
33
26 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
34 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
27 from rhodecode.lib.base import BaseController, render
35 from rhodecode.lib.base import BaseController, render
28 from rhodecode.model.scm import ScmModel
36 from rhodecode.model.scm import ScmModel
29 from webhelpers.paginate import Page
37
30 import logging
31 log = logging.getLogger(__name__)
38 log = logging.getLogger(__name__)
32
39
33 class ShortlogController(BaseController):
40 class ShortlogController(BaseController):
34
41
35 @LoginRequired()
42 @LoginRequired()
36 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
43 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
37 'repository.admin')
44 'repository.admin')
38 def __before__(self):
45 def __before__(self):
39 super(ShortlogController, self).__before__()
46 super(ShortlogController, self).__before__()
40
47
41 def index(self):
48 def index(self):
42 p = int(request.params.get('page', 1))
49 p = int(request.params.get('page', 1))
43 repo = ScmModel().get_repo(c.repo_name)
50 repo = ScmModel().get_repo(c.repo_name)
44 c.repo_changesets = Page(repo, page=p, items_per_page=20)
51 c.repo_changesets = Page(repo, page=p, items_per_page=20)
45 c.shortlog_data = render('shortlog/shortlog_data.html')
52 c.shortlog_data = render('shortlog/shortlog_data.html')
46 if request.params.get('partial'):
53 if request.params.get('partial'):
47 return c.shortlog_data
54 return c.shortlog_data
48 r = render('shortlog/shortlog.html')
55 r = render('shortlog/shortlog.html')
49 return r
56 return r
@@ -1,47 +1,53 b''
1 #!/usr/bin/env python
1 # -*- coding: utf-8 -*-
2 # encoding: utf-8
2 """
3 # tags controller for pylons
3 rhodecode.controllers.tags
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~
5 #
5
6 Tags controller for rhodecode
7
8 :created_on: Apr 21, 2010
9 :author: marcink
10 :copyright: (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
6 # This program is free software; you can redistribute it and/or
13 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
14 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
15 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
16 # of the License or (at your opinion) any later version of the license.
10 #
17 #
11 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
21 # GNU General Public License for more details.
15 #
22 #
16 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
24 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
26 # MA 02110-1301, USA.
20 """
27 import logging
21 Created on April 21, 2010
28
22 tags controller for pylons
23 @author: marcink
24 """
25 from pylons import tmpl_context as c
29 from pylons import tmpl_context as c
30
26 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
31 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
27 from rhodecode.lib.base import BaseController, render
32 from rhodecode.lib.base import BaseController, render
28 from rhodecode.lib.utils import OrderedDict
33 from rhodecode.lib.utils import OrderedDict
29 from rhodecode.model.scm import ScmModel
34 from rhodecode.model.scm import ScmModel
30 import logging
35
31 log = logging.getLogger(__name__)
36 log = logging.getLogger(__name__)
32
37
33 class TagsController(BaseController):
38 class TagsController(BaseController):
34
39
35 @LoginRequired()
40 @LoginRequired()
36 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', 'repository.admin')
41 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
42 'repository.admin')
37 def __before__(self):
43 def __before__(self):
38 super(TagsController, self).__before__()
44 super(TagsController, self).__before__()
39
45
40 def index(self):
46 def index(self):
41 hg_model = ScmModel()
47 hg_model = ScmModel()
42 c.repo_info = hg_model.get_repo(c.repo_name)
48 c.repo_info = hg_model.get_repo(c.repo_name)
43 c.repo_tags = OrderedDict()
49 c.repo_tags = OrderedDict()
44 for name, hash_ in c.repo_info.tags.items():
50 for name, hash_ in c.repo_info.tags.items():
45 c.repo_tags[name] = c.repo_info.get_changeset(hash_)
51 c.repo_tags[name] = c.repo_info.get_changeset(hash_)
46
52
47 return render('tags/tags.html')
53 return render('tags/tags.html')
General Comments 0
You need to be logged in to leave comments. Login now