##// END OF EJS Templates
Use changelog controller for displaying history of files....
marcink -
r3760:6302a142 beta
parent child Browse files
Show More
@@ -1,679 +1,679 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
10
11 # prefix for non repository related links needs to be prefixed with `/`
11 # prefix for non repository related links needs to be prefixed with `/`
12 ADMIN_PREFIX = '/_admin'
12 ADMIN_PREFIX = '/_admin'
13
13
14
14
15 def make_map(config):
15 def make_map(config):
16 """Create, configure and return the routes Mapper"""
16 """Create, configure and return the routes Mapper"""
17 rmap = Mapper(directory=config['pylons.paths']['controllers'],
17 rmap = Mapper(directory=config['pylons.paths']['controllers'],
18 always_scan=config['debug'])
18 always_scan=config['debug'])
19 rmap.minimization = False
19 rmap.minimization = False
20 rmap.explicit = False
20 rmap.explicit = False
21
21
22 from rhodecode.lib.utils import is_valid_repo
22 from rhodecode.lib.utils import is_valid_repo
23 from rhodecode.lib.utils import is_valid_repos_group
23 from rhodecode.lib.utils import is_valid_repos_group
24
24
25 def check_repo(environ, match_dict):
25 def check_repo(environ, match_dict):
26 """
26 """
27 check for valid repository for proper 404 handling
27 check for valid repository for proper 404 handling
28
28
29 :param environ:
29 :param environ:
30 :param match_dict:
30 :param match_dict:
31 """
31 """
32 from rhodecode.model.db import Repository
32 from rhodecode.model.db import Repository
33 repo_name = match_dict.get('repo_name')
33 repo_name = match_dict.get('repo_name')
34
34
35 if match_dict.get('f_path'):
35 if match_dict.get('f_path'):
36 #fix for multiple initial slashes that causes errors
36 #fix for multiple initial slashes that causes errors
37 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
37 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
38
38
39 try:
39 try:
40 by_id = repo_name.split('_')
40 by_id = repo_name.split('_')
41 if len(by_id) == 2 and by_id[1].isdigit() and by_id[0] == '':
41 if len(by_id) == 2 and by_id[1].isdigit() and by_id[0] == '':
42 repo_name = Repository.get(by_id[1]).repo_name
42 repo_name = Repository.get(by_id[1]).repo_name
43 match_dict['repo_name'] = repo_name
43 match_dict['repo_name'] = repo_name
44 except Exception:
44 except Exception:
45 pass
45 pass
46
46
47 return is_valid_repo(repo_name, config['base_path'])
47 return is_valid_repo(repo_name, config['base_path'])
48
48
49 def check_group(environ, match_dict):
49 def check_group(environ, match_dict):
50 """
50 """
51 check for valid repository group for proper 404 handling
51 check for valid repository group for proper 404 handling
52
52
53 :param environ:
53 :param environ:
54 :param match_dict:
54 :param match_dict:
55 """
55 """
56 repos_group_name = match_dict.get('group_name')
56 repos_group_name = match_dict.get('group_name')
57 return is_valid_repos_group(repos_group_name, config['base_path'])
57 return is_valid_repos_group(repos_group_name, config['base_path'])
58
58
59 def check_group_skip_path(environ, match_dict):
59 def check_group_skip_path(environ, match_dict):
60 """
60 """
61 check for valid repository group for proper 404 handling, but skips
61 check for valid repository group for proper 404 handling, but skips
62 verification of existing path
62 verification of existing path
63
63
64 :param environ:
64 :param environ:
65 :param match_dict:
65 :param match_dict:
66 """
66 """
67 repos_group_name = match_dict.get('group_name')
67 repos_group_name = match_dict.get('group_name')
68 return is_valid_repos_group(repos_group_name, config['base_path'],
68 return is_valid_repos_group(repos_group_name, config['base_path'],
69 skip_path_check=True)
69 skip_path_check=True)
70
70
71 def check_user_group(environ, match_dict):
71 def check_user_group(environ, match_dict):
72 """
72 """
73 check for valid user group for proper 404 handling
73 check for valid user group for proper 404 handling
74
74
75 :param environ:
75 :param environ:
76 :param match_dict:
76 :param match_dict:
77 """
77 """
78 return True
78 return True
79
79
80 def check_int(environ, match_dict):
80 def check_int(environ, match_dict):
81 return match_dict.get('id').isdigit()
81 return match_dict.get('id').isdigit()
82
82
83 # The ErrorController route (handles 404/500 error pages); it should
83 # The ErrorController route (handles 404/500 error pages); it should
84 # likely stay at the top, ensuring it can always be resolved
84 # likely stay at the top, ensuring it can always be resolved
85 rmap.connect('/error/{action}', controller='error')
85 rmap.connect('/error/{action}', controller='error')
86 rmap.connect('/error/{action}/{id}', controller='error')
86 rmap.connect('/error/{action}/{id}', controller='error')
87
87
88 #==========================================================================
88 #==========================================================================
89 # CUSTOM ROUTES HERE
89 # CUSTOM ROUTES HERE
90 #==========================================================================
90 #==========================================================================
91
91
92 #MAIN PAGE
92 #MAIN PAGE
93 rmap.connect('home', '/', controller='home', action='index')
93 rmap.connect('home', '/', controller='home', action='index')
94 rmap.connect('repo_switcher', '/repos', controller='home',
94 rmap.connect('repo_switcher', '/repos', controller='home',
95 action='repo_switcher')
95 action='repo_switcher')
96 rmap.connect('branch_tag_switcher', '/branches-tags/{repo_name:.*?}',
96 rmap.connect('branch_tag_switcher', '/branches-tags/{repo_name:.*?}',
97 controller='home', action='branch_tag_switcher')
97 controller='home', action='branch_tag_switcher')
98 rmap.connect('bugtracker',
98 rmap.connect('bugtracker',
99 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
99 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
100 _static=True)
100 _static=True)
101 rmap.connect('rst_help',
101 rmap.connect('rst_help',
102 "http://docutils.sourceforge.net/docs/user/rst/quickref.html",
102 "http://docutils.sourceforge.net/docs/user/rst/quickref.html",
103 _static=True)
103 _static=True)
104 rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
104 rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
105
105
106 #ADMIN REPOSITORY REST ROUTES
106 #ADMIN REPOSITORY REST ROUTES
107 with rmap.submapper(path_prefix=ADMIN_PREFIX,
107 with rmap.submapper(path_prefix=ADMIN_PREFIX,
108 controller='admin/repos') as m:
108 controller='admin/repos') as m:
109 m.connect("repos", "/repos",
109 m.connect("repos", "/repos",
110 action="create", conditions=dict(method=["POST"]))
110 action="create", conditions=dict(method=["POST"]))
111 m.connect("repos", "/repos",
111 m.connect("repos", "/repos",
112 action="index", conditions=dict(method=["GET"]))
112 action="index", conditions=dict(method=["GET"]))
113 m.connect("formatted_repos", "/repos.{format}",
113 m.connect("formatted_repos", "/repos.{format}",
114 action="index",
114 action="index",
115 conditions=dict(method=["GET"]))
115 conditions=dict(method=["GET"]))
116 m.connect("new_repo", "/create_repository",
116 m.connect("new_repo", "/create_repository",
117 action="create_repository", conditions=dict(method=["GET"]))
117 action="create_repository", conditions=dict(method=["GET"]))
118 m.connect("/repos/{repo_name:.*?}",
118 m.connect("/repos/{repo_name:.*?}",
119 action="update", conditions=dict(method=["PUT"],
119 action="update", conditions=dict(method=["PUT"],
120 function=check_repo))
120 function=check_repo))
121 m.connect("/repos/{repo_name:.*?}",
121 m.connect("/repos/{repo_name:.*?}",
122 action="delete", conditions=dict(method=["DELETE"],
122 action="delete", conditions=dict(method=["DELETE"],
123 function=check_repo))
123 function=check_repo))
124 m.connect("formatted_edit_repo", "/repos/{repo_name:.*?}.{format}/edit",
124 m.connect("formatted_edit_repo", "/repos/{repo_name:.*?}.{format}/edit",
125 action="edit", conditions=dict(method=["GET"],
125 action="edit", conditions=dict(method=["GET"],
126 function=check_repo))
126 function=check_repo))
127 m.connect("repo", "/repos/{repo_name:.*?}",
127 m.connect("repo", "/repos/{repo_name:.*?}",
128 action="show", conditions=dict(method=["GET"],
128 action="show", conditions=dict(method=["GET"],
129 function=check_repo))
129 function=check_repo))
130 m.connect("formatted_repo", "/repos/{repo_name:.*?}.{format}",
130 m.connect("formatted_repo", "/repos/{repo_name:.*?}.{format}",
131 action="show", conditions=dict(method=["GET"],
131 action="show", conditions=dict(method=["GET"],
132 function=check_repo))
132 function=check_repo))
133 #add repo perm member
133 #add repo perm member
134 m.connect('set_repo_perm_member',
134 m.connect('set_repo_perm_member',
135 "/repos/{repo_name:.*?}/grant_perm",
135 "/repos/{repo_name:.*?}/grant_perm",
136 action="set_repo_perm_member",
136 action="set_repo_perm_member",
137 conditions=dict(method=["POST"], function=check_repo))
137 conditions=dict(method=["POST"], function=check_repo))
138
138
139 #ajax delete repo perm user
139 #ajax delete repo perm user
140 m.connect('delete_repo_perm_member',
140 m.connect('delete_repo_perm_member',
141 "/repos/{repo_name:.*?}/revoke_perm",
141 "/repos/{repo_name:.*?}/revoke_perm",
142 action="delete_repo_perm_member",
142 action="delete_repo_perm_member",
143 conditions=dict(method=["DELETE"], function=check_repo))
143 conditions=dict(method=["DELETE"], function=check_repo))
144
144
145 #settings actions
145 #settings actions
146 m.connect('repo_stats', "/repos_stats/{repo_name:.*?}",
146 m.connect('repo_stats', "/repos_stats/{repo_name:.*?}",
147 action="repo_stats", conditions=dict(method=["DELETE"],
147 action="repo_stats", conditions=dict(method=["DELETE"],
148 function=check_repo))
148 function=check_repo))
149 m.connect('repo_cache', "/repos_cache/{repo_name:.*?}",
149 m.connect('repo_cache', "/repos_cache/{repo_name:.*?}",
150 action="repo_cache", conditions=dict(method=["DELETE"],
150 action="repo_cache", conditions=dict(method=["DELETE"],
151 function=check_repo))
151 function=check_repo))
152 m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*?}",
152 m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*?}",
153 action="repo_public_journal", conditions=dict(method=["PUT"],
153 action="repo_public_journal", conditions=dict(method=["PUT"],
154 function=check_repo))
154 function=check_repo))
155 m.connect('repo_pull', "/repo_pull/{repo_name:.*?}",
155 m.connect('repo_pull', "/repo_pull/{repo_name:.*?}",
156 action="repo_pull", conditions=dict(method=["PUT"],
156 action="repo_pull", conditions=dict(method=["PUT"],
157 function=check_repo))
157 function=check_repo))
158 m.connect('repo_as_fork', "/repo_as_fork/{repo_name:.*?}",
158 m.connect('repo_as_fork', "/repo_as_fork/{repo_name:.*?}",
159 action="repo_as_fork", conditions=dict(method=["PUT"],
159 action="repo_as_fork", conditions=dict(method=["PUT"],
160 function=check_repo))
160 function=check_repo))
161 m.connect('repo_locking', "/repo_locking/{repo_name:.*?}",
161 m.connect('repo_locking', "/repo_locking/{repo_name:.*?}",
162 action="repo_locking", conditions=dict(method=["PUT"],
162 action="repo_locking", conditions=dict(method=["PUT"],
163 function=check_repo))
163 function=check_repo))
164 m.connect('toggle_locking', "/locking_toggle/{repo_name:.*?}",
164 m.connect('toggle_locking', "/locking_toggle/{repo_name:.*?}",
165 action="toggle_locking", conditions=dict(method=["GET"],
165 action="toggle_locking", conditions=dict(method=["GET"],
166 function=check_repo))
166 function=check_repo))
167
167
168 #repo fields
168 #repo fields
169 m.connect('create_repo_fields', "/repo_fields/{repo_name:.*?}/new",
169 m.connect('create_repo_fields', "/repo_fields/{repo_name:.*?}/new",
170 action="create_repo_field", conditions=dict(method=["PUT"],
170 action="create_repo_field", conditions=dict(method=["PUT"],
171 function=check_repo))
171 function=check_repo))
172
172
173 m.connect('delete_repo_fields', "/repo_fields/{repo_name:.*?}/{field_id}",
173 m.connect('delete_repo_fields', "/repo_fields/{repo_name:.*?}/{field_id}",
174 action="delete_repo_field", conditions=dict(method=["DELETE"],
174 action="delete_repo_field", conditions=dict(method=["DELETE"],
175 function=check_repo))
175 function=check_repo))
176
176
177 with rmap.submapper(path_prefix=ADMIN_PREFIX,
177 with rmap.submapper(path_prefix=ADMIN_PREFIX,
178 controller='admin/repos_groups') as m:
178 controller='admin/repos_groups') as m:
179 m.connect("repos_groups", "/repos_groups",
179 m.connect("repos_groups", "/repos_groups",
180 action="create", conditions=dict(method=["POST"]))
180 action="create", conditions=dict(method=["POST"]))
181 m.connect("repos_groups", "/repos_groups",
181 m.connect("repos_groups", "/repos_groups",
182 action="index", conditions=dict(method=["GET"]))
182 action="index", conditions=dict(method=["GET"]))
183 m.connect("formatted_repos_groups", "/repos_groups.{format}",
183 m.connect("formatted_repos_groups", "/repos_groups.{format}",
184 action="index", conditions=dict(method=["GET"]))
184 action="index", conditions=dict(method=["GET"]))
185 m.connect("new_repos_group", "/repos_groups/new",
185 m.connect("new_repos_group", "/repos_groups/new",
186 action="new", conditions=dict(method=["GET"]))
186 action="new", conditions=dict(method=["GET"]))
187 m.connect("formatted_new_repos_group", "/repos_groups/new.{format}",
187 m.connect("formatted_new_repos_group", "/repos_groups/new.{format}",
188 action="new", conditions=dict(method=["GET"]))
188 action="new", conditions=dict(method=["GET"]))
189 m.connect("update_repos_group", "/repos_groups/{group_name:.*?}",
189 m.connect("update_repos_group", "/repos_groups/{group_name:.*?}",
190 action="update", conditions=dict(method=["PUT"],
190 action="update", conditions=dict(method=["PUT"],
191 function=check_group))
191 function=check_group))
192 #add repo group perm member
192 #add repo group perm member
193 m.connect('set_repo_group_perm_member',
193 m.connect('set_repo_group_perm_member',
194 "/repos_groups/{group_name:.*?}/grant_perm",
194 "/repos_groups/{group_name:.*?}/grant_perm",
195 action="set_repo_group_perm_member",
195 action="set_repo_group_perm_member",
196 conditions=dict(method=["POST"], function=check_group))
196 conditions=dict(method=["POST"], function=check_group))
197
197
198 #ajax delete repo group perm
198 #ajax delete repo group perm
199 m.connect('delete_repo_group_perm_member',
199 m.connect('delete_repo_group_perm_member',
200 "/repos_groups/{group_name:.*?}/revoke_perm",
200 "/repos_groups/{group_name:.*?}/revoke_perm",
201 action="delete_repo_group_perm_member",
201 action="delete_repo_group_perm_member",
202 conditions=dict(method=["DELETE"], function=check_group))
202 conditions=dict(method=["DELETE"], function=check_group))
203
203
204 m.connect("delete_repos_group", "/repos_groups/{group_name:.*?}",
204 m.connect("delete_repos_group", "/repos_groups/{group_name:.*?}",
205 action="delete", conditions=dict(method=["DELETE"],
205 action="delete", conditions=dict(method=["DELETE"],
206 function=check_group_skip_path))
206 function=check_group_skip_path))
207 m.connect("edit_repos_group", "/repos_groups/{group_name:.*?}/edit",
207 m.connect("edit_repos_group", "/repos_groups/{group_name:.*?}/edit",
208 action="edit", conditions=dict(method=["GET"],
208 action="edit", conditions=dict(method=["GET"],
209 function=check_group))
209 function=check_group))
210 m.connect("formatted_edit_repos_group",
210 m.connect("formatted_edit_repos_group",
211 "/repos_groups/{group_name:.*?}.{format}/edit",
211 "/repos_groups/{group_name:.*?}.{format}/edit",
212 action="edit", conditions=dict(method=["GET"],
212 action="edit", conditions=dict(method=["GET"],
213 function=check_group))
213 function=check_group))
214 m.connect("repos_group", "/repos_groups/{group_name:.*?}",
214 m.connect("repos_group", "/repos_groups/{group_name:.*?}",
215 action="show", conditions=dict(method=["GET"],
215 action="show", conditions=dict(method=["GET"],
216 function=check_group))
216 function=check_group))
217 m.connect("formatted_repos_group", "/repos_groups/{group_name:.*?}.{format}",
217 m.connect("formatted_repos_group", "/repos_groups/{group_name:.*?}.{format}",
218 action="show", conditions=dict(method=["GET"],
218 action="show", conditions=dict(method=["GET"],
219 function=check_group))
219 function=check_group))
220
220
221 #ADMIN USER REST ROUTES
221 #ADMIN USER REST ROUTES
222 with rmap.submapper(path_prefix=ADMIN_PREFIX,
222 with rmap.submapper(path_prefix=ADMIN_PREFIX,
223 controller='admin/users') as m:
223 controller='admin/users') as m:
224 m.connect("users", "/users",
224 m.connect("users", "/users",
225 action="create", conditions=dict(method=["POST"]))
225 action="create", conditions=dict(method=["POST"]))
226 m.connect("users", "/users",
226 m.connect("users", "/users",
227 action="index", conditions=dict(method=["GET"]))
227 action="index", conditions=dict(method=["GET"]))
228 m.connect("formatted_users", "/users.{format}",
228 m.connect("formatted_users", "/users.{format}",
229 action="index", conditions=dict(method=["GET"]))
229 action="index", conditions=dict(method=["GET"]))
230 m.connect("new_user", "/users/new",
230 m.connect("new_user", "/users/new",
231 action="new", conditions=dict(method=["GET"]))
231 action="new", conditions=dict(method=["GET"]))
232 m.connect("formatted_new_user", "/users/new.{format}",
232 m.connect("formatted_new_user", "/users/new.{format}",
233 action="new", conditions=dict(method=["GET"]))
233 action="new", conditions=dict(method=["GET"]))
234 m.connect("update_user", "/users/{id}",
234 m.connect("update_user", "/users/{id}",
235 action="update", conditions=dict(method=["PUT"]))
235 action="update", conditions=dict(method=["PUT"]))
236 m.connect("delete_user", "/users/{id}",
236 m.connect("delete_user", "/users/{id}",
237 action="delete", conditions=dict(method=["DELETE"]))
237 action="delete", conditions=dict(method=["DELETE"]))
238 m.connect("edit_user", "/users/{id}/edit",
238 m.connect("edit_user", "/users/{id}/edit",
239 action="edit", conditions=dict(method=["GET"]))
239 action="edit", conditions=dict(method=["GET"]))
240 m.connect("formatted_edit_user",
240 m.connect("formatted_edit_user",
241 "/users/{id}.{format}/edit",
241 "/users/{id}.{format}/edit",
242 action="edit", conditions=dict(method=["GET"]))
242 action="edit", conditions=dict(method=["GET"]))
243 m.connect("user", "/users/{id}",
243 m.connect("user", "/users/{id}",
244 action="show", conditions=dict(method=["GET"]))
244 action="show", conditions=dict(method=["GET"]))
245 m.connect("formatted_user", "/users/{id}.{format}",
245 m.connect("formatted_user", "/users/{id}.{format}",
246 action="show", conditions=dict(method=["GET"]))
246 action="show", conditions=dict(method=["GET"]))
247
247
248 #EXTRAS USER ROUTES
248 #EXTRAS USER ROUTES
249 m.connect("user_perm", "/users_perm/{id}",
249 m.connect("user_perm", "/users_perm/{id}",
250 action="update_perm", conditions=dict(method=["PUT"]))
250 action="update_perm", conditions=dict(method=["PUT"]))
251 m.connect("user_emails", "/users_emails/{id}",
251 m.connect("user_emails", "/users_emails/{id}",
252 action="add_email", conditions=dict(method=["PUT"]))
252 action="add_email", conditions=dict(method=["PUT"]))
253 m.connect("user_emails_delete", "/users_emails/{id}",
253 m.connect("user_emails_delete", "/users_emails/{id}",
254 action="delete_email", conditions=dict(method=["DELETE"]))
254 action="delete_email", conditions=dict(method=["DELETE"]))
255 m.connect("user_ips", "/users_ips/{id}",
255 m.connect("user_ips", "/users_ips/{id}",
256 action="add_ip", conditions=dict(method=["PUT"]))
256 action="add_ip", conditions=dict(method=["PUT"]))
257 m.connect("user_ips_delete", "/users_ips/{id}",
257 m.connect("user_ips_delete", "/users_ips/{id}",
258 action="delete_ip", conditions=dict(method=["DELETE"]))
258 action="delete_ip", conditions=dict(method=["DELETE"]))
259
259
260 #ADMIN USER GROUPS REST ROUTES
260 #ADMIN USER GROUPS REST ROUTES
261 with rmap.submapper(path_prefix=ADMIN_PREFIX,
261 with rmap.submapper(path_prefix=ADMIN_PREFIX,
262 controller='admin/users_groups') as m:
262 controller='admin/users_groups') as m:
263 m.connect("users_groups", "/users_groups",
263 m.connect("users_groups", "/users_groups",
264 action="create", conditions=dict(method=["POST"]))
264 action="create", conditions=dict(method=["POST"]))
265 m.connect("users_groups", "/users_groups",
265 m.connect("users_groups", "/users_groups",
266 action="index", conditions=dict(method=["GET"]))
266 action="index", conditions=dict(method=["GET"]))
267 m.connect("formatted_users_groups", "/users_groups.{format}",
267 m.connect("formatted_users_groups", "/users_groups.{format}",
268 action="index", conditions=dict(method=["GET"]))
268 action="index", conditions=dict(method=["GET"]))
269 m.connect("new_users_group", "/users_groups/new",
269 m.connect("new_users_group", "/users_groups/new",
270 action="new", conditions=dict(method=["GET"]))
270 action="new", conditions=dict(method=["GET"]))
271 m.connect("formatted_new_users_group", "/users_groups/new.{format}",
271 m.connect("formatted_new_users_group", "/users_groups/new.{format}",
272 action="new", conditions=dict(method=["GET"]))
272 action="new", conditions=dict(method=["GET"]))
273 m.connect("update_users_group", "/users_groups/{id}",
273 m.connect("update_users_group", "/users_groups/{id}",
274 action="update", conditions=dict(method=["PUT"]))
274 action="update", conditions=dict(method=["PUT"]))
275 m.connect("delete_users_group", "/users_groups/{id}",
275 m.connect("delete_users_group", "/users_groups/{id}",
276 action="delete", conditions=dict(method=["DELETE"]))
276 action="delete", conditions=dict(method=["DELETE"]))
277 m.connect("edit_users_group", "/users_groups/{id}/edit",
277 m.connect("edit_users_group", "/users_groups/{id}/edit",
278 action="edit", conditions=dict(method=["GET"]),
278 action="edit", conditions=dict(method=["GET"]),
279 function=check_user_group)
279 function=check_user_group)
280 m.connect("formatted_edit_users_group",
280 m.connect("formatted_edit_users_group",
281 "/users_groups/{id}.{format}/edit",
281 "/users_groups/{id}.{format}/edit",
282 action="edit", conditions=dict(method=["GET"]))
282 action="edit", conditions=dict(method=["GET"]))
283 m.connect("users_group", "/users_groups/{id}",
283 m.connect("users_group", "/users_groups/{id}",
284 action="show", conditions=dict(method=["GET"]))
284 action="show", conditions=dict(method=["GET"]))
285 m.connect("formatted_users_group", "/users_groups/{id}.{format}",
285 m.connect("formatted_users_group", "/users_groups/{id}.{format}",
286 action="show", conditions=dict(method=["GET"]))
286 action="show", conditions=dict(method=["GET"]))
287
287
288 #EXTRAS USER ROUTES
288 #EXTRAS USER ROUTES
289 # update
289 # update
290 m.connect("users_group_perm", "/users_groups/{id}/update_global_perm",
290 m.connect("users_group_perm", "/users_groups/{id}/update_global_perm",
291 action="update_perm", conditions=dict(method=["PUT"]))
291 action="update_perm", conditions=dict(method=["PUT"]))
292
292
293 #add user group perm member
293 #add user group perm member
294 m.connect('set_user_group_perm_member', "/users_groups/{id}/grant_perm",
294 m.connect('set_user_group_perm_member', "/users_groups/{id}/grant_perm",
295 action="set_user_group_perm_member",
295 action="set_user_group_perm_member",
296 conditions=dict(method=["POST"]))
296 conditions=dict(method=["POST"]))
297
297
298 #ajax delete user group perm
298 #ajax delete user group perm
299 m.connect('delete_user_group_perm_member', "/users_groups/{id}/revoke_perm",
299 m.connect('delete_user_group_perm_member', "/users_groups/{id}/revoke_perm",
300 action="delete_user_group_perm_member",
300 action="delete_user_group_perm_member",
301 conditions=dict(method=["DELETE"]))
301 conditions=dict(method=["DELETE"]))
302
302
303 #ADMIN GROUP REST ROUTES
303 #ADMIN GROUP REST ROUTES
304 rmap.resource('group', 'groups',
304 rmap.resource('group', 'groups',
305 controller='admin/groups', path_prefix=ADMIN_PREFIX)
305 controller='admin/groups', path_prefix=ADMIN_PREFIX)
306
306
307 #ADMIN PERMISSIONS REST ROUTES
307 #ADMIN PERMISSIONS REST ROUTES
308 rmap.resource('permission', 'permissions',
308 rmap.resource('permission', 'permissions',
309 controller='admin/permissions', path_prefix=ADMIN_PREFIX)
309 controller='admin/permissions', path_prefix=ADMIN_PREFIX)
310
310
311 #ADMIN DEFAULTS REST ROUTES
311 #ADMIN DEFAULTS REST ROUTES
312 rmap.resource('default', 'defaults',
312 rmap.resource('default', 'defaults',
313 controller='admin/defaults', path_prefix=ADMIN_PREFIX)
313 controller='admin/defaults', path_prefix=ADMIN_PREFIX)
314
314
315 ##ADMIN LDAP SETTINGS
315 ##ADMIN LDAP SETTINGS
316 rmap.connect('ldap_settings', '%s/ldap' % ADMIN_PREFIX,
316 rmap.connect('ldap_settings', '%s/ldap' % ADMIN_PREFIX,
317 controller='admin/ldap_settings', action='ldap_settings',
317 controller='admin/ldap_settings', action='ldap_settings',
318 conditions=dict(method=["POST"]))
318 conditions=dict(method=["POST"]))
319
319
320 rmap.connect('ldap_home', '%s/ldap' % ADMIN_PREFIX,
320 rmap.connect('ldap_home', '%s/ldap' % ADMIN_PREFIX,
321 controller='admin/ldap_settings')
321 controller='admin/ldap_settings')
322
322
323 #ADMIN SETTINGS REST ROUTES
323 #ADMIN SETTINGS REST ROUTES
324 with rmap.submapper(path_prefix=ADMIN_PREFIX,
324 with rmap.submapper(path_prefix=ADMIN_PREFIX,
325 controller='admin/settings') as m:
325 controller='admin/settings') as m:
326 m.connect("admin_settings", "/settings",
326 m.connect("admin_settings", "/settings",
327 action="create", conditions=dict(method=["POST"]))
327 action="create", conditions=dict(method=["POST"]))
328 m.connect("admin_settings", "/settings",
328 m.connect("admin_settings", "/settings",
329 action="index", conditions=dict(method=["GET"]))
329 action="index", conditions=dict(method=["GET"]))
330 m.connect("formatted_admin_settings", "/settings.{format}",
330 m.connect("formatted_admin_settings", "/settings.{format}",
331 action="index", conditions=dict(method=["GET"]))
331 action="index", conditions=dict(method=["GET"]))
332 m.connect("admin_new_setting", "/settings/new",
332 m.connect("admin_new_setting", "/settings/new",
333 action="new", conditions=dict(method=["GET"]))
333 action="new", conditions=dict(method=["GET"]))
334 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
334 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
335 action="new", conditions=dict(method=["GET"]))
335 action="new", conditions=dict(method=["GET"]))
336 m.connect("/settings/{setting_id}",
336 m.connect("/settings/{setting_id}",
337 action="update", conditions=dict(method=["PUT"]))
337 action="update", conditions=dict(method=["PUT"]))
338 m.connect("/settings/{setting_id}",
338 m.connect("/settings/{setting_id}",
339 action="delete", conditions=dict(method=["DELETE"]))
339 action="delete", conditions=dict(method=["DELETE"]))
340 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
340 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
341 action="edit", conditions=dict(method=["GET"]))
341 action="edit", conditions=dict(method=["GET"]))
342 m.connect("formatted_admin_edit_setting",
342 m.connect("formatted_admin_edit_setting",
343 "/settings/{setting_id}.{format}/edit",
343 "/settings/{setting_id}.{format}/edit",
344 action="edit", conditions=dict(method=["GET"]))
344 action="edit", conditions=dict(method=["GET"]))
345 m.connect("admin_setting", "/settings/{setting_id}",
345 m.connect("admin_setting", "/settings/{setting_id}",
346 action="show", conditions=dict(method=["GET"]))
346 action="show", conditions=dict(method=["GET"]))
347 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
347 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
348 action="show", conditions=dict(method=["GET"]))
348 action="show", conditions=dict(method=["GET"]))
349 m.connect("admin_settings_my_account", "/my_account",
349 m.connect("admin_settings_my_account", "/my_account",
350 action="my_account", conditions=dict(method=["GET"]))
350 action="my_account", conditions=dict(method=["GET"]))
351 m.connect("admin_settings_my_account_update", "/my_account_update",
351 m.connect("admin_settings_my_account_update", "/my_account_update",
352 action="my_account_update", conditions=dict(method=["PUT"]))
352 action="my_account_update", conditions=dict(method=["PUT"]))
353 m.connect("admin_settings_my_repos", "/my_account/repos",
353 m.connect("admin_settings_my_repos", "/my_account/repos",
354 action="my_account_my_repos", conditions=dict(method=["GET"]))
354 action="my_account_my_repos", conditions=dict(method=["GET"]))
355 m.connect("admin_settings_my_pullrequests", "/my_account/pull_requests",
355 m.connect("admin_settings_my_pullrequests", "/my_account/pull_requests",
356 action="my_account_my_pullrequests", conditions=dict(method=["GET"]))
356 action="my_account_my_pullrequests", conditions=dict(method=["GET"]))
357
357
358 #NOTIFICATION REST ROUTES
358 #NOTIFICATION REST ROUTES
359 with rmap.submapper(path_prefix=ADMIN_PREFIX,
359 with rmap.submapper(path_prefix=ADMIN_PREFIX,
360 controller='admin/notifications') as m:
360 controller='admin/notifications') as m:
361 m.connect("notifications", "/notifications",
361 m.connect("notifications", "/notifications",
362 action="create", conditions=dict(method=["POST"]))
362 action="create", conditions=dict(method=["POST"]))
363 m.connect("notifications", "/notifications",
363 m.connect("notifications", "/notifications",
364 action="index", conditions=dict(method=["GET"]))
364 action="index", conditions=dict(method=["GET"]))
365 m.connect("notifications_mark_all_read", "/notifications/mark_all_read",
365 m.connect("notifications_mark_all_read", "/notifications/mark_all_read",
366 action="mark_all_read", conditions=dict(method=["GET"]))
366 action="mark_all_read", conditions=dict(method=["GET"]))
367 m.connect("formatted_notifications", "/notifications.{format}",
367 m.connect("formatted_notifications", "/notifications.{format}",
368 action="index", conditions=dict(method=["GET"]))
368 action="index", conditions=dict(method=["GET"]))
369 m.connect("new_notification", "/notifications/new",
369 m.connect("new_notification", "/notifications/new",
370 action="new", conditions=dict(method=["GET"]))
370 action="new", conditions=dict(method=["GET"]))
371 m.connect("formatted_new_notification", "/notifications/new.{format}",
371 m.connect("formatted_new_notification", "/notifications/new.{format}",
372 action="new", conditions=dict(method=["GET"]))
372 action="new", conditions=dict(method=["GET"]))
373 m.connect("/notification/{notification_id}",
373 m.connect("/notification/{notification_id}",
374 action="update", conditions=dict(method=["PUT"]))
374 action="update", conditions=dict(method=["PUT"]))
375 m.connect("/notification/{notification_id}",
375 m.connect("/notification/{notification_id}",
376 action="delete", conditions=dict(method=["DELETE"]))
376 action="delete", conditions=dict(method=["DELETE"]))
377 m.connect("edit_notification", "/notification/{notification_id}/edit",
377 m.connect("edit_notification", "/notification/{notification_id}/edit",
378 action="edit", conditions=dict(method=["GET"]))
378 action="edit", conditions=dict(method=["GET"]))
379 m.connect("formatted_edit_notification",
379 m.connect("formatted_edit_notification",
380 "/notification/{notification_id}.{format}/edit",
380 "/notification/{notification_id}.{format}/edit",
381 action="edit", conditions=dict(method=["GET"]))
381 action="edit", conditions=dict(method=["GET"]))
382 m.connect("notification", "/notification/{notification_id}",
382 m.connect("notification", "/notification/{notification_id}",
383 action="show", conditions=dict(method=["GET"]))
383 action="show", conditions=dict(method=["GET"]))
384 m.connect("formatted_notification", "/notifications/{notification_id}.{format}",
384 m.connect("formatted_notification", "/notifications/{notification_id}.{format}",
385 action="show", conditions=dict(method=["GET"]))
385 action="show", conditions=dict(method=["GET"]))
386
386
387 #ADMIN MAIN PAGES
387 #ADMIN MAIN PAGES
388 with rmap.submapper(path_prefix=ADMIN_PREFIX,
388 with rmap.submapper(path_prefix=ADMIN_PREFIX,
389 controller='admin/admin') as m:
389 controller='admin/admin') as m:
390 m.connect('admin_home', '', action='index')
390 m.connect('admin_home', '', action='index')
391 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
391 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
392 action='add_repo')
392 action='add_repo')
393
393
394 #==========================================================================
394 #==========================================================================
395 # API V2
395 # API V2
396 #==========================================================================
396 #==========================================================================
397 with rmap.submapper(path_prefix=ADMIN_PREFIX,
397 with rmap.submapper(path_prefix=ADMIN_PREFIX,
398 controller='api/api') as m:
398 controller='api/api') as m:
399 m.connect('api', '/api')
399 m.connect('api', '/api')
400
400
401 #USER JOURNAL
401 #USER JOURNAL
402 rmap.connect('journal', '%s/journal' % ADMIN_PREFIX,
402 rmap.connect('journal', '%s/journal' % ADMIN_PREFIX,
403 controller='journal', action='index')
403 controller='journal', action='index')
404 rmap.connect('journal_rss', '%s/journal/rss' % ADMIN_PREFIX,
404 rmap.connect('journal_rss', '%s/journal/rss' % ADMIN_PREFIX,
405 controller='journal', action='journal_rss')
405 controller='journal', action='journal_rss')
406 rmap.connect('journal_atom', '%s/journal/atom' % ADMIN_PREFIX,
406 rmap.connect('journal_atom', '%s/journal/atom' % ADMIN_PREFIX,
407 controller='journal', action='journal_atom')
407 controller='journal', action='journal_atom')
408
408
409 rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
409 rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
410 controller='journal', action="public_journal")
410 controller='journal', action="public_journal")
411
411
412 rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX,
412 rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX,
413 controller='journal', action="public_journal_rss")
413 controller='journal', action="public_journal_rss")
414
414
415 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % ADMIN_PREFIX,
415 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % ADMIN_PREFIX,
416 controller='journal', action="public_journal_rss")
416 controller='journal', action="public_journal_rss")
417
417
418 rmap.connect('public_journal_atom',
418 rmap.connect('public_journal_atom',
419 '%s/public_journal/atom' % ADMIN_PREFIX, controller='journal',
419 '%s/public_journal/atom' % ADMIN_PREFIX, controller='journal',
420 action="public_journal_atom")
420 action="public_journal_atom")
421
421
422 rmap.connect('public_journal_atom_old',
422 rmap.connect('public_journal_atom_old',
423 '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal',
423 '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal',
424 action="public_journal_atom")
424 action="public_journal_atom")
425
425
426 rmap.connect('toggle_following', '%s/toggle_following' % ADMIN_PREFIX,
426 rmap.connect('toggle_following', '%s/toggle_following' % ADMIN_PREFIX,
427 controller='journal', action='toggle_following',
427 controller='journal', action='toggle_following',
428 conditions=dict(method=["POST"]))
428 conditions=dict(method=["POST"]))
429
429
430 #SEARCH
430 #SEARCH
431 rmap.connect('search', '%s/search' % ADMIN_PREFIX, controller='search',)
431 rmap.connect('search', '%s/search' % ADMIN_PREFIX, controller='search',)
432 rmap.connect('search_repo_admin', '%s/search/{repo_name:.*}' % ADMIN_PREFIX,
432 rmap.connect('search_repo_admin', '%s/search/{repo_name:.*}' % ADMIN_PREFIX,
433 controller='search',
433 controller='search',
434 conditions=dict(function=check_repo))
434 conditions=dict(function=check_repo))
435 rmap.connect('search_repo', '/{repo_name:.*?}/search',
435 rmap.connect('search_repo', '/{repo_name:.*?}/search',
436 controller='search',
436 controller='search',
437 conditions=dict(function=check_repo),
437 conditions=dict(function=check_repo),
438 )
438 )
439
439
440 #LOGIN/LOGOUT/REGISTER/SIGN IN
440 #LOGIN/LOGOUT/REGISTER/SIGN IN
441 rmap.connect('login_home', '%s/login' % ADMIN_PREFIX, controller='login')
441 rmap.connect('login_home', '%s/login' % ADMIN_PREFIX, controller='login')
442 rmap.connect('logout_home', '%s/logout' % ADMIN_PREFIX, controller='login',
442 rmap.connect('logout_home', '%s/logout' % ADMIN_PREFIX, controller='login',
443 action='logout')
443 action='logout')
444
444
445 rmap.connect('register', '%s/register' % ADMIN_PREFIX, controller='login',
445 rmap.connect('register', '%s/register' % ADMIN_PREFIX, controller='login',
446 action='register')
446 action='register')
447
447
448 rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX,
448 rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX,
449 controller='login', action='password_reset')
449 controller='login', action='password_reset')
450
450
451 rmap.connect('reset_password_confirmation',
451 rmap.connect('reset_password_confirmation',
452 '%s/password_reset_confirmation' % ADMIN_PREFIX,
452 '%s/password_reset_confirmation' % ADMIN_PREFIX,
453 controller='login', action='password_reset_confirmation')
453 controller='login', action='password_reset_confirmation')
454
454
455 #FEEDS
455 #FEEDS
456 rmap.connect('rss_feed_home', '/{repo_name:.*?}/feed/rss',
456 rmap.connect('rss_feed_home', '/{repo_name:.*?}/feed/rss',
457 controller='feed', action='rss',
457 controller='feed', action='rss',
458 conditions=dict(function=check_repo))
458 conditions=dict(function=check_repo))
459
459
460 rmap.connect('atom_feed_home', '/{repo_name:.*?}/feed/atom',
460 rmap.connect('atom_feed_home', '/{repo_name:.*?}/feed/atom',
461 controller='feed', action='atom',
461 controller='feed', action='atom',
462 conditions=dict(function=check_repo))
462 conditions=dict(function=check_repo))
463
463
464 #==========================================================================
464 #==========================================================================
465 # REPOSITORY ROUTES
465 # REPOSITORY ROUTES
466 #==========================================================================
466 #==========================================================================
467 rmap.connect('summary_home', '/{repo_name:.*?}',
467 rmap.connect('summary_home', '/{repo_name:.*?}',
468 controller='summary',
468 controller='summary',
469 conditions=dict(function=check_repo))
469 conditions=dict(function=check_repo))
470
470
471 rmap.connect('repo_size', '/{repo_name:.*?}/repo_size',
471 rmap.connect('repo_size', '/{repo_name:.*?}/repo_size',
472 controller='summary', action='repo_size',
472 controller='summary', action='repo_size',
473 conditions=dict(function=check_repo))
473 conditions=dict(function=check_repo))
474
474
475 rmap.connect('repos_group_home', '/{group_name:.*}',
475 rmap.connect('repos_group_home', '/{group_name:.*}',
476 controller='admin/repos_groups', action="show_by_name",
476 controller='admin/repos_groups', action="show_by_name",
477 conditions=dict(function=check_group))
477 conditions=dict(function=check_group))
478
478
479 rmap.connect('changeset_home', '/{repo_name:.*?}/changeset/{revision}',
479 rmap.connect('changeset_home', '/{repo_name:.*?}/changeset/{revision}',
480 controller='changeset', revision='tip',
480 controller='changeset', revision='tip',
481 conditions=dict(function=check_repo))
481 conditions=dict(function=check_repo))
482
482
483 # no longer user, but kept for routes to work
483 # no longer user, but kept for routes to work
484 rmap.connect("_edit_repo", "/{repo_name:.*?}/edit",
484 rmap.connect("_edit_repo", "/{repo_name:.*?}/edit",
485 controller='admin/repos', action="edit",
485 controller='admin/repos', action="edit",
486 conditions=dict(method=["GET"], function=check_repo)
486 conditions=dict(method=["GET"], function=check_repo)
487 )
487 )
488
488
489 rmap.connect("edit_repo", "/{repo_name:.*?}/settings",
489 rmap.connect("edit_repo", "/{repo_name:.*?}/settings",
490 controller='admin/repos', action="edit",
490 controller='admin/repos', action="edit",
491 conditions=dict(method=["GET"], function=check_repo)
491 conditions=dict(method=["GET"], function=check_repo)
492 )
492 )
493
493
494 #still working url for backward compat.
494 #still working url for backward compat.
495 rmap.connect('raw_changeset_home_depraced',
495 rmap.connect('raw_changeset_home_depraced',
496 '/{repo_name:.*?}/raw-changeset/{revision}',
496 '/{repo_name:.*?}/raw-changeset/{revision}',
497 controller='changeset', action='changeset_raw',
497 controller='changeset', action='changeset_raw',
498 revision='tip', conditions=dict(function=check_repo))
498 revision='tip', conditions=dict(function=check_repo))
499
499
500 ## new URLs
500 ## new URLs
501 rmap.connect('changeset_raw_home',
501 rmap.connect('changeset_raw_home',
502 '/{repo_name:.*?}/changeset-diff/{revision}',
502 '/{repo_name:.*?}/changeset-diff/{revision}',
503 controller='changeset', action='changeset_raw',
503 controller='changeset', action='changeset_raw',
504 revision='tip', conditions=dict(function=check_repo))
504 revision='tip', conditions=dict(function=check_repo))
505
505
506 rmap.connect('changeset_patch_home',
506 rmap.connect('changeset_patch_home',
507 '/{repo_name:.*?}/changeset-patch/{revision}',
507 '/{repo_name:.*?}/changeset-patch/{revision}',
508 controller='changeset', action='changeset_patch',
508 controller='changeset', action='changeset_patch',
509 revision='tip', conditions=dict(function=check_repo))
509 revision='tip', conditions=dict(function=check_repo))
510
510
511 rmap.connect('changeset_download_home',
511 rmap.connect('changeset_download_home',
512 '/{repo_name:.*?}/changeset-download/{revision}',
512 '/{repo_name:.*?}/changeset-download/{revision}',
513 controller='changeset', action='changeset_download',
513 controller='changeset', action='changeset_download',
514 revision='tip', conditions=dict(function=check_repo))
514 revision='tip', conditions=dict(function=check_repo))
515
515
516 rmap.connect('changeset_comment',
516 rmap.connect('changeset_comment',
517 '/{repo_name:.*?}/changeset/{revision}/comment',
517 '/{repo_name:.*?}/changeset/{revision}/comment',
518 controller='changeset', revision='tip', action='comment',
518 controller='changeset', revision='tip', action='comment',
519 conditions=dict(function=check_repo))
519 conditions=dict(function=check_repo))
520
520
521 rmap.connect('changeset_comment_preview',
521 rmap.connect('changeset_comment_preview',
522 '/{repo_name:.*?}/changeset/comment/preview',
522 '/{repo_name:.*?}/changeset/comment/preview',
523 controller='changeset', action='preview_comment',
523 controller='changeset', action='preview_comment',
524 conditions=dict(function=check_repo, method=["POST"]))
524 conditions=dict(function=check_repo, method=["POST"]))
525
525
526 rmap.connect('changeset_comment_delete',
526 rmap.connect('changeset_comment_delete',
527 '/{repo_name:.*?}/changeset/comment/{comment_id}/delete',
527 '/{repo_name:.*?}/changeset/comment/{comment_id}/delete',
528 controller='changeset', action='delete_comment',
528 controller='changeset', action='delete_comment',
529 conditions=dict(function=check_repo, method=["DELETE"]))
529 conditions=dict(function=check_repo, method=["DELETE"]))
530
530
531 rmap.connect('changeset_info', '/changeset_info/{repo_name:.*?}/{revision}',
531 rmap.connect('changeset_info', '/changeset_info/{repo_name:.*?}/{revision}',
532 controller='changeset', action='changeset_info')
532 controller='changeset', action='changeset_info')
533
533
534 rmap.connect('compare_url',
534 rmap.connect('compare_url',
535 '/{repo_name:.*?}/compare/{org_ref_type}@{org_ref:.*?}...{other_ref_type}@{other_ref:.*?}',
535 '/{repo_name:.*?}/compare/{org_ref_type}@{org_ref:.*?}...{other_ref_type}@{other_ref:.*?}',
536 controller='compare', action='index',
536 controller='compare', action='index',
537 conditions=dict(function=check_repo),
537 conditions=dict(function=check_repo),
538 requirements=dict(
538 requirements=dict(
539 org_ref_type='(branch|book|tag|rev|__other_ref_type__)',
539 org_ref_type='(branch|book|tag|rev|__other_ref_type__)',
540 other_ref_type='(branch|book|tag|rev|__org_ref_type__)')
540 other_ref_type='(branch|book|tag|rev|__org_ref_type__)')
541 )
541 )
542
542
543 rmap.connect('pullrequest_home',
543 rmap.connect('pullrequest_home',
544 '/{repo_name:.*?}/pull-request/new', controller='pullrequests',
544 '/{repo_name:.*?}/pull-request/new', controller='pullrequests',
545 action='index', conditions=dict(function=check_repo,
545 action='index', conditions=dict(function=check_repo,
546 method=["GET"]))
546 method=["GET"]))
547
547
548 rmap.connect('pullrequest',
548 rmap.connect('pullrequest',
549 '/{repo_name:.*?}/pull-request/new', controller='pullrequests',
549 '/{repo_name:.*?}/pull-request/new', controller='pullrequests',
550 action='create', conditions=dict(function=check_repo,
550 action='create', conditions=dict(function=check_repo,
551 method=["POST"]))
551 method=["POST"]))
552
552
553 rmap.connect('pullrequest_show',
553 rmap.connect('pullrequest_show',
554 '/{repo_name:.*?}/pull-request/{pull_request_id}',
554 '/{repo_name:.*?}/pull-request/{pull_request_id}',
555 controller='pullrequests',
555 controller='pullrequests',
556 action='show', conditions=dict(function=check_repo,
556 action='show', conditions=dict(function=check_repo,
557 method=["GET"]))
557 method=["GET"]))
558 rmap.connect('pullrequest_update',
558 rmap.connect('pullrequest_update',
559 '/{repo_name:.*?}/pull-request/{pull_request_id}',
559 '/{repo_name:.*?}/pull-request/{pull_request_id}',
560 controller='pullrequests',
560 controller='pullrequests',
561 action='update', conditions=dict(function=check_repo,
561 action='update', conditions=dict(function=check_repo,
562 method=["PUT"]))
562 method=["PUT"]))
563 rmap.connect('pullrequest_delete',
563 rmap.connect('pullrequest_delete',
564 '/{repo_name:.*?}/pull-request/{pull_request_id}',
564 '/{repo_name:.*?}/pull-request/{pull_request_id}',
565 controller='pullrequests',
565 controller='pullrequests',
566 action='delete', conditions=dict(function=check_repo,
566 action='delete', conditions=dict(function=check_repo,
567 method=["DELETE"]))
567 method=["DELETE"]))
568
568
569 rmap.connect('pullrequest_show_all',
569 rmap.connect('pullrequest_show_all',
570 '/{repo_name:.*?}/pull-request',
570 '/{repo_name:.*?}/pull-request',
571 controller='pullrequests',
571 controller='pullrequests',
572 action='show_all', conditions=dict(function=check_repo,
572 action='show_all', conditions=dict(function=check_repo,
573 method=["GET"]))
573 method=["GET"]))
574
574
575 rmap.connect('pullrequest_comment',
575 rmap.connect('pullrequest_comment',
576 '/{repo_name:.*?}/pull-request-comment/{pull_request_id}',
576 '/{repo_name:.*?}/pull-request-comment/{pull_request_id}',
577 controller='pullrequests',
577 controller='pullrequests',
578 action='comment', conditions=dict(function=check_repo,
578 action='comment', conditions=dict(function=check_repo,
579 method=["POST"]))
579 method=["POST"]))
580
580
581 rmap.connect('pullrequest_comment_delete',
581 rmap.connect('pullrequest_comment_delete',
582 '/{repo_name:.*?}/pull-request-comment/{comment_id}/delete',
582 '/{repo_name:.*?}/pull-request-comment/{comment_id}/delete',
583 controller='pullrequests', action='delete_comment',
583 controller='pullrequests', action='delete_comment',
584 conditions=dict(function=check_repo, method=["DELETE"]))
584 conditions=dict(function=check_repo, method=["DELETE"]))
585
585
586 rmap.connect('summary_home_summary', '/{repo_name:.*?}/summary',
586 rmap.connect('summary_home_summary', '/{repo_name:.*?}/summary',
587 controller='summary', conditions=dict(function=check_repo))
587 controller='summary', conditions=dict(function=check_repo))
588
588
589 rmap.connect('shortlog_home', '/{repo_name:.*?}/shortlog',
589 rmap.connect('shortlog_home', '/{repo_name:.*?}/shortlog',
590 controller='shortlog', conditions=dict(function=check_repo))
590 controller='shortlog', conditions=dict(function=check_repo))
591
591
592 rmap.connect('shortlog_file_home', '/{repo_name:.*?}/shortlog/{revision}/{f_path:.*}',
593 controller='shortlog', f_path=None,
594 conditions=dict(function=check_repo))
595
596 rmap.connect('branches_home', '/{repo_name:.*?}/branches',
592 rmap.connect('branches_home', '/{repo_name:.*?}/branches',
597 controller='branches', conditions=dict(function=check_repo))
593 controller='branches', conditions=dict(function=check_repo))
598
594
599 rmap.connect('tags_home', '/{repo_name:.*?}/tags',
595 rmap.connect('tags_home', '/{repo_name:.*?}/tags',
600 controller='tags', conditions=dict(function=check_repo))
596 controller='tags', conditions=dict(function=check_repo))
601
597
602 rmap.connect('bookmarks_home', '/{repo_name:.*?}/bookmarks',
598 rmap.connect('bookmarks_home', '/{repo_name:.*?}/bookmarks',
603 controller='bookmarks', conditions=dict(function=check_repo))
599 controller='bookmarks', conditions=dict(function=check_repo))
604
600
605 rmap.connect('changelog_home', '/{repo_name:.*?}/changelog',
601 rmap.connect('changelog_home', '/{repo_name:.*?}/changelog',
606 controller='changelog', conditions=dict(function=check_repo))
602 controller='changelog', conditions=dict(function=check_repo))
607
603
604 rmap.connect('changelog_file_home', '/{repo_name:.*?}/changelog/{revision}/{f_path:.*}',
605 controller='changelog', f_path=None,
606 conditions=dict(function=check_repo))
607
608 rmap.connect('changelog_details', '/{repo_name:.*?}/changelog_details/{cs}',
608 rmap.connect('changelog_details', '/{repo_name:.*?}/changelog_details/{cs}',
609 controller='changelog', action='changelog_details',
609 controller='changelog', action='changelog_details',
610 conditions=dict(function=check_repo))
610 conditions=dict(function=check_repo))
611
611
612 rmap.connect('files_home', '/{repo_name:.*?}/files/{revision}/{f_path:.*}',
612 rmap.connect('files_home', '/{repo_name:.*?}/files/{revision}/{f_path:.*}',
613 controller='files', revision='tip', f_path='',
613 controller='files', revision='tip', f_path='',
614 conditions=dict(function=check_repo))
614 conditions=dict(function=check_repo))
615
615
616 rmap.connect('files_home_nopath', '/{repo_name:.*?}/files/{revision}',
616 rmap.connect('files_home_nopath', '/{repo_name:.*?}/files/{revision}',
617 controller='files', revision='tip', f_path='',
617 controller='files', revision='tip', f_path='',
618 conditions=dict(function=check_repo))
618 conditions=dict(function=check_repo))
619
619
620 rmap.connect('files_history_home',
620 rmap.connect('files_history_home',
621 '/{repo_name:.*?}/history/{revision}/{f_path:.*}',
621 '/{repo_name:.*?}/history/{revision}/{f_path:.*}',
622 controller='files', action='history', revision='tip', f_path='',
622 controller='files', action='history', revision='tip', f_path='',
623 conditions=dict(function=check_repo))
623 conditions=dict(function=check_repo))
624
624
625 rmap.connect('files_diff_home', '/{repo_name:.*?}/diff/{f_path:.*}',
625 rmap.connect('files_diff_home', '/{repo_name:.*?}/diff/{f_path:.*}',
626 controller='files', action='diff', revision='tip', f_path='',
626 controller='files', action='diff', revision='tip', f_path='',
627 conditions=dict(function=check_repo))
627 conditions=dict(function=check_repo))
628
628
629 rmap.connect('files_rawfile_home',
629 rmap.connect('files_rawfile_home',
630 '/{repo_name:.*?}/rawfile/{revision}/{f_path:.*}',
630 '/{repo_name:.*?}/rawfile/{revision}/{f_path:.*}',
631 controller='files', action='rawfile', revision='tip',
631 controller='files', action='rawfile', revision='tip',
632 f_path='', conditions=dict(function=check_repo))
632 f_path='', conditions=dict(function=check_repo))
633
633
634 rmap.connect('files_raw_home',
634 rmap.connect('files_raw_home',
635 '/{repo_name:.*?}/raw/{revision}/{f_path:.*}',
635 '/{repo_name:.*?}/raw/{revision}/{f_path:.*}',
636 controller='files', action='raw', revision='tip', f_path='',
636 controller='files', action='raw', revision='tip', f_path='',
637 conditions=dict(function=check_repo))
637 conditions=dict(function=check_repo))
638
638
639 rmap.connect('files_annotate_home',
639 rmap.connect('files_annotate_home',
640 '/{repo_name:.*?}/annotate/{revision}/{f_path:.*}',
640 '/{repo_name:.*?}/annotate/{revision}/{f_path:.*}',
641 controller='files', action='index', revision='tip',
641 controller='files', action='index', revision='tip',
642 f_path='', annotate=True, conditions=dict(function=check_repo))
642 f_path='', annotate=True, conditions=dict(function=check_repo))
643
643
644 rmap.connect('files_edit_home',
644 rmap.connect('files_edit_home',
645 '/{repo_name:.*?}/edit/{revision}/{f_path:.*}',
645 '/{repo_name:.*?}/edit/{revision}/{f_path:.*}',
646 controller='files', action='edit', revision='tip',
646 controller='files', action='edit', revision='tip',
647 f_path='', conditions=dict(function=check_repo))
647 f_path='', conditions=dict(function=check_repo))
648
648
649 rmap.connect('files_add_home',
649 rmap.connect('files_add_home',
650 '/{repo_name:.*?}/add/{revision}/{f_path:.*}',
650 '/{repo_name:.*?}/add/{revision}/{f_path:.*}',
651 controller='files', action='add', revision='tip',
651 controller='files', action='add', revision='tip',
652 f_path='', conditions=dict(function=check_repo))
652 f_path='', conditions=dict(function=check_repo))
653
653
654 rmap.connect('files_archive_home', '/{repo_name:.*?}/archive/{fname}',
654 rmap.connect('files_archive_home', '/{repo_name:.*?}/archive/{fname}',
655 controller='files', action='archivefile',
655 controller='files', action='archivefile',
656 conditions=dict(function=check_repo))
656 conditions=dict(function=check_repo))
657
657
658 rmap.connect('files_nodelist_home',
658 rmap.connect('files_nodelist_home',
659 '/{repo_name:.*?}/nodelist/{revision}/{f_path:.*}',
659 '/{repo_name:.*?}/nodelist/{revision}/{f_path:.*}',
660 controller='files', action='nodelist',
660 controller='files', action='nodelist',
661 conditions=dict(function=check_repo))
661 conditions=dict(function=check_repo))
662
662
663 rmap.connect('repo_fork_create_home', '/{repo_name:.*?}/fork',
663 rmap.connect('repo_fork_create_home', '/{repo_name:.*?}/fork',
664 controller='forks', action='fork_create',
664 controller='forks', action='fork_create',
665 conditions=dict(function=check_repo, method=["POST"]))
665 conditions=dict(function=check_repo, method=["POST"]))
666
666
667 rmap.connect('repo_fork_home', '/{repo_name:.*?}/fork',
667 rmap.connect('repo_fork_home', '/{repo_name:.*?}/fork',
668 controller='forks', action='fork',
668 controller='forks', action='fork',
669 conditions=dict(function=check_repo))
669 conditions=dict(function=check_repo))
670
670
671 rmap.connect('repo_forks_home', '/{repo_name:.*?}/forks',
671 rmap.connect('repo_forks_home', '/{repo_name:.*?}/forks',
672 controller='forks', action='forks',
672 controller='forks', action='forks',
673 conditions=dict(function=check_repo))
673 conditions=dict(function=check_repo))
674
674
675 rmap.connect('repo_followers_home', '/{repo_name:.*?}/followers',
675 rmap.connect('repo_followers_home', '/{repo_name:.*?}/followers',
676 controller='followers', action='followers',
676 controller='followers', action='followers',
677 conditions=dict(function=check_repo))
677 conditions=dict(function=check_repo))
678
678
679 return rmap
679 return rmap
@@ -1,122 +1,142 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.changelog
3 rhodecode.controllers.changelog
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 changelog controller for rhodecode
6 changelog controller for rhodecode
7
7
8 :created_on: Apr 21, 2010
8 :created_on: Apr 21, 2010
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2010-2012 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 logging
26 import logging
27 import traceback
27 import traceback
28
28
29 from pylons import request, url, session, tmpl_context as c
29 from pylons import request, url, session, tmpl_context as c
30 from pylons.controllers.util import redirect
30 from pylons.controllers.util import redirect
31 from pylons.i18n.translation import _
31 from pylons.i18n.translation import _
32
32
33 import rhodecode.lib.helpers as h
33 import rhodecode.lib.helpers as h
34 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
34 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
35 from rhodecode.lib.base import BaseRepoController, render
35 from rhodecode.lib.base import BaseRepoController, render
36 from rhodecode.lib.helpers import RepoPage
36 from rhodecode.lib.helpers import RepoPage
37 from rhodecode.lib.compat import json
37 from rhodecode.lib.compat import json
38 from rhodecode.lib.graphmod import _colored, _dagwalker
38 from rhodecode.lib.graphmod import _colored, _dagwalker
39 from rhodecode.lib.vcs.exceptions import RepositoryError, ChangesetDoesNotExistError
39 from rhodecode.lib.vcs.exceptions import RepositoryError, ChangesetDoesNotExistError,\
40 ChangesetError, NodeDoesNotExistError
40 from rhodecode.lib.utils2 import safe_int
41 from rhodecode.lib.utils2 import safe_int
41
42
42 log = logging.getLogger(__name__)
43 log = logging.getLogger(__name__)
43
44
44
45
45 class ChangelogController(BaseRepoController):
46 class ChangelogController(BaseRepoController):
46
47
47 def __before__(self):
48 def __before__(self):
48 super(ChangelogController, self).__before__()
49 super(ChangelogController, self).__before__()
49 c.affected_files_cut_off = 60
50 c.affected_files_cut_off = 60
50
51
51 def _graph(self, repo, revs_int, repo_size, size, p):
52 def _graph(self, repo, revs_int, repo_size, size, p):
52 """
53 """
53 Generates a DAG graph for repo
54 Generates a DAG graph for repo
54
55
55 :param repo:
56 :param repo:
56 :param revs_int:
57 :param revs_int:
57 :param repo_size:
58 :param repo_size:
58 :param size:
59 :param size:
59 :param p:
60 :param p:
60 """
61 """
61 if not revs_int:
62 if not revs_int:
62 c.jsdata = json.dumps([])
63 c.jsdata = json.dumps([])
63 return
64 return
64
65
65 data = []
66 data = []
66 revs = revs_int
67 revs = revs_int
67
68
68 dag = _dagwalker(repo, revs, repo.alias)
69 dag = _dagwalker(repo, revs, repo.alias)
69 dag = _colored(dag)
70 dag = _colored(dag)
70 for (id, type, ctx, vtx, edges) in dag:
71 for (id, type, ctx, vtx, edges) in dag:
71 data.append(['', vtx, edges])
72 data.append(['', vtx, edges])
72
73
73 c.jsdata = json.dumps(data)
74 c.jsdata = json.dumps(data)
74
75
75 @LoginRequired()
76 @LoginRequired()
76 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
77 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
77 'repository.admin')
78 'repository.admin')
78 def index(self):
79 def index(self, repo_name, revision=None, f_path=None):
79 limit = 100
80 limit = 100
80 default = 20
81 default = 20
81 if request.GET.get('size'):
82 if request.GET.get('size'):
82 c.size = max(min(safe_int(request.GET.get('size')), limit), 1)
83 c.size = max(min(safe_int(request.GET.get('size')), limit), 1)
83 session['changelog_size'] = c.size
84 session['changelog_size'] = c.size
84 session.save()
85 session.save()
85 else:
86 else:
86 c.size = int(session.get('changelog_size', default))
87 c.size = int(session.get('changelog_size', default))
87 # min size must be 1
88 # min size must be 1
88 c.size = max(c.size, 1)
89 c.size = max(c.size, 1)
89 p = safe_int(request.GET.get('page', 1), 1)
90 p = safe_int(request.GET.get('page', 1), 1)
90 branch_name = request.GET.get('branch', None)
91 branch_name = request.GET.get('branch', None)
92 c.changelog_for_path = f_path
91 try:
93 try:
94
95 if f_path:
96 log.debug('generating changelog for path %s' % f_path)
97 # get the history for the file !
98 tip_cs = c.rhodecode_repo.get_changeset()
99 try:
100 collection = tip_cs.get_file_history(f_path)
101 except (NodeDoesNotExistError, ChangesetError):
102 #this node is not present at tip !
103 try:
104 cs = self.__get_cs_or_redirect(revision, repo_name)
105 collection = cs.get_file_history(f_path)
106 except RepositoryError, e:
107 h.flash(str(e), category='warning')
108 redirect(h.url('changelog_home', repo_name=repo_name))
109 collection = list(reversed(collection))
110 else:
92 collection = c.rhodecode_repo.get_changesets(start=0,
111 collection = c.rhodecode_repo.get_changesets(start=0,
93 branch_name=branch_name)
112 branch_name=branch_name)
94 c.total_cs = len(collection)
113 c.total_cs = len(collection)
95
114
96 c.pagination = RepoPage(collection, page=p, item_count=c.total_cs,
115 c.pagination = RepoPage(collection, page=p, item_count=c.total_cs,
97 items_per_page=c.size, branch=branch_name)
116 items_per_page=c.size, branch=branch_name)
98 collection = list(c.pagination)
117 collection = list(c.pagination)
99 page_revisions = [x.raw_id for x in c.pagination]
118 page_revisions = [x.raw_id for x in c.pagination]
100 c.comments = c.rhodecode_db_repo.get_comments(page_revisions)
119 c.comments = c.rhodecode_db_repo.get_comments(page_revisions)
101 c.statuses = c.rhodecode_db_repo.statuses(page_revisions)
120 c.statuses = c.rhodecode_db_repo.statuses(page_revisions)
102 except (RepositoryError, ChangesetDoesNotExistError, Exception), e:
121 except (RepositoryError, ChangesetDoesNotExistError, Exception), e:
103 log.error(traceback.format_exc())
122 log.error(traceback.format_exc())
104 h.flash(str(e), category='error')
123 h.flash(str(e), category='error')
105 return redirect(url('changelog_home', repo_name=c.repo_name))
124 return redirect(url('changelog_home', repo_name=c.repo_name))
106
125
107 c.branch_name = branch_name
126 c.branch_name = branch_name
108 c.branch_filters = [('', _('All Branches'))] + \
127 c.branch_filters = [('', _('All Branches'))] + \
109 [(k, k) for k in c.rhodecode_repo.branches.keys()]
128 [(k, k) for k in c.rhodecode_repo.branches.keys()]
110
129 _revs = []
111 self._graph(c.rhodecode_repo, [x.revision for x in c.pagination],
130 if not f_path:
112 c.total_cs, c.size, p)
131 _revs = [x.revision for x in c.pagination]
132 self._graph(c.rhodecode_repo, _revs, c.total_cs, c.size, p)
113
133
114 return render('changelog/changelog.html')
134 return render('changelog/changelog.html')
115
135
116 @LoginRequired()
136 @LoginRequired()
117 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
137 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
118 'repository.admin')
138 'repository.admin')
119 def changelog_details(self, cs):
139 def changelog_details(self, cs):
120 if request.environ.get('HTTP_X_PARTIAL_XHR'):
140 if request.environ.get('HTTP_X_PARTIAL_XHR'):
121 c.cs = c.rhodecode_repo.get_changeset(cs)
141 c.cs = c.rhodecode_repo.get_changeset(cs)
122 return render('changelog/changelog_details.html')
142 return render('changelog/changelog_details.html')
@@ -1,274 +1,280 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2
2
3 <%inherit file="/base/base.html"/>
3 <%inherit file="/base/base.html"/>
4
4
5 <%def name="title()">
5 <%def name="title()">
6 ${_('%s Changelog') % c.repo_name} &middot; ${c.rhodecode_name}
6 ${_('%s Changelog') % c.repo_name} &middot; ${c.rhodecode_name}
7 </%def>
7 </%def>
8
8
9 <%def name="breadcrumbs_links()">
9 <%def name="breadcrumbs_links()">
10 <% size = c.size if c.size <= c.total_cs else c.total_cs %>
10 <% size = c.size if c.size <= c.total_cs else c.total_cs %>
11 ${_('Changelog')} - ${ungettext('showing %d out of %d revision', 'showing %d out of %d revisions', size) % (size, c.total_cs)}
11 ${_('Changelog')} - ${ungettext('showing %d out of %d revision', 'showing %d out of %d revisions', size) % (size, c.total_cs)}
12 </%def>
12 </%def>
13
13
14 <%def name="page_nav()">
14 <%def name="page_nav()">
15 ${self.menu('repositories')}
15 ${self.menu('repositories')}
16 </%def>
16 </%def>
17
17
18 <%def name="main()">
18 <%def name="main()">
19 ${self.context_bar('changelog')}
19 ${self.context_bar('changelog')}
20 <div class="box">
20 <div class="box">
21 <!-- box / title -->
21 <!-- box / title -->
22 <div class="title">
22 <div class="title">
23 ${self.breadcrumbs()}
23 ${self.breadcrumbs()}
24 </div>
24 </div>
25 <div class="table">
25 <div class="table">
26 % if c.pagination:
26 % if c.pagination:
27 <div id="graph">
27 <div id="graph">
28 <div style="display:${'none' if c.changelog_for_path else ''}">
28 <div class="info_box" style="clear: both;padding: 10px 6px;min-height: 12px;text-align: right;">
29 <div class="info_box" style="clear: both;padding: 10px 6px;min-height: 12px;text-align: right;">
29 <a href="#" class="ui-btn small" id="rev_range_container" style="display:none"></a>
30 <a href="#" class="ui-btn small" id="rev_range_container" style="display:none"></a>
30 <a href="#" class="ui-btn small" id="rev_range_clear" style="display:none">${_('Clear selection')}</a>
31 <a href="#" class="ui-btn small" id="rev_range_clear" style="display:none">${_('Clear selection')}</a>
31
32
32 %if c.rhodecode_db_repo.fork:
33 %if c.rhodecode_db_repo.fork:
33 <a id="compare_fork" title="${_('Compare fork with %s' % c.rhodecode_db_repo.fork.repo_name)}" href="${h.url('compare_url',repo_name=c.rhodecode_db_repo.fork.repo_name,org_ref_type='branch',org_ref='default',other_repo=c.repo_name,other_ref_type='branch',other_ref=request.GET.get('branch') or 'default',merge=1)}" class="ui-btn small">${_('Compare fork with parent')}</a>
34 <a id="compare_fork" title="${_('Compare fork with %s' % c.rhodecode_db_repo.fork.repo_name)}" href="${h.url('compare_url',repo_name=c.rhodecode_db_repo.fork.repo_name,org_ref_type='branch',org_ref='default',other_repo=c.repo_name,other_ref_type='branch',other_ref=request.GET.get('branch') or 'default',merge=1)}" class="ui-btn small">${_('Compare fork with parent')}</a>
34 %endif
35 %endif
35 %if h.is_hg(c.rhodecode_repo):
36 %if h.is_hg(c.rhodecode_repo):
36 <a id="open_new_pr" href="${h.url('pullrequest_home',repo_name=c.repo_name)}" class="ui-btn small">${_('Open new pull request')}</a>
37 <a id="open_new_pr" href="${h.url('pullrequest_home',repo_name=c.repo_name)}" class="ui-btn small">${_('Open new pull request')}</a>
37 %endif
38 %endif
38 </div>
39 </div>
39 <div class="container_header">
40 <div class="container_header">
40 ${h.form(h.url.current(),method='get')}
41 ${h.form(h.url.current(),method='get')}
41 <div style="float:left">
42 <div style="float:left">
42 ${h.submit('set',_('Show'),class_="ui-btn")}
43 ${h.submit('set',_('Show'),class_="ui-btn")}
43 ${h.text('size',size=1,value=c.size)}
44 ${h.text('size',size=1,value=c.size)}
44 ${_('revisions')}
45 ${_('revisions')}
45 </div>
46 </div>
46 ${h.end_form()}
47 ${h.end_form()}
47 <div style="float:right">${h.select('branch_filter',c.branch_name,c.branch_filters)}</div>
48 <div style="float:right">${h.select('branch_filter',c.branch_name,c.branch_filters)}</div>
48 </div>
49 </div>
50 </div>
49 <div id="graph_nodes">
51 <div id="graph_nodes">
50 <canvas id="graph_canvas"></canvas>
52 <canvas id="graph_canvas"></canvas>
51 </div>
53 </div>
52 <div id="graph_content">
54 <div id="graph_content">
53
55
54 <table id="changesets">
56 <table id="changesets">
55 <tbody>
57 <tbody>
56 %for cnt,cs in enumerate(c.pagination):
58 %for cnt,cs in enumerate(c.pagination):
57 <tr id="chg_${cnt+1}" class="container ${'tablerow%s' % (cnt%2)}">
59 <tr id="chg_${cnt+1}" class="container ${'tablerow%s' % (cnt%2)}">
58 <td class="checkbox">
60 <td class="checkbox">
61 %if c.changelog_for_path:
62 ${h.checkbox(cs.raw_id,class_="changeset_range", disabled="disabled")}
63 %else:
59 ${h.checkbox(cs.raw_id,class_="changeset_range")}
64 ${h.checkbox(cs.raw_id,class_="changeset_range")}
65 %endif
60 <td class="status">
66 <td class="status">
61 %if c.statuses.get(cs.raw_id):
67 %if c.statuses.get(cs.raw_id):
62 <div class="changeset-status-ico">
68 <div class="changeset-status-ico">
63 %if c.statuses.get(cs.raw_id)[2]:
69 %if c.statuses.get(cs.raw_id)[2]:
64 <a class="tooltip" title="${_('Click to open associated pull request #%s' % c.statuses.get(cs.raw_id)[2])}" href="${h.url('pullrequest_show',repo_name=c.statuses.get(cs.raw_id)[3],pull_request_id=c.statuses.get(cs.raw_id)[2])}">
70 <a class="tooltip" title="${_('Click to open associated pull request #%s' % c.statuses.get(cs.raw_id)[2])}" href="${h.url('pullrequest_show',repo_name=c.statuses.get(cs.raw_id)[3],pull_request_id=c.statuses.get(cs.raw_id)[2])}">
65 <img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" />
71 <img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" />
66 </a>
72 </a>
67 %else:
73 %else:
68 <img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" />
74 <img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" />
69 %endif
75 %endif
70 </div>
76 </div>
71 %endif
77 %endif
72 </td>
78 </td>
73 <td class="author">
79 <td class="author">
74 <img alt="gravatar" src="${h.gravatar_url(h.email_or_none(cs.author),16)}"/>
80 <img alt="gravatar" src="${h.gravatar_url(h.email_or_none(cs.author),16)}"/>
75 <span title="${cs.author}" class="user">${h.shorter(h.person(cs.author),22)}</span>
81 <span title="${cs.author}" class="user">${h.shorter(h.person(cs.author),22)}</span>
76 </td>
82 </td>
77 <td class="hash" style="width:${len(h.show_id(cs))*6.5}px">
83 <td class="hash" style="width:${len(h.show_id(cs))*6.5}px">
78 <a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id)}">
84 <a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id)}">
79 <span class="changeset_hash">${h.show_id(cs)}</span>
85 <span class="changeset_hash">${h.show_id(cs)}</span>
80 </a>
86 </a>
81 </td>
87 </td>
82 <td class="date">
88 <td class="date">
83 <div class="date">${h.age(cs.date,True)}</div>
89 <div class="date">${h.age(cs.date,True)}</div>
84 </td>
90 </td>
85 <td class="mid">
91 <td class="mid">
86 <div class="log-container">
92 <div class="log-container">
87 <div class="message">${h.urlify_commit(cs.message, c.repo_name,h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div>
93 <div class="message">${h.urlify_commit(cs.message, c.repo_name,h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div>
88 <div class="expand"><span class="expandtext">&darr; ${_('Show more')} &darr;</span></div>
94 <div class="expand"><span class="expandtext">&darr; ${_('Show more')} &darr;</span></div>
89 <div class="extra-container">
95 <div class="extra-container">
90 %if c.comments.get(cs.raw_id,[]):
96 %if c.comments.get(cs.raw_id,[]):
91 <div class="comments-container">
97 <div class="comments-container">
92 <div class="comments-cnt" title="${('comments')}">
98 <div class="comments-cnt" title="${('comments')}">
93 <a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id,anchor='comment-%s' % c.comments[cs.raw_id][0].comment_id)}">
99 <a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id,anchor='comment-%s' % c.comments[cs.raw_id][0].comment_id)}">
94 ${len(c.comments[cs.raw_id])}
100 ${len(c.comments[cs.raw_id])}
95 </a>
101 </a>
96 </div>
102 </div>
97 </div>
103 </div>
98 %endif
104 %endif
99 %if h.is_hg(c.rhodecode_repo):
105 %if h.is_hg(c.rhodecode_repo):
100 %for book in cs.bookmarks:
106 %for book in cs.bookmarks:
101 <div class="booktag" title="${_('Bookmark %s') % book}">
107 <div class="booktag" title="${_('Bookmark %s') % book}">
102 ${h.link_to(h.shorter(book),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
108 ${h.link_to(h.shorter(book),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
103 </div>
109 </div>
104 %endfor
110 %endfor
105 %endif
111 %endif
106 %for tag in cs.tags:
112 %for tag in cs.tags:
107 <div class="tagtag" title="${_('Tag %s') % tag}">
113 <div class="tagtag" title="${_('Tag %s') % tag}">
108 ${h.link_to(h.shorter(tag),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
114 ${h.link_to(h.shorter(tag),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
109 </div>
115 </div>
110 %endfor
116 %endfor
111 %if (not c.branch_name) and cs.branch:
117 %if (not c.branch_name) and cs.branch:
112 <div class="branchtag" title="${_('Branch %s' % cs.branch)}">
118 <div class="branchtag" title="${_('Branch %s' % cs.branch)}">
113 ${h.link_to(h.shorter(cs.branch),h.url('changelog_home',repo_name=c.repo_name,branch=cs.branch))}
119 ${h.link_to(h.shorter(cs.branch),h.url('changelog_home',repo_name=c.repo_name,branch=cs.branch))}
114 </div>
120 </div>
115 %endif
121 %endif
116 </div>
122 </div>
117 </div>
123 </div>
118 </td>
124 </td>
119 </tr>
125 </tr>
120 %endfor
126 %endfor
121 </tbody>
127 </tbody>
122 </table>
128 </table>
123
129
124 <div class="pagination-wh pagination-left">
130 <div class="pagination-wh pagination-left">
125 ${c.pagination.pager('$link_previous ~2~ $link_next')}
131 ${c.pagination.pager('$link_previous ~2~ $link_next')}
126 </div>
132 </div>
127 </div>
133 </div>
128 </div>
134 </div>
129
135
130 <script type="text/javascript" src="${h.url('/js/graph.js')}"></script>
136 <script type="text/javascript" src="${h.url('/js/graph.js')}"></script>
131 <script type="text/javascript">
137 <script type="text/javascript">
132 YAHOO.util.Event.onDOMReady(function(){
138 YAHOO.util.Event.onDOMReady(function(){
133
139
134 //Monitor range checkboxes and build a link to changesets
140 //Monitor range checkboxes and build a link to changesets
135 //ranges
141 //ranges
136 var checkboxes = YUD.getElementsByClassName('changeset_range');
142 var checkboxes = YUD.getElementsByClassName('changeset_range');
137 var url_tmpl = "${h.url('changeset_home',repo_name=c.repo_name,revision='__REVRANGE__')}";
143 var url_tmpl = "${h.url('changeset_home',repo_name=c.repo_name,revision='__REVRANGE__')}";
138 var pr_tmpl = "${h.url('pullrequest_home',repo_name=c.repo_name)}";
144 var pr_tmpl = "${h.url('pullrequest_home',repo_name=c.repo_name)}";
139
145
140 var checkbox_checker = function(e){
146 var checkbox_checker = function(e){
141 var checked_checkboxes = [];
147 var checked_checkboxes = [];
142 for (pos in checkboxes){
148 for (pos in checkboxes){
143 if(checkboxes[pos].checked){
149 if(checkboxes[pos].checked){
144 checked_checkboxes.push(checkboxes[pos]);
150 checked_checkboxes.push(checkboxes[pos]);
145 }
151 }
146 }
152 }
147 if(YUD.get('open_new_pr')){
153 if(YUD.get('open_new_pr')){
148 if(checked_checkboxes.length>1){
154 if(checked_checkboxes.length>1){
149 YUD.setStyle('open_new_pr','display','none');
155 YUD.setStyle('open_new_pr','display','none');
150 } else {
156 } else {
151 YUD.setStyle('open_new_pr','display','');
157 YUD.setStyle('open_new_pr','display','');
152 if(checked_checkboxes.length>0){
158 if(checked_checkboxes.length>0){
153 YUD.get('open_new_pr').innerHTML = _TM['Open new pull request for selected changesets'];
159 YUD.get('open_new_pr').innerHTML = _TM['Open new pull request for selected changesets'];
154 }else{
160 }else{
155 YUD.get('open_new_pr').innerHTML = _TM['Open new pull request'];
161 YUD.get('open_new_pr').innerHTML = _TM['Open new pull request'];
156 }
162 }
157 }
163 }
158 }
164 }
159
165
160 if(checked_checkboxes.length>0){
166 if(checked_checkboxes.length>0){
161 var rev_end = checked_checkboxes[0].name;
167 var rev_end = checked_checkboxes[0].name;
162 var rev_start = checked_checkboxes[checked_checkboxes.length-1].name;
168 var rev_start = checked_checkboxes[checked_checkboxes.length-1].name;
163 var url = url_tmpl.replace('__REVRANGE__',
169 var url = url_tmpl.replace('__REVRANGE__',
164 rev_start+'...'+rev_end);
170 rev_start+'...'+rev_end);
165
171
166 var link = (rev_start == rev_end)
172 var link = (rev_start == rev_end)
167 ? _TM['Show selected changeset __S']
173 ? _TM['Show selected changeset __S']
168 : _TM['Show selected changesets __S -> __E'];
174 : _TM['Show selected changesets __S -> __E'];
169
175
170 link = link.replace('__S',rev_start.substr(0,6));
176 link = link.replace('__S',rev_start.substr(0,6));
171 link = link.replace('__E',rev_end.substr(0,6));
177 link = link.replace('__E',rev_end.substr(0,6));
172 YUD.get('rev_range_container').href = url;
178 YUD.get('rev_range_container').href = url;
173 YUD.get('rev_range_container').innerHTML = link;
179 YUD.get('rev_range_container').innerHTML = link;
174 YUD.setStyle('rev_range_container','display','');
180 YUD.setStyle('rev_range_container','display','');
175 YUD.setStyle('rev_range_clear','display','');
181 YUD.setStyle('rev_range_clear','display','');
176
182
177 YUD.get('open_new_pr').href = pr_tmpl + '?rev_start={0}&rev_end={1}'.format(rev_start,rev_end);
183 YUD.get('open_new_pr').href = pr_tmpl + '?rev_start={0}&rev_end={1}'.format(rev_start,rev_end);
178 YUD.setStyle('compare_fork','display','none');
184 YUD.setStyle('compare_fork','display','none');
179 }else{
185 }else{
180 YUD.setStyle('rev_range_container','display','none');
186 YUD.setStyle('rev_range_container','display','none');
181 YUD.setStyle('rev_range_clear','display','none');
187 YUD.setStyle('rev_range_clear','display','none');
182 if (checkboxes){
188 if (checkboxes){
183 YUD.get('open_new_pr').href = pr_tmpl + '?rev_end={0}'.format(checkboxes[0].name);
189 YUD.get('open_new_pr').href = pr_tmpl + '?rev_end={0}'.format(checkboxes[0].name);
184 }
190 }
185 YUD.setStyle('compare_fork','display','');
191 YUD.setStyle('compare_fork','display','');
186 }
192 }
187 };
193 };
188 YUE.onDOMReady(checkbox_checker);
194 YUE.onDOMReady(checkbox_checker);
189 YUE.on(checkboxes,'click', checkbox_checker);
195 YUE.on(checkboxes,'click', checkbox_checker);
190
196
191 YUE.on('rev_range_clear','click',function(e){
197 YUE.on('rev_range_clear','click',function(e){
192 for (var i=0; i<checkboxes.length; i++){
198 for (var i=0; i<checkboxes.length; i++){
193 var cb = checkboxes[i];
199 var cb = checkboxes[i];
194 cb.checked = false;
200 cb.checked = false;
195 }
201 }
196 checkbox_checker();
202 checkbox_checker();
197 YUE.preventDefault(e);
203 YUE.preventDefault(e);
198 });
204 });
199
205
200 var msgs = YUQ('.message');
206 var msgs = YUQ('.message');
201 // get first element height
207 // get first element height
202 var el = YUQ('#graph_content .container')[0];
208 var el = YUQ('#graph_content .container')[0];
203 var row_h = el.clientHeight;
209 var row_h = el.clientHeight;
204 for(var i=0;i<msgs.length;i++){
210 for(var i=0;i<msgs.length;i++){
205 var m = msgs[i];
211 var m = msgs[i];
206
212
207 var h = m.clientHeight;
213 var h = m.clientHeight;
208 var pad = YUD.getStyle(m,'padding');
214 var pad = YUD.getStyle(m,'padding');
209 if(h > row_h){
215 if(h > row_h){
210 var offset = row_h - (h+12);
216 var offset = row_h - (h+12);
211 YUD.setStyle(m.nextElementSibling,'display','block');
217 YUD.setStyle(m.nextElementSibling,'display','block');
212 YUD.setStyle(m.nextElementSibling,'margin-top',offset+'px');
218 YUD.setStyle(m.nextElementSibling,'margin-top',offset+'px');
213 };
219 };
214 }
220 }
215 YUE.on(YUQ('.expand'),'click',function(e){
221 YUE.on(YUQ('.expand'),'click',function(e){
216 var elem = e.currentTarget.parentNode.parentNode;
222 var elem = e.currentTarget.parentNode.parentNode;
217 YUD.setStyle(e.currentTarget,'display','none');
223 YUD.setStyle(e.currentTarget,'display','none');
218 YUD.setStyle(elem,'height','auto');
224 YUD.setStyle(elem,'height','auto');
219
225
220 //redraw the graph, line_count and jsdata are global vars
226 //redraw the graph, line_count and jsdata are global vars
221 set_canvas(100);
227 set_canvas(100);
222
228
223 var r = new BranchRenderer();
229 var r = new BranchRenderer();
224 r.render(jsdata,100,line_count);
230 r.render(jsdata,100,line_count);
225
231
226 });
232 });
227
233
228 // change branch filter
234 // change branch filter
229 YUE.on(YUD.get('branch_filter'),'change',function(e){
235 YUE.on(YUD.get('branch_filter'),'change',function(e){
230 var selected_branch = e.currentTarget.options[e.currentTarget.selectedIndex].value;
236 var selected_branch = e.currentTarget.options[e.currentTarget.selectedIndex].value;
231 var url_main = "${h.url('changelog_home',repo_name=c.repo_name)}";
237 var url_main = "${h.url('changelog_home',repo_name=c.repo_name)}";
232 var url = "${h.url('changelog_home',repo_name=c.repo_name,branch='__BRANCH__')}";
238 var url = "${h.url('changelog_home',repo_name=c.repo_name,branch='__BRANCH__')}";
233 var url = url.replace('__BRANCH__',selected_branch);
239 var url = url.replace('__BRANCH__',selected_branch);
234 if(selected_branch != ''){
240 if(selected_branch != ''){
235 window.location = url;
241 window.location = url;
236 }else{
242 }else{
237 window.location = url_main;
243 window.location = url_main;
238 }
244 }
239
245
240 });
246 });
241
247
242 function set_canvas(width) {
248 function set_canvas(width) {
243 var c = document.getElementById('graph_nodes');
249 var c = document.getElementById('graph_nodes');
244 var t = document.getElementById('graph_content');
250 var t = document.getElementById('graph_content');
245 canvas = document.getElementById('graph_canvas');
251 canvas = document.getElementById('graph_canvas');
246 var div_h = t.clientHeight;
252 var div_h = t.clientHeight;
247 canvas.setAttribute('height',div_h);
253 canvas.setAttribute('height',div_h);
248 canvas.setAttribute('width',width);
254 canvas.setAttribute('width',width);
249 };
255 };
250 var heads = 1;
256 var heads = 1;
251 var line_count = 0;
257 var line_count = 0;
252 var jsdata = ${c.jsdata|n};
258 var jsdata = ${c.jsdata|n};
253
259
254 for (var i=0;i<jsdata.length;i++) {
260 for (var i=0;i<jsdata.length;i++) {
255 var in_l = jsdata[i][2];
261 var in_l = jsdata[i][2];
256 for (var j in in_l) {
262 for (var j in in_l) {
257 var m = in_l[j][1];
263 var m = in_l[j][1];
258 if (m > line_count)
264 if (m > line_count)
259 line_count = m;
265 line_count = m;
260 }
266 }
261 }
267 }
262 set_canvas(100);
268 set_canvas(100);
263
269
264 var r = new BranchRenderer();
270 var r = new BranchRenderer();
265 r.render(jsdata,100,line_count);
271 r.render(jsdata,100,line_count);
266
272
267 });
273 });
268 </script>
274 </script>
269 %else:
275 %else:
270 ${_('There are no changes yet')}
276 ${_('There are no changes yet')}
271 %endif
277 %endif
272 </div>
278 </div>
273 </div>
279 </div>
274 </%def>
280 </%def>
@@ -1,26 +1,26 b''
1 <dl>
1 <dl>
2 <dt class="file_history">${_('History')}</dt>
2 <dt class="file_history">${_('History')}</dt>
3 <dd>
3 <dd>
4 <div>
4 <div>
5 <div style="float:left">
5 <div style="float:left">
6 ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')}
6 ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='get')}
7 ${h.hidden('diff2',c.file_changeset.raw_id)}
7 ${h.hidden('diff2',c.file_changeset.raw_id)}
8 ${h.select('diff1',c.file_changeset.raw_id,c.file_history)}
8 ${h.select('diff1',c.file_changeset.raw_id,c.file_history)}
9 ${h.submit('diff',_('Diff to revision'),class_="ui-btn")}
9 ${h.submit('diff',_('Diff to revision'),class_="ui-btn")}
10 ${h.submit('show_rev',_('Show at revision'),class_="ui-btn")}
10 ${h.submit('show_rev',_('Show at revision'),class_="ui-btn")}
11 ${h.link_to(_('Show full history'),h.url('shortlog_file_home',repo_name=c.repo_name, revision=c.file_changeset.raw_id, f_path=c.f_path),class_="ui-btn")}
11 ${h.link_to(_('Show full history'),h.url('changelog_file_home',repo_name=c.repo_name, revision=c.file_changeset.raw_id, f_path=c.f_path),class_="ui-btn")}
12 ${h.hidden('annotate', c.annotate)}
12 ${h.hidden('annotate', c.annotate)}
13 ${h.end_form()}
13 ${h.end_form()}
14 </div>
14 </div>
15 <div class="file_author">
15 <div class="file_author">
16 <div class="item">${h.literal(ungettext(u'%s author',u'%s authors',len(c.authors)) % ('<b>%s</b>' % len(c.authors))) }</div>
16 <div class="item">${h.literal(ungettext(u'%s author',u'%s authors',len(c.authors)) % ('<b>%s</b>' % len(c.authors))) }</div>
17 %for email, user in c.authors:
17 %for email, user in c.authors:
18 <div class="contributor tooltip" style="float:left" title="${h.tooltip(user)}">
18 <div class="contributor tooltip" style="float:left" title="${h.tooltip(user)}">
19 <div class="gravatar" style="margin:1px"><img alt="gravatar" src="${h.gravatar_url(email, 20)}"/> </div>
19 <div class="gravatar" style="margin:1px"><img alt="gravatar" src="${h.gravatar_url(email, 20)}"/> </div>
20 </div>
20 </div>
21 %endfor
21 %endfor
22 </div>
22 </div>
23 </div>
23 </div>
24 <div style="clear:both"></div>
24 <div style="clear:both"></div>
25 </dd>
25 </dd>
26 </dl>
26 </dl>
@@ -1,126 +1,175 b''
1 from rhodecode.tests import *
1 from rhodecode.tests import *
2
2
3
3
4 class TestChangelogController(TestController):
4 class TestChangelogController(TestController):
5
5
6 def test_index_hg(self):
6 def test_index_hg(self):
7 self.log_user()
7 self.log_user()
8 response = self.app.get(url(controller='changelog', action='index',
8 response = self.app.get(url(controller='changelog', action='index',
9 repo_name=HG_REPO))
9 repo_name=HG_REPO))
10
10
11 response.mustcontain('''id="chg_20" class="container tablerow1"''')
11 response.mustcontain('''id="chg_20" class="container tablerow1"''')
12 response.mustcontain(
12 response.mustcontain(
13 """<input class="changeset_range" """
13 """<input class="changeset_range" """
14 """id="5e204e7583b9c8e7b93a020bd036564b1e731dae" """
14 """id="5e204e7583b9c8e7b93a020bd036564b1e731dae" """
15 """name="5e204e7583b9c8e7b93a020bd036564b1e731dae" """
15 """name="5e204e7583b9c8e7b93a020bd036564b1e731dae" """
16 """type="checkbox" value="1" />"""
16 """type="checkbox" value="1" />"""
17 )
17 )
18
18
19 response.mustcontain(
19 response.mustcontain(
20 """<span class="changeset_hash">r154:5e204e7583b9</span>"""
20 """<span class="changeset_hash">r154:5e204e7583b9</span>"""
21 )
21 )
22
22
23 response.mustcontain("""Small update at simplevcs app""")
23 response.mustcontain("""Small update at simplevcs app""")
24
24
25 # response.mustcontain(
25 # response.mustcontain(
26 # """<div id="changed_total_5e204e7583b9c8e7b93a020bd036564b1e731dae" """
26 # """<div id="changed_total_5e204e7583b9c8e7b93a020bd036564b1e731dae" """
27 # """style="float:right;" class="changed_total tooltip" """
27 # """style="float:right;" class="changed_total tooltip" """
28 # """title="Affected number of files, click to show """
28 # """title="Affected number of files, click to show """
29 # """more details">3</div>"""
29 # """more details">3</div>"""
30 # )
30 # )
31
31
32 def test_index_pagination_hg(self):
32 def test_index_pagination_hg(self):
33 self.log_user()
33 self.log_user()
34 #pagination
34 #pagination
35 self.app.get(url(controller='changelog', action='index',
35 self.app.get(url(controller='changelog', action='index',
36 repo_name=HG_REPO), {'page': 1})
36 repo_name=HG_REPO), {'page': 1})
37 self.app.get(url(controller='changelog', action='index',
37 self.app.get(url(controller='changelog', action='index',
38 repo_name=HG_REPO), {'page': 2})
38 repo_name=HG_REPO), {'page': 2})
39 self.app.get(url(controller='changelog', action='index',
39 self.app.get(url(controller='changelog', action='index',
40 repo_name=HG_REPO), {'page': 3})
40 repo_name=HG_REPO), {'page': 3})
41 self.app.get(url(controller='changelog', action='index',
41 self.app.get(url(controller='changelog', action='index',
42 repo_name=HG_REPO), {'page': 4})
42 repo_name=HG_REPO), {'page': 4})
43 self.app.get(url(controller='changelog', action='index',
43 self.app.get(url(controller='changelog', action='index',
44 repo_name=HG_REPO), {'page': 5})
44 repo_name=HG_REPO), {'page': 5})
45 response = self.app.get(url(controller='changelog', action='index',
45 response = self.app.get(url(controller='changelog', action='index',
46 repo_name=HG_REPO), {'page': 6})
46 repo_name=HG_REPO), {'page': 6})
47
47
48 # Test response after pagination...
48 # Test response after pagination...
49 response.mustcontain(
49 response.mustcontain(
50 """<input class="changeset_range" """
50 """<input class="changeset_range" """
51 """id="46ad32a4f974e45472a898c6b0acb600320579b1" """
51 """id="46ad32a4f974e45472a898c6b0acb600320579b1" """
52 """name="46ad32a4f974e45472a898c6b0acb600320579b1" """
52 """name="46ad32a4f974e45472a898c6b0acb600320579b1" """
53 """type="checkbox" value="1" />"""
53 """type="checkbox" value="1" />"""
54 )
54 )
55
55
56 response.mustcontain(
56 response.mustcontain(
57 """<span class="changeset_hash">r64:46ad32a4f974</span>"""
57 """<span class="changeset_hash">r64:46ad32a4f974</span>"""
58 )
58 )
59
59
60 # response.mustcontain(
60 # response.mustcontain(
61 # """<div id="changed_total_46ad32a4f974e45472a898c6b0acb600320579b1" """
61 # """<div id="changed_total_46ad32a4f974e45472a898c6b0acb600320579b1" """
62 # """style="float:right;" class="changed_total tooltip" """
62 # """style="float:right;" class="changed_total tooltip" """
63 # """title="Affected number of files, click to show """
63 # """title="Affected number of files, click to show """
64 # """more details">21</div>"""
64 # """more details">21</div>"""
65 # )
65 # )
66 #
66 #
67 # response.mustcontain(
67 # response.mustcontain(
68 # """<a href="/%s/changeset/"""
68 # """<a href="/%s/changeset/"""
69 # """46ad32a4f974e45472a898c6b0acb600320579b1" """
69 # """46ad32a4f974e45472a898c6b0acb600320579b1" """
70 # """title="Merge with 2e6a2bf9356ca56df08807f4ad86d480da72a8f4">"""
70 # """title="Merge with 2e6a2bf9356ca56df08807f4ad86d480da72a8f4">"""
71 # """46ad32a4f974</a>""" % HG_REPO
71 # """46ad32a4f974</a>""" % HG_REPO
72 # )
72 # )
73
73
74 def test_index_git(self):
74 def test_index_git(self):
75 self.log_user()
75 self.log_user()
76 response = self.app.get(url(controller='changelog', action='index',
76 response = self.app.get(url(controller='changelog', action='index',
77 repo_name=GIT_REPO))
77 repo_name=GIT_REPO))
78
78
79 response.mustcontain('''id="chg_20" class="container tablerow1"''')
79 response.mustcontain('''id="chg_20" class="container tablerow1"''')
80 response.mustcontain(
80 response.mustcontain(
81 """<input class="changeset_range" """
81 """<input class="changeset_range" """
82 """id="95f9a91d775b0084b2368ae7779e44931c849c0e" """
82 """id="95f9a91d775b0084b2368ae7779e44931c849c0e" """
83 """name="95f9a91d775b0084b2368ae7779e44931c849c0e" """
83 """name="95f9a91d775b0084b2368ae7779e44931c849c0e" """
84 """type="checkbox" value="1" />"""
84 """type="checkbox" value="1" />"""
85 )
85 )
86
86
87 response.mustcontain(
87 response.mustcontain(
88 """<span class="changeset_hash">r613:95f9a91d775b</span>"""
88 """<span class="changeset_hash">r613:95f9a91d775b</span>"""
89 )
89 )
90
90
91 response.mustcontain("""fixing stupid typo in context for mercurial""")
91 response.mustcontain("""fixing stupid typo in context for mercurial""")
92
92
93 # response.mustcontain(
93 # response.mustcontain(
94 # """<div id="changed_total_5e204e7583b9c8e7b93a020bd036564b1e731dae" """
94 # """<div id="changed_total_5e204e7583b9c8e7b93a020bd036564b1e731dae" """
95 # """style="float:right;" class="changed_total tooltip" """
95 # """style="float:right;" class="changed_total tooltip" """
96 # """title="Affected number of files, click to show """
96 # """title="Affected number of files, click to show """
97 # """more details">3</div>"""
97 # """more details">3</div>"""
98 # )
98 # )
99
99
100 def test_index_pagination_git(self):
100 def test_index_pagination_git(self):
101 self.log_user()
101 self.log_user()
102 #pagination
102 #pagination
103 self.app.get(url(controller='changelog', action='index',
103 self.app.get(url(controller='changelog', action='index',
104 repo_name=GIT_REPO), {'page': 1})
104 repo_name=GIT_REPO), {'page': 1})
105 self.app.get(url(controller='changelog', action='index',
105 self.app.get(url(controller='changelog', action='index',
106 repo_name=GIT_REPO), {'page': 2})
106 repo_name=GIT_REPO), {'page': 2})
107 self.app.get(url(controller='changelog', action='index',
107 self.app.get(url(controller='changelog', action='index',
108 repo_name=GIT_REPO), {'page': 3})
108 repo_name=GIT_REPO), {'page': 3})
109 self.app.get(url(controller='changelog', action='index',
109 self.app.get(url(controller='changelog', action='index',
110 repo_name=GIT_REPO), {'page': 4})
110 repo_name=GIT_REPO), {'page': 4})
111 self.app.get(url(controller='changelog', action='index',
111 self.app.get(url(controller='changelog', action='index',
112 repo_name=GIT_REPO), {'page': 5})
112 repo_name=GIT_REPO), {'page': 5})
113 response = self.app.get(url(controller='changelog', action='index',
113 response = self.app.get(url(controller='changelog', action='index',
114 repo_name=GIT_REPO), {'page': 6})
114 repo_name=GIT_REPO), {'page': 6})
115
115
116 # Test response after pagination...
116 # Test response after pagination...
117 response.mustcontain(
117 response.mustcontain(
118 """<input class="changeset_range" """
118 """<input class="changeset_range" """
119 """id="636ed213f2f11ef91071b9c24f2d5e6bd01a6ed5" """
119 """id="636ed213f2f11ef91071b9c24f2d5e6bd01a6ed5" """
120 """name="636ed213f2f11ef91071b9c24f2d5e6bd01a6ed5" """
120 """name="636ed213f2f11ef91071b9c24f2d5e6bd01a6ed5" """
121 """type="checkbox" value="1" />"""
121 """type="checkbox" value="1" />"""
122 )
122 )
123
123
124 response.mustcontain(
124 response.mustcontain(
125 """<span class="changeset_hash">r515:636ed213f2f1</span>"""
125 """<span class="changeset_hash">r515:636ed213f2f1</span>"""
126 )
126 )
127
128 def test_index_hg_with_filenode(self):
129 self.log_user()
130 response = self.app.get(url(controller='changelog', action='index',
131 revision='tip', f_path='/vcs/exceptions.py',
132 repo_name=HG_REPO))
133 #history commits messages
134 response.mustcontain('Added exceptions module, this time for real')
135 response.mustcontain('Added not implemented hg backend test case')
136 response.mustcontain('Added BaseChangeset class')
137 # Test response...
138
139 def test_index_git_with_filenode(self):
140 self.log_user()
141 response = self.app.get(url(controller='changelog', action='index',
142 revision='tip', f_path='/vcs/exceptions.py',
143 repo_name=GIT_REPO))
144 #history commits messages
145 response.mustcontain('Added exceptions module, this time for real')
146 response.mustcontain('Added not implemented hg backend test case')
147 response.mustcontain('Added BaseChangeset class')
148
149 def test_index_hg_with_filenode_that_is_dirnode(self):
150 self.log_user()
151 response = self.app.get(url(controller='changelog', action='index',
152 revision='tip', f_path='/tests',
153 repo_name=HG_REPO))
154 self.assertEqual(response.status, '302 Found')
155
156 def test_index_git_with_filenode_that_is_dirnode(self):
157 self.log_user()
158 response = self.app.get(url(controller='changelog', action='index',
159 revision='tip', f_path='/tests',
160 repo_name=GIT_REPO))
161 self.assertEqual(response.status, '302 Found')
162
163 def test_index_hg_with_filenode_not_existing(self):
164 self.log_user()
165 response = self.app.get(url(controller='changelog', action='index',
166 revision='tip', f_path='/wrong_path',
167 repo_name=HG_REPO))
168 self.assertEqual(response.status, '302 Found')
169
170 def test_index_git_with_filenode_not_existing(self):
171 self.log_user()
172 response = self.app.get(url(controller='changelog', action='index',
173 revision='tip', f_path='/wrong_path',
174 repo_name=GIT_REPO))
175 self.assertEqual(response.status, '302 Found')
@@ -1,65 +1,16 b''
1 from rhodecode.tests import *
1 from rhodecode.tests import *
2
2
3
3
4 class TestShortlogController(TestController):
4 class TestShortlogController(TestController):
5
5
6 def test_index_hg(self):
6 def test_index_hg(self):
7 self.log_user()
7 self.log_user()
8 response = self.app.get(url(controller='shortlog', action='index',
8 response = self.app.get(url(controller='shortlog', action='index',
9 repo_name=HG_REPO))
9 repo_name=HG_REPO))
10 # Test response...
10 # Test response...
11
11
12 def test_index_git(self):
12 def test_index_git(self):
13 self.log_user()
13 self.log_user()
14 response = self.app.get(url(controller='shortlog', action='index',
14 response = self.app.get(url(controller='shortlog', action='index',
15 repo_name=GIT_REPO))
15 repo_name=GIT_REPO))
16 # Test response...
16 # Test response...
17
18 def test_index_hg_with_filenode(self):
19 self.log_user()
20 response = self.app.get(url(controller='shortlog', action='index',
21 revision='tip', f_path='/vcs/exceptions.py',
22 repo_name=HG_REPO))
23 #history commits messages
24 response.mustcontain('Added exceptions module, this time for real')
25 response.mustcontain('Added not implemented hg backend test case')
26 response.mustcontain('Added BaseChangeset class')
27 # Test response...
28
29 def test_index_git_with_filenode(self):
30 self.log_user()
31 response = self.app.get(url(controller='shortlog', action='index',
32 revision='tip', f_path='/vcs/exceptions.py',
33 repo_name=GIT_REPO))
34 #history commits messages
35 response.mustcontain('Added exceptions module, this time for real')
36 response.mustcontain('Added not implemented hg backend test case')
37 response.mustcontain('Added BaseChangeset class')
38
39 def test_index_hg_with_filenode_that_is_dirnode(self):
40 self.log_user()
41 response = self.app.get(url(controller='shortlog', action='index',
42 revision='tip', f_path='/tests',
43 repo_name=HG_REPO))
44 self.assertEqual(response.status, '302 Found')
45
46 def test_index_git_with_filenode_that_is_dirnode(self):
47 self.log_user()
48 response = self.app.get(url(controller='shortlog', action='index',
49 revision='tip', f_path='/tests',
50 repo_name=GIT_REPO))
51 self.assertEqual(response.status, '302 Found')
52
53 def test_index_hg_with_filenode_not_existing(self):
54 self.log_user()
55 response = self.app.get(url(controller='shortlog', action='index',
56 revision='tip', f_path='/wrong_path',
57 repo_name=HG_REPO))
58 self.assertEqual(response.status, '302 Found')
59
60 def test_index_git_with_filenode_not_existing(self):
61 self.log_user()
62 response = self.app.get(url(controller='shortlog', action='index',
63 revision='tip', f_path='/wrong_path',
64 repo_name=GIT_REPO))
65 self.assertEqual(response.status, '302 Found')
General Comments 0
You need to be logged in to leave comments. Login now