##// END OF EJS Templates
Rewrote url routes to make all validations and parsing for compare view + added compare fork button into forked repos
marcink -
r2363:745dda78 codereview
parent child Browse files
Show More
@@ -1,521 +1,523 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 try:
35 try:
36 by_id = repo_name.split('_')
36 by_id = repo_name.split('_')
37 if len(by_id) == 2 and by_id[1].isdigit():
37 if len(by_id) == 2 and by_id[1].isdigit():
38 repo_name = Repository.get(by_id[1]).repo_name
38 repo_name = Repository.get(by_id[1]).repo_name
39 match_dict['repo_name'] = repo_name
39 match_dict['repo_name'] = repo_name
40 except:
40 except:
41 pass
41 pass
42
42
43 return is_valid_repo(repo_name, config['base_path'])
43 return is_valid_repo(repo_name, config['base_path'])
44
44
45 def check_group(environ, match_dict):
45 def check_group(environ, match_dict):
46 """
46 """
47 check for valid repositories group for proper 404 handling
47 check for valid repositories group for proper 404 handling
48
48
49 :param environ:
49 :param environ:
50 :param match_dict:
50 :param match_dict:
51 """
51 """
52 repos_group_name = match_dict.get('group_name')
52 repos_group_name = match_dict.get('group_name')
53
53
54 return is_valid_repos_group(repos_group_name, config['base_path'])
54 return is_valid_repos_group(repos_group_name, config['base_path'])
55
55
56 def check_int(environ, match_dict):
56 def check_int(environ, match_dict):
57 return match_dict.get('id').isdigit()
57 return match_dict.get('id').isdigit()
58
58
59 # The ErrorController route (handles 404/500 error pages); it should
59 # The ErrorController route (handles 404/500 error pages); it should
60 # likely stay at the top, ensuring it can always be resolved
60 # likely stay at the top, ensuring it can always be resolved
61 rmap.connect('/error/{action}', controller='error')
61 rmap.connect('/error/{action}', controller='error')
62 rmap.connect('/error/{action}/{id}', controller='error')
62 rmap.connect('/error/{action}/{id}', controller='error')
63
63
64 #==========================================================================
64 #==========================================================================
65 # CUSTOM ROUTES HERE
65 # CUSTOM ROUTES HERE
66 #==========================================================================
66 #==========================================================================
67
67
68 #MAIN PAGE
68 #MAIN PAGE
69 rmap.connect('home', '/', controller='home', action='index')
69 rmap.connect('home', '/', controller='home', action='index')
70 rmap.connect('repo_switcher', '/repos', controller='home',
70 rmap.connect('repo_switcher', '/repos', controller='home',
71 action='repo_switcher')
71 action='repo_switcher')
72 rmap.connect('branch_tag_switcher', '/branches-tags/{repo_name:.*}',
72 rmap.connect('branch_tag_switcher', '/branches-tags/{repo_name:.*}',
73 controller='home', action='branch_tag_switcher')
73 controller='home', action='branch_tag_switcher')
74 rmap.connect('bugtracker',
74 rmap.connect('bugtracker',
75 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
75 "http://bitbucket.org/marcinkuzminski/rhodecode/issues",
76 _static=True)
76 _static=True)
77 rmap.connect('rst_help',
77 rmap.connect('rst_help',
78 "http://docutils.sourceforge.net/docs/user/rst/quickref.html",
78 "http://docutils.sourceforge.net/docs/user/rst/quickref.html",
79 _static=True)
79 _static=True)
80 rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
80 rmap.connect('rhodecode_official', "http://rhodecode.org", _static=True)
81
81
82 #ADMIN REPOSITORY REST ROUTES
82 #ADMIN REPOSITORY REST ROUTES
83 with rmap.submapper(path_prefix=ADMIN_PREFIX,
83 with rmap.submapper(path_prefix=ADMIN_PREFIX,
84 controller='admin/repos') as m:
84 controller='admin/repos') as m:
85 m.connect("repos", "/repos",
85 m.connect("repos", "/repos",
86 action="create", conditions=dict(method=["POST"]))
86 action="create", conditions=dict(method=["POST"]))
87 m.connect("repos", "/repos",
87 m.connect("repos", "/repos",
88 action="index", conditions=dict(method=["GET"]))
88 action="index", conditions=dict(method=["GET"]))
89 m.connect("formatted_repos", "/repos.{format}",
89 m.connect("formatted_repos", "/repos.{format}",
90 action="index",
90 action="index",
91 conditions=dict(method=["GET"]))
91 conditions=dict(method=["GET"]))
92 m.connect("new_repo", "/repos/new",
92 m.connect("new_repo", "/repos/new",
93 action="new", conditions=dict(method=["GET"]))
93 action="new", conditions=dict(method=["GET"]))
94 m.connect("formatted_new_repo", "/repos/new.{format}",
94 m.connect("formatted_new_repo", "/repos/new.{format}",
95 action="new", conditions=dict(method=["GET"]))
95 action="new", conditions=dict(method=["GET"]))
96 m.connect("/repos/{repo_name:.*}",
96 m.connect("/repos/{repo_name:.*}",
97 action="update", conditions=dict(method=["PUT"],
97 action="update", conditions=dict(method=["PUT"],
98 function=check_repo))
98 function=check_repo))
99 m.connect("/repos/{repo_name:.*}",
99 m.connect("/repos/{repo_name:.*}",
100 action="delete", conditions=dict(method=["DELETE"],
100 action="delete", conditions=dict(method=["DELETE"],
101 function=check_repo))
101 function=check_repo))
102 m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
102 m.connect("edit_repo", "/repos/{repo_name:.*}/edit",
103 action="edit", conditions=dict(method=["GET"],
103 action="edit", conditions=dict(method=["GET"],
104 function=check_repo))
104 function=check_repo))
105 m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
105 m.connect("formatted_edit_repo", "/repos/{repo_name:.*}.{format}/edit",
106 action="edit", conditions=dict(method=["GET"],
106 action="edit", conditions=dict(method=["GET"],
107 function=check_repo))
107 function=check_repo))
108 m.connect("repo", "/repos/{repo_name:.*}",
108 m.connect("repo", "/repos/{repo_name:.*}",
109 action="show", conditions=dict(method=["GET"],
109 action="show", conditions=dict(method=["GET"],
110 function=check_repo))
110 function=check_repo))
111 m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
111 m.connect("formatted_repo", "/repos/{repo_name:.*}.{format}",
112 action="show", conditions=dict(method=["GET"],
112 action="show", conditions=dict(method=["GET"],
113 function=check_repo))
113 function=check_repo))
114 #ajax delete repo perm user
114 #ajax delete repo perm user
115 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
115 m.connect('delete_repo_user', "/repos_delete_user/{repo_name:.*}",
116 action="delete_perm_user",
116 action="delete_perm_user",
117 conditions=dict(method=["DELETE"], function=check_repo))
117 conditions=dict(method=["DELETE"], function=check_repo))
118
118
119 #ajax delete repo perm users_group
119 #ajax delete repo perm users_group
120 m.connect('delete_repo_users_group',
120 m.connect('delete_repo_users_group',
121 "/repos_delete_users_group/{repo_name:.*}",
121 "/repos_delete_users_group/{repo_name:.*}",
122 action="delete_perm_users_group",
122 action="delete_perm_users_group",
123 conditions=dict(method=["DELETE"], function=check_repo))
123 conditions=dict(method=["DELETE"], function=check_repo))
124
124
125 #settings actions
125 #settings actions
126 m.connect('repo_stats', "/repos_stats/{repo_name:.*}",
126 m.connect('repo_stats', "/repos_stats/{repo_name:.*}",
127 action="repo_stats", conditions=dict(method=["DELETE"],
127 action="repo_stats", conditions=dict(method=["DELETE"],
128 function=check_repo))
128 function=check_repo))
129 m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
129 m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
130 action="repo_cache", conditions=dict(method=["DELETE"],
130 action="repo_cache", conditions=dict(method=["DELETE"],
131 function=check_repo))
131 function=check_repo))
132 m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*}",
132 m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*}",
133 action="repo_public_journal", conditions=dict(method=["PUT"],
133 action="repo_public_journal", conditions=dict(method=["PUT"],
134 function=check_repo))
134 function=check_repo))
135 m.connect('repo_pull', "/repo_pull/{repo_name:.*}",
135 m.connect('repo_pull', "/repo_pull/{repo_name:.*}",
136 action="repo_pull", conditions=dict(method=["PUT"],
136 action="repo_pull", conditions=dict(method=["PUT"],
137 function=check_repo))
137 function=check_repo))
138 m.connect('repo_as_fork', "/repo_as_fork/{repo_name:.*}",
138 m.connect('repo_as_fork', "/repo_as_fork/{repo_name:.*}",
139 action="repo_as_fork", conditions=dict(method=["PUT"],
139 action="repo_as_fork", conditions=dict(method=["PUT"],
140 function=check_repo))
140 function=check_repo))
141
141
142 with rmap.submapper(path_prefix=ADMIN_PREFIX,
142 with rmap.submapper(path_prefix=ADMIN_PREFIX,
143 controller='admin/repos_groups') as m:
143 controller='admin/repos_groups') as m:
144 m.connect("repos_groups", "/repos_groups",
144 m.connect("repos_groups", "/repos_groups",
145 action="create", conditions=dict(method=["POST"]))
145 action="create", conditions=dict(method=["POST"]))
146 m.connect("repos_groups", "/repos_groups",
146 m.connect("repos_groups", "/repos_groups",
147 action="index", conditions=dict(method=["GET"]))
147 action="index", conditions=dict(method=["GET"]))
148 m.connect("formatted_repos_groups", "/repos_groups.{format}",
148 m.connect("formatted_repos_groups", "/repos_groups.{format}",
149 action="index", conditions=dict(method=["GET"]))
149 action="index", conditions=dict(method=["GET"]))
150 m.connect("new_repos_group", "/repos_groups/new",
150 m.connect("new_repos_group", "/repos_groups/new",
151 action="new", conditions=dict(method=["GET"]))
151 action="new", conditions=dict(method=["GET"]))
152 m.connect("formatted_new_repos_group", "/repos_groups/new.{format}",
152 m.connect("formatted_new_repos_group", "/repos_groups/new.{format}",
153 action="new", conditions=dict(method=["GET"]))
153 action="new", conditions=dict(method=["GET"]))
154 m.connect("update_repos_group", "/repos_groups/{id}",
154 m.connect("update_repos_group", "/repos_groups/{id}",
155 action="update", conditions=dict(method=["PUT"],
155 action="update", conditions=dict(method=["PUT"],
156 function=check_int))
156 function=check_int))
157 m.connect("delete_repos_group", "/repos_groups/{id}",
157 m.connect("delete_repos_group", "/repos_groups/{id}",
158 action="delete", conditions=dict(method=["DELETE"],
158 action="delete", conditions=dict(method=["DELETE"],
159 function=check_int))
159 function=check_int))
160 m.connect("edit_repos_group", "/repos_groups/{id}/edit",
160 m.connect("edit_repos_group", "/repos_groups/{id}/edit",
161 action="edit", conditions=dict(method=["GET"],
161 action="edit", conditions=dict(method=["GET"],
162 function=check_int))
162 function=check_int))
163 m.connect("formatted_edit_repos_group",
163 m.connect("formatted_edit_repos_group",
164 "/repos_groups/{id}.{format}/edit",
164 "/repos_groups/{id}.{format}/edit",
165 action="edit", conditions=dict(method=["GET"],
165 action="edit", conditions=dict(method=["GET"],
166 function=check_int))
166 function=check_int))
167 m.connect("repos_group", "/repos_groups/{id}",
167 m.connect("repos_group", "/repos_groups/{id}",
168 action="show", conditions=dict(method=["GET"],
168 action="show", conditions=dict(method=["GET"],
169 function=check_int))
169 function=check_int))
170 m.connect("formatted_repos_group", "/repos_groups/{id}.{format}",
170 m.connect("formatted_repos_group", "/repos_groups/{id}.{format}",
171 action="show", conditions=dict(method=["GET"],
171 action="show", conditions=dict(method=["GET"],
172 function=check_int))
172 function=check_int))
173 # ajax delete repos group perm user
173 # ajax delete repos group perm user
174 m.connect('delete_repos_group_user_perm',
174 m.connect('delete_repos_group_user_perm',
175 "/delete_repos_group_user_perm/{group_name:.*}",
175 "/delete_repos_group_user_perm/{group_name:.*}",
176 action="delete_repos_group_user_perm",
176 action="delete_repos_group_user_perm",
177 conditions=dict(method=["DELETE"], function=check_group))
177 conditions=dict(method=["DELETE"], function=check_group))
178
178
179 # ajax delete repos group perm users_group
179 # ajax delete repos group perm users_group
180 m.connect('delete_repos_group_users_group_perm',
180 m.connect('delete_repos_group_users_group_perm',
181 "/delete_repos_group_users_group_perm/{group_name:.*}",
181 "/delete_repos_group_users_group_perm/{group_name:.*}",
182 action="delete_repos_group_users_group_perm",
182 action="delete_repos_group_users_group_perm",
183 conditions=dict(method=["DELETE"], function=check_group))
183 conditions=dict(method=["DELETE"], function=check_group))
184
184
185 #ADMIN USER REST ROUTES
185 #ADMIN USER REST ROUTES
186 with rmap.submapper(path_prefix=ADMIN_PREFIX,
186 with rmap.submapper(path_prefix=ADMIN_PREFIX,
187 controller='admin/users') as m:
187 controller='admin/users') as m:
188 m.connect("users", "/users",
188 m.connect("users", "/users",
189 action="create", conditions=dict(method=["POST"]))
189 action="create", conditions=dict(method=["POST"]))
190 m.connect("users", "/users",
190 m.connect("users", "/users",
191 action="index", conditions=dict(method=["GET"]))
191 action="index", conditions=dict(method=["GET"]))
192 m.connect("formatted_users", "/users.{format}",
192 m.connect("formatted_users", "/users.{format}",
193 action="index", conditions=dict(method=["GET"]))
193 action="index", conditions=dict(method=["GET"]))
194 m.connect("new_user", "/users/new",
194 m.connect("new_user", "/users/new",
195 action="new", conditions=dict(method=["GET"]))
195 action="new", conditions=dict(method=["GET"]))
196 m.connect("formatted_new_user", "/users/new.{format}",
196 m.connect("formatted_new_user", "/users/new.{format}",
197 action="new", conditions=dict(method=["GET"]))
197 action="new", conditions=dict(method=["GET"]))
198 m.connect("update_user", "/users/{id}",
198 m.connect("update_user", "/users/{id}",
199 action="update", conditions=dict(method=["PUT"]))
199 action="update", conditions=dict(method=["PUT"]))
200 m.connect("delete_user", "/users/{id}",
200 m.connect("delete_user", "/users/{id}",
201 action="delete", conditions=dict(method=["DELETE"]))
201 action="delete", conditions=dict(method=["DELETE"]))
202 m.connect("edit_user", "/users/{id}/edit",
202 m.connect("edit_user", "/users/{id}/edit",
203 action="edit", conditions=dict(method=["GET"]))
203 action="edit", conditions=dict(method=["GET"]))
204 m.connect("formatted_edit_user",
204 m.connect("formatted_edit_user",
205 "/users/{id}.{format}/edit",
205 "/users/{id}.{format}/edit",
206 action="edit", conditions=dict(method=["GET"]))
206 action="edit", conditions=dict(method=["GET"]))
207 m.connect("user", "/users/{id}",
207 m.connect("user", "/users/{id}",
208 action="show", conditions=dict(method=["GET"]))
208 action="show", conditions=dict(method=["GET"]))
209 m.connect("formatted_user", "/users/{id}.{format}",
209 m.connect("formatted_user", "/users/{id}.{format}",
210 action="show", conditions=dict(method=["GET"]))
210 action="show", conditions=dict(method=["GET"]))
211
211
212 #EXTRAS USER ROUTES
212 #EXTRAS USER ROUTES
213 m.connect("user_perm", "/users_perm/{id}",
213 m.connect("user_perm", "/users_perm/{id}",
214 action="update_perm", conditions=dict(method=["PUT"]))
214 action="update_perm", conditions=dict(method=["PUT"]))
215 m.connect("user_emails", "/users_emails/{id}",
215 m.connect("user_emails", "/users_emails/{id}",
216 action="add_email", conditions=dict(method=["PUT"]))
216 action="add_email", conditions=dict(method=["PUT"]))
217 m.connect("user_emails_delete", "/users_emails/{id}",
217 m.connect("user_emails_delete", "/users_emails/{id}",
218 action="delete_email", conditions=dict(method=["DELETE"]))
218 action="delete_email", conditions=dict(method=["DELETE"]))
219
219
220 #ADMIN USERS REST ROUTES
220 #ADMIN USERS REST ROUTES
221 with rmap.submapper(path_prefix=ADMIN_PREFIX,
221 with rmap.submapper(path_prefix=ADMIN_PREFIX,
222 controller='admin/users_groups') as m:
222 controller='admin/users_groups') as m:
223 m.connect("users_groups", "/users_groups",
223 m.connect("users_groups", "/users_groups",
224 action="create", conditions=dict(method=["POST"]))
224 action="create", conditions=dict(method=["POST"]))
225 m.connect("users_groups", "/users_groups",
225 m.connect("users_groups", "/users_groups",
226 action="index", conditions=dict(method=["GET"]))
226 action="index", conditions=dict(method=["GET"]))
227 m.connect("formatted_users_groups", "/users_groups.{format}",
227 m.connect("formatted_users_groups", "/users_groups.{format}",
228 action="index", conditions=dict(method=["GET"]))
228 action="index", conditions=dict(method=["GET"]))
229 m.connect("new_users_group", "/users_groups/new",
229 m.connect("new_users_group", "/users_groups/new",
230 action="new", conditions=dict(method=["GET"]))
230 action="new", conditions=dict(method=["GET"]))
231 m.connect("formatted_new_users_group", "/users_groups/new.{format}",
231 m.connect("formatted_new_users_group", "/users_groups/new.{format}",
232 action="new", conditions=dict(method=["GET"]))
232 action="new", conditions=dict(method=["GET"]))
233 m.connect("update_users_group", "/users_groups/{id}",
233 m.connect("update_users_group", "/users_groups/{id}",
234 action="update", conditions=dict(method=["PUT"]))
234 action="update", conditions=dict(method=["PUT"]))
235 m.connect("delete_users_group", "/users_groups/{id}",
235 m.connect("delete_users_group", "/users_groups/{id}",
236 action="delete", conditions=dict(method=["DELETE"]))
236 action="delete", conditions=dict(method=["DELETE"]))
237 m.connect("edit_users_group", "/users_groups/{id}/edit",
237 m.connect("edit_users_group", "/users_groups/{id}/edit",
238 action="edit", conditions=dict(method=["GET"]))
238 action="edit", conditions=dict(method=["GET"]))
239 m.connect("formatted_edit_users_group",
239 m.connect("formatted_edit_users_group",
240 "/users_groups/{id}.{format}/edit",
240 "/users_groups/{id}.{format}/edit",
241 action="edit", conditions=dict(method=["GET"]))
241 action="edit", conditions=dict(method=["GET"]))
242 m.connect("users_group", "/users_groups/{id}",
242 m.connect("users_group", "/users_groups/{id}",
243 action="show", conditions=dict(method=["GET"]))
243 action="show", conditions=dict(method=["GET"]))
244 m.connect("formatted_users_group", "/users_groups/{id}.{format}",
244 m.connect("formatted_users_group", "/users_groups/{id}.{format}",
245 action="show", conditions=dict(method=["GET"]))
245 action="show", conditions=dict(method=["GET"]))
246
246
247 #EXTRAS USER ROUTES
247 #EXTRAS USER ROUTES
248 m.connect("users_group_perm", "/users_groups_perm/{id}",
248 m.connect("users_group_perm", "/users_groups_perm/{id}",
249 action="update_perm", conditions=dict(method=["PUT"]))
249 action="update_perm", conditions=dict(method=["PUT"]))
250
250
251 #ADMIN GROUP REST ROUTES
251 #ADMIN GROUP REST ROUTES
252 rmap.resource('group', 'groups',
252 rmap.resource('group', 'groups',
253 controller='admin/groups', path_prefix=ADMIN_PREFIX)
253 controller='admin/groups', path_prefix=ADMIN_PREFIX)
254
254
255 #ADMIN PERMISSIONS REST ROUTES
255 #ADMIN PERMISSIONS REST ROUTES
256 rmap.resource('permission', 'permissions',
256 rmap.resource('permission', 'permissions',
257 controller='admin/permissions', path_prefix=ADMIN_PREFIX)
257 controller='admin/permissions', path_prefix=ADMIN_PREFIX)
258
258
259 ##ADMIN LDAP SETTINGS
259 ##ADMIN LDAP SETTINGS
260 rmap.connect('ldap_settings', '%s/ldap' % ADMIN_PREFIX,
260 rmap.connect('ldap_settings', '%s/ldap' % ADMIN_PREFIX,
261 controller='admin/ldap_settings', action='ldap_settings',
261 controller='admin/ldap_settings', action='ldap_settings',
262 conditions=dict(method=["POST"]))
262 conditions=dict(method=["POST"]))
263
263
264 rmap.connect('ldap_home', '%s/ldap' % ADMIN_PREFIX,
264 rmap.connect('ldap_home', '%s/ldap' % ADMIN_PREFIX,
265 controller='admin/ldap_settings')
265 controller='admin/ldap_settings')
266
266
267 #ADMIN SETTINGS REST ROUTES
267 #ADMIN SETTINGS REST ROUTES
268 with rmap.submapper(path_prefix=ADMIN_PREFIX,
268 with rmap.submapper(path_prefix=ADMIN_PREFIX,
269 controller='admin/settings') as m:
269 controller='admin/settings') as m:
270 m.connect("admin_settings", "/settings",
270 m.connect("admin_settings", "/settings",
271 action="create", conditions=dict(method=["POST"]))
271 action="create", conditions=dict(method=["POST"]))
272 m.connect("admin_settings", "/settings",
272 m.connect("admin_settings", "/settings",
273 action="index", conditions=dict(method=["GET"]))
273 action="index", conditions=dict(method=["GET"]))
274 m.connect("formatted_admin_settings", "/settings.{format}",
274 m.connect("formatted_admin_settings", "/settings.{format}",
275 action="index", conditions=dict(method=["GET"]))
275 action="index", conditions=dict(method=["GET"]))
276 m.connect("admin_new_setting", "/settings/new",
276 m.connect("admin_new_setting", "/settings/new",
277 action="new", conditions=dict(method=["GET"]))
277 action="new", conditions=dict(method=["GET"]))
278 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
278 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
279 action="new", conditions=dict(method=["GET"]))
279 action="new", conditions=dict(method=["GET"]))
280 m.connect("/settings/{setting_id}",
280 m.connect("/settings/{setting_id}",
281 action="update", conditions=dict(method=["PUT"]))
281 action="update", conditions=dict(method=["PUT"]))
282 m.connect("/settings/{setting_id}",
282 m.connect("/settings/{setting_id}",
283 action="delete", conditions=dict(method=["DELETE"]))
283 action="delete", conditions=dict(method=["DELETE"]))
284 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
284 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
285 action="edit", conditions=dict(method=["GET"]))
285 action="edit", conditions=dict(method=["GET"]))
286 m.connect("formatted_admin_edit_setting",
286 m.connect("formatted_admin_edit_setting",
287 "/settings/{setting_id}.{format}/edit",
287 "/settings/{setting_id}.{format}/edit",
288 action="edit", conditions=dict(method=["GET"]))
288 action="edit", conditions=dict(method=["GET"]))
289 m.connect("admin_setting", "/settings/{setting_id}",
289 m.connect("admin_setting", "/settings/{setting_id}",
290 action="show", conditions=dict(method=["GET"]))
290 action="show", conditions=dict(method=["GET"]))
291 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
291 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
292 action="show", conditions=dict(method=["GET"]))
292 action="show", conditions=dict(method=["GET"]))
293 m.connect("admin_settings_my_account", "/my_account",
293 m.connect("admin_settings_my_account", "/my_account",
294 action="my_account", conditions=dict(method=["GET"]))
294 action="my_account", conditions=dict(method=["GET"]))
295 m.connect("admin_settings_my_account_update", "/my_account_update",
295 m.connect("admin_settings_my_account_update", "/my_account_update",
296 action="my_account_update", conditions=dict(method=["PUT"]))
296 action="my_account_update", conditions=dict(method=["PUT"]))
297 m.connect("admin_settings_create_repository", "/create_repository",
297 m.connect("admin_settings_create_repository", "/create_repository",
298 action="create_repository", conditions=dict(method=["GET"]))
298 action="create_repository", conditions=dict(method=["GET"]))
299
299
300 #NOTIFICATION REST ROUTES
300 #NOTIFICATION REST ROUTES
301 with rmap.submapper(path_prefix=ADMIN_PREFIX,
301 with rmap.submapper(path_prefix=ADMIN_PREFIX,
302 controller='admin/notifications') as m:
302 controller='admin/notifications') as m:
303 m.connect("notifications", "/notifications",
303 m.connect("notifications", "/notifications",
304 action="create", conditions=dict(method=["POST"]))
304 action="create", conditions=dict(method=["POST"]))
305 m.connect("notifications", "/notifications",
305 m.connect("notifications", "/notifications",
306 action="index", conditions=dict(method=["GET"]))
306 action="index", conditions=dict(method=["GET"]))
307 m.connect("notifications_mark_all_read", "/notifications/mark_all_read",
307 m.connect("notifications_mark_all_read", "/notifications/mark_all_read",
308 action="mark_all_read", conditions=dict(method=["GET"]))
308 action="mark_all_read", conditions=dict(method=["GET"]))
309 m.connect("formatted_notifications", "/notifications.{format}",
309 m.connect("formatted_notifications", "/notifications.{format}",
310 action="index", conditions=dict(method=["GET"]))
310 action="index", conditions=dict(method=["GET"]))
311 m.connect("new_notification", "/notifications/new",
311 m.connect("new_notification", "/notifications/new",
312 action="new", conditions=dict(method=["GET"]))
312 action="new", conditions=dict(method=["GET"]))
313 m.connect("formatted_new_notification", "/notifications/new.{format}",
313 m.connect("formatted_new_notification", "/notifications/new.{format}",
314 action="new", conditions=dict(method=["GET"]))
314 action="new", conditions=dict(method=["GET"]))
315 m.connect("/notification/{notification_id}",
315 m.connect("/notification/{notification_id}",
316 action="update", conditions=dict(method=["PUT"]))
316 action="update", conditions=dict(method=["PUT"]))
317 m.connect("/notification/{notification_id}",
317 m.connect("/notification/{notification_id}",
318 action="delete", conditions=dict(method=["DELETE"]))
318 action="delete", conditions=dict(method=["DELETE"]))
319 m.connect("edit_notification", "/notification/{notification_id}/edit",
319 m.connect("edit_notification", "/notification/{notification_id}/edit",
320 action="edit", conditions=dict(method=["GET"]))
320 action="edit", conditions=dict(method=["GET"]))
321 m.connect("formatted_edit_notification",
321 m.connect("formatted_edit_notification",
322 "/notification/{notification_id}.{format}/edit",
322 "/notification/{notification_id}.{format}/edit",
323 action="edit", conditions=dict(method=["GET"]))
323 action="edit", conditions=dict(method=["GET"]))
324 m.connect("notification", "/notification/{notification_id}",
324 m.connect("notification", "/notification/{notification_id}",
325 action="show", conditions=dict(method=["GET"]))
325 action="show", conditions=dict(method=["GET"]))
326 m.connect("formatted_notification", "/notifications/{notification_id}.{format}",
326 m.connect("formatted_notification", "/notifications/{notification_id}.{format}",
327 action="show", conditions=dict(method=["GET"]))
327 action="show", conditions=dict(method=["GET"]))
328
328
329 #ADMIN MAIN PAGES
329 #ADMIN MAIN PAGES
330 with rmap.submapper(path_prefix=ADMIN_PREFIX,
330 with rmap.submapper(path_prefix=ADMIN_PREFIX,
331 controller='admin/admin') as m:
331 controller='admin/admin') as m:
332 m.connect('admin_home', '', action='index')
332 m.connect('admin_home', '', action='index')
333 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
333 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
334 action='add_repo')
334 action='add_repo')
335
335
336 #==========================================================================
336 #==========================================================================
337 # API V2
337 # API V2
338 #==========================================================================
338 #==========================================================================
339 with rmap.submapper(path_prefix=ADMIN_PREFIX,
339 with rmap.submapper(path_prefix=ADMIN_PREFIX,
340 controller='api/api') as m:
340 controller='api/api') as m:
341 m.connect('api', '/api')
341 m.connect('api', '/api')
342
342
343 #USER JOURNAL
343 #USER JOURNAL
344 rmap.connect('journal', '%s/journal' % ADMIN_PREFIX, controller='journal')
344 rmap.connect('journal', '%s/journal' % ADMIN_PREFIX, controller='journal')
345
345
346 rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
346 rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
347 controller='journal', action="public_journal")
347 controller='journal', action="public_journal")
348
348
349 rmap.connect('public_journal_rss', '%s/public_journal_rss' % ADMIN_PREFIX,
349 rmap.connect('public_journal_rss', '%s/public_journal_rss' % ADMIN_PREFIX,
350 controller='journal', action="public_journal_rss")
350 controller='journal', action="public_journal_rss")
351
351
352 rmap.connect('public_journal_atom',
352 rmap.connect('public_journal_atom',
353 '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal',
353 '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal',
354 action="public_journal_atom")
354 action="public_journal_atom")
355
355
356 rmap.connect('toggle_following', '%s/toggle_following' % ADMIN_PREFIX,
356 rmap.connect('toggle_following', '%s/toggle_following' % ADMIN_PREFIX,
357 controller='journal', action='toggle_following',
357 controller='journal', action='toggle_following',
358 conditions=dict(method=["POST"]))
358 conditions=dict(method=["POST"]))
359
359
360 #SEARCH
360 #SEARCH
361 rmap.connect('search', '%s/search' % ADMIN_PREFIX, controller='search',)
361 rmap.connect('search', '%s/search' % ADMIN_PREFIX, controller='search',)
362 rmap.connect('search_repo', '%s/search/{search_repo:.*}' % ADMIN_PREFIX,
362 rmap.connect('search_repo', '%s/search/{search_repo:.*}' % ADMIN_PREFIX,
363 controller='search')
363 controller='search')
364
364
365 #LOGIN/LOGOUT/REGISTER/SIGN IN
365 #LOGIN/LOGOUT/REGISTER/SIGN IN
366 rmap.connect('login_home', '%s/login' % ADMIN_PREFIX, controller='login')
366 rmap.connect('login_home', '%s/login' % ADMIN_PREFIX, controller='login')
367 rmap.connect('logout_home', '%s/logout' % ADMIN_PREFIX, controller='login',
367 rmap.connect('logout_home', '%s/logout' % ADMIN_PREFIX, controller='login',
368 action='logout')
368 action='logout')
369
369
370 rmap.connect('register', '%s/register' % ADMIN_PREFIX, controller='login',
370 rmap.connect('register', '%s/register' % ADMIN_PREFIX, controller='login',
371 action='register')
371 action='register')
372
372
373 rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX,
373 rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX,
374 controller='login', action='password_reset')
374 controller='login', action='password_reset')
375
375
376 rmap.connect('reset_password_confirmation',
376 rmap.connect('reset_password_confirmation',
377 '%s/password_reset_confirmation' % ADMIN_PREFIX,
377 '%s/password_reset_confirmation' % ADMIN_PREFIX,
378 controller='login', action='password_reset_confirmation')
378 controller='login', action='password_reset_confirmation')
379
379
380 #FEEDS
380 #FEEDS
381 rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
381 rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
382 controller='feed', action='rss',
382 controller='feed', action='rss',
383 conditions=dict(function=check_repo))
383 conditions=dict(function=check_repo))
384
384
385 rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
385 rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
386 controller='feed', action='atom',
386 controller='feed', action='atom',
387 conditions=dict(function=check_repo))
387 conditions=dict(function=check_repo))
388
388
389 #==========================================================================
389 #==========================================================================
390 # REPOSITORY ROUTES
390 # REPOSITORY ROUTES
391 #==========================================================================
391 #==========================================================================
392 rmap.connect('summary_home', '/{repo_name:.*}',
392 rmap.connect('summary_home', '/{repo_name:.*}',
393 controller='summary',
393 controller='summary',
394 conditions=dict(function=check_repo))
394 conditions=dict(function=check_repo))
395
395
396 rmap.connect('repos_group_home', '/{group_name:.*}',
396 rmap.connect('repos_group_home', '/{group_name:.*}',
397 controller='admin/repos_groups', action="show_by_name",
397 controller='admin/repos_groups', action="show_by_name",
398 conditions=dict(function=check_group))
398 conditions=dict(function=check_group))
399
399
400 rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
400 rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
401 controller='changeset', revision='tip',
401 controller='changeset', revision='tip',
402 conditions=dict(function=check_repo))
402 conditions=dict(function=check_repo))
403
403
404 rmap.connect('changeset_comment',
404 rmap.connect('changeset_comment',
405 '/{repo_name:.*}/changeset/{revision}/comment',
405 '/{repo_name:.*}/changeset/{revision}/comment',
406 controller='changeset', revision='tip', action='comment',
406 controller='changeset', revision='tip', action='comment',
407 conditions=dict(function=check_repo))
407 conditions=dict(function=check_repo))
408
408
409 rmap.connect('changeset_comment_delete',
409 rmap.connect('changeset_comment_delete',
410 '/{repo_name:.*}/changeset/comment/{comment_id}/delete',
410 '/{repo_name:.*}/changeset/comment/{comment_id}/delete',
411 controller='changeset', action='delete_comment',
411 controller='changeset', action='delete_comment',
412 conditions=dict(function=check_repo, method=["DELETE"]))
412 conditions=dict(function=check_repo, method=["DELETE"]))
413
413
414 rmap.connect('raw_changeset_home',
414 rmap.connect('raw_changeset_home',
415 '/{repo_name:.*}/raw-changeset/{revision}',
415 '/{repo_name:.*}/raw-changeset/{revision}',
416 controller='changeset', action='raw_changeset',
416 controller='changeset', action='raw_changeset',
417 revision='tip', conditions=dict(function=check_repo))
417 revision='tip', conditions=dict(function=check_repo))
418
418
419 rmap.connect('compare_home',
419 rmap.connect('compare_url',
420 '/{repo_name:.*}/compare/{ref:.*}',
420 '/{repo_name:.*}/compare/{org_ref_type}@{org_ref}...{other_ref_type}@{other_ref}',
421 controller='compare', action='index',
421 controller='compare', action='index',
422 conditions=dict(function=check_repo))
422 conditions=dict(function=check_repo),
423 requirements=dict(org_ref_type='(branch|book|tag)',
424 other_ref_type='(branch|book|tag)'))
423
425
424 rmap.connect('pullrequest_home',
426 rmap.connect('pullrequest_home',
425 '/{repo_name:.*}/pull-request/new',
427 '/{repo_name:.*}/pull-request/new',
426 controller='pullrequests', action='index',
428 controller='pullrequests', action='index',
427 conditions=dict(function=check_repo))
429 conditions=dict(function=check_repo))
428
430
429 rmap.connect('summary_home', '/{repo_name:.*}/summary',
431 rmap.connect('summary_home', '/{repo_name:.*}/summary',
430 controller='summary', conditions=dict(function=check_repo))
432 controller='summary', conditions=dict(function=check_repo))
431
433
432 rmap.connect('shortlog_home', '/{repo_name:.*}/shortlog',
434 rmap.connect('shortlog_home', '/{repo_name:.*}/shortlog',
433 controller='shortlog', conditions=dict(function=check_repo))
435 controller='shortlog', conditions=dict(function=check_repo))
434
436
435 rmap.connect('branches_home', '/{repo_name:.*}/branches',
437 rmap.connect('branches_home', '/{repo_name:.*}/branches',
436 controller='branches', conditions=dict(function=check_repo))
438 controller='branches', conditions=dict(function=check_repo))
437
439
438 rmap.connect('tags_home', '/{repo_name:.*}/tags',
440 rmap.connect('tags_home', '/{repo_name:.*}/tags',
439 controller='tags', conditions=dict(function=check_repo))
441 controller='tags', conditions=dict(function=check_repo))
440
442
441 rmap.connect('bookmarks_home', '/{repo_name:.*}/bookmarks',
443 rmap.connect('bookmarks_home', '/{repo_name:.*}/bookmarks',
442 controller='bookmarks', conditions=dict(function=check_repo))
444 controller='bookmarks', conditions=dict(function=check_repo))
443
445
444 rmap.connect('changelog_home', '/{repo_name:.*}/changelog',
446 rmap.connect('changelog_home', '/{repo_name:.*}/changelog',
445 controller='changelog', conditions=dict(function=check_repo))
447 controller='changelog', conditions=dict(function=check_repo))
446
448
447 rmap.connect('changelog_details', '/{repo_name:.*}/changelog_details/{cs}',
449 rmap.connect('changelog_details', '/{repo_name:.*}/changelog_details/{cs}',
448 controller='changelog', action='changelog_details',
450 controller='changelog', action='changelog_details',
449 conditions=dict(function=check_repo))
451 conditions=dict(function=check_repo))
450
452
451 rmap.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
453 rmap.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
452 controller='files', revision='tip', f_path='',
454 controller='files', revision='tip', f_path='',
453 conditions=dict(function=check_repo))
455 conditions=dict(function=check_repo))
454
456
455 rmap.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
457 rmap.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
456 controller='files', action='diff', revision='tip', f_path='',
458 controller='files', action='diff', revision='tip', f_path='',
457 conditions=dict(function=check_repo))
459 conditions=dict(function=check_repo))
458
460
459 rmap.connect('files_rawfile_home',
461 rmap.connect('files_rawfile_home',
460 '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
462 '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
461 controller='files', action='rawfile', revision='tip',
463 controller='files', action='rawfile', revision='tip',
462 f_path='', conditions=dict(function=check_repo))
464 f_path='', conditions=dict(function=check_repo))
463
465
464 rmap.connect('files_raw_home',
466 rmap.connect('files_raw_home',
465 '/{repo_name:.*}/raw/{revision}/{f_path:.*}',
467 '/{repo_name:.*}/raw/{revision}/{f_path:.*}',
466 controller='files', action='raw', revision='tip', f_path='',
468 controller='files', action='raw', revision='tip', f_path='',
467 conditions=dict(function=check_repo))
469 conditions=dict(function=check_repo))
468
470
469 rmap.connect('files_annotate_home',
471 rmap.connect('files_annotate_home',
470 '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
472 '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
471 controller='files', action='index', revision='tip',
473 controller='files', action='index', revision='tip',
472 f_path='', annotate=True, conditions=dict(function=check_repo))
474 f_path='', annotate=True, conditions=dict(function=check_repo))
473
475
474 rmap.connect('files_edit_home',
476 rmap.connect('files_edit_home',
475 '/{repo_name:.*}/edit/{revision}/{f_path:.*}',
477 '/{repo_name:.*}/edit/{revision}/{f_path:.*}',
476 controller='files', action='edit', revision='tip',
478 controller='files', action='edit', revision='tip',
477 f_path='', conditions=dict(function=check_repo))
479 f_path='', conditions=dict(function=check_repo))
478
480
479 rmap.connect('files_add_home',
481 rmap.connect('files_add_home',
480 '/{repo_name:.*}/add/{revision}/{f_path:.*}',
482 '/{repo_name:.*}/add/{revision}/{f_path:.*}',
481 controller='files', action='add', revision='tip',
483 controller='files', action='add', revision='tip',
482 f_path='', conditions=dict(function=check_repo))
484 f_path='', conditions=dict(function=check_repo))
483
485
484 rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}',
486 rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}',
485 controller='files', action='archivefile',
487 controller='files', action='archivefile',
486 conditions=dict(function=check_repo))
488 conditions=dict(function=check_repo))
487
489
488 rmap.connect('files_nodelist_home',
490 rmap.connect('files_nodelist_home',
489 '/{repo_name:.*}/nodelist/{revision}/{f_path:.*}',
491 '/{repo_name:.*}/nodelist/{revision}/{f_path:.*}',
490 controller='files', action='nodelist',
492 controller='files', action='nodelist',
491 conditions=dict(function=check_repo))
493 conditions=dict(function=check_repo))
492
494
493 rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings',
495 rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings',
494 controller='settings', action="delete",
496 controller='settings', action="delete",
495 conditions=dict(method=["DELETE"], function=check_repo))
497 conditions=dict(method=["DELETE"], function=check_repo))
496
498
497 rmap.connect('repo_settings_update', '/{repo_name:.*}/settings',
499 rmap.connect('repo_settings_update', '/{repo_name:.*}/settings',
498 controller='settings', action="update",
500 controller='settings', action="update",
499 conditions=dict(method=["PUT"], function=check_repo))
501 conditions=dict(method=["PUT"], function=check_repo))
500
502
501 rmap.connect('repo_settings_home', '/{repo_name:.*}/settings',
503 rmap.connect('repo_settings_home', '/{repo_name:.*}/settings',
502 controller='settings', action='index',
504 controller='settings', action='index',
503 conditions=dict(function=check_repo))
505 conditions=dict(function=check_repo))
504
506
505 rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
507 rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
506 controller='forks', action='fork_create',
508 controller='forks', action='fork_create',
507 conditions=dict(function=check_repo, method=["POST"]))
509 conditions=dict(function=check_repo, method=["POST"]))
508
510
509 rmap.connect('repo_fork_home', '/{repo_name:.*}/fork',
511 rmap.connect('repo_fork_home', '/{repo_name:.*}/fork',
510 controller='forks', action='fork',
512 controller='forks', action='fork',
511 conditions=dict(function=check_repo))
513 conditions=dict(function=check_repo))
512
514
513 rmap.connect('repo_forks_home', '/{repo_name:.*}/forks',
515 rmap.connect('repo_forks_home', '/{repo_name:.*}/forks',
514 controller='forks', action='forks',
516 controller='forks', action='forks',
515 conditions=dict(function=check_repo))
517 conditions=dict(function=check_repo))
516
518
517 rmap.connect('repo_followers_home', '/{repo_name:.*}/followers',
519 rmap.connect('repo_followers_home', '/{repo_name:.*}/followers',
518 controller='followers', action='followers',
520 controller='followers', action='followers',
519 conditions=dict(function=check_repo))
521 conditions=dict(function=check_repo))
520
522
521 return rmap
523 return rmap
@@ -1,170 +1,140 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.compare
3 rhodecode.controllers.compare
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 compare controller for pylons showoing differences between two
6 compare controller for pylons showoing differences between two
7 repos, branches, bookmarks or tips
7 repos, branches, bookmarks or tips
8
8
9 :created_on: May 6, 2012
9 :created_on: May 6, 2012
10 :author: marcink
10 :author: marcink
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
11 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
12 :license: GPLv3, see COPYING for more details.
12 :license: GPLv3, see COPYING for more details.
13 """
13 """
14 # This program is free software: you can redistribute it and/or modify
14 # This program is free software: you can redistribute it and/or modify
15 # it under the terms of the GNU General Public License as published by
15 # it under the terms of the GNU General Public License as published by
16 # the Free Software Foundation, either version 3 of the License, or
16 # the Free Software Foundation, either version 3 of the License, or
17 # (at your option) any later version.
17 # (at your option) any later version.
18 #
18 #
19 # This program is distributed in the hope that it will be useful,
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU General Public License for more details.
22 # GNU General Public License for more details.
23 #
23 #
24 # You should have received a copy of the GNU General Public License
24 # You should have received a copy of the GNU General Public License
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25 # along with this program. If not, see <http://www.gnu.org/licenses/>.
26 import logging
26 import logging
27 import traceback
27 import traceback
28 import binascii
28 import binascii
29
29
30 from webob.exc import HTTPNotFound
30 from webob.exc import HTTPNotFound
31 from pylons import request, response, session, tmpl_context as c, url
31 from pylons import request, response, session, tmpl_context as c, url
32 from pylons.controllers.util import abort, redirect
32 from pylons.controllers.util import abort, redirect
33
33
34 from rhodecode.lib import helpers as h
34 from rhodecode.lib import helpers as h
35 from rhodecode.lib.base import BaseRepoController, render
35 from rhodecode.lib.base import BaseRepoController, render
36 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
36 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
37 from rhodecode.lib import diffs
37 from rhodecode.lib import diffs
38
38
39 from rhodecode.model.db import Repository
39 from rhodecode.model.db import Repository
40
40
41 log = logging.getLogger(__name__)
41 log = logging.getLogger(__name__)
42
42
43
43
44 class CompareController(BaseRepoController):
44 class CompareController(BaseRepoController):
45
45
46 @LoginRequired()
46 @LoginRequired()
47 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
47 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
48 'repository.admin')
48 'repository.admin')
49 def __before__(self):
49 def __before__(self):
50 super(CompareController, self).__before__()
50 super(CompareController, self).__before__()
51
51
52 def _handle_ref(self, ref):
53 """
54 Parse the org...other string
55 Possible formats are
56 `(branch|book|tag):<name>...(branch|book|tag):<othername>`
57
58 :param ref: <orginal_reference>...<other_reference>
59 :type ref: str
60 """
61 org_repo = c.rhodecode_db_repo.repo_name
62
63 def org_parser(org):
64 _repo = org_repo
65 name, val = org.split(':')
66 return _repo, (name, val)
67
68 def other_parser(other):
69 _other_repo = request.GET.get('repo')
70 _repo = org_repo
71 name, val = other.split(':')
72 if _other_repo:
73 _repo = _other_repo
74
75 return _repo, (name, val)
76
77 if '...' in ref:
78 try:
79 org, other = ref.split('...')
80 org_repo, org_ref = org_parser(org)
81 other_repo, other_ref = other_parser(other)
82 return org_repo, org_ref, other_repo, other_ref
83 except:
84 log.error(traceback.format_exc())
85
86 raise HTTPNotFound
87
52
88 def _get_discovery(self, org_repo, org_ref, other_repo, other_ref):
53 def _get_discovery(self, org_repo, org_ref, other_repo, other_ref):
89 from mercurial import discovery
54 from mercurial import discovery
90 other = org_repo._repo
55 other = org_repo._repo
91 repo = other_repo._repo
56 repo = other_repo._repo
92 tip = other[org_ref[1]]
57 tip = other[org_ref[1]]
93 log.debug('Doing discovery for %s@%s vs %s@%s' % (
58 log.debug('Doing discovery for %s@%s vs %s@%s' % (
94 org_repo, org_ref, other_repo, other_ref)
59 org_repo, org_ref, other_repo, other_ref)
95 )
60 )
96 log.debug('Filter heads are %s[%s]' % (tip, org_ref[1]))
61 log.debug('Filter heads are %s[%s]' % (tip, org_ref[1]))
97 tmp = discovery.findcommonincoming(
62 tmp = discovery.findcommonincoming(
98 repo=repo, # other_repo we check for incoming
63 repo=repo, # other_repo we check for incoming
99 remote=other, # org_repo source for incoming
64 remote=other, # org_repo source for incoming
100 heads=[tip.node()],
65 heads=[tip.node()],
101 force=False
66 force=False
102 )
67 )
103 return tmp
68 return tmp
104
69
105 def _get_changesets(self, org_repo, org_ref, other_repo, other_ref, tmp):
70 def _get_changesets(self, org_repo, org_ref, other_repo, other_ref, tmp):
106 changesets = []
71 changesets = []
107 #case two independent repos
72 #case two independent repos
108 if org_repo != other_repo:
73 if org_repo != other_repo:
109 common, incoming, rheads = tmp
74 common, incoming, rheads = tmp
110
75
111 if not incoming:
76 if not incoming:
112 revs = []
77 revs = []
113 else:
78 else:
114 revs = org_repo._repo.changelog.findmissing(common, rheads)
79 revs = org_repo._repo.changelog.findmissing(common, rheads)
115
80
116 for cs in reversed(map(binascii.hexlify, revs)):
81 for cs in reversed(map(binascii.hexlify, revs)):
117 changesets.append(org_repo.get_changeset(cs))
82 changesets.append(org_repo.get_changeset(cs))
118 else:
83 else:
119 revs = ['ancestors(%s) and not ancestors(%s)' % (org_ref[1],
84 revs = ['ancestors(%s) and not ancestors(%s)' % (org_ref[1],
120 other_ref[1])]
85 other_ref[1])]
121 from mercurial import scmutil
86 from mercurial import scmutil
122 out = scmutil.revrange(org_repo._repo, revs)
87 out = scmutil.revrange(org_repo._repo, revs)
123 for cs in reversed(out):
88 for cs in reversed(out):
124 changesets.append(org_repo.get_changeset(cs))
89 changesets.append(org_repo.get_changeset(cs))
125
90
126 return changesets
91 return changesets
127
92
128 def index(self, ref):
93 def index(self, org_ref_type, org_ref, other_ref_type, other_ref):
129 org_repo, org_ref, other_repo, other_ref = self._handle_ref(ref)
130
94
131 c.swap_url = h.url('compare_home', repo_name=other_repo,
95 org_repo = c.rhodecode_db_repo.repo_name
132 ref='%s...%s' % (':'.join(other_ref),
96 org_ref = (org_ref_type, org_ref)
133 ':'.join(org_ref)),
97 other_ref = (other_ref_type, other_ref)
98 other_repo = request.GET.get('repo', org_repo)
99
100 c.swap_url = h.url('compare_url', repo_name=other_repo,
101 org_ref_type=other_ref[0], org_ref=other_ref[1],
102 other_ref_type=org_ref[0], other_ref=org_ref[1],
134 repo=org_repo)
103 repo=org_repo)
104
135 c.org_repo = org_repo = Repository.get_by_repo_name(org_repo)
105 c.org_repo = org_repo = Repository.get_by_repo_name(org_repo)
136 c.other_repo = other_repo = Repository.get_by_repo_name(other_repo)
106 c.other_repo = other_repo = Repository.get_by_repo_name(other_repo)
137
107
138 if c.org_repo is None or c.other_repo is None:
108 if c.org_repo is None or c.other_repo is None:
139 log.error('Could not found repo %s or %s' % (org_repo, other_repo))
109 log.error('Could not found repo %s or %s' % (org_repo, other_repo))
140 raise HTTPNotFound
110 raise HTTPNotFound
141
111
142 discovery_data = self._get_discovery(org_repo.scm_instance,
112 discovery_data = self._get_discovery(org_repo.scm_instance,
143 org_ref,
113 org_ref,
144 other_repo.scm_instance,
114 other_repo.scm_instance,
145 other_ref)
115 other_ref)
146 c.cs_ranges = self._get_changesets(org_repo.scm_instance,
116 c.cs_ranges = self._get_changesets(org_repo.scm_instance,
147 org_ref,
117 org_ref,
148 other_repo.scm_instance,
118 other_repo.scm_instance,
149 other_ref,
119 other_ref,
150 discovery_data)
120 discovery_data)
151
121
152 c.org_ref = org_ref[1]
122 c.org_ref = org_ref[1]
153 c.other_ref = other_ref[1]
123 c.other_ref = other_ref[1]
154 # diff needs to have swapped org with other to generate proper diff
124 # diff needs to have swapped org with other to generate proper diff
155 _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref,
125 _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref,
156 discovery_data)
126 discovery_data)
157 diff_processor = diffs.DiffProcessor(_diff, format='gitdiff')
127 diff_processor = diffs.DiffProcessor(_diff, format='gitdiff')
158 _parsed = diff_processor.prepare()
128 _parsed = diff_processor.prepare()
159
129
160 c.files = []
130 c.files = []
161 c.changes = {}
131 c.changes = {}
162 # sort Added first then Modified last Deleted files
132 # sort Added first then Modified last Deleted files
163 sorter = lambda info: {'A': 0, 'M': 1, 'D': 2}.get(info['operation'])
133 sorter = lambda info: {'A': 0, 'M': 1, 'D': 2}.get(info['operation'])
164 for f in sorted(_parsed, key=sorter):
134 for f in sorted(_parsed, key=sorter):
165 fid = h.FID('', f['filename'])
135 fid = h.FID('', f['filename'])
166 c.files.append([fid, f['operation'], f['filename'], f['stats']])
136 c.files.append([fid, f['operation'], f['filename'], f['stats']])
167 diff = diff_processor.as_html(enable_comments=False, diff_lines=[f])
137 diff = diff_processor.as_html(enable_comments=False, diff_lines=[f])
168 c.changes[fid] = [f['operation'], f['filename'], diff]
138 c.changes[fid] = [f['operation'], f['filename'], diff]
169
139
170 return render('compare/compare_diff.html')
140 return render('compare/compare_diff.html')
@@ -1,93 +1,94 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3
3
4 <%def name="title()">
4 <%def name="title()">
5 ${c.repo_name} ${_('Branches')} - ${c.rhodecode_name}
5 ${c.repo_name} ${_('Branches')} - ${c.rhodecode_name}
6 </%def>
6 </%def>
7
7
8 <%def name="breadcrumbs_links()">
8 <%def name="breadcrumbs_links()">
9 <input class="q_filter_box" id="q_filter_branches" size="15" type="text" name="filter" value="${_('quick filter...')}"/>
9 <input class="q_filter_box" id="q_filter_branches" size="15" type="text" name="filter" value="${_('quick filter...')}"/>
10 ${h.link_to(u'Home',h.url('/'))}
10 ${h.link_to(u'Home',h.url('/'))}
11 &raquo;
11 &raquo;
12 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
12 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
13 &raquo;
13 &raquo;
14 ${_('branches')}
14 ${_('branches')}
15 </%def>
15 </%def>
16
16
17 <%def name="page_nav()">
17 <%def name="page_nav()">
18 ${self.menu('branches')}
18 ${self.menu('branches')}
19 </%def>
19 </%def>
20
20
21 <%def name="main()">
21 <%def name="main()">
22 <div class="box">
22 <div class="box">
23 <!-- box / title -->
23 <!-- box / title -->
24 <div class="title">
24 <div class="title">
25 ${self.breadcrumbs()}
25 ${self.breadcrumbs()}
26 </div>
26 </div>
27 <!-- end box / title -->
27 <!-- end box / title -->
28 %if c.repo_branches:
28 %if c.repo_branches:
29 <div class="info_box" id="compare_branches" style="clear: both;padding: 10px 19px;vertical-align: right;text-align: right;"><a href="#" class="ui-btn small">${_('Compare branches')}</a></div>
29 <div class="info_box" id="compare_branches" style="clear: both;padding: 10px 19px;vertical-align: right;text-align: right;"><a href="#" class="ui-btn small">${_('Compare branches')}</a></div>
30 %endif
30 %endif
31 <div class="table">
31 <div class="table">
32 <%include file='branches_data.html'/>
32 <%include file='branches_data.html'/>
33 </div>
33 </div>
34 </div>
34 </div>
35 <script type="text/javascript">
35 <script type="text/javascript">
36 YUE.on('compare_branches','click',function(e){
36 YUE.on('compare_branches','click',function(e){
37 YUE.preventDefault(e);
37 YUE.preventDefault(e);
38 var org = YUQ('input[name=compare_org]:checked')[0];
38 var org = YUQ('input[name=compare_org]:checked')[0];
39 var other = YUQ('input[name=compare_other]:checked')[0];
39 var other = YUQ('input[name=compare_other]:checked')[0];
40 var compare_url = "${h.url('compare_home',repo_name=c.repo_name,ref='__ORG__...__OTHER__')}";
40
41 if(org && other){
41 if(org && other){
42 var u = compare_url.replace('__ORG__','branch:'+org.value)
42 var compare_url = "${h.url('compare_url',repo_name=c.repo_name,org_ref_type='branch',org_ref='__ORG__',other_ref_type='branch',other_ref='__OTHER__')}";
43 .replace('__OTHER__','branch:'+other.value);
43 var u = compare_url.replace('__ORG__',org.value)
44 .replace('__OTHER__',other.value);
44 window.location=u;
45 window.location=u;
45 }
46 }
46
47
47 })
48 })
48 // main table sorting
49 // main table sorting
49 var myColumnDefs = [
50 var myColumnDefs = [
50 {key:"name",label:"${_('Name')}",sortable:true},
51 {key:"name",label:"${_('Name')}",sortable:true},
51 {key:"date",label:"${_('Date')}",sortable:true,
52 {key:"date",label:"${_('Date')}",sortable:true,
52 sortOptions: { sortFunction: dateSort }},
53 sortOptions: { sortFunction: dateSort }},
53 {key:"author",label:"${_('Author')}",sortable:true},
54 {key:"author",label:"${_('Author')}",sortable:true},
54 {key:"revision",label:"${_('Revision')}",sortable:true,
55 {key:"revision",label:"${_('Revision')}",sortable:true,
55 sortOptions: { sortFunction: revisionSort }},
56 sortOptions: { sortFunction: revisionSort }},
56 {key:"compare",label:"${_('Compare')}",sortable:false,},
57 {key:"compare",label:"${_('Compare')}",sortable:false,},
57 ];
58 ];
58
59
59 var myDataSource = new YAHOO.util.DataSource(YUD.get("branches_data"));
60 var myDataSource = new YAHOO.util.DataSource(YUD.get("branches_data"));
60
61
61 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
62 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
62
63
63 myDataSource.responseSchema = {
64 myDataSource.responseSchema = {
64 fields: [
65 fields: [
65 {key:"name"},
66 {key:"name"},
66 {key:"date"},
67 {key:"date"},
67 {key:"author"},
68 {key:"author"},
68 {key:"revision"},
69 {key:"revision"},
69 {key:"compare"},
70 {key:"compare"},
70 ]
71 ]
71 };
72 };
72
73
73 var myDataTable = new YAHOO.widget.DataTable("table_wrap", myColumnDefs, myDataSource,
74 var myDataTable = new YAHOO.widget.DataTable("table_wrap", myColumnDefs, myDataSource,
74 {
75 {
75 sortedBy:{key:"name",dir:"asc"},
76 sortedBy:{key:"name",dir:"asc"},
76 MSG_SORTASC:"${_('Click to sort ascending')}",
77 MSG_SORTASC:"${_('Click to sort ascending')}",
77 MSG_SORTDESC:"${_('Click to sort descending')}",
78 MSG_SORTDESC:"${_('Click to sort descending')}",
78 MSG_EMPTY:"${_('No records found.')}",
79 MSG_EMPTY:"${_('No records found.')}",
79 MSG_ERROR:"${_('Data error.')}",
80 MSG_ERROR:"${_('Data error.')}",
80 MSG_LOADING:"${_('Loading...')}",
81 MSG_LOADING:"${_('Loading...')}",
81 }
82 }
82 );
83 );
83 myDataTable.subscribe('postRenderEvent',function(oArgs) {
84 myDataTable.subscribe('postRenderEvent',function(oArgs) {
84 tooltip_activate();
85 tooltip_activate();
85 var func = function(node){
86 var func = function(node){
86 return node.parentNode.parentNode.parentNode.parentNode.parentNode;
87 return node.parentNode.parentNode.parentNode.parentNode.parentNode;
87 }
88 }
88 q_filter('q_filter_branches',YUQ('div.table tr td .logtags .branchtag a'),func);
89 q_filter('q_filter_branches',YUQ('div.table tr td .logtags .branchtag a'),func);
89 });
90 });
90
91
91 </script>
92 </script>
92
93
93 </%def>
94 </%def>
@@ -1,246 +1,251 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 ${c.repo_name} ${_('Changelog')} - ${c.rhodecode_name}
6 ${c.repo_name} ${_('Changelog')} - ${c.rhodecode_name}
7 </%def>
7 </%def>
8
8
9 <%def name="breadcrumbs_links()">
9 <%def name="breadcrumbs_links()">
10 ${h.link_to(u'Home',h.url('/'))}
10 ${h.link_to(u'Home',h.url('/'))}
11 &raquo;
11 &raquo;
12 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
12 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
13 &raquo;
13 &raquo;
14 <% size = c.size if c.size <= c.total_cs else c.total_cs %>
14 <% size = c.size if c.size <= c.total_cs else c.total_cs %>
15 ${_('Changelog')} - ${ungettext('showing %d out of %d revision', 'showing %d out of %d revisions', size) % (size, c.total_cs)}
15 ${_('Changelog')} - ${ungettext('showing %d out of %d revision', 'showing %d out of %d revisions', size) % (size, c.total_cs)}
16 </%def>
16 </%def>
17
17
18 <%def name="page_nav()">
18 <%def name="page_nav()">
19 ${self.menu('changelog')}
19 ${self.menu('changelog')}
20 </%def>
20 </%def>
21
21
22 <%def name="main()">
22 <%def name="main()">
23 <div class="box">
23 <div class="box">
24 <!-- box / title -->
24 <!-- box / title -->
25 <div class="title">
25 <div class="title">
26 ${self.breadcrumbs()}
26 ${self.breadcrumbs()}
27 </div>
27 </div>
28 <div class="table">
28 <div class="table">
29 % if c.pagination:
29 % if c.pagination:
30 <div id="graph">
30 <div id="graph">
31 <div id="graph_nodes">
31 <div id="graph_nodes">
32 <canvas id="graph_canvas"></canvas>
32 <canvas id="graph_canvas"></canvas>
33 </div>
33 </div>
34 <div id="graph_content">
34 <div id="graph_content">
35 <div class="info_box" style="clear: both;padding: 10px 6px;vertical-align: right;text-align: right;"><a href="${h.url('pullrequest_home',repo_name=c.repo_name)}" class="ui-btn small">${_('Open new pull request')}</a></div>
35 <div class="info_box" style="clear: both;padding: 10px 6px;vertical-align: right;text-align: right;">
36 %if c.rhodecode_db_repo.fork:
37 <a title="${_('compare fork with %s' % c.rhodecode_db_repo.fork.repo_name)}" href="${h.url('compare_url',repo_name=c.repo_name,org_ref_type='branch',org_ref='default',other_ref_type='branch',other_ref='default',repo=c.rhodecode_db_repo.fork.repo_name)}" class="ui-btn small">${_('Compare fork')}</a>
38 %endif
39 <a href="${h.url('pullrequest_home',repo_name=c.repo_name)}" class="ui-btn small">${_('Open new pull request')}</a>
40 </div>
36 <div class="container_header">
41 <div class="container_header">
37 ${h.form(h.url.current(),method='get')}
42 ${h.form(h.url.current(),method='get')}
38 <div class="info_box" style="float:left">
43 <div class="info_box" style="float:left">
39 ${h.submit('set',_('Show'),class_="ui-btn")}
44 ${h.submit('set',_('Show'),class_="ui-btn")}
40 ${h.text('size',size=1,value=c.size)}
45 ${h.text('size',size=1,value=c.size)}
41 ${_('revisions')}
46 ${_('revisions')}
42 </div>
47 </div>
43 ${h.end_form()}
48 ${h.end_form()}
44 <div id="rev_range_container" style="display:none"></div>
49 <div id="rev_range_container" style="display:none"></div>
45 <div style="float:right">${h.select('branch_filter',c.branch_name,c.branch_filters)}</div>
50 <div style="float:right">${h.select('branch_filter',c.branch_name,c.branch_filters)}</div>
46 </div>
51 </div>
47
52
48 %for cnt,cs in enumerate(c.pagination):
53 %for cnt,cs in enumerate(c.pagination):
49 <div id="chg_${cnt+1}" class="container ${'tablerow%s' % (cnt%2)}">
54 <div id="chg_${cnt+1}" class="container ${'tablerow%s' % (cnt%2)}">
50 <div class="left">
55 <div class="left">
51 <div>
56 <div>
52 ${h.checkbox(cs.short_id,class_="changeset_range")}
57 ${h.checkbox(cs.short_id,class_="changeset_range")}
53 <span class="tooltip" title="${h.age(cs.date)}"><a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id)}"><span class="changeset_id">${cs.revision}:<span class="changeset_hash">${h.short_id(cs.raw_id)}</span></span></a></span>
58 <span class="tooltip" title="${h.age(cs.date)}"><a href="${h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id)}"><span class="changeset_id">${cs.revision}:<span class="changeset_hash">${h.short_id(cs.raw_id)}</span></span></a></span>
54 </div>
59 </div>
55 <div class="author">
60 <div class="author">
56 <div class="gravatar">
61 <div class="gravatar">
57 <img alt="gravatar" src="${h.gravatar_url(h.email(cs.author),16)}"/>
62 <img alt="gravatar" src="${h.gravatar_url(h.email(cs.author),16)}"/>
58 </div>
63 </div>
59 <div title="${cs.author}" class="user">${h.shorter(h.person(cs.author),22)}</div>
64 <div title="${cs.author}" class="user">${h.shorter(h.person(cs.author),22)}</div>
60 </div>
65 </div>
61 <div class="date">${cs.date}</div>
66 <div class="date">${cs.date}</div>
62 </div>
67 </div>
63 <div class="mid">
68 <div class="mid">
64 <div class="message">${h.urlify_commit(h.wrap_paragraphs(cs.message),c.repo_name,h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div>
69 <div class="message">${h.urlify_commit(h.wrap_paragraphs(cs.message),c.repo_name,h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}</div>
65 <div class="expand"><span class="expandtext">&darr; ${_('show more')} &darr;</span></div>
70 <div class="expand"><span class="expandtext">&darr; ${_('show more')} &darr;</span></div>
66 </div>
71 </div>
67 <div class="right">
72 <div class="right">
68 <div class="changes">
73 <div class="changes">
69 <div id="${cs.raw_id}" style="float:right;" class="changed_total tooltip" title="${_('Affected number of files, click to show more details')}">${len(cs.affected_files)}</div>
74 <div id="${cs.raw_id}" style="float:right;" class="changed_total tooltip" title="${_('Affected number of files, click to show more details')}">${len(cs.affected_files)}</div>
70 <div class="comments-container">
75 <div class="comments-container">
71 %if len(c.comments.get(cs.raw_id,[])) > 0:
76 %if len(c.comments.get(cs.raw_id,[])) > 0:
72 <div class="comments-cnt" title="${('comments')}">
77 <div class="comments-cnt" title="${('comments')}">
73 <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)}">
78 <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)}">
74 <div class="comments-cnt">${len(c.comments[cs.raw_id])}</div>
79 <div class="comments-cnt">${len(c.comments[cs.raw_id])}</div>
75 <img src="${h.url('/images/icons/comments.png')}">
80 <img src="${h.url('/images/icons/comments.png')}">
76 </a>
81 </a>
77 </div>
82 </div>
78 %endif
83 %endif
79 </div>
84 </div>
80 <div class="changeset-status-container">
85 <div class="changeset-status-container">
81 %if c.statuses.get(cs.raw_id):
86 %if c.statuses.get(cs.raw_id):
82 <div title="${_('Changeset status')}" class="changeset-status-lbl">${c.statuses.get(cs.raw_id)[1]}</div>
87 <div title="${_('Changeset status')}" class="changeset-status-lbl">${c.statuses.get(cs.raw_id)[1]}</div>
83 <div class="changeset-status-ico"><img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" /></div>
88 <div class="changeset-status-ico"><img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])}" /></div>
84 %endif
89 %endif
85 </div>
90 </div>
86 </div>
91 </div>
87 %if cs.parents:
92 %if cs.parents:
88 %for p_cs in reversed(cs.parents):
93 %for p_cs in reversed(cs.parents):
89 <div class="parent">${_('Parent')}
94 <div class="parent">${_('Parent')}
90 <span class="changeset_id">${p_cs.revision}:<span class="changeset_hash">${h.link_to(h.short_id(p_cs.raw_id),
95 <span class="changeset_id">${p_cs.revision}:<span class="changeset_hash">${h.link_to(h.short_id(p_cs.raw_id),
91 h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}</span></span>
96 h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)}</span></span>
92 </div>
97 </div>
93 %endfor
98 %endfor
94 %else:
99 %else:
95 <div class="parent">${_('No parents')}</div>
100 <div class="parent">${_('No parents')}</div>
96 %endif
101 %endif
97
102
98 <span class="logtags">
103 <span class="logtags">
99 %if len(cs.parents)>1:
104 %if len(cs.parents)>1:
100 <span class="merge">${_('merge')}</span>
105 <span class="merge">${_('merge')}</span>
101 %endif
106 %endif
102 %if cs.branch:
107 %if cs.branch:
103 <span class="branchtag" title="${'%s %s' % (_('branch'),cs.branch)}">
108 <span class="branchtag" title="${'%s %s' % (_('branch'),cs.branch)}">
104 ${h.link_to(h.shorter(cs.branch),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
109 ${h.link_to(h.shorter(cs.branch),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
105 </span>
110 </span>
106 %endif
111 %endif
107 %if h.is_hg(c.rhodecode_repo):
112 %if h.is_hg(c.rhodecode_repo):
108 %for book in cs.bookmarks:
113 %for book in cs.bookmarks:
109 <span class="bookbook" title="${'%s %s' % (_('bookmark'),book)}">
114 <span class="bookbook" title="${'%s %s' % (_('bookmark'),book)}">
110 ${h.link_to(h.shorter(book),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
115 ${h.link_to(h.shorter(book),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}
111 </span>
116 </span>
112 %endfor
117 %endfor
113 %endif
118 %endif
114 %for tag in cs.tags:
119 %for tag in cs.tags:
115 <span class="tagtag" title="${'%s %s' % (_('tag'),tag)}">
120 <span class="tagtag" title="${'%s %s' % (_('tag'),tag)}">
116 ${h.link_to(h.shorter(tag),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}</span>
121 ${h.link_to(h.shorter(tag),h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id))}</span>
117 %endfor
122 %endfor
118 </span>
123 </span>
119 </div>
124 </div>
120 </div>
125 </div>
121
126
122 %endfor
127 %endfor
123 <div class="pagination-wh pagination-left">
128 <div class="pagination-wh pagination-left">
124 ${c.pagination.pager('$link_previous ~2~ $link_next')}
129 ${c.pagination.pager('$link_previous ~2~ $link_next')}
125 </div>
130 </div>
126 </div>
131 </div>
127 </div>
132 </div>
128
133
129 <script type="text/javascript" src="${h.url('/js/graph.js')}"></script>
134 <script type="text/javascript" src="${h.url('/js/graph.js')}"></script>
130 <script type="text/javascript">
135 <script type="text/javascript">
131 YAHOO.util.Event.onDOMReady(function(){
136 YAHOO.util.Event.onDOMReady(function(){
132
137
133 //Monitor range checkboxes and build a link to changesets
138 //Monitor range checkboxes and build a link to changesets
134 //ranges
139 //ranges
135 var checkboxes = YUD.getElementsByClassName('changeset_range');
140 var checkboxes = YUD.getElementsByClassName('changeset_range');
136 var url_tmpl = "${h.url('changeset_home',repo_name=c.repo_name,revision='__REVRANGE__')}";
141 var url_tmpl = "${h.url('changeset_home',repo_name=c.repo_name,revision='__REVRANGE__')}";
137 YUE.on(checkboxes,'click',function(e){
142 YUE.on(checkboxes,'click',function(e){
138 var checked_checkboxes = [];
143 var checked_checkboxes = [];
139 for (pos in checkboxes){
144 for (pos in checkboxes){
140 if(checkboxes[pos].checked){
145 if(checkboxes[pos].checked){
141 checked_checkboxes.push(checkboxes[pos]);
146 checked_checkboxes.push(checkboxes[pos]);
142 }
147 }
143 }
148 }
144 if(checked_checkboxes.length>1){
149 if(checked_checkboxes.length>1){
145 var rev_end = checked_checkboxes[0].name;
150 var rev_end = checked_checkboxes[0].name;
146 var rev_start = checked_checkboxes[checked_checkboxes.length-1].name;
151 var rev_start = checked_checkboxes[checked_checkboxes.length-1].name;
147
152
148 var url = url_tmpl.replace('__REVRANGE__',
153 var url = url_tmpl.replace('__REVRANGE__',
149 rev_start+'...'+rev_end);
154 rev_start+'...'+rev_end);
150
155
151 var link = "<a href="+url+">${_('Show selected changes __S -> __E')}</a>"
156 var link = "<a href="+url+">${_('Show selected changes __S -> __E')}</a>"
152 link = link.replace('__S',rev_start);
157 link = link.replace('__S',rev_start);
153 link = link.replace('__E',rev_end);
158 link = link.replace('__E',rev_end);
154 YUD.get('rev_range_container').innerHTML = link;
159 YUD.get('rev_range_container').innerHTML = link;
155 YUD.setStyle('rev_range_container','display','');
160 YUD.setStyle('rev_range_container','display','');
156 }
161 }
157 else{
162 else{
158 YUD.setStyle('rev_range_container','display','none');
163 YUD.setStyle('rev_range_container','display','none');
159
164
160 }
165 }
161 });
166 });
162
167
163 var msgs = YUQ('.message');
168 var msgs = YUQ('.message');
164 // get first element height
169 // get first element height
165 var el = YUQ('#graph_content .container')[0];
170 var el = YUQ('#graph_content .container')[0];
166 var row_h = el.clientHeight;
171 var row_h = el.clientHeight;
167 for(var i=0;i<msgs.length;i++){
172 for(var i=0;i<msgs.length;i++){
168 var m = msgs[i];
173 var m = msgs[i];
169
174
170 var h = m.clientHeight;
175 var h = m.clientHeight;
171 var pad = YUD.getStyle(m,'padding');
176 var pad = YUD.getStyle(m,'padding');
172 if(h > row_h){
177 if(h > row_h){
173 var offset = row_h - (h+12);
178 var offset = row_h - (h+12);
174 YUD.setStyle(m.nextElementSibling,'display','block');
179 YUD.setStyle(m.nextElementSibling,'display','block');
175 YUD.setStyle(m.nextElementSibling,'margin-top',offset+'px');
180 YUD.setStyle(m.nextElementSibling,'margin-top',offset+'px');
176 };
181 };
177 }
182 }
178 YUE.on(YUQ('.expand'),'click',function(e){
183 YUE.on(YUQ('.expand'),'click',function(e){
179 var elem = e.currentTarget.parentNode.parentNode;
184 var elem = e.currentTarget.parentNode.parentNode;
180 YUD.setStyle(e.currentTarget,'display','none');
185 YUD.setStyle(e.currentTarget,'display','none');
181 YUD.setStyle(elem,'height','auto');
186 YUD.setStyle(elem,'height','auto');
182
187
183 //redraw the graph, max_w and jsdata are global vars
188 //redraw the graph, max_w and jsdata are global vars
184 set_canvas(max_w);
189 set_canvas(max_w);
185
190
186 var r = new BranchRenderer();
191 var r = new BranchRenderer();
187 r.render(jsdata,max_w);
192 r.render(jsdata,max_w);
188
193
189 })
194 })
190
195
191 // Fetch changeset details
196 // Fetch changeset details
192 YUE.on(YUD.getElementsByClassName('changed_total'),'click',function(e){
197 YUE.on(YUD.getElementsByClassName('changed_total'),'click',function(e){
193 var id = e.currentTarget.id
198 var id = e.currentTarget.id
194 var url = "${h.url('changelog_details',repo_name=c.repo_name,cs='__CS__')}"
199 var url = "${h.url('changelog_details',repo_name=c.repo_name,cs='__CS__')}"
195 var url = url.replace('__CS__',id);
200 var url = url.replace('__CS__',id);
196 ypjax(url,id,function(){tooltip_activate()});
201 ypjax(url,id,function(){tooltip_activate()});
197 });
202 });
198
203
199 // change branch filter
204 // change branch filter
200 YUE.on(YUD.get('branch_filter'),'change',function(e){
205 YUE.on(YUD.get('branch_filter'),'change',function(e){
201 var selected_branch = e.currentTarget.options[e.currentTarget.selectedIndex].value;
206 var selected_branch = e.currentTarget.options[e.currentTarget.selectedIndex].value;
202 var url_main = "${h.url('changelog_home',repo_name=c.repo_name)}";
207 var url_main = "${h.url('changelog_home',repo_name=c.repo_name)}";
203 var url = "${h.url('changelog_home',repo_name=c.repo_name,branch='__BRANCH__')}";
208 var url = "${h.url('changelog_home',repo_name=c.repo_name,branch='__BRANCH__')}";
204 var url = url.replace('__BRANCH__',selected_branch);
209 var url = url.replace('__BRANCH__',selected_branch);
205 if(selected_branch != ''){
210 if(selected_branch != ''){
206 window.location = url;
211 window.location = url;
207 }else{
212 }else{
208 window.location = url_main;
213 window.location = url_main;
209 }
214 }
210
215
211 });
216 });
212
217
213 function set_canvas(heads) {
218 function set_canvas(heads) {
214 var c = document.getElementById('graph_nodes');
219 var c = document.getElementById('graph_nodes');
215 var t = document.getElementById('graph_content');
220 var t = document.getElementById('graph_content');
216 canvas = document.getElementById('graph_canvas');
221 canvas = document.getElementById('graph_canvas');
217 var div_h = t.clientHeight;
222 var div_h = t.clientHeight;
218 c.style.height=div_h+'px';
223 c.style.height=div_h+'px';
219 canvas.setAttribute('height',div_h);
224 canvas.setAttribute('height',div_h);
220 c.style.height=max_w+'px';
225 c.style.height=max_w+'px';
221 canvas.setAttribute('width',max_w);
226 canvas.setAttribute('width',max_w);
222 };
227 };
223 var heads = 1;
228 var heads = 1;
224 var max_heads = 0;
229 var max_heads = 0;
225 var jsdata = ${c.jsdata|n};
230 var jsdata = ${c.jsdata|n};
226
231
227 for( var i=0;i<jsdata.length;i++){
232 for( var i=0;i<jsdata.length;i++){
228 var m = Math.max.apply(Math, jsdata[i][1]);
233 var m = Math.max.apply(Math, jsdata[i][1]);
229 if (m>max_heads){
234 if (m>max_heads){
230 max_heads = m;
235 max_heads = m;
231 }
236 }
232 }
237 }
233 var max_w = Math.max(100,max_heads*25);
238 var max_w = Math.max(100,max_heads*25);
234 set_canvas(max_w);
239 set_canvas(max_w);
235
240
236 var r = new BranchRenderer();
241 var r = new BranchRenderer();
237 r.render(jsdata,max_w);
242 r.render(jsdata,max_w);
238
243
239 });
244 });
240 </script>
245 </script>
241 %else:
246 %else:
242 ${_('There are no changes yet')}
247 ${_('There are no changes yet')}
243 %endif
248 %endif
244 </div>
249 </div>
245 </div>
250 </div>
246 </%def>
251 </%def>
General Comments 0
You need to be logged in to leave comments. Login now