##// END OF EJS Templates
artifacts: added admin panel to manage all artifacts in an instance.
milka -
r4661:df96df1f default
parent child Browse files
Show More
@@ -1,269 +1,270 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2020 RhodeCode GmbH
3 # Copyright (C) 2016-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import os
21 import os
22 import time
22 import time
23 import errno
23 import errno
24 import hashlib
24 import hashlib
25
25
26 from rhodecode.lib.ext_json import json
26 from rhodecode.lib.ext_json import json
27 from rhodecode.apps.file_store import utils
27 from rhodecode.apps.file_store import utils
28 from rhodecode.apps.file_store.extensions import resolve_extensions
28 from rhodecode.apps.file_store.extensions import resolve_extensions
29 from rhodecode.apps.file_store.exceptions import (
29 from rhodecode.apps.file_store.exceptions import (
30 FileNotAllowedException, FileOverSizeException)
30 FileNotAllowedException, FileOverSizeException)
31
31
32 METADATA_VER = 'v1'
32 METADATA_VER = 'v1'
33
33
34
34
35 def safe_make_dirs(dir_path):
35 def safe_make_dirs(dir_path):
36 if not os.path.exists(dir_path):
36 if not os.path.exists(dir_path):
37 try:
37 try:
38 os.makedirs(dir_path)
38 os.makedirs(dir_path)
39 except OSError as e:
39 except OSError as e:
40 if e.errno != errno.EEXIST:
40 if e.errno != errno.EEXIST:
41 raise
41 raise
42 return
42 return
43
43
44
44
45 class LocalFileStorage(object):
45 class LocalFileStorage(object):
46
46
47 @classmethod
47 @classmethod
48 def apply_counter(cls, counter, filename):
48 def apply_counter(cls, counter, filename):
49 name_counted = '%d-%s' % (counter, filename)
49 name_counted = '%d-%s' % (counter, filename)
50 return name_counted
50 return name_counted
51
51
52 @classmethod
52 @classmethod
53 def resolve_name(cls, name, directory):
53 def resolve_name(cls, name, directory):
54 """
54 """
55 Resolves a unique name and the correct path. If a filename
55 Resolves a unique name and the correct path. If a filename
56 for that path already exists then a numeric prefix with values > 0 will be
56 for that path already exists then a numeric prefix with values > 0 will be
57 added, for example test.jpg -> 1-test.jpg etc. initially file would have 0 prefix.
57 added, for example test.jpg -> 1-test.jpg etc. initially file would have 0 prefix.
58
58
59 :param name: base name of file
59 :param name: base name of file
60 :param directory: absolute directory path
60 :param directory: absolute directory path
61 """
61 """
62
62
63 counter = 0
63 counter = 0
64 while True:
64 while True:
65 name_counted = cls.apply_counter(counter, name)
65 name_counted = cls.apply_counter(counter, name)
66
66
67 # sub_store prefix to optimize disk usage, e.g some_path/ab/final_file
67 # sub_store prefix to optimize disk usage, e.g some_path/ab/final_file
68 sub_store = cls._sub_store_from_filename(name_counted)
68 sub_store = cls._sub_store_from_filename(name_counted)
69 sub_store_path = os.path.join(directory, sub_store)
69 sub_store_path = os.path.join(directory, sub_store)
70 safe_make_dirs(sub_store_path)
70 safe_make_dirs(sub_store_path)
71
71
72 path = os.path.join(sub_store_path, name_counted)
72 path = os.path.join(sub_store_path, name_counted)
73 if not os.path.exists(path):
73 if not os.path.exists(path):
74 return name_counted, path
74 return name_counted, path
75 counter += 1
75 counter += 1
76
76
77 @classmethod
77 @classmethod
78 def _sub_store_from_filename(cls, filename):
78 def _sub_store_from_filename(cls, filename):
79 return filename[:2]
79 return filename[:2]
80
80
81 @classmethod
81 @classmethod
82 def calculate_path_hash(cls, file_path):
82 def calculate_path_hash(cls, file_path):
83 """
83 """
84 Efficient calculation of file_path sha256 sum
84 Efficient calculation of file_path sha256 sum
85
85
86 :param file_path:
86 :param file_path:
87 :return: sha256sum
87 :return: sha256sum
88 """
88 """
89 digest = hashlib.sha256()
89 digest = hashlib.sha256()
90 with open(file_path, 'rb') as f:
90 with open(file_path, 'rb') as f:
91 for chunk in iter(lambda: f.read(1024 * 100), b""):
91 for chunk in iter(lambda: f.read(1024 * 100), b""):
92 digest.update(chunk)
92 digest.update(chunk)
93
93
94 return digest.hexdigest()
94 return digest.hexdigest()
95
95
96 def __init__(self, base_path, extension_groups=None):
96 def __init__(self, base_path, extension_groups=None):
97
97
98 """
98 """
99 Local file storage
99 Local file storage
100
100
101 :param base_path: the absolute base path where uploads are stored
101 :param base_path: the absolute base path where uploads are stored
102 :param extension_groups: extensions string
102 :param extension_groups: extensions string
103 """
103 """
104
104
105 extension_groups = extension_groups or ['any']
105 extension_groups = extension_groups or ['any']
106 self.base_path = base_path
106 self.base_path = base_path
107 self.extensions = resolve_extensions([], groups=extension_groups)
107 self.extensions = resolve_extensions([], groups=extension_groups)
108
108
109 def __repr__(self):
109 def __repr__(self):
110 return '{}@{}'.format(self.__class__, self.base_path)
110 return '{}@{}'.format(self.__class__, self.base_path)
111
111
112 def store_path(self, filename):
112 def store_path(self, filename):
113 """
113 """
114 Returns absolute file path of the filename, joined to the
114 Returns absolute file path of the filename, joined to the
115 base_path.
115 base_path.
116
116
117 :param filename: base name of file
117 :param filename: base name of file
118 """
118 """
119 prefix_dir = ''
119 prefix_dir = ''
120 if '/' in filename:
120 if '/' in filename:
121 prefix_dir, filename = filename.split('/')
121 prefix_dir, filename = filename.split('/')
122 sub_store = self._sub_store_from_filename(filename)
122 sub_store = self._sub_store_from_filename(filename)
123 else:
123 else:
124 sub_store = self._sub_store_from_filename(filename)
124 sub_store = self._sub_store_from_filename(filename)
125 return os.path.join(self.base_path, prefix_dir, sub_store, filename)
125 return os.path.join(self.base_path, prefix_dir, sub_store, filename)
126
126
127 def delete(self, filename):
127 def delete(self, filename):
128 """
128 """
129 Deletes the filename. Filename is resolved with the
129 Deletes the filename. Filename is resolved with the
130 absolute path based on base_path. If file does not exist,
130 absolute path based on base_path. If file does not exist,
131 returns **False**, otherwise **True**
131 returns **False**, otherwise **True**
132
132
133 :param filename: base name of file
133 :param filename: base name of file
134 """
134 """
135 if self.exists(filename):
135 if self.exists(filename):
136 os.remove(self.store_path(filename))
136 os.remove(self.store_path(filename))
137 return True
137 return True
138 return False
138 return False
139
139
140 def exists(self, filename):
140 def exists(self, filename):
141 """
141 """
142 Checks if file exists. Resolves filename's absolute
142 Checks if file exists. Resolves filename's absolute
143 path based on base_path.
143 path based on base_path.
144
144
145 :param filename: file_uid name of file, e.g 0-f62b2b2d-9708-4079-a071-ec3f958448d4.svg
145 :param filename: file_uid name of file, e.g 0-f62b2b2d-9708-4079-a071-ec3f958448d4.svg
146 """
146 """
147 return os.path.exists(self.store_path(filename))
147 return os.path.exists(self.store_path(filename))
148
148
149 def filename_allowed(self, filename, extensions=None):
149 def filename_allowed(self, filename, extensions=None):
150 """Checks if a filename has an allowed extension
150 """Checks if a filename has an allowed extension
151
151
152 :param filename: base name of file
152 :param filename: base name of file
153 :param extensions: iterable of extensions (or self.extensions)
153 :param extensions: iterable of extensions (or self.extensions)
154 """
154 """
155 _, ext = os.path.splitext(filename)
155 _, ext = os.path.splitext(filename)
156 return self.extension_allowed(ext, extensions)
156 return self.extension_allowed(ext, extensions)
157
157
158 def extension_allowed(self, ext, extensions=None):
158 def extension_allowed(self, ext, extensions=None):
159 """
159 """
160 Checks if an extension is permitted. Both e.g. ".jpg" and
160 Checks if an extension is permitted. Both e.g. ".jpg" and
161 "jpg" can be passed in. Extension lookup is case-insensitive.
161 "jpg" can be passed in. Extension lookup is case-insensitive.
162
162
163 :param ext: extension to check
163 :param ext: extension to check
164 :param extensions: iterable of extensions to validate against (or self.extensions)
164 :param extensions: iterable of extensions to validate against (or self.extensions)
165 """
165 """
166 def normalize_ext(_ext):
166 def normalize_ext(_ext):
167 if _ext.startswith('.'):
167 if _ext.startswith('.'):
168 _ext = _ext[1:]
168 _ext = _ext[1:]
169 return _ext.lower()
169 return _ext.lower()
170
170
171 extensions = extensions or self.extensions
171 extensions = extensions or self.extensions
172 if not extensions:
172 if not extensions:
173 return True
173 return True
174
174
175 ext = normalize_ext(ext)
175 ext = normalize_ext(ext)
176
176
177 return ext in [normalize_ext(x) for x in extensions]
177 return ext in [normalize_ext(x) for x in extensions]
178
178
179 def save_file(self, file_obj, filename, directory=None, extensions=None,
179 def save_file(self, file_obj, filename, directory=None, extensions=None,
180 extra_metadata=None, max_filesize=None, randomized_name=True, **kwargs):
180 extra_metadata=None, max_filesize=None, randomized_name=True, **kwargs):
181 """
181 """
182 Saves a file object to the uploads location.
182 Saves a file object to the uploads location.
183 Returns the resolved filename, i.e. the directory +
183 Returns the resolved filename, i.e. the directory +
184 the (randomized/incremented) base name.
184 the (randomized/incremented) base name.
185
185
186 :param file_obj: **cgi.FieldStorage** object (or similar)
186 :param file_obj: **cgi.FieldStorage** object (or similar)
187 :param filename: original filename
187 :param filename: original filename
188 :param directory: relative path of sub-directory
188 :param directory: relative path of sub-directory
189 :param extensions: iterable of allowed extensions, if not default
189 :param extensions: iterable of allowed extensions, if not default
190 :param max_filesize: maximum size of file that should be allowed
190 :param max_filesize: maximum size of file that should be allowed
191 :param randomized_name: generate random generated UID or fixed based on the filename
191 :param randomized_name: generate random generated UID or fixed based on the filename
192 :param extra_metadata: extra JSON metadata to store next to the file with .meta suffix
192 :param extra_metadata: extra JSON metadata to store next to the file with .meta suffix
193
193
194 """
194 """
195
195
196 extensions = extensions or self.extensions
196 extensions = extensions or self.extensions
197
197
198 if not self.filename_allowed(filename, extensions):
198 if not self.filename_allowed(filename, extensions):
199 raise FileNotAllowedException()
199 raise FileNotAllowedException()
200
200
201 if directory:
201 if directory:
202 dest_directory = os.path.join(self.base_path, directory)
202 dest_directory = os.path.join(self.base_path, directory)
203 else:
203 else:
204 dest_directory = self.base_path
204 dest_directory = self.base_path
205
205
206 safe_make_dirs(dest_directory)
206 safe_make_dirs(dest_directory)
207
207
208 uid_filename = utils.uid_filename(filename, randomized=randomized_name)
208 uid_filename = utils.uid_filename(filename, randomized=randomized_name)
209
209
210 # resolve also produces special sub-dir for file optimized store
210 # resolve also produces special sub-dir for file optimized store
211 filename, path = self.resolve_name(uid_filename, dest_directory)
211 filename, path = self.resolve_name(uid_filename, dest_directory)
212 stored_file_dir = os.path.dirname(path)
212 stored_file_dir = os.path.dirname(path)
213
213
214 no_body_seek = kwargs.pop('no_body_seek', False)
214 no_body_seek = kwargs.pop('no_body_seek', False)
215 if no_body_seek:
215 if no_body_seek:
216 pass
216 pass
217 else:
217 else:
218 file_obj.seek(0)
218 file_obj.seek(0)
219
219
220 with open(path, "wb") as dest:
220 with open(path, "wb") as dest:
221 length = 256 * 1024
221 length = 256 * 1024
222 while 1:
222 while 1:
223 buf = file_obj.read(length)
223 buf = file_obj.read(length)
224 if not buf:
224 if not buf:
225 break
225 break
226 dest.write(buf)
226 dest.write(buf)
227
227
228 metadata = {}
228 metadata = {}
229 if extra_metadata:
229 if extra_metadata:
230 metadata = extra_metadata
230 metadata = extra_metadata
231
231
232 size = os.stat(path).st_size
232 size = os.stat(path).st_size
233
233
234 if max_filesize and size > max_filesize:
234 if max_filesize and size > max_filesize:
235 # free up the copied file, and raise exc
235 # free up the copied file, and raise exc
236 os.remove(path)
236 os.remove(path)
237 raise FileOverSizeException()
237 raise FileOverSizeException()
238
238
239 file_hash = self.calculate_path_hash(path)
239 file_hash = self.calculate_path_hash(path)
240
240
241 metadata.update({
241 metadata.update({
242 "filename": filename,
242 "filename": filename,
243 "size": size,
243 "size": size,
244 "time": time.time(),
244 "time": time.time(),
245 "sha256": file_hash,
245 "sha256": file_hash,
246 "meta_ver": METADATA_VER
246 "meta_ver": METADATA_VER
247 })
247 })
248
248
249 filename_meta = filename + '.meta'
249 filename_meta = filename + '.meta'
250 with open(os.path.join(stored_file_dir, filename_meta), "wb") as dest_meta:
250 with open(os.path.join(stored_file_dir, filename_meta), "wb") as dest_meta:
251 dest_meta.write(json.dumps(metadata))
251 dest_meta.write(json.dumps(metadata))
252
252
253 if directory:
253 if directory:
254 filename = os.path.join(directory, filename)
254 filename = os.path.join(directory, filename)
255
255
256 return filename, metadata
256 return filename, metadata
257
257
258 def get_metadata(self, filename):
258 def get_metadata(self, filename, ignore_missing=False):
259 """
259 """
260 Reads JSON stored metadata for a file
260 Reads JSON stored metadata for a file
261
261
262 :param filename:
262 :param filename:
263 :return:
263 :return:
264 """
264 """
265 filename = self.store_path(filename)
265 filename = self.store_path(filename)
266 filename_meta = filename + '.meta'
266 filename_meta = filename + '.meta'
267
267 if ignore_missing and not os.path.isfile(filename_meta):
268 return {}
268 with open(filename_meta, "rb") as source_meta:
269 with open(filename_meta, "rb") as source_meta:
269 return json.loads(source_meta.read())
270 return json.loads(source_meta.read())
@@ -1,405 +1,411 b''
1
1
2 /******************************************************************************
2 /******************************************************************************
3 * *
3 * *
4 * DO NOT CHANGE THIS FILE MANUALLY *
4 * DO NOT CHANGE THIS FILE MANUALLY *
5 * *
5 * *
6 * *
6 * *
7 * This file is automatically generated when the app starts up with *
7 * This file is automatically generated when the app starts up with *
8 * generate_js_files = true *
8 * generate_js_files = true *
9 * *
9 * *
10 * To add a route here pass jsroute=True to the route definition in the app *
10 * To add a route here pass jsroute=True to the route definition in the app *
11 * *
11 * *
12 ******************************************************************************/
12 ******************************************************************************/
13 function registerRCRoutes() {
13 function registerRCRoutes() {
14 // routes registration
14 // routes registration
15 pyroutes.register('admin_artifacts', '/_admin/artifacts', []);
16 pyroutes.register('admin_artifacts_data', '/_admin/artifacts-data', []);
17 pyroutes.register('admin_artifacts_delete', '/_admin/artifacts/%(uid)s/delete', ['uid']);
18 pyroutes.register('admin_artifacts_show_all', '/_admin/artifacts', []);
19 pyroutes.register('admin_artifacts_show_info', '/_admin/artifacts/%(uid)s', ['uid']);
20 pyroutes.register('admin_artifacts_update', '/_admin/artifacts/%(uid)s/update', ['uid']);
15 pyroutes.register('admin_audit_log_entry', '/_admin/audit_logs/%(audit_log_id)s', ['audit_log_id']);
21 pyroutes.register('admin_audit_log_entry', '/_admin/audit_logs/%(audit_log_id)s', ['audit_log_id']);
16 pyroutes.register('admin_audit_logs', '/_admin/audit_logs', []);
22 pyroutes.register('admin_audit_logs', '/_admin/audit_logs', []);
17 pyroutes.register('admin_defaults_repositories', '/_admin/defaults/repositories', []);
23 pyroutes.register('admin_defaults_repositories', '/_admin/defaults/repositories', []);
18 pyroutes.register('admin_defaults_repositories_update', '/_admin/defaults/repositories/update', []);
24 pyroutes.register('admin_defaults_repositories_update', '/_admin/defaults/repositories/update', []);
19 pyroutes.register('admin_home', '/_admin', []);
25 pyroutes.register('admin_home', '/_admin', []);
20 pyroutes.register('admin_permissions_application', '/_admin/permissions/application', []);
26 pyroutes.register('admin_permissions_application', '/_admin/permissions/application', []);
21 pyroutes.register('admin_permissions_application_update', '/_admin/permissions/application/update', []);
27 pyroutes.register('admin_permissions_application_update', '/_admin/permissions/application/update', []);
22 pyroutes.register('admin_permissions_auth_token_access', '/_admin/permissions/auth_token_access', []);
28 pyroutes.register('admin_permissions_auth_token_access', '/_admin/permissions/auth_token_access', []);
23 pyroutes.register('admin_permissions_branch', '/_admin/permissions/branch', []);
29 pyroutes.register('admin_permissions_branch', '/_admin/permissions/branch', []);
24 pyroutes.register('admin_permissions_branch_update', '/_admin/permissions/branch/update', []);
30 pyroutes.register('admin_permissions_branch_update', '/_admin/permissions/branch/update', []);
25 pyroutes.register('admin_permissions_global', '/_admin/permissions/global', []);
31 pyroutes.register('admin_permissions_global', '/_admin/permissions/global', []);
26 pyroutes.register('admin_permissions_global_update', '/_admin/permissions/global/update', []);
32 pyroutes.register('admin_permissions_global_update', '/_admin/permissions/global/update', []);
27 pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []);
33 pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []);
28 pyroutes.register('admin_permissions_object', '/_admin/permissions/object', []);
34 pyroutes.register('admin_permissions_object', '/_admin/permissions/object', []);
29 pyroutes.register('admin_permissions_object_update', '/_admin/permissions/object/update', []);
35 pyroutes.register('admin_permissions_object_update', '/_admin/permissions/object/update', []);
30 pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []);
36 pyroutes.register('admin_permissions_overview', '/_admin/permissions/overview', []);
31 pyroutes.register('admin_permissions_ssh_keys', '/_admin/permissions/ssh_keys', []);
37 pyroutes.register('admin_permissions_ssh_keys', '/_admin/permissions/ssh_keys', []);
32 pyroutes.register('admin_permissions_ssh_keys_data', '/_admin/permissions/ssh_keys/data', []);
38 pyroutes.register('admin_permissions_ssh_keys_data', '/_admin/permissions/ssh_keys/data', []);
33 pyroutes.register('admin_permissions_ssh_keys_update', '/_admin/permissions/ssh_keys/update', []);
39 pyroutes.register('admin_permissions_ssh_keys_update', '/_admin/permissions/ssh_keys/update', []);
34 pyroutes.register('admin_settings', '/_admin/settings', []);
40 pyroutes.register('admin_settings', '/_admin/settings', []);
35 pyroutes.register('admin_settings_automation', '/_admin/settings/automation', []);
41 pyroutes.register('admin_settings_automation', '/_admin/settings/automation', []);
36 pyroutes.register('admin_settings_automation_update', '/_admin/settings/automation/%(entry_id)s/update', ['entry_id']);
42 pyroutes.register('admin_settings_automation_update', '/_admin/settings/automation/%(entry_id)s/update', ['entry_id']);
37 pyroutes.register('admin_settings_email', '/_admin/settings/email', []);
43 pyroutes.register('admin_settings_email', '/_admin/settings/email', []);
38 pyroutes.register('admin_settings_email_update', '/_admin/settings/email/update', []);
44 pyroutes.register('admin_settings_email_update', '/_admin/settings/email/update', []);
39 pyroutes.register('admin_settings_exception_tracker', '/_admin/settings/exceptions', []);
45 pyroutes.register('admin_settings_exception_tracker', '/_admin/settings/exceptions', []);
40 pyroutes.register('admin_settings_exception_tracker_delete', '/_admin/settings/exceptions/%(exception_id)s/delete', ['exception_id']);
46 pyroutes.register('admin_settings_exception_tracker_delete', '/_admin/settings/exceptions/%(exception_id)s/delete', ['exception_id']);
41 pyroutes.register('admin_settings_exception_tracker_delete_all', '/_admin/settings/exceptions_delete_all', []);
47 pyroutes.register('admin_settings_exception_tracker_delete_all', '/_admin/settings/exceptions_delete_all', []);
42 pyroutes.register('admin_settings_exception_tracker_show', '/_admin/settings/exceptions/%(exception_id)s', ['exception_id']);
48 pyroutes.register('admin_settings_exception_tracker_show', '/_admin/settings/exceptions/%(exception_id)s', ['exception_id']);
43 pyroutes.register('admin_settings_global', '/_admin/settings/global', []);
49 pyroutes.register('admin_settings_global', '/_admin/settings/global', []);
44 pyroutes.register('admin_settings_global_update', '/_admin/settings/global/update', []);
50 pyroutes.register('admin_settings_global_update', '/_admin/settings/global/update', []);
45 pyroutes.register('admin_settings_hooks', '/_admin/settings/hooks', []);
51 pyroutes.register('admin_settings_hooks', '/_admin/settings/hooks', []);
46 pyroutes.register('admin_settings_hooks_delete', '/_admin/settings/hooks/delete', []);
52 pyroutes.register('admin_settings_hooks_delete', '/_admin/settings/hooks/delete', []);
47 pyroutes.register('admin_settings_hooks_update', '/_admin/settings/hooks/update', []);
53 pyroutes.register('admin_settings_hooks_update', '/_admin/settings/hooks/update', []);
48 pyroutes.register('admin_settings_issuetracker', '/_admin/settings/issue-tracker', []);
54 pyroutes.register('admin_settings_issuetracker', '/_admin/settings/issue-tracker', []);
49 pyroutes.register('admin_settings_issuetracker_delete', '/_admin/settings/issue-tracker/delete', []);
55 pyroutes.register('admin_settings_issuetracker_delete', '/_admin/settings/issue-tracker/delete', []);
50 pyroutes.register('admin_settings_issuetracker_test', '/_admin/settings/issue-tracker/test', []);
56 pyroutes.register('admin_settings_issuetracker_test', '/_admin/settings/issue-tracker/test', []);
51 pyroutes.register('admin_settings_issuetracker_update', '/_admin/settings/issue-tracker/update', []);
57 pyroutes.register('admin_settings_issuetracker_update', '/_admin/settings/issue-tracker/update', []);
52 pyroutes.register('admin_settings_labs', '/_admin/settings/labs', []);
58 pyroutes.register('admin_settings_labs', '/_admin/settings/labs', []);
53 pyroutes.register('admin_settings_labs_update', '/_admin/settings/labs/update', []);
59 pyroutes.register('admin_settings_labs_update', '/_admin/settings/labs/update', []);
54 pyroutes.register('admin_settings_license', '/_admin/settings/license', []);
60 pyroutes.register('admin_settings_license', '/_admin/settings/license', []);
55 pyroutes.register('admin_settings_license_unlock', '/_admin/settings/license_unlock', []);
61 pyroutes.register('admin_settings_license_unlock', '/_admin/settings/license_unlock', []);
56 pyroutes.register('admin_settings_mapping', '/_admin/settings/mapping', []);
62 pyroutes.register('admin_settings_mapping', '/_admin/settings/mapping', []);
57 pyroutes.register('admin_settings_mapping_update', '/_admin/settings/mapping/update', []);
63 pyroutes.register('admin_settings_mapping_update', '/_admin/settings/mapping/update', []);
58 pyroutes.register('admin_settings_open_source', '/_admin/settings/open_source', []);
64 pyroutes.register('admin_settings_open_source', '/_admin/settings/open_source', []);
59 pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []);
65 pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []);
60 pyroutes.register('admin_settings_process_management_data', '/_admin/settings/process_management/data', []);
66 pyroutes.register('admin_settings_process_management_data', '/_admin/settings/process_management/data', []);
61 pyroutes.register('admin_settings_process_management_master_signal', '/_admin/settings/process_management/master_signal', []);
67 pyroutes.register('admin_settings_process_management_master_signal', '/_admin/settings/process_management/master_signal', []);
62 pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []);
68 pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []);
63 pyroutes.register('admin_settings_scheduler_create', '/_admin/settings/scheduler/create', []);
69 pyroutes.register('admin_settings_scheduler_create', '/_admin/settings/scheduler/create', []);
64 pyroutes.register('admin_settings_scheduler_delete', '/_admin/settings/scheduler/%(schedule_id)s/delete', ['schedule_id']);
70 pyroutes.register('admin_settings_scheduler_delete', '/_admin/settings/scheduler/%(schedule_id)s/delete', ['schedule_id']);
65 pyroutes.register('admin_settings_scheduler_edit', '/_admin/settings/scheduler/%(schedule_id)s', ['schedule_id']);
71 pyroutes.register('admin_settings_scheduler_edit', '/_admin/settings/scheduler/%(schedule_id)s', ['schedule_id']);
66 pyroutes.register('admin_settings_scheduler_execute', '/_admin/settings/scheduler/%(schedule_id)s/execute', ['schedule_id']);
72 pyroutes.register('admin_settings_scheduler_execute', '/_admin/settings/scheduler/%(schedule_id)s/execute', ['schedule_id']);
67 pyroutes.register('admin_settings_scheduler_new', '/_admin/settings/scheduler/new', []);
73 pyroutes.register('admin_settings_scheduler_new', '/_admin/settings/scheduler/new', []);
68 pyroutes.register('admin_settings_scheduler_show_all', '/_admin/settings/scheduler', []);
74 pyroutes.register('admin_settings_scheduler_show_all', '/_admin/settings/scheduler', []);
69 pyroutes.register('admin_settings_scheduler_show_tasks', '/_admin/settings/scheduler/_tasks', []);
75 pyroutes.register('admin_settings_scheduler_show_tasks', '/_admin/settings/scheduler/_tasks', []);
70 pyroutes.register('admin_settings_scheduler_update', '/_admin/settings/scheduler/%(schedule_id)s/update', ['schedule_id']);
76 pyroutes.register('admin_settings_scheduler_update', '/_admin/settings/scheduler/%(schedule_id)s/update', ['schedule_id']);
71 pyroutes.register('admin_settings_search', '/_admin/settings/search', []);
77 pyroutes.register('admin_settings_search', '/_admin/settings/search', []);
72 pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []);
78 pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []);
73 pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []);
79 pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []);
74 pyroutes.register('admin_settings_system', '/_admin/settings/system', []);
80 pyroutes.register('admin_settings_system', '/_admin/settings/system', []);
75 pyroutes.register('admin_settings_system_update', '/_admin/settings/system/updates', []);
81 pyroutes.register('admin_settings_system_update', '/_admin/settings/system/updates', []);
76 pyroutes.register('admin_settings_update', '/_admin/settings/update', []);
82 pyroutes.register('admin_settings_update', '/_admin/settings/update', []);
77 pyroutes.register('admin_settings_vcs', '/_admin/settings/vcs', []);
83 pyroutes.register('admin_settings_vcs', '/_admin/settings/vcs', []);
78 pyroutes.register('admin_settings_vcs_svn_generate_cfg', '/_admin/settings/vcs/svn_generate_cfg', []);
84 pyroutes.register('admin_settings_vcs_svn_generate_cfg', '/_admin/settings/vcs/svn_generate_cfg', []);
79 pyroutes.register('admin_settings_vcs_svn_pattern_delete', '/_admin/settings/vcs/svn_pattern_delete', []);
85 pyroutes.register('admin_settings_vcs_svn_pattern_delete', '/_admin/settings/vcs/svn_pattern_delete', []);
80 pyroutes.register('admin_settings_vcs_update', '/_admin/settings/vcs/update', []);
86 pyroutes.register('admin_settings_vcs_update', '/_admin/settings/vcs/update', []);
81 pyroutes.register('admin_settings_visual', '/_admin/settings/visual', []);
87 pyroutes.register('admin_settings_visual', '/_admin/settings/visual', []);
82 pyroutes.register('admin_settings_visual_update', '/_admin/settings/visual/update', []);
88 pyroutes.register('admin_settings_visual_update', '/_admin/settings/visual/update', []);
83 pyroutes.register('apiv2', '/_admin/api', []);
89 pyroutes.register('apiv2', '/_admin/api', []);
84 pyroutes.register('atom_feed_home', '/%(repo_name)s/feed-atom', ['repo_name']);
90 pyroutes.register('atom_feed_home', '/%(repo_name)s/feed-atom', ['repo_name']);
85 pyroutes.register('atom_feed_home_old', '/%(repo_name)s/feed/atom', ['repo_name']);
91 pyroutes.register('atom_feed_home_old', '/%(repo_name)s/feed/atom', ['repo_name']);
86 pyroutes.register('auth_home', '/_admin/auth*traverse', []);
92 pyroutes.register('auth_home', '/_admin/auth*traverse', []);
87 pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
93 pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
88 pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
94 pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
89 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
95 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
90 pyroutes.register('channelstream_proxy', '/_channelstream', []);
96 pyroutes.register('channelstream_proxy', '/_channelstream', []);
91 pyroutes.register('channelstream_subscribe', '/_admin/channelstream/subscribe', []);
97 pyroutes.register('channelstream_subscribe', '/_admin/channelstream/subscribe', []);
92 pyroutes.register('commit_draft_comments_submit', '/%(repo_name)s/changeset/%(commit_id)s/draft_comments_submit', ['repo_name', 'commit_id']);
98 pyroutes.register('commit_draft_comments_submit', '/%(repo_name)s/changeset/%(commit_id)s/draft_comments_submit', ['repo_name', 'commit_id']);
93 pyroutes.register('debug_style_email', '/_admin/debug_style/email/%(email_id)s', ['email_id']);
99 pyroutes.register('debug_style_email', '/_admin/debug_style/email/%(email_id)s', ['email_id']);
94 pyroutes.register('debug_style_email_plain_rendered', '/_admin/debug_style/email-rendered/%(email_id)s', ['email_id']);
100 pyroutes.register('debug_style_email_plain_rendered', '/_admin/debug_style/email-rendered/%(email_id)s', ['email_id']);
95 pyroutes.register('debug_style_home', '/_admin/debug_style', []);
101 pyroutes.register('debug_style_home', '/_admin/debug_style', []);
96 pyroutes.register('debug_style_template', '/_admin/debug_style/t/%(t_path)s', ['t_path']);
102 pyroutes.register('debug_style_template', '/_admin/debug_style/t/%(t_path)s', ['t_path']);
97 pyroutes.register('download_file', '/_file_store/download/%(fid)s', ['fid']);
103 pyroutes.register('download_file', '/_file_store/download/%(fid)s', ['fid']);
98 pyroutes.register('download_file_by_token', '/_file_store/token-download/%(_auth_token)s/%(fid)s', ['_auth_token', 'fid']);
104 pyroutes.register('download_file_by_token', '/_file_store/token-download/%(_auth_token)s/%(fid)s', ['_auth_token', 'fid']);
99 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
105 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
100 pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
106 pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
101 pyroutes.register('edit_repo_advanced_archive', '/%(repo_name)s/settings/advanced/archive', ['repo_name']);
107 pyroutes.register('edit_repo_advanced_archive', '/%(repo_name)s/settings/advanced/archive', ['repo_name']);
102 pyroutes.register('edit_repo_advanced_delete', '/%(repo_name)s/settings/advanced/delete', ['repo_name']);
108 pyroutes.register('edit_repo_advanced_delete', '/%(repo_name)s/settings/advanced/delete', ['repo_name']);
103 pyroutes.register('edit_repo_advanced_fork', '/%(repo_name)s/settings/advanced/fork', ['repo_name']);
109 pyroutes.register('edit_repo_advanced_fork', '/%(repo_name)s/settings/advanced/fork', ['repo_name']);
104 pyroutes.register('edit_repo_advanced_hooks', '/%(repo_name)s/settings/advanced/hooks', ['repo_name']);
110 pyroutes.register('edit_repo_advanced_hooks', '/%(repo_name)s/settings/advanced/hooks', ['repo_name']);
105 pyroutes.register('edit_repo_advanced_journal', '/%(repo_name)s/settings/advanced/journal', ['repo_name']);
111 pyroutes.register('edit_repo_advanced_journal', '/%(repo_name)s/settings/advanced/journal', ['repo_name']);
106 pyroutes.register('edit_repo_advanced_locking', '/%(repo_name)s/settings/advanced/locking', ['repo_name']);
112 pyroutes.register('edit_repo_advanced_locking', '/%(repo_name)s/settings/advanced/locking', ['repo_name']);
107 pyroutes.register('edit_repo_audit_logs', '/%(repo_name)s/settings/audit_logs', ['repo_name']);
113 pyroutes.register('edit_repo_audit_logs', '/%(repo_name)s/settings/audit_logs', ['repo_name']);
108 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
114 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
109 pyroutes.register('edit_repo_fields', '/%(repo_name)s/settings/fields', ['repo_name']);
115 pyroutes.register('edit_repo_fields', '/%(repo_name)s/settings/fields', ['repo_name']);
110 pyroutes.register('edit_repo_fields_create', '/%(repo_name)s/settings/fields/create', ['repo_name']);
116 pyroutes.register('edit_repo_fields_create', '/%(repo_name)s/settings/fields/create', ['repo_name']);
111 pyroutes.register('edit_repo_fields_delete', '/%(repo_name)s/settings/fields/%(field_id)s/delete', ['repo_name', 'field_id']);
117 pyroutes.register('edit_repo_fields_delete', '/%(repo_name)s/settings/fields/%(field_id)s/delete', ['repo_name', 'field_id']);
112 pyroutes.register('edit_repo_group', '/%(repo_group_name)s/_edit', ['repo_group_name']);
118 pyroutes.register('edit_repo_group', '/%(repo_group_name)s/_edit', ['repo_group_name']);
113 pyroutes.register('edit_repo_group_advanced', '/%(repo_group_name)s/_settings/advanced', ['repo_group_name']);
119 pyroutes.register('edit_repo_group_advanced', '/%(repo_group_name)s/_settings/advanced', ['repo_group_name']);
114 pyroutes.register('edit_repo_group_advanced_delete', '/%(repo_group_name)s/_settings/advanced/delete', ['repo_group_name']);
120 pyroutes.register('edit_repo_group_advanced_delete', '/%(repo_group_name)s/_settings/advanced/delete', ['repo_group_name']);
115 pyroutes.register('edit_repo_group_perms', '/%(repo_group_name)s/_settings/permissions', ['repo_group_name']);
121 pyroutes.register('edit_repo_group_perms', '/%(repo_group_name)s/_settings/permissions', ['repo_group_name']);
116 pyroutes.register('edit_repo_group_perms_update', '/%(repo_group_name)s/_settings/permissions/update', ['repo_group_name']);
122 pyroutes.register('edit_repo_group_perms_update', '/%(repo_group_name)s/_settings/permissions/update', ['repo_group_name']);
117 pyroutes.register('edit_repo_issuetracker', '/%(repo_name)s/settings/issue_trackers', ['repo_name']);
123 pyroutes.register('edit_repo_issuetracker', '/%(repo_name)s/settings/issue_trackers', ['repo_name']);
118 pyroutes.register('edit_repo_issuetracker_delete', '/%(repo_name)s/settings/issue_trackers/delete', ['repo_name']);
124 pyroutes.register('edit_repo_issuetracker_delete', '/%(repo_name)s/settings/issue_trackers/delete', ['repo_name']);
119 pyroutes.register('edit_repo_issuetracker_test', '/%(repo_name)s/settings/issue_trackers/test', ['repo_name']);
125 pyroutes.register('edit_repo_issuetracker_test', '/%(repo_name)s/settings/issue_trackers/test', ['repo_name']);
120 pyroutes.register('edit_repo_issuetracker_update', '/%(repo_name)s/settings/issue_trackers/update', ['repo_name']);
126 pyroutes.register('edit_repo_issuetracker_update', '/%(repo_name)s/settings/issue_trackers/update', ['repo_name']);
121 pyroutes.register('edit_repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']);
127 pyroutes.register('edit_repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']);
122 pyroutes.register('edit_repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']);
128 pyroutes.register('edit_repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']);
123 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
129 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
124 pyroutes.register('edit_repo_perms_branch', '/%(repo_name)s/settings/branch_permissions', ['repo_name']);
130 pyroutes.register('edit_repo_perms_branch', '/%(repo_name)s/settings/branch_permissions', ['repo_name']);
125 pyroutes.register('edit_repo_perms_branch_delete', '/%(repo_name)s/settings/branch_permissions/%(rule_id)s/delete', ['repo_name', 'rule_id']);
131 pyroutes.register('edit_repo_perms_branch_delete', '/%(repo_name)s/settings/branch_permissions/%(rule_id)s/delete', ['repo_name', 'rule_id']);
126 pyroutes.register('edit_repo_perms_set_private', '/%(repo_name)s/settings/permissions/set_private', ['repo_name']);
132 pyroutes.register('edit_repo_perms_set_private', '/%(repo_name)s/settings/permissions/set_private', ['repo_name']);
127 pyroutes.register('edit_repo_remote', '/%(repo_name)s/settings/remote', ['repo_name']);
133 pyroutes.register('edit_repo_remote', '/%(repo_name)s/settings/remote', ['repo_name']);
128 pyroutes.register('edit_repo_remote_pull', '/%(repo_name)s/settings/remote/pull', ['repo_name']);
134 pyroutes.register('edit_repo_remote_pull', '/%(repo_name)s/settings/remote/pull', ['repo_name']);
129 pyroutes.register('edit_repo_remote_push', '/%(repo_name)s/settings/remote/push', ['repo_name']);
135 pyroutes.register('edit_repo_remote_push', '/%(repo_name)s/settings/remote/push', ['repo_name']);
130 pyroutes.register('edit_repo_statistics', '/%(repo_name)s/settings/statistics', ['repo_name']);
136 pyroutes.register('edit_repo_statistics', '/%(repo_name)s/settings/statistics', ['repo_name']);
131 pyroutes.register('edit_repo_statistics_reset', '/%(repo_name)s/settings/statistics/update', ['repo_name']);
137 pyroutes.register('edit_repo_statistics_reset', '/%(repo_name)s/settings/statistics/update', ['repo_name']);
132 pyroutes.register('edit_repo_strip', '/%(repo_name)s/settings/strip', ['repo_name']);
138 pyroutes.register('edit_repo_strip', '/%(repo_name)s/settings/strip', ['repo_name']);
133 pyroutes.register('edit_repo_vcs', '/%(repo_name)s/settings/vcs', ['repo_name']);
139 pyroutes.register('edit_repo_vcs', '/%(repo_name)s/settings/vcs', ['repo_name']);
134 pyroutes.register('edit_repo_vcs_svn_pattern_delete', '/%(repo_name)s/settings/vcs/svn_pattern/delete', ['repo_name']);
140 pyroutes.register('edit_repo_vcs_svn_pattern_delete', '/%(repo_name)s/settings/vcs/svn_pattern/delete', ['repo_name']);
135 pyroutes.register('edit_repo_vcs_update', '/%(repo_name)s/settings/vcs/update', ['repo_name']);
141 pyroutes.register('edit_repo_vcs_update', '/%(repo_name)s/settings/vcs/update', ['repo_name']);
136 pyroutes.register('edit_user_audit_logs', '/_admin/users/%(user_id)s/edit/audit', ['user_id']);
142 pyroutes.register('edit_user_audit_logs', '/_admin/users/%(user_id)s/edit/audit', ['user_id']);
137 pyroutes.register('edit_user_audit_logs_download', '/_admin/users/%(user_id)s/edit/audit/download', ['user_id']);
143 pyroutes.register('edit_user_audit_logs_download', '/_admin/users/%(user_id)s/edit/audit/download', ['user_id']);
138 pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']);
144 pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']);
139 pyroutes.register('edit_user_auth_tokens_add', '/_admin/users/%(user_id)s/edit/auth_tokens/new', ['user_id']);
145 pyroutes.register('edit_user_auth_tokens_add', '/_admin/users/%(user_id)s/edit/auth_tokens/new', ['user_id']);
140 pyroutes.register('edit_user_auth_tokens_delete', '/_admin/users/%(user_id)s/edit/auth_tokens/delete', ['user_id']);
146 pyroutes.register('edit_user_auth_tokens_delete', '/_admin/users/%(user_id)s/edit/auth_tokens/delete', ['user_id']);
141 pyroutes.register('edit_user_auth_tokens_view', '/_admin/users/%(user_id)s/edit/auth_tokens/view', ['user_id']);
147 pyroutes.register('edit_user_auth_tokens_view', '/_admin/users/%(user_id)s/edit/auth_tokens/view', ['user_id']);
142 pyroutes.register('edit_user_caches', '/_admin/users/%(user_id)s/edit/caches', ['user_id']);
148 pyroutes.register('edit_user_caches', '/_admin/users/%(user_id)s/edit/caches', ['user_id']);
143 pyroutes.register('edit_user_caches_update', '/_admin/users/%(user_id)s/edit/caches/update', ['user_id']);
149 pyroutes.register('edit_user_caches_update', '/_admin/users/%(user_id)s/edit/caches/update', ['user_id']);
144 pyroutes.register('edit_user_emails', '/_admin/users/%(user_id)s/edit/emails', ['user_id']);
150 pyroutes.register('edit_user_emails', '/_admin/users/%(user_id)s/edit/emails', ['user_id']);
145 pyroutes.register('edit_user_emails_add', '/_admin/users/%(user_id)s/edit/emails/new', ['user_id']);
151 pyroutes.register('edit_user_emails_add', '/_admin/users/%(user_id)s/edit/emails/new', ['user_id']);
146 pyroutes.register('edit_user_emails_delete', '/_admin/users/%(user_id)s/edit/emails/delete', ['user_id']);
152 pyroutes.register('edit_user_emails_delete', '/_admin/users/%(user_id)s/edit/emails/delete', ['user_id']);
147 pyroutes.register('edit_user_group', '/_admin/user_groups/%(user_group_id)s/edit', ['user_group_id']);
153 pyroutes.register('edit_user_group', '/_admin/user_groups/%(user_group_id)s/edit', ['user_group_id']);
148 pyroutes.register('edit_user_group_advanced', '/_admin/user_groups/%(user_group_id)s/edit/advanced', ['user_group_id']);
154 pyroutes.register('edit_user_group_advanced', '/_admin/user_groups/%(user_group_id)s/edit/advanced', ['user_group_id']);
149 pyroutes.register('edit_user_group_advanced_sync', '/_admin/user_groups/%(user_group_id)s/edit/advanced/sync', ['user_group_id']);
155 pyroutes.register('edit_user_group_advanced_sync', '/_admin/user_groups/%(user_group_id)s/edit/advanced/sync', ['user_group_id']);
150 pyroutes.register('edit_user_group_global_perms', '/_admin/user_groups/%(user_group_id)s/edit/global_permissions', ['user_group_id']);
156 pyroutes.register('edit_user_group_global_perms', '/_admin/user_groups/%(user_group_id)s/edit/global_permissions', ['user_group_id']);
151 pyroutes.register('edit_user_group_global_perms_update', '/_admin/user_groups/%(user_group_id)s/edit/global_permissions/update', ['user_group_id']);
157 pyroutes.register('edit_user_group_global_perms_update', '/_admin/user_groups/%(user_group_id)s/edit/global_permissions/update', ['user_group_id']);
152 pyroutes.register('edit_user_group_perms', '/_admin/user_groups/%(user_group_id)s/edit/permissions', ['user_group_id']);
158 pyroutes.register('edit_user_group_perms', '/_admin/user_groups/%(user_group_id)s/edit/permissions', ['user_group_id']);
153 pyroutes.register('edit_user_group_perms_summary', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary', ['user_group_id']);
159 pyroutes.register('edit_user_group_perms_summary', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary', ['user_group_id']);
154 pyroutes.register('edit_user_group_perms_summary_json', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary/json', ['user_group_id']);
160 pyroutes.register('edit_user_group_perms_summary_json', '/_admin/user_groups/%(user_group_id)s/edit/permissions_summary/json', ['user_group_id']);
155 pyroutes.register('edit_user_group_perms_update', '/_admin/user_groups/%(user_group_id)s/edit/permissions/update', ['user_group_id']);
161 pyroutes.register('edit_user_group_perms_update', '/_admin/user_groups/%(user_group_id)s/edit/permissions/update', ['user_group_id']);
156 pyroutes.register('edit_user_groups_management', '/_admin/users/%(user_id)s/edit/groups_management', ['user_id']);
162 pyroutes.register('edit_user_groups_management', '/_admin/users/%(user_id)s/edit/groups_management', ['user_id']);
157 pyroutes.register('edit_user_groups_management_updates', '/_admin/users/%(user_id)s/edit/edit_user_groups_management/updates', ['user_id']);
163 pyroutes.register('edit_user_groups_management_updates', '/_admin/users/%(user_id)s/edit/edit_user_groups_management/updates', ['user_id']);
158 pyroutes.register('edit_user_ips', '/_admin/users/%(user_id)s/edit/ips', ['user_id']);
164 pyroutes.register('edit_user_ips', '/_admin/users/%(user_id)s/edit/ips', ['user_id']);
159 pyroutes.register('edit_user_ips_add', '/_admin/users/%(user_id)s/edit/ips/new', ['user_id']);
165 pyroutes.register('edit_user_ips_add', '/_admin/users/%(user_id)s/edit/ips/new', ['user_id']);
160 pyroutes.register('edit_user_ips_delete', '/_admin/users/%(user_id)s/edit/ips/delete', ['user_id']);
166 pyroutes.register('edit_user_ips_delete', '/_admin/users/%(user_id)s/edit/ips/delete', ['user_id']);
161 pyroutes.register('edit_user_perms_summary', '/_admin/users/%(user_id)s/edit/permissions_summary', ['user_id']);
167 pyroutes.register('edit_user_perms_summary', '/_admin/users/%(user_id)s/edit/permissions_summary', ['user_id']);
162 pyroutes.register('edit_user_perms_summary_json', '/_admin/users/%(user_id)s/edit/permissions_summary/json', ['user_id']);
168 pyroutes.register('edit_user_perms_summary_json', '/_admin/users/%(user_id)s/edit/permissions_summary/json', ['user_id']);
163 pyroutes.register('edit_user_ssh_keys', '/_admin/users/%(user_id)s/edit/ssh_keys', ['user_id']);
169 pyroutes.register('edit_user_ssh_keys', '/_admin/users/%(user_id)s/edit/ssh_keys', ['user_id']);
164 pyroutes.register('edit_user_ssh_keys_add', '/_admin/users/%(user_id)s/edit/ssh_keys/new', ['user_id']);
170 pyroutes.register('edit_user_ssh_keys_add', '/_admin/users/%(user_id)s/edit/ssh_keys/new', ['user_id']);
165 pyroutes.register('edit_user_ssh_keys_delete', '/_admin/users/%(user_id)s/edit/ssh_keys/delete', ['user_id']);
171 pyroutes.register('edit_user_ssh_keys_delete', '/_admin/users/%(user_id)s/edit/ssh_keys/delete', ['user_id']);
166 pyroutes.register('edit_user_ssh_keys_generate_keypair', '/_admin/users/%(user_id)s/edit/ssh_keys/generate', ['user_id']);
172 pyroutes.register('edit_user_ssh_keys_generate_keypair', '/_admin/users/%(user_id)s/edit/ssh_keys/generate', ['user_id']);
167 pyroutes.register('favicon', '/favicon.ico', []);
173 pyroutes.register('favicon', '/favicon.ico', []);
168 pyroutes.register('file_preview', '/_file_preview', []);
174 pyroutes.register('file_preview', '/_file_preview', []);
169 pyroutes.register('gist_delete', '/_admin/gists/%(gist_id)s/delete', ['gist_id']);
175 pyroutes.register('gist_delete', '/_admin/gists/%(gist_id)s/delete', ['gist_id']);
170 pyroutes.register('gist_edit', '/_admin/gists/%(gist_id)s/edit', ['gist_id']);
176 pyroutes.register('gist_edit', '/_admin/gists/%(gist_id)s/edit', ['gist_id']);
171 pyroutes.register('gist_edit_check_revision', '/_admin/gists/%(gist_id)s/edit/check_revision', ['gist_id']);
177 pyroutes.register('gist_edit_check_revision', '/_admin/gists/%(gist_id)s/edit/check_revision', ['gist_id']);
172 pyroutes.register('gist_show', '/_admin/gists/%(gist_id)s', ['gist_id']);
178 pyroutes.register('gist_show', '/_admin/gists/%(gist_id)s', ['gist_id']);
173 pyroutes.register('gist_show_formatted', '/_admin/gists/%(gist_id)s/rev/%(revision)s/%(format)s', ['gist_id', 'revision', 'format']);
179 pyroutes.register('gist_show_formatted', '/_admin/gists/%(gist_id)s/rev/%(revision)s/%(format)s', ['gist_id', 'revision', 'format']);
174 pyroutes.register('gist_show_formatted_path', '/_admin/gists/%(gist_id)s/rev/%(revision)s/%(format)s/%(f_path)s', ['gist_id', 'revision', 'format', 'f_path']);
180 pyroutes.register('gist_show_formatted_path', '/_admin/gists/%(gist_id)s/rev/%(revision)s/%(format)s/%(f_path)s', ['gist_id', 'revision', 'format', 'f_path']);
175 pyroutes.register('gist_show_rev', '/_admin/gists/%(gist_id)s/rev/%(revision)s', ['gist_id', 'revision']);
181 pyroutes.register('gist_show_rev', '/_admin/gists/%(gist_id)s/rev/%(revision)s', ['gist_id', 'revision']);
176 pyroutes.register('gist_update', '/_admin/gists/%(gist_id)s/update', ['gist_id']);
182 pyroutes.register('gist_update', '/_admin/gists/%(gist_id)s/update', ['gist_id']);
177 pyroutes.register('gists_create', '/_admin/gists/create', []);
183 pyroutes.register('gists_create', '/_admin/gists/create', []);
178 pyroutes.register('gists_new', '/_admin/gists/new', []);
184 pyroutes.register('gists_new', '/_admin/gists/new', []);
179 pyroutes.register('gists_show', '/_admin/gists', []);
185 pyroutes.register('gists_show', '/_admin/gists', []);
180 pyroutes.register('global_integrations_create', '/_admin/integrations/%(integration)s/new', ['integration']);
186 pyroutes.register('global_integrations_create', '/_admin/integrations/%(integration)s/new', ['integration']);
181 pyroutes.register('global_integrations_edit', '/_admin/integrations/%(integration)s/%(integration_id)s', ['integration', 'integration_id']);
187 pyroutes.register('global_integrations_edit', '/_admin/integrations/%(integration)s/%(integration_id)s', ['integration', 'integration_id']);
182 pyroutes.register('global_integrations_home', '/_admin/integrations', []);
188 pyroutes.register('global_integrations_home', '/_admin/integrations', []);
183 pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']);
189 pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']);
184 pyroutes.register('global_integrations_new', '/_admin/integrations/new', []);
190 pyroutes.register('global_integrations_new', '/_admin/integrations/new', []);
185 pyroutes.register('goto_switcher_data', '/_goto_data', []);
191 pyroutes.register('goto_switcher_data', '/_goto_data', []);
186 pyroutes.register('home', '/', []);
192 pyroutes.register('home', '/', []);
187 pyroutes.register('hovercard_pull_request', '/_hovercard/pull_request/%(pull_request_id)s', ['pull_request_id']);
193 pyroutes.register('hovercard_pull_request', '/_hovercard/pull_request/%(pull_request_id)s', ['pull_request_id']);
188 pyroutes.register('hovercard_repo_commit', '/_hovercard/commit/%(repo_name)s/%(commit_id)s', ['repo_name', 'commit_id']);
194 pyroutes.register('hovercard_repo_commit', '/_hovercard/commit/%(repo_name)s/%(commit_id)s', ['repo_name', 'commit_id']);
189 pyroutes.register('hovercard_user', '/_hovercard/user/%(user_id)s', ['user_id']);
195 pyroutes.register('hovercard_user', '/_hovercard/user/%(user_id)s', ['user_id']);
190 pyroutes.register('hovercard_user_group', '/_hovercard/user_group/%(user_group_id)s', ['user_group_id']);
196 pyroutes.register('hovercard_user_group', '/_hovercard/user_group/%(user_group_id)s', ['user_group_id']);
191 pyroutes.register('hovercard_username', '/_hovercard/username/%(username)s', ['username']);
197 pyroutes.register('hovercard_username', '/_hovercard/username/%(username)s', ['username']);
192 pyroutes.register('journal', '/_admin/journal', []);
198 pyroutes.register('journal', '/_admin/journal', []);
193 pyroutes.register('journal_atom', '/_admin/journal/atom', []);
199 pyroutes.register('journal_atom', '/_admin/journal/atom', []);
194 pyroutes.register('journal_public', '/_admin/public_journal', []);
200 pyroutes.register('journal_public', '/_admin/public_journal', []);
195 pyroutes.register('journal_public_atom', '/_admin/public_journal/atom', []);
201 pyroutes.register('journal_public_atom', '/_admin/public_journal/atom', []);
196 pyroutes.register('journal_public_atom_old', '/_admin/public_journal_atom', []);
202 pyroutes.register('journal_public_atom_old', '/_admin/public_journal_atom', []);
197 pyroutes.register('journal_public_rss', '/_admin/public_journal/rss', []);
203 pyroutes.register('journal_public_rss', '/_admin/public_journal/rss', []);
198 pyroutes.register('journal_public_rss_old', '/_admin/public_journal_rss', []);
204 pyroutes.register('journal_public_rss_old', '/_admin/public_journal_rss', []);
199 pyroutes.register('journal_rss', '/_admin/journal/rss', []);
205 pyroutes.register('journal_rss', '/_admin/journal/rss', []);
200 pyroutes.register('login', '/_admin/login', []);
206 pyroutes.register('login', '/_admin/login', []);
201 pyroutes.register('logout', '/_admin/logout', []);
207 pyroutes.register('logout', '/_admin/logout', []);
202 pyroutes.register('main_page_repo_groups_data', '/_home_repo_groups', []);
208 pyroutes.register('main_page_repo_groups_data', '/_home_repo_groups', []);
203 pyroutes.register('main_page_repos_data', '/_home_repos', []);
209 pyroutes.register('main_page_repos_data', '/_home_repos', []);
204 pyroutes.register('markup_preview', '/_markup_preview', []);
210 pyroutes.register('markup_preview', '/_markup_preview', []);
205 pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []);
211 pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []);
206 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
212 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
207 pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []);
213 pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []);
208 pyroutes.register('my_account_auth_tokens_view', '/_admin/my_account/auth_tokens/view', []);
214 pyroutes.register('my_account_auth_tokens_view', '/_admin/my_account/auth_tokens/view', []);
209 pyroutes.register('my_account_bookmarks', '/_admin/my_account/bookmarks', []);
215 pyroutes.register('my_account_bookmarks', '/_admin/my_account/bookmarks', []);
210 pyroutes.register('my_account_bookmarks_update', '/_admin/my_account/bookmarks/update', []);
216 pyroutes.register('my_account_bookmarks_update', '/_admin/my_account/bookmarks/update', []);
211 pyroutes.register('my_account_edit', '/_admin/my_account/edit', []);
217 pyroutes.register('my_account_edit', '/_admin/my_account/edit', []);
212 pyroutes.register('my_account_emails', '/_admin/my_account/emails', []);
218 pyroutes.register('my_account_emails', '/_admin/my_account/emails', []);
213 pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []);
219 pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []);
214 pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []);
220 pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []);
215 pyroutes.register('my_account_external_identity', '/_admin/my_account/external-identity', []);
221 pyroutes.register('my_account_external_identity', '/_admin/my_account/external-identity', []);
216 pyroutes.register('my_account_external_identity_delete', '/_admin/my_account/external-identity/delete', []);
222 pyroutes.register('my_account_external_identity_delete', '/_admin/my_account/external-identity/delete', []);
217 pyroutes.register('my_account_goto_bookmark', '/_admin/my_account/bookmark/%(bookmark_id)s', ['bookmark_id']);
223 pyroutes.register('my_account_goto_bookmark', '/_admin/my_account/bookmark/%(bookmark_id)s', ['bookmark_id']);
218 pyroutes.register('my_account_notifications', '/_admin/my_account/notifications', []);
224 pyroutes.register('my_account_notifications', '/_admin/my_account/notifications', []);
219 pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []);
225 pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []);
220 pyroutes.register('my_account_notifications_toggle_visibility', '/_admin/my_account/toggle_visibility', []);
226 pyroutes.register('my_account_notifications_toggle_visibility', '/_admin/my_account/toggle_visibility', []);
221 pyroutes.register('my_account_password', '/_admin/my_account/password', []);
227 pyroutes.register('my_account_password', '/_admin/my_account/password', []);
222 pyroutes.register('my_account_password_update', '/_admin/my_account/password/update', []);
228 pyroutes.register('my_account_password_update', '/_admin/my_account/password/update', []);
223 pyroutes.register('my_account_perms', '/_admin/my_account/perms', []);
229 pyroutes.register('my_account_perms', '/_admin/my_account/perms', []);
224 pyroutes.register('my_account_profile', '/_admin/my_account/profile', []);
230 pyroutes.register('my_account_profile', '/_admin/my_account/profile', []);
225 pyroutes.register('my_account_pullrequests', '/_admin/my_account/pull_requests', []);
231 pyroutes.register('my_account_pullrequests', '/_admin/my_account/pull_requests', []);
226 pyroutes.register('my_account_pullrequests_data', '/_admin/my_account/pull_requests/data', []);
232 pyroutes.register('my_account_pullrequests_data', '/_admin/my_account/pull_requests/data', []);
227 pyroutes.register('my_account_repos', '/_admin/my_account/repos', []);
233 pyroutes.register('my_account_repos', '/_admin/my_account/repos', []);
228 pyroutes.register('my_account_ssh_keys', '/_admin/my_account/ssh_keys', []);
234 pyroutes.register('my_account_ssh_keys', '/_admin/my_account/ssh_keys', []);
229 pyroutes.register('my_account_ssh_keys_add', '/_admin/my_account/ssh_keys/new', []);
235 pyroutes.register('my_account_ssh_keys_add', '/_admin/my_account/ssh_keys/new', []);
230 pyroutes.register('my_account_ssh_keys_delete', '/_admin/my_account/ssh_keys/delete', []);
236 pyroutes.register('my_account_ssh_keys_delete', '/_admin/my_account/ssh_keys/delete', []);
231 pyroutes.register('my_account_ssh_keys_generate', '/_admin/my_account/ssh_keys/generate', []);
237 pyroutes.register('my_account_ssh_keys_generate', '/_admin/my_account/ssh_keys/generate', []);
232 pyroutes.register('my_account_update', '/_admin/my_account/update', []);
238 pyroutes.register('my_account_update', '/_admin/my_account/update', []);
233 pyroutes.register('my_account_user_group_membership', '/_admin/my_account/user_group_membership', []);
239 pyroutes.register('my_account_user_group_membership', '/_admin/my_account/user_group_membership', []);
234 pyroutes.register('my_account_watched', '/_admin/my_account/watched', []);
240 pyroutes.register('my_account_watched', '/_admin/my_account/watched', []);
235 pyroutes.register('notifications_delete', '/_admin/notifications/%(notification_id)s/delete', ['notification_id']);
241 pyroutes.register('notifications_delete', '/_admin/notifications/%(notification_id)s/delete', ['notification_id']);
236 pyroutes.register('notifications_mark_all_read', '/_admin/notifications_mark_all_read', []);
242 pyroutes.register('notifications_mark_all_read', '/_admin/notifications_mark_all_read', []);
237 pyroutes.register('notifications_show', '/_admin/notifications/%(notification_id)s', ['notification_id']);
243 pyroutes.register('notifications_show', '/_admin/notifications/%(notification_id)s', ['notification_id']);
238 pyroutes.register('notifications_show_all', '/_admin/notifications', []);
244 pyroutes.register('notifications_show_all', '/_admin/notifications', []);
239 pyroutes.register('notifications_update', '/_admin/notifications/%(notification_id)s/update', ['notification_id']);
245 pyroutes.register('notifications_update', '/_admin/notifications/%(notification_id)s/update', ['notification_id']);
240 pyroutes.register('ops_error_test', '/_admin/ops/error', []);
246 pyroutes.register('ops_error_test', '/_admin/ops/error', []);
241 pyroutes.register('ops_ping', '/_admin/ops/ping', []);
247 pyroutes.register('ops_ping', '/_admin/ops/ping', []);
242 pyroutes.register('ops_redirect_test', '/_admin/ops/redirect', []);
248 pyroutes.register('ops_redirect_test', '/_admin/ops/redirect', []);
243 pyroutes.register('plugin_admin_chat', '/_admin/plugin_admin_chat/%(action)s', ['action']);
249 pyroutes.register('plugin_admin_chat', '/_admin/plugin_admin_chat/%(action)s', ['action']);
244 pyroutes.register('pull_requests_global', '/_admin/pull-request/%(pull_request_id)s', ['pull_request_id']);
250 pyroutes.register('pull_requests_global', '/_admin/pull-request/%(pull_request_id)s', ['pull_request_id']);
245 pyroutes.register('pull_requests_global_0', '/_admin/pull_requests/%(pull_request_id)s', ['pull_request_id']);
251 pyroutes.register('pull_requests_global_0', '/_admin/pull_requests/%(pull_request_id)s', ['pull_request_id']);
246 pyroutes.register('pull_requests_global_1', '/_admin/pull-requests/%(pull_request_id)s', ['pull_request_id']);
252 pyroutes.register('pull_requests_global_1', '/_admin/pull-requests/%(pull_request_id)s', ['pull_request_id']);
247 pyroutes.register('pullrequest_comment_create', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment', ['repo_name', 'pull_request_id']);
253 pyroutes.register('pullrequest_comment_create', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment', ['repo_name', 'pull_request_id']);
248 pyroutes.register('pullrequest_comment_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment/%(comment_id)s/delete', ['repo_name', 'pull_request_id', 'comment_id']);
254 pyroutes.register('pullrequest_comment_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment/%(comment_id)s/delete', ['repo_name', 'pull_request_id', 'comment_id']);
249 pyroutes.register('pullrequest_comment_edit', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment/%(comment_id)s/edit', ['repo_name', 'pull_request_id', 'comment_id']);
255 pyroutes.register('pullrequest_comment_edit', '/%(repo_name)s/pull-request/%(pull_request_id)s/comment/%(comment_id)s/edit', ['repo_name', 'pull_request_id', 'comment_id']);
250 pyroutes.register('pullrequest_comments', '/%(repo_name)s/pull-request/%(pull_request_id)s/comments', ['repo_name', 'pull_request_id']);
256 pyroutes.register('pullrequest_comments', '/%(repo_name)s/pull-request/%(pull_request_id)s/comments', ['repo_name', 'pull_request_id']);
251 pyroutes.register('pullrequest_create', '/%(repo_name)s/pull-request/create', ['repo_name']);
257 pyroutes.register('pullrequest_create', '/%(repo_name)s/pull-request/create', ['repo_name']);
252 pyroutes.register('pullrequest_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/delete', ['repo_name', 'pull_request_id']);
258 pyroutes.register('pullrequest_delete', '/%(repo_name)s/pull-request/%(pull_request_id)s/delete', ['repo_name', 'pull_request_id']);
253 pyroutes.register('pullrequest_draft_comments_submit', '/%(repo_name)s/pull-request/%(pull_request_id)s/draft_comments_submit', ['repo_name', 'pull_request_id']);
259 pyroutes.register('pullrequest_draft_comments_submit', '/%(repo_name)s/pull-request/%(pull_request_id)s/draft_comments_submit', ['repo_name', 'pull_request_id']);
254 pyroutes.register('pullrequest_drafts', '/%(repo_name)s/pull-request/%(pull_request_id)s/drafts', ['repo_name', 'pull_request_id']);
260 pyroutes.register('pullrequest_drafts', '/%(repo_name)s/pull-request/%(pull_request_id)s/drafts', ['repo_name', 'pull_request_id']);
255 pyroutes.register('pullrequest_merge', '/%(repo_name)s/pull-request/%(pull_request_id)s/merge', ['repo_name', 'pull_request_id']);
261 pyroutes.register('pullrequest_merge', '/%(repo_name)s/pull-request/%(pull_request_id)s/merge', ['repo_name', 'pull_request_id']);
256 pyroutes.register('pullrequest_new', '/%(repo_name)s/pull-request/new', ['repo_name']);
262 pyroutes.register('pullrequest_new', '/%(repo_name)s/pull-request/new', ['repo_name']);
257 pyroutes.register('pullrequest_repo_refs', '/%(repo_name)s/pull-request/refs/%(target_repo_name)s', ['repo_name', 'target_repo_name']);
263 pyroutes.register('pullrequest_repo_refs', '/%(repo_name)s/pull-request/refs/%(target_repo_name)s', ['repo_name', 'target_repo_name']);
258 pyroutes.register('pullrequest_repo_targets', '/%(repo_name)s/pull-request/repo-targets', ['repo_name']);
264 pyroutes.register('pullrequest_repo_targets', '/%(repo_name)s/pull-request/repo-targets', ['repo_name']);
259 pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
265 pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
260 pyroutes.register('pullrequest_show_all', '/%(repo_name)s/pull-request', ['repo_name']);
266 pyroutes.register('pullrequest_show_all', '/%(repo_name)s/pull-request', ['repo_name']);
261 pyroutes.register('pullrequest_show_all_data', '/%(repo_name)s/pull-request-data', ['repo_name']);
267 pyroutes.register('pullrequest_show_all_data', '/%(repo_name)s/pull-request-data', ['repo_name']);
262 pyroutes.register('pullrequest_todos', '/%(repo_name)s/pull-request/%(pull_request_id)s/todos', ['repo_name', 'pull_request_id']);
268 pyroutes.register('pullrequest_todos', '/%(repo_name)s/pull-request/%(pull_request_id)s/todos', ['repo_name', 'pull_request_id']);
263 pyroutes.register('pullrequest_update', '/%(repo_name)s/pull-request/%(pull_request_id)s/update', ['repo_name', 'pull_request_id']);
269 pyroutes.register('pullrequest_update', '/%(repo_name)s/pull-request/%(pull_request_id)s/update', ['repo_name', 'pull_request_id']);
264 pyroutes.register('register', '/_admin/register', []);
270 pyroutes.register('register', '/_admin/register', []);
265 pyroutes.register('repo_archivefile', '/%(repo_name)s/archive/%(fname)s', ['repo_name', 'fname']);
271 pyroutes.register('repo_archivefile', '/%(repo_name)s/archive/%(fname)s', ['repo_name', 'fname']);
266 pyroutes.register('repo_artifacts_data', '/%(repo_name)s/artifacts_data', ['repo_name']);
272 pyroutes.register('repo_artifacts_data', '/%(repo_name)s/artifacts_data', ['repo_name']);
267 pyroutes.register('repo_artifacts_delete', '/%(repo_name)s/artifacts/delete/%(uid)s', ['repo_name', 'uid']);
273 pyroutes.register('repo_artifacts_delete', '/%(repo_name)s/artifacts/delete/%(uid)s', ['repo_name', 'uid']);
268 pyroutes.register('repo_artifacts_get', '/%(repo_name)s/artifacts/download/%(uid)s', ['repo_name', 'uid']);
274 pyroutes.register('repo_artifacts_get', '/%(repo_name)s/artifacts/download/%(uid)s', ['repo_name', 'uid']);
269 pyroutes.register('repo_artifacts_info', '/%(repo_name)s/artifacts/info/%(uid)s', ['repo_name', 'uid']);
275 pyroutes.register('repo_artifacts_info', '/%(repo_name)s/artifacts/info/%(uid)s', ['repo_name', 'uid']);
270 pyroutes.register('repo_artifacts_list', '/%(repo_name)s/artifacts', ['repo_name']);
276 pyroutes.register('repo_artifacts_list', '/%(repo_name)s/artifacts', ['repo_name']);
271 pyroutes.register('repo_artifacts_new', '/%(repo_name)s/artifacts/new', ['repo_name']);
277 pyroutes.register('repo_artifacts_new', '/%(repo_name)s/artifacts/new', ['repo_name']);
272 pyroutes.register('repo_artifacts_store', '/%(repo_name)s/artifacts/store', ['repo_name']);
278 pyroutes.register('repo_artifacts_store', '/%(repo_name)s/artifacts/store', ['repo_name']);
273 pyroutes.register('repo_artifacts_stream_script', '/_file_store/stream-upload-script', []);
279 pyroutes.register('repo_artifacts_stream_script', '/_file_store/stream-upload-script', []);
274 pyroutes.register('repo_artifacts_stream_store', '/_file_store/stream-upload', []);
280 pyroutes.register('repo_artifacts_stream_store', '/_file_store/stream-upload', []);
275 pyroutes.register('repo_artifacts_update', '/%(repo_name)s/artifacts/update/%(uid)s', ['repo_name', 'uid']);
281 pyroutes.register('repo_artifacts_update', '/%(repo_name)s/artifacts/update/%(uid)s', ['repo_name', 'uid']);
276 pyroutes.register('repo_automation', '/%(repo_name)s/settings/automation', ['repo_name']);
282 pyroutes.register('repo_automation', '/%(repo_name)s/settings/automation', ['repo_name']);
277 pyroutes.register('repo_automation_update', '/%(repo_name)s/settings/automation/%(entry_id)s/update', ['repo_name', 'entry_id']);
283 pyroutes.register('repo_automation_update', '/%(repo_name)s/settings/automation/%(entry_id)s/update', ['repo_name', 'entry_id']);
278 pyroutes.register('repo_changelog', '/%(repo_name)s/changelog', ['repo_name']);
284 pyroutes.register('repo_changelog', '/%(repo_name)s/changelog', ['repo_name']);
279 pyroutes.register('repo_changelog_file', '/%(repo_name)s/changelog/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
285 pyroutes.register('repo_changelog_file', '/%(repo_name)s/changelog/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
280 pyroutes.register('repo_commit', '/%(repo_name)s/changeset/%(commit_id)s', ['repo_name', 'commit_id']);
286 pyroutes.register('repo_commit', '/%(repo_name)s/changeset/%(commit_id)s', ['repo_name', 'commit_id']);
281 pyroutes.register('repo_commit_children', '/%(repo_name)s/changeset_children/%(commit_id)s', ['repo_name', 'commit_id']);
287 pyroutes.register('repo_commit_children', '/%(repo_name)s/changeset_children/%(commit_id)s', ['repo_name', 'commit_id']);
282 pyroutes.register('repo_commit_comment_attachment_upload', '/%(repo_name)s/changeset/%(commit_id)s/comment/attachment_upload', ['repo_name', 'commit_id']);
288 pyroutes.register('repo_commit_comment_attachment_upload', '/%(repo_name)s/changeset/%(commit_id)s/comment/attachment_upload', ['repo_name', 'commit_id']);
283 pyroutes.register('repo_commit_comment_create', '/%(repo_name)s/changeset/%(commit_id)s/comment/create', ['repo_name', 'commit_id']);
289 pyroutes.register('repo_commit_comment_create', '/%(repo_name)s/changeset/%(commit_id)s/comment/create', ['repo_name', 'commit_id']);
284 pyroutes.register('repo_commit_comment_delete', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_id)s/delete', ['repo_name', 'commit_id', 'comment_id']);
290 pyroutes.register('repo_commit_comment_delete', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_id)s/delete', ['repo_name', 'commit_id', 'comment_id']);
285 pyroutes.register('repo_commit_comment_edit', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_id)s/edit', ['repo_name', 'commit_id', 'comment_id']);
291 pyroutes.register('repo_commit_comment_edit', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_id)s/edit', ['repo_name', 'commit_id', 'comment_id']);
286 pyroutes.register('repo_commit_comment_history_view', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_history_id)s/history_view', ['repo_name', 'commit_id', 'comment_history_id']);
292 pyroutes.register('repo_commit_comment_history_view', '/%(repo_name)s/changeset/%(commit_id)s/comment/%(comment_history_id)s/history_view', ['repo_name', 'commit_id', 'comment_history_id']);
287 pyroutes.register('repo_commit_comment_preview', '/%(repo_name)s/changeset/%(commit_id)s/comment/preview', ['repo_name', 'commit_id']);
293 pyroutes.register('repo_commit_comment_preview', '/%(repo_name)s/changeset/%(commit_id)s/comment/preview', ['repo_name', 'commit_id']);
288 pyroutes.register('repo_commit_data', '/%(repo_name)s/changeset-data/%(commit_id)s', ['repo_name', 'commit_id']);
294 pyroutes.register('repo_commit_data', '/%(repo_name)s/changeset-data/%(commit_id)s', ['repo_name', 'commit_id']);
289 pyroutes.register('repo_commit_download', '/%(repo_name)s/changeset-download/%(commit_id)s', ['repo_name', 'commit_id']);
295 pyroutes.register('repo_commit_download', '/%(repo_name)s/changeset-download/%(commit_id)s', ['repo_name', 'commit_id']);
290 pyroutes.register('repo_commit_parents', '/%(repo_name)s/changeset_parents/%(commit_id)s', ['repo_name', 'commit_id']);
296 pyroutes.register('repo_commit_parents', '/%(repo_name)s/changeset_parents/%(commit_id)s', ['repo_name', 'commit_id']);
291 pyroutes.register('repo_commit_patch', '/%(repo_name)s/changeset-patch/%(commit_id)s', ['repo_name', 'commit_id']);
297 pyroutes.register('repo_commit_patch', '/%(repo_name)s/changeset-patch/%(commit_id)s', ['repo_name', 'commit_id']);
292 pyroutes.register('repo_commit_raw', '/%(repo_name)s/changeset-diff/%(commit_id)s', ['repo_name', 'commit_id']);
298 pyroutes.register('repo_commit_raw', '/%(repo_name)s/changeset-diff/%(commit_id)s', ['repo_name', 'commit_id']);
293 pyroutes.register('repo_commit_raw_deprecated', '/%(repo_name)s/raw-changeset/%(commit_id)s', ['repo_name', 'commit_id']);
299 pyroutes.register('repo_commit_raw_deprecated', '/%(repo_name)s/raw-changeset/%(commit_id)s', ['repo_name', 'commit_id']);
294 pyroutes.register('repo_commits', '/%(repo_name)s/commits', ['repo_name']);
300 pyroutes.register('repo_commits', '/%(repo_name)s/commits', ['repo_name']);
295 pyroutes.register('repo_commits_elements', '/%(repo_name)s/commits_elements', ['repo_name']);
301 pyroutes.register('repo_commits_elements', '/%(repo_name)s/commits_elements', ['repo_name']);
296 pyroutes.register('repo_commits_elements_file', '/%(repo_name)s/commits_elements/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
302 pyroutes.register('repo_commits_elements_file', '/%(repo_name)s/commits_elements/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
297 pyroutes.register('repo_commits_file', '/%(repo_name)s/commits/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
303 pyroutes.register('repo_commits_file', '/%(repo_name)s/commits/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
298 pyroutes.register('repo_compare', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']);
304 pyroutes.register('repo_compare', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']);
299 pyroutes.register('repo_compare_select', '/%(repo_name)s/compare', ['repo_name']);
305 pyroutes.register('repo_compare_select', '/%(repo_name)s/compare', ['repo_name']);
300 pyroutes.register('repo_create', '/_admin/repos/create', []);
306 pyroutes.register('repo_create', '/_admin/repos/create', []);
301 pyroutes.register('repo_creating', '/%(repo_name)s/repo_creating', ['repo_name']);
307 pyroutes.register('repo_creating', '/%(repo_name)s/repo_creating', ['repo_name']);
302 pyroutes.register('repo_creating_check', '/%(repo_name)s/repo_creating_check', ['repo_name']);
308 pyroutes.register('repo_creating_check', '/%(repo_name)s/repo_creating_check', ['repo_name']);
303 pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/settings/review/default-reviewers', ['repo_name']);
309 pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/settings/review/default-reviewers', ['repo_name']);
304 pyroutes.register('repo_edit_toggle_locking', '/%(repo_name)s/settings/toggle_locking', ['repo_name']);
310 pyroutes.register('repo_edit_toggle_locking', '/%(repo_name)s/settings/toggle_locking', ['repo_name']);
305 pyroutes.register('repo_file_authors', '/%(repo_name)s/authors/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
311 pyroutes.register('repo_file_authors', '/%(repo_name)s/authors/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
306 pyroutes.register('repo_file_download', '/%(repo_name)s/download/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
312 pyroutes.register('repo_file_download', '/%(repo_name)s/download/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
307 pyroutes.register('repo_file_download:legacy', '/%(repo_name)s/rawfile/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
313 pyroutes.register('repo_file_download:legacy', '/%(repo_name)s/rawfile/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
308 pyroutes.register('repo_file_history', '/%(repo_name)s/history/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
314 pyroutes.register('repo_file_history', '/%(repo_name)s/history/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
309 pyroutes.register('repo_file_raw', '/%(repo_name)s/raw/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
315 pyroutes.register('repo_file_raw', '/%(repo_name)s/raw/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
310 pyroutes.register('repo_files', '/%(repo_name)s/files/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
316 pyroutes.register('repo_files', '/%(repo_name)s/files/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
311 pyroutes.register('repo_files:annotated', '/%(repo_name)s/annotate/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
317 pyroutes.register('repo_files:annotated', '/%(repo_name)s/annotate/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
312 pyroutes.register('repo_files:annotated_previous', '/%(repo_name)s/annotate-previous/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
318 pyroutes.register('repo_files:annotated_previous', '/%(repo_name)s/annotate-previous/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
313 pyroutes.register('repo_files:default_commit', '/%(repo_name)s/files', ['repo_name']);
319 pyroutes.register('repo_files:default_commit', '/%(repo_name)s/files', ['repo_name']);
314 pyroutes.register('repo_files:default_path', '/%(repo_name)s/files/%(commit_id)s/', ['repo_name', 'commit_id']);
320 pyroutes.register('repo_files:default_path', '/%(repo_name)s/files/%(commit_id)s/', ['repo_name', 'commit_id']);
315 pyroutes.register('repo_files:rendered', '/%(repo_name)s/render/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
321 pyroutes.register('repo_files:rendered', '/%(repo_name)s/render/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
316 pyroutes.register('repo_files_add_file', '/%(repo_name)s/add_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
322 pyroutes.register('repo_files_add_file', '/%(repo_name)s/add_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
317 pyroutes.register('repo_files_check_head', '/%(repo_name)s/check_head/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
323 pyroutes.register('repo_files_check_head', '/%(repo_name)s/check_head/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
318 pyroutes.register('repo_files_create_file', '/%(repo_name)s/create_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
324 pyroutes.register('repo_files_create_file', '/%(repo_name)s/create_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
319 pyroutes.register('repo_files_delete_file', '/%(repo_name)s/delete_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
325 pyroutes.register('repo_files_delete_file', '/%(repo_name)s/delete_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
320 pyroutes.register('repo_files_diff', '/%(repo_name)s/diff/%(f_path)s', ['repo_name', 'f_path']);
326 pyroutes.register('repo_files_diff', '/%(repo_name)s/diff/%(f_path)s', ['repo_name', 'f_path']);
321 pyroutes.register('repo_files_diff_2way_redirect', '/%(repo_name)s/diff-2way/%(f_path)s', ['repo_name', 'f_path']);
327 pyroutes.register('repo_files_diff_2way_redirect', '/%(repo_name)s/diff-2way/%(f_path)s', ['repo_name', 'f_path']);
322 pyroutes.register('repo_files_edit_file', '/%(repo_name)s/edit_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
328 pyroutes.register('repo_files_edit_file', '/%(repo_name)s/edit_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
323 pyroutes.register('repo_files_nodelist', '/%(repo_name)s/nodelist/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
329 pyroutes.register('repo_files_nodelist', '/%(repo_name)s/nodelist/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
324 pyroutes.register('repo_files_remove_file', '/%(repo_name)s/remove_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
330 pyroutes.register('repo_files_remove_file', '/%(repo_name)s/remove_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
325 pyroutes.register('repo_files_update_file', '/%(repo_name)s/update_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
331 pyroutes.register('repo_files_update_file', '/%(repo_name)s/update_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
326 pyroutes.register('repo_files_upload_file', '/%(repo_name)s/upload_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
332 pyroutes.register('repo_files_upload_file', '/%(repo_name)s/upload_file/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
327 pyroutes.register('repo_fork_create', '/%(repo_name)s/fork/create', ['repo_name']);
333 pyroutes.register('repo_fork_create', '/%(repo_name)s/fork/create', ['repo_name']);
328 pyroutes.register('repo_fork_new', '/%(repo_name)s/fork', ['repo_name']);
334 pyroutes.register('repo_fork_new', '/%(repo_name)s/fork', ['repo_name']);
329 pyroutes.register('repo_forks_data', '/%(repo_name)s/forks/data', ['repo_name']);
335 pyroutes.register('repo_forks_data', '/%(repo_name)s/forks/data', ['repo_name']);
330 pyroutes.register('repo_forks_show_all', '/%(repo_name)s/forks', ['repo_name']);
336 pyroutes.register('repo_forks_show_all', '/%(repo_name)s/forks', ['repo_name']);
331 pyroutes.register('repo_group_create', '/_admin/repo_group/create', []);
337 pyroutes.register('repo_group_create', '/_admin/repo_group/create', []);
332 pyroutes.register('repo_group_home', '/%(repo_group_name)s', ['repo_group_name']);
338 pyroutes.register('repo_group_home', '/%(repo_group_name)s', ['repo_group_name']);
333 pyroutes.register('repo_group_home_slash', '/%(repo_group_name)s/', ['repo_group_name']);
339 pyroutes.register('repo_group_home_slash', '/%(repo_group_name)s/', ['repo_group_name']);
334 pyroutes.register('repo_group_integrations_create', '/%(repo_group_name)s/_settings/integrations/%(integration)s/new', ['repo_group_name', 'integration']);
340 pyroutes.register('repo_group_integrations_create', '/%(repo_group_name)s/_settings/integrations/%(integration)s/new', ['repo_group_name', 'integration']);
335 pyroutes.register('repo_group_integrations_edit', '/%(repo_group_name)s/_settings/integrations/%(integration)s/%(integration_id)s', ['repo_group_name', 'integration', 'integration_id']);
341 pyroutes.register('repo_group_integrations_edit', '/%(repo_group_name)s/_settings/integrations/%(integration)s/%(integration_id)s', ['repo_group_name', 'integration', 'integration_id']);
336 pyroutes.register('repo_group_integrations_home', '/%(repo_group_name)s/_settings/integrations', ['repo_group_name']);
342 pyroutes.register('repo_group_integrations_home', '/%(repo_group_name)s/_settings/integrations', ['repo_group_name']);
337 pyroutes.register('repo_group_integrations_list', '/%(repo_group_name)s/_settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
343 pyroutes.register('repo_group_integrations_list', '/%(repo_group_name)s/_settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
338 pyroutes.register('repo_group_integrations_new', '/%(repo_group_name)s/_settings/integrations/new', ['repo_group_name']);
344 pyroutes.register('repo_group_integrations_new', '/%(repo_group_name)s/_settings/integrations/new', ['repo_group_name']);
339 pyroutes.register('repo_group_list_data', '/_repo_groups', []);
345 pyroutes.register('repo_group_list_data', '/_repo_groups', []);
340 pyroutes.register('repo_group_new', '/_admin/repo_group/new', []);
346 pyroutes.register('repo_group_new', '/_admin/repo_group/new', []);
341 pyroutes.register('repo_groups', '/_admin/repo_groups', []);
347 pyroutes.register('repo_groups', '/_admin/repo_groups', []);
342 pyroutes.register('repo_groups_data', '/_admin/repo_groups_data', []);
348 pyroutes.register('repo_groups_data', '/_admin/repo_groups_data', []);
343 pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
349 pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
344 pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
350 pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
345 pyroutes.register('repo_integrations_home', '/%(repo_name)s/settings/integrations', ['repo_name']);
351 pyroutes.register('repo_integrations_home', '/%(repo_name)s/settings/integrations', ['repo_name']);
346 pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
352 pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
347 pyroutes.register('repo_integrations_new', '/%(repo_name)s/settings/integrations/new', ['repo_name']);
353 pyroutes.register('repo_integrations_new', '/%(repo_name)s/settings/integrations/new', ['repo_name']);
348 pyroutes.register('repo_list_data', '/_repos', []);
354 pyroutes.register('repo_list_data', '/_repos', []);
349 pyroutes.register('repo_new', '/_admin/repos/new', []);
355 pyroutes.register('repo_new', '/_admin/repos/new', []);
350 pyroutes.register('repo_nodetree_full', '/%(repo_name)s/nodetree_full/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
356 pyroutes.register('repo_nodetree_full', '/%(repo_name)s/nodetree_full/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
351 pyroutes.register('repo_nodetree_full:default_path', '/%(repo_name)s/nodetree_full/%(commit_id)s/', ['repo_name', 'commit_id']);
357 pyroutes.register('repo_nodetree_full:default_path', '/%(repo_name)s/nodetree_full/%(commit_id)s/', ['repo_name', 'commit_id']);
352 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
358 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
353 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
359 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
354 pyroutes.register('repo_reviewers', '/%(repo_name)s/settings/review/rules', ['repo_name']);
360 pyroutes.register('repo_reviewers', '/%(repo_name)s/settings/review/rules', ['repo_name']);
355 pyroutes.register('repo_reviewers_review_rule_delete', '/%(repo_name)s/settings/review/rules/%(rule_id)s/delete', ['repo_name', 'rule_id']);
361 pyroutes.register('repo_reviewers_review_rule_delete', '/%(repo_name)s/settings/review/rules/%(rule_id)s/delete', ['repo_name', 'rule_id']);
356 pyroutes.register('repo_reviewers_review_rule_edit', '/%(repo_name)s/settings/review/rules/%(rule_id)s', ['repo_name', 'rule_id']);
362 pyroutes.register('repo_reviewers_review_rule_edit', '/%(repo_name)s/settings/review/rules/%(rule_id)s', ['repo_name', 'rule_id']);
357 pyroutes.register('repo_reviewers_review_rule_new', '/%(repo_name)s/settings/review/rules/new', ['repo_name']);
363 pyroutes.register('repo_reviewers_review_rule_new', '/%(repo_name)s/settings/review/rules/new', ['repo_name']);
358 pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
364 pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
359 pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']);
365 pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']);
360 pyroutes.register('repo_summary_commits', '/%(repo_name)s/summary-commits', ['repo_name']);
366 pyroutes.register('repo_summary_commits', '/%(repo_name)s/summary-commits', ['repo_name']);
361 pyroutes.register('repo_summary_explicit', '/%(repo_name)s/summary', ['repo_name']);
367 pyroutes.register('repo_summary_explicit', '/%(repo_name)s/summary', ['repo_name']);
362 pyroutes.register('repo_summary_slash', '/%(repo_name)s/', ['repo_name']);
368 pyroutes.register('repo_summary_slash', '/%(repo_name)s/', ['repo_name']);
363 pyroutes.register('repos', '/_admin/repos', []);
369 pyroutes.register('repos', '/_admin/repos', []);
364 pyroutes.register('repos_data', '/_admin/repos_data', []);
370 pyroutes.register('repos_data', '/_admin/repos_data', []);
365 pyroutes.register('reset_password', '/_admin/password_reset', []);
371 pyroutes.register('reset_password', '/_admin/password_reset', []);
366 pyroutes.register('reset_password_confirmation', '/_admin/password_reset_confirmation', []);
372 pyroutes.register('reset_password_confirmation', '/_admin/password_reset_confirmation', []);
367 pyroutes.register('robots', '/robots.txt', []);
373 pyroutes.register('robots', '/robots.txt', []);
368 pyroutes.register('rss_feed_home', '/%(repo_name)s/feed-rss', ['repo_name']);
374 pyroutes.register('rss_feed_home', '/%(repo_name)s/feed-rss', ['repo_name']);
369 pyroutes.register('rss_feed_home_old', '/%(repo_name)s/feed/rss', ['repo_name']);
375 pyroutes.register('rss_feed_home_old', '/%(repo_name)s/feed/rss', ['repo_name']);
370 pyroutes.register('search', '/_admin/search', []);
376 pyroutes.register('search', '/_admin/search', []);
371 pyroutes.register('search_repo', '/%(repo_name)s/_search', ['repo_name']);
377 pyroutes.register('search_repo', '/%(repo_name)s/_search', ['repo_name']);
372 pyroutes.register('search_repo_alt', '/%(repo_name)s/search', ['repo_name']);
378 pyroutes.register('search_repo_alt', '/%(repo_name)s/search', ['repo_name']);
373 pyroutes.register('search_repo_group', '/%(repo_group_name)s/_search', ['repo_group_name']);
379 pyroutes.register('search_repo_group', '/%(repo_group_name)s/_search', ['repo_group_name']);
374 pyroutes.register('store_user_session_value', '/_store_session_attr', []);
380 pyroutes.register('store_user_session_value', '/_store_session_attr', []);
375 pyroutes.register('strip_check', '/%(repo_name)s/settings/strip_check', ['repo_name']);
381 pyroutes.register('strip_check', '/%(repo_name)s/settings/strip_check', ['repo_name']);
376 pyroutes.register('strip_execute', '/%(repo_name)s/settings/strip_execute', ['repo_name']);
382 pyroutes.register('strip_execute', '/%(repo_name)s/settings/strip_execute', ['repo_name']);
377 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
383 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
378 pyroutes.register('toggle_following', '/_admin/toggle_following', []);
384 pyroutes.register('toggle_following', '/_admin/toggle_following', []);
379 pyroutes.register('upload_file', '/_file_store/upload', []);
385 pyroutes.register('upload_file', '/_file_store/upload', []);
380 pyroutes.register('user_autocomplete_data', '/_users', []);
386 pyroutes.register('user_autocomplete_data', '/_users', []);
381 pyroutes.register('user_create_personal_repo_group', '/_admin/users/%(user_id)s/create_repo_group', ['user_id']);
387 pyroutes.register('user_create_personal_repo_group', '/_admin/users/%(user_id)s/create_repo_group', ['user_id']);
382 pyroutes.register('user_delete', '/_admin/users/%(user_id)s/delete', ['user_id']);
388 pyroutes.register('user_delete', '/_admin/users/%(user_id)s/delete', ['user_id']);
383 pyroutes.register('user_disable_force_password_reset', '/_admin/users/%(user_id)s/password_reset_disable', ['user_id']);
389 pyroutes.register('user_disable_force_password_reset', '/_admin/users/%(user_id)s/password_reset_disable', ['user_id']);
384 pyroutes.register('user_edit', '/_admin/users/%(user_id)s/edit', ['user_id']);
390 pyroutes.register('user_edit', '/_admin/users/%(user_id)s/edit', ['user_id']);
385 pyroutes.register('user_edit_advanced', '/_admin/users/%(user_id)s/edit/advanced', ['user_id']);
391 pyroutes.register('user_edit_advanced', '/_admin/users/%(user_id)s/edit/advanced', ['user_id']);
386 pyroutes.register('user_edit_global_perms', '/_admin/users/%(user_id)s/edit/global_permissions', ['user_id']);
392 pyroutes.register('user_edit_global_perms', '/_admin/users/%(user_id)s/edit/global_permissions', ['user_id']);
387 pyroutes.register('user_edit_global_perms_update', '/_admin/users/%(user_id)s/edit/global_permissions/update', ['user_id']);
393 pyroutes.register('user_edit_global_perms_update', '/_admin/users/%(user_id)s/edit/global_permissions/update', ['user_id']);
388 pyroutes.register('user_enable_force_password_reset', '/_admin/users/%(user_id)s/password_reset_enable', ['user_id']);
394 pyroutes.register('user_enable_force_password_reset', '/_admin/users/%(user_id)s/password_reset_enable', ['user_id']);
389 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
395 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
390 pyroutes.register('user_group_members_data', '/_admin/user_groups/%(user_group_id)s/members', ['user_group_id']);
396 pyroutes.register('user_group_members_data', '/_admin/user_groups/%(user_group_id)s/members', ['user_group_id']);
391 pyroutes.register('user_group_profile', '/_profile_user_group/%(user_group_name)s', ['user_group_name']);
397 pyroutes.register('user_group_profile', '/_profile_user_group/%(user_group_name)s', ['user_group_name']);
392 pyroutes.register('user_groups', '/_admin/user_groups', []);
398 pyroutes.register('user_groups', '/_admin/user_groups', []);
393 pyroutes.register('user_groups_create', '/_admin/user_groups/create', []);
399 pyroutes.register('user_groups_create', '/_admin/user_groups/create', []);
394 pyroutes.register('user_groups_data', '/_admin/user_groups_data', []);
400 pyroutes.register('user_groups_data', '/_admin/user_groups_data', []);
395 pyroutes.register('user_groups_delete', '/_admin/user_groups/%(user_group_id)s/delete', ['user_group_id']);
401 pyroutes.register('user_groups_delete', '/_admin/user_groups/%(user_group_id)s/delete', ['user_group_id']);
396 pyroutes.register('user_groups_new', '/_admin/user_groups/new', []);
402 pyroutes.register('user_groups_new', '/_admin/user_groups/new', []);
397 pyroutes.register('user_groups_update', '/_admin/user_groups/%(user_group_id)s/update', ['user_group_id']);
403 pyroutes.register('user_groups_update', '/_admin/user_groups/%(user_group_id)s/update', ['user_group_id']);
398 pyroutes.register('user_notice_dismiss', '/_admin/users/%(user_id)s/notice_dismiss', ['user_id']);
404 pyroutes.register('user_notice_dismiss', '/_admin/users/%(user_id)s/notice_dismiss', ['user_id']);
399 pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']);
405 pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']);
400 pyroutes.register('user_update', '/_admin/users/%(user_id)s/update', ['user_id']);
406 pyroutes.register('user_update', '/_admin/users/%(user_id)s/update', ['user_id']);
401 pyroutes.register('users', '/_admin/users', []);
407 pyroutes.register('users', '/_admin/users', []);
402 pyroutes.register('users_create', '/_admin/users/create', []);
408 pyroutes.register('users_create', '/_admin/users/create', []);
403 pyroutes.register('users_data', '/_admin/users_data', []);
409 pyroutes.register('users_data', '/_admin/users_data', []);
404 pyroutes.register('users_new', '/_admin/users/new', []);
410 pyroutes.register('users_new', '/_admin/users/new', []);
405 }
411 }
@@ -1,1262 +1,1263 b''
1 ## -*- coding: utf-8 -*-
1 ## -*- coding: utf-8 -*-
2
2
3 <%!
3 <%!
4 from rhodecode.lib import html_filters
4 from rhodecode.lib import html_filters
5 %>
5 %>
6
6
7 <%inherit file="root.mako"/>
7 <%inherit file="root.mako"/>
8
8
9 <%include file="/ejs_templates/templates.html"/>
9 <%include file="/ejs_templates/templates.html"/>
10
10
11 <div class="outerwrapper">
11 <div class="outerwrapper">
12 <!-- HEADER -->
12 <!-- HEADER -->
13 <div class="header">
13 <div class="header">
14 <div id="header-inner" class="wrapper">
14 <div id="header-inner" class="wrapper">
15 <div id="logo">
15 <div id="logo">
16 <div class="logo-wrapper">
16 <div class="logo-wrapper">
17 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
17 <a href="${h.route_path('home')}"><img src="${h.asset('images/rhodecode-logo-white-60x60.png')}" alt="RhodeCode"/></a>
18 </div>
18 </div>
19 % if c.rhodecode_name:
19 % if c.rhodecode_name:
20 <div class="branding">
20 <div class="branding">
21 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
21 <a href="${h.route_path('home')}">${h.branding(c.rhodecode_name)}</a>
22 </div>
22 </div>
23 % endif
23 % endif
24 </div>
24 </div>
25 <!-- MENU BAR NAV -->
25 <!-- MENU BAR NAV -->
26 ${self.menu_bar_nav()}
26 ${self.menu_bar_nav()}
27 <!-- END MENU BAR NAV -->
27 <!-- END MENU BAR NAV -->
28 </div>
28 </div>
29 </div>
29 </div>
30 ${self.menu_bar_subnav()}
30 ${self.menu_bar_subnav()}
31 <!-- END HEADER -->
31 <!-- END HEADER -->
32
32
33 <!-- CONTENT -->
33 <!-- CONTENT -->
34 <div id="content" class="wrapper">
34 <div id="content" class="wrapper">
35
35
36 <rhodecode-toast id="notifications"></rhodecode-toast>
36 <rhodecode-toast id="notifications"></rhodecode-toast>
37
37
38 <div class="main">
38 <div class="main">
39 ${next.main()}
39 ${next.main()}
40 </div>
40 </div>
41
41
42 </div>
42 </div>
43 <!-- END CONTENT -->
43 <!-- END CONTENT -->
44
44
45 </div>
45 </div>
46
46
47 <!-- FOOTER -->
47 <!-- FOOTER -->
48 <div id="footer">
48 <div id="footer">
49 <div id="footer-inner" class="title wrapper">
49 <div id="footer-inner" class="title wrapper">
50 <div>
50 <div>
51 <% sid = 'block' if request.GET.get('showrcid') else 'none' %>
51 <% sid = 'block' if request.GET.get('showrcid') else 'none' %>
52
52
53 <p class="footer-link-right">
53 <p class="footer-link-right">
54 <a class="grey-link-action" href="${h.route_path('home', _query={'showrcid': 1})}">
54 <a class="grey-link-action" href="${h.route_path('home', _query={'showrcid': 1})}">
55 RhodeCode
55 RhodeCode
56 % if c.visual.show_version:
56 % if c.visual.show_version:
57 ${c.rhodecode_version}
57 ${c.rhodecode_version}
58 % endif
58 % endif
59 ${c.rhodecode_edition}
59 ${c.rhodecode_edition}
60 </a> |
60 </a> |
61
61
62 % if c.visual.rhodecode_support_url:
62 % if c.visual.rhodecode_support_url:
63 <a class="grey-link-action" href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support')}</a> |
63 <a class="grey-link-action" href="${c.visual.rhodecode_support_url}" target="_blank">${_('Support')}</a> |
64 <a class="grey-link-action" href="https://docs.rhodecode.com" target="_blank">${_('Documentation')}</a>
64 <a class="grey-link-action" href="https://docs.rhodecode.com" target="_blank">${_('Documentation')}</a>
65 % endif
65 % endif
66
66
67 </p>
67 </p>
68
68
69 <p class="server-instance" style="display:${sid}">
69 <p class="server-instance" style="display:${sid}">
70 ## display hidden instance ID if specially defined
70 ## display hidden instance ID if specially defined
71 &copy; 2010-${h.datetime.today().year}, <a href="${h.route_url('rhodecode_official')}" target="_blank">RhodeCode GmbH</a>. All rights reserved.
71 &copy; 2010-${h.datetime.today().year}, <a href="${h.route_url('rhodecode_official')}" target="_blank">RhodeCode GmbH</a>. All rights reserved.
72 % if c.rhodecode_instanceid:
72 % if c.rhodecode_instanceid:
73 ${_('RhodeCode instance id: {}').format(c.rhodecode_instanceid)}
73 ${_('RhodeCode instance id: {}').format(c.rhodecode_instanceid)}
74 % endif
74 % endif
75 </p>
75 </p>
76 </div>
76 </div>
77 </div>
77 </div>
78 </div>
78 </div>
79
79
80 <!-- END FOOTER -->
80 <!-- END FOOTER -->
81
81
82 ### MAKO DEFS ###
82 ### MAKO DEFS ###
83
83
84 <%def name="menu_bar_subnav()">
84 <%def name="menu_bar_subnav()">
85 </%def>
85 </%def>
86
86
87 <%def name="breadcrumbs(class_='breadcrumbs')">
87 <%def name="breadcrumbs(class_='breadcrumbs')">
88 <div class="${class_}">
88 <div class="${class_}">
89 ${self.breadcrumbs_links()}
89 ${self.breadcrumbs_links()}
90 </div>
90 </div>
91 </%def>
91 </%def>
92
92
93 <%def name="admin_menu(active=None)">
93 <%def name="admin_menu(active=None)">
94
94
95 <div id="context-bar">
95 <div id="context-bar">
96 <div class="wrapper">
96 <div class="wrapper">
97 <div class="title">
97 <div class="title">
98 <div class="title-content">
98 <div class="title-content">
99 <div class="title-main">
99 <div class="title-main">
100 % if c.is_super_admin:
100 % if c.is_super_admin:
101 ${_('Super-admin Panel')}
101 ${_('Super-admin Panel')}
102 % else:
102 % else:
103 ${_('Delegated Admin Panel')}
103 ${_('Delegated Admin Panel')}
104 % endif
104 % endif
105 </div>
105 </div>
106 </div>
106 </div>
107 </div>
107 </div>
108
108
109 <ul id="context-pages" class="navigation horizontal-list">
109 <ul id="context-pages" class="navigation horizontal-list">
110
110
111 ## super-admin case
111 ## super-admin case
112 % if c.is_super_admin:
112 % if c.is_super_admin:
113 <li class="${h.is_active('audit_logs', active)}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
113 <li class="${h.is_active('audit_logs', active)}"><a href="${h.route_path('admin_audit_logs')}">${_('Admin audit logs')}</a></li>
114 <li class="${h.is_active('repositories', active)}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
114 <li class="${h.is_active('repositories', active)}"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
115 <li class="${h.is_active('repository_groups', active)}"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
115 <li class="${h.is_active('repository_groups', active)}"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
116 <li class="${h.is_active('users', active)}"><a href="${h.route_path('users')}">${_('Users')}</a></li>
116 <li class="${h.is_active('users', active)}"><a href="${h.route_path('users')}">${_('Users')}</a></li>
117 <li class="${h.is_active('user_groups', active)}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
117 <li class="${h.is_active('user_groups', active)}"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
118 <li class="${h.is_active('artifacts', active)}"><a href="${h.route_path('admin_artifacts')}">${_('Artifacts')}</a></li>
118 <li class="${h.is_active('permissions', active)}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
119 <li class="${h.is_active('permissions', active)}"><a href="${h.route_path('admin_permissions_application')}">${_('Permissions')}</a></li>
119 <li class="${h.is_active('authentication', active)}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
120 <li class="${h.is_active('authentication', active)}"><a href="${h.route_path('auth_home', traverse='')}">${_('Authentication')}</a></li>
120 <li class="${h.is_active('integrations', active)}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
121 <li class="${h.is_active('integrations', active)}"><a href="${h.route_path('global_integrations_home')}">${_('Integrations')}</a></li>
121 <li class="${h.is_active('defaults', active)}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
122 <li class="${h.is_active('defaults', active)}"><a href="${h.route_path('admin_defaults_repositories')}">${_('Defaults')}</a></li>
122 <li class="${h.is_active('settings', active)}"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
123 <li class="${h.is_active('settings', active)}"><a href="${h.route_path('admin_settings')}">${_('Settings')}</a></li>
123
124
124 ## delegated admin
125 ## delegated admin
125 % elif c.is_delegated_admin:
126 % elif c.is_delegated_admin:
126 <%
127 <%
127 repositories=c.auth_user.repositories_admin or c.can_create_repo
128 repositories=c.auth_user.repositories_admin or c.can_create_repo
128 repository_groups=c.auth_user.repository_groups_admin or c.can_create_repo_group
129 repository_groups=c.auth_user.repository_groups_admin or c.can_create_repo_group
129 user_groups=c.auth_user.user_groups_admin or c.can_create_user_group
130 user_groups=c.auth_user.user_groups_admin or c.can_create_user_group
130 %>
131 %>
131
132
132 %if repositories:
133 %if repositories:
133 <li class="${h.is_active('repositories', active)} local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
134 <li class="${h.is_active('repositories', active)} local-admin-repos"><a href="${h.route_path('repos')}">${_('Repositories')}</a></li>
134 %endif
135 %endif
135 %if repository_groups:
136 %if repository_groups:
136 <li class="${h.is_active('repository_groups', active)} local-admin-repo-groups"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
137 <li class="${h.is_active('repository_groups', active)} local-admin-repo-groups"><a href="${h.route_path('repo_groups')}">${_('Repository groups')}</a></li>
137 %endif
138 %endif
138 %if user_groups:
139 %if user_groups:
139 <li class="${h.is_active('user_groups', active)} local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
140 <li class="${h.is_active('user_groups', active)} local-admin-user-groups"><a href="${h.route_path('user_groups')}">${_('User groups')}</a></li>
140 %endif
141 %endif
141 % endif
142 % endif
142 </ul>
143 </ul>
143
144
144 </div>
145 </div>
145 <div class="clear"></div>
146 <div class="clear"></div>
146 </div>
147 </div>
147 </%def>
148 </%def>
148
149
149 <%def name="dt_info_panel(elements)">
150 <%def name="dt_info_panel(elements)">
150 <dl class="dl-horizontal">
151 <dl class="dl-horizontal">
151 %for dt, dd, title, show_items in elements:
152 %for dt, dd, title, show_items in elements:
152 <dt>${dt}:</dt>
153 <dt>${dt}:</dt>
153 <dd title="${h.tooltip(title)}">
154 <dd title="${h.tooltip(title)}">
154 %if callable(dd):
155 %if callable(dd):
155 ## allow lazy evaluation of elements
156 ## allow lazy evaluation of elements
156 ${dd()}
157 ${dd()}
157 %else:
158 %else:
158 ${dd}
159 ${dd}
159 %endif
160 %endif
160 %if show_items:
161 %if show_items:
161 <span class="btn-collapse" data-toggle="item-${h.md5_safe(dt)[:6]}-details">${_('Show More')} </span>
162 <span class="btn-collapse" data-toggle="item-${h.md5_safe(dt)[:6]}-details">${_('Show More')} </span>
162 %endif
163 %endif
163 </dd>
164 </dd>
164
165
165 %if show_items:
166 %if show_items:
166 <div class="collapsable-content" data-toggle="item-${h.md5_safe(dt)[:6]}-details" style="display: none">
167 <div class="collapsable-content" data-toggle="item-${h.md5_safe(dt)[:6]}-details" style="display: none">
167 %for item in show_items:
168 %for item in show_items:
168 <dt></dt>
169 <dt></dt>
169 <dd>${item}</dd>
170 <dd>${item}</dd>
170 %endfor
171 %endfor
171 </div>
172 </div>
172 %endif
173 %endif
173
174
174 %endfor
175 %endfor
175 </dl>
176 </dl>
176 </%def>
177 </%def>
177
178
178 <%def name="tr_info_entry(element)">
179 <%def name="tr_info_entry(element)">
179 <% key, val, title, show_items = element %>
180 <% key, val, title, show_items = element %>
180
181
181 <tr>
182 <tr>
182 <td style="vertical-align: top">${key}</td>
183 <td style="vertical-align: top">${key}</td>
183 <td title="${h.tooltip(title)}">
184 <td title="${h.tooltip(title)}">
184 %if callable(val):
185 %if callable(val):
185 ## allow lazy evaluation of elements
186 ## allow lazy evaluation of elements
186 ${val()}
187 ${val()}
187 %else:
188 %else:
188 ${val}
189 ${val}
189 %endif
190 %endif
190 %if show_items:
191 %if show_items:
191 <div class="collapsable-content" data-toggle="item-${h.md5_safe(val)[:6]}-details" style="display: none">
192 <div class="collapsable-content" data-toggle="item-${h.md5_safe(val)[:6]}-details" style="display: none">
192 % for item in show_items:
193 % for item in show_items:
193 <dt></dt>
194 <dt></dt>
194 <dd>${item}</dd>
195 <dd>${item}</dd>
195 % endfor
196 % endfor
196 </div>
197 </div>
197 %endif
198 %endif
198 </td>
199 </td>
199 <td style="vertical-align: top">
200 <td style="vertical-align: top">
200 %if show_items:
201 %if show_items:
201 <span class="btn-collapse" data-toggle="item-${h.md5_safe(val)[:6]}-details">${_('Show More')} </span>
202 <span class="btn-collapse" data-toggle="item-${h.md5_safe(val)[:6]}-details">${_('Show More')} </span>
202 %endif
203 %endif
203 </td>
204 </td>
204 </tr>
205 </tr>
205
206
206 </%def>
207 </%def>
207
208
208 <%def name="gravatar(email, size=16, tooltip=False, tooltip_alt=None, user=None, extra_class=None)">
209 <%def name="gravatar(email, size=16, tooltip=False, tooltip_alt=None, user=None, extra_class=None)">
209 <%
210 <%
210 if size > 16:
211 if size > 16:
211 gravatar_class = ['gravatar','gravatar-large']
212 gravatar_class = ['gravatar','gravatar-large']
212 else:
213 else:
213 gravatar_class = ['gravatar']
214 gravatar_class = ['gravatar']
214
215
215 data_hovercard_url = ''
216 data_hovercard_url = ''
216 data_hovercard_alt = tooltip_alt.replace('<', '&lt;').replace('>', '&gt;') if tooltip_alt else ''
217 data_hovercard_alt = tooltip_alt.replace('<', '&lt;').replace('>', '&gt;') if tooltip_alt else ''
217
218
218 if tooltip:
219 if tooltip:
219 gravatar_class += ['tooltip-hovercard']
220 gravatar_class += ['tooltip-hovercard']
220 if extra_class:
221 if extra_class:
221 gravatar_class += extra_class
222 gravatar_class += extra_class
222 if tooltip and user:
223 if tooltip and user:
223 if user.username == h.DEFAULT_USER:
224 if user.username == h.DEFAULT_USER:
224 gravatar_class.pop(-1)
225 gravatar_class.pop(-1)
225 else:
226 else:
226 data_hovercard_url = request.route_path('hovercard_user', user_id=getattr(user, 'user_id', ''))
227 data_hovercard_url = request.route_path('hovercard_user', user_id=getattr(user, 'user_id', ''))
227 gravatar_class = ' '.join(gravatar_class)
228 gravatar_class = ' '.join(gravatar_class)
228
229
229 %>
230 %>
230 <%doc>
231 <%doc>
231 TODO: johbo: For now we serve double size images to make it smooth
232 TODO: johbo: For now we serve double size images to make it smooth
232 for retina. This is how it worked until now. Should be replaced
233 for retina. This is how it worked until now. Should be replaced
233 with a better solution at some point.
234 with a better solution at some point.
234 </%doc>
235 </%doc>
235
236
236 <img class="${gravatar_class}" height="${size}" width="${size}" data-hovercard-url="${data_hovercard_url}" data-hovercard-alt="${data_hovercard_alt}" src="${h.gravatar_url(email, size * 2)}" />
237 <img class="${gravatar_class}" height="${size}" width="${size}" data-hovercard-url="${data_hovercard_url}" data-hovercard-alt="${data_hovercard_alt}" src="${h.gravatar_url(email, size * 2)}" />
237 </%def>
238 </%def>
238
239
239
240
240 <%def name="gravatar_with_user(contact, size=16, show_disabled=False, tooltip=False, _class='rc-user')">
241 <%def name="gravatar_with_user(contact, size=16, show_disabled=False, tooltip=False, _class='rc-user')">
241 <%
242 <%
242 email = h.email_or_none(contact)
243 email = h.email_or_none(contact)
243 rc_user = h.discover_user(contact)
244 rc_user = h.discover_user(contact)
244 %>
245 %>
245
246
246 <div class="${_class}">
247 <div class="${_class}">
247 ${self.gravatar(email, size, tooltip=tooltip, tooltip_alt=contact, user=rc_user)}
248 ${self.gravatar(email, size, tooltip=tooltip, tooltip_alt=contact, user=rc_user)}
248 <span class="${('user user-disabled' if show_disabled else 'user')}">
249 <span class="${('user user-disabled' if show_disabled else 'user')}">
249 ${h.link_to_user(rc_user or contact)}
250 ${h.link_to_user(rc_user or contact)}
250 </span>
251 </span>
251 </div>
252 </div>
252 </%def>
253 </%def>
253
254
254
255
255 <%def name="user_group_icon(user_group=None, size=16, tooltip=False)">
256 <%def name="user_group_icon(user_group=None, size=16, tooltip=False)">
256 <%
257 <%
257 if (size > 16):
258 if (size > 16):
258 gravatar_class = 'icon-user-group-alt'
259 gravatar_class = 'icon-user-group-alt'
259 else:
260 else:
260 gravatar_class = 'icon-user-group-alt'
261 gravatar_class = 'icon-user-group-alt'
261
262
262 if tooltip:
263 if tooltip:
263 gravatar_class += ' tooltip-hovercard'
264 gravatar_class += ' tooltip-hovercard'
264
265
265 data_hovercard_url = request.route_path('hovercard_user_group', user_group_id=user_group.users_group_id)
266 data_hovercard_url = request.route_path('hovercard_user_group', user_group_id=user_group.users_group_id)
266 %>
267 %>
267 <%doc>
268 <%doc>
268 TODO: johbo: For now we serve double size images to make it smooth
269 TODO: johbo: For now we serve double size images to make it smooth
269 for retina. This is how it worked until now. Should be replaced
270 for retina. This is how it worked until now. Should be replaced
270 with a better solution at some point.
271 with a better solution at some point.
271 </%doc>
272 </%doc>
272
273
273 <i style="font-size: ${size}px" class="${gravatar_class} x-icon-size-${size}" data-hovercard-url="${data_hovercard_url}"></i>
274 <i style="font-size: ${size}px" class="${gravatar_class} x-icon-size-${size}" data-hovercard-url="${data_hovercard_url}"></i>
274 </%def>
275 </%def>
275
276
276 <%def name="repo_page_title(repo_instance)">
277 <%def name="repo_page_title(repo_instance)">
277 <div class="title-content repo-title">
278 <div class="title-content repo-title">
278
279
279 <div class="title-main">
280 <div class="title-main">
280 ## SVN/HG/GIT icons
281 ## SVN/HG/GIT icons
281 %if h.is_hg(repo_instance):
282 %if h.is_hg(repo_instance):
282 <i class="icon-hg"></i>
283 <i class="icon-hg"></i>
283 %endif
284 %endif
284 %if h.is_git(repo_instance):
285 %if h.is_git(repo_instance):
285 <i class="icon-git"></i>
286 <i class="icon-git"></i>
286 %endif
287 %endif
287 %if h.is_svn(repo_instance):
288 %if h.is_svn(repo_instance):
288 <i class="icon-svn"></i>
289 <i class="icon-svn"></i>
289 %endif
290 %endif
290
291
291 ## public/private
292 ## public/private
292 %if repo_instance.private:
293 %if repo_instance.private:
293 <i class="icon-repo-private"></i>
294 <i class="icon-repo-private"></i>
294 %else:
295 %else:
295 <i class="icon-repo-public"></i>
296 <i class="icon-repo-public"></i>
296 %endif
297 %endif
297
298
298 ## repo name with group name
299 ## repo name with group name
299 ${h.breadcrumb_repo_link(repo_instance)}
300 ${h.breadcrumb_repo_link(repo_instance)}
300
301
301 ## Context Actions
302 ## Context Actions
302 <div class="pull-right">
303 <div class="pull-right">
303 %if c.rhodecode_user.username != h.DEFAULT_USER:
304 %if c.rhodecode_user.username != h.DEFAULT_USER:
304 <a href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_uid, _query=dict(auth_token=c.rhodecode_user.feed_token))}" title="${_('RSS Feed')}" class="btn btn-sm"><i class="icon-rss-sign"></i>RSS</a>
305 <a href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_uid, _query=dict(auth_token=c.rhodecode_user.feed_token))}" title="${_('RSS Feed')}" class="btn btn-sm"><i class="icon-rss-sign"></i>RSS</a>
305
306
306 <a href="#WatchRepo" onclick="toggleFollowingRepo(this, templateContext.repo_id); return false" title="${_('Watch this Repository and actions on it in your personalized journal')}" class="btn btn-sm ${('watching' if c.repository_is_user_following else '')}">
307 <a href="#WatchRepo" onclick="toggleFollowingRepo(this, templateContext.repo_id); return false" title="${_('Watch this Repository and actions on it in your personalized journal')}" class="btn btn-sm ${('watching' if c.repository_is_user_following else '')}">
307 % if c.repository_is_user_following:
308 % if c.repository_is_user_following:
308 <i class="icon-eye-off"></i>${_('Unwatch')}
309 <i class="icon-eye-off"></i>${_('Unwatch')}
309 % else:
310 % else:
310 <i class="icon-eye"></i>${_('Watch')}
311 <i class="icon-eye"></i>${_('Watch')}
311 % endif
312 % endif
312
313
313 </a>
314 </a>
314 %else:
315 %else:
315 <a href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_uid)}" title="${_('RSS Feed')}" class="btn btn-sm"><i class="icon-rss-sign"></i>RSS</a>
316 <a href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_uid)}" title="${_('RSS Feed')}" class="btn btn-sm"><i class="icon-rss-sign"></i>RSS</a>
316 %endif
317 %endif
317 </div>
318 </div>
318
319
319 </div>
320 </div>
320
321
321 ## FORKED
322 ## FORKED
322 %if repo_instance.fork:
323 %if repo_instance.fork:
323 <p class="discreet">
324 <p class="discreet">
324 <i class="icon-code-fork"></i> ${_('Fork of')}
325 <i class="icon-code-fork"></i> ${_('Fork of')}
325 ${h.link_to_if(c.has_origin_repo_read_perm,repo_instance.fork.repo_name, h.route_path('repo_summary', repo_name=repo_instance.fork.repo_name))}
326 ${h.link_to_if(c.has_origin_repo_read_perm,repo_instance.fork.repo_name, h.route_path('repo_summary', repo_name=repo_instance.fork.repo_name))}
326 </p>
327 </p>
327 %endif
328 %endif
328
329
329 ## IMPORTED FROM REMOTE
330 ## IMPORTED FROM REMOTE
330 %if repo_instance.clone_uri:
331 %if repo_instance.clone_uri:
331 <p class="discreet">
332 <p class="discreet">
332 <i class="icon-code-fork"></i> ${_('Clone from')}
333 <i class="icon-code-fork"></i> ${_('Clone from')}
333 <a href="${h.safe_str(h.hide_credentials(repo_instance.clone_uri))}">${h.hide_credentials(repo_instance.clone_uri)}</a>
334 <a href="${h.safe_str(h.hide_credentials(repo_instance.clone_uri))}">${h.hide_credentials(repo_instance.clone_uri)}</a>
334 </p>
335 </p>
335 %endif
336 %endif
336
337
337 ## LOCKING STATUS
338 ## LOCKING STATUS
338 %if repo_instance.locked[0]:
339 %if repo_instance.locked[0]:
339 <p class="locking_locked discreet">
340 <p class="locking_locked discreet">
340 <i class="icon-repo-lock"></i>
341 <i class="icon-repo-lock"></i>
341 ${_('Repository locked by %(user)s') % {'user': h.person_by_id(repo_instance.locked[0])}}
342 ${_('Repository locked by %(user)s') % {'user': h.person_by_id(repo_instance.locked[0])}}
342 </p>
343 </p>
343 %elif repo_instance.enable_locking:
344 %elif repo_instance.enable_locking:
344 <p class="locking_unlocked discreet">
345 <p class="locking_unlocked discreet">
345 <i class="icon-repo-unlock"></i>
346 <i class="icon-repo-unlock"></i>
346 ${_('Repository not locked. Pull repository to lock it.')}
347 ${_('Repository not locked. Pull repository to lock it.')}
347 </p>
348 </p>
348 %endif
349 %endif
349
350
350 </div>
351 </div>
351 </%def>
352 </%def>
352
353
353 <%def name="repo_menu(active=None)">
354 <%def name="repo_menu(active=None)">
354 <%
355 <%
355 ## determine if we have "any" option available
356 ## determine if we have "any" option available
356 can_lock = h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking
357 can_lock = h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name) and c.rhodecode_db_repo.enable_locking
357 has_actions = can_lock
358 has_actions = can_lock
358
359
359 %>
360 %>
360 % if c.rhodecode_db_repo.archived:
361 % if c.rhodecode_db_repo.archived:
361 <div class="alert alert-warning text-center">
362 <div class="alert alert-warning text-center">
362 <strong>${_('This repository has been archived. It is now read-only.')}</strong>
363 <strong>${_('This repository has been archived. It is now read-only.')}</strong>
363 </div>
364 </div>
364 % endif
365 % endif
365
366
366 <!--- REPO CONTEXT BAR -->
367 <!--- REPO CONTEXT BAR -->
367 <div id="context-bar">
368 <div id="context-bar">
368 <div class="wrapper">
369 <div class="wrapper">
369
370
370 <div class="title">
371 <div class="title">
371 ${self.repo_page_title(c.rhodecode_db_repo)}
372 ${self.repo_page_title(c.rhodecode_db_repo)}
372 </div>
373 </div>
373
374
374 <ul id="context-pages" class="navigation horizontal-list">
375 <ul id="context-pages" class="navigation horizontal-list">
375 <li class="${h.is_active('summary', active)}"><a class="menulink" href="${h.route_path('repo_summary_explicit', repo_name=c.repo_name)}"><div class="menulabel">${_('Summary')}</div></a></li>
376 <li class="${h.is_active('summary', active)}"><a class="menulink" href="${h.route_path('repo_summary_explicit', repo_name=c.repo_name)}"><div class="menulabel">${_('Summary')}</div></a></li>
376 <li class="${h.is_active('commits', active)}"><a class="menulink" href="${h.route_path('repo_commits', repo_name=c.repo_name)}"><div class="menulabel">${_('Commits')}</div></a></li>
377 <li class="${h.is_active('commits', active)}"><a class="menulink" href="${h.route_path('repo_commits', repo_name=c.repo_name)}"><div class="menulabel">${_('Commits')}</div></a></li>
377 <li class="${h.is_active('files', active)}"><a class="menulink" href="${h.repo_files_by_ref_url(c.repo_name, c.rhodecode_db_repo.repo_type, f_path='', ref_name=c.rhodecode_db_repo.landing_ref_name, commit_id='tip', query={'at':c.rhodecode_db_repo.landing_ref_name})}"><div class="menulabel">${_('Files')}</div></a></li>
378 <li class="${h.is_active('files', active)}"><a class="menulink" href="${h.repo_files_by_ref_url(c.repo_name, c.rhodecode_db_repo.repo_type, f_path='', ref_name=c.rhodecode_db_repo.landing_ref_name, commit_id='tip', query={'at':c.rhodecode_db_repo.landing_ref_name})}"><div class="menulabel">${_('Files')}</div></a></li>
378 <li class="${h.is_active('compare', active)}"><a class="menulink" href="${h.route_path('repo_compare_select',repo_name=c.repo_name)}"><div class="menulabel">${_('Compare')}</div></a></li>
379 <li class="${h.is_active('compare', active)}"><a class="menulink" href="${h.route_path('repo_compare_select',repo_name=c.repo_name)}"><div class="menulabel">${_('Compare')}</div></a></li>
379
380
380 ## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
381 ## TODO: anderson: ideally it would have a function on the scm_instance "enable_pullrequest() and enable_fork()"
381 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
382 %if c.rhodecode_db_repo.repo_type in ['git','hg']:
382 <li class="${h.is_active('showpullrequest', active)}">
383 <li class="${h.is_active('showpullrequest', active)}">
383 <a class="menulink" href="${h.route_path('pullrequest_show_all', repo_name=c.repo_name)}" title="${h.tooltip(_('Show Pull Requests for %s') % c.repo_name)}">
384 <a class="menulink" href="${h.route_path('pullrequest_show_all', repo_name=c.repo_name)}" title="${h.tooltip(_('Show Pull Requests for %s') % c.repo_name)}">
384 <div class="menulabel">
385 <div class="menulabel">
385 ${_('Pull Requests')} <span class="menulink-counter">${c.repository_pull_requests}</span>
386 ${_('Pull Requests')} <span class="menulink-counter">${c.repository_pull_requests}</span>
386 </div>
387 </div>
387 </a>
388 </a>
388 </li>
389 </li>
389 %endif
390 %endif
390
391
391 <li class="${h.is_active('artifacts', active)}">
392 <li class="${h.is_active('artifacts', active)}">
392 <a class="menulink" href="${h.route_path('repo_artifacts_list',repo_name=c.repo_name)}">
393 <a class="menulink" href="${h.route_path('repo_artifacts_list',repo_name=c.repo_name)}">
393 <div class="menulabel">
394 <div class="menulabel">
394 ${_('Artifacts')} <span class="menulink-counter">${c.repository_artifacts}</span>
395 ${_('Artifacts')} <span class="menulink-counter">${c.repository_artifacts}</span>
395 </div>
396 </div>
396 </a>
397 </a>
397 </li>
398 </li>
398
399
399 %if not c.rhodecode_db_repo.archived and h.HasRepoPermissionAll('repository.admin')(c.repo_name):
400 %if not c.rhodecode_db_repo.archived and h.HasRepoPermissionAll('repository.admin')(c.repo_name):
400 <li class="${h.is_active('settings', active)}"><a class="menulink" href="${h.route_path('edit_repo',repo_name=c.repo_name)}"><div class="menulabel">${_('Repository Settings')}</div></a></li>
401 <li class="${h.is_active('settings', active)}"><a class="menulink" href="${h.route_path('edit_repo',repo_name=c.repo_name)}"><div class="menulabel">${_('Repository Settings')}</div></a></li>
401 %endif
402 %endif
402
403
403 <li class="${h.is_active('options', active)}">
404 <li class="${h.is_active('options', active)}">
404 % if has_actions:
405 % if has_actions:
405 <a class="menulink dropdown">
406 <a class="menulink dropdown">
406 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
407 <div class="menulabel">${_('Options')}<div class="show_more"></div></div>
407 </a>
408 </a>
408 <ul class="submenu">
409 <ul class="submenu">
409 %if can_lock:
410 %if can_lock:
410 %if c.rhodecode_db_repo.locked[0]:
411 %if c.rhodecode_db_repo.locked[0]:
411 <li><a class="locking_del" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Unlock Repository')}</a></li>
412 <li><a class="locking_del" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Unlock Repository')}</a></li>
412 %else:
413 %else:
413 <li><a class="locking_add" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Lock Repository')}</a></li>
414 <li><a class="locking_add" href="${h.route_path('repo_edit_toggle_locking',repo_name=c.repo_name)}">${_('Lock Repository')}</a></li>
414 %endif
415 %endif
415 %endif
416 %endif
416 </ul>
417 </ul>
417 % endif
418 % endif
418 </li>
419 </li>
419
420
420 </ul>
421 </ul>
421 </div>
422 </div>
422 <div class="clear"></div>
423 <div class="clear"></div>
423 </div>
424 </div>
424
425
425 <!--- REPO END CONTEXT BAR -->
426 <!--- REPO END CONTEXT BAR -->
426
427
427 </%def>
428 </%def>
428
429
429 <%def name="repo_group_page_title(repo_group_instance)">
430 <%def name="repo_group_page_title(repo_group_instance)">
430 <div class="title-content">
431 <div class="title-content">
431 <div class="title-main">
432 <div class="title-main">
432 ## Repository Group icon
433 ## Repository Group icon
433 <i class="icon-repo-group"></i>
434 <i class="icon-repo-group"></i>
434
435
435 ## repo name with group name
436 ## repo name with group name
436 ${h.breadcrumb_repo_group_link(repo_group_instance)}
437 ${h.breadcrumb_repo_group_link(repo_group_instance)}
437 </div>
438 </div>
438
439
439 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
440 <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
440 <div class="repo-group-desc discreet">
441 <div class="repo-group-desc discreet">
441 ${dt.repo_group_desc(repo_group_instance.description_safe, repo_group_instance.personal, c.visual.stylify_metatags)}
442 ${dt.repo_group_desc(repo_group_instance.description_safe, repo_group_instance.personal, c.visual.stylify_metatags)}
442 </div>
443 </div>
443
444
444 </div>
445 </div>
445 </%def>
446 </%def>
446
447
447
448
448 <%def name="repo_group_menu(active=None)">
449 <%def name="repo_group_menu(active=None)">
449 <%
450 <%
450 gr_name = c.repo_group.group_name if c.repo_group else None
451 gr_name = c.repo_group.group_name if c.repo_group else None
451 # create repositories with write permission on group is set to true
452 # create repositories with write permission on group is set to true
452 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
453 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
453
454
454 %>
455 %>
455
456
456
457
457 <!--- REPO GROUP CONTEXT BAR -->
458 <!--- REPO GROUP CONTEXT BAR -->
458 <div id="context-bar">
459 <div id="context-bar">
459 <div class="wrapper">
460 <div class="wrapper">
460 <div class="title">
461 <div class="title">
461 ${self.repo_group_page_title(c.repo_group)}
462 ${self.repo_group_page_title(c.repo_group)}
462 </div>
463 </div>
463
464
464 <ul id="context-pages" class="navigation horizontal-list">
465 <ul id="context-pages" class="navigation horizontal-list">
465 <li class="${h.is_active('home', active)}">
466 <li class="${h.is_active('home', active)}">
466 <a class="menulink" href="${h.route_path('repo_group_home', repo_group_name=c.repo_group.group_name)}"><div class="menulabel">${_('Group Home')}</div></a>
467 <a class="menulink" href="${h.route_path('repo_group_home', repo_group_name=c.repo_group.group_name)}"><div class="menulabel">${_('Group Home')}</div></a>
467 </li>
468 </li>
468 % if c.is_super_admin or group_admin:
469 % if c.is_super_admin or group_admin:
469 <li class="${h.is_active('settings', active)}">
470 <li class="${h.is_active('settings', active)}">
470 <a class="menulink" href="${h.route_path('edit_repo_group',repo_group_name=c.repo_group.group_name)}" title="${_('You have admin right to this group, and can edit it')}"><div class="menulabel">${_('Group Settings')}</div></a>
471 <a class="menulink" href="${h.route_path('edit_repo_group',repo_group_name=c.repo_group.group_name)}" title="${_('You have admin right to this group, and can edit it')}"><div class="menulabel">${_('Group Settings')}</div></a>
471 </li>
472 </li>
472 % endif
473 % endif
473
474
474 </ul>
475 </ul>
475 </div>
476 </div>
476 <div class="clear"></div>
477 <div class="clear"></div>
477 </div>
478 </div>
478
479
479 <!--- REPO GROUP CONTEXT BAR -->
480 <!--- REPO GROUP CONTEXT BAR -->
480
481
481 </%def>
482 </%def>
482
483
483
484
484 <%def name="usermenu(active=False)">
485 <%def name="usermenu(active=False)">
485 <%
486 <%
486 not_anonymous = c.rhodecode_user.username != h.DEFAULT_USER
487 not_anonymous = c.rhodecode_user.username != h.DEFAULT_USER
487
488
488 gr_name = c.repo_group.group_name if (hasattr(c, 'repo_group') and c.repo_group) else None
489 gr_name = c.repo_group.group_name if (hasattr(c, 'repo_group') and c.repo_group) else None
489 # create repositories with write permission on group is set to true
490 # create repositories with write permission on group is set to true
490
491
491 can_fork = c.is_super_admin or h.HasPermissionAny('hg.fork.repository')()
492 can_fork = c.is_super_admin or h.HasPermissionAny('hg.fork.repository')()
492 create_on_write = h.HasPermissionAny('hg.create.write_on_repogroup.true')()
493 create_on_write = h.HasPermissionAny('hg.create.write_on_repogroup.true')()
493 group_write = h.HasRepoGroupPermissionAny('group.write')(gr_name, 'can write into group index page')
494 group_write = h.HasRepoGroupPermissionAny('group.write')(gr_name, 'can write into group index page')
494 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
495 group_admin = h.HasRepoGroupPermissionAny('group.admin')(gr_name, 'group admin index page')
495
496
496 can_create_repos = c.is_super_admin or c.can_create_repo
497 can_create_repos = c.is_super_admin or c.can_create_repo
497 can_create_repo_groups = c.is_super_admin or c.can_create_repo_group
498 can_create_repo_groups = c.is_super_admin or c.can_create_repo_group
498
499
499 can_create_repos_in_group = c.is_super_admin or group_admin or (group_write and create_on_write)
500 can_create_repos_in_group = c.is_super_admin or group_admin or (group_write and create_on_write)
500 can_create_repo_groups_in_group = c.is_super_admin or group_admin
501 can_create_repo_groups_in_group = c.is_super_admin or group_admin
501 %>
502 %>
502
503
503 % if not_anonymous:
504 % if not_anonymous:
504 <%
505 <%
505 default_target_group = dict()
506 default_target_group = dict()
506 if c.rhodecode_user.personal_repo_group:
507 if c.rhodecode_user.personal_repo_group:
507 default_target_group = dict(parent_group=c.rhodecode_user.personal_repo_group.group_id)
508 default_target_group = dict(parent_group=c.rhodecode_user.personal_repo_group.group_id)
508 %>
509 %>
509
510
510 ## create action
511 ## create action
511 <li>
512 <li>
512 <a href="#create-actions" onclick="return false;" class="menulink childs">
513 <a href="#create-actions" onclick="return false;" class="menulink childs">
513 <i class="icon-plus-circled"></i>
514 <i class="icon-plus-circled"></i>
514 </a>
515 </a>
515
516
516 <div class="action-menu submenu">
517 <div class="action-menu submenu">
517
518
518 <ol>
519 <ol>
519 ## scope of within a repository
520 ## scope of within a repository
520 % if hasattr(c, 'rhodecode_db_repo') and c.rhodecode_db_repo:
521 % if hasattr(c, 'rhodecode_db_repo') and c.rhodecode_db_repo:
521 <li class="submenu-title">${_('This Repository')}</li>
522 <li class="submenu-title">${_('This Repository')}</li>
522 <li>
523 <li>
523 <a href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">${_('Create Pull Request')}</a>
524 <a href="${h.route_path('pullrequest_new',repo_name=c.repo_name)}">${_('Create Pull Request')}</a>
524 </li>
525 </li>
525 % if can_fork:
526 % if can_fork:
526 <li>
527 <li>
527 <a href="${h.route_path('repo_fork_new',repo_name=c.repo_name,_query=default_target_group)}">${_('Fork this repository')}</a>
528 <a href="${h.route_path('repo_fork_new',repo_name=c.repo_name,_query=default_target_group)}">${_('Fork this repository')}</a>
528 </li>
529 </li>
529 % endif
530 % endif
530 % endif
531 % endif
531
532
532 ## scope of within repository groups
533 ## scope of within repository groups
533 % if hasattr(c, 'repo_group') and c.repo_group and (can_create_repos_in_group or can_create_repo_groups_in_group):
534 % if hasattr(c, 'repo_group') and c.repo_group and (can_create_repos_in_group or can_create_repo_groups_in_group):
534 <li class="submenu-title">${_('This Repository Group')}</li>
535 <li class="submenu-title">${_('This Repository Group')}</li>
535
536
536 % if can_create_repos_in_group:
537 % if can_create_repos_in_group:
537 <li>
538 <li>
538 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('New Repository')}</a>
539 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.repo_group.group_id))}">${_('New Repository')}</a>
539 </li>
540 </li>
540 % endif
541 % endif
541
542
542 % if can_create_repo_groups_in_group:
543 % if can_create_repo_groups_in_group:
543 <li>
544 <li>
544 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_(u'New Repository Group')}</a>
545 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.repo_group.group_id))}">${_(u'New Repository Group')}</a>
545 </li>
546 </li>
546 % endif
547 % endif
547 % endif
548 % endif
548
549
549 ## personal group
550 ## personal group
550 % if c.rhodecode_user.personal_repo_group:
551 % if c.rhodecode_user.personal_repo_group:
551 <li class="submenu-title">Personal Group</li>
552 <li class="submenu-title">Personal Group</li>
552
553
553 <li>
554 <li>
554 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}" >${_('New Repository')} </a>
555 <a href="${h.route_path('repo_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}" >${_('New Repository')} </a>
555 </li>
556 </li>
556
557
557 <li>
558 <li>
558 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}">${_('New Repository Group')} </a>
559 <a href="${h.route_path('repo_group_new',_query=dict(parent_group=c.rhodecode_user.personal_repo_group.group_id))}">${_('New Repository Group')} </a>
559 </li>
560 </li>
560 % endif
561 % endif
561
562
562 ## Global actions
563 ## Global actions
563 <li class="submenu-title">RhodeCode</li>
564 <li class="submenu-title">RhodeCode</li>
564 % if can_create_repos:
565 % if can_create_repos:
565 <li>
566 <li>
566 <a href="${h.route_path('repo_new')}" >${_('New Repository')}</a>
567 <a href="${h.route_path('repo_new')}" >${_('New Repository')}</a>
567 </li>
568 </li>
568 % endif
569 % endif
569
570
570 % if can_create_repo_groups:
571 % if can_create_repo_groups:
571 <li>
572 <li>
572 <a href="${h.route_path('repo_group_new')}" >${_(u'New Repository Group')}</a>
573 <a href="${h.route_path('repo_group_new')}" >${_(u'New Repository Group')}</a>
573 </li>
574 </li>
574 % endif
575 % endif
575
576
576 <li>
577 <li>
577 <a href="${h.route_path('gists_new')}">${_(u'New Gist')}</a>
578 <a href="${h.route_path('gists_new')}">${_(u'New Gist')}</a>
578 </li>
579 </li>
579
580
580 </ol>
581 </ol>
581
582
582 </div>
583 </div>
583 </li>
584 </li>
584
585
585 ## notifications
586 ## notifications
586 <li>
587 <li>
587 <a class="${('empty' if c.unread_notifications == 0 else '')}" href="${h.route_path('notifications_show_all')}">
588 <a class="${('empty' if c.unread_notifications == 0 else '')}" href="${h.route_path('notifications_show_all')}">
588 ${c.unread_notifications}
589 ${c.unread_notifications}
589 </a>
590 </a>
590 </li>
591 </li>
591 % endif
592 % endif
592
593
593 ## USER MENU
594 ## USER MENU
594 <li id="quick_login_li" class="${'active' if active else ''}">
595 <li id="quick_login_li" class="${'active' if active else ''}">
595 % if c.rhodecode_user.username == h.DEFAULT_USER:
596 % if c.rhodecode_user.username == h.DEFAULT_USER:
596 <a id="quick_login_link" class="menulink childs" href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">
597 <a id="quick_login_link" class="menulink childs" href="${h.route_path('login', _query={'came_from': h.current_route_path(request)})}">
597 ${gravatar(c.rhodecode_user.email, 20)}
598 ${gravatar(c.rhodecode_user.email, 20)}
598 <span class="user">
599 <span class="user">
599 <span>${_('Sign in')}</span>
600 <span>${_('Sign in')}</span>
600 </span>
601 </span>
601 </a>
602 </a>
602 % else:
603 % else:
603 ## logged in user
604 ## logged in user
604 <a id="quick_login_link" class="menulink childs">
605 <a id="quick_login_link" class="menulink childs">
605 ${gravatar(c.rhodecode_user.email, 20)}
606 ${gravatar(c.rhodecode_user.email, 20)}
606 <span class="user">
607 <span class="user">
607 <span class="menu_link_user">${c.rhodecode_user.username}</span>
608 <span class="menu_link_user">${c.rhodecode_user.username}</span>
608 <div class="show_more"></div>
609 <div class="show_more"></div>
609 </span>
610 </span>
610 </a>
611 </a>
611 ## subnav with menu for logged in user
612 ## subnav with menu for logged in user
612 <div class="user-menu submenu">
613 <div class="user-menu submenu">
613 <div id="quick_login">
614 <div id="quick_login">
614 %if c.rhodecode_user.username != h.DEFAULT_USER:
615 %if c.rhodecode_user.username != h.DEFAULT_USER:
615 <div class="">
616 <div class="">
616 <div class="big_gravatar">${gravatar(c.rhodecode_user.email, 48)}</div>
617 <div class="big_gravatar">${gravatar(c.rhodecode_user.email, 48)}</div>
617 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
618 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
618 <div class="email">${c.rhodecode_user.email}</div>
619 <div class="email">${c.rhodecode_user.email}</div>
619 </div>
620 </div>
620 <div class="">
621 <div class="">
621 <ol class="links">
622 <ol class="links">
622 <li>${h.link_to(_(u'My account'),h.route_path('my_account_profile'))}</li>
623 <li>${h.link_to(_(u'My account'),h.route_path('my_account_profile'))}</li>
623 % if c.rhodecode_user.personal_repo_group:
624 % if c.rhodecode_user.personal_repo_group:
624 <li>${h.link_to(_(u'My personal group'), h.route_path('repo_group_home', repo_group_name=c.rhodecode_user.personal_repo_group.group_name))}</li>
625 <li>${h.link_to(_(u'My personal group'), h.route_path('repo_group_home', repo_group_name=c.rhodecode_user.personal_repo_group.group_name))}</li>
625 % endif
626 % endif
626 <li>${h.link_to(_(u'Pull Requests'), h.route_path('my_account_pullrequests'))}</li>
627 <li>${h.link_to(_(u'Pull Requests'), h.route_path('my_account_pullrequests'))}</li>
627
628
628 % if c.debug_style:
629 % if c.debug_style:
629 <li>
630 <li>
630 <a class="menulink" title="${_('Style')}" href="${h.route_path('debug_style_home')}">
631 <a class="menulink" title="${_('Style')}" href="${h.route_path('debug_style_home')}">
631 <div class="menulabel">${_('[Style]')}</div>
632 <div class="menulabel">${_('[Style]')}</div>
632 </a>
633 </a>
633 </li>
634 </li>
634 % endif
635 % endif
635
636
636 ## bookmark-items
637 ## bookmark-items
637 <li class="bookmark-items">
638 <li class="bookmark-items">
638 ${_('Bookmarks')}
639 ${_('Bookmarks')}
639 <div class="pull-right">
640 <div class="pull-right">
640 <a href="${h.route_path('my_account_bookmarks')}">
641 <a href="${h.route_path('my_account_bookmarks')}">
641
642
642 <i class="icon-cog"></i>
643 <i class="icon-cog"></i>
643 </a>
644 </a>
644 </div>
645 </div>
645 </li>
646 </li>
646 % if not c.bookmark_items:
647 % if not c.bookmark_items:
647 <li>
648 <li>
648 <a href="${h.route_path('my_account_bookmarks')}">${_('No Bookmarks yet.')}</a>
649 <a href="${h.route_path('my_account_bookmarks')}">${_('No Bookmarks yet.')}</a>
649 </li>
650 </li>
650 % endif
651 % endif
651 % for item in c.bookmark_items:
652 % for item in c.bookmark_items:
652 <li>
653 <li>
653 % if item.repository:
654 % if item.repository:
654 <div>
655 <div>
655 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
656 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
656 <code>${item.position}</code>
657 <code>${item.position}</code>
657 % if item.repository.repo_type == 'hg':
658 % if item.repository.repo_type == 'hg':
658 <i class="icon-hg" title="${_('Repository')}" style="font-size: 16px"></i>
659 <i class="icon-hg" title="${_('Repository')}" style="font-size: 16px"></i>
659 % elif item.repository.repo_type == 'git':
660 % elif item.repository.repo_type == 'git':
660 <i class="icon-git" title="${_('Repository')}" style="font-size: 16px"></i>
661 <i class="icon-git" title="${_('Repository')}" style="font-size: 16px"></i>
661 % elif item.repository.repo_type == 'svn':
662 % elif item.repository.repo_type == 'svn':
662 <i class="icon-svn" title="${_('Repository')}" style="font-size: 16px"></i>
663 <i class="icon-svn" title="${_('Repository')}" style="font-size: 16px"></i>
663 % endif
664 % endif
664 ${(item.title or h.shorter(item.repository.repo_name, 30))}
665 ${(item.title or h.shorter(item.repository.repo_name, 30))}
665 </a>
666 </a>
666 </div>
667 </div>
667 % elif item.repository_group:
668 % elif item.repository_group:
668 <div>
669 <div>
669 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
670 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
670 <code>${item.position}</code>
671 <code>${item.position}</code>
671 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
672 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
672 ${(item.title or h.shorter(item.repository_group.group_name, 30))}
673 ${(item.title or h.shorter(item.repository_group.group_name, 30))}
673 </a>
674 </a>
674 </div>
675 </div>
675 % else:
676 % else:
676 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
677 <a class="bookmark-item" href="${h.route_path('my_account_goto_bookmark', bookmark_id=item.position)}">
677 <code>${item.position}</code>
678 <code>${item.position}</code>
678 ${item.title}
679 ${item.title}
679 </a>
680 </a>
680 % endif
681 % endif
681 </li>
682 </li>
682 % endfor
683 % endfor
683
684
684 <li class="logout">
685 <li class="logout">
685 ${h.secure_form(h.route_path('logout'), request=request)}
686 ${h.secure_form(h.route_path('logout'), request=request)}
686 ${h.submit('log_out', _(u'Sign Out'),class_="btn btn-primary")}
687 ${h.submit('log_out', _(u'Sign Out'),class_="btn btn-primary")}
687 ${h.end_form()}
688 ${h.end_form()}
688 </li>
689 </li>
689 </ol>
690 </ol>
690 </div>
691 </div>
691 %endif
692 %endif
692 </div>
693 </div>
693 </div>
694 </div>
694
695
695 % endif
696 % endif
696 </li>
697 </li>
697 </%def>
698 </%def>
698
699
699 <%def name="menu_items(active=None)">
700 <%def name="menu_items(active=None)">
700 <%
701 <%
701 notice_messages, notice_level = c.rhodecode_user.get_notice_messages()
702 notice_messages, notice_level = c.rhodecode_user.get_notice_messages()
702 notice_display = 'none' if len(notice_messages) == 0 else ''
703 notice_display = 'none' if len(notice_messages) == 0 else ''
703 %>
704 %>
704
705
705 <ul id="quick" class="main_nav navigation horizontal-list">
706 <ul id="quick" class="main_nav navigation horizontal-list">
706 ## notice box for important system messages
707 ## notice box for important system messages
707 <li style="display: ${notice_display}">
708 <li style="display: ${notice_display}">
708 <a class="notice-box" href="#openNotice" onclick="$('.notice-messages-container').toggle(); return false">
709 <a class="notice-box" href="#openNotice" onclick="$('.notice-messages-container').toggle(); return false">
709 <div class="menulabel-notice ${notice_level}" >
710 <div class="menulabel-notice ${notice_level}" >
710 ${len(notice_messages)}
711 ${len(notice_messages)}
711 </div>
712 </div>
712 </a>
713 </a>
713 </li>
714 </li>
714 <div class="notice-messages-container" style="display: none">
715 <div class="notice-messages-container" style="display: none">
715 <div class="notice-messages">
716 <div class="notice-messages">
716 <table class="rctable">
717 <table class="rctable">
717 % for notice in notice_messages:
718 % for notice in notice_messages:
718 <tr id="notice-message-${notice['msg_id']}" class="notice-message-${notice['level']}">
719 <tr id="notice-message-${notice['msg_id']}" class="notice-message-${notice['level']}">
719 <td style="vertical-align: text-top; width: 20px">
720 <td style="vertical-align: text-top; width: 20px">
720 <i class="tooltip icon-info notice-color-${notice['level']}" title="${notice['level']}"></i>
721 <i class="tooltip icon-info notice-color-${notice['level']}" title="${notice['level']}"></i>
721 </td>
722 </td>
722 <td>
723 <td>
723 <span><i class="icon-plus-squared cursor-pointer" onclick="$('#notice-${notice['msg_id']}').toggle()"></i> </span>
724 <span><i class="icon-plus-squared cursor-pointer" onclick="$('#notice-${notice['msg_id']}').toggle()"></i> </span>
724 ${notice['subject']}
725 ${notice['subject']}
725
726
726 <div id="notice-${notice['msg_id']}" style="display: none">
727 <div id="notice-${notice['msg_id']}" style="display: none">
727 ${h.render(notice['body'], renderer='markdown')}
728 ${h.render(notice['body'], renderer='markdown')}
728 </div>
729 </div>
729 </td>
730 </td>
730 <td style="vertical-align: text-top; width: 35px;">
731 <td style="vertical-align: text-top; width: 35px;">
731 <a class="tooltip" title="${_('dismiss')}" href="#dismiss" onclick="dismissNotice(${notice['msg_id']});return false">
732 <a class="tooltip" title="${_('dismiss')}" href="#dismiss" onclick="dismissNotice(${notice['msg_id']});return false">
732 <i class="icon-remove icon-filled-red"></i>
733 <i class="icon-remove icon-filled-red"></i>
733 </a>
734 </a>
734 </td>
735 </td>
735 </tr>
736 </tr>
736
737
737 % endfor
738 % endfor
738 </table>
739 </table>
739 </div>
740 </div>
740 </div>
741 </div>
741 ## Main filter
742 ## Main filter
742 <li>
743 <li>
743 <div class="menulabel main_filter_box">
744 <div class="menulabel main_filter_box">
744 <div class="main_filter_input_box">
745 <div class="main_filter_input_box">
745 <ul class="searchItems">
746 <ul class="searchItems">
746
747
747 <li class="searchTag searchTagIcon">
748 <li class="searchTag searchTagIcon">
748 <i class="icon-search"></i>
749 <i class="icon-search"></i>
749 </li>
750 </li>
750
751
751 % if c.template_context['search_context']['repo_id']:
752 % if c.template_context['search_context']['repo_id']:
752 <li class="searchTag searchTagFilter searchTagHidable" >
753 <li class="searchTag searchTagFilter searchTagHidable" >
753 ##<a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">
754 ##<a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">
754 <span class="tag">
755 <span class="tag">
755 This repo
756 This repo
756 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
757 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
757 </span>
758 </span>
758 ##</a>
759 ##</a>
759 </li>
760 </li>
760 % elif c.template_context['search_context']['repo_group_id']:
761 % elif c.template_context['search_context']['repo_group_id']:
761 <li class="searchTag searchTagFilter searchTagHidable">
762 <li class="searchTag searchTagFilter searchTagHidable">
762 ##<a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">
763 ##<a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">
763 <span class="tag">
764 <span class="tag">
764 This group
765 This group
765 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
766 <a href="#removeGoToFilter" onclick="removeGoToFilter(); return false"><i class="icon-cancel-circled"></i></a>
766 </span>
767 </span>
767 ##</a>
768 ##</a>
768 </li>
769 </li>
769 % endif
770 % endif
770
771
771 <li class="searchTagInput">
772 <li class="searchTagInput">
772 <input class="main_filter_input" id="main_filter" size="25" type="text" name="main_filter" placeholder="${_('search / go to...')}" value="" />
773 <input class="main_filter_input" id="main_filter" size="25" type="text" name="main_filter" placeholder="${_('search / go to...')}" value="" />
773 </li>
774 </li>
774 <li class="searchTag searchTagHelp">
775 <li class="searchTag searchTagHelp">
775 <a href="#showFilterHelp" onclick="showMainFilterBox(); return false">?</a>
776 <a href="#showFilterHelp" onclick="showMainFilterBox(); return false">?</a>
776 </li>
777 </li>
777 </ul>
778 </ul>
778 </div>
779 </div>
779 </div>
780 </div>
780
781
781 <div id="main_filter_help" style="display: none">
782 <div id="main_filter_help" style="display: none">
782 - Use '/' key to quickly access this field.
783 - Use '/' key to quickly access this field.
783
784
784 - Enter a name of repository, or repository group for quick search.
785 - Enter a name of repository, or repository group for quick search.
785
786
786 - Prefix query to allow special search:
787 - Prefix query to allow special search:
787
788
788 <strong>user:</strong>admin, to search for usernames, always global
789 <strong>user:</strong>admin, to search for usernames, always global
789
790
790 <strong>user_group:</strong>devops, to search for user groups, always global
791 <strong>user_group:</strong>devops, to search for user groups, always global
791
792
792 <strong>pr:</strong>303, to search for pull request number, title, or description, always global
793 <strong>pr:</strong>303, to search for pull request number, title, or description, always global
793
794
794 <strong>commit:</strong>efced4, to search for commits, scoped to repositories or groups
795 <strong>commit:</strong>efced4, to search for commits, scoped to repositories or groups
795
796
796 <strong>file:</strong>models.py, to search for file paths, scoped to repositories or groups
797 <strong>file:</strong>models.py, to search for file paths, scoped to repositories or groups
797
798
798 % if c.template_context['search_context']['repo_id']:
799 % if c.template_context['search_context']['repo_id']:
799 For advanced full text search visit: <a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">repository search</a>
800 For advanced full text search visit: <a href="${h.route_path('search_repo',repo_name=c.template_context['search_context']['repo_name'])}">repository search</a>
800 % elif c.template_context['search_context']['repo_group_id']:
801 % elif c.template_context['search_context']['repo_group_id']:
801 For advanced full text search visit: <a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">repository group search</a>
802 For advanced full text search visit: <a href="${h.route_path('search_repo_group',repo_group_name=c.template_context['search_context']['repo_group_name'])}">repository group search</a>
802 % else:
803 % else:
803 For advanced full text search visit: <a href="${h.route_path('search')}">global search</a>
804 For advanced full text search visit: <a href="${h.route_path('search')}">global search</a>
804 % endif
805 % endif
805 </div>
806 </div>
806 </li>
807 </li>
807
808
808 ## ROOT MENU
809 ## ROOT MENU
809 <li class="${h.is_active('home', active)}">
810 <li class="${h.is_active('home', active)}">
810 <a class="menulink" title="${_('Home')}" href="${h.route_path('home')}">
811 <a class="menulink" title="${_('Home')}" href="${h.route_path('home')}">
811 <div class="menulabel">${_('Home')}</div>
812 <div class="menulabel">${_('Home')}</div>
812 </a>
813 </a>
813 </li>
814 </li>
814
815
815 %if c.rhodecode_user.username != h.DEFAULT_USER:
816 %if c.rhodecode_user.username != h.DEFAULT_USER:
816 <li class="${h.is_active('journal', active)}">
817 <li class="${h.is_active('journal', active)}">
817 <a class="menulink" title="${_('Show activity journal')}" href="${h.route_path('journal')}">
818 <a class="menulink" title="${_('Show activity journal')}" href="${h.route_path('journal')}">
818 <div class="menulabel">${_('Journal')}</div>
819 <div class="menulabel">${_('Journal')}</div>
819 </a>
820 </a>
820 </li>
821 </li>
821 %else:
822 %else:
822 <li class="${h.is_active('journal', active)}">
823 <li class="${h.is_active('journal', active)}">
823 <a class="menulink" title="${_('Show Public activity journal')}" href="${h.route_path('journal_public')}">
824 <a class="menulink" title="${_('Show Public activity journal')}" href="${h.route_path('journal_public')}">
824 <div class="menulabel">${_('Public journal')}</div>
825 <div class="menulabel">${_('Public journal')}</div>
825 </a>
826 </a>
826 </li>
827 </li>
827 %endif
828 %endif
828
829
829 <li class="${h.is_active('gists', active)}">
830 <li class="${h.is_active('gists', active)}">
830 <a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
831 <a class="menulink childs" title="${_('Show Gists')}" href="${h.route_path('gists_show')}">
831 <div class="menulabel">${_('Gists')}</div>
832 <div class="menulabel">${_('Gists')}</div>
832 </a>
833 </a>
833 </li>
834 </li>
834
835
835 % if c.is_super_admin or c.is_delegated_admin:
836 % if c.is_super_admin or c.is_delegated_admin:
836 <li class="${h.is_active('admin', active)}">
837 <li class="${h.is_active('admin', active)}">
837 <a class="menulink childs" title="${_('Admin settings')}" href="${h.route_path('admin_home')}">
838 <a class="menulink childs" title="${_('Admin settings')}" href="${h.route_path('admin_home')}">
838 <div class="menulabel">${_('Admin')} </div>
839 <div class="menulabel">${_('Admin')} </div>
839 </a>
840 </a>
840 </li>
841 </li>
841 % endif
842 % endif
842
843
843 ## render extra user menu
844 ## render extra user menu
844 ${usermenu(active=(active=='my_account'))}
845 ${usermenu(active=(active=='my_account'))}
845
846
846 </ul>
847 </ul>
847
848
848 <script type="text/javascript">
849 <script type="text/javascript">
849 var visualShowPublicIcon = "${c.visual.show_public_icon}" == "True";
850 var visualShowPublicIcon = "${c.visual.show_public_icon}" == "True";
850
851
851 var formatRepoResult = function(result, container, query, escapeMarkup) {
852 var formatRepoResult = function(result, container, query, escapeMarkup) {
852 return function(data, escapeMarkup) {
853 return function(data, escapeMarkup) {
853 if (!data.repo_id){
854 if (!data.repo_id){
854 return data.text; // optgroup text Repositories
855 return data.text; // optgroup text Repositories
855 }
856 }
856
857
857 var tmpl = '';
858 var tmpl = '';
858 var repoType = data['repo_type'];
859 var repoType = data['repo_type'];
859 var repoName = data['text'];
860 var repoName = data['text'];
860
861
861 if(data && data.type == 'repo'){
862 if(data && data.type == 'repo'){
862 if(repoType === 'hg'){
863 if(repoType === 'hg'){
863 tmpl += '<i class="icon-hg"></i> ';
864 tmpl += '<i class="icon-hg"></i> ';
864 }
865 }
865 else if(repoType === 'git'){
866 else if(repoType === 'git'){
866 tmpl += '<i class="icon-git"></i> ';
867 tmpl += '<i class="icon-git"></i> ';
867 }
868 }
868 else if(repoType === 'svn'){
869 else if(repoType === 'svn'){
869 tmpl += '<i class="icon-svn"></i> ';
870 tmpl += '<i class="icon-svn"></i> ';
870 }
871 }
871 if(data['private']){
872 if(data['private']){
872 tmpl += '<i class="icon-lock" ></i> ';
873 tmpl += '<i class="icon-lock" ></i> ';
873 }
874 }
874 else if(visualShowPublicIcon){
875 else if(visualShowPublicIcon){
875 tmpl += '<i class="icon-unlock-alt"></i> ';
876 tmpl += '<i class="icon-unlock-alt"></i> ';
876 }
877 }
877 }
878 }
878 tmpl += escapeMarkup(repoName);
879 tmpl += escapeMarkup(repoName);
879 return tmpl;
880 return tmpl;
880
881
881 }(result, escapeMarkup);
882 }(result, escapeMarkup);
882 };
883 };
883
884
884 var formatRepoGroupResult = function(result, container, query, escapeMarkup) {
885 var formatRepoGroupResult = function(result, container, query, escapeMarkup) {
885 return function(data, escapeMarkup) {
886 return function(data, escapeMarkup) {
886 if (!data.repo_group_id){
887 if (!data.repo_group_id){
887 return data.text; // optgroup text Repositories
888 return data.text; // optgroup text Repositories
888 }
889 }
889
890
890 var tmpl = '';
891 var tmpl = '';
891 var repoGroupName = data['text'];
892 var repoGroupName = data['text'];
892
893
893 if(data){
894 if(data){
894
895
895 tmpl += '<i class="icon-repo-group"></i> ';
896 tmpl += '<i class="icon-repo-group"></i> ';
896
897
897 }
898 }
898 tmpl += escapeMarkup(repoGroupName);
899 tmpl += escapeMarkup(repoGroupName);
899 return tmpl;
900 return tmpl;
900
901
901 }(result, escapeMarkup);
902 }(result, escapeMarkup);
902 };
903 };
903
904
904 var escapeRegExChars = function (value) {
905 var escapeRegExChars = function (value) {
905 return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
906 return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
906 };
907 };
907
908
908 var getRepoIcon = function(repo_type) {
909 var getRepoIcon = function(repo_type) {
909 if (repo_type === 'hg') {
910 if (repo_type === 'hg') {
910 return '<i class="icon-hg"></i> ';
911 return '<i class="icon-hg"></i> ';
911 }
912 }
912 else if (repo_type === 'git') {
913 else if (repo_type === 'git') {
913 return '<i class="icon-git"></i> ';
914 return '<i class="icon-git"></i> ';
914 }
915 }
915 else if (repo_type === 'svn') {
916 else if (repo_type === 'svn') {
916 return '<i class="icon-svn"></i> ';
917 return '<i class="icon-svn"></i> ';
917 }
918 }
918 return ''
919 return ''
919 };
920 };
920
921
921 var autocompleteMainFilterFormatResult = function (data, value, org_formatter) {
922 var autocompleteMainFilterFormatResult = function (data, value, org_formatter) {
922
923
923 if (value.split(':').length === 2) {
924 if (value.split(':').length === 2) {
924 value = value.split(':')[1]
925 value = value.split(':')[1]
925 }
926 }
926
927
927 var searchType = data['type'];
928 var searchType = data['type'];
928 var searchSubType = data['subtype'];
929 var searchSubType = data['subtype'];
929 var valueDisplay = data['value_display'];
930 var valueDisplay = data['value_display'];
930 var valueIcon = data['value_icon'];
931 var valueIcon = data['value_icon'];
931
932
932 var pattern = '(' + escapeRegExChars(value) + ')';
933 var pattern = '(' + escapeRegExChars(value) + ')';
933
934
934 valueDisplay = Select2.util.escapeMarkup(valueDisplay);
935 valueDisplay = Select2.util.escapeMarkup(valueDisplay);
935
936
936 // highlight match
937 // highlight match
937 if (searchType != 'text') {
938 if (searchType != 'text') {
938 valueDisplay = valueDisplay.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
939 valueDisplay = valueDisplay.replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>');
939 }
940 }
940
941
941 var icon = '';
942 var icon = '';
942
943
943 if (searchType === 'hint') {
944 if (searchType === 'hint') {
944 icon += '<i class="icon-repo-group"></i> ';
945 icon += '<i class="icon-repo-group"></i> ';
945 }
946 }
946 // full text search/hints
947 // full text search/hints
947 else if (searchType === 'search') {
948 else if (searchType === 'search') {
948 if (valueIcon === undefined) {
949 if (valueIcon === undefined) {
949 icon += '<i class="icon-more"></i> ';
950 icon += '<i class="icon-more"></i> ';
950 } else {
951 } else {
951 icon += valueIcon + ' ';
952 icon += valueIcon + ' ';
952 }
953 }
953
954
954 if (searchSubType !== undefined && searchSubType == 'repo') {
955 if (searchSubType !== undefined && searchSubType == 'repo') {
955 valueDisplay += '<div class="pull-right tag">repository</div>';
956 valueDisplay += '<div class="pull-right tag">repository</div>';
956 }
957 }
957 else if (searchSubType !== undefined && searchSubType == 'repo_group') {
958 else if (searchSubType !== undefined && searchSubType == 'repo_group') {
958 valueDisplay += '<div class="pull-right tag">repo group</div>';
959 valueDisplay += '<div class="pull-right tag">repo group</div>';
959 }
960 }
960 }
961 }
961 // repository
962 // repository
962 else if (searchType === 'repo') {
963 else if (searchType === 'repo') {
963
964
964 var repoIcon = getRepoIcon(data['repo_type']);
965 var repoIcon = getRepoIcon(data['repo_type']);
965 icon += repoIcon;
966 icon += repoIcon;
966
967
967 if (data['private']) {
968 if (data['private']) {
968 icon += '<i class="icon-lock" ></i> ';
969 icon += '<i class="icon-lock" ></i> ';
969 }
970 }
970 else if (visualShowPublicIcon) {
971 else if (visualShowPublicIcon) {
971 icon += '<i class="icon-unlock-alt"></i> ';
972 icon += '<i class="icon-unlock-alt"></i> ';
972 }
973 }
973 }
974 }
974 // repository groups
975 // repository groups
975 else if (searchType === 'repo_group') {
976 else if (searchType === 'repo_group') {
976 icon += '<i class="icon-repo-group"></i> ';
977 icon += '<i class="icon-repo-group"></i> ';
977 }
978 }
978 // user group
979 // user group
979 else if (searchType === 'user_group') {
980 else if (searchType === 'user_group') {
980 icon += '<i class="icon-group"></i> ';
981 icon += '<i class="icon-group"></i> ';
981 }
982 }
982 // user
983 // user
983 else if (searchType === 'user') {
984 else if (searchType === 'user') {
984 icon += '<img class="gravatar" src="{0}"/>'.format(data['icon_link']);
985 icon += '<img class="gravatar" src="{0}"/>'.format(data['icon_link']);
985 }
986 }
986 // pull request
987 // pull request
987 else if (searchType === 'pull_request') {
988 else if (searchType === 'pull_request') {
988 icon += '<i class="icon-merge"></i> ';
989 icon += '<i class="icon-merge"></i> ';
989 }
990 }
990 // commit
991 // commit
991 else if (searchType === 'commit') {
992 else if (searchType === 'commit') {
992 var repo_data = data['repo_data'];
993 var repo_data = data['repo_data'];
993 var repoIcon = getRepoIcon(repo_data['repository_type']);
994 var repoIcon = getRepoIcon(repo_data['repository_type']);
994 if (repoIcon) {
995 if (repoIcon) {
995 icon += repoIcon;
996 icon += repoIcon;
996 } else {
997 } else {
997 icon += '<i class="icon-tag"></i>';
998 icon += '<i class="icon-tag"></i>';
998 }
999 }
999 }
1000 }
1000 // file
1001 // file
1001 else if (searchType === 'file') {
1002 else if (searchType === 'file') {
1002 var repo_data = data['repo_data'];
1003 var repo_data = data['repo_data'];
1003 var repoIcon = getRepoIcon(repo_data['repository_type']);
1004 var repoIcon = getRepoIcon(repo_data['repository_type']);
1004 if (repoIcon) {
1005 if (repoIcon) {
1005 icon += repoIcon;
1006 icon += repoIcon;
1006 } else {
1007 } else {
1007 icon += '<i class="icon-tag"></i>';
1008 icon += '<i class="icon-tag"></i>';
1008 }
1009 }
1009 }
1010 }
1010 // generic text
1011 // generic text
1011 else if (searchType === 'text') {
1012 else if (searchType === 'text') {
1012 icon = '';
1013 icon = '';
1013 }
1014 }
1014
1015
1015 var tmpl = '<div class="ac-container-wrap">{0}{1}</div>';
1016 var tmpl = '<div class="ac-container-wrap">{0}{1}</div>';
1016 return tmpl.format(icon, valueDisplay);
1017 return tmpl.format(icon, valueDisplay);
1017 };
1018 };
1018
1019
1019 var handleSelect = function(element, suggestion) {
1020 var handleSelect = function(element, suggestion) {
1020 if (suggestion.type === "hint") {
1021 if (suggestion.type === "hint") {
1021 // we skip action
1022 // we skip action
1022 $('#main_filter').focus();
1023 $('#main_filter').focus();
1023 }
1024 }
1024 else if (suggestion.type === "text") {
1025 else if (suggestion.type === "text") {
1025 // we skip action
1026 // we skip action
1026 $('#main_filter').focus();
1027 $('#main_filter').focus();
1027
1028
1028 } else {
1029 } else {
1029 window.location = suggestion['url'];
1030 window.location = suggestion['url'];
1030 }
1031 }
1031 };
1032 };
1032
1033
1033 var autocompleteMainFilterResult = function (suggestion, originalQuery, queryLowerCase) {
1034 var autocompleteMainFilterResult = function (suggestion, originalQuery, queryLowerCase) {
1034 if (queryLowerCase.split(':').length === 2) {
1035 if (queryLowerCase.split(':').length === 2) {
1035 queryLowerCase = queryLowerCase.split(':')[1]
1036 queryLowerCase = queryLowerCase.split(':')[1]
1036 }
1037 }
1037 if (suggestion.type === "text") {
1038 if (suggestion.type === "text") {
1038 // special case we don't want to "skip" display for
1039 // special case we don't want to "skip" display for
1039 return true
1040 return true
1040 }
1041 }
1041 return suggestion.value_display.toLowerCase().indexOf(queryLowerCase) !== -1;
1042 return suggestion.value_display.toLowerCase().indexOf(queryLowerCase) !== -1;
1042 };
1043 };
1043
1044
1044 var cleanContext = {
1045 var cleanContext = {
1045 repo_view_type: null,
1046 repo_view_type: null,
1046
1047
1047 repo_id: null,
1048 repo_id: null,
1048 repo_name: "",
1049 repo_name: "",
1049
1050
1050 repo_group_id: null,
1051 repo_group_id: null,
1051 repo_group_name: null
1052 repo_group_name: null
1052 };
1053 };
1053 var removeGoToFilter = function () {
1054 var removeGoToFilter = function () {
1054 $('.searchTagHidable').hide();
1055 $('.searchTagHidable').hide();
1055 $('#main_filter').autocomplete(
1056 $('#main_filter').autocomplete(
1056 'setOptions', {params:{search_context: cleanContext}});
1057 'setOptions', {params:{search_context: cleanContext}});
1057 };
1058 };
1058
1059
1059 $('#main_filter').autocomplete({
1060 $('#main_filter').autocomplete({
1060 serviceUrl: pyroutes.url('goto_switcher_data'),
1061 serviceUrl: pyroutes.url('goto_switcher_data'),
1061 params: {
1062 params: {
1062 "search_context": templateContext.search_context
1063 "search_context": templateContext.search_context
1063 },
1064 },
1064 minChars:2,
1065 minChars:2,
1065 maxHeight:400,
1066 maxHeight:400,
1066 deferRequestBy: 300, //miliseconds
1067 deferRequestBy: 300, //miliseconds
1067 tabDisabled: true,
1068 tabDisabled: true,
1068 autoSelectFirst: false,
1069 autoSelectFirst: false,
1069 containerClass: 'autocomplete-qfilter-suggestions',
1070 containerClass: 'autocomplete-qfilter-suggestions',
1070 formatResult: autocompleteMainFilterFormatResult,
1071 formatResult: autocompleteMainFilterFormatResult,
1071 lookupFilter: autocompleteMainFilterResult,
1072 lookupFilter: autocompleteMainFilterResult,
1072 onSelect: function (element, suggestion) {
1073 onSelect: function (element, suggestion) {
1073 handleSelect(element, suggestion);
1074 handleSelect(element, suggestion);
1074 return false;
1075 return false;
1075 },
1076 },
1076 onSearchError: function (element, query, jqXHR, textStatus, errorThrown) {
1077 onSearchError: function (element, query, jqXHR, textStatus, errorThrown) {
1077 if (jqXHR !== 'abort') {
1078 if (jqXHR !== 'abort') {
1078 var message = formatErrorMessage(jqXHR, textStatus, errorThrown);
1079 var message = formatErrorMessage(jqXHR, textStatus, errorThrown);
1079 SwalNoAnimation.fire({
1080 SwalNoAnimation.fire({
1080 icon: 'error',
1081 icon: 'error',
1081 title: _gettext('Error during search operation'),
1082 title: _gettext('Error during search operation'),
1082 html: '<span style="white-space: pre-line">{0}</span>'.format(message),
1083 html: '<span style="white-space: pre-line">{0}</span>'.format(message),
1083 }).then(function(result) {
1084 }).then(function(result) {
1084 window.location.reload();
1085 window.location.reload();
1085 })
1086 })
1086 }
1087 }
1087 },
1088 },
1088 onSearchStart: function (params) {
1089 onSearchStart: function (params) {
1089 $('.searchTag.searchTagIcon').html('<i class="icon-spin animate-spin"></i>')
1090 $('.searchTag.searchTagIcon').html('<i class="icon-spin animate-spin"></i>')
1090 },
1091 },
1091 onSearchComplete: function (query, suggestions) {
1092 onSearchComplete: function (query, suggestions) {
1092 $('.searchTag.searchTagIcon').html('<i class="icon-search"></i>')
1093 $('.searchTag.searchTagIcon').html('<i class="icon-search"></i>')
1093 },
1094 },
1094 });
1095 });
1095
1096
1096 showMainFilterBox = function () {
1097 showMainFilterBox = function () {
1097 $('#main_filter_help').toggle();
1098 $('#main_filter_help').toggle();
1098 };
1099 };
1099
1100
1100 $('#main_filter').on('keydown.autocomplete', function (e) {
1101 $('#main_filter').on('keydown.autocomplete', function (e) {
1101
1102
1102 var BACKSPACE = 8;
1103 var BACKSPACE = 8;
1103 var el = $(e.currentTarget);
1104 var el = $(e.currentTarget);
1104 if(e.which === BACKSPACE){
1105 if(e.which === BACKSPACE){
1105 var inputVal = el.val();
1106 var inputVal = el.val();
1106 if (inputVal === ""){
1107 if (inputVal === ""){
1107 removeGoToFilter()
1108 removeGoToFilter()
1108 }
1109 }
1109 }
1110 }
1110 });
1111 });
1111
1112
1112 var dismissNotice = function(noticeId) {
1113 var dismissNotice = function(noticeId) {
1113
1114
1114 var url = pyroutes.url('user_notice_dismiss',
1115 var url = pyroutes.url('user_notice_dismiss',
1115 {"user_id": templateContext.rhodecode_user.user_id});
1116 {"user_id": templateContext.rhodecode_user.user_id});
1116
1117
1117 var postData = {
1118 var postData = {
1118 'csrf_token': CSRF_TOKEN,
1119 'csrf_token': CSRF_TOKEN,
1119 'notice_id': noticeId,
1120 'notice_id': noticeId,
1120 };
1121 };
1121
1122
1122 var success = function(response) {
1123 var success = function(response) {
1123 $('#notice-message-' + noticeId).remove();
1124 $('#notice-message-' + noticeId).remove();
1124 return false;
1125 return false;
1125 };
1126 };
1126 var failure = function(data, textStatus, xhr) {
1127 var failure = function(data, textStatus, xhr) {
1127 alert("error processing request: " + textStatus);
1128 alert("error processing request: " + textStatus);
1128 return false;
1129 return false;
1129 };
1130 };
1130 ajaxPOST(url, postData, success, failure);
1131 ajaxPOST(url, postData, success, failure);
1131 }
1132 }
1132
1133
1133 var hideLicenseWarning = function () {
1134 var hideLicenseWarning = function () {
1134 var fingerprint = templateContext.session_attrs.license_fingerprint;
1135 var fingerprint = templateContext.session_attrs.license_fingerprint;
1135 storeUserSessionAttr('rc_user_session_attr.hide_license_warning', fingerprint);
1136 storeUserSessionAttr('rc_user_session_attr.hide_license_warning', fingerprint);
1136 $('#notifications').hide();
1137 $('#notifications').hide();
1137 }
1138 }
1138
1139
1139 var hideLicenseError = function () {
1140 var hideLicenseError = function () {
1140 var fingerprint = templateContext.session_attrs.license_fingerprint;
1141 var fingerprint = templateContext.session_attrs.license_fingerprint;
1141 storeUserSessionAttr('rc_user_session_attr.hide_license_error', fingerprint);
1142 storeUserSessionAttr('rc_user_session_attr.hide_license_error', fingerprint);
1142 $('#notifications').hide();
1143 $('#notifications').hide();
1143 }
1144 }
1144
1145
1145 </script>
1146 </script>
1146 <script src="${h.asset('js/rhodecode/base/keyboard-bindings.js', ver=c.rhodecode_version_hash)}"></script>
1147 <script src="${h.asset('js/rhodecode/base/keyboard-bindings.js', ver=c.rhodecode_version_hash)}"></script>
1147 </%def>
1148 </%def>
1148
1149
1149 <div class="modal" id="help_kb" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
1150 <div class="modal" id="help_kb" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
1150 <div class="modal-dialog">
1151 <div class="modal-dialog">
1151 <div class="modal-content">
1152 <div class="modal-content">
1152 <div class="modal-header">
1153 <div class="modal-header">
1153 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
1154 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
1154 <h4 class="modal-title" id="myModalLabel">${_('Keyboard shortcuts')}</h4>
1155 <h4 class="modal-title" id="myModalLabel">${_('Keyboard shortcuts')}</h4>
1155 </div>
1156 </div>
1156 <div class="modal-body">
1157 <div class="modal-body">
1157 <div class="block-left">
1158 <div class="block-left">
1158 <table class="keyboard-mappings">
1159 <table class="keyboard-mappings">
1159 <tbody>
1160 <tbody>
1160 <tr>
1161 <tr>
1161 <th></th>
1162 <th></th>
1162 <th>${_('Site-wide shortcuts')}</th>
1163 <th>${_('Site-wide shortcuts')}</th>
1163 </tr>
1164 </tr>
1164 <%
1165 <%
1165 elems = [
1166 elems = [
1166 ('/', 'Use quick search box'),
1167 ('/', 'Use quick search box'),
1167 ('g h', 'Goto home page'),
1168 ('g h', 'Goto home page'),
1168 ('g g', 'Goto my private gists page'),
1169 ('g g', 'Goto my private gists page'),
1169 ('g G', 'Goto my public gists page'),
1170 ('g G', 'Goto my public gists page'),
1170 ('g 0-9', 'Goto bookmarked items from 0-9'),
1171 ('g 0-9', 'Goto bookmarked items from 0-9'),
1171 ('n r', 'New repository page'),
1172 ('n r', 'New repository page'),
1172 ('n g', 'New gist page'),
1173 ('n g', 'New gist page'),
1173 ]
1174 ]
1174 %>
1175 %>
1175 %for key, desc in elems:
1176 %for key, desc in elems:
1176 <tr>
1177 <tr>
1177 <td class="keys">
1178 <td class="keys">
1178 <span class="key tag">${key}</span>
1179 <span class="key tag">${key}</span>
1179 </td>
1180 </td>
1180 <td>${desc}</td>
1181 <td>${desc}</td>
1181 </tr>
1182 </tr>
1182 %endfor
1183 %endfor
1183 </tbody>
1184 </tbody>
1184 </table>
1185 </table>
1185 </div>
1186 </div>
1186 <div class="block-left">
1187 <div class="block-left">
1187 <table class="keyboard-mappings">
1188 <table class="keyboard-mappings">
1188 <tbody>
1189 <tbody>
1189 <tr>
1190 <tr>
1190 <th></th>
1191 <th></th>
1191 <th>${_('Repositories')}</th>
1192 <th>${_('Repositories')}</th>
1192 </tr>
1193 </tr>
1193 <%
1194 <%
1194 elems = [
1195 elems = [
1195 ('g s', 'Goto summary page'),
1196 ('g s', 'Goto summary page'),
1196 ('g c', 'Goto changelog page'),
1197 ('g c', 'Goto changelog page'),
1197 ('g f', 'Goto files page'),
1198 ('g f', 'Goto files page'),
1198 ('g F', 'Goto files page with file search activated'),
1199 ('g F', 'Goto files page with file search activated'),
1199 ('g p', 'Goto pull requests page'),
1200 ('g p', 'Goto pull requests page'),
1200 ('g o', 'Goto repository settings'),
1201 ('g o', 'Goto repository settings'),
1201 ('g O', 'Goto repository access permissions settings'),
1202 ('g O', 'Goto repository access permissions settings'),
1202 ('t s', 'Toggle sidebar on some pages'),
1203 ('t s', 'Toggle sidebar on some pages'),
1203 ]
1204 ]
1204 %>
1205 %>
1205 %for key, desc in elems:
1206 %for key, desc in elems:
1206 <tr>
1207 <tr>
1207 <td class="keys">
1208 <td class="keys">
1208 <span class="key tag">${key}</span>
1209 <span class="key tag">${key}</span>
1209 </td>
1210 </td>
1210 <td>${desc}</td>
1211 <td>${desc}</td>
1211 </tr>
1212 </tr>
1212 %endfor
1213 %endfor
1213 </tbody>
1214 </tbody>
1214 </table>
1215 </table>
1215 </div>
1216 </div>
1216 </div>
1217 </div>
1217 <div class="modal-footer">
1218 <div class="modal-footer">
1218 </div>
1219 </div>
1219 </div><!-- /.modal-content -->
1220 </div><!-- /.modal-content -->
1220 </div><!-- /.modal-dialog -->
1221 </div><!-- /.modal-dialog -->
1221 </div><!-- /.modal -->
1222 </div><!-- /.modal -->
1222
1223
1223
1224
1224 <script type="text/javascript">
1225 <script type="text/javascript">
1225 (function () {
1226 (function () {
1226 "use sctrict";
1227 "use sctrict";
1227
1228
1228 // details block auto-hide menu
1229 // details block auto-hide menu
1229 $(document).mouseup(function(e) {
1230 $(document).mouseup(function(e) {
1230 var container = $('.details-inline-block');
1231 var container = $('.details-inline-block');
1231 if (!container.is(e.target) && container.has(e.target).length === 0) {
1232 if (!container.is(e.target) && container.has(e.target).length === 0) {
1232 $('.details-inline-block[open]').removeAttr('open')
1233 $('.details-inline-block[open]').removeAttr('open')
1233 }
1234 }
1234 });
1235 });
1235
1236
1236 var $sideBar = $('.right-sidebar');
1237 var $sideBar = $('.right-sidebar');
1237 var expanded = $sideBar.hasClass('right-sidebar-expanded');
1238 var expanded = $sideBar.hasClass('right-sidebar-expanded');
1238 var sidebarState = templateContext.session_attrs.sidebarState;
1239 var sidebarState = templateContext.session_attrs.sidebarState;
1239 var sidebarEnabled = $('aside.right-sidebar').get(0);
1240 var sidebarEnabled = $('aside.right-sidebar').get(0);
1240
1241
1241 if (sidebarState === 'expanded') {
1242 if (sidebarState === 'expanded') {
1242 expanded = true
1243 expanded = true
1243 } else if (sidebarState === 'collapsed') {
1244 } else if (sidebarState === 'collapsed') {
1244 expanded = false
1245 expanded = false
1245 }
1246 }
1246 if (sidebarEnabled) {
1247 if (sidebarEnabled) {
1247 // show sidebar since it's hidden on load
1248 // show sidebar since it's hidden on load
1248 $('.right-sidebar').show();
1249 $('.right-sidebar').show();
1249
1250
1250 // init based on set initial class, or if defined user session attrs
1251 // init based on set initial class, or if defined user session attrs
1251 if (expanded) {
1252 if (expanded) {
1252 window.expandSidebar();
1253 window.expandSidebar();
1253 window.updateStickyHeader();
1254 window.updateStickyHeader();
1254
1255
1255 } else {
1256 } else {
1256 window.collapseSidebar();
1257 window.collapseSidebar();
1257 window.updateStickyHeader();
1258 window.updateStickyHeader();
1258 }
1259 }
1259 }
1260 }
1260 })()
1261 })()
1261
1262
1262 </script>
1263 </script>
@@ -1,492 +1,499 b''
1 ## DATA TABLE RE USABLE ELEMENTS
1 ## DATA TABLE RE USABLE ELEMENTS
2 ## usage:
2 ## usage:
3 ## <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
3 ## <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
4 <%namespace name="base" file="/base/base.mako"/>
4 <%namespace name="base" file="/base/base.mako"/>
5
5
6 <%def name="metatags_help()">
6 <%def name="metatags_help()">
7 <table>
7 <table>
8 <%
8 <%
9 example_tags = [
9 example_tags = [
10 ('state','[stable]'),
10 ('state','[stable]'),
11 ('state','[stale]'),
11 ('state','[stale]'),
12 ('state','[featured]'),
12 ('state','[featured]'),
13 ('state','[dev]'),
13 ('state','[dev]'),
14 ('state','[dead]'),
14 ('state','[dead]'),
15 ('state','[deprecated]'),
15 ('state','[deprecated]'),
16
16
17 ('label','[personal]'),
17 ('label','[personal]'),
18 ('generic','[v2.0.0]'),
18 ('generic','[v2.0.0]'),
19
19
20 ('lang','[lang =&gt; JavaScript]'),
20 ('lang','[lang =&gt; JavaScript]'),
21 ('license','[license =&gt; LicenseName]'),
21 ('license','[license =&gt; LicenseName]'),
22
22
23 ('ref','[requires =&gt; RepoName]'),
23 ('ref','[requires =&gt; RepoName]'),
24 ('ref','[recommends =&gt; GroupName]'),
24 ('ref','[recommends =&gt; GroupName]'),
25 ('ref','[conflicts =&gt; SomeName]'),
25 ('ref','[conflicts =&gt; SomeName]'),
26 ('ref','[base =&gt; SomeName]'),
26 ('ref','[base =&gt; SomeName]'),
27 ('url','[url =&gt; [linkName](https://rhodecode.com)]'),
27 ('url','[url =&gt; [linkName](https://rhodecode.com)]'),
28 ('see','[see =&gt; http://rhodecode.com]'),
28 ('see','[see =&gt; http://rhodecode.com]'),
29 ]
29 ]
30 %>
30 %>
31 % for tag_type, tag in example_tags:
31 % for tag_type, tag in example_tags:
32 <tr>
32 <tr>
33 <td>${tag|n}</td>
33 <td>${tag|n}</td>
34 <td>${h.style_metatag(tag_type, tag)|n}</td>
34 <td>${h.style_metatag(tag_type, tag)|n}</td>
35 </tr>
35 </tr>
36 % endfor
36 % endfor
37 </table>
37 </table>
38 </%def>
38 </%def>
39
39
40 <%def name="render_description(description, stylify_metatags)">
40 <%def name="render_description(description, stylify_metatags)">
41 <%
41 <%
42 tags = []
42 tags = []
43 if stylify_metatags:
43 if stylify_metatags:
44 tags, description = h.extract_metatags(description)
44 tags, description = h.extract_metatags(description)
45 %>
45 %>
46 % for tag_type, tag in tags:
46 % for tag_type, tag in tags:
47 ${h.style_metatag(tag_type, tag)|n,trim}
47 ${h.style_metatag(tag_type, tag)|n,trim}
48 % endfor
48 % endfor
49 <code style="white-space: pre-wrap">${description}</code>
49 <code style="white-space: pre-wrap">${description}</code>
50 </%def>
50 </%def>
51
51
52 ## REPOSITORY RENDERERS
52 ## REPOSITORY RENDERERS
53 <%def name="quick_menu(repo_name)">
53 <%def name="quick_menu(repo_name)">
54 <i class="icon-more"></i>
54 <i class="icon-more"></i>
55 <div class="menu_items_container hidden">
55 <div class="menu_items_container hidden">
56 <ul class="menu_items">
56 <ul class="menu_items">
57 <li>
57 <li>
58 <a title="${_('Summary')}" href="${h.route_path('repo_summary',repo_name=repo_name)}">
58 <a title="${_('Summary')}" href="${h.route_path('repo_summary',repo_name=repo_name)}">
59 <span>${_('Summary')}</span>
59 <span>${_('Summary')}</span>
60 </a>
60 </a>
61 </li>
61 </li>
62 <li>
62 <li>
63 <a title="${_('Commits')}" href="${h.route_path('repo_commits',repo_name=repo_name)}">
63 <a title="${_('Commits')}" href="${h.route_path('repo_commits',repo_name=repo_name)}">
64 <span>${_('Commits')}</span>
64 <span>${_('Commits')}</span>
65 </a>
65 </a>
66 </li>
66 </li>
67 <li>
67 <li>
68 <a title="${_('Files')}" href="${h.route_path('repo_files:default_commit',repo_name=repo_name)}">
68 <a title="${_('Files')}" href="${h.route_path('repo_files:default_commit',repo_name=repo_name)}">
69 <span>${_('Files')}</span>
69 <span>${_('Files')}</span>
70 </a>
70 </a>
71 </li>
71 </li>
72 <li>
72 <li>
73 <a title="${_('Fork')}" href="${h.route_path('repo_fork_new',repo_name=repo_name)}">
73 <a title="${_('Fork')}" href="${h.route_path('repo_fork_new',repo_name=repo_name)}">
74 <span>${_('Fork')}</span>
74 <span>${_('Fork')}</span>
75 </a>
75 </a>
76 </li>
76 </li>
77 </ul>
77 </ul>
78 </div>
78 </div>
79 </%def>
79 </%def>
80
80
81 <%def name="repo_name(name,rtype,rstate,private,archived,fork_of,short_name=False,admin=False)">
81 <%def name="repo_name(name,rtype,rstate,private,archived,fork_of,short_name=False,admin=False)">
82 <%
82 <%
83 def get_name(name,short_name=short_name):
83 def get_name(name,short_name=short_name):
84 if short_name:
84 if short_name:
85 return name.split('/')[-1]
85 return name.split('/')[-1]
86 else:
86 else:
87 return name
87 return name
88 %>
88 %>
89 <div class="${'repo_state_pending' if rstate == 'repo_state_pending' else ''} truncate">
89 <div class="${'repo_state_pending' if rstate == 'repo_state_pending' else ''} truncate">
90 ##NAME
90 ##NAME
91 <a href="${h.route_path('edit_repo',repo_name=name) if admin else h.route_path('repo_summary',repo_name=name)}">
91 <a href="${h.route_path('edit_repo',repo_name=name) if admin else h.route_path('repo_summary',repo_name=name)}">
92
92
93 ##TYPE OF REPO
93 ##TYPE OF REPO
94 %if h.is_hg(rtype):
94 %if h.is_hg(rtype):
95 <span title="${_('Mercurial repository')}"><i class="icon-hg" style="font-size: 14px;"></i></span>
95 <span title="${_('Mercurial repository')}"><i class="icon-hg" style="font-size: 14px;"></i></span>
96 %elif h.is_git(rtype):
96 %elif h.is_git(rtype):
97 <span title="${_('Git repository')}"><i class="icon-git" style="font-size: 14px"></i></span>
97 <span title="${_('Git repository')}"><i class="icon-git" style="font-size: 14px"></i></span>
98 %elif h.is_svn(rtype):
98 %elif h.is_svn(rtype):
99 <span title="${_('Subversion repository')}"><i class="icon-svn" style="font-size: 14px"></i></span>
99 <span title="${_('Subversion repository')}"><i class="icon-svn" style="font-size: 14px"></i></span>
100 %endif
100 %endif
101
101
102 ##PRIVATE/PUBLIC
102 ##PRIVATE/PUBLIC
103 %if private is True and c.visual.show_private_icon:
103 %if private is True and c.visual.show_private_icon:
104 <i class="icon-lock" title="${_('Private repository')}"></i>
104 <i class="icon-lock" title="${_('Private repository')}"></i>
105 %elif private is False and c.visual.show_public_icon:
105 %elif private is False and c.visual.show_public_icon:
106 <i class="icon-unlock-alt" title="${_('Public repository')}"></i>
106 <i class="icon-unlock-alt" title="${_('Public repository')}"></i>
107 %else:
107 %else:
108 <span></span>
108 <span></span>
109 %endif
109 %endif
110 ${get_name(name)}
110 ${get_name(name)}
111 </a>
111 </a>
112 %if fork_of:
112 %if fork_of:
113 <a href="${h.route_path('repo_summary',repo_name=fork_of.repo_name)}"><i class="icon-code-fork"></i></a>
113 <a href="${h.route_path('repo_summary',repo_name=fork_of.repo_name)}"><i class="icon-code-fork"></i></a>
114 %endif
114 %endif
115 %if rstate == 'repo_state_pending':
115 %if rstate == 'repo_state_pending':
116 <span class="creation_in_progress tooltip" title="${_('This repository is being created in a background task')}">
116 <span class="creation_in_progress tooltip" title="${_('This repository is being created in a background task')}">
117 (${_('creating...')})
117 (${_('creating...')})
118 </span>
118 </span>
119 %endif
119 %endif
120
120
121 </div>
121 </div>
122 </%def>
122 </%def>
123
123
124 <%def name="repo_desc(description, stylify_metatags)">
124 <%def name="repo_desc(description, stylify_metatags)">
125 <%
125 <%
126 tags, description = h.extract_metatags(description)
126 tags, description = h.extract_metatags(description)
127 %>
127 %>
128
128
129 <div class="truncate-wrap">
129 <div class="truncate-wrap">
130 % if stylify_metatags:
130 % if stylify_metatags:
131 % for tag_type, tag in tags:
131 % for tag_type, tag in tags:
132 ${h.style_metatag(tag_type, tag)|n}
132 ${h.style_metatag(tag_type, tag)|n}
133 % endfor
133 % endfor
134 % endif
134 % endif
135 ${description}
135 ${description}
136 </div>
136 </div>
137
137
138 </%def>
138 </%def>
139
139
140 <%def name="last_change(last_change)">
140 <%def name="last_change(last_change)">
141 ${h.age_component(last_change, time_is_local=True)}
141 ${h.age_component(last_change, time_is_local=True)}
142 </%def>
142 </%def>
143
143
144 <%def name="revision(repo_name, rev, commit_id, author, last_msg, commit_date)">
144 <%def name="revision(repo_name, rev, commit_id, author, last_msg, commit_date)">
145 <div>
145 <div>
146 %if rev >= 0:
146 %if rev >= 0:
147 <code><a class="tooltip-hovercard" data-hovercard-alt=${h.tooltip(last_msg)} data-hovercard-url="${h.route_path('hovercard_repo_commit', repo_name=repo_name, commit_id=commit_id)}" href="${h.route_path('repo_commit',repo_name=repo_name,commit_id=commit_id)}">${'r{}:{}'.format(rev,h.short_id(commit_id))}</a></code>
147 <code><a class="tooltip-hovercard" data-hovercard-alt=${h.tooltip(last_msg)} data-hovercard-url="${h.route_path('hovercard_repo_commit', repo_name=repo_name, commit_id=commit_id)}" href="${h.route_path('repo_commit',repo_name=repo_name,commit_id=commit_id)}">${'r{}:{}'.format(rev,h.short_id(commit_id))}</a></code>
148 %else:
148 %else:
149 ${_('No commits yet')}
149 ${_('No commits yet')}
150 %endif
150 %endif
151 </div>
151 </div>
152 </%def>
152 </%def>
153
153
154 <%def name="rss(name)">
154 <%def name="rss(name)">
155 %if c.rhodecode_user.username != h.DEFAULT_USER:
155 %if c.rhodecode_user.username != h.DEFAULT_USER:
156 <a title="${h.tooltip(_('Subscribe to %s rss feed')% name)}" href="${h.route_path('rss_feed_home', repo_name=name, _query=dict(auth_token=c.rhodecode_user.feed_token))}"><i class="icon-rss-sign"></i></a>
156 <a title="${h.tooltip(_('Subscribe to %s rss feed')% name)}" href="${h.route_path('rss_feed_home', repo_name=name, _query=dict(auth_token=c.rhodecode_user.feed_token))}"><i class="icon-rss-sign"></i></a>
157 %else:
157 %else:
158 <a title="${h.tooltip(_('Subscribe to %s rss feed')% name)}" href="${h.route_path('rss_feed_home', repo_name=name)}"><i class="icon-rss-sign"></i></a>
158 <a title="${h.tooltip(_('Subscribe to %s rss feed')% name)}" href="${h.route_path('rss_feed_home', repo_name=name)}"><i class="icon-rss-sign"></i></a>
159 %endif
159 %endif
160 </%def>
160 </%def>
161
161
162 <%def name="atom(name)">
162 <%def name="atom(name)">
163 %if c.rhodecode_user.username != h.DEFAULT_USER:
163 %if c.rhodecode_user.username != h.DEFAULT_USER:
164 <a title="${h.tooltip(_('Subscribe to %s atom feed')% name)}" href="${h.route_path('atom_feed_home', repo_name=name, _query=dict(auth_token=c.rhodecode_user.feed_token))}"><i class="icon-rss-sign"></i></a>
164 <a title="${h.tooltip(_('Subscribe to %s atom feed')% name)}" href="${h.route_path('atom_feed_home', repo_name=name, _query=dict(auth_token=c.rhodecode_user.feed_token))}"><i class="icon-rss-sign"></i></a>
165 %else:
165 %else:
166 <a title="${h.tooltip(_('Subscribe to %s atom feed')% name)}" href="${h.route_path('atom_feed_home', repo_name=name)}"><i class="icon-rss-sign"></i></a>
166 <a title="${h.tooltip(_('Subscribe to %s atom feed')% name)}" href="${h.route_path('atom_feed_home', repo_name=name)}"><i class="icon-rss-sign"></i></a>
167 %endif
167 %endif
168 </%def>
168 </%def>
169
169
170 <%def name="repo_actions(repo_name, super_user=True)">
170 <%def name="repo_actions(repo_name, super_user=True)">
171 <div>
171 <div>
172 <div class="grid_edit">
172 <div class="grid_edit">
173 <a href="${h.route_path('edit_repo',repo_name=repo_name)}" title="${_('Edit')}">
173 <a href="${h.route_path('edit_repo',repo_name=repo_name)}" title="${_('Edit')}">
174 Edit
174 Edit
175 </a>
175 </a>
176 </div>
176 </div>
177 <div class="grid_delete">
177 <div class="grid_delete">
178 ${h.secure_form(h.route_path('edit_repo_advanced_delete', repo_name=repo_name), request=request)}
178 ${h.secure_form(h.route_path('edit_repo_advanced_delete', repo_name=repo_name), request=request)}
179 <input class="btn btn-link btn-danger" id="remove_${repo_name}" name="remove_${repo_name}"
179 <input class="btn btn-link btn-danger" id="remove_${repo_name}" name="remove_${repo_name}"
180 onclick="submitConfirm(event, this, _gettext('Confirm to delete this repository'), _gettext('Delete'), '${repo_name}')"
180 onclick="submitConfirm(event, this, _gettext('Confirm to delete this repository'), _gettext('Delete'), '${repo_name}')"
181 type="submit" value="Delete"
181 type="submit" value="Delete"
182 >
182 >
183 ${h.end_form()}
183 ${h.end_form()}
184 </div>
184 </div>
185 </div>
185 </div>
186 </%def>
186 </%def>
187
187
188 <%def name="repo_state(repo_state)">
188 <%def name="repo_state(repo_state)">
189 <div>
189 <div>
190 %if repo_state == 'repo_state_pending':
190 %if repo_state == 'repo_state_pending':
191 <div class="tag tag4">${_('Creating')}</div>
191 <div class="tag tag4">${_('Creating')}</div>
192 %elif repo_state == 'repo_state_created':
192 %elif repo_state == 'repo_state_created':
193 <div class="tag tag1">${_('Created')}</div>
193 <div class="tag tag1">${_('Created')}</div>
194 %else:
194 %else:
195 <div class="tag alert2" title="${h.tooltip(repo_state)}">invalid</div>
195 <div class="tag alert2" title="${h.tooltip(repo_state)}">invalid</div>
196 %endif
196 %endif
197 </div>
197 </div>
198 </%def>
198 </%def>
199
199
200
200
201 ## REPO GROUP RENDERERS
201 ## REPO GROUP RENDERERS
202 <%def name="quick_repo_group_menu(repo_group_name)">
202 <%def name="quick_repo_group_menu(repo_group_name)">
203 <i class="icon-more"></i>
203 <i class="icon-more"></i>
204 <div class="menu_items_container hidden">
204 <div class="menu_items_container hidden">
205 <ul class="menu_items">
205 <ul class="menu_items">
206 <li>
206 <li>
207 <a href="${h.route_path('repo_group_home', repo_group_name=repo_group_name)}">${_('Summary')}</a>
207 <a href="${h.route_path('repo_group_home', repo_group_name=repo_group_name)}">${_('Summary')}</a>
208 </li>
208 </li>
209
209
210 </ul>
210 </ul>
211 </div>
211 </div>
212 </%def>
212 </%def>
213
213
214 <%def name="repo_group_name(repo_group_name, children_groups=None)">
214 <%def name="repo_group_name(repo_group_name, children_groups=None)">
215 <div>
215 <div>
216 <a href="${h.route_path('repo_group_home', repo_group_name=repo_group_name)}">
216 <a href="${h.route_path('repo_group_home', repo_group_name=repo_group_name)}">
217 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
217 <i class="icon-repo-group" title="${_('Repository group')}" style="font-size: 14px"></i>
218 %if children_groups:
218 %if children_groups:
219 ${h.literal(' &raquo; '.join(children_groups))}
219 ${h.literal(' &raquo; '.join(children_groups))}
220 %else:
220 %else:
221 ${repo_group_name}
221 ${repo_group_name}
222 %endif
222 %endif
223 </a>
223 </a>
224 </div>
224 </div>
225 </%def>
225 </%def>
226
226
227 <%def name="repo_group_desc(description, personal, stylify_metatags)">
227 <%def name="repo_group_desc(description, personal, stylify_metatags)">
228
228
229 <%
229 <%
230 if stylify_metatags:
230 if stylify_metatags:
231 tags, description = h.extract_metatags(description)
231 tags, description = h.extract_metatags(description)
232 %>
232 %>
233
233
234 <div class="truncate-wrap">
234 <div class="truncate-wrap">
235 % if personal:
235 % if personal:
236 <div class="metatag" tag="personal">${_('personal')}</div>
236 <div class="metatag" tag="personal">${_('personal')}</div>
237 % endif
237 % endif
238
238
239 % if stylify_metatags:
239 % if stylify_metatags:
240 % for tag_type, tag in tags:
240 % for tag_type, tag in tags:
241 ${h.style_metatag(tag_type, tag)|n}
241 ${h.style_metatag(tag_type, tag)|n}
242 % endfor
242 % endfor
243 % endif
243 % endif
244 ${description}
244 ${description}
245 </div>
245 </div>
246
246
247 </%def>
247 </%def>
248
248
249 <%def name="repo_group_actions(repo_group_id, repo_group_name, gr_count)">
249 <%def name="repo_group_actions(repo_group_id, repo_group_name, gr_count)">
250 <div class="grid_edit">
250 <div class="grid_edit">
251 <a href="${h.route_path('edit_repo_group',repo_group_name=repo_group_name)}" title="${_('Edit')}">Edit</a>
251 <a href="${h.route_path('edit_repo_group',repo_group_name=repo_group_name)}" title="${_('Edit')}">Edit</a>
252 </div>
252 </div>
253 <div class="grid_delete">
253 <div class="grid_delete">
254 ${h.secure_form(h.route_path('edit_repo_group_advanced_delete', repo_group_name=repo_group_name), request=request)}
254 ${h.secure_form(h.route_path('edit_repo_group_advanced_delete', repo_group_name=repo_group_name), request=request)}
255 <input class="btn btn-link btn-danger" id="remove_${repo_group_name}" name="remove_${repo_group_name}"
255 <input class="btn btn-link btn-danger" id="remove_${repo_group_name}" name="remove_${repo_group_name}"
256 onclick="submitConfirm(event, this, _gettext('Confirm to delete this repository group'), _gettext('Delete'), '${_ungettext('`{}` with {} repository','`{}` with {} repositories',gr_count).format(repo_group_name, gr_count)}')"
256 onclick="submitConfirm(event, this, _gettext('Confirm to delete this repository group'), _gettext('Delete'), '${_ungettext('`{}` with {} repository','`{}` with {} repositories',gr_count).format(repo_group_name, gr_count)}')"
257 type="submit" value="Delete"
257 type="submit" value="Delete"
258 >
258 >
259 ${h.end_form()}
259 ${h.end_form()}
260 </div>
260 </div>
261 </%def>
261 </%def>
262
262
263
263
264 <%def name="user_actions(user_id, username)">
264 <%def name="user_actions(user_id, username)">
265 <div class="grid_edit">
265 <div class="grid_edit">
266 <a href="${h.route_path('user_edit',user_id=user_id)}" title="${_('Edit')}">
266 <a href="${h.route_path('user_edit',user_id=user_id)}" title="${_('Edit')}">
267 ${_('Edit')}
267 ${_('Edit')}
268 </a>
268 </a>
269 </div>
269 </div>
270 <div class="grid_delete">
270 <div class="grid_delete">
271 ${h.secure_form(h.route_path('user_delete', user_id=user_id), request=request)}
271 ${h.secure_form(h.route_path('user_delete', user_id=user_id), request=request)}
272 <input class="btn btn-link btn-danger" id="remove_user_${user_id}" name="remove_user_${user_id}"
272 <input class="btn btn-link btn-danger" id="remove_user_${user_id}" name="remove_user_${user_id}"
273 onclick="submitConfirm(event, this, _gettext('Confirm to delete this user'), _gettext('Delete'), '${username}')"
273 onclick="submitConfirm(event, this, _gettext('Confirm to delete this user'), _gettext('Delete'), '${username}')"
274 type="submit" value="Delete"
274 type="submit" value="Delete"
275 >
275 >
276 ${h.end_form()}
276 ${h.end_form()}
277 </div>
277 </div>
278 </%def>
278 </%def>
279
279
280 <%def name="user_group_actions(user_group_id, user_group_name)">
280 <%def name="user_group_actions(user_group_id, user_group_name)">
281 <div class="grid_edit">
281 <div class="grid_edit">
282 <a href="${h.route_path('edit_user_group', user_group_id=user_group_id)}" title="${_('Edit')}">Edit</a>
282 <a href="${h.route_path('edit_user_group', user_group_id=user_group_id)}" title="${_('Edit')}">Edit</a>
283 </div>
283 </div>
284 <div class="grid_delete">
284 <div class="grid_delete">
285 ${h.secure_form(h.route_path('user_groups_delete', user_group_id=user_group_id), request=request)}
285 ${h.secure_form(h.route_path('user_groups_delete', user_group_id=user_group_id), request=request)}
286 <input class="btn btn-link btn-danger" id="remove_group_${user_group_id}" name="remove_group_${user_group_id}"
286 <input class="btn btn-link btn-danger" id="remove_group_${user_group_id}" name="remove_group_${user_group_id}"
287 onclick="submitConfirm(event, this, _gettext('Confirm to delete this user group'), _gettext('Delete'), '${user_group_name}')"
287 onclick="submitConfirm(event, this, _gettext('Confirm to delete this user group'), _gettext('Delete'), '${user_group_name}')"
288 type="submit" value="Delete"
288 type="submit" value="Delete"
289 >
289 >
290 ${h.end_form()}
290 ${h.end_form()}
291 </div>
291 </div>
292 </%def>
292 </%def>
293
293
294
294
295 <%def name="user_name(user_id, username)">
295 <%def name="user_name(user_id, username)">
296 ${h.link_to(h.person(username, 'username_or_name_or_email'), h.route_path('user_edit', user_id=user_id))}
296 ${h.link_to(h.person(username, 'username_or_name_or_email'), h.route_path('user_edit', user_id=user_id))}
297 </%def>
297 </%def>
298
298
299 <%def name="user_profile(username)">
299 <%def name="user_profile(username)">
300 ${base.gravatar_with_user(username, 16, tooltip=True)}
300 ${base.gravatar_with_user(username, 16, tooltip=True)}
301 </%def>
301 </%def>
302
302
303 <%def name="user_group_name(user_group_name)">
303 <%def name="user_group_name(user_group_name)">
304 <div>
304 <div>
305 <i class="icon-user-group" title="${_('User group')}"></i>
305 <i class="icon-user-group" title="${_('User group')}"></i>
306 ${h.link_to_group(user_group_name)}
306 ${h.link_to_group(user_group_name)}
307 </div>
307 </div>
308 </%def>
308 </%def>
309
309
310
310
311 ## GISTS
311 ## GISTS
312
312
313 <%def name="gist_gravatar(full_contact)">
313 <%def name="gist_gravatar(full_contact)">
314 <div class="gist_gravatar">
314 <div class="gist_gravatar">
315 ${base.gravatar(full_contact, 30)}
315 ${base.gravatar(full_contact, 30)}
316 </div>
316 </div>
317 </%def>
317 </%def>
318
318
319 <%def name="gist_access_id(gist_access_id, full_contact)">
319 <%def name="gist_access_id(gist_access_id, full_contact)">
320 <div>
320 <div>
321 <code>
321 <code>
322 <a href="${h.route_path('gist_show', gist_id=gist_access_id)}">${gist_access_id}</a>
322 <a href="${h.route_path('gist_show', gist_id=gist_access_id)}">${gist_access_id}</a>
323 </code>
323 </code>
324 </div>
324 </div>
325 </%def>
325 </%def>
326
326
327 <%def name="gist_author(full_contact, created_on, expires)">
327 <%def name="gist_author(full_contact, created_on, expires)">
328 ${base.gravatar_with_user(full_contact, 16, tooltip=True)}
328 ${base.gravatar_with_user(full_contact, 16, tooltip=True)}
329 </%def>
329 </%def>
330
330
331
331
332 <%def name="gist_created(created_on)">
332 <%def name="gist_created(created_on)">
333 <div class="created">
333 <div class="created">
334 ${h.age_component(created_on, time_is_local=True)}
334 ${h.age_component(created_on, time_is_local=True)}
335 </div>
335 </div>
336 </%def>
336 </%def>
337
337
338 <%def name="gist_expires(expires)">
338 <%def name="gist_expires(expires)">
339 <div class="created">
339 <div class="created">
340 %if expires == -1:
340 %if expires == -1:
341 ${_('never')}
341 ${_('never')}
342 %else:
342 %else:
343 ${h.age_component(h.time_to_utcdatetime(expires))}
343 ${h.age_component(h.time_to_utcdatetime(expires))}
344 %endif
344 %endif
345 </div>
345 </div>
346 </%def>
346 </%def>
347
347
348 <%def name="gist_type(gist_type)">
348 <%def name="gist_type(gist_type)">
349 %if gist_type == 'public':
349 %if gist_type == 'public':
350 <span class="tag tag-gist-public disabled">${_('Public Gist')}</span>
350 <span class="tag tag-gist-public disabled">${_('Public Gist')}</span>
351 %else:
351 %else:
352 <span class="tag tag-gist-private disabled">${_('Private Gist')}</span>
352 <span class="tag tag-gist-private disabled">${_('Private Gist')}</span>
353 %endif
353 %endif
354 </%def>
354 </%def>
355
355
356 <%def name="gist_description(gist_description)">
356 <%def name="gist_description(gist_description)">
357 ${gist_description}
357 ${gist_description}
358 </%def>
358 </%def>
359
359
360
360
361 ## PULL REQUESTS GRID RENDERERS
361 ## PULL REQUESTS GRID RENDERERS
362
362
363 <%def name="pullrequest_target_repo(repo_name)">
363 <%def name="pullrequest_target_repo(repo_name)">
364 <div class="truncate">
364 <div class="truncate">
365 ${h.link_to(repo_name,h.route_path('repo_summary',repo_name=repo_name))}
365 ${h.link_to(repo_name,h.route_path('repo_summary',repo_name=repo_name))}
366 </div>
366 </div>
367 </%def>
367 </%def>
368
368
369 <%def name="pullrequest_status(status)">
369 <%def name="pullrequest_status(status)">
370 <i class="icon-circle review-status-${status}"></i>
370 <i class="icon-circle review-status-${status}"></i>
371 </%def>
371 </%def>
372
372
373 <%def name="pullrequest_title(title, description)">
373 <%def name="pullrequest_title(title, description)">
374 ${title}
374 ${title}
375 </%def>
375 </%def>
376
376
377 <%def name="pullrequest_comments(comments_nr)">
377 <%def name="pullrequest_comments(comments_nr)">
378 <i class="icon-comment"></i> ${comments_nr}
378 <i class="icon-comment"></i> ${comments_nr}
379 </%def>
379 </%def>
380
380
381 <%def name="pullrequest_name(pull_request_id, state, is_wip, target_repo_name, short=False)">
381 <%def name="pullrequest_name(pull_request_id, state, is_wip, target_repo_name, short=False)">
382 <code>
382 <code>
383 <a href="${h.route_path('pullrequest_show',repo_name=target_repo_name,pull_request_id=pull_request_id)}">
383 <a href="${h.route_path('pullrequest_show',repo_name=target_repo_name,pull_request_id=pull_request_id)}">
384 % if short:
384 % if short:
385 !${pull_request_id}
385 !${pull_request_id}
386 % else:
386 % else:
387 ${_('Pull request !{}').format(pull_request_id)}
387 ${_('Pull request !{}').format(pull_request_id)}
388 % endif
388 % endif
389 </a>
389 </a>
390 </code>
390 </code>
391 % if state not in ['created']:
391 % if state not in ['created']:
392 <span class="tag tag-merge-state-${state} tooltip" title="Pull request state is changing">${state}</span>
392 <span class="tag tag-merge-state-${state} tooltip" title="Pull request state is changing">${state}</span>
393 % endif
393 % endif
394
394
395 % if is_wip:
395 % if is_wip:
396 <span class="tag tooltip" title="${_('Work in progress')}">wip</span>
396 <span class="tag tooltip" title="${_('Work in progress')}">wip</span>
397 % endif
397 % endif
398 </%def>
398 </%def>
399
399
400 <%def name="pullrequest_updated_on(updated_on, pr_version=None)">
400 <%def name="pullrequest_updated_on(updated_on, pr_version=None)">
401 % if pr_version:
401 % if pr_version:
402 <code>v${pr_version}</code>
402 <code>v${pr_version}</code>
403 % endif
403 % endif
404 ${h.age_component(h.time_to_utcdatetime(updated_on))}
404 ${h.age_component(h.time_to_utcdatetime(updated_on))}
405 </%def>
405 </%def>
406
406
407 <%def name="pullrequest_author(full_contact)">
407 <%def name="pullrequest_author(full_contact)">
408 ${base.gravatar_with_user(full_contact, 16, tooltip=True)}
408 ${base.gravatar_with_user(full_contact, 16, tooltip=True)}
409 </%def>
409 </%def>
410
410
411
411
412 ## ARTIFACT RENDERERS
412 ## ARTIFACT RENDERERS
413 <%def name="repo_artifact_name(repo_name, file_uid, artifact_display_name)">
413 <%def name="repo_artifact_name(repo_name, file_uid, artifact_display_name)">
414 <a href="${h.route_path('repo_artifacts_get', repo_name=repo_name, uid=file_uid)}">
414 <a href="${h.route_path('repo_artifacts_get', repo_name=repo_name, uid=file_uid)}">
415 ${artifact_display_name or '_EMPTY_NAME_'}
415 ${artifact_display_name or '_EMPTY_NAME_'}
416 </a>
416 </a>
417 </%def>
417 </%def>
418
418
419 <%def name="repo_artifact_admin_name(file_uid, artifact_display_name)">
420 <a href="${h.route_path('admin_artifacts_show_info', uid=file_uid)}">
421 ${(artifact_display_name or '_EMPTY_NAME_')}
422 </a>
423 </%def>
424
419 <%def name="repo_artifact_uid(repo_name, file_uid)">
425 <%def name="repo_artifact_uid(repo_name, file_uid)">
420 <code>${h.shorter(file_uid, size=24, prefix=True)}</code>
426 <code>${h.shorter(file_uid, size=24, prefix=True)}</code>
421 </%def>
427 </%def>
422
428
423 <%def name="repo_artifact_sha256(artifact_sha256)">
429 <%def name="repo_artifact_sha256(artifact_sha256)">
424 <div class="code">${h.shorter(artifact_sha256, 12)}</div>
430 <div class="code">${h.shorter(artifact_sha256, 12)}</div>
425 </%def>
431 </%def>
426
432
427 <%def name="repo_artifact_actions(repo_name, file_store_id, file_uid)">
433 <%def name="repo_artifact_actions(repo_name, file_store_id, file_uid)">
428 ## <div class="grid_edit">
434 ## <div class="grid_edit">
429 ## <a href="#Edit" title="${_('Edit')}">${_('Edit')}</a>
435 ## <a href="#Edit" title="${_('Edit')}">${_('Edit')}</a>
430 ## </div>
436 ## </div>
431 <div class="grid_edit">
437 <div class="grid_edit">
432 <a href="${h.route_path('repo_artifacts_info', repo_name=repo_name, uid=file_store_id)}" title="${_('Info')}">${_('Info')}</a>
438 <a href="${h.route_path('repo_artifacts_info', repo_name=repo_name, uid=file_store_id)}" title="${_('Info')}">${_('Info')}</a>
433 </div>
439 </div>
434 % if h.HasRepoPermissionAny('repository.admin')(c.repo_name):
440 % if h.HasRepoPermissionAny('repository.admin')(c.repo_name):
435 <div class="grid_delete">
441 <div class="grid_delete">
436 ${h.secure_form(h.route_path('repo_artifacts_delete', repo_name=repo_name, uid=file_store_id), request=request)}
442 ${h.secure_form(h.route_path('repo_artifacts_delete', repo_name=repo_name, uid=file_store_id), request=request)}
437 <input class="btn btn-link btn-danger" id="remove_artifact_${file_store_id}" name="remove_artifact_${file_store_id}"
443 <input class="btn btn-link btn-danger" id="remove_artifact_${file_store_id}" name="remove_artifact_${file_store_id}"
438 onclick="submitConfirm(event, this, _gettext('Confirm to delete this artifact'), _gettext('Delete'), '${file_uid}')"
444 onclick="submitConfirm(event, this, _gettext('Confirm to delete this artifact'), _gettext('Delete'), '${file_uid}')"
439 type="submit" value="${_('Delete')}"
445 type="submit" value="${_('Delete')}"
440 >
446 >
441 ${h.end_form()}
447 ${h.end_form()}
442 </div>
448 </div>
443 % endif
449 % endif
444 </%def>
450 </%def>
445
451
452
446 <%def name="markup_form(form_id, form_text='', help_text=None)">
453 <%def name="markup_form(form_id, form_text='', help_text=None)">
447
454
448 <div class="markup-form">
455 <div class="markup-form">
449 <div class="markup-form-area">
456 <div class="markup-form-area">
450 <div class="markup-form-area-header">
457 <div class="markup-form-area-header">
451 <ul class="nav-links clearfix">
458 <ul class="nav-links clearfix">
452 <li class="active">
459 <li class="active">
453 <a href="#edit-text" tabindex="-1" id="edit-btn_${form_id}">${_('Write')}</a>
460 <a href="#edit-text" tabindex="-1" id="edit-btn_${form_id}">${_('Write')}</a>
454 </li>
461 </li>
455 <li class="">
462 <li class="">
456 <a href="#preview-text" tabindex="-1" id="preview-btn_${form_id}">${_('Preview')}</a>
463 <a href="#preview-text" tabindex="-1" id="preview-btn_${form_id}">${_('Preview')}</a>
457 </li>
464 </li>
458 </ul>
465 </ul>
459 </div>
466 </div>
460
467
461 <div class="markup-form-area-write" style="display: block;">
468 <div class="markup-form-area-write" style="display: block;">
462 <div id="edit-container_${form_id}" style="margin-top: -1px">
469 <div id="edit-container_${form_id}" style="margin-top: -1px">
463 <textarea id="${form_id}" name="${form_id}" class="comment-block-ta ac-input">${form_text if form_text else ''}</textarea>
470 <textarea id="${form_id}" name="${form_id}" class="comment-block-ta ac-input">${form_text if form_text else ''}</textarea>
464 </div>
471 </div>
465 <div id="preview-container_${form_id}" class="clearfix" style="display: none;">
472 <div id="preview-container_${form_id}" class="clearfix" style="display: none;">
466 <div id="preview-box_${form_id}" class="preview-box"></div>
473 <div id="preview-box_${form_id}" class="preview-box"></div>
467 </div>
474 </div>
468 </div>
475 </div>
469
476
470 <div class="markup-form-area-footer">
477 <div class="markup-form-area-footer">
471 <div class="toolbar">
478 <div class="toolbar">
472 <div class="toolbar-text">
479 <div class="toolbar-text">
473 ${(_('Parsed using %s syntax') % (
480 ${(_('Parsed using %s syntax') % (
474 ('<a href="%s">%s</a>' % (h.route_url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper())),
481 ('<a href="%s">%s</a>' % (h.route_url('%s_help' % c.visual.default_renderer), c.visual.default_renderer.upper())),
475 )
482 )
476 )|n}
483 )|n}
477 </div>
484 </div>
478 </div>
485 </div>
479 </div>
486 </div>
480 </div>
487 </div>
481
488
482 <div class="markup-form-footer">
489 <div class="markup-form-footer">
483 % if help_text:
490 % if help_text:
484 <span class="help-block">${help_text}</span>
491 <span class="help-block">${help_text}</span>
485 % endif
492 % endif
486 </div>
493 </div>
487 </div>
494 </div>
488 <script type="text/javascript">
495 <script type="text/javascript">
489 new MarkupForm('${form_id}');
496 new MarkupForm('${form_id}');
490 </script>
497 </script>
491
498
492 </%def>
499 </%def>
General Comments 0
You need to be logged in to leave comments. Login now