##// END OF EJS Templates
Added simple forks page, resolves issue #179
marcink -
r1301:7e75af30 beta
parent child Browse files
Show More
@@ -0,0 +1,56 b''
1 # -*- coding: utf-8 -*-
2 """
3 rhodecode.controllers.forks
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
6 forks controller for rhodecode
7
8 :created_on: Apr 23, 2011
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
12 """
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
17 #
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
22 #
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 import logging
26
27 from pylons import tmpl_context as c, request
28
29 from rhodecode.lib.helpers import Page
30 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
31 from rhodecode.lib.base import BaseRepoController, render
32 from rhodecode.model.db import Repository, User, UserFollowing
33
34 log = logging.getLogger(__name__)
35
36
37 class ForksController(BaseRepoController):
38
39 @LoginRequired()
40 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
41 'repository.admin')
42 def __before__(self):
43 super(ForksController, self).__before__()
44
45 def forks(self, repo_name):
46 p = int(request.params.get('page', 1))
47 repo_id = Repository.by_repo_name(repo_name).repo_id
48 d = Repository.get_repo_forks(repo_id)
49 c.forks_pager = Page(d, page=p, items_per_page=20)
50
51 c.forks_data = render('/forks/forks_data.html')
52
53 if request.params.get('partial'):
54 return c.forks_data
55
56 return render('/forks/forks.html')
@@ -0,0 +1,32 b''
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
3
4 <%def name="title()">
5 ${c.repo_name} ${_('Forks')} - ${c.rhodecode_name}
6 </%def>
7
8 <%def name="breadcrumbs_links()">
9 ${h.link_to(u'Home',h.url('/'))}
10 &raquo;
11 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
12 &raquo;
13 ${_('forks')}
14 </%def>
15
16 <%def name="page_nav()">
17 ${self.menu('forks')}
18 </%def>
19 <%def name="main()">
20 <div class="box">
21 <!-- box / title -->
22 <div class="title">
23 ${self.breadcrumbs()}
24 </div>
25 <!-- end box / title -->
26 <div class="table">
27 <div id="forks">
28 ${c.forks_data}
29 </div>
30 </div>
31 </div>
32 </%def> No newline at end of file
@@ -0,0 +1,40 b''
1 ## -*- coding: utf-8 -*-
2
3 % for f in c.forks_pager:
4 <div>
5 <div class="fork_user">
6 <div class="gravatar">
7 <img alt="gravatar" src="${h.gravatar_url(f.user.email,24)}"/>
8 </div>
9 <span style="font-size: 20px">
10 <b>${f.user.username}</b> (${f.user.name} ${f.user.lastname}) /
11 ${h.link_to(f.repo_name,h.url('summary_home',repo_name=f.repo_name))}
12 </span>
13 <div style="padding:5px 3px 3px 42px;">${f.description}</div>
14 </div>
15 <div style="clear:both;padding-top: 10px"></div>
16 <div class="follower_date">${_('forked')} -
17 <span class="tooltip" title="${f.created_on}"> ${h.age(f.created_on)}</span></div>
18 <div style="border-bottom: 1px solid #DDD;margin:10px 0px 10px 0px"></div>
19 </div>
20 % endfor
21
22 <div class="pagination-wh pagination-left">
23 <script type="text/javascript">
24 var data_div = 'forks';
25 YAHOO.util.Event.onDOMReady(function(){
26 YAHOO.util.Event.addListener(
27 YUD.getElementsByClassName('pager_link'),"click",
28 function(){
29 YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');
30 });
31 });
32 </script>
33
34 ${c.forks_pager.pager('$link_previous ~2~ $link_next',
35 onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{
36 success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText;
37 YUE.on(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){
38 YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');});
39 YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")}
40 </div> No newline at end of file
@@ -1,344 +1,348 b''
1 """
1 """
2 Routes configuration
2 Routes configuration
3
3
4 The more specific and detailed routes should be defined first so they
4 The more specific and detailed routes should be defined first so they
5 may take precedent over the more generic routes. For more information
5 may take precedent over the more generic routes. For more information
6 refer to the routes manual at http://routes.groovie.org/docs/
6 refer to the routes manual at http://routes.groovie.org/docs/
7 """
7 """
8 from __future__ import with_statement
8 from __future__ import with_statement
9 from routes import Mapper
9 from routes import Mapper
10 from rhodecode.lib.utils import check_repo_fast as cr
10 from rhodecode.lib.utils import check_repo_fast as cr
11
11
12
12
13 def make_map(config):
13 def make_map(config):
14 """Create, configure and return the routes Mapper"""
14 """Create, configure and return the routes Mapper"""
15 rmap = Mapper(directory=config['pylons.paths']['controllers'],
15 rmap = Mapper(directory=config['pylons.paths']['controllers'],
16 always_scan=config['debug'])
16 always_scan=config['debug'])
17 rmap.minimization = False
17 rmap.minimization = False
18 rmap.explicit = False
18 rmap.explicit = False
19
19
20 def check_repo(environ, match_dict):
20 def check_repo(environ, match_dict):
21 """
21 """
22 check for valid repository for proper 404 handling
22 check for valid repository for proper 404 handling
23 :param environ:
23 :param environ:
24 :param match_dict:
24 :param match_dict:
25 """
25 """
26 repo_name = match_dict.get('repo_name')
26 repo_name = match_dict.get('repo_name')
27 return not cr(repo_name, config['base_path'])
27 return not cr(repo_name, config['base_path'])
28
28
29 # The ErrorController route (handles 404/500 error pages); it should
29 # The ErrorController route (handles 404/500 error pages); it should
30 # likely stay at the top, ensuring it can always be resolved
30 # likely stay at the top, ensuring it can always be resolved
31 rmap.connect('/error/{action}', controller='error')
31 rmap.connect('/error/{action}', controller='error')
32 rmap.connect('/error/{action}/{id}', controller='error')
32 rmap.connect('/error/{action}/{id}', controller='error')
33
33
34 #==========================================================================
34 #==========================================================================
35 # CUSTOM ROUTES HERE
35 # CUSTOM ROUTES HERE
36 #==========================================================================
36 #==========================================================================
37
37
38 #MAIN PAGE
38 #MAIN PAGE
39 rmap.connect('home', '/', controller='home', action='index')
39 rmap.connect('home', '/', controller='home', action='index')
40 rmap.connect('repo_switcher', '/repos', controller='home',
40 rmap.connect('repo_switcher', '/repos', controller='home',
41 action='repo_switcher')
41 action='repo_switcher')
42 rmap.connect('bugtracker',
42 rmap.connect('bugtracker',
43 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
43 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
44 _static=True)
44 _static=True)
45 rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
45 rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
46
46
47 #ADMIN REPOSITORY REST ROUTES
47 #ADMIN REPOSITORY REST ROUTES
48 with rmap.submapper(path_prefix='/_admin', controller='admin/repos') as m:
48 with rmap.submapper(path_prefix='/_admin', controller='admin/repos') as m:
49 m.connect("repos", "/repos",
49 m.connect("repos", "/repos",
50 action="create", conditions=dict(method=["POST"]))
50 action="create", conditions=dict(method=["POST"]))
51 m.connect("repos", "/repos",
51 m.connect("repos", "/repos",
52 action="index", conditions=dict(method=["GET"]))
52 action="index", conditions=dict(method=["GET"]))
53 m.connect("formatted_repos", "/repos.{format}",
53 m.connect("formatted_repos", "/repos.{format}",
54 action="index",
54 action="index",
55 conditions=dict(method=["GET"]))
55 conditions=dict(method=["GET"]))
56 m.connect("new_repo", "/repos/new",
56 m.connect("new_repo", "/repos/new",
57 action="new", conditions=dict(method=["GET"]))
57 action="new", conditions=dict(method=["GET"]))
58 m.connect("formatted_new_repo", "/repos/new.{format}",
58 m.connect("formatted_new_repo", "/repos/new.{format}",
59 action="new", conditions=dict(method=["GET"]))
59 action="new", conditions=dict(method=["GET"]))
60 m.connect("/repos/{repo_name:.*}",
60 m.connect("/repos/{repo_name:.*}",
61 action="update", conditions=dict(method=["PUT"],
61 action="update", conditions=dict(method=["PUT"],
62 function=check_repo))
62 function=check_repo))
63 m.connect("/repos/{repo_name:.*}",
63 m.connect("/repos/{repo_name:.*}",
64 action="delete", conditions=dict(method=["DELETE"],
64 action="delete", conditions=dict(method=["DELETE"],
65 function=check_repo))
65 function=check_repo))
66 m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
66 m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
67 action="edit", conditions=dict(method=["GET"],
67 action="edit", conditions=dict(method=["GET"],
68 function=check_repo))
68 function=check_repo))
69 m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
69 m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
70 action="edit", conditions=dict(method=["GET"],
70 action="edit", conditions=dict(method=["GET"],
71 function=check_repo))
71 function=check_repo))
72 m.connect("repo", "/repos/{repo_name:.*}",
72 m.connect("repo", "/repos/{repo_name:.*}",
73 action="show", conditions=dict(method=["GET"],
73 action="show", conditions=dict(method=["GET"],
74 function=check_repo))
74 function=check_repo))
75 m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
75 m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
76 action="show", conditions=dict(method=["GET"],
76 action="show", conditions=dict(method=["GET"],
77 function=check_repo))
77 function=check_repo))
78 #ajax delete repo perm user
78 #ajax delete repo perm user
79 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
79 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
80 action="delete_perm_user", conditions=dict(method=["DELETE"],
80 action="delete_perm_user", conditions=dict(method=["DELETE"],
81 function=check_repo))
81 function=check_repo))
82 #ajax delete repo perm users_group
82 #ajax delete repo perm users_group
83 m.connect('delete_repo_users_group',
83 m.connect('delete_repo_users_group',
84 "/repos_delete_users_group/{repo_name:.*}",
84 "/repos_delete_users_group/{repo_name:.*}",
85 action="delete_perm_users_group",
85 action="delete_perm_users_group",
86 conditions=dict(method=["DELETE"], function=check_repo))
86 conditions=dict(method=["DELETE"], function=check_repo))
87
87
88 #settings actions
88 #settings actions
89 m.connect('repo_stats', "/repos_stats/{repo_name:.*}",
89 m.connect('repo_stats', "/repos_stats/{repo_name:.*}",
90 action="repo_stats", conditions=dict(method=["DELETE"],
90 action="repo_stats", conditions=dict(method=["DELETE"],
91 function=check_repo))
91 function=check_repo))
92 m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
92 m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
93 action="repo_cache", conditions=dict(method=["DELETE"],
93 action="repo_cache", conditions=dict(method=["DELETE"],
94 function=check_repo))
94 function=check_repo))
95 m.connect('repo_public_journal',
95 m.connect('repo_public_journal',
96 "/repos_public_journal/{repo_name:.*}",
96 "/repos_public_journal/{repo_name:.*}",
97 action="repo_public_journal", conditions=dict(method=["PUT"],
97 action="repo_public_journal", conditions=dict(method=["PUT"],
98 function=check_repo))
98 function=check_repo))
99 m.connect('repo_pull', "/repo_pull/{repo_name:.*}",
99 m.connect('repo_pull', "/repo_pull/{repo_name:.*}",
100 action="repo_pull", conditions=dict(method=["PUT"],
100 action="repo_pull", conditions=dict(method=["PUT"],
101 function=check_repo))
101 function=check_repo))
102
102
103 #ADMIN REPOS GROUP REST ROUTES
103 #ADMIN REPOS GROUP REST ROUTES
104 rmap.resource('repos_group', 'repos_groups',
104 rmap.resource('repos_group', 'repos_groups',
105 controller='admin/repos_groups', path_prefix='/_admin')
105 controller='admin/repos_groups', path_prefix='/_admin')
106
106
107 #ADMIN USER REST ROUTES
107 #ADMIN USER REST ROUTES
108 with rmap.submapper(path_prefix='/_admin', controller='admin/users') as m:
108 with rmap.submapper(path_prefix='/_admin', controller='admin/users') as m:
109 m.connect("users", "/users",
109 m.connect("users", "/users",
110 action="create", conditions=dict(method=["POST"]))
110 action="create", conditions=dict(method=["POST"]))
111 m.connect("users", "/users",
111 m.connect("users", "/users",
112 action="index", conditions=dict(method=["GET"]))
112 action="index", conditions=dict(method=["GET"]))
113 m.connect("formatted_users", "/users.{format}",
113 m.connect("formatted_users", "/users.{format}",
114 action="index", conditions=dict(method=["GET"]))
114 action="index", conditions=dict(method=["GET"]))
115 m.connect("new_user", "/users/new",
115 m.connect("new_user", "/users/new",
116 action="new", conditions=dict(method=["GET"]))
116 action="new", conditions=dict(method=["GET"]))
117 m.connect("formatted_new_user", "/users/new.{format}",
117 m.connect("formatted_new_user", "/users/new.{format}",
118 action="new", conditions=dict(method=["GET"]))
118 action="new", conditions=dict(method=["GET"]))
119 m.connect("update_user", "/users/{id}",
119 m.connect("update_user", "/users/{id}",
120 action="update", conditions=dict(method=["PUT"]))
120 action="update", conditions=dict(method=["PUT"]))
121 m.connect("delete_user", "/users/{id}",
121 m.connect("delete_user", "/users/{id}",
122 action="delete", conditions=dict(method=["DELETE"]))
122 action="delete", conditions=dict(method=["DELETE"]))
123 m.connect("edit_user", "/users/{id}/edit",
123 m.connect("edit_user", "/users/{id}/edit",
124 action="edit", conditions=dict(method=["GET"]))
124 action="edit", conditions=dict(method=["GET"]))
125 m.connect("formatted_edit_user",
125 m.connect("formatted_edit_user",
126 "/users/{id}.{format}/edit",
126 "/users/{id}.{format}/edit",
127 action="edit", conditions=dict(method=["GET"]))
127 action="edit", conditions=dict(method=["GET"]))
128 m.connect("user", "/users/{id}",
128 m.connect("user", "/users/{id}",
129 action="show", conditions=dict(method=["GET"]))
129 action="show", conditions=dict(method=["GET"]))
130 m.connect("formatted_user", "/users/{id}.{format}",
130 m.connect("formatted_user", "/users/{id}.{format}",
131 action="show", conditions=dict(method=["GET"]))
131 action="show", conditions=dict(method=["GET"]))
132
132
133 #EXTRAS USER ROUTES
133 #EXTRAS USER ROUTES
134 m.connect("user_perm", "/users_perm/{id}",
134 m.connect("user_perm", "/users_perm/{id}",
135 action="update_perm", conditions=dict(method=["PUT"]))
135 action="update_perm", conditions=dict(method=["PUT"]))
136
136
137 #ADMIN USERS REST ROUTES
137 #ADMIN USERS REST ROUTES
138 with rmap.submapper(path_prefix='/_admin',
138 with rmap.submapper(path_prefix='/_admin',
139 controller='admin/users_groups') as m:
139 controller='admin/users_groups') as m:
140 m.connect("users_groups", "/users_groups",
140 m.connect("users_groups", "/users_groups",
141 action="create", conditions=dict(method=["POST"]))
141 action="create", conditions=dict(method=["POST"]))
142 m.connect("users_groups", "/users_groups",
142 m.connect("users_groups", "/users_groups",
143 action="index", conditions=dict(method=["GET"]))
143 action="index", conditions=dict(method=["GET"]))
144 m.connect("formatted_users_groups", "/users_groups.{format}",
144 m.connect("formatted_users_groups", "/users_groups.{format}",
145 action="index", conditions=dict(method=["GET"]))
145 action="index", conditions=dict(method=["GET"]))
146 m.connect("new_users_group", "/users_groups/new",
146 m.connect("new_users_group", "/users_groups/new",
147 action="new", conditions=dict(method=["GET"]))
147 action="new", conditions=dict(method=["GET"]))
148 m.connect("formatted_new_users_group", "/users_groups/new.{format}",
148 m.connect("formatted_new_users_group", "/users_groups/new.{format}",
149 action="new", conditions=dict(method=["GET"]))
149 action="new", conditions=dict(method=["GET"]))
150 m.connect("update_users_group", "/users_groups/{id}",
150 m.connect("update_users_group", "/users_groups/{id}",
151 action="update", conditions=dict(method=["PUT"]))
151 action="update", conditions=dict(method=["PUT"]))
152 m.connect("delete_users_group", "/users_groups/{id}",
152 m.connect("delete_users_group", "/users_groups/{id}",
153 action="delete", conditions=dict(method=["DELETE"]))
153 action="delete", conditions=dict(method=["DELETE"]))
154 m.connect("edit_users_group", "/users_groups/{id}/edit",
154 m.connect("edit_users_group", "/users_groups/{id}/edit",
155 action="edit", conditions=dict(method=["GET"]))
155 action="edit", conditions=dict(method=["GET"]))
156 m.connect("formatted_edit_users_group",
156 m.connect("formatted_edit_users_group",
157 "/users_groups/{id}.{format}/edit",
157 "/users_groups/{id}.{format}/edit",
158 action="edit", conditions=dict(method=["GET"]))
158 action="edit", conditions=dict(method=["GET"]))
159 m.connect("users_group", "/users_groups/{id}",
159 m.connect("users_group", "/users_groups/{id}",
160 action="show", conditions=dict(method=["GET"]))
160 action="show", conditions=dict(method=["GET"]))
161 m.connect("formatted_users_group", "/users_groups/{id}.{format}",
161 m.connect("formatted_users_group", "/users_groups/{id}.{format}",
162 action="show", conditions=dict(method=["GET"]))
162 action="show", conditions=dict(method=["GET"]))
163
163
164 #EXTRAS USER ROUTES
164 #EXTRAS USER ROUTES
165 m.connect("users_group_perm", "/users_groups_perm/{id}",
165 m.connect("users_group_perm", "/users_groups_perm/{id}",
166 action="update_perm", conditions=dict(method=["PUT"]))
166 action="update_perm", conditions=dict(method=["PUT"]))
167
167
168 #ADMIN GROUP REST ROUTES
168 #ADMIN GROUP REST ROUTES
169 rmap.resource('group', 'groups',
169 rmap.resource('group', 'groups',
170 controller='admin/groups', path_prefix='/_admin')
170 controller='admin/groups', path_prefix='/_admin')
171
171
172 #ADMIN PERMISSIONS REST ROUTES
172 #ADMIN PERMISSIONS REST ROUTES
173 rmap.resource('permission', 'permissions',
173 rmap.resource('permission', 'permissions',
174 controller='admin/permissions', path_prefix='/_admin')
174 controller='admin/permissions', path_prefix='/_admin')
175
175
176 ##ADMIN LDAP SETTINGS
176 ##ADMIN LDAP SETTINGS
177 rmap.connect('ldap_settings', '/_admin/ldap',
177 rmap.connect('ldap_settings', '/_admin/ldap',
178 controller='admin/ldap_settings', action='ldap_settings',
178 controller='admin/ldap_settings', action='ldap_settings',
179 conditions=dict(method=["POST"]))
179 conditions=dict(method=["POST"]))
180
180
181 rmap.connect('ldap_home', '/_admin/ldap',
181 rmap.connect('ldap_home', '/_admin/ldap',
182 controller='admin/ldap_settings')
182 controller='admin/ldap_settings')
183
183
184 #ADMIN SETTINGS REST ROUTES
184 #ADMIN SETTINGS REST ROUTES
185 with rmap.submapper(path_prefix='/_admin',
185 with rmap.submapper(path_prefix='/_admin',
186 controller='admin/settings') as m:
186 controller='admin/settings') as m:
187 m.connect("admin_settings", "/settings",
187 m.connect("admin_settings", "/settings",
188 action="create", conditions=dict(method=["POST"]))
188 action="create", conditions=dict(method=["POST"]))
189 m.connect("admin_settings", "/settings",
189 m.connect("admin_settings", "/settings",
190 action="index", conditions=dict(method=["GET"]))
190 action="index", conditions=dict(method=["GET"]))
191 m.connect("formatted_admin_settings", "/settings.{format}",
191 m.connect("formatted_admin_settings", "/settings.{format}",
192 action="index", conditions=dict(method=["GET"]))
192 action="index", conditions=dict(method=["GET"]))
193 m.connect("admin_new_setting", "/settings/new",
193 m.connect("admin_new_setting", "/settings/new",
194 action="new", conditions=dict(method=["GET"]))
194 action="new", conditions=dict(method=["GET"]))
195 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
195 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
196 action="new", conditions=dict(method=["GET"]))
196 action="new", conditions=dict(method=["GET"]))
197 m.connect("/settings/{setting_id}",
197 m.connect("/settings/{setting_id}",
198 action="update", conditions=dict(method=["PUT"]))
198 action="update", conditions=dict(method=["PUT"]))
199 m.connect("/settings/{setting_id}",
199 m.connect("/settings/{setting_id}",
200 action="delete", conditions=dict(method=["DELETE"]))
200 action="delete", conditions=dict(method=["DELETE"]))
201 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
201 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
202 action="edit", conditions=dict(method=["GET"]))
202 action="edit", conditions=dict(method=["GET"]))
203 m.connect("formatted_admin_edit_setting",
203 m.connect("formatted_admin_edit_setting",
204 "/settings/{setting_id}.{format}/edit",
204 "/settings/{setting_id}.{format}/edit",
205 action="edit", conditions=dict(method=["GET"]))
205 action="edit", conditions=dict(method=["GET"]))
206 m.connect("admin_setting", "/settings/{setting_id}",
206 m.connect("admin_setting", "/settings/{setting_id}",
207 action="show", conditions=dict(method=["GET"]))
207 action="show", conditions=dict(method=["GET"]))
208 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
208 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
209 action="show", conditions=dict(method=["GET"]))
209 action="show", conditions=dict(method=["GET"]))
210 m.connect("admin_settings_my_account", "/my_account",
210 m.connect("admin_settings_my_account", "/my_account",
211 action="my_account", conditions=dict(method=["GET"]))
211 action="my_account", conditions=dict(method=["GET"]))
212 m.connect("admin_settings_my_account_update", "/my_account_update",
212 m.connect("admin_settings_my_account_update", "/my_account_update",
213 action="my_account_update", conditions=dict(method=["PUT"]))
213 action="my_account_update", conditions=dict(method=["PUT"]))
214 m.connect("admin_settings_create_repository", "/create_repository",
214 m.connect("admin_settings_create_repository", "/create_repository",
215 action="create_repository", conditions=dict(method=["GET"]))
215 action="create_repository", conditions=dict(method=["GET"]))
216
216
217 #ADMIN MAIN PAGES
217 #ADMIN MAIN PAGES
218 with rmap.submapper(path_prefix='/_admin', controller='admin/admin') as m:
218 with rmap.submapper(path_prefix='/_admin', controller='admin/admin') as m:
219 m.connect('admin_home', '', action='index')
219 m.connect('admin_home', '', action='index')
220 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
220 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
221 action='add_repo')
221 action='add_repo')
222
222
223 #USER JOURNAL
223 #USER JOURNAL
224 rmap.connect('journal', '/_admin/journal', controller='journal')
224 rmap.connect('journal', '/_admin/journal', controller='journal')
225
225
226 rmap.connect('public_journal', '/_admin/public_journal',
226 rmap.connect('public_journal', '/_admin/public_journal',
227 controller='journal', action="public_journal")
227 controller='journal', action="public_journal")
228
228
229 rmap.connect('public_journal_rss', '/_admin/public_journal_rss',
229 rmap.connect('public_journal_rss', '/_admin/public_journal_rss',
230 controller='journal', action="public_journal_rss")
230 controller='journal', action="public_journal_rss")
231
231
232 rmap.connect('public_journal_atom', '/_admin/public_journal_atom',
232 rmap.connect('public_journal_atom', '/_admin/public_journal_atom',
233 controller='journal', action="public_journal_atom")
233 controller='journal', action="public_journal_atom")
234
234
235 rmap.connect('toggle_following', '/_admin/toggle_following',
235 rmap.connect('toggle_following', '/_admin/toggle_following',
236 controller='journal', action='toggle_following',
236 controller='journal', action='toggle_following',
237 conditions=dict(method=["POST"]))
237 conditions=dict(method=["POST"]))
238
238
239 #SEARCH
239 #SEARCH
240 rmap.connect('search', '/_admin/search', controller='search',)
240 rmap.connect('search', '/_admin/search', controller='search',)
241 rmap.connect('search_repo', '/_admin/search/{search_repo:.*}',
241 rmap.connect('search_repo', '/_admin/search/{search_repo:.*}',
242 controller='search')
242 controller='search')
243
243
244 #LOGIN/LOGOUT/REGISTER/SIGN IN
244 #LOGIN/LOGOUT/REGISTER/SIGN IN
245 rmap.connect('login_home', '/_admin/login', controller='login')
245 rmap.connect('login_home', '/_admin/login', controller='login')
246 rmap.connect('logout_home', '/_admin/logout', controller='login',
246 rmap.connect('logout_home', '/_admin/logout', controller='login',
247 action='logout')
247 action='logout')
248
248
249 rmap.connect('register', '/_admin/register', controller='login',
249 rmap.connect('register', '/_admin/register', controller='login',
250 action='register')
250 action='register')
251
251
252 rmap.connect('reset_password', '/_admin/password_reset',
252 rmap.connect('reset_password', '/_admin/password_reset',
253 controller='login', action='password_reset')
253 controller='login', action='password_reset')
254
254
255 #FEEDS
255 #FEEDS
256 rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
256 rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
257 controller='feed', action='rss',
257 controller='feed', action='rss',
258 conditions=dict(function=check_repo))
258 conditions=dict(function=check_repo))
259
259
260 rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
260 rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
261 controller='feed', action='atom',
261 controller='feed', action='atom',
262 conditions=dict(function=check_repo))
262 conditions=dict(function=check_repo))
263
263
264 #==========================================================================
264 #==========================================================================
265 # REPOSITORY ROUTES
265 # REPOSITORY ROUTES
266 #==========================================================================
266 #==========================================================================
267 rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
267 rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
268 controller='changeset', revision='tip',
268 controller='changeset', revision='tip',
269 conditions=dict(function=check_repo))
269 conditions=dict(function=check_repo))
270
270
271 rmap.connect('raw_changeset_home',
271 rmap.connect('raw_changeset_home',
272 '/{repo_name:.*}/raw-changeset/{revision}',
272 '/{repo_name:.*}/raw-changeset/{revision}',
273 controller='changeset', action='raw_changeset',
273 controller='changeset', action='raw_changeset',
274 revision='tip', conditions=dict(function=check_repo))
274 revision='tip', conditions=dict(function=check_repo))
275
275
276 rmap.connect('summary_home', '/{repo_name:.*}',
276 rmap.connect('summary_home', '/{repo_name:.*}',
277 controller='summary', conditions=dict(function=check_repo))
277 controller='summary', conditions=dict(function=check_repo))
278
278
279 rmap.connect('summary_home', '/{repo_name:.*}/summary',
279 rmap.connect('summary_home', '/{repo_name:.*}/summary',
280 controller='summary', conditions=dict(function=check_repo))
280 controller='summary', conditions=dict(function=check_repo))
281
281
282 rmap.connect('shortlog_home', '/{repo_name:.*}/shortlog',
282 rmap.connect('shortlog_home', '/{repo_name:.*}/shortlog',
283 controller='shortlog', conditions=dict(function=check_repo))
283 controller='shortlog', conditions=dict(function=check_repo))
284
284
285 rmap.connect('branches_home', '/{repo_name:.*}/branches',
285 rmap.connect('branches_home', '/{repo_name:.*}/branches',
286 controller='branches', conditions=dict(function=check_repo))
286 controller='branches', conditions=dict(function=check_repo))
287
287
288 rmap.connect('tags_home', '/{repo_name:.*}/tags',
288 rmap.connect('tags_home', '/{repo_name:.*}/tags',
289 controller='tags', conditions=dict(function=check_repo))
289 controller='tags', conditions=dict(function=check_repo))
290
290
291 rmap.connect('changelog_home', '/{repo_name:.*}/changelog',
291 rmap.connect('changelog_home', '/{repo_name:.*}/changelog',
292 controller='changelog', conditions=dict(function=check_repo))
292 controller='changelog', conditions=dict(function=check_repo))
293
293
294 rmap.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
294 rmap.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
295 controller='files', revision='tip', f_path='',
295 controller='files', revision='tip', f_path='',
296 conditions=dict(function=check_repo))
296 conditions=dict(function=check_repo))
297
297
298 rmap.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
298 rmap.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
299 controller='files', action='diff', revision='tip', f_path='',
299 controller='files', action='diff', revision='tip', f_path='',
300 conditions=dict(function=check_repo))
300 conditions=dict(function=check_repo))
301
301
302 rmap.connect('files_rawfile_home',
302 rmap.connect('files_rawfile_home',
303 '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
303 '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
304 controller='files', action='rawfile', revision='tip',
304 controller='files', action='rawfile', revision='tip',
305 f_path='', conditions=dict(function=check_repo))
305 f_path='', conditions=dict(function=check_repo))
306
306
307 rmap.connect('files_raw_home',
307 rmap.connect('files_raw_home',
308 '/{repo_name:.*}/raw/{revision}/{f_path:.*}',
308 '/{repo_name:.*}/raw/{revision}/{f_path:.*}',
309 controller='files', action='raw', revision='tip', f_path='',
309 controller='files', action='raw', revision='tip', f_path='',
310 conditions=dict(function=check_repo))
310 conditions=dict(function=check_repo))
311
311
312 rmap.connect('files_annotate_home',
312 rmap.connect('files_annotate_home',
313 '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
313 '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
314 controller='files', action='annotate', revision='tip',
314 controller='files', action='annotate', revision='tip',
315 f_path='', conditions=dict(function=check_repo))
315 f_path='', conditions=dict(function=check_repo))
316
316
317 rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}',
317 rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}',
318 controller='files', action='archivefile',
318 controller='files', action='archivefile',
319 conditions=dict(function=check_repo))
319 conditions=dict(function=check_repo))
320
320
321 rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings',
321 rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings',
322 controller='settings', action="delete",
322 controller='settings', action="delete",
323 conditions=dict(method=["DELETE"], function=check_repo))
323 conditions=dict(method=["DELETE"], function=check_repo))
324
324
325 rmap.connect('repo_settings_update', '/{repo_name:.*}/settings',
325 rmap.connect('repo_settings_update', '/{repo_name:.*}/settings',
326 controller='settings', action="update",
326 controller='settings', action="update",
327 conditions=dict(method=["PUT"], function=check_repo))
327 conditions=dict(method=["PUT"], function=check_repo))
328
328
329 rmap.connect('repo_settings_home', '/{repo_name:.*}/settings',
329 rmap.connect('repo_settings_home', '/{repo_name:.*}/settings',
330 controller='settings', action='index',
330 controller='settings', action='index',
331 conditions=dict(function=check_repo))
331 conditions=dict(function=check_repo))
332
332
333 rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
333 rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
334 controller='settings', action='fork_create',
334 controller='settings', action='fork_create',
335 conditions=dict(function=check_repo, method=["POST"]))
335 conditions=dict(function=check_repo, method=["POST"]))
336
336
337 rmap.connect('repo_fork_home', '/{repo_name:.*}/fork',
337 rmap.connect('repo_fork_home', '/{repo_name:.*}/fork',
338 controller='settings', action='fork',
338 controller='settings', action='fork',
339 conditions=dict(function=check_repo))
339 conditions=dict(function=check_repo))
340
340
341 rmap.connect('repo_followers_home', '/{repo_name:.*}/followers',
341 rmap.connect('repo_followers_home', '/{repo_name:.*}/followers',
342 controller='followers', action='followers',
342 controller='followers', action='followers',
343 conditions=dict(function=check_repo))
343 conditions=dict(function=check_repo))
344
345 rmap.connect('repo_forks_home', '/{repo_name:.*}/forks',
346 controller='forks', action='forks',
347 conditions=dict(function=check_repo))
344 return rmap
348 return rmap
@@ -1,57 +1,57 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.followers
3 rhodecode.controllers.followers
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Followers controller for rhodecode
6 Followers controller for rhodecode
7
7
8 :created_on: Apr 23, 2011
8 :created_on: Apr 23, 2011
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # 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,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # 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
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 import logging
25 import logging
26
26
27 from pylons import tmpl_context as c, request
27 from pylons import tmpl_context as c, request
28
28
29 from rhodecode.lib.helpers import Page
29 from rhodecode.lib.helpers import Page
30 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
30 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
31 from rhodecode.lib.base import BaseRepoController, render
31 from rhodecode.lib.base import BaseRepoController, render
32 from rhodecode.model.db import Repository, User, UserFollowing
32 from rhodecode.model.db import Repository, User, UserFollowing
33
33
34 log = logging.getLogger(__name__)
34 log = logging.getLogger(__name__)
35
35
36
36
37 class FollowersController(BaseRepoController):
37 class FollowersController(BaseRepoController):
38
38
39 @LoginRequired()
39 @LoginRequired()
40 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
40 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
41 'repository.admin')
41 'repository.admin')
42 def __before__(self):
42 def __before__(self):
43 super(FollowersController, self).__before__()
43 super(FollowersController, self).__before__()
44
44
45 def followers(self, repo_name):
45 def followers(self, repo_name):
46 p = int(request.params.get('page', 1))
46 p = int(request.params.get('page', 1))
47 repo_id = getattr(Repository.by_repo_name(repo_name), 'repo_id')
47 repo_id = Repository.by_repo_name(repo_name).repo_id
48 d = UserFollowing.get_repo_followers(repo_id)\
48 d = UserFollowing.get_repo_followers(repo_id)\
49 .order_by(UserFollowing.follows_from)
49 .order_by(UserFollowing.follows_from)
50 c.followers_pager = Page(d, page=p, items_per_page=20)
50 c.followers_pager = Page(d, page=p, items_per_page=20)
51
51
52 c.followers_data = render('/followers/followers_data.html')
52 c.followers_data = render('/followers/followers_data.html')
53
53
54 if request.params.get('partial'):
54 if request.params.get('partial'):
55 return c.followers_data
55 return c.followers_data
56
56
57 return render('/followers/followers.html')
57 return render('/followers/followers.html')
@@ -1,531 +1,538 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.db
3 rhodecode.model.db
4 ~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~
5
5
6 Database Models for RhodeCode
6 Database Models for RhodeCode
7
7
8 :created_on: Apr 08, 2010
8 :created_on: Apr 08, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2009-2011 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # 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,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # 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
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import os
26 import os
27 import logging
27 import logging
28 import datetime
28 import datetime
29 from datetime import date
29 from datetime import date
30
30
31 from sqlalchemy import *
31 from sqlalchemy import *
32 from sqlalchemy.exc import DatabaseError
32 from sqlalchemy.exc import DatabaseError
33 from sqlalchemy.orm import relationship, backref
33 from sqlalchemy.orm import relationship, backref
34 from sqlalchemy.orm.interfaces import MapperExtension
34 from sqlalchemy.orm.interfaces import MapperExtension
35
35
36 from rhodecode.lib import str2bool
36 from rhodecode.lib import str2bool
37 from rhodecode.model.meta import Base, Session
37 from rhodecode.model.meta import Base, Session
38 from rhodecode.model.caching_query import FromCache
38 from rhodecode.model.caching_query import FromCache
39
39
40 log = logging.getLogger(__name__)
40 log = logging.getLogger(__name__)
41
41
42 #==============================================================================
42 #==============================================================================
43 # MAPPER EXTENSIONS
43 # MAPPER EXTENSIONS
44 #==============================================================================
44 #==============================================================================
45
45
46 class RepositoryMapper(MapperExtension):
46 class RepositoryMapper(MapperExtension):
47 def after_update(self, mapper, connection, instance):
47 def after_update(self, mapper, connection, instance):
48 pass
48 pass
49
49
50
50
51 class RhodeCodeSettings(Base):
51 class RhodeCodeSettings(Base):
52 __tablename__ = 'rhodecode_settings'
52 __tablename__ = 'rhodecode_settings'
53 __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
53 __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
54 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
54 app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
55 app_settings_name = Column("app_settings_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
55 app_settings_name = Column("app_settings_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
56 app_settings_value = Column("app_settings_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
56 app_settings_value = Column("app_settings_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
57
57
58 def __init__(self, k='', v=''):
58 def __init__(self, k='', v=''):
59 self.app_settings_name = k
59 self.app_settings_name = k
60 self.app_settings_value = v
60 self.app_settings_value = v
61
61
62 def __repr__(self):
62 def __repr__(self):
63 return "<%s('%s:%s')>" % (self.__class__.__name__,
63 return "<%s('%s:%s')>" % (self.__class__.__name__,
64 self.app_settings_name, self.app_settings_value)
64 self.app_settings_name, self.app_settings_value)
65
65
66
66
67 @classmethod
67 @classmethod
68 def get_by_name(cls, ldap_key):
68 def get_by_name(cls, ldap_key):
69 return Session.query(cls)\
69 return Session.query(cls)\
70 .filter(cls.app_settings_name == ldap_key).scalar()
70 .filter(cls.app_settings_name == ldap_key).scalar()
71
71
72 @classmethod
72 @classmethod
73 def get_app_settings(cls, cache=False):
73 def get_app_settings(cls, cache=False):
74
74
75 ret = Session.query(cls)
75 ret = Session.query(cls)
76
76
77 if cache:
77 if cache:
78 ret = ret.options(FromCache("sql_cache_short", "get_hg_settings"))
78 ret = ret.options(FromCache("sql_cache_short", "get_hg_settings"))
79
79
80 if not ret:
80 if not ret:
81 raise Exception('Could not get application settings !')
81 raise Exception('Could not get application settings !')
82 settings = {}
82 settings = {}
83 for each in ret:
83 for each in ret:
84 settings['rhodecode_' + each.app_settings_name] = \
84 settings['rhodecode_' + each.app_settings_name] = \
85 each.app_settings_value
85 each.app_settings_value
86
86
87 return settings
87 return settings
88
88
89 @classmethod
89 @classmethod
90 def get_ldap_settings(cls, cache=False):
90 def get_ldap_settings(cls, cache=False):
91 ret = Session.query(cls)\
91 ret = Session.query(cls)\
92 .filter(cls.app_settings_name.startswith('ldap_'))\
92 .filter(cls.app_settings_name.startswith('ldap_'))\
93 .all()
93 .all()
94 fd = {}
94 fd = {}
95 for row in ret:
95 for row in ret:
96 fd.update({row.app_settings_name:row.app_settings_value})
96 fd.update({row.app_settings_name:row.app_settings_value})
97 return fd
97 return fd
98
98
99
99
100 class RhodeCodeUi(Base):
100 class RhodeCodeUi(Base):
101 __tablename__ = 'rhodecode_ui'
101 __tablename__ = 'rhodecode_ui'
102 __table_args__ = {'useexisting':True}
102 __table_args__ = {'useexisting':True}
103 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
103 ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
104 ui_section = Column("ui_section", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
104 ui_section = Column("ui_section", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
105 ui_key = Column("ui_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
105 ui_key = Column("ui_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
106 ui_value = Column("ui_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
106 ui_value = Column("ui_value", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
107 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
107 ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True)
108
108
109
109
110 class User(Base):
110 class User(Base):
111 __tablename__ = 'users'
111 __tablename__ = 'users'
112 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
112 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
113 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
113 user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
114 username = Column("username", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
114 username = Column("username", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
115 password = Column("password", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
115 password = Column("password", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
116 active = Column("active", Boolean(), nullable=True, unique=None, default=None)
116 active = Column("active", Boolean(), nullable=True, unique=None, default=None)
117 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
117 admin = Column("admin", Boolean(), nullable=True, unique=None, default=False)
118 name = Column("name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
118 name = Column("name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
119 lastname = Column("lastname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
119 lastname = Column("lastname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
120 email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
120 email = Column("email", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
121 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
121 last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None)
122 ldap_dn = Column("ldap_dn", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
122 ldap_dn = Column("ldap_dn", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
123 api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
123 api_key = Column("api_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
124
124
125 user_log = relationship('UserLog', cascade='all')
125 user_log = relationship('UserLog', cascade='all')
126 user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
126 user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all')
127
127
128 repositories = relationship('Repository')
128 repositories = relationship('Repository')
129 user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
129 user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all')
130
130
131 group_member = relationship('UsersGroupMember', cascade='all')
131 group_member = relationship('UsersGroupMember', cascade='all')
132
132
133 @property
133 @property
134 def full_contact(self):
134 def full_contact(self):
135 return '%s %s <%s>' % (self.name, self.lastname, self.email)
135 return '%s %s <%s>' % (self.name, self.lastname, self.email)
136
136
137 @property
137 @property
138 def short_contact(self):
138 def short_contact(self):
139 return '%s %s' % (self.name, self.lastname)
139 return '%s %s' % (self.name, self.lastname)
140
140
141
141
142 @property
142 @property
143 def is_admin(self):
143 def is_admin(self):
144 return self.admin
144 return self.admin
145
145
146 def __repr__(self):
146 def __repr__(self):
147 return "<%s('id:%s:%s')>" % (self.__class__.__name__,
147 return "<%s('id:%s:%s')>" % (self.__class__.__name__,
148 self.user_id, self.username)
148 self.user_id, self.username)
149
149
150 @classmethod
150 @classmethod
151 def by_username(cls, username):
151 def by_username(cls, username):
152 return Session.query(cls).filter(cls.username == username).one()
152 return Session.query(cls).filter(cls.username == username).one()
153
153
154
154
155 def update_lastlogin(self):
155 def update_lastlogin(self):
156 """Update user lastlogin"""
156 """Update user lastlogin"""
157
157
158 try:
158 try:
159 session = Session.object_session(self)
159 session = Session.object_session(self)
160 self.last_login = datetime.datetime.now()
160 self.last_login = datetime.datetime.now()
161 session.add(self)
161 session.add(self)
162 session.commit()
162 session.commit()
163 log.debug('updated user %s lastlogin', self.username)
163 log.debug('updated user %s lastlogin', self.username)
164 except (DatabaseError,):
164 except (DatabaseError,):
165 session.rollback()
165 session.rollback()
166
166
167
167
168 class UserLog(Base):
168 class UserLog(Base):
169 __tablename__ = 'user_logs'
169 __tablename__ = 'user_logs'
170 __table_args__ = {'useexisting':True}
170 __table_args__ = {'useexisting':True}
171 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
171 user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
172 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
172 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
173 repository_id = Column("repository_id", Integer(length=None, convert_unicode=False, assert_unicode=None), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
173 repository_id = Column("repository_id", Integer(length=None, convert_unicode=False, assert_unicode=None), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
174 repository_name = Column("repository_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
174 repository_name = Column("repository_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
175 user_ip = Column("user_ip", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
175 user_ip = Column("user_ip", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
176 action = Column("action", UnicodeText(length=1200000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
176 action = Column("action", UnicodeText(length=1200000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
177 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
177 action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None)
178
178
179 @property
179 @property
180 def action_as_day(self):
180 def action_as_day(self):
181 return date(*self.action_date.timetuple()[:3])
181 return date(*self.action_date.timetuple()[:3])
182
182
183 user = relationship('User')
183 user = relationship('User')
184 repository = relationship('Repository')
184 repository = relationship('Repository')
185
185
186
186
187 class UsersGroup(Base):
187 class UsersGroup(Base):
188 __tablename__ = 'users_groups'
188 __tablename__ = 'users_groups'
189 __table_args__ = {'useexisting':True}
189 __table_args__ = {'useexisting':True}
190
190
191 users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
191 users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
192 users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
192 users_group_name = Column("users_group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
193 users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
193 users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None)
194
194
195 members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
195 members = relationship('UsersGroupMember', cascade="all, delete, delete-orphan", lazy="joined")
196
196
197
197
198 @classmethod
198 @classmethod
199 def get_by_group_name(cls, group_name, cache=False, case_insensitive=False):
199 def get_by_group_name(cls, group_name, cache=False, case_insensitive=False):
200 if case_insensitive:
200 if case_insensitive:
201 gr = Session.query(cls)\
201 gr = Session.query(cls)\
202 .filter(cls.users_group_name.ilike(group_name))
202 .filter(cls.users_group_name.ilike(group_name))
203 else:
203 else:
204 gr = Session.query(UsersGroup)\
204 gr = Session.query(UsersGroup)\
205 .filter(UsersGroup.users_group_name == group_name)
205 .filter(UsersGroup.users_group_name == group_name)
206 if cache:
206 if cache:
207 gr = gr.options(FromCache("sql_cache_short",
207 gr = gr.options(FromCache("sql_cache_short",
208 "get_user_%s" % group_name))
208 "get_user_%s" % group_name))
209 return gr.scalar()
209 return gr.scalar()
210
210
211 class UsersGroupMember(Base):
211 class UsersGroupMember(Base):
212 __tablename__ = 'users_groups_members'
212 __tablename__ = 'users_groups_members'
213 __table_args__ = {'useexisting':True}
213 __table_args__ = {'useexisting':True}
214
214
215 users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
215 users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
216 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
216 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
217 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
217 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
218
218
219 user = relationship('User', lazy='joined')
219 user = relationship('User', lazy='joined')
220 users_group = relationship('UsersGroup')
220 users_group = relationship('UsersGroup')
221
221
222 def __init__(self, gr_id='', u_id=''):
222 def __init__(self, gr_id='', u_id=''):
223 self.users_group_id = gr_id
223 self.users_group_id = gr_id
224 self.user_id = u_id
224 self.user_id = u_id
225
225
226 class Repository(Base):
226 class Repository(Base):
227 __tablename__ = 'repositories'
227 __tablename__ = 'repositories'
228 __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
228 __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
229 __mapper_args__ = {'extension':RepositoryMapper()}
229 __mapper_args__ = {'extension':RepositoryMapper()}
230
230
231 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
231 repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
232 repo_name = Column("repo_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
232 repo_name = Column("repo_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
233 clone_uri = Column("clone_uri", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
233 clone_uri = Column("clone_uri", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=False, default=None)
234 repo_type = Column("repo_type", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default='hg')
234 repo_type = Column("repo_type", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=False, default='hg')
235 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
235 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None)
236 private = Column("private", Boolean(), nullable=True, unique=None, default=None)
236 private = Column("private", Boolean(), nullable=True, unique=None, default=None)
237 enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
237 enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True)
238 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
238 enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True)
239 description = Column("description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
239 description = Column("description", String(length=10000, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
240 created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
241
240 fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
242 fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None)
241 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
243 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None)
242
244
243
245
244 user = relationship('User')
246 user = relationship('User')
245 fork = relationship('Repository', remote_side=repo_id)
247 fork = relationship('Repository', remote_side=repo_id)
246 group = relationship('Group')
248 group = relationship('Group')
247 repo_to_perm = relationship('RepoToPerm', cascade='all', order_by='RepoToPerm.repo_to_perm_id')
249 repo_to_perm = relationship('RepoToPerm', cascade='all', order_by='RepoToPerm.repo_to_perm_id')
248 users_group_to_perm = relationship('UsersGroupRepoToPerm', cascade='all')
250 users_group_to_perm = relationship('UsersGroupRepoToPerm', cascade='all')
249 stats = relationship('Statistics', cascade='all', uselist=False)
251 stats = relationship('Statistics', cascade='all', uselist=False)
250
252
251 followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all')
253 followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all')
252
254
253 logs = relationship('UserLog', cascade='all')
255 logs = relationship('UserLog', cascade='all')
254
256
255 def __repr__(self):
257 def __repr__(self):
256 return "<%s('%s:%s')>" % (self.__class__.__name__,
258 return "<%s('%s:%s')>" % (self.__class__.__name__,
257 self.repo_id, self.repo_name)
259 self.repo_id, self.repo_name)
258
260
259 @classmethod
261 @classmethod
260 def by_repo_name(cls, repo_name):
262 def by_repo_name(cls, repo_name):
261 return Session.query(cls).filter(cls.repo_name == repo_name).one()
263 return Session.query(cls).filter(cls.repo_name == repo_name).one()
262
264
265
266 @classmethod
267 def get_repo_forks(cls, repo_id):
268 return Session.query(cls).filter(Repository.fork_id == repo_id)
269
263 @property
270 @property
264 def just_name(self):
271 def just_name(self):
265 return self.repo_name.split(os.sep)[-1]
272 return self.repo_name.split(os.sep)[-1]
266
273
267 @property
274 @property
268 def groups_with_parents(self):
275 def groups_with_parents(self):
269 groups = []
276 groups = []
270 if self.group is None:
277 if self.group is None:
271 return groups
278 return groups
272
279
273 cur_gr = self.group
280 cur_gr = self.group
274 groups.insert(0, cur_gr)
281 groups.insert(0, cur_gr)
275 while 1:
282 while 1:
276 gr = getattr(cur_gr, 'parent_group', None)
283 gr = getattr(cur_gr, 'parent_group', None)
277 cur_gr = cur_gr.parent_group
284 cur_gr = cur_gr.parent_group
278 if gr is None:
285 if gr is None:
279 break
286 break
280 groups.insert(0, gr)
287 groups.insert(0, gr)
281
288
282 return groups
289 return groups
283
290
284 @property
291 @property
285 def groups_and_repo(self):
292 def groups_and_repo(self):
286 return self.groups_with_parents, self.just_name
293 return self.groups_with_parents, self.just_name
287
294
288
295
289 class Group(Base):
296 class Group(Base):
290 __tablename__ = 'groups'
297 __tablename__ = 'groups'
291 __table_args__ = (UniqueConstraint('group_name'), {'useexisting':True},)
298 __table_args__ = (UniqueConstraint('group_name'), {'useexisting':True},)
292
299
293 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
300 group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
294 group_name = Column("group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
301 group_name = Column("group_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
295 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
302 group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None)
296
303
297 parent_group = relationship('Group', remote_side=group_id)
304 parent_group = relationship('Group', remote_side=group_id)
298
305
299
306
300 def __init__(self, group_name='', parent_group=None):
307 def __init__(self, group_name='', parent_group=None):
301 self.group_name = group_name
308 self.group_name = group_name
302 self.parent_group = parent_group
309 self.parent_group = parent_group
303
310
304 def __repr__(self):
311 def __repr__(self):
305 return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id,
312 return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id,
306 self.group_name)
313 self.group_name)
307
314
308 @property
315 @property
309 def parents(self):
316 def parents(self):
310 groups = []
317 groups = []
311 if self.parent_group is None:
318 if self.parent_group is None:
312 return groups
319 return groups
313 cur_gr = self.parent_group
320 cur_gr = self.parent_group
314 groups.insert(0, cur_gr)
321 groups.insert(0, cur_gr)
315 while 1:
322 while 1:
316 gr = getattr(cur_gr, 'parent_group', None)
323 gr = getattr(cur_gr, 'parent_group', None)
317 cur_gr = cur_gr.parent_group
324 cur_gr = cur_gr.parent_group
318 if gr is None:
325 if gr is None:
319 break
326 break
320 groups.insert(0, gr)
327 groups.insert(0, gr)
321 return groups
328 return groups
322
329
323 @property
330 @property
324 def repositories(self):
331 def repositories(self):
325 return Session.query(Repository).filter(Repository.group == self).all()
332 return Session.query(Repository).filter(Repository.group == self).all()
326
333
327 class Permission(Base):
334 class Permission(Base):
328 __tablename__ = 'permissions'
335 __tablename__ = 'permissions'
329 __table_args__ = {'useexisting':True}
336 __table_args__ = {'useexisting':True}
330 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
337 permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
331 permission_name = Column("permission_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
338 permission_name = Column("permission_name", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
332 permission_longname = Column("permission_longname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
339 permission_longname = Column("permission_longname", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
333
340
334 def __repr__(self):
341 def __repr__(self):
335 return "<%s('%s:%s')>" % (self.__class__.__name__,
342 return "<%s('%s:%s')>" % (self.__class__.__name__,
336 self.permission_id, self.permission_name)
343 self.permission_id, self.permission_name)
337
344
338 @classmethod
345 @classmethod
339 def get_by_key(cls, key):
346 def get_by_key(cls, key):
340 return Session.query(cls).filter(cls.permission_name == key).scalar()
347 return Session.query(cls).filter(cls.permission_name == key).scalar()
341
348
342 class RepoToPerm(Base):
349 class RepoToPerm(Base):
343 __tablename__ = 'repo_to_perm'
350 __tablename__ = 'repo_to_perm'
344 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
351 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
345 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
352 repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
346 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
353 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
347 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
354 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
348 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
355 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
349
356
350 user = relationship('User')
357 user = relationship('User')
351 permission = relationship('Permission')
358 permission = relationship('Permission')
352 repository = relationship('Repository')
359 repository = relationship('Repository')
353
360
354 class UserToPerm(Base):
361 class UserToPerm(Base):
355 __tablename__ = 'user_to_perm'
362 __tablename__ = 'user_to_perm'
356 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
363 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
357 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
364 user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
358 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
365 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
359 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
366 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
360
367
361 user = relationship('User')
368 user = relationship('User')
362 permission = relationship('Permission')
369 permission = relationship('Permission')
363
370
364 @classmethod
371 @classmethod
365 def has_perm(cls, user_id, perm):
372 def has_perm(cls, user_id, perm):
366 if not isinstance(perm, Permission):
373 if not isinstance(perm, Permission):
367 raise Exception('perm needs to be an instance of Permission class')
374 raise Exception('perm needs to be an instance of Permission class')
368
375
369 return Session.query(cls).filter(cls.user_id == user_id)\
376 return Session.query(cls).filter(cls.user_id == user_id)\
370 .filter(cls.permission == perm).scalar() is not None
377 .filter(cls.permission == perm).scalar() is not None
371
378
372 @classmethod
379 @classmethod
373 def grant_perm(cls, user_id, perm):
380 def grant_perm(cls, user_id, perm):
374 if not isinstance(perm, Permission):
381 if not isinstance(perm, Permission):
375 raise Exception('perm needs to be an instance of Permission class')
382 raise Exception('perm needs to be an instance of Permission class')
376
383
377 new = cls()
384 new = cls()
378 new.user_id = user_id
385 new.user_id = user_id
379 new.permission = perm
386 new.permission = perm
380 try:
387 try:
381 Session.add(new)
388 Session.add(new)
382 Session.commit()
389 Session.commit()
383 except:
390 except:
384 Session.rollback()
391 Session.rollback()
385
392
386
393
387 @classmethod
394 @classmethod
388 def revoke_perm(cls, user_id, perm):
395 def revoke_perm(cls, user_id, perm):
389 if not isinstance(perm, Permission):
396 if not isinstance(perm, Permission):
390 raise Exception('perm needs to be an instance of Permission class')
397 raise Exception('perm needs to be an instance of Permission class')
391
398
392 try:
399 try:
393 Session.query(cls).filter(cls.user_id == user_id)\
400 Session.query(cls).filter(cls.user_id == user_id)\
394 .filter(cls.permission == perm).delete()
401 .filter(cls.permission == perm).delete()
395 Session.commit()
402 Session.commit()
396 except:
403 except:
397 Session.rollback()
404 Session.rollback()
398
405
399 class UsersGroupRepoToPerm(Base):
406 class UsersGroupRepoToPerm(Base):
400 __tablename__ = 'users_group_repo_to_perm'
407 __tablename__ = 'users_group_repo_to_perm'
401 __table_args__ = (UniqueConstraint('users_group_id', 'permission_id'), {'useexisting':True})
408 __table_args__ = (UniqueConstraint('users_group_id', 'permission_id'), {'useexisting':True})
402 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
409 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
403 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
410 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
404 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
411 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
405 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
412 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None)
406
413
407 users_group = relationship('UsersGroup')
414 users_group = relationship('UsersGroup')
408 permission = relationship('Permission')
415 permission = relationship('Permission')
409 repository = relationship('Repository')
416 repository = relationship('Repository')
410
417
411
418
412 class UsersGroupToPerm(Base):
419 class UsersGroupToPerm(Base):
413 __tablename__ = 'users_group_to_perm'
420 __tablename__ = 'users_group_to_perm'
414 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
421 users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
415 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
422 users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None)
416 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
423 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
417
424
418 users_group = relationship('UsersGroup')
425 users_group = relationship('UsersGroup')
419 permission = relationship('Permission')
426 permission = relationship('Permission')
420
427
421
428
422 @classmethod
429 @classmethod
423 def has_perm(cls, users_group_id, perm):
430 def has_perm(cls, users_group_id, perm):
424 if not isinstance(perm, Permission):
431 if not isinstance(perm, Permission):
425 raise Exception('perm needs to be an instance of Permission class')
432 raise Exception('perm needs to be an instance of Permission class')
426
433
427 return Session.query(cls).filter(cls.users_group_id ==
434 return Session.query(cls).filter(cls.users_group_id ==
428 users_group_id)\
435 users_group_id)\
429 .filter(cls.permission == perm)\
436 .filter(cls.permission == perm)\
430 .scalar() is not None
437 .scalar() is not None
431
438
432 @classmethod
439 @classmethod
433 def grant_perm(cls, users_group_id, perm):
440 def grant_perm(cls, users_group_id, perm):
434 if not isinstance(perm, Permission):
441 if not isinstance(perm, Permission):
435 raise Exception('perm needs to be an instance of Permission class')
442 raise Exception('perm needs to be an instance of Permission class')
436
443
437 new = cls()
444 new = cls()
438 new.users_group_id = users_group_id
445 new.users_group_id = users_group_id
439 new.permission = perm
446 new.permission = perm
440 try:
447 try:
441 Session.add(new)
448 Session.add(new)
442 Session.commit()
449 Session.commit()
443 except:
450 except:
444 Session.rollback()
451 Session.rollback()
445
452
446
453
447 @classmethod
454 @classmethod
448 def revoke_perm(cls, users_group_id, perm):
455 def revoke_perm(cls, users_group_id, perm):
449 if not isinstance(perm, Permission):
456 if not isinstance(perm, Permission):
450 raise Exception('perm needs to be an instance of Permission class')
457 raise Exception('perm needs to be an instance of Permission class')
451
458
452 try:
459 try:
453 Session.query(cls).filter(cls.users_group_id == users_group_id)\
460 Session.query(cls).filter(cls.users_group_id == users_group_id)\
454 .filter(cls.permission == perm).delete()
461 .filter(cls.permission == perm).delete()
455 Session.commit()
462 Session.commit()
456 except:
463 except:
457 Session.rollback()
464 Session.rollback()
458
465
459
466
460 class GroupToPerm(Base):
467 class GroupToPerm(Base):
461 __tablename__ = 'group_to_perm'
468 __tablename__ = 'group_to_perm'
462 __table_args__ = (UniqueConstraint('group_id', 'permission_id'), {'useexisting':True})
469 __table_args__ = (UniqueConstraint('group_id', 'permission_id'), {'useexisting':True})
463
470
464 group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
471 group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
465 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
472 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
466 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
473 permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None)
467 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
474 group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None)
468
475
469 user = relationship('User')
476 user = relationship('User')
470 permission = relationship('Permission')
477 permission = relationship('Permission')
471 group = relationship('Group')
478 group = relationship('Group')
472
479
473 class Statistics(Base):
480 class Statistics(Base):
474 __tablename__ = 'statistics'
481 __tablename__ = 'statistics'
475 __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
482 __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
476 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
483 stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
477 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
484 repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None)
478 stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
485 stat_on_revision = Column("stat_on_revision", Integer(), nullable=False)
479 commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
486 commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data
480 commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
487 commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data
481 languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
488 languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data
482
489
483 repository = relationship('Repository', single_parent=True)
490 repository = relationship('Repository', single_parent=True)
484
491
485 class UserFollowing(Base):
492 class UserFollowing(Base):
486 __tablename__ = 'user_followings'
493 __tablename__ = 'user_followings'
487 __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
494 __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'),
488 UniqueConstraint('user_id', 'follows_user_id')
495 UniqueConstraint('user_id', 'follows_user_id')
489 , {'useexisting':True})
496 , {'useexisting':True})
490
497
491 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
498 user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
492 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
499 user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
493 follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
500 follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None)
494 follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
501 follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None)
495 follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
502 follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now)
496
503
497 user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
504 user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id')
498
505
499 follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
506 follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id')
500 follows_repository = relationship('Repository', order_by='Repository.repo_name')
507 follows_repository = relationship('Repository', order_by='Repository.repo_name')
501
508
502
509
503
510
504 @classmethod
511 @classmethod
505 def get_repo_followers(cls, repo_id):
512 def get_repo_followers(cls, repo_id):
506 return Session.query(cls).filter(cls.follows_repo_id == repo_id)
513 return Session.query(cls).filter(cls.follows_repo_id == repo_id)
507
514
508 class CacheInvalidation(Base):
515 class CacheInvalidation(Base):
509 __tablename__ = 'cache_invalidation'
516 __tablename__ = 'cache_invalidation'
510 __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True})
517 __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True})
511 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
518 cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True)
512 cache_key = Column("cache_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
519 cache_key = Column("cache_key", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
513 cache_args = Column("cache_args", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
520 cache_args = Column("cache_args", String(length=255, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
514 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
521 cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False)
515
522
516
523
517 def __init__(self, cache_key, cache_args=''):
524 def __init__(self, cache_key, cache_args=''):
518 self.cache_key = cache_key
525 self.cache_key = cache_key
519 self.cache_args = cache_args
526 self.cache_args = cache_args
520 self.cache_active = False
527 self.cache_active = False
521
528
522 def __repr__(self):
529 def __repr__(self):
523 return "<%s('%s:%s')>" % (self.__class__.__name__,
530 return "<%s('%s:%s')>" % (self.__class__.__name__,
524 self.cache_id, self.cache_key)
531 self.cache_id, self.cache_key)
525
532
526 class DbMigrateVersion(Base):
533 class DbMigrateVersion(Base):
527 __tablename__ = 'db_migrate_version'
534 __tablename__ = 'db_migrate_version'
528 __table_args__ = {'useexisting':True}
535 __table_args__ = {'useexisting':True}
529 repository_id = Column('repository_id', String(250), primary_key=True)
536 repository_id = Column('repository_id', String(250), primary_key=True)
530 repository_path = Column('repository_path', Text)
537 repository_path = Column('repository_path', Text)
531 version = Column('version', Integer)
538 version = Column('version', Integer)
@@ -1,355 +1,355 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="root.html"/>
2 <%inherit file="root.html"/>
3
3
4 <!-- HEADER -->
4 <!-- HEADER -->
5 <div id="header">
5 <div id="header">
6 <!-- user -->
6 <!-- user -->
7 <ul id="logged-user">
7 <ul id="logged-user">
8 <li class="first">
8 <li class="first">
9 <div class="gravatar">
9 <div class="gravatar">
10 <img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,20)}" />
10 <img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,20)}" />
11 </div>
11 </div>
12 <div class="account">
12 <div class="account">
13 %if c.rhodecode_user.username == 'default':
13 %if c.rhodecode_user.username == 'default':
14 <a href="${h.url('public_journal')}">${_('Public journal')}</a>
14 <a href="${h.url('public_journal')}">${_('Public journal')}</a>
15 %else:
15 %else:
16 ${h.link_to(c.rhodecode_user.username,h.url('admin_settings_my_account'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))}
16 ${h.link_to(c.rhodecode_user.username,h.url('admin_settings_my_account'),title='%s %s'%(c.rhodecode_user.name,c.rhodecode_user.lastname))}
17 %endif
17 %endif
18 </div>
18 </div>
19 </li>
19 </li>
20 <li>
20 <li>
21 <a href="${h.url('home')}">${_('Home')}</a>
21 <a href="${h.url('home')}">${_('Home')}</a>
22 </li>
22 </li>
23 %if c.rhodecode_user.username != 'default':
23 %if c.rhodecode_user.username != 'default':
24 <li>
24 <li>
25 <a href="${h.url('journal')}">${_('Journal')}</a>
25 <a href="${h.url('journal')}">${_('Journal')}</a>
26 ##(${c.unread_journal}
26 ##(${c.unread_journal}
27 </li>
27 </li>
28 %endif
28 %endif
29 %if c.rhodecode_user.username == 'default':
29 %if c.rhodecode_user.username == 'default':
30 <li class="last highlight">${h.link_to(u'Login',h.url('login_home'))}</li>
30 <li class="last highlight">${h.link_to(u'Login',h.url('login_home'))}</li>
31 %else:
31 %else:
32 <li class="last highlight">${h.link_to(u'Log Out',h.url('logout_home'))}</li>
32 <li class="last highlight">${h.link_to(u'Log Out',h.url('logout_home'))}</li>
33 %endif
33 %endif
34 </ul>
34 </ul>
35 <!-- end user -->
35 <!-- end user -->
36 <div id="header-inner" class="title top-left-rounded-corner top-right-rounded-corner">
36 <div id="header-inner" class="title top-left-rounded-corner top-right-rounded-corner">
37 <div id="logo">
37 <div id="logo">
38 <h1><a href="${h.url('home')}">${c.rhodecode_name}</a></h1>
38 <h1><a href="${h.url('home')}">${c.rhodecode_name}</a></h1>
39 </div>
39 </div>
40 <!-- MENU -->
40 <!-- MENU -->
41 ${self.page_nav()}
41 ${self.page_nav()}
42 <!-- END MENU -->
42 <!-- END MENU -->
43 ${self.body()}
43 ${self.body()}
44 </div>
44 </div>
45 </div>
45 </div>
46 <!-- END HEADER -->
46 <!-- END HEADER -->
47
47
48 <!-- CONTENT -->
48 <!-- CONTENT -->
49 <div id="content">
49 <div id="content">
50 <div class="flash_msg">
50 <div class="flash_msg">
51 <% messages = h.flash.pop_messages() %>
51 <% messages = h.flash.pop_messages() %>
52 % if messages:
52 % if messages:
53 <ul id="flash-messages">
53 <ul id="flash-messages">
54 % for message in messages:
54 % for message in messages:
55 <li class="${message.category}_msg">${message}</li>
55 <li class="${message.category}_msg">${message}</li>
56 % endfor
56 % endfor
57 </ul>
57 </ul>
58 % endif
58 % endif
59 </div>
59 </div>
60 <div id="main">
60 <div id="main">
61 ${next.main()}
61 ${next.main()}
62 </div>
62 </div>
63 </div>
63 </div>
64 <!-- END CONTENT -->
64 <!-- END CONTENT -->
65
65
66 <!-- FOOTER -->
66 <!-- FOOTER -->
67 <div id="footer">
67 <div id="footer">
68 <div id="footer-inner" class="title bottom-left-rounded-corner bottom-right-rounded-corner">
68 <div id="footer-inner" class="title bottom-left-rounded-corner bottom-right-rounded-corner">
69 <div>
69 <div>
70 <p class="footer-link">
70 <p class="footer-link">
71 <a href="${h.url('bugtracker')}">${_('Submit a bug')}</a>
71 <a href="${h.url('bugtracker')}">${_('Submit a bug')}</a>
72 </p>
72 </p>
73 <p class="footer-link-right">
73 <p class="footer-link-right">
74 <a href="${h.url('rhodecode_official')}">RhodeCode</a>
74 <a href="${h.url('rhodecode_official')}">RhodeCode</a>
75 ${c.rhodecode_version} &copy; 2010-${h.datetime.today().year} by Marcin Kuzminski
75 ${c.rhodecode_version} &copy; 2010-${h.datetime.today().year} by Marcin Kuzminski
76 </p>
76 </p>
77 </div>
77 </div>
78 </div>
78 </div>
79 <script type="text/javascript">
79 <script type="text/javascript">
80 function tooltip_activate(){
80 function tooltip_activate(){
81 ${h.tooltip.activate()}
81 ${h.tooltip.activate()}
82 }
82 }
83 tooltip_activate();
83 tooltip_activate();
84 </script>
84 </script>
85 </div>
85 </div>
86 <!-- END FOOTER -->
86 <!-- END FOOTER -->
87
87
88 ### MAKO DEFS ###
88 ### MAKO DEFS ###
89 <%def name="page_nav()">
89 <%def name="page_nav()">
90 ${self.menu()}
90 ${self.menu()}
91 </%def>
91 </%def>
92
92
93 <%def name="breadcrumbs()">
93 <%def name="breadcrumbs()">
94 <div class="breadcrumbs">
94 <div class="breadcrumbs">
95 ${self.breadcrumbs_links()}
95 ${self.breadcrumbs_links()}
96 </div>
96 </div>
97 </%def>
97 </%def>
98
98
99
99
100 <%def name="menu(current=None)">
100 <%def name="menu(current=None)">
101 <%
101 <%
102 def is_current(selected):
102 def is_current(selected):
103 if selected == current:
103 if selected == current:
104 return h.literal('class="current"')
104 return h.literal('class="current"')
105 %>
105 %>
106 %if current not in ['home','admin']:
106 %if current not in ['home','admin']:
107 ##REGULAR MENU
107 ##REGULAR MENU
108 <ul id="quick">
108 <ul id="quick">
109 <!-- repo switcher -->
109 <!-- repo switcher -->
110 <li>
110 <li>
111 <a id="repo_switcher" title="${_('Switch repository')}" href="#">
111 <a id="repo_switcher" title="${_('Switch repository')}" href="#">
112 <span class="icon">
112 <span class="icon">
113 <img src="${h.url("/images/icons/database.png")}" alt="${_('Products')}" />
113 <img src="${h.url("/images/icons/database.png")}" alt="${_('Products')}" />
114 </span>
114 </span>
115 <span>&darr;</span>
115 <span>&darr;</span>
116 </a>
116 </a>
117 <ul id="repo_switcher_list" class="repo_switcher">
117 <ul id="repo_switcher_list" class="repo_switcher">
118 <li>
118 <li>
119 <a href="#">${_('loading...')}</a>
119 <a href="#">${_('loading...')}</a>
120 </li>
120 </li>
121 </ul>
121 </ul>
122 <script type="text/javascript">
122 <script type="text/javascript">
123 YUE.on('repo_switcher','mouseover',function(){
123 YUE.on('repo_switcher','mouseover',function(){
124 function qfilter(){
124 function qfilter(){
125 var S = YAHOO.util.Selector;
125 var S = YAHOO.util.Selector;
126
126
127 var q_filter = YUD.get('q_filter_rs');
127 var q_filter = YUD.get('q_filter_rs');
128 var F = YAHOO.namespace('q_filter_rs');
128 var F = YAHOO.namespace('q_filter_rs');
129
129
130 YUE.on(q_filter,'click',function(){
130 YUE.on(q_filter,'click',function(){
131 q_filter.value = '';
131 q_filter.value = '';
132 });
132 });
133
133
134 F.filterTimeout = null;
134 F.filterTimeout = null;
135
135
136 F.updateFilter = function() {
136 F.updateFilter = function() {
137 // Reset timeout
137 // Reset timeout
138 F.filterTimeout = null;
138 F.filterTimeout = null;
139
139
140 var obsolete = [];
140 var obsolete = [];
141 var nodes = S.query('ul#repo_switcher_list li a.repo_name');
141 var nodes = S.query('ul#repo_switcher_list li a.repo_name');
142 var req = YUD.get('q_filter_rs').value;
142 var req = YUD.get('q_filter_rs').value;
143 for (n in nodes){
143 for (n in nodes){
144 YUD.setStyle(nodes[n].parentNode,'display','')
144 YUD.setStyle(nodes[n].parentNode,'display','')
145 }
145 }
146 if (req){
146 if (req){
147 for (n in nodes){
147 for (n in nodes){
148 console.log(n);
148 console.log(n);
149 if (nodes[n].innerHTML.toLowerCase().indexOf(req) == -1) {
149 if (nodes[n].innerHTML.toLowerCase().indexOf(req) == -1) {
150 obsolete.push(nodes[n]);
150 obsolete.push(nodes[n]);
151 }
151 }
152 }
152 }
153 if(obsolete){
153 if(obsolete){
154 for (n in obsolete){
154 for (n in obsolete){
155 YUD.setStyle(obsolete[n].parentNode,'display','none');
155 YUD.setStyle(obsolete[n].parentNode,'display','none');
156 }
156 }
157 }
157 }
158 }
158 }
159 }
159 }
160
160
161 YUE.on(q_filter,'keyup',function(e){
161 YUE.on(q_filter,'keyup',function(e){
162 clearTimeout(F.filterTimeout);
162 clearTimeout(F.filterTimeout);
163 setTimeout(F.updateFilter,600);
163 setTimeout(F.updateFilter,600);
164 });
164 });
165 }
165 }
166 var loaded = YUD.hasClass('repo_switcher','loaded');
166 var loaded = YUD.hasClass('repo_switcher','loaded');
167 if(!loaded){
167 if(!loaded){
168 YUD.addClass('repo_switcher','loaded');
168 YUD.addClass('repo_switcher','loaded');
169 YAHOO.util.Connect.asyncRequest('GET',"${h.url('repo_switcher')}",{
169 YAHOO.util.Connect.asyncRequest('GET',"${h.url('repo_switcher')}",{
170 success:function(o){
170 success:function(o){
171 YUD.get('repo_switcher_list').innerHTML = o.responseText;
171 YUD.get('repo_switcher_list').innerHTML = o.responseText;
172 qfilter();
172 qfilter();
173 },
173 },
174 failure:function(o){
174 failure:function(o){
175 YUD.removeClass('repo_switcher','loaded');
175 YUD.removeClass('repo_switcher','loaded');
176 }
176 }
177 },null);
177 },null);
178 }
178 }
179 return false;
179 return false;
180 });
180 });
181 </script>
181 </script>
182 </li>
182 </li>
183
183
184 <li ${is_current('summary')}>
184 <li ${is_current('summary')}>
185 <a title="${_('Summary')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
185 <a title="${_('Summary')}" href="${h.url('summary_home',repo_name=c.repo_name)}">
186 <span class="icon">
186 <span class="icon">
187 <img src="${h.url("/images/icons/clipboard_16.png")}" alt="${_('Summary')}" />
187 <img src="${h.url("/images/icons/clipboard_16.png")}" alt="${_('Summary')}" />
188 </span>
188 </span>
189 <span>${_('Summary')}</span>
189 <span>${_('Summary')}</span>
190 </a>
190 </a>
191 </li>
191 </li>
192 ##<li ${is_current('shortlog')}>
192 ##<li ${is_current('shortlog')}>
193 ## <a title="${_('Shortlog')}" href="${h.url('shortlog_home',repo_name=c.repo_name)}">
193 ## <a title="${_('Shortlog')}" href="${h.url('shortlog_home',repo_name=c.repo_name)}">
194 ## <span class="icon">
194 ## <span class="icon">
195 ## <img src="${h.url("/images/icons/application_view_list.png")}" alt="${_('Shortlog')}" />
195 ## <img src="${h.url("/images/icons/application_view_list.png")}" alt="${_('Shortlog')}" />
196 ## </span>
196 ## </span>
197 ## <span>${_('Shortlog')}</span>
197 ## <span>${_('Shortlog')}</span>
198 ## </a>
198 ## </a>
199 ##</li>
199 ##</li>
200 <li ${is_current('changelog')}>
200 <li ${is_current('changelog')}>
201 <a title="${_('Changelog')}" href="${h.url('changelog_home',repo_name=c.repo_name)}">
201 <a title="${_('Changelog')}" href="${h.url('changelog_home',repo_name=c.repo_name)}">
202 <span class="icon">
202 <span class="icon">
203 <img src="${h.url("/images/icons/time.png")}" alt="${_('Changelog')}" />
203 <img src="${h.url("/images/icons/time.png")}" alt="${_('Changelog')}" />
204 </span>
204 </span>
205 <span>${_('Changelog')}</span>
205 <span>${_('Changelog')}</span>
206 </a>
206 </a>
207 </li>
207 </li>
208
208
209 <li ${is_current('switch_to')}>
209 <li ${is_current('switch_to')}>
210 <a title="${_('Switch to')}" href="#">
210 <a title="${_('Switch to')}" href="#">
211 <span class="icon">
211 <span class="icon">
212 <img src="${h.url("/images/icons/arrow_switch.png")}" alt="${_('Switch to')}" />
212 <img src="${h.url("/images/icons/arrow_switch.png")}" alt="${_('Switch to')}" />
213 </span>
213 </span>
214 <span>${_('Switch to')}</span>
214 <span>${_('Switch to')}</span>
215 </a>
215 </a>
216 <ul>
216 <ul>
217 <li>
217 <li>
218 ${h.link_to('%s (%s)' % (_('branches'),len(c.rhodecode_repo.branches.values()),),h.url('branches_home',repo_name=c.repo_name),class_='branches childs')}
218 ${h.link_to('%s (%s)' % (_('branches'),len(c.rhodecode_repo.branches.values()),),h.url('branches_home',repo_name=c.repo_name),class_='branches childs')}
219 <ul>
219 <ul>
220 %if c.rhodecode_repo.branches.values():
220 %if c.rhodecode_repo.branches.values():
221 %for cnt,branch in enumerate(c.rhodecode_repo.branches.items()):
221 %for cnt,branch in enumerate(c.rhodecode_repo.branches.items()):
222 <li>${h.link_to('%s - %s' % (branch[0],h.short_id(branch[1])),h.url('files_home',repo_name=c.repo_name,revision=branch[1]))}</li>
222 <li>${h.link_to('%s - %s' % (branch[0],h.short_id(branch[1])),h.url('files_home',repo_name=c.repo_name,revision=branch[1]))}</li>
223 %endfor
223 %endfor
224 %else:
224 %else:
225 <li>${h.link_to(_('There are no branches yet'),'#')}</li>
225 <li>${h.link_to(_('There are no branches yet'),'#')}</li>
226 %endif
226 %endif
227 </ul>
227 </ul>
228 </li>
228 </li>
229 <li>
229 <li>
230 ${h.link_to('%s (%s)' % (_('tags'),len(c.rhodecode_repo.tags.values()),),h.url('tags_home',repo_name=c.repo_name),class_='tags childs')}
230 ${h.link_to('%s (%s)' % (_('tags'),len(c.rhodecode_repo.tags.values()),),h.url('tags_home',repo_name=c.repo_name),class_='tags childs')}
231 <ul>
231 <ul>
232 %if c.rhodecode_repo.tags.values():
232 %if c.rhodecode_repo.tags.values():
233 %for cnt,tag in enumerate(c.rhodecode_repo.tags.items()):
233 %for cnt,tag in enumerate(c.rhodecode_repo.tags.items()):
234 <li>${h.link_to('%s - %s' % (tag[0],h.short_id(tag[1])),h.url('files_home',repo_name=c.repo_name,revision=tag[1]))}</li>
234 <li>${h.link_to('%s - %s' % (tag[0],h.short_id(tag[1])),h.url('files_home',repo_name=c.repo_name,revision=tag[1]))}</li>
235 %endfor
235 %endfor
236 %else:
236 %else:
237 <li>${h.link_to(_('There are no tags yet'),'#')}</li>
237 <li>${h.link_to(_('There are no tags yet'),'#')}</li>
238 %endif
238 %endif
239 </ul>
239 </ul>
240 </li>
240 </li>
241 </ul>
241 </ul>
242 </li>
242 </li>
243 <li ${is_current('files')}>
243 <li ${is_current('files')}>
244 <a title="${_('Files')}" href="${h.url('files_home',repo_name=c.repo_name)}">
244 <a title="${_('Files')}" href="${h.url('files_home',repo_name=c.repo_name)}">
245 <span class="icon">
245 <span class="icon">
246 <img src="${h.url("/images/icons/file.png")}" alt="${_('Files')}" />
246 <img src="${h.url("/images/icons/file.png")}" alt="${_('Files')}" />
247 </span>
247 </span>
248 <span>${_('Files')}</span>
248 <span>${_('Files')}</span>
249 </a>
249 </a>
250 </li>
250 </li>
251
251
252 <li ${is_current('options')}>
252 <li ${is_current('options')}>
253 <a title="${_('Options')}" href="#">
253 <a title="${_('Options')}" href="#">
254 <span class="icon">
254 <span class="icon">
255 <img src="${h.url("/images/icons/table_gear.png")}" alt="${_('Admin')}" />
255 <img src="${h.url("/images/icons/table_gear.png")}" alt="${_('Admin')}" />
256 </span>
256 </span>
257 <span>${_('Options')}</span>
257 <span>${_('Options')}</span>
258 </a>
258 </a>
259 <ul>
259 <ul>
260 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
260 %if h.HasRepoPermissionAll('repository.admin')(c.repo_name):
261 %if h.HasPermissionAll('hg.admin')('access settings on repository'):
261 %if h.HasPermissionAll('hg.admin')('access settings on repository'):
262 <li>${h.link_to(_('settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li>
262 <li>${h.link_to(_('settings'),h.url('edit_repo',repo_name=c.repo_name),class_='settings')}</li>
263 %else:
263 %else:
264 <li>${h.link_to(_('settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
264 <li>${h.link_to(_('settings'),h.url('repo_settings_home',repo_name=c.repo_name),class_='settings')}</li>
265 %endif
265 %endif
266 %endif
266 %endif
267 <li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li>
267 <li>${h.link_to(_('fork'),h.url('repo_fork_home',repo_name=c.repo_name),class_='fork')}</li>
268 <li>${h.link_to(_('search'),h.url('search_repo',search_repo=c.repo_name),class_='search')}</li>
268 <li>${h.link_to(_('search'),h.url('search_repo',search_repo=c.repo_name),class_='search')}</li>
269
269
270 %if h.HasPermissionAll('hg.admin')('access admin main page'):
270 %if h.HasPermissionAll('hg.admin')('access admin main page'):
271 <li>
271 <li>
272 ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
272 ${h.link_to(_('admin'),h.url('admin_home'),class_='admin')}
273 <%def name="admin_menu()">
273 <%def name="admin_menu()">
274 <ul>
274 <ul>
275 <li>${h.link_to(_('journal'),h.url('admin_home'),class_='journal')}</li>
275 <li>${h.link_to(_('journal'),h.url('admin_home'),class_='journal')}</li>
276 <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
276 <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
277 <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
277 <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
278 <li>${h.link_to(_('users groups'),h.url('users_groups'),class_='groups')}</li>
278 <li>${h.link_to(_('users groups'),h.url('users_groups'),class_='groups')}</li>
279 <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
279 <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
280 <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li>
280 <li>${h.link_to(_('ldap'),h.url('ldap_home'),class_='ldap')}</li>
281 <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
281 <li class="last">${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
282 </ul>
282 </ul>
283 </%def>
283 </%def>
284
284
285 ${admin_menu()}
285 ${admin_menu()}
286 </li>
286 </li>
287 %endif
287 %endif
288
288
289 </ul>
289 </ul>
290 </li>
290 </li>
291
291
292 <li>
292 <li>
293 <a title="${_('Followers')}" href="${h.url('repo_followers_home',repo_name=c.repo_name)}">
293 <a title="${_('Followers')}" href="${h.url('repo_followers_home',repo_name=c.repo_name)}">
294 <span class="icon_short">
294 <span class="icon_short">
295 <img src="${h.url("/images/icons/heart.png")}" alt="${_('Followers')}" />
295 <img src="${h.url("/images/icons/heart.png")}" alt="${_('Followers')}" />
296 </span>
296 </span>
297 <span id="current_followers_count" class="short">${c.repository_followers}</span>
297 <span id="current_followers_count" class="short">${c.repository_followers}</span>
298 </a>
298 </a>
299 </li>
299 </li>
300 <li>
300 <li>
301 <a title="${_('Forks')}" href="#">
301 <a title="${_('Forks')}" href="${h.url('repo_forks_home',repo_name=c.repo_name)}">
302 <span class="icon_short">
302 <span class="icon_short">
303 <img src="${h.url("/images/icons/arrow_divide.png")}" alt="${_('Forks')}" />
303 <img src="${h.url("/images/icons/arrow_divide.png")}" alt="${_('Forks')}" />
304 </span>
304 </span>
305 <span class="short">${c.repository_forks}</span>
305 <span class="short">${c.repository_forks}</span>
306 </a>
306 </a>
307 </li>
307 </li>
308
308
309
309
310
310
311 </ul>
311 </ul>
312 %else:
312 %else:
313 ##ROOT MENU
313 ##ROOT MENU
314 <ul id="quick">
314 <ul id="quick">
315 <li>
315 <li>
316 <a title="${_('Home')}" href="${h.url('home')}">
316 <a title="${_('Home')}" href="${h.url('home')}">
317 <span class="icon">
317 <span class="icon">
318 <img src="${h.url("/images/icons/home_16.png")}" alt="${_('Home')}" />
318 <img src="${h.url("/images/icons/home_16.png")}" alt="${_('Home')}" />
319 </span>
319 </span>
320 <span>${_('Home')}</span>
320 <span>${_('Home')}</span>
321 </a>
321 </a>
322 </li>
322 </li>
323 %if c.rhodecode_user.username != 'default':
323 %if c.rhodecode_user.username != 'default':
324 <li>
324 <li>
325 <a title="${_('Journal')}" href="${h.url('journal')}">
325 <a title="${_('Journal')}" href="${h.url('journal')}">
326 <span class="icon">
326 <span class="icon">
327 <img src="${h.url("/images/icons/book.png")}" alt="${_('Journal')}" />
327 <img src="${h.url("/images/icons/book.png")}" alt="${_('Journal')}" />
328 </span>
328 </span>
329 <span>${_('Journal')}</span>
329 <span>${_('Journal')}</span>
330 </a>
330 </a>
331 </li>
331 </li>
332 %endif
332 %endif
333 <li>
333 <li>
334 <a title="${_('Search')}" href="${h.url('search')}">
334 <a title="${_('Search')}" href="${h.url('search')}">
335 <span class="icon">
335 <span class="icon">
336 <img src="${h.url("/images/icons/search_16.png")}" alt="${_('Search')}" />
336 <img src="${h.url("/images/icons/search_16.png")}" alt="${_('Search')}" />
337 </span>
337 </span>
338 <span>${_('Search')}</span>
338 <span>${_('Search')}</span>
339 </a>
339 </a>
340 </li>
340 </li>
341
341
342 %if h.HasPermissionAll('hg.admin')('access admin main page'):
342 %if h.HasPermissionAll('hg.admin')('access admin main page'):
343 <li ${is_current('admin')}>
343 <li ${is_current('admin')}>
344 <a title="${_('Admin')}" href="${h.url('admin_home')}">
344 <a title="${_('Admin')}" href="${h.url('admin_home')}">
345 <span class="icon">
345 <span class="icon">
346 <img src="${h.url("/images/icons/cog_edit.png")}" alt="${_('Admin')}" />
346 <img src="${h.url("/images/icons/cog_edit.png")}" alt="${_('Admin')}" />
347 </span>
347 </span>
348 <span>${_('Admin')}</span>
348 <span>${_('Admin')}</span>
349 </a>
349 </a>
350 ${admin_menu()}
350 ${admin_menu()}
351 </li>
351 </li>
352 %endif
352 %endif
353 </ul>
353 </ul>
354 %endif
354 %endif
355 </%def> No newline at end of file
355 </%def>
General Comments 0
You need to be logged in to leave comments. Login now