##// END OF EJS Templates
added rss/atom feeds into personalized journal
marcink -
r2397:d815d617 beta
parent child Browse files
Show More
@@ -1,514 +1,519 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
215
216 #ADMIN USERS GROUPS REST ROUTES
216 #ADMIN USERS GROUPS REST ROUTES
217 with rmap.submapper(path_prefix=ADMIN_PREFIX,
217 with rmap.submapper(path_prefix=ADMIN_PREFIX,
218 controller='admin/users_groups') as m:
218 controller='admin/users_groups') as m:
219 m.connect("users_groups", "/users_groups",
219 m.connect("users_groups", "/users_groups",
220 action="create", conditions=dict(method=["POST"]))
220 action="create", conditions=dict(method=["POST"]))
221 m.connect("users_groups", "/users_groups",
221 m.connect("users_groups", "/users_groups",
222 action="index", conditions=dict(method=["GET"]))
222 action="index", conditions=dict(method=["GET"]))
223 m.connect("formatted_users_groups", "/users_groups.{format}",
223 m.connect("formatted_users_groups", "/users_groups.{format}",
224 action="index", conditions=dict(method=["GET"]))
224 action="index", conditions=dict(method=["GET"]))
225 m.connect("new_users_group", "/users_groups/new",
225 m.connect("new_users_group", "/users_groups/new",
226 action="new", conditions=dict(method=["GET"]))
226 action="new", conditions=dict(method=["GET"]))
227 m.connect("formatted_new_users_group", "/users_groups/new.{format}",
227 m.connect("formatted_new_users_group", "/users_groups/new.{format}",
228 action="new", conditions=dict(method=["GET"]))
228 action="new", conditions=dict(method=["GET"]))
229 m.connect("update_users_group", "/users_groups/{id}",
229 m.connect("update_users_group", "/users_groups/{id}",
230 action="update", conditions=dict(method=["PUT"]))
230 action="update", conditions=dict(method=["PUT"]))
231 m.connect("delete_users_group", "/users_groups/{id}",
231 m.connect("delete_users_group", "/users_groups/{id}",
232 action="delete", conditions=dict(method=["DELETE"]))
232 action="delete", conditions=dict(method=["DELETE"]))
233 m.connect("edit_users_group", "/users_groups/{id}/edit",
233 m.connect("edit_users_group", "/users_groups/{id}/edit",
234 action="edit", conditions=dict(method=["GET"]))
234 action="edit", conditions=dict(method=["GET"]))
235 m.connect("formatted_edit_users_group",
235 m.connect("formatted_edit_users_group",
236 "/users_groups/{id}.{format}/edit",
236 "/users_groups/{id}.{format}/edit",
237 action="edit", conditions=dict(method=["GET"]))
237 action="edit", conditions=dict(method=["GET"]))
238 m.connect("users_group", "/users_groups/{id}",
238 m.connect("users_group", "/users_groups/{id}",
239 action="show", conditions=dict(method=["GET"]))
239 action="show", conditions=dict(method=["GET"]))
240 m.connect("formatted_users_group", "/users_groups/{id}.{format}",
240 m.connect("formatted_users_group", "/users_groups/{id}.{format}",
241 action="show", conditions=dict(method=["GET"]))
241 action="show", conditions=dict(method=["GET"]))
242
242
243 #EXTRAS USER ROUTES
243 #EXTRAS USER ROUTES
244 m.connect("users_group_perm", "/users_groups_perm/{id}",
244 m.connect("users_group_perm", "/users_groups_perm/{id}",
245 action="update_perm", conditions=dict(method=["PUT"]))
245 action="update_perm", conditions=dict(method=["PUT"]))
246
246
247 #ADMIN GROUP REST ROUTES
247 #ADMIN GROUP REST ROUTES
248 rmap.resource('group', 'groups',
248 rmap.resource('group', 'groups',
249 controller='admin/groups', path_prefix=ADMIN_PREFIX)
249 controller='admin/groups', path_prefix=ADMIN_PREFIX)
250
250
251 #ADMIN PERMISSIONS REST ROUTES
251 #ADMIN PERMISSIONS REST ROUTES
252 rmap.resource('permission', 'permissions',
252 rmap.resource('permission', 'permissions',
253 controller='admin/permissions', path_prefix=ADMIN_PREFIX)
253 controller='admin/permissions', path_prefix=ADMIN_PREFIX)
254
254
255 ##ADMIN LDAP SETTINGS
255 ##ADMIN LDAP SETTINGS
256 rmap.connect('ldap_settings', '%s/ldap' % ADMIN_PREFIX,
256 rmap.connect('ldap_settings', '%s/ldap' % ADMIN_PREFIX,
257 controller='admin/ldap_settings', action='ldap_settings',
257 controller='admin/ldap_settings', action='ldap_settings',
258 conditions=dict(method=["POST"]))
258 conditions=dict(method=["POST"]))
259
259
260 rmap.connect('ldap_home', '%s/ldap' % ADMIN_PREFIX,
260 rmap.connect('ldap_home', '%s/ldap' % ADMIN_PREFIX,
261 controller='admin/ldap_settings')
261 controller='admin/ldap_settings')
262
262
263 #ADMIN SETTINGS REST ROUTES
263 #ADMIN SETTINGS REST ROUTES
264 with rmap.submapper(path_prefix=ADMIN_PREFIX,
264 with rmap.submapper(path_prefix=ADMIN_PREFIX,
265 controller='admin/settings') as m:
265 controller='admin/settings') as m:
266 m.connect("admin_settings", "/settings",
266 m.connect("admin_settings", "/settings",
267 action="create", conditions=dict(method=["POST"]))
267 action="create", conditions=dict(method=["POST"]))
268 m.connect("admin_settings", "/settings",
268 m.connect("admin_settings", "/settings",
269 action="index", conditions=dict(method=["GET"]))
269 action="index", conditions=dict(method=["GET"]))
270 m.connect("formatted_admin_settings", "/settings.{format}",
270 m.connect("formatted_admin_settings", "/settings.{format}",
271 action="index", conditions=dict(method=["GET"]))
271 action="index", conditions=dict(method=["GET"]))
272 m.connect("admin_new_setting", "/settings/new",
272 m.connect("admin_new_setting", "/settings/new",
273 action="new", conditions=dict(method=["GET"]))
273 action="new", conditions=dict(method=["GET"]))
274 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
274 m.connect("formatted_admin_new_setting", "/settings/new.{format}",
275 action="new", conditions=dict(method=["GET"]))
275 action="new", conditions=dict(method=["GET"]))
276 m.connect("/settings/{setting_id}",
276 m.connect("/settings/{setting_id}",
277 action="update", conditions=dict(method=["PUT"]))
277 action="update", conditions=dict(method=["PUT"]))
278 m.connect("/settings/{setting_id}",
278 m.connect("/settings/{setting_id}",
279 action="delete", conditions=dict(method=["DELETE"]))
279 action="delete", conditions=dict(method=["DELETE"]))
280 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
280 m.connect("admin_edit_setting", "/settings/{setting_id}/edit",
281 action="edit", conditions=dict(method=["GET"]))
281 action="edit", conditions=dict(method=["GET"]))
282 m.connect("formatted_admin_edit_setting",
282 m.connect("formatted_admin_edit_setting",
283 "/settings/{setting_id}.{format}/edit",
283 "/settings/{setting_id}.{format}/edit",
284 action="edit", conditions=dict(method=["GET"]))
284 action="edit", conditions=dict(method=["GET"]))
285 m.connect("admin_setting", "/settings/{setting_id}",
285 m.connect("admin_setting", "/settings/{setting_id}",
286 action="show", conditions=dict(method=["GET"]))
286 action="show", conditions=dict(method=["GET"]))
287 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
287 m.connect("formatted_admin_setting", "/settings/{setting_id}.{format}",
288 action="show", conditions=dict(method=["GET"]))
288 action="show", conditions=dict(method=["GET"]))
289 m.connect("admin_settings_my_account", "/my_account",
289 m.connect("admin_settings_my_account", "/my_account",
290 action="my_account", conditions=dict(method=["GET"]))
290 action="my_account", conditions=dict(method=["GET"]))
291 m.connect("admin_settings_my_account_update", "/my_account_update",
291 m.connect("admin_settings_my_account_update", "/my_account_update",
292 action="my_account_update", conditions=dict(method=["PUT"]))
292 action="my_account_update", conditions=dict(method=["PUT"]))
293 m.connect("admin_settings_create_repository", "/create_repository",
293 m.connect("admin_settings_create_repository", "/create_repository",
294 action="create_repository", conditions=dict(method=["GET"]))
294 action="create_repository", conditions=dict(method=["GET"]))
295
295
296 #NOTIFICATION REST ROUTES
296 #NOTIFICATION REST ROUTES
297 with rmap.submapper(path_prefix=ADMIN_PREFIX,
297 with rmap.submapper(path_prefix=ADMIN_PREFIX,
298 controller='admin/notifications') as m:
298 controller='admin/notifications') as m:
299 m.connect("notifications", "/notifications",
299 m.connect("notifications", "/notifications",
300 action="create", conditions=dict(method=["POST"]))
300 action="create", conditions=dict(method=["POST"]))
301 m.connect("notifications", "/notifications",
301 m.connect("notifications", "/notifications",
302 action="index", conditions=dict(method=["GET"]))
302 action="index", conditions=dict(method=["GET"]))
303 m.connect("notifications_mark_all_read", "/notifications/mark_all_read",
303 m.connect("notifications_mark_all_read", "/notifications/mark_all_read",
304 action="mark_all_read", conditions=dict(method=["GET"]))
304 action="mark_all_read", conditions=dict(method=["GET"]))
305 m.connect("formatted_notifications", "/notifications.{format}",
305 m.connect("formatted_notifications", "/notifications.{format}",
306 action="index", conditions=dict(method=["GET"]))
306 action="index", conditions=dict(method=["GET"]))
307 m.connect("new_notification", "/notifications/new",
307 m.connect("new_notification", "/notifications/new",
308 action="new", conditions=dict(method=["GET"]))
308 action="new", conditions=dict(method=["GET"]))
309 m.connect("formatted_new_notification", "/notifications/new.{format}",
309 m.connect("formatted_new_notification", "/notifications/new.{format}",
310 action="new", conditions=dict(method=["GET"]))
310 action="new", conditions=dict(method=["GET"]))
311 m.connect("/notification/{notification_id}",
311 m.connect("/notification/{notification_id}",
312 action="update", conditions=dict(method=["PUT"]))
312 action="update", conditions=dict(method=["PUT"]))
313 m.connect("/notification/{notification_id}",
313 m.connect("/notification/{notification_id}",
314 action="delete", conditions=dict(method=["DELETE"]))
314 action="delete", conditions=dict(method=["DELETE"]))
315 m.connect("edit_notification", "/notification/{notification_id}/edit",
315 m.connect("edit_notification", "/notification/{notification_id}/edit",
316 action="edit", conditions=dict(method=["GET"]))
316 action="edit", conditions=dict(method=["GET"]))
317 m.connect("formatted_edit_notification",
317 m.connect("formatted_edit_notification",
318 "/notification/{notification_id}.{format}/edit",
318 "/notification/{notification_id}.{format}/edit",
319 action="edit", conditions=dict(method=["GET"]))
319 action="edit", conditions=dict(method=["GET"]))
320 m.connect("notification", "/notification/{notification_id}",
320 m.connect("notification", "/notification/{notification_id}",
321 action="show", conditions=dict(method=["GET"]))
321 action="show", conditions=dict(method=["GET"]))
322 m.connect("formatted_notification", "/notifications/{notification_id}.{format}",
322 m.connect("formatted_notification", "/notifications/{notification_id}.{format}",
323 action="show", conditions=dict(method=["GET"]))
323 action="show", conditions=dict(method=["GET"]))
324
324
325 #ADMIN MAIN PAGES
325 #ADMIN MAIN PAGES
326 with rmap.submapper(path_prefix=ADMIN_PREFIX,
326 with rmap.submapper(path_prefix=ADMIN_PREFIX,
327 controller='admin/admin') as m:
327 controller='admin/admin') as m:
328 m.connect('admin_home', '', action='index')
328 m.connect('admin_home', '', action='index')
329 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
329 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
330 action='add_repo')
330 action='add_repo')
331
331
332 #==========================================================================
332 #==========================================================================
333 # API V2
333 # API V2
334 #==========================================================================
334 #==========================================================================
335 with rmap.submapper(path_prefix=ADMIN_PREFIX,
335 with rmap.submapper(path_prefix=ADMIN_PREFIX,
336 controller='api/api') as m:
336 controller='api/api') as m:
337 m.connect('api', '/api')
337 m.connect('api', '/api')
338
338
339 #USER JOURNAL
339 #USER JOURNAL
340 rmap.connect('journal', '%s/journal' % ADMIN_PREFIX, controller='journal')
340 rmap.connect('journal', '%s/journal' % ADMIN_PREFIX,
341 controller='journal', action='index')
342 rmap.connect('journal_rss', '%s/journal/rss' % ADMIN_PREFIX,
343 controller='journal', action='journal_rss')
344 rmap.connect('journal_atom', '%s/journal/atom' % ADMIN_PREFIX,
345 controller='journal', action='journal_atom')
341
346
342 rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
347 rmap.connect('public_journal', '%s/public_journal' % ADMIN_PREFIX,
343 controller='journal', action="public_journal")
348 controller='journal', action="public_journal")
344
349
345 rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX,
350 rmap.connect('public_journal_rss', '%s/public_journal/rss' % ADMIN_PREFIX,
346 controller='journal', action="public_journal_rss")
351 controller='journal', action="public_journal_rss")
347
352
348 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % ADMIN_PREFIX,
353 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % ADMIN_PREFIX,
349 controller='journal', action="public_journal_rss")
354 controller='journal', action="public_journal_rss")
350
355
351 rmap.connect('public_journal_atom',
356 rmap.connect('public_journal_atom',
352 '%s/public_journal/atom' % ADMIN_PREFIX, controller='journal',
357 '%s/public_journal/atom' % ADMIN_PREFIX, controller='journal',
353 action="public_journal_atom")
358 action="public_journal_atom")
354
359
355 rmap.connect('public_journal_atom_old',
360 rmap.connect('public_journal_atom_old',
356 '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal',
361 '%s/public_journal_atom' % ADMIN_PREFIX, controller='journal',
357 action="public_journal_atom")
362 action="public_journal_atom")
358
363
359 rmap.connect('toggle_following', '%s/toggle_following' % ADMIN_PREFIX,
364 rmap.connect('toggle_following', '%s/toggle_following' % ADMIN_PREFIX,
360 controller='journal', action='toggle_following',
365 controller='journal', action='toggle_following',
361 conditions=dict(method=["POST"]))
366 conditions=dict(method=["POST"]))
362
367
363 #SEARCH
368 #SEARCH
364 rmap.connect('search', '%s/search' % ADMIN_PREFIX, controller='search',)
369 rmap.connect('search', '%s/search' % ADMIN_PREFIX, controller='search',)
365 rmap.connect('search_repo', '%s/search/{search_repo:.*}' % ADMIN_PREFIX,
370 rmap.connect('search_repo', '%s/search/{search_repo:.*}' % ADMIN_PREFIX,
366 controller='search')
371 controller='search')
367
372
368 #LOGIN/LOGOUT/REGISTER/SIGN IN
373 #LOGIN/LOGOUT/REGISTER/SIGN IN
369 rmap.connect('login_home', '%s/login' % ADMIN_PREFIX, controller='login')
374 rmap.connect('login_home', '%s/login' % ADMIN_PREFIX, controller='login')
370 rmap.connect('logout_home', '%s/logout' % ADMIN_PREFIX, controller='login',
375 rmap.connect('logout_home', '%s/logout' % ADMIN_PREFIX, controller='login',
371 action='logout')
376 action='logout')
372
377
373 rmap.connect('register', '%s/register' % ADMIN_PREFIX, controller='login',
378 rmap.connect('register', '%s/register' % ADMIN_PREFIX, controller='login',
374 action='register')
379 action='register')
375
380
376 rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX,
381 rmap.connect('reset_password', '%s/password_reset' % ADMIN_PREFIX,
377 controller='login', action='password_reset')
382 controller='login', action='password_reset')
378
383
379 rmap.connect('reset_password_confirmation',
384 rmap.connect('reset_password_confirmation',
380 '%s/password_reset_confirmation' % ADMIN_PREFIX,
385 '%s/password_reset_confirmation' % ADMIN_PREFIX,
381 controller='login', action='password_reset_confirmation')
386 controller='login', action='password_reset_confirmation')
382
387
383 #FEEDS
388 #FEEDS
384 rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
389 rmap.connect('rss_feed_home', '/{repo_name:.*}/feed/rss',
385 controller='feed', action='rss',
390 controller='feed', action='rss',
386 conditions=dict(function=check_repo))
391 conditions=dict(function=check_repo))
387
392
388 rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
393 rmap.connect('atom_feed_home', '/{repo_name:.*}/feed/atom',
389 controller='feed', action='atom',
394 controller='feed', action='atom',
390 conditions=dict(function=check_repo))
395 conditions=dict(function=check_repo))
391
396
392 #==========================================================================
397 #==========================================================================
393 # REPOSITORY ROUTES
398 # REPOSITORY ROUTES
394 #==========================================================================
399 #==========================================================================
395 rmap.connect('summary_home', '/{repo_name:.*}',
400 rmap.connect('summary_home', '/{repo_name:.*}',
396 controller='summary',
401 controller='summary',
397 conditions=dict(function=check_repo))
402 conditions=dict(function=check_repo))
398
403
399 rmap.connect('repos_group_home', '/{group_name:.*}',
404 rmap.connect('repos_group_home', '/{group_name:.*}',
400 controller='admin/repos_groups', action="show_by_name",
405 controller='admin/repos_groups', action="show_by_name",
401 conditions=dict(function=check_group))
406 conditions=dict(function=check_group))
402
407
403 rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
408 rmap.connect('changeset_home', '/{repo_name:.*}/changeset/{revision}',
404 controller='changeset', revision='tip',
409 controller='changeset', revision='tip',
405 conditions=dict(function=check_repo))
410 conditions=dict(function=check_repo))
406
411
407 rmap.connect('changeset_comment',
412 rmap.connect('changeset_comment',
408 '/{repo_name:.*}/changeset/{revision}/comment',
413 '/{repo_name:.*}/changeset/{revision}/comment',
409 controller='changeset', revision='tip', action='comment',
414 controller='changeset', revision='tip', action='comment',
410 conditions=dict(function=check_repo))
415 conditions=dict(function=check_repo))
411
416
412 rmap.connect('changeset_comment_delete',
417 rmap.connect('changeset_comment_delete',
413 '/{repo_name:.*}/changeset/comment/{comment_id}/delete',
418 '/{repo_name:.*}/changeset/comment/{comment_id}/delete',
414 controller='changeset', action='delete_comment',
419 controller='changeset', action='delete_comment',
415 conditions=dict(function=check_repo, method=["DELETE"]))
420 conditions=dict(function=check_repo, method=["DELETE"]))
416
421
417 rmap.connect('raw_changeset_home',
422 rmap.connect('raw_changeset_home',
418 '/{repo_name:.*}/raw-changeset/{revision}',
423 '/{repo_name:.*}/raw-changeset/{revision}',
419 controller='changeset', action='raw_changeset',
424 controller='changeset', action='raw_changeset',
420 revision='tip', conditions=dict(function=check_repo))
425 revision='tip', conditions=dict(function=check_repo))
421
426
422 rmap.connect('summary_home', '/{repo_name:.*}/summary',
427 rmap.connect('summary_home', '/{repo_name:.*}/summary',
423 controller='summary', conditions=dict(function=check_repo))
428 controller='summary', conditions=dict(function=check_repo))
424
429
425 rmap.connect('shortlog_home', '/{repo_name:.*}/shortlog',
430 rmap.connect('shortlog_home', '/{repo_name:.*}/shortlog',
426 controller='shortlog', conditions=dict(function=check_repo))
431 controller='shortlog', conditions=dict(function=check_repo))
427
432
428 rmap.connect('branches_home', '/{repo_name:.*}/branches',
433 rmap.connect('branches_home', '/{repo_name:.*}/branches',
429 controller='branches', conditions=dict(function=check_repo))
434 controller='branches', conditions=dict(function=check_repo))
430
435
431 rmap.connect('tags_home', '/{repo_name:.*}/tags',
436 rmap.connect('tags_home', '/{repo_name:.*}/tags',
432 controller='tags', conditions=dict(function=check_repo))
437 controller='tags', conditions=dict(function=check_repo))
433
438
434 rmap.connect('bookmarks_home', '/{repo_name:.*}/bookmarks',
439 rmap.connect('bookmarks_home', '/{repo_name:.*}/bookmarks',
435 controller='bookmarks', conditions=dict(function=check_repo))
440 controller='bookmarks', conditions=dict(function=check_repo))
436
441
437 rmap.connect('changelog_home', '/{repo_name:.*}/changelog',
442 rmap.connect('changelog_home', '/{repo_name:.*}/changelog',
438 controller='changelog', conditions=dict(function=check_repo))
443 controller='changelog', conditions=dict(function=check_repo))
439
444
440 rmap.connect('changelog_details', '/{repo_name:.*}/changelog_details/{cs}',
445 rmap.connect('changelog_details', '/{repo_name:.*}/changelog_details/{cs}',
441 controller='changelog', action='changelog_details',
446 controller='changelog', action='changelog_details',
442 conditions=dict(function=check_repo))
447 conditions=dict(function=check_repo))
443
448
444 rmap.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
449 rmap.connect('files_home', '/{repo_name:.*}/files/{revision}/{f_path:.*}',
445 controller='files', revision='tip', f_path='',
450 controller='files', revision='tip', f_path='',
446 conditions=dict(function=check_repo))
451 conditions=dict(function=check_repo))
447
452
448 rmap.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
453 rmap.connect('files_diff_home', '/{repo_name:.*}/diff/{f_path:.*}',
449 controller='files', action='diff', revision='tip', f_path='',
454 controller='files', action='diff', revision='tip', f_path='',
450 conditions=dict(function=check_repo))
455 conditions=dict(function=check_repo))
451
456
452 rmap.connect('files_rawfile_home',
457 rmap.connect('files_rawfile_home',
453 '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
458 '/{repo_name:.*}/rawfile/{revision}/{f_path:.*}',
454 controller='files', action='rawfile', revision='tip',
459 controller='files', action='rawfile', revision='tip',
455 f_path='', conditions=dict(function=check_repo))
460 f_path='', conditions=dict(function=check_repo))
456
461
457 rmap.connect('files_raw_home',
462 rmap.connect('files_raw_home',
458 '/{repo_name:.*}/raw/{revision}/{f_path:.*}',
463 '/{repo_name:.*}/raw/{revision}/{f_path:.*}',
459 controller='files', action='raw', revision='tip', f_path='',
464 controller='files', action='raw', revision='tip', f_path='',
460 conditions=dict(function=check_repo))
465 conditions=dict(function=check_repo))
461
466
462 rmap.connect('files_annotate_home',
467 rmap.connect('files_annotate_home',
463 '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
468 '/{repo_name:.*}/annotate/{revision}/{f_path:.*}',
464 controller='files', action='index', revision='tip',
469 controller='files', action='index', revision='tip',
465 f_path='', annotate=True, conditions=dict(function=check_repo))
470 f_path='', annotate=True, conditions=dict(function=check_repo))
466
471
467 rmap.connect('files_edit_home',
472 rmap.connect('files_edit_home',
468 '/{repo_name:.*}/edit/{revision}/{f_path:.*}',
473 '/{repo_name:.*}/edit/{revision}/{f_path:.*}',
469 controller='files', action='edit', revision='tip',
474 controller='files', action='edit', revision='tip',
470 f_path='', conditions=dict(function=check_repo))
475 f_path='', conditions=dict(function=check_repo))
471
476
472 rmap.connect('files_add_home',
477 rmap.connect('files_add_home',
473 '/{repo_name:.*}/add/{revision}/{f_path:.*}',
478 '/{repo_name:.*}/add/{revision}/{f_path:.*}',
474 controller='files', action='add', revision='tip',
479 controller='files', action='add', revision='tip',
475 f_path='', conditions=dict(function=check_repo))
480 f_path='', conditions=dict(function=check_repo))
476
481
477 rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}',
482 rmap.connect('files_archive_home', '/{repo_name:.*}/archive/{fname}',
478 controller='files', action='archivefile',
483 controller='files', action='archivefile',
479 conditions=dict(function=check_repo))
484 conditions=dict(function=check_repo))
480
485
481 rmap.connect('files_nodelist_home',
486 rmap.connect('files_nodelist_home',
482 '/{repo_name:.*}/nodelist/{revision}/{f_path:.*}',
487 '/{repo_name:.*}/nodelist/{revision}/{f_path:.*}',
483 controller='files', action='nodelist',
488 controller='files', action='nodelist',
484 conditions=dict(function=check_repo))
489 conditions=dict(function=check_repo))
485
490
486 rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings',
491 rmap.connect('repo_settings_delete', '/{repo_name:.*}/settings',
487 controller='settings', action="delete",
492 controller='settings', action="delete",
488 conditions=dict(method=["DELETE"], function=check_repo))
493 conditions=dict(method=["DELETE"], function=check_repo))
489
494
490 rmap.connect('repo_settings_update', '/{repo_name:.*}/settings',
495 rmap.connect('repo_settings_update', '/{repo_name:.*}/settings',
491 controller='settings', action="update",
496 controller='settings', action="update",
492 conditions=dict(method=["PUT"], function=check_repo))
497 conditions=dict(method=["PUT"], function=check_repo))
493
498
494 rmap.connect('repo_settings_home', '/{repo_name:.*}/settings',
499 rmap.connect('repo_settings_home', '/{repo_name:.*}/settings',
495 controller='settings', action='index',
500 controller='settings', action='index',
496 conditions=dict(function=check_repo))
501 conditions=dict(function=check_repo))
497
502
498 rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
503 rmap.connect('repo_fork_create_home', '/{repo_name:.*}/fork',
499 controller='forks', action='fork_create',
504 controller='forks', action='fork_create',
500 conditions=dict(function=check_repo, method=["POST"]))
505 conditions=dict(function=check_repo, method=["POST"]))
501
506
502 rmap.connect('repo_fork_home', '/{repo_name:.*}/fork',
507 rmap.connect('repo_fork_home', '/{repo_name:.*}/fork',
503 controller='forks', action='fork',
508 controller='forks', action='fork',
504 conditions=dict(function=check_repo))
509 conditions=dict(function=check_repo))
505
510
506 rmap.connect('repo_forks_home', '/{repo_name:.*}/forks',
511 rmap.connect('repo_forks_home', '/{repo_name:.*}/forks',
507 controller='forks', action='forks',
512 controller='forks', action='forks',
508 conditions=dict(function=check_repo))
513 conditions=dict(function=check_repo))
509
514
510 rmap.connect('repo_followers_home', '/{repo_name:.*}/followers',
515 rmap.connect('repo_followers_home', '/{repo_name:.*}/followers',
511 controller='followers', action='followers',
516 controller='followers', action='followers',
512 conditions=dict(function=check_repo))
517 conditions=dict(function=check_repo))
513
518
514 return rmap
519 return rmap
@@ -1,240 +1,292 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.controllers.journal
3 rhodecode.controllers.journal
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 Journal controller for pylons
6 Journal controller for pylons
7
7
8 :created_on: Nov 21, 2010
8 :created_on: Nov 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 import logging
25 import logging
26 from itertools import groupby
26 from itertools import groupby
27
27
28 from sqlalchemy import or_
28 from sqlalchemy import or_
29 from sqlalchemy.orm import joinedload
29 from sqlalchemy.orm import joinedload
30 from webhelpers.paginate import Page
30 from webhelpers.paginate import Page
31 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
31 from webhelpers.feedgenerator import Atom1Feed, Rss201rev2Feed
32
32
33 from paste.httpexceptions import HTTPBadRequest
33 from paste.httpexceptions import HTTPBadRequest
34 from pylons import request, tmpl_context as c, response, url
34 from pylons import request, tmpl_context as c, response, url
35 from pylons.i18n.translation import _
35 from pylons.i18n.translation import _
36
36
37 import rhodecode.lib.helpers as h
37 import rhodecode.lib.helpers as h
38 from rhodecode.lib.auth import LoginRequired, NotAnonymous
38 from rhodecode.lib.auth import LoginRequired, NotAnonymous
39 from rhodecode.lib.base import BaseController, render
39 from rhodecode.lib.base import BaseController, render
40 from rhodecode.model.db import UserLog, UserFollowing, Repository, User
40 from rhodecode.model.db import UserLog, UserFollowing, Repository, User
41 from rhodecode.model.meta import Session
41 from rhodecode.model.meta import Session
42 from sqlalchemy.sql.expression import func
42 from sqlalchemy.sql.expression import func
43 from rhodecode.model.scm import ScmModel
43 from rhodecode.model.scm import ScmModel
44
44
45 log = logging.getLogger(__name__)
45 log = logging.getLogger(__name__)
46
46
47
47
48 class JournalController(BaseController):
48 class JournalController(BaseController):
49
49
50 def __before__(self):
50 def __before__(self):
51 super(JournalController, self).__before__()
51 super(JournalController, self).__before__()
52 self.rhodecode_user = self.rhodecode_user
53 self.title = _('%s public journal %s feed') % (c.rhodecode_name, '%s')
54 self.language = 'en-us'
52 self.language = 'en-us'
55 self.ttl = "5"
53 self.ttl = "5"
56 self.feed_nr = 20
54 self.feed_nr = 20
57
55
58 @LoginRequired()
56 @LoginRequired()
59 @NotAnonymous()
57 @NotAnonymous()
60 def index(self):
58 def index(self):
61 # Return a rendered template
59 # Return a rendered template
62 p = int(request.params.get('page', 1))
60 p = int(request.params.get('page', 1))
63
61
64 c.user = User.get(self.rhodecode_user.user_id)
62 c.user = User.get(self.rhodecode_user.user_id)
65 all_repos = self.sa.query(Repository)\
63 all_repos = self.sa.query(Repository)\
66 .filter(Repository.user_id == c.user.user_id)\
64 .filter(Repository.user_id == c.user.user_id)\
67 .order_by(func.lower(Repository.repo_name)).all()
65 .order_by(func.lower(Repository.repo_name)).all()
68
66
69 c.user_repos = ScmModel().get_repos(all_repos)
67 c.user_repos = ScmModel().get_repos(all_repos)
70
68
71 c.following = self.sa.query(UserFollowing)\
69 c.following = self.sa.query(UserFollowing)\
72 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
70 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
73 .options(joinedload(UserFollowing.follows_repository))\
71 .options(joinedload(UserFollowing.follows_repository))\
74 .all()
72 .all()
75
73
76 journal = self._get_journal_data(c.following)
74 journal = self._get_journal_data(c.following)
77
75
78 c.journal_pager = Page(journal, page=p, items_per_page=20)
76 c.journal_pager = Page(journal, page=p, items_per_page=20)
79
77
80 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
78 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
81
79
82 c.journal_data = render('journal/journal_data.html')
80 c.journal_data = render('journal/journal_data.html')
83 if request.environ.get('HTTP_X_PARTIAL_XHR'):
81 if request.environ.get('HTTP_X_PARTIAL_XHR'):
84 return c.journal_data
82 return c.journal_data
85 return render('journal/journal.html')
83 return render('journal/journal.html')
86
84
85 @LoginRequired(api_access=True)
86 def journal_atom(self):
87 """
88 Produce an atom-1.0 feed via feedgenerator module
89 """
90 following = self.sa.query(UserFollowing)\
91 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
92 .options(joinedload(UserFollowing.follows_repository))\
93 .all()
94 return self._atom_feed(following, public=False)
95
96 @LoginRequired(api_access=True)
97 def journal_rss(self):
98 """
99 Produce an rss feed via feedgenerator module
100 """
101 following = self.sa.query(UserFollowing)\
102 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
103 .options(joinedload(UserFollowing.follows_repository))\
104 .all()
105 return self._rss_feed(following, public=False)
106
87 def _get_daily_aggregate(self, journal):
107 def _get_daily_aggregate(self, journal):
88 groups = []
108 groups = []
89 for k, g in groupby(journal, lambda x: x.action_as_day):
109 for k, g in groupby(journal, lambda x: x.action_as_day):
90 user_group = []
110 user_group = []
91 for k2, g2 in groupby(list(g), lambda x: x.user.email):
111 for k2, g2 in groupby(list(g), lambda x: x.user.email):
92 l = list(g2)
112 l = list(g2)
93 user_group.append((l[0].user, l))
113 user_group.append((l[0].user, l))
94
114
95 groups.append((k, user_group,))
115 groups.append((k, user_group,))
96
116
97 return groups
117 return groups
98
118
99 def _get_journal_data(self, following_repos):
119 def _get_journal_data(self, following_repos):
100 repo_ids = [x.follows_repository.repo_id for x in following_repos
120 repo_ids = [x.follows_repository.repo_id for x in following_repos
101 if x.follows_repository is not None]
121 if x.follows_repository is not None]
102 user_ids = [x.follows_user.user_id for x in following_repos
122 user_ids = [x.follows_user.user_id for x in following_repos
103 if x.follows_user is not None]
123 if x.follows_user is not None]
104
124
105 filtering_criterion = None
125 filtering_criterion = None
106
126
107 if repo_ids and user_ids:
127 if repo_ids and user_ids:
108 filtering_criterion = or_(UserLog.repository_id.in_(repo_ids),
128 filtering_criterion = or_(UserLog.repository_id.in_(repo_ids),
109 UserLog.user_id.in_(user_ids))
129 UserLog.user_id.in_(user_ids))
110 if repo_ids and not user_ids:
130 if repo_ids and not user_ids:
111 filtering_criterion = UserLog.repository_id.in_(repo_ids)
131 filtering_criterion = UserLog.repository_id.in_(repo_ids)
112 if not repo_ids and user_ids:
132 if not repo_ids and user_ids:
113 filtering_criterion = UserLog.user_id.in_(user_ids)
133 filtering_criterion = UserLog.user_id.in_(user_ids)
114 if filtering_criterion is not None:
134 if filtering_criterion is not None:
115 journal = self.sa.query(UserLog)\
135 journal = self.sa.query(UserLog)\
116 .options(joinedload(UserLog.user))\
136 .options(joinedload(UserLog.user))\
117 .options(joinedload(UserLog.repository))\
137 .options(joinedload(UserLog.repository))\
118 .filter(filtering_criterion)\
138 .filter(filtering_criterion)\
119 .order_by(UserLog.action_date.desc())
139 .order_by(UserLog.action_date.desc())
120 else:
140 else:
121 journal = []
141 journal = []
122
142
123 return journal
143 return journal
124
144
125 @LoginRequired()
145 @LoginRequired()
126 @NotAnonymous()
146 @NotAnonymous()
127 def toggle_following(self):
147 def toggle_following(self):
128 cur_token = request.POST.get('auth_token')
148 cur_token = request.POST.get('auth_token')
129 token = h.get_token()
149 token = h.get_token()
130 if cur_token == token:
150 if cur_token == token:
131
151
132 user_id = request.POST.get('follows_user_id')
152 user_id = request.POST.get('follows_user_id')
133 if user_id:
153 if user_id:
134 try:
154 try:
135 self.scm_model.toggle_following_user(user_id,
155 self.scm_model.toggle_following_user(user_id,
136 self.rhodecode_user.user_id)
156 self.rhodecode_user.user_id)
137 Session.commit()
157 Session.commit()
138 return 'ok'
158 return 'ok'
139 except:
159 except:
140 raise HTTPBadRequest()
160 raise HTTPBadRequest()
141
161
142 repo_id = request.POST.get('follows_repo_id')
162 repo_id = request.POST.get('follows_repo_id')
143 if repo_id:
163 if repo_id:
144 try:
164 try:
145 self.scm_model.toggle_following_repo(repo_id,
165 self.scm_model.toggle_following_repo(repo_id,
146 self.rhodecode_user.user_id)
166 self.rhodecode_user.user_id)
147 Session.commit()
167 Session.commit()
148 return 'ok'
168 return 'ok'
149 except:
169 except:
150 raise HTTPBadRequest()
170 raise HTTPBadRequest()
151
171
152 log.debug('token mismatch %s vs %s' % (cur_token, token))
172 log.debug('token mismatch %s vs %s' % (cur_token, token))
153 raise HTTPBadRequest()
173 raise HTTPBadRequest()
154
174
155 @LoginRequired()
175 @LoginRequired()
156 def public_journal(self):
176 def public_journal(self):
157 # Return a rendered template
177 # Return a rendered template
158 p = int(request.params.get('page', 1))
178 p = int(request.params.get('page', 1))
159
179
160 c.following = self.sa.query(UserFollowing)\
180 c.following = self.sa.query(UserFollowing)\
161 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
181 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
162 .options(joinedload(UserFollowing.follows_repository))\
182 .options(joinedload(UserFollowing.follows_repository))\
163 .all()
183 .all()
164
184
165 journal = self._get_journal_data(c.following)
185 journal = self._get_journal_data(c.following)
166
186
167 c.journal_pager = Page(journal, page=p, items_per_page=20)
187 c.journal_pager = Page(journal, page=p, items_per_page=20)
168
188
169 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
189 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
170
190
171 c.journal_data = render('journal/journal_data.html')
191 c.journal_data = render('journal/journal_data.html')
172 if request.environ.get('HTTP_X_PARTIAL_XHR'):
192 if request.environ.get('HTTP_X_PARTIAL_XHR'):
173 return c.journal_data
193 return c.journal_data
174 return render('journal/public_journal.html')
194 return render('journal/public_journal.html')
175
195
196 def _atom_feed(self, repos, public=True):
197 journal = self._get_journal_data(repos)
198 if public:
199 _link = url('public_journal_atom', qualified=True)
200 _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
201 'atom feed')
202 else:
203 _link = url('journal_atom', qualified=True)
204 _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'atom feed')
205
206 feed = Atom1Feed(title=_desc,
207 link=_link,
208 description=_desc,
209 language=self.language,
210 ttl=self.ttl)
211
212 for entry in journal[:self.feed_nr]:
213 action, action_extra, ico = h.action_parser(entry, feed=True)
214 title = "%s - %s %s" % (entry.user.short_contact, action(),
215 entry.repository.repo_name)
216 desc = action_extra()
217 _url = None
218 if entry.repository is not None:
219 _url = url('changelog_home',
220 repo_name=entry.repository.repo_name,
221 qualified=True)
222
223 feed.add_item(title=title,
224 pubdate=entry.action_date,
225 link=_url or url('', qualified=True),
226 author_email=entry.user.email,
227 author_name=entry.user.full_contact,
228 description=desc)
229
230 response.content_type = feed.mime_type
231 return feed.writeString('utf-8')
232
233 def _rss_feed(self, repos, public=True):
234 journal = self._get_journal_data(repos)
235 if public:
236 _link = url('public_journal_atom', qualified=True)
237 _desc = '%s %s %s' % (c.rhodecode_name, _('public journal'),
238 'rss feed')
239 else:
240 _link = url('journal_atom', qualified=True)
241 _desc = '%s %s %s' % (c.rhodecode_name, _('journal'), 'rss feed')
242
243 feed = Rss201rev2Feed(title=_desc,
244 link=_link,
245 description=_desc,
246 language=self.language,
247 ttl=self.ttl)
248
249 for entry in journal[:self.feed_nr]:
250 action, action_extra, ico = h.action_parser(entry, feed=True)
251 title = "%s - %s %s" % (entry.user.short_contact, action(),
252 entry.repository.repo_name)
253 desc = action_extra()
254 _url = None
255 if entry.repository is not None:
256 _url = url('changelog_home',
257 repo_name=entry.repository.repo_name,
258 qualified=True)
259
260 feed.add_item(title=title,
261 pubdate=entry.action_date,
262 link=_url or url('', qualified=True),
263 author_email=entry.user.email,
264 author_name=entry.user.full_contact,
265 description=desc)
266
267 response.content_type = feed.mime_type
268 return feed.writeString('utf-8')
269
176 @LoginRequired(api_access=True)
270 @LoginRequired(api_access=True)
177 def public_journal_atom(self):
271 def public_journal_atom(self):
178 """
272 """
179 Produce an atom-1.0 feed via feedgenerator module
273 Produce an atom-1.0 feed via feedgenerator module
180 """
274 """
181 c.following = self.sa.query(UserFollowing)\
275 c.following = self.sa.query(UserFollowing)\
182 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
276 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
183 .options(joinedload(UserFollowing.follows_repository))\
277 .options(joinedload(UserFollowing.follows_repository))\
184 .all()
278 .all()
185
279
186 journal = self._get_journal_data(c.following)
280 return self._atom_feed(c.following)
187
188 feed = Atom1Feed(title=self.title % 'atom',
189 link=url('public_journal_atom', qualified=True),
190 description=_('Public journal'),
191 language=self.language,
192 ttl=self.ttl)
193
194 for entry in journal[:self.feed_nr]:
195 action, action_extra, ico = h.action_parser(entry, feed=True)
196 title = "%s - %s %s" % (entry.user.short_contact, action(),
197 entry.repository.repo_name)
198 desc = action_extra()
199 feed.add_item(title=title,
200 pubdate=entry.action_date,
201 link=url('', qualified=True),
202 author_email=entry.user.email,
203 author_name=entry.user.full_contact,
204 description=desc)
205
206 response.content_type = feed.mime_type
207 return feed.writeString('utf-8')
208
281
209 @LoginRequired(api_access=True)
282 @LoginRequired(api_access=True)
210 def public_journal_rss(self):
283 def public_journal_rss(self):
211 """
284 """
212 Produce an rss2 feed via feedgenerator module
285 Produce an rss2 feed via feedgenerator module
213 """
286 """
214 c.following = self.sa.query(UserFollowing)\
287 c.following = self.sa.query(UserFollowing)\
215 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
288 .filter(UserFollowing.user_id == self.rhodecode_user.user_id)\
216 .options(joinedload(UserFollowing.follows_repository))\
289 .options(joinedload(UserFollowing.follows_repository))\
217 .all()
290 .all()
218
291
219 journal = self._get_journal_data(c.following)
292 return self._rss_feed(c.following)
220
221 feed = Rss201rev2Feed(title=self.title % 'rss',
222 link=url('public_journal_rss', qualified=True),
223 description=_('Public journal'),
224 language=self.language,
225 ttl=self.ttl)
226
227 for entry in journal[:self.feed_nr]:
228 action, action_extra, ico = h.action_parser(entry, feed=True)
229 title = "%s - %s %s" % (entry.user.short_contact, action(),
230 entry.repository.repo_name)
231 desc = action_extra()
232 feed.add_item(title=title,
233 pubdate=entry.action_date,
234 link=url('', qualified=True),
235 author_email=entry.user.email,
236 author_name=entry.user.full_contact,
237 description=desc)
238
239 response.content_type = feed.mime_type
240 return feed.writeString('utf-8')
@@ -1,220 +1,225 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3 <%def name="title()">
3 <%def name="title()">
4 ${_('Journal')} - ${c.rhodecode_name}
4 ${_('Journal')} - ${c.rhodecode_name}
5 </%def>
5 </%def>
6 <%def name="breadcrumbs()">
6 <%def name="breadcrumbs()">
7 ${c.rhodecode_name}
7 ${c.rhodecode_name}
8 </%def>
8 </%def>
9 <%def name="page_nav()">
9 <%def name="page_nav()">
10 ${self.menu('home')}
10 ${self.menu('home')}
11 </%def>
11 </%def>
12 <%def name="main()">
12 <%def name="main()">
13
13
14 <div class="box box-left">
14 <div class="box box-left">
15 <!-- box / title -->
15 <!-- box / title -->
16 <div class="title">
16 <div class="title">
17 <h5>${_('Journal')}</h5>
17 <h5>${_('Journal')}</h5>
18 <ul class="links">
18 <ul class="links">
19 <li>
19 <li>
20 <span><a id="refresh" href="${h.url('journal')}"><img class="icon" title="${_('Refresh')}" alt="${_('Refresh')}" src="${h.url('/images/icons/arrow_refresh.png')}"/>
20 <span><a id="refresh" href="${h.url('journal')}"><img class="icon" title="${_('Refresh')}" alt="${_('Refresh')}" src="${h.url('/images/icons/arrow_refresh.png')}"/></a></span>
21 </a></span>
22 </li>
21 </li>
22 <li>
23 <span><a href="${h.url('journal_rss')}"><img class="icon" title="${_('RSS feed')}" alt="${_('RSS feed')}" src="${h.url('/images/icons/atom.png')}"/></a></span>
24 </li>
25 <li>
26 <span><a href="${h.url('journal_atom')}"><img class="icon" title="${_('ATOM feed')}" alt="${_('ATOM feed')}" src="${h.url('/images/icons/rss_16.png')}"/></a></span>
27 </li>
23 </ul>
28 </ul>
24 </div>
29 </div>
25 <div id="journal">${c.journal_data}</div>
30 <div id="journal">${c.journal_data}</div>
26 </div>
31 </div>
27 <div class="box box-right">
32 <div class="box box-right">
28 <!-- box / title -->
33 <!-- box / title -->
29 <div class="title">
34 <div class="title">
30 <h5>
35 <h5>
31 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/>
36 <input class="q_filter_box" id="q_filter" size="15" type="text" name="filter" value="${_('quick filter...')}"/>
32 <a id="show_my" class="link-white" href="#my">${_('My repos')}</a> / <a id="show_watched" class="link-white" href="#watched">${_('Watched')}</a>
37 <a id="show_my" class="link-white" href="#my">${_('My repos')}</a> / <a id="show_watched" class="link-white" href="#watched">${_('Watched')}</a>
33 </h5>
38 </h5>
34 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
39 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
35 <ul class="links">
40 <ul class="links">
36 <li>
41 <li>
37 <span>${h.link_to(_('ADD'),h.url('admin_settings_create_repository'))}</span>
42 <span>${h.link_to(_('ADD'),h.url('admin_settings_create_repository'))}</span>
38 </li>
43 </li>
39 </ul>
44 </ul>
40 %endif
45 %endif
41 </div>
46 </div>
42 <!-- end box / title -->
47 <!-- end box / title -->
43 <div id="my" class="table">
48 <div id="my" class="table">
44 %if c.user_repos:
49 %if c.user_repos:
45 <div id='repos_list_wrap' class="yui-skin-sam">
50 <div id='repos_list_wrap' class="yui-skin-sam">
46 <table id="repos_list">
51 <table id="repos_list">
47 <thead>
52 <thead>
48 <tr>
53 <tr>
49 <th></th>
54 <th></th>
50 <th class="left">${_('Name')}</th>
55 <th class="left">${_('Name')}</th>
51 <th class="left">${_('Revision')}</th>
56 <th class="left">${_('Revision')}</th>
52 <th class="left">${_('Action')}</th>
57 <th class="left">${_('Action')}</th>
53 <th class="left">${_('Action')}</th>
58 <th class="left">${_('Action')}</th>
54 </thead>
59 </thead>
55 <tbody>
60 <tbody>
56 <%namespace name="dt" file="/data_table/_dt_elements.html"/>
61 <%namespace name="dt" file="/data_table/_dt_elements.html"/>
57 %for repo in c.user_repos:
62 %for repo in c.user_repos:
58 <tr>
63 <tr>
59 ##QUICK MENU
64 ##QUICK MENU
60 <td class="quick_repo_menu">
65 <td class="quick_repo_menu">
61 ${dt.quick_menu(repo['name'])}
66 ${dt.quick_menu(repo['name'])}
62 </td>
67 </td>
63 ##REPO NAME AND ICONS
68 ##REPO NAME AND ICONS
64 <td class="reponame">
69 <td class="reponame">
65 ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],repo['dbrepo_fork'].get('repo_name'))}
70 ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],repo['dbrepo_fork'].get('repo_name'))}
66 </td>
71 </td>
67 ##LAST REVISION
72 ##LAST REVISION
68 <td>
73 <td>
69 ${dt.revision(repo['name'],repo['rev'],repo['tip'],repo['author'],repo['last_msg'])}
74 ${dt.revision(repo['name'],repo['rev'],repo['tip'],repo['author'],repo['last_msg'])}
70 </td>
75 </td>
71 ##
76 ##
72 <td><a href="${h.url('repo_settings_home',repo_name=repo['name'])}" title="${_('edit')}"><img class="icon" alt="${_('private')}" src="${h.url('/images/icons/application_form_edit.png')}"/></a></td>
77 <td><a href="${h.url('repo_settings_home',repo_name=repo['name'])}" title="${_('edit')}"><img class="icon" alt="${_('private')}" src="${h.url('/images/icons/application_form_edit.png')}"/></a></td>
73 <td>
78 <td>
74 ${h.form(url('repo_settings_delete', repo_name=repo['name']),method='delete')}
79 ${h.form(url('repo_settings_delete', repo_name=repo['name']),method='delete')}
75 ${h.submit('remove_%s' % repo['name'],'',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
80 ${h.submit('remove_%s' % repo['name'],'',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
76 ${h.end_form()}
81 ${h.end_form()}
77 </td>
82 </td>
78 </tr>
83 </tr>
79 %endfor
84 %endfor
80 </tbody>
85 </tbody>
81 </table>
86 </table>
82 </div>
87 </div>
83 %else:
88 %else:
84 <div style="padding:5px 0px 10px 0px;">
89 <div style="padding:5px 0px 10px 0px;">
85 ${_('No repositories yet')}
90 ${_('No repositories yet')}
86 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
91 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
87 ${h.link_to(_('create one now'),h.url('admin_settings_create_repository'),class_="ui-btn")}
92 ${h.link_to(_('create one now'),h.url('admin_settings_create_repository'),class_="ui-btn")}
88 %endif
93 %endif
89 </div>
94 </div>
90 %endif
95 %endif
91 </div>
96 </div>
92
97
93 <div id="watched" class="table" style="display:none">
98 <div id="watched" class="table" style="display:none">
94 %if c.following:
99 %if c.following:
95 <table>
100 <table>
96 <thead>
101 <thead>
97 <tr>
102 <tr>
98 <th class="left">${_('Name')}</th>
103 <th class="left">${_('Name')}</th>
99 </thead>
104 </thead>
100 <tbody>
105 <tbody>
101 %for entry in c.following:
106 %for entry in c.following:
102 <tr>
107 <tr>
103 <td>
108 <td>
104 %if entry.follows_user_id:
109 %if entry.follows_user_id:
105 <img title="${_('following user')}" alt="${_('user')}" src="${h.url('/images/icons/user.png')}"/>
110 <img title="${_('following user')}" alt="${_('user')}" src="${h.url('/images/icons/user.png')}"/>
106 ${entry.follows_user.full_contact}
111 ${entry.follows_user.full_contact}
107 %endif
112 %endif
108
113
109 %if entry.follows_repo_id:
114 %if entry.follows_repo_id:
110 <div style="float:right;padding-right:5px">
115 <div style="float:right;padding-right:5px">
111 <span id="follow_toggle_${entry.follows_repository.repo_id}" class="following" title="${_('Stop following this repository')}"
116 <span id="follow_toggle_${entry.follows_repository.repo_id}" class="following" title="${_('Stop following this repository')}"
112 onclick="javascript:toggleFollowingRepo(this,${entry.follows_repository.repo_id},'${str(h.get_token())}')">
117 onclick="javascript:toggleFollowingRepo(this,${entry.follows_repository.repo_id},'${str(h.get_token())}')">
113 </span>
118 </span>
114 </div>
119 </div>
115
120
116 %if h.is_hg(entry.follows_repository):
121 %if h.is_hg(entry.follows_repository):
117 <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
122 <img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url('/images/icons/hgicon.png')}"/>
118 %elif h.is_git(entry.follows_repository):
123 %elif h.is_git(entry.follows_repository):
119 <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
124 <img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url('/images/icons/giticon.png')}"/>
120 %endif
125 %endif
121
126
122 %if entry.follows_repository.private:
127 %if entry.follows_repository.private:
123 <img class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
128 <img class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url('/images/icons/lock.png')}"/>
124 %else:
129 %else:
125 <img class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
130 <img class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url('/images/icons/lock_open.png')}"/>
126 %endif
131 %endif
127 <span class="watched_repo">
132 <span class="watched_repo">
128 ${h.link_to(entry.follows_repository.repo_name,h.url('summary_home',repo_name=entry.follows_repository.repo_name))}
133 ${h.link_to(entry.follows_repository.repo_name,h.url('summary_home',repo_name=entry.follows_repository.repo_name))}
129 </span>
134 </span>
130 %endif
135 %endif
131 </td>
136 </td>
132 </tr>
137 </tr>
133 %endfor
138 %endfor
134 </tbody>
139 </tbody>
135 </table>
140 </table>
136 %else:
141 %else:
137 <div style="padding:5px 0px 10px 0px;">
142 <div style="padding:5px 0px 10px 0px;">
138 ${_('You are not following any users or repositories')}
143 ${_('You are not following any users or repositories')}
139 </div>
144 </div>
140 %endif
145 %endif
141 </div>
146 </div>
142 </div>
147 </div>
143
148
144 <script type="text/javascript">
149 <script type="text/javascript">
145
150
146 YUE.on('show_my','click',function(e){
151 YUE.on('show_my','click',function(e){
147 YUD.setStyle('watched','display','none');
152 YUD.setStyle('watched','display','none');
148 YUD.setStyle('my','display','');
153 YUD.setStyle('my','display','');
149 var nodes = YUQ('#my tr td a.repo_name');
154 var nodes = YUQ('#my tr td a.repo_name');
150 var target = 'q_filter';
155 var target = 'q_filter';
151 var func = function(node){
156 var func = function(node){
152 return node.parentNode.parentNode.parentNode.parentNode;
157 return node.parentNode.parentNode.parentNode.parentNode;
153 }
158 }
154 q_filter(target,nodes,func);
159 q_filter(target,nodes,func);
155 YUE.preventDefault(e);
160 YUE.preventDefault(e);
156 })
161 })
157 YUE.on('show_watched','click',function(e){
162 YUE.on('show_watched','click',function(e){
158 YUD.setStyle('my','display','none');
163 YUD.setStyle('my','display','none');
159 YUD.setStyle('watched','display','');
164 YUD.setStyle('watched','display','');
160 var nodes = YUQ('#watched .watched_repo a');
165 var nodes = YUQ('#watched .watched_repo a');
161 var target = 'q_filter';
166 var target = 'q_filter';
162 var func = function(node){
167 var func = function(node){
163 return node.parentNode.parentNode;
168 return node.parentNode.parentNode;
164 }
169 }
165 q_filter(target,nodes,func);
170 q_filter(target,nodes,func);
166 YUE.preventDefault(e);
171 YUE.preventDefault(e);
167 })
172 })
168 YUE.on('refresh','click',function(e){
173 YUE.on('refresh','click',function(e){
169 ypjax(e.currentTarget.href,"journal",function(){show_more_event();tooltip_activate();});
174 ypjax(e.currentTarget.href,"journal",function(){show_more_event();tooltip_activate();});
170 YUE.preventDefault(e);
175 YUE.preventDefault(e);
171 });
176 });
172
177
173
178
174 // main table sorting
179 // main table sorting
175 var myColumnDefs = [
180 var myColumnDefs = [
176 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
181 {key:"menu",label:"",sortable:false,className:"quick_repo_menu hidden"},
177 {key:"name",label:"${_('Name')}",sortable:true,
182 {key:"name",label:"${_('Name')}",sortable:true,
178 sortOptions: { sortFunction: nameSort }},
183 sortOptions: { sortFunction: nameSort }},
179 {key:"tip",label:"${_('Tip')}",sortable:true,
184 {key:"tip",label:"${_('Tip')}",sortable:true,
180 sortOptions: { sortFunction: revisionSort }},
185 sortOptions: { sortFunction: revisionSort }},
181 {key:"action1",label:"",sortable:false},
186 {key:"action1",label:"",sortable:false},
182 {key:"action2",label:"",sortable:false},
187 {key:"action2",label:"",sortable:false},
183 ];
188 ];
184
189
185 var myDataSource = new YAHOO.util.DataSource(YUD.get("repos_list"));
190 var myDataSource = new YAHOO.util.DataSource(YUD.get("repos_list"));
186
191
187 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
192 myDataSource.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
188
193
189 myDataSource.responseSchema = {
194 myDataSource.responseSchema = {
190 fields: [
195 fields: [
191 {key:"menu"},
196 {key:"menu"},
192 {key:"name"},
197 {key:"name"},
193 {key:"tip"},
198 {key:"tip"},
194 {key:"action1"},
199 {key:"action1"},
195 {key:"action2"}
200 {key:"action2"}
196 ]
201 ]
197 };
202 };
198
203
199 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,
204 var myDataTable = new YAHOO.widget.DataTable("repos_list_wrap", myColumnDefs, myDataSource,
200 {
205 {
201 sortedBy:{key:"name",dir:"asc"},
206 sortedBy:{key:"name",dir:"asc"},
202 MSG_SORTASC:"${_('Click to sort ascending')}",
207 MSG_SORTASC:"${_('Click to sort ascending')}",
203 MSG_SORTDESC:"${_('Click to sort descending')}",
208 MSG_SORTDESC:"${_('Click to sort descending')}",
204 MSG_EMPTY:"${_('No records found.')}",
209 MSG_EMPTY:"${_('No records found.')}",
205 MSG_ERROR:"${_('Data error.')}",
210 MSG_ERROR:"${_('Data error.')}",
206 MSG_LOADING:"${_('Loading...')}",
211 MSG_LOADING:"${_('Loading...')}",
207 }
212 }
208 );
213 );
209 myDataTable.subscribe('postRenderEvent',function(oArgs) {
214 myDataTable.subscribe('postRenderEvent',function(oArgs) {
210 tooltip_activate();
215 tooltip_activate();
211 quick_repo_menu();
216 quick_repo_menu();
212 var func = function(node){
217 var func = function(node){
213 return node.parentNode.parentNode.parentNode.parentNode;
218 return node.parentNode.parentNode.parentNode.parentNode;
214 }
219 }
215 q_filter('q_filter',YUQ('#my tr td a.repo_name'),func);
220 q_filter('q_filter',YUQ('#my tr td a.repo_name'),func);
216 });
221 });
217
222
218
223
219 </script>
224 </script>
220 </%def>
225 </%def>
@@ -1,41 +1,40 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2 <%inherit file="/base/base.html"/>
2 <%inherit file="/base/base.html"/>
3 <%def name="title()">
3 <%def name="title()">
4 ${_('Journal')} - ${c.rhodecode_name}
4 ${_('Journal')} - ${c.rhodecode_name}
5 </%def>
5 </%def>
6 <%def name="breadcrumbs()">
6 <%def name="breadcrumbs()">
7 ${c.rhodecode_name}
7 ${c.rhodecode_name}
8 </%def>
8 </%def>
9 <%def name="page_nav()">
9 <%def name="page_nav()">
10 ${self.menu('home')}
10 ${self.menu('home')}
11 </%def>
11 </%def>
12 <%def name="main()">
12 <%def name="main()">
13
13
14 <div class="box">
14 <div class="box">
15 <!-- box / title -->
15 <!-- box / title -->
16 <div class="title">
16 <div class="title">
17 <h5>${_('Public Journal')}</h5>
17 <h5>${_('Public Journal')}</h5>
18 <ul class="links">
18 <ul class="links">
19 <li>
19 <li>
20 <span>${h.link_to(_('RSS'),h.url('public_journal_rss'),class_='rss_icon')}</span>
20 <span><a href="${h.url('public_journal_rss')}"><img class="icon" title="${_('RSS feed')}" alt="${_('RSS feed')}" src="${h.url('/images/icons/atom.png')}"/></a></span>
21 </li>
21 </li>
22 <li>
22 <li>
23 <span>${h.link_to(_('Atom'),h.url('public_journal_atom'),class_='atom_icon')}</span>
23 <span><a href="${h.url('public_journal_atom')}"><img class="icon" title="${_('ATOM feed')}" alt="${_('ATOM feed')}" src="${h.url('/images/icons/rss_16.png')}"/></a></span>
24 </li>
24 </li>
25
26 </ul>
25 </ul>
27
26
28 </div>
27 </div>
29 <script type="text/javascript">
28 <script type="text/javascript">
30 function show_more_event(){
29 function show_more_event(){
31 YUE.on(YUD.getElementsByClassName('show_more'),'click',function(e){
30 YUE.on(YUD.getElementsByClassName('show_more'),'click',function(e){
32 var el = e.target;
31 var el = e.target;
33 YUD.setStyle(YUD.get(el.id.substring(1)),'display','');
32 YUD.setStyle(YUD.get(el.id.substring(1)),'display','');
34 YUD.setStyle(el.parentNode,'display','none');
33 YUD.setStyle(el.parentNode,'display','none');
35 });
34 });
36 }
35 }
37 </script>
36 </script>
38 <div id="journal">${c.journal_data}</div>
37 <div id="journal">${c.journal_data}</div>
39 </div>
38 </div>
40
39
41 </%def>
40 </%def>
General Comments 0
You need to be logged in to leave comments. Login now