Show More
@@ -28,7 +28,7 b' import click' | |||||
28 |
|
28 | |||
29 | import kallithea.bin.kallithea_cli_base as cli_base |
|
29 | import kallithea.bin.kallithea_cli_base as cli_base | |
30 | from kallithea.lib.utils import REMOVED_REPO_PAT, repo2db_mapper |
|
30 | from kallithea.lib.utils import REMOVED_REPO_PAT, repo2db_mapper | |
31 |
from kallithea.lib.utils2 import ask_ok, safe_str |
|
31 | from kallithea.lib.utils2 import ask_ok, safe_str | |
32 | from kallithea.model.db import Repository, Ui |
|
32 | from kallithea.model.db import Repository, Ui | |
33 | from kallithea.model.meta import Session |
|
33 | from kallithea.model.meta import Session | |
34 | from kallithea.model.scm import ScmModel |
|
34 | from kallithea.model.scm import ScmModel | |
@@ -74,7 +74,7 b' def repo_update_metadata(repositories):' | |||||
74 | if not repositories: |
|
74 | if not repositories: | |
75 | repo_list = Repository.query().all() |
|
75 | repo_list = Repository.query().all() | |
76 | else: |
|
76 | else: | |
77 |
repo_names = [ |
|
77 | repo_names = [n.strip() for n in repositories] | |
78 | repo_list = list(Repository.query() |
|
78 | repo_list = list(Repository.query() | |
79 | .filter(Repository.repo_name.in_(repo_names))) |
|
79 | .filter(Repository.repo_name.in_(repo_names))) | |
80 |
|
80 |
@@ -182,7 +182,10 b' class GistsController(BaseController):' | |||||
182 | log.error(traceback.format_exc()) |
|
182 | log.error(traceback.format_exc()) | |
183 | raise HTTPNotFound() |
|
183 | raise HTTPNotFound() | |
184 | if format == 'raw': |
|
184 | if format == 'raw': | |
185 | content = '\n\n'.join([safe_unicode(f.content) for f in c.files if (f_path is None or safe_unicode(f.path) == f_path)]) |
|
185 | content = '\n\n'.join( | |
|
186 | safe_unicode(f.content) | |||
|
187 | for f in c.files if (f_path is None or f.path == f_path) | |||
|
188 | ) | |||
186 | response.content_type = 'text/plain' |
|
189 | response.content_type = 'text/plain' | |
187 | return content |
|
190 | return content | |
188 | return render('admin/gists/show.html') |
|
191 | return render('admin/gists/show.html') |
@@ -40,7 +40,7 b' from kallithea.config.routing import url' | |||||
40 | from kallithea.lib import helpers as h |
|
40 | from kallithea.lib import helpers as h | |
41 | from kallithea.lib.auth import HasPermissionAny, HasRepoGroupPermissionLevel, HasRepoGroupPermissionLevelDecorator, LoginRequired |
|
41 | from kallithea.lib.auth import HasPermissionAny, HasRepoGroupPermissionLevel, HasRepoGroupPermissionLevelDecorator, LoginRequired | |
42 | from kallithea.lib.base import BaseController, render |
|
42 | from kallithea.lib.base import BaseController, render | |
43 |
from kallithea.lib.utils2 import safe_int |
|
43 | from kallithea.lib.utils2 import safe_int | |
44 | from kallithea.model.db import RepoGroup, Repository |
|
44 | from kallithea.model.db import RepoGroup, Repository | |
45 | from kallithea.model.forms import RepoGroupForm, RepoGroupPermsForm |
|
45 | from kallithea.model.forms import RepoGroupForm, RepoGroupPermsForm | |
46 | from kallithea.model.meta import Session |
|
46 | from kallithea.model.meta import Session | |
@@ -116,7 +116,7 b' class RepoGroupsController(BaseControlle' | |||||
116 | ) |
|
116 | ) | |
117 |
|
117 | |||
118 | for repo_gr in group_iter: |
|
118 | for repo_gr in group_iter: | |
119 |
children_groups = [ |
|
119 | children_groups = [g.name for g in repo_gr.parents] + [repo_gr.name] | |
120 | repo_count = repo_gr.repositories.count() |
|
120 | repo_count = repo_gr.repositories.count() | |
121 | repo_groups_data.append({ |
|
121 | repo_groups_data.append({ | |
122 | "raw_name": repo_gr.group_name, |
|
122 | "raw_name": repo_gr.group_name, |
@@ -257,7 +257,7 b' def create_cs_pr_comment(repo_name, revi' | |||||
257 | Session().commit() |
|
257 | Session().commit() | |
258 |
|
258 | |||
259 | data = { |
|
259 | data = { | |
260 |
'target_id': h.safeid |
|
260 | 'target_id': h.safeid(request.POST.get('f_path')), | |
261 | } |
|
261 | } | |
262 | if comment is not None: |
|
262 | if comment is not None: | |
263 | c.comment = comment |
|
263 | c.comment = comment |
@@ -96,7 +96,7 b' class FeedController(BaseRepoController)' | |||||
96 | desc_msg.append('\n\n') |
|
96 | desc_msg.append('\n\n') | |
97 | desc_msg.append(safe_unicode(raw_diff)) |
|
97 | desc_msg.append(safe_unicode(raw_diff)) | |
98 | desc_msg.append('</pre>') |
|
98 | desc_msg.append('</pre>') | |
99 | return [safe_unicode(chunk) for chunk in desc_msg] |
|
99 | return desc_msg | |
100 |
|
100 | |||
101 | def _feed(self, repo_name, feeder): |
|
101 | def _feed(self, repo_name, feeder): | |
102 | """Produce a simple feed""" |
|
102 | """Produce a simple feed""" |
@@ -42,7 +42,7 b' from kallithea import __platform__, is_u' | |||||
42 | from kallithea.config.routing import url |
|
42 | from kallithea.config.routing import url | |
43 | from kallithea.lib.caching_query import FromCache |
|
43 | from kallithea.lib.caching_query import FromCache | |
44 | from kallithea.lib.utils import conditional_cache, get_repo_group_slug, get_repo_slug, get_user_group_slug |
|
44 | from kallithea.lib.utils import conditional_cache, get_repo_group_slug, get_repo_slug, get_user_group_slug | |
45 |
from kallithea.lib.utils2 import ascii_bytes, ascii_str, safe_bytes |
|
45 | from kallithea.lib.utils2 import ascii_bytes, ascii_str, safe_bytes | |
46 | from kallithea.lib.vcs.utils.lazy import LazyProperty |
|
46 | from kallithea.lib.vcs.utils.lazy import LazyProperty | |
47 | from kallithea.model.db import ( |
|
47 | from kallithea.model.db import ( | |
48 | Permission, RepoGroup, Repository, User, UserApiKeys, UserGroup, UserGroupMember, UserGroupRepoGroupToPerm, UserGroupRepoToPerm, UserGroupToPerm, UserGroupUserGroupToPerm, UserIpMap, UserToPerm) |
|
48 | Permission, RepoGroup, Repository, User, UserApiKeys, UserGroup, UserGroupMember, UserGroupRepoGroupToPerm, UserGroupRepoToPerm, UserGroupToPerm, UserGroupUserGroupToPerm, UserIpMap, UserToPerm) | |
@@ -817,10 +817,6 b' class HasPermissionAnyMiddleware(object)' | |||||
817 | self.required_perms = set(perms) |
|
817 | self.required_perms = set(perms) | |
818 |
|
818 | |||
819 | def __call__(self, authuser, repo_name, purpose=None): |
|
819 | def __call__(self, authuser, repo_name, purpose=None): | |
820 | # repo_name MUST be unicode, since we handle keys in ok |
|
|||
821 | # dict by unicode |
|
|||
822 | repo_name = safe_unicode(repo_name) |
|
|||
823 |
|
||||
824 | try: |
|
820 | try: | |
825 | ok = authuser.permissions['repositories'][repo_name] in self.required_perms |
|
821 | ok = authuser.permissions['repositories'][repo_name] in self.required_perms | |
826 | except KeyError: |
|
822 | except KeyError: |
@@ -29,7 +29,7 b' import logging' | |||||
29 |
|
29 | |||
30 | from kallithea.lib import auth_modules |
|
30 | from kallithea.lib import auth_modules | |
31 | from kallithea.lib.compat import hybrid_property |
|
31 | from kallithea.lib.compat import hybrid_property | |
32 |
from kallithea.lib.utils2 import safe_str, |
|
32 | from kallithea.lib.utils2 import safe_str, str2bool | |
33 | from kallithea.model.db import Setting |
|
33 | from kallithea.model.db import Setting | |
34 |
|
34 | |||
35 |
|
35 | |||
@@ -199,8 +199,8 b' class KallitheaAuthPlugin(auth_modules.K' | |||||
199 |
|
199 | |||
200 | user_data = { |
|
200 | user_data = { | |
201 | 'username': username, |
|
201 | 'username': username, | |
202 |
'firstname': |
|
202 | 'firstname': firstname or username, | |
203 |
'lastname': |
|
203 | 'lastname': lastname or '', | |
204 | 'groups': [], |
|
204 | 'groups': [], | |
205 | 'email': email or '', |
|
205 | 'email': email or '', | |
206 | 'admin': admin or False, |
|
206 | 'admin': admin or False, |
@@ -31,7 +31,7 b' import logging' | |||||
31 | from kallithea.lib import auth_modules |
|
31 | from kallithea.lib import auth_modules | |
32 | from kallithea.lib.compat import hybrid_property |
|
32 | from kallithea.lib.compat import hybrid_property | |
33 | from kallithea.lib.exceptions import LdapConnectionError, LdapImportError, LdapPasswordError, LdapUsernameError |
|
33 | from kallithea.lib.exceptions import LdapConnectionError, LdapImportError, LdapPasswordError, LdapUsernameError | |
34 |
from kallithea.lib.utils2 import safe_str |
|
34 | from kallithea.lib.utils2 import safe_str | |
35 |
|
35 | |||
36 |
|
36 | |||
37 | log = logging.getLogger(__name__) |
|
37 | log = logging.getLogger(__name__) | |
@@ -338,8 +338,8 b' class KallitheaAuthPlugin(auth_modules.K' | |||||
338 |
|
338 | |||
339 | user_data = { |
|
339 | user_data = { | |
340 | 'username': username, |
|
340 | 'username': username, | |
341 |
'firstname': |
|
341 | 'firstname': get_ldap_attr('attr_firstname') or firstname, | |
342 |
'lastname': |
|
342 | 'lastname': get_ldap_attr('attr_lastname') or lastname, | |
343 | 'groups': [], |
|
343 | 'groups': [], | |
344 | 'email': get_ldap_attr('attr_email') or email, |
|
344 | 'email': get_ldap_attr('attr_email') or email, | |
345 | 'admin': admin, |
|
345 | 'admin': admin, |
@@ -553,7 +553,7 b' class BaseRepoController(BaseController)' | |||||
553 | return |
|
553 | return | |
554 |
|
554 | |||
555 | log.debug('Found repository in database %s with state `%s`', |
|
555 | log.debug('Found repository in database %s with state `%s`', | |
556 |
|
|
556 | _dbr, _dbr.repo_state) | |
557 | route = getattr(request.environ.get('routes.route'), 'name', '') |
|
557 | route = getattr(request.environ.get('routes.route'), 'name', '') | |
558 |
|
558 | |||
559 | # allow to delete repos that are somehow damages in filesystem |
|
559 | # allow to delete repos that are somehow damages in filesystem |
@@ -205,8 +205,6 b' def FID(raw_id, path):' | |||||
205 | class _FilesBreadCrumbs(object): |
|
205 | class _FilesBreadCrumbs(object): | |
206 |
|
206 | |||
207 | def __call__(self, repo_name, rev, paths): |
|
207 | def __call__(self, repo_name, rev, paths): | |
208 | if isinstance(paths, str): |
|
|||
209 | paths = safe_unicode(paths) |
|
|||
210 | url_l = [link_to(repo_name, url('files_home', |
|
208 | url_l = [link_to(repo_name, url('files_home', | |
211 | repo_name=repo_name, |
|
209 | repo_name=repo_name, | |
212 | revision=rev, f_path=''), |
|
210 | revision=rev, f_path=''), | |
@@ -954,7 +952,7 b' def changed_tooltip(nodes):' | |||||
954 | suf = '' |
|
952 | suf = '' | |
955 | if len(nodes) > 30: |
|
953 | if len(nodes) > 30: | |
956 | suf = '<br/>' + _(' and %s more') % (len(nodes) - 30) |
|
954 | suf = '<br/>' + _(' and %s more') % (len(nodes) - 30) | |
957 |
return literal(pref + '<br/> '.join([ |
|
955 | return literal(pref + '<br/> '.join([x.path | |
958 | for x in nodes[:30]]) + suf) |
|
956 | for x in nodes[:30]]) + suf) | |
959 | else: |
|
957 | else: | |
960 | return ': ' + _('No files') |
|
958 | return ': ' + _('No files') |
@@ -34,7 +34,7 b' import mercurial.scmutil' | |||||
34 | from kallithea.lib import helpers as h |
|
34 | from kallithea.lib import helpers as h | |
35 | from kallithea.lib.exceptions import UserCreationError |
|
35 | from kallithea.lib.exceptions import UserCreationError | |
36 | from kallithea.lib.utils import action_logger, make_ui |
|
36 | from kallithea.lib.utils import action_logger, make_ui | |
37 |
from kallithea.lib.utils2 import HookEnvironmentError, ascii_str, get_hook_environment, safe_bytes, safe_str |
|
37 | from kallithea.lib.utils2 import HookEnvironmentError, ascii_str, get_hook_environment, safe_bytes, safe_str | |
38 | from kallithea.lib.vcs.backends.base import EmptyChangeset |
|
38 | from kallithea.lib.vcs.backends.base import EmptyChangeset | |
39 | from kallithea.model.db import Repository, User |
|
39 | from kallithea.model.db import Repository, User | |
40 |
|
40 | |||
@@ -312,7 +312,6 b' def _hook_environment(repo_path):' | |||||
312 | #logging.config.fileConfig(ini_file_path) # Note: we are in a different process - don't use configured logging |
|
312 | #logging.config.fileConfig(ini_file_path) # Note: we are in a different process - don't use configured logging | |
313 | kallithea.config.middleware.make_app(kallithea.CONFIG.global_conf, **kallithea.CONFIG.local_conf) |
|
313 | kallithea.config.middleware.make_app(kallithea.CONFIG.global_conf, **kallithea.CONFIG.local_conf) | |
314 |
|
314 | |||
315 | repo_path = safe_unicode(repo_path) |
|
|||
316 | # fix if it's not a bare repo |
|
315 | # fix if it's not a bare repo | |
317 | if repo_path.endswith(os.sep + '.git'): |
|
316 | if repo_path.endswith(os.sep + '.git'): | |
318 | repo_path = repo_path[:-5] |
|
317 | repo_path = repo_path[:-5] |
@@ -77,8 +77,7 b' class WhooshIndexingDaemon(object):' | |||||
77 |
|
77 | |||
78 | # filter repo list |
|
78 | # filter repo list | |
79 | if repo_list: |
|
79 | if repo_list: | |
80 | # Fix non-ascii repo names to unicode |
|
80 | repo_list = set(repo_list) | |
81 | repo_list = set(safe_unicode(repo_name) for repo_name in repo_list) |
|
|||
82 | self.filtered_repo_paths = {} |
|
81 | self.filtered_repo_paths = {} | |
83 | for repo_name, repo in self.repo_paths.items(): |
|
82 | for repo_name, repo in self.repo_paths.items(): | |
84 | if repo_name in repo_list: |
|
83 | if repo_name in repo_list: | |
@@ -110,7 +109,7 b' class WhooshIndexingDaemon(object):' | |||||
110 | self.initial = False |
|
109 | self.initial = False | |
111 |
|
110 | |||
112 | def _get_index_revision(self, repo): |
|
111 | def _get_index_revision(self, repo): | |
113 |
db_repo = Repository.get_by_repo_name( |
|
112 | db_repo = Repository.get_by_repo_name(repo.name) | |
114 | landing_rev = 'tip' |
|
113 | landing_rev = 'tip' | |
115 | if db_repo: |
|
114 | if db_repo: | |
116 | _rev_type, _rev = db_repo.landing_rev |
|
115 | _rev_type, _rev = db_repo.landing_rev | |
@@ -197,13 +196,12 b' class WhooshIndexingDaemon(object):' | |||||
197 | u_content = u'' |
|
196 | u_content = u'' | |
198 | indexed += 1 |
|
197 | indexed += 1 | |
199 |
|
198 | |||
200 | p = safe_unicode(path) |
|
|||
201 | writer.add_document( |
|
199 | writer.add_document( | |
202 | fileid=p, |
|
200 | fileid=path, | |
203 |
owner= |
|
201 | owner=repo.contact, | |
204 |
repository_rawname= |
|
202 | repository_rawname=repo_name, | |
205 |
repository= |
|
203 | repository=repo_name, | |
206 | path=p, |
|
204 | path=path, | |
207 | content=u_content, |
|
205 | content=u_content, | |
208 | modtime=self.get_node_mtime(node), |
|
206 | modtime=self.get_node_mtime(node), | |
209 | extension=node.extension |
|
207 | extension=node.extension | |
@@ -238,18 +236,18 b' class WhooshIndexingDaemon(object):' | |||||
238 | indexed += 1 |
|
236 | indexed += 1 | |
239 | log.debug(' >> %s %s/%s', cs, indexed, total) |
|
237 | log.debug(' >> %s %s/%s', cs, indexed, total) | |
240 | writer.add_document( |
|
238 | writer.add_document( | |
241 |
raw_id= |
|
239 | raw_id=cs.raw_id, | |
242 |
owner= |
|
240 | owner=repo.contact, | |
243 | date=cs._timestamp, |
|
241 | date=cs._timestamp, | |
244 |
repository_rawname= |
|
242 | repository_rawname=repo_name, | |
245 |
repository= |
|
243 | repository=repo_name, | |
246 | author=cs.author, |
|
244 | author=cs.author, | |
247 | message=cs.message, |
|
245 | message=cs.message, | |
248 | last=cs.last, |
|
246 | last=cs.last, | |
249 |
added=u' '.join( |
|
247 | added=u' '.join(node.path for node in cs.added).lower(), | |
250 |
removed=u' '.join( |
|
248 | removed=u' '.join(node.path for node in cs.removed).lower(), | |
251 |
changed=u' '.join( |
|
249 | changed=u' '.join(node.path for node in cs.changed).lower(), | |
252 |
parents=u' '.join( |
|
250 | parents=u' '.join(cs.raw_id for cs in cs.parents), | |
253 | ) |
|
251 | ) | |
254 |
|
252 | |||
255 | return indexed |
|
253 | return indexed | |
@@ -391,9 +389,7 b' class WhooshIndexingDaemon(object):' | |||||
391 | ri_cnt = 0 # indexed |
|
389 | ri_cnt = 0 # indexed | |
392 | riwc_cnt = 0 # indexed with content |
|
390 | riwc_cnt = 0 # indexed with content | |
393 | for path in self.get_paths(repo): |
|
391 | for path in self.get_paths(repo): | |
394 | path = safe_unicode(path) |
|
|||
395 | if path in to_index or path not in indexed_paths: |
|
392 | if path in to_index or path not in indexed_paths: | |
396 |
|
||||
397 | # This is either a file that's changed, or a new file |
|
393 | # This is either a file that's changed, or a new file | |
398 | # that wasn't indexed before. So index it! |
|
394 | # that wasn't indexed before. So index it! | |
399 | i, iwc = self.add_doc(writer, path, repo, repo_name) |
|
395 | i, iwc = self.add_doc(writer, path, repo, repo_name) |
@@ -33,7 +33,7 b' import traceback' | |||||
33 | from webob import Request, Response, exc |
|
33 | from webob import Request, Response, exc | |
34 |
|
34 | |||
35 | import kallithea |
|
35 | import kallithea | |
36 |
from kallithea.lib.utils2 import ascii_bytes |
|
36 | from kallithea.lib.utils2 import ascii_bytes | |
37 | from kallithea.lib.vcs import subprocessio |
|
37 | from kallithea.lib.vcs import subprocessio | |
38 |
|
38 | |||
39 |
|
39 | |||
@@ -87,7 +87,6 b' class GitRepository(object):' | |||||
87 |
|
87 | |||
88 | :param path: |
|
88 | :param path: | |
89 | """ |
|
89 | """ | |
90 | path = safe_unicode(path) |
|
|||
91 | assert path.startswith('/' + self.repo_name + '/') |
|
90 | assert path.startswith('/' + self.repo_name + '/') | |
92 | return path[len(self.repo_name) + 2:].strip('/') |
|
91 | return path[len(self.repo_name) + 2:].strip('/') | |
93 |
|
92 |
@@ -35,7 +35,6 b' from kallithea.lib.base import BaseVCSCo' | |||||
35 | from kallithea.lib.hooks import log_pull_action |
|
35 | from kallithea.lib.hooks import log_pull_action | |
36 | from kallithea.lib.middleware.pygrack import make_wsgi_app |
|
36 | from kallithea.lib.middleware.pygrack import make_wsgi_app | |
37 | from kallithea.lib.utils import make_ui |
|
37 | from kallithea.lib.utils import make_ui | |
38 | from kallithea.lib.utils2 import safe_unicode |
|
|||
39 | from kallithea.model.db import Repository |
|
38 | from kallithea.model.db import Repository | |
40 |
|
39 | |||
41 |
|
40 | |||
@@ -64,7 +63,7 b' class SimpleGit(BaseVCSController):' | |||||
64 |
|
63 | |||
65 | class parsed_request(object): |
|
64 | class parsed_request(object): | |
66 | # See https://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols#_the_smart_protocol |
|
65 | # See https://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols#_the_smart_protocol | |
67 |
repo_name = |
|
66 | repo_name = m.group(1).rstrip('/') | |
68 | cmd = m.group(2) |
|
67 | cmd = m.group(2) | |
69 |
|
68 | |||
70 | query_string = environ['QUERY_STRING'] |
|
69 | query_string = environ['QUERY_STRING'] |
@@ -36,7 +36,7 b' import mercurial.hgweb' | |||||
36 |
|
36 | |||
37 | from kallithea.lib.base import BaseVCSController, get_path_info |
|
37 | from kallithea.lib.base import BaseVCSController, get_path_info | |
38 | from kallithea.lib.utils import make_ui |
|
38 | from kallithea.lib.utils import make_ui | |
39 |
from kallithea.lib.utils2 import safe_bytes, safe_str |
|
39 | from kallithea.lib.utils2 import safe_bytes, safe_str | |
40 |
|
40 | |||
41 |
|
41 | |||
42 | log = logging.getLogger(__name__) |
|
42 | log = logging.getLogger(__name__) | |
@@ -105,7 +105,7 b' class SimpleHg(BaseVCSController):' | |||||
105 | return None |
|
105 | return None | |
106 |
|
106 | |||
107 | class parsed_request(object): |
|
107 | class parsed_request(object): | |
108 |
repo_name = |
|
108 | repo_name = path_info[1:].rstrip('/') | |
109 |
|
109 | |||
110 | query_string = environ['QUERY_STRING'] |
|
110 | query_string = environ['QUERY_STRING'] | |
111 |
|
111 |
@@ -40,7 +40,7 b' from tg.i18n import ugettext as _' | |||||
40 |
|
40 | |||
41 | import kallithea.config.conf |
|
41 | import kallithea.config.conf | |
42 | from kallithea.lib.exceptions import HgsubversionImportError |
|
42 | from kallithea.lib.exceptions import HgsubversionImportError | |
43 |
from kallithea.lib.utils2 import ascii_bytes, aslist, get_current_authuser, safe_bytes, safe_str |
|
43 | from kallithea.lib.utils2 import ascii_bytes, aslist, get_current_authuser, safe_bytes, safe_str | |
44 | from kallithea.lib.vcs.backends.git.repository import GitRepository |
|
44 | from kallithea.lib.vcs.backends.git.repository import GitRepository | |
45 | from kallithea.lib.vcs.backends.hg.repository import MercurialRepository |
|
45 | from kallithea.lib.vcs.backends.hg.repository import MercurialRepository | |
46 | from kallithea.lib.vcs.conf import settings |
|
46 | from kallithea.lib.vcs.conf import settings | |
@@ -150,7 +150,7 b' def action_logger(user, action, repo, ip' | |||||
150 | user_log = UserLog() |
|
150 | user_log = UserLog() | |
151 | user_log.user_id = user_obj.user_id |
|
151 | user_log.user_id = user_obj.user_id | |
152 | user_log.username = user_obj.username |
|
152 | user_log.username = user_obj.username | |
153 |
user_log.action = |
|
153 | user_log.action = action | |
154 |
|
154 | |||
155 | user_log.repository = repo_obj |
|
155 | user_log.repository = repo_obj | |
156 | user_log.repository_name = repo_name |
|
156 | user_log.repository_name = repo_name | |
@@ -160,7 +160,7 b' def action_logger(user, action, repo, ip' | |||||
160 | meta.Session().add(user_log) |
|
160 | meta.Session().add(user_log) | |
161 |
|
161 | |||
162 | log.info('Logging action:%s on %s by user:%s ip:%s', |
|
162 | log.info('Logging action:%s on %s by user:%s ip:%s', | |
163 |
action, |
|
163 | action, repo, user_obj, ipaddr) | |
164 | if commit: |
|
164 | if commit: | |
165 | meta.Session().commit() |
|
165 | meta.Session().commit() | |
166 |
|
166 | |||
@@ -480,8 +480,7 b' def repo2db_mapper(initial_repo_dict, re' | |||||
480 |
|
480 | |||
481 | for name, repo in initial_repo_dict.items(): |
|
481 | for name, repo in initial_repo_dict.items(): | |
482 | group = map_groups(name) |
|
482 | group = map_groups(name) | |
483 | unicode_name = safe_unicode(name) |
|
483 | db_repo = repo_model.get_by_repo_name(name) | |
484 | db_repo = repo_model.get_by_repo_name(unicode_name) |
|
|||
485 | # found repo that is on filesystem not in Kallithea database |
|
484 | # found repo that is on filesystem not in Kallithea database | |
486 | if not db_repo: |
|
485 | if not db_repo: | |
487 | log.info('repository %s not found, creating now', name) |
|
486 | log.info('repository %s not found, creating now', name) | |
@@ -517,9 +516,8 b' def repo2db_mapper(initial_repo_dict, re' | |||||
517 |
|
516 | |||
518 | removed = [] |
|
517 | removed = [] | |
519 | # remove from database those repositories that are not in the filesystem |
|
518 | # remove from database those repositories that are not in the filesystem | |
520 | unicode_initial_repo_names = set(safe_unicode(name) for name in initial_repo_dict) |
|
|||
521 | for repo in sa.query(Repository).all(): |
|
519 | for repo in sa.query(Repository).all(): | |
522 |
if repo.repo_name not in |
|
520 | if repo.repo_name not in initial_repo_dict: | |
523 | if remove_obsolete: |
|
521 | if remove_obsolete: | |
524 | log.debug("Removing non-existing repository found in db `%s`", |
|
522 | log.debug("Removing non-existing repository found in db `%s`", | |
525 | repo.repo_name) |
|
523 | repo.repo_name) |
@@ -322,19 +322,19 b' def credentials_filter(uri):' | |||||
322 |
|
322 | |||
323 | def get_clone_url(clone_uri_tmpl, prefix_url, repo_name, repo_id, username=None): |
|
323 | def get_clone_url(clone_uri_tmpl, prefix_url, repo_name, repo_id, username=None): | |
324 | parsed_url = urlobject.URLObject(prefix_url) |
|
324 | parsed_url = urlobject.URLObject(prefix_url) | |
325 |
prefix = |
|
325 | prefix = urllib.parse.unquote(parsed_url.path.rstrip('/')) | |
326 | try: |
|
326 | try: | |
327 | system_user = pwd.getpwuid(os.getuid()).pw_name |
|
327 | system_user = pwd.getpwuid(os.getuid()).pw_name | |
328 | except Exception: # TODO: support all systems - especially Windows |
|
328 | except Exception: # TODO: support all systems - especially Windows | |
329 | system_user = 'kallithea' # hardcoded default value ... |
|
329 | system_user = 'kallithea' # hardcoded default value ... | |
330 | args = { |
|
330 | args = { | |
331 | 'scheme': parsed_url.scheme, |
|
331 | 'scheme': parsed_url.scheme, | |
332 |
'user': |
|
332 | 'user': urllib.parse.quote(safe_str(username or '')), | |
333 | 'netloc': parsed_url.netloc + prefix, # like "hostname:port/prefix" (with optional ":port" and "/prefix") |
|
333 | 'netloc': parsed_url.netloc + prefix, # like "hostname:port/prefix" (with optional ":port" and "/prefix") | |
334 | 'prefix': prefix, # undocumented, empty or starting with / |
|
334 | 'prefix': prefix, # undocumented, empty or starting with / | |
335 | 'repo': repo_name, |
|
335 | 'repo': repo_name, | |
336 | 'repoid': str(repo_id), |
|
336 | 'repoid': str(repo_id), | |
337 |
'system_user': |
|
337 | 'system_user': system_user, | |
338 | 'hostname': parsed_url.hostname, |
|
338 | 'hostname': parsed_url.hostname, | |
339 | } |
|
339 | } | |
340 | url = re.sub('{([^{}]+)}', lambda m: args.get(m.group(1), m.group(0)), clone_uri_tmpl) |
|
340 | url = re.sub('{([^{}]+)}', lambda m: args.get(m.group(1), m.group(0)), clone_uri_tmpl) | |
@@ -344,7 +344,7 b' def get_clone_url(clone_uri_tmpl, prefix' | |||||
344 | if not url_obj.username: |
|
344 | if not url_obj.username: | |
345 | url_obj = url_obj.with_username(None) |
|
345 | url_obj = url_obj.with_username(None) | |
346 |
|
346 | |||
347 |
return s |
|
347 | return str(url_obj) | |
348 |
|
348 | |||
349 |
|
349 | |||
350 | def get_changeset_safe(repo, rev): |
|
350 | def get_changeset_safe(repo, rev): |
@@ -15,7 +15,7 b' import itertools' | |||||
15 | from kallithea.lib.vcs.conf import settings |
|
15 | from kallithea.lib.vcs.conf import settings | |
16 | from kallithea.lib.vcs.exceptions import ( |
|
16 | from kallithea.lib.vcs.exceptions import ( | |
17 | ChangesetError, EmptyRepositoryError, NodeAlreadyAddedError, NodeAlreadyChangedError, NodeAlreadyExistsError, NodeAlreadyRemovedError, NodeDoesNotExistError, NodeNotChangedError, RepositoryError) |
|
17 | ChangesetError, EmptyRepositoryError, NodeAlreadyAddedError, NodeAlreadyChangedError, NodeAlreadyExistsError, NodeAlreadyRemovedError, NodeDoesNotExistError, NodeNotChangedError, RepositoryError) | |
18 |
from kallithea.lib.vcs.utils import author_email, author_name |
|
18 | from kallithea.lib.vcs.utils import author_email, author_name | |
19 | from kallithea.lib.vcs.utils.helpers import get_dict_for_attrs |
|
19 | from kallithea.lib.vcs.utils.helpers import get_dict_for_attrs | |
20 | from kallithea.lib.vcs.utils.lazy import LazyProperty |
|
20 | from kallithea.lib.vcs.utils.lazy import LazyProperty | |
21 |
|
21 | |||
@@ -376,9 +376,9 b' class BaseChangeset(object):' | |||||
376 | message=self.message, |
|
376 | message=self.message, | |
377 | date=self.date, |
|
377 | date=self.date, | |
378 | author=self.author, |
|
378 | author=self.author, | |
379 |
added=[ |
|
379 | added=[el.path for el in self.added], | |
380 |
changed=[ |
|
380 | changed=[el.path for el in self.changed], | |
381 |
removed=[ |
|
381 | removed=[el.path for el in self.removed], | |
382 | ) |
|
382 | ) | |
383 | else: |
|
383 | else: | |
384 | return dict( |
|
384 | return dict( | |
@@ -643,9 +643,9 b' class BaseChangeset(object):' | |||||
643 | data = get_dict_for_attrs(self, ['raw_id', 'short_id', |
|
643 | data = get_dict_for_attrs(self, ['raw_id', 'short_id', | |
644 | 'revision', 'date', 'message']) |
|
644 | 'revision', 'date', 'message']) | |
645 | data['author'] = {'name': self.author_name, 'email': self.author_email} |
|
645 | data['author'] = {'name': self.author_name, 'email': self.author_email} | |
646 |
data['added'] = [ |
|
646 | data['added'] = [node.path for node in self.added] | |
647 |
data['changed'] = [ |
|
647 | data['changed'] = [node.path for node in self.changed] | |
648 |
data['removed'] = [ |
|
648 | data['removed'] = [node.path for node in self.removed] | |
649 | return data |
|
649 | return data | |
650 |
|
650 | |||
651 | @LazyProperty |
|
651 | @LazyProperty |
@@ -54,7 +54,7 b' class GitRepository(BaseRepository):' | |||||
54 | def __init__(self, repo_path, create=False, src_url=None, |
|
54 | def __init__(self, repo_path, create=False, src_url=None, | |
55 | update_after_clone=False, bare=False): |
|
55 | update_after_clone=False, bare=False): | |
56 |
|
56 | |||
57 |
self.path = |
|
57 | self.path = abspath(repo_path) | |
58 | self.repo = self._get_repo(create, src_url, update_after_clone, bare) |
|
58 | self.repo = self._get_repo(create, src_url, update_after_clone, bare) | |
59 | self.bare = self.repo.bare |
|
59 | self.bare = self.repo.bare | |
60 |
|
60 |
@@ -18,7 +18,7 b' import os' | |||||
18 | from kallithea.lib.hooks import log_pull_action |
|
18 | from kallithea.lib.hooks import log_pull_action | |
19 | from kallithea.lib.utils import make_ui |
|
19 | from kallithea.lib.utils import make_ui | |
20 | from kallithea.lib.vcs.backends.ssh import BaseSshHandler |
|
20 | from kallithea.lib.vcs.backends.ssh import BaseSshHandler | |
21 |
from kallithea.lib.vcs.utils import safe_str |
|
21 | from kallithea.lib.vcs.utils import safe_str | |
22 |
|
22 | |||
23 |
|
23 | |||
24 | log = logging.getLogger(__name__) |
|
24 | log = logging.getLogger(__name__) | |
@@ -56,7 +56,7 b' class GitSshHandler(BaseSshHandler):' | |||||
56 | ssh_command_parts[0] in ['git-upload-pack', 'git-receive-pack'] and |
|
56 | ssh_command_parts[0] in ['git-upload-pack', 'git-receive-pack'] and | |
57 | ssh_command_parts[1].startswith('/') |
|
57 | ssh_command_parts[1].startswith('/') | |
58 | ): |
|
58 | ): | |
59 |
return cls |
|
59 | return cls(ssh_command_parts[1][1:], ssh_command_parts[0]) | |
60 |
|
60 | |||
61 | return None |
|
61 | return None | |
62 |
|
62 |
@@ -19,7 +19,7 b' import mercurial.wireprotoserver' | |||||
19 |
|
19 | |||
20 | from kallithea.lib.utils import make_ui |
|
20 | from kallithea.lib.utils import make_ui | |
21 | from kallithea.lib.vcs.backends.ssh import BaseSshHandler |
|
21 | from kallithea.lib.vcs.backends.ssh import BaseSshHandler | |
22 |
from kallithea.lib.vcs.utils import safe_bytes |
|
22 | from kallithea.lib.vcs.utils import safe_bytes | |
23 |
|
23 | |||
24 |
|
24 | |||
25 | log = logging.getLogger(__name__) |
|
25 | log = logging.getLogger(__name__) | |
@@ -47,7 +47,7 b' class MercurialSshHandler(BaseSshHandler' | |||||
47 | >>> MercurialSshHandler.make(shlex.split('git-upload-pack "/foo"')) # not handled here |
|
47 | >>> MercurialSshHandler.make(shlex.split('git-upload-pack "/foo"')) # not handled here | |
48 | """ |
|
48 | """ | |
49 | if ssh_command_parts[:2] == ['hg', '-R'] and ssh_command_parts[3:] == ['serve', '--stdio']: |
|
49 | if ssh_command_parts[:2] == ['hg', '-R'] and ssh_command_parts[3:] == ['serve', '--stdio']: | |
50 |
return cls( |
|
50 | return cls(ssh_command_parts[2]) | |
51 |
|
51 | |||
52 | return None |
|
52 | return None | |
53 |
|
53 |
@@ -126,7 +126,7 b' class Node(object):' | |||||
126 | Returns name of the node so if its path |
|
126 | Returns name of the node so if its path | |
127 | then only last part is returned. |
|
127 | then only last part is returned. | |
128 | """ |
|
128 | """ | |
129 |
return |
|
129 | return self.path.rstrip('/').split('/')[-1] | |
130 |
|
130 | |||
131 | def _get_kind(self): |
|
131 | def _get_kind(self): | |
132 | return self._kind |
|
132 | return self._kind | |
@@ -605,5 +605,5 b' class SubModuleNode(Node):' | |||||
605 | Returns name of the node so if its path |
|
605 | Returns name of the node so if its path | |
606 | then only last part is returned. |
|
606 | then only last part is returned. | |
607 | """ |
|
607 | """ | |
608 |
org = |
|
608 | org = self.path.rstrip('/').rsplit('/', 1)[-1] | |
609 | return u'%s @ %s' % (org, self.changeset.short_id) |
|
609 | return u'%s @ %s' % (org, self.changeset.short_id) |
@@ -31,7 +31,7 b' from collections import defaultdict' | |||||
31 | from tg.i18n import ugettext as _ |
|
31 | from tg.i18n import ugettext as _ | |
32 |
|
32 | |||
33 | from kallithea.lib import helpers as h |
|
33 | from kallithea.lib import helpers as h | |
34 |
from kallithea.lib.utils2 import extract_mentioned_users |
|
34 | from kallithea.lib.utils2 import extract_mentioned_users | |
35 | from kallithea.model.db import ChangesetComment, PullRequest, Repository, User |
|
35 | from kallithea.model.db import ChangesetComment, PullRequest, Repository, User | |
36 | from kallithea.model.meta import Session |
|
36 | from kallithea.model.meta import Session | |
37 | from kallithea.model.notification import NotificationModel |
|
37 | from kallithea.model.notification import NotificationModel | |
@@ -81,11 +81,10 b' class ChangesetCommentsModel(object):' | |||||
81 | repo_name=repo.repo_name, |
|
81 | repo_name=repo.repo_name, | |
82 | revision=revision, |
|
82 | revision=revision, | |
83 | anchor='comment-%s' % comment.comment_id) |
|
83 | anchor='comment-%s' % comment.comment_id) | |
84 |
subj = |
|
84 | subj = h.link_to( | |
85 |
|
|
85 | 'Re changeset: %(desc)s %(line)s' % | |
86 | {'desc': desc, 'line': line}, |
|
86 | {'desc': desc, 'line': line}, | |
87 |
|
|
87 | comment_url) | |
88 | ) |
|
|||
89 | # get the current participants of this changeset |
|
88 | # get the current participants of this changeset | |
90 | recipients = _list_changeset_commenters(revision) |
|
89 | recipients = _list_changeset_commenters(revision) | |
91 | # add changeset author if it's known locally |
|
90 | # add changeset author if it's known locally | |
@@ -127,13 +126,12 b' class ChangesetCommentsModel(object):' | |||||
127 | h.canonical_hostname())) |
|
126 | h.canonical_hostname())) | |
128 | comment_url = pull_request.url(canonical=True, |
|
127 | comment_url = pull_request.url(canonical=True, | |
129 | anchor='comment-%s' % comment.comment_id) |
|
128 | anchor='comment-%s' % comment.comment_id) | |
130 |
subj = |
|
129 | subj = h.link_to( | |
131 |
|
|
130 | 'Re pull request %(pr_nice_id)s: %(desc)s %(line)s' % | |
132 | {'desc': desc, |
|
131 | {'desc': desc, | |
133 | 'pr_nice_id': comment.pull_request.nice_id(), |
|
132 | 'pr_nice_id': comment.pull_request.nice_id(), | |
134 | 'line': line}, |
|
133 | 'line': line}, | |
135 |
|
|
134 | comment_url) | |
136 | ) |
|
|||
137 | # get the current participants of this pull request |
|
135 | # get the current participants of this pull request | |
138 | recipients = _list_pull_request_commenters(pull_request) |
|
136 | recipients = _list_pull_request_commenters(pull_request) | |
139 | recipients.append(pull_request.owner) |
|
137 | recipients.append(pull_request.owner) |
@@ -328,9 +328,9 b' class Setting(Base, BaseDbModel):' | |||||
328 | info = { |
|
328 | info = { | |
329 | 'modules': sorted(mods, key=lambda k: k[0].lower()), |
|
329 | 'modules': sorted(mods, key=lambda k: k[0].lower()), | |
330 | 'py_version': platform.python_version(), |
|
330 | 'py_version': platform.python_version(), | |
331 |
'platform': |
|
331 | 'platform': platform.platform(), | |
332 | 'kallithea_version': kallithea.__version__, |
|
332 | 'kallithea_version': kallithea.__version__, | |
333 |
'git_version': s |
|
333 | 'git_version': str(check_git_version()), | |
334 | 'git_path': kallithea.CONFIG.get('git_path') |
|
334 | 'git_path': kallithea.CONFIG.get('git_path') | |
335 | } |
|
335 | } | |
336 | return info |
|
336 | return info | |
@@ -1162,7 +1162,7 b' class Repository(Base, BaseDbModel):' | |||||
1162 | # names in the database, but that eventually needs to be converted |
|
1162 | # names in the database, but that eventually needs to be converted | |
1163 | # into a valid system path |
|
1163 | # into a valid system path | |
1164 | p += self.repo_name.split(Repository.url_sep()) |
|
1164 | p += self.repo_name.split(Repository.url_sep()) | |
1165 |
return os.path.join(* |
|
1165 | return os.path.join(*p) | |
1166 |
|
1166 | |||
1167 | @property |
|
1167 | @property | |
1168 | def cache_keys(self): |
|
1168 | def cache_keys(self): | |
@@ -2282,7 +2282,7 b' class PullRequest(Base, BaseDbModel):' | |||||
2282 |
|
2282 | |||
2283 | @revisions.setter |
|
2283 | @revisions.setter | |
2284 | def revisions(self, val): |
|
2284 | def revisions(self, val): | |
2285 |
self._revisions = |
|
2285 | self._revisions = ':'.join(val) | |
2286 |
|
2286 | |||
2287 | @property |
|
2287 | @property | |
2288 | def org_ref_parts(self): |
|
2288 | def org_ref_parts(self): |
@@ -33,7 +33,7 b' import time' | |||||
33 | import traceback |
|
33 | import traceback | |
34 |
|
34 | |||
35 | from kallithea.lib import ext_json |
|
35 | from kallithea.lib import ext_json | |
36 |
from kallithea.lib.utils2 import AttributeDict, ascii_bytes, safe_int, |
|
36 | from kallithea.lib.utils2 import AttributeDict, ascii_bytes, safe_int, time_to_datetime | |
37 | from kallithea.model.db import Gist, Session, User |
|
37 | from kallithea.model.db import Gist, Session, User | |
38 | from kallithea.model.repo import RepoModel |
|
38 | from kallithea.model.repo import RepoModel | |
39 | from kallithea.model.scm import ScmModel |
|
39 | from kallithea.model.scm import ScmModel | |
@@ -120,7 +120,7 b' class GistModel(object):' | |||||
120 | gist.gist_access_id = gist_access_id |
|
120 | gist.gist_access_id = gist_access_id | |
121 | gist.owner_id = owner.user_id |
|
121 | gist.owner_id = owner.user_id | |
122 | gist.gist_expires = gist_expires |
|
122 | gist.gist_expires = gist_expires | |
123 |
gist.gist_type = |
|
123 | gist.gist_type = gist_type | |
124 | Session().add(gist) |
|
124 | Session().add(gist) | |
125 | Session().flush() # make database assign gist.gist_id |
|
125 | Session().flush() # make database assign gist.gist_id | |
126 | if gist_type == Gist.GIST_PUBLIC: |
|
126 | if gist_type == Gist.GIST_PUBLIC: |
@@ -33,7 +33,7 b' from tg import request' | |||||
33 | from tg.i18n import ugettext as _ |
|
33 | from tg.i18n import ugettext as _ | |
34 |
|
34 | |||
35 | from kallithea.lib import helpers as h |
|
35 | from kallithea.lib import helpers as h | |
36 |
from kallithea.lib.utils2 import ascii_bytes, extract_mentioned_users |
|
36 | from kallithea.lib.utils2 import ascii_bytes, extract_mentioned_users | |
37 | from kallithea.model.db import ChangesetStatus, PullRequest, PullRequestReviewer, User |
|
37 | from kallithea.model.db import ChangesetStatus, PullRequest, PullRequestReviewer, User | |
38 | from kallithea.model.meta import Session |
|
38 | from kallithea.model.meta import Session | |
39 | from kallithea.model.notification import NotificationModel |
|
39 | from kallithea.model.notification import NotificationModel | |
@@ -68,14 +68,12 b' class PullRequestModel(object):' | |||||
68 | threading = ['%s-pr-%s@%s' % (pr.other_repo.repo_name, |
|
68 | threading = ['%s-pr-%s@%s' % (pr.other_repo.repo_name, | |
69 | pr.pull_request_id, |
|
69 | pr.pull_request_id, | |
70 | h.canonical_hostname())] |
|
70 | h.canonical_hostname())] | |
71 |
subject = |
|
71 | subject = h.link_to( | |
72 | h.link_to( |
|
72 | _('%(user)s wants you to review pull request %(pr_nice_id)s: %(pr_title)s') % | |
73 | _('%(user)s wants you to review pull request %(pr_nice_id)s: %(pr_title)s') % |
|
|||
74 | {'user': user.username, |
|
73 | {'user': user.username, | |
75 | 'pr_title': pr.title, |
|
74 | 'pr_title': pr.title, | |
76 | 'pr_nice_id': pr.nice_id()}, |
|
75 | 'pr_nice_id': pr.nice_id()}, | |
77 |
|
|
76 | pr_url) | |
78 | ) |
|
|||
79 | body = pr.description |
|
77 | body = pr.description | |
80 | _org_ref_type, org_ref_name, _org_rev = pr.org_ref.split(':') |
|
78 | _org_ref_type, org_ref_name, _org_rev = pr.org_ref.split(':') | |
81 | _other_ref_type, other_ref_name, _other_rev = pr.other_ref.split(':') |
|
79 | _other_ref_type, other_ref_name, _other_rev = pr.other_ref.split(':') |
@@ -39,7 +39,7 b' from kallithea.lib.caching_query import ' | |||||
39 | from kallithea.lib.exceptions import AttachedForksError |
|
39 | from kallithea.lib.exceptions import AttachedForksError | |
40 | from kallithea.lib.hooks import log_delete_repository |
|
40 | from kallithea.lib.hooks import log_delete_repository | |
41 | from kallithea.lib.utils import is_valid_repo_uri, make_ui |
|
41 | from kallithea.lib.utils import is_valid_repo_uri, make_ui | |
42 |
from kallithea.lib.utils2 import LazyProperty, get_current_authuser, obfuscate_url_pw, remove_prefix, safe_str |
|
42 | from kallithea.lib.utils2 import LazyProperty, get_current_authuser, obfuscate_url_pw, remove_prefix, safe_str | |
43 | from kallithea.lib.vcs.backends import get_backend |
|
43 | from kallithea.lib.vcs.backends import get_backend | |
44 | from kallithea.model.db import ( |
|
44 | from kallithea.model.db import ( | |
45 | Permission, RepoGroup, Repository, RepositoryField, Session, Statistics, Ui, User, UserGroup, UserGroupRepoGroupToPerm, UserGroupRepoToPerm, UserRepoGroupToPerm, UserRepoToPerm) |
|
45 | Permission, RepoGroup, Repository, RepositoryField, Session, Statistics, Ui, User, UserGroup, UserGroupRepoGroupToPerm, UserGroupRepoToPerm, UserRepoGroupToPerm, UserRepoToPerm) | |
@@ -337,8 +337,8 b' class RepoModel(object):' | |||||
337 | fork_of = Repository.guess_instance(fork_of) |
|
337 | fork_of = Repository.guess_instance(fork_of) | |
338 | repo_group = RepoGroup.guess_instance(repo_group) |
|
338 | repo_group = RepoGroup.guess_instance(repo_group) | |
339 | try: |
|
339 | try: | |
340 |
repo_name = |
|
340 | repo_name = repo_name | |
341 |
description = |
|
341 | description = description | |
342 | # repo name is just a name of repository |
|
342 | # repo name is just a name of repository | |
343 | # while repo_name_full is a full qualified name that is combined |
|
343 | # while repo_name_full is a full qualified name that is combined | |
344 | # with name and path of group |
|
344 | # with name and path of group | |
@@ -653,7 +653,7 b' class RepoModel(object):' | |||||
653 | raise Exception('This path %s is a valid group' % repo_path) |
|
653 | raise Exception('This path %s is a valid group' % repo_path) | |
654 |
|
654 | |||
655 | log.info('creating repo %s in %s from url: `%s`', |
|
655 | log.info('creating repo %s in %s from url: `%s`', | |
656 |
repo_name, |
|
656 | repo_name, repo_path, | |
657 | obfuscate_url_pw(clone_uri)) |
|
657 | obfuscate_url_pw(clone_uri)) | |
658 |
|
658 | |||
659 | backend = get_backend(repo_type) |
|
659 | backend = get_backend(repo_type) | |
@@ -674,7 +674,7 b' class RepoModel(object):' | |||||
674 | raise Exception('Not supported repo_type %s expected hg/git' % repo_type) |
|
674 | raise Exception('Not supported repo_type %s expected hg/git' % repo_type) | |
675 |
|
675 | |||
676 | log.debug('Created repo %s with %s backend', |
|
676 | log.debug('Created repo %s with %s backend', | |
677 |
|
|
677 | repo_name, repo_type) | |
678 | return repo |
|
678 | return repo | |
679 |
|
679 | |||
680 | def _rename_filesystem_repo(self, old, new): |
|
680 | def _rename_filesystem_repo(self, old, new): |
@@ -41,7 +41,7 b' from kallithea.lib.auth import HasPermis' | |||||
41 | from kallithea.lib.exceptions import IMCCommitError, NonRelativePathError |
|
41 | from kallithea.lib.exceptions import IMCCommitError, NonRelativePathError | |
42 | from kallithea.lib.hooks import process_pushed_raw_ids |
|
42 | from kallithea.lib.hooks import process_pushed_raw_ids | |
43 | from kallithea.lib.utils import action_logger, get_filesystem_repos, make_ui |
|
43 | from kallithea.lib.utils import action_logger, get_filesystem_repos, make_ui | |
44 |
from kallithea.lib.utils2 import safe_bytes, safe_str, |
|
44 | from kallithea.lib.utils2 import safe_bytes, safe_str, set_hook_environment | |
45 | from kallithea.lib.vcs import get_backend |
|
45 | from kallithea.lib.vcs import get_backend | |
46 | from kallithea.lib.vcs.backends.base import EmptyChangeset |
|
46 | from kallithea.lib.vcs.backends.base import EmptyChangeset | |
47 | from kallithea.lib.vcs.exceptions import RepositoryError |
|
47 | from kallithea.lib.vcs.exceptions import RepositoryError | |
@@ -401,10 +401,6 b' class ScmModel(object):' | |||||
401 | # in any other case this will throw exceptions and deny commit |
|
401 | # in any other case this will throw exceptions and deny commit | |
402 | content = safe_str(content) |
|
402 | content = safe_str(content) | |
403 | path = safe_str(f_path) |
|
403 | path = safe_str(f_path) | |
404 | # message and author needs to be unicode |
|
|||
405 | # proper backend should then translate that into required type |
|
|||
406 | message = safe_unicode(message) |
|
|||
407 | author = safe_unicode(author) |
|
|||
408 | imc = IMC(repo) |
|
404 | imc = IMC(repo) | |
409 | imc.change(FileNode(path, content, mode=cs.get_file_mode(f_path))) |
|
405 | imc.change(FileNode(path, content, mode=cs.get_file_mode(f_path))) | |
410 | try: |
|
406 | try: | |
@@ -491,9 +487,10 b' class ScmModel(object):' | |||||
491 | content = content.read() |
|
487 | content = content.read() | |
492 | processed_nodes.append((f_path, content)) |
|
488 | processed_nodes.append((f_path, content)) | |
493 |
|
489 | |||
494 |
message = |
|
490 | message = message | |
495 | committer = user.full_contact |
|
491 | committer = user.full_contact | |
496 | author = safe_unicode(author) if author else committer |
|
492 | if not author: | |
|
493 | author = committer | |||
497 |
|
494 | |||
498 | IMC = self._get_IMC_module(scm_instance.alias) |
|
495 | IMC = self._get_IMC_module(scm_instance.alias) | |
499 | imc = IMC(scm_instance) |
|
496 | imc = IMC(scm_instance) | |
@@ -534,9 +531,10 b' class ScmModel(object):' | |||||
534 | user = User.guess_instance(user) |
|
531 | user = User.guess_instance(user) | |
535 | scm_instance = repo.scm_instance_no_cache() |
|
532 | scm_instance = repo.scm_instance_no_cache() | |
536 |
|
533 | |||
537 |
message = |
|
534 | message = message | |
538 | committer = user.full_contact |
|
535 | committer = user.full_contact | |
539 | author = safe_unicode(author) if author else committer |
|
536 | if not author: | |
|
537 | author = committer | |||
540 |
|
538 | |||
541 | imc_class = self._get_IMC_module(scm_instance.alias) |
|
539 | imc_class = self._get_IMC_module(scm_instance.alias) | |
542 | imc = imc_class(scm_instance) |
|
540 | imc = imc_class(scm_instance) | |
@@ -614,9 +612,10 b' class ScmModel(object):' | |||||
614 | content = nodes[f_path].get('content') |
|
612 | content = nodes[f_path].get('content') | |
615 | processed_nodes.append((f_path, content)) |
|
613 | processed_nodes.append((f_path, content)) | |
616 |
|
614 | |||
617 |
message = |
|
615 | message = message | |
618 | committer = user.full_contact |
|
616 | committer = user.full_contact | |
619 | author = safe_unicode(author) if author else committer |
|
617 | if not author: | |
|
618 | author = committer | |||
620 |
|
619 | |||
621 | IMC = self._get_IMC_module(scm_instance.alias) |
|
620 | IMC = self._get_IMC_module(scm_instance.alias) | |
622 | imc = IMC(scm_instance) |
|
621 | imc = IMC(scm_instance) |
@@ -38,7 +38,7 b' from tg.i18n import ugettext as _' | |||||
38 |
|
38 | |||
39 | from kallithea.lib.caching_query import FromCache |
|
39 | from kallithea.lib.caching_query import FromCache | |
40 | from kallithea.lib.exceptions import DefaultUserException, UserOwnsReposException |
|
40 | from kallithea.lib.exceptions import DefaultUserException, UserOwnsReposException | |
41 |
from kallithea.lib.utils2 import generate_api_key, get_current_authuser |
|
41 | from kallithea.lib.utils2 import generate_api_key, get_current_authuser | |
42 | from kallithea.model.db import Permission, User, UserEmailMap, UserIpMap, UserToPerm |
|
42 | from kallithea.model.db import Permission, User, UserEmailMap, UserIpMap, UserToPerm | |
43 | from kallithea.model.meta import Session |
|
43 | from kallithea.model.meta import Session | |
44 |
|
44 | |||
@@ -142,10 +142,8 b' class UserModel(object):' | |||||
142 | new_user.admin = admin |
|
142 | new_user.admin = admin | |
143 | new_user.email = email |
|
143 | new_user.email = email | |
144 | new_user.active = active |
|
144 | new_user.active = active | |
145 |
new_user.extern_name = |
|
145 | new_user.extern_name = extern_name | |
146 | if extern_name else None |
|
146 | new_user.extern_type = extern_type | |
147 | new_user.extern_type = safe_unicode(extern_type) \ |
|
|||
148 | if extern_type else None |
|
|||
149 | new_user.name = firstname |
|
147 | new_user.name = firstname | |
150 | new_user.lastname = lastname |
|
148 | new_user.lastname = lastname | |
151 |
|
149 |
@@ -67,8 +67,8 b'' | |||||
67 | % for cnt, file in enumerate(c.files): |
|
67 | % for cnt, file in enumerate(c.files): | |
68 | <div id="body" class="panel panel-default form-inline"> |
|
68 | <div id="body" class="panel panel-default form-inline"> | |
69 | <div class="panel-heading"> |
|
69 | <div class="panel-heading"> | |
70 |
<input type="hidden" value="${ |
|
70 | <input type="hidden" value="${file.path}" name="org_files"> | |
71 |
<input class="form-control" id="filename_${h.FID('f',file.path)}" name="files" size="30" type="text" value="${ |
|
71 | <input class="form-control" id="filename_${h.FID('f',file.path)}" name="files" size="30" type="text" value="${file.path}"> | |
72 | <select class="form-control" id="mimetype_${h.FID('f',file.path)}" name="mimetypes"></select> |
|
72 | <select class="form-control" id="mimetype_${h.FID('f',file.path)}" name="mimetypes"></select> | |
73 | </div> |
|
73 | </div> | |
74 | <div class="panel-body no-padding"> |
|
74 | <div class="panel-body no-padding"> |
@@ -76,10 +76,10 b'' | |||||
76 | <div class="panel panel-default"> |
|
76 | <div class="panel panel-default"> | |
77 | <div id="${h.FID('G', file.path)}" class="panel-heading clearfix"> |
|
77 | <div id="${h.FID('G', file.path)}" class="panel-heading clearfix"> | |
78 | <div class="pull-left"> |
|
78 | <div class="pull-left"> | |
79 |
<b>${ |
|
79 | <b>${file.path}</b> | |
80 | </div> |
|
80 | </div> | |
81 | <div class="pull-right"> |
|
81 | <div class="pull-right"> | |
82 |
${h.link_to(_('Show as raw'),h.url('formatted_gist_file', gist_id=c.gist.gist_access_id, format='raw', revision=file.changeset.raw_id, f_path= |
|
82 | ${h.link_to(_('Show as raw'),h.url('formatted_gist_file', gist_id=c.gist.gist_access_id, format='raw', revision=file.changeset.raw_id, f_path=file.path),class_="btn btn-default btn-xs")} | |
83 | </div> |
|
83 | </div> | |
84 | </div> |
|
84 | </div> | |
85 | <div class="panel-body no-padding"> |
|
85 | <div class="panel-body no-padding"> |
@@ -143,7 +143,7 b'' | |||||
143 | %for fid, url_fid, op, a_path, path, diff, stats in file_diff_data: |
|
143 | %for fid, url_fid, op, a_path, path, diff, stats in file_diff_data: | |
144 | <div class="cs_${op} clearfix"> |
|
144 | <div class="cs_${op} clearfix"> | |
145 | <span class="node"> |
|
145 | <span class="node"> | |
146 |
<i class="icon-diff-${op}"></i>${h.link_to( |
|
146 | <i class="icon-diff-${op}"></i>${h.link_to(path, '#%s' % fid)} | |
147 | </span> |
|
147 | </span> | |
148 | <div class="changes">${h.fancy_file_stats(stats)}</div> |
|
148 | <div class="changes">${h.fancy_file_stats(stats)}</div> | |
149 | </div> |
|
149 | </div> |
@@ -164,7 +164,7 b'' | |||||
164 | <div class="comments inline-comments"> |
|
164 | <div class="comments inline-comments"> | |
165 | %for f_path, lines in c.inline_comments: |
|
165 | %for f_path, lines in c.inline_comments: | |
166 | %for line_no, comments in lines.items(): |
|
166 | %for line_no, comments in lines.items(): | |
167 |
<div class="comments-list-chunk" data-f_path="${f_path}" data-line_no="${line_no}" data-target-id="${h.safeid( |
|
167 | <div class="comments-list-chunk" data-f_path="${f_path}" data-line_no="${line_no}" data-target-id="${h.safeid(f_path)}_${line_no}"> | |
168 | %for co in comments: |
|
168 | %for co in comments: | |
169 | ${comment_block(co)} |
|
169 | ${comment_block(co)} | |
170 | %endfor |
|
170 | %endfor |
@@ -56,7 +56,7 b'' | |||||
56 | <div class="cs_${op} clearfix"> |
|
56 | <div class="cs_${op} clearfix"> | |
57 | <span class="node"> |
|
57 | <span class="node"> | |
58 | <i class="icon-diff-${op}"></i> |
|
58 | <i class="icon-diff-${op}"></i> | |
59 |
${h.link_to( |
|
59 | ${h.link_to(path, '#%s' % fid)} | |
60 | </span> |
|
60 | </span> | |
61 | <div class="changes">${h.fancy_file_stats(stats)}</div> |
|
61 | <div class="changes">${h.fancy_file_stats(stats)}</div> | |
62 | </div> |
|
62 | </div> |
@@ -22,7 +22,7 b'' | |||||
22 | <div id="${id_fid}" class="panel panel-default ${cls}"> |
|
22 | <div id="${id_fid}" class="panel panel-default ${cls}"> | |
23 | <div class="panel-heading clearfix"> |
|
23 | <div class="panel-heading clearfix"> | |
24 | <div class="pull-left"> |
|
24 | <div class="pull-left"> | |
25 |
${ |
|
25 | ${cs_filename} | |
26 | </div> |
|
26 | </div> | |
27 | <div class="pull-left diff-actions"> |
|
27 | <div class="pull-left diff-actions"> | |
28 | <span> |
|
28 | <span> | |
@@ -57,13 +57,13 b'' | |||||
57 | %endif |
|
57 | %endif | |
58 | </span> |
|
58 | </span> | |
59 |
|
59 | |||
60 |
<a href="${h.url('files_diff_home',repo_name=cs_repo_name,f_path= |
|
60 | <a href="${h.url('files_diff_home',repo_name=cs_repo_name,f_path=cs_filename,diff2=cs_rev,diff1=a_rev,diff='diff',fulldiff=1)}" data-toggle="tooltip" title="${_('Show full diff for this file')}"> | |
61 | <i class="icon-file-code"></i></a> |
|
61 | <i class="icon-file-code"></i></a> | |
62 |
<a href="${h.url('files_diff_2way_home',repo_name=cs_repo_name,f_path= |
|
62 | <a href="${h.url('files_diff_2way_home',repo_name=cs_repo_name,f_path=cs_filename,diff2=cs_rev,diff1=a_rev,diff='diff',fulldiff=1)}" data-toggle="tooltip" title="${_('Show full side-by-side diff for this file')}"> | |
63 | <i class="icon-docs"></i></a> |
|
63 | <i class="icon-docs"></i></a> | |
64 |
<a href="${h.url('files_diff_home',repo_name=cs_repo_name,f_path= |
|
64 | <a href="${h.url('files_diff_home',repo_name=cs_repo_name,f_path=cs_filename,diff2=cs_rev,diff1=a_rev,diff='raw')}" data-toggle="tooltip" title="${_('Raw diff')}"> | |
65 | <i class="icon-diff"></i></a> |
|
65 | <i class="icon-diff"></i></a> | |
66 |
<a href="${h.url('files_diff_home',repo_name=cs_repo_name,f_path= |
|
66 | <a href="${h.url('files_diff_home',repo_name=cs_repo_name,f_path=cs_filename,diff2=cs_rev,diff1=a_rev,diff='download')}" data-toggle="tooltip" title="${_('Download diff')}"> | |
67 | <i class="icon-floppy"></i></a> |
|
67 | <i class="icon-floppy"></i></a> | |
68 | ${c.ignorews_url(request.GET, url_fid)} |
|
68 | ${c.ignorews_url(request.GET, url_fid)} | |
69 | ${c.context_url(request.GET, url_fid)} |
|
69 | ${c.context_url(request.GET, url_fid)} | |
@@ -73,7 +73,7 b'' | |||||
73 | ${h.checkbox('checkbox-show-inline-' + id_fid, checked="checked",class_="show-inline-comments",**{'data-id_for':id_fid})} |
|
73 | ${h.checkbox('checkbox-show-inline-' + id_fid, checked="checked",class_="show-inline-comments",**{'data-id_for':id_fid})} | |
74 | </div> |
|
74 | </div> | |
75 | </div> |
|
75 | </div> | |
76 |
<div class="no-padding panel-body" data-f_path="${ |
|
76 | <div class="no-padding panel-body" data-f_path="${cs_filename}"> | |
77 | ${diff|n} |
|
77 | ${diff|n} | |
78 | %if op and cs_filename.rsplit('.')[-1] in ['png', 'gif', 'jpg', 'bmp']: |
|
78 | %if op and cs_filename.rsplit('.')[-1] in ['png', 'gif', 'jpg', 'bmp']: | |
79 | <div class="btn btn-image-diff-show">Show images</div> |
|
79 | <div class="btn btn-image-diff-show">Show images</div> |
@@ -72,7 +72,7 b'' | |||||
72 | <div class="cs_${op} clearfix"> |
|
72 | <div class="cs_${op} clearfix"> | |
73 | <span class="node"> |
|
73 | <span class="node"> | |
74 | <i class="icon-diff-${op}"></i> |
|
74 | <i class="icon-diff-${op}"></i> | |
75 |
${h.link_to( |
|
75 | ${h.link_to(path, '#%s' % fid)} | |
76 | </span> |
|
76 | </span> | |
77 | <div class="changes">${h.fancy_file_stats(stats)}</div> |
|
77 | <div class="changes">${h.fancy_file_stats(stats)}</div> | |
78 | </div> |
|
78 | </div> |
@@ -34,22 +34,22 b'' | |||||
34 | <div class="panel panel-default"> |
|
34 | <div class="panel panel-default"> | |
35 | <div class="panel-heading clearfix"> |
|
35 | <div class="panel-heading clearfix"> | |
36 | <div class="pull-left"> |
|
36 | <div class="pull-left"> | |
37 |
${h.link_to( |
|
37 | ${h.link_to(c.node1.path,h.url('files_home',repo_name=c.repo_name, | |
38 |
revision=c.cs2.raw_id,f_path= |
|
38 | revision=c.cs2.raw_id,f_path=c.node1.path))} | |
39 | </div> |
|
39 | </div> | |
40 | <div class="pull-left diff-actions"> |
|
40 | <div class="pull-left diff-actions"> | |
41 |
<a href="${h.url('files_diff_home',repo_name=c.repo_name,f_path= |
|
41 | <a href="${h.url('files_diff_home',repo_name=c.repo_name,f_path=c.node1.path,diff2=c.cs2.raw_id,diff1=c.cs1.raw_id,diff='diff',fulldiff=1)}" | |
42 | data-toggle="tooltip" |
|
42 | data-toggle="tooltip" | |
43 | title="${_('Show full diff for this file')}"> |
|
43 | title="${_('Show full diff for this file')}"> | |
44 | <i class="icon-file-code"></i></a> |
|
44 | <i class="icon-file-code"></i></a> | |
45 |
<a href="${h.url('files_diff_2way_home',repo_name=c.repo_name,f_path= |
|
45 | <a href="${h.url('files_diff_2way_home',repo_name=c.repo_name,f_path=c.node1.path,diff2=c.cs2.raw_id,diff1=c.cs1.raw_id,diff='diff',fulldiff=1)}" | |
46 | data-toggle="tooltip" |
|
46 | data-toggle="tooltip" | |
47 | title="${_('Show full side-by-side diff for this file')}"> |
|
47 | title="${_('Show full side-by-side diff for this file')}"> | |
48 | <i class="icon-docs"></i></a> |
|
48 | <i class="icon-docs"></i></a> | |
49 |
<a href="${h.url('files_diff_home',repo_name=c.repo_name,f_path= |
|
49 | <a href="${h.url('files_diff_home',repo_name=c.repo_name,f_path=c.node1.path,diff2=c.cs2.raw_id,diff1=c.cs1.raw_id,diff='raw')}" | |
50 | data-toggle="tooltip" |
|
50 | data-toggle="tooltip" | |
51 | title="${_('Raw diff')}"><i class="icon-diff"></i></a> |
|
51 | title="${_('Raw diff')}"><i class="icon-diff"></i></a> | |
52 |
<a href="${h.url('files_diff_home',repo_name=c.repo_name,f_path= |
|
52 | <a href="${h.url('files_diff_home',repo_name=c.repo_name,f_path=c.node1.path,diff2=c.cs2.raw_id,diff1=c.cs1.raw_id,diff='download')}" | |
53 | data-toggle="tooltip" |
|
53 | data-toggle="tooltip" | |
54 | title="${_('Download diff')}"><i class="icon-floppy"></i></a> |
|
54 | title="${_('Download diff')}"><i class="icon-floppy"></i></a> | |
55 | ${h.checkbox('ignorews', label=_('Ignore whitespace'))} |
|
55 | ${h.checkbox('ignorews', label=_('Ignore whitespace'))} | |
@@ -61,8 +61,8 b'' | |||||
61 | </div> |
|
61 | </div> | |
62 |
|
62 | |||
63 | <script> |
|
63 | <script> | |
64 |
var orig1_url = ${h.jshtml(h.url('files_raw_home',repo_name=c.repo_name,f_path= |
|
64 | var orig1_url = ${h.jshtml(h.url('files_raw_home',repo_name=c.repo_name,f_path=c.node1.path,revision=c.cs1.raw_id))}; | |
65 |
var orig2_url = ${h.jshtml(h.url('files_raw_home',repo_name=c.repo_name,f_path= |
|
65 | var orig2_url = ${h.jshtml(h.url('files_raw_home',repo_name=c.repo_name,f_path=c.node2.path,revision=c.cs2.raw_id))}; | |
66 |
|
66 | |||
67 | $(document).ready(function () { |
|
67 | $(document).ready(function () { | |
68 | $('#compare').mergely({ |
|
68 | $('#compare').mergely({ |
@@ -3,7 +3,7 b'' | |||||
3 | <%block name="title"> |
|
3 | <%block name="title"> | |
4 | ${_('%s Files') % c.repo_name} |
|
4 | ${_('%s Files') % c.repo_name} | |
5 | %if hasattr(c,'file'): |
|
5 | %if hasattr(c,'file'): | |
6 |
· ${ |
|
6 | · ${c.file.path or '/'} | |
7 | %endif |
|
7 | %endif | |
8 | </%block> |
|
8 | </%block> | |
9 |
|
9 | |||
@@ -217,12 +217,12 b' var post_load_state = function(state) {' | |||||
217 | }); |
|
217 | }); | |
218 |
|
218 | |||
219 | // init the search filter |
|
219 | // init the search filter | |
220 |
var _node_list_url = node_list_url.replace('__REV__', ${h.js(c.changeset.raw_id)}).replace('__FPATH__', ${h.js( |
|
220 | var _node_list_url = node_list_url.replace('__REV__', ${h.js(c.changeset.raw_id)}).replace('__FPATH__', ${h.js(c.file.path)}); | |
221 | var _url_base = url_base.replace('__REV__', ${h.js(c.changeset.raw_id)}); |
|
221 | var _url_base = url_base.replace('__REV__', ${h.js(c.changeset.raw_id)}); | |
222 | fileBrowserListeners(_node_list_url, _url_base); |
|
222 | fileBrowserListeners(_node_list_url, _url_base); | |
223 |
|
223 | |||
224 | var initial_state = {url:window.location.href, title:document.title, url_base:_url_base, |
|
224 | var initial_state = {url:window.location.href, title:document.title, url_base:_url_base, | |
225 |
node_list_url:_node_list_url, rev:${h.js(c.changeset.raw_id)}, f_path:${h.js( |
|
225 | node_list_url:_node_list_url, rev:${h.js(c.changeset.raw_id)}, f_path:${h.js(c.file.path)}}; | |
226 |
|
226 | |||
227 | // change branch filter |
|
227 | // change branch filter | |
228 | $("#branch_selector").select2({ |
|
228 | $("#branch_selector").select2({ | |
@@ -234,7 +234,7 b' var post_load_state = function(state) {' | |||||
234 | $("#branch_selector").change(function(e){ |
|
234 | $("#branch_selector").change(function(e){ | |
235 | var selected = e.currentTarget.options[e.currentTarget.selectedIndex].value; |
|
235 | var selected = e.currentTarget.options[e.currentTarget.selectedIndex].value; | |
236 | if(selected && selected != ${h.js(c.changeset.raw_id)}){ |
|
236 | if(selected && selected != ${h.js(c.changeset.raw_id)}){ | |
237 |
window.location = pyroutes.url('files_home', {'repo_name': ${h.js( |
|
237 | window.location = pyroutes.url('files_home', {'repo_name': ${h.js(c.repo_name)}, 'revision': selected, 'f_path': ${h.js(c.file.path)}}); | |
238 | $("#body").hide(); |
|
238 | $("#body").hide(); | |
239 | } else { |
|
239 | } else { | |
240 | $("#branch_selector").val(${h.js(c.changeset.raw_id)}); |
|
240 | $("#branch_selector").val(${h.js(c.changeset.raw_id)}); | |
@@ -242,7 +242,7 b' var post_load_state = function(state) {' | |||||
242 | }); |
|
242 | }); | |
243 | $('#show_authors').on('click', function(){ |
|
243 | $('#show_authors').on('click', function(){ | |
244 | $.ajax({ |
|
244 | $.ajax({ | |
245 |
url: pyroutes.url('files_authors_home', {'revision': ${h.js(c.changeset.raw_id)}, 'f_path': ${h.js( |
|
245 | url: pyroutes.url('files_authors_home', {'revision': ${h.js(c.changeset.raw_id)}, 'f_path': ${h.js(c.file.path)}}), | |
246 | success: function(data) { |
|
246 | success: function(data) { | |
247 | $('#file_authors').html(data); |
|
247 | $('#file_authors').html(data); | |
248 | $('#file_authors').show(); |
|
248 | $('#file_authors').show(); |
@@ -13,7 +13,7 b'' | |||||
13 | %if node.is_submodule(): |
|
13 | %if node.is_submodule(): | |
14 | <%return node.url or '#'%> |
|
14 | <%return node.url or '#'%> | |
15 | %else: |
|
15 | %else: | |
16 |
<%return h.url('files_home', repo_name=c.repo_name, revision=c.changeset.raw_id, f_path= |
|
16 | <%return h.url('files_home', repo_name=c.repo_name, revision=c.changeset.raw_id, f_path=node.path)%> | |
17 | %endif |
|
17 | %endif | |
18 | </%def> |
|
18 | </%def> | |
19 | <%def name="_file_name(iconclass, name)"> |
|
19 | <%def name="_file_name(iconclass, name)"> |
@@ -300,7 +300,7 b'' | |||||
300 | <div class="cs_${op} clearfix"> |
|
300 | <div class="cs_${op} clearfix"> | |
301 | <span class="node"> |
|
301 | <span class="node"> | |
302 | <i class="icon-diff-${op}"></i> |
|
302 | <i class="icon-diff-${op}"></i> | |
303 |
${h.link_to( |
|
303 | ${h.link_to(path, '#%s' % fid)} | |
304 | </span> |
|
304 | </span> | |
305 | <div class="changes">${h.fancy_file_stats(stats)}</div> |
|
305 | <div class="changes">${h.fancy_file_stats(stats)}</div> | |
306 | </div> |
|
306 | </div> |
@@ -3,7 +3,6 b' import datetime' | |||||
3 | import os |
|
3 | import os | |
4 | from os.path import dirname |
|
4 | from os.path import dirname | |
5 |
|
5 | |||
6 | from kallithea.lib.utils2 import safe_unicode |
|
|||
7 | from kallithea.model.db import UserLog |
|
6 | from kallithea.model.db import UserLog | |
8 | from kallithea.model.meta import Session |
|
7 | from kallithea.model.meta import Session | |
9 | from kallithea.tests import base |
|
8 | from kallithea.tests import base | |
@@ -35,7 +34,6 b' class TestAdminController(base.TestContr' | |||||
35 | for row in csv.DictReader(f): |
|
34 | for row in csv.DictReader(f): | |
36 | ul = UserLog() |
|
35 | ul = UserLog() | |
37 | for k, v in row.items(): |
|
36 | for k, v in row.items(): | |
38 | v = safe_unicode(v) |
|
|||
39 | if k == 'action_date': |
|
37 | if k == 'action_date': | |
40 | v = strptime(v) |
|
38 | v = strptime(v) | |
41 | if k in ['user_id', 'repository_id']: |
|
39 | if k in ['user_id', 'repository_id']: |
@@ -7,7 +7,7 b' import mock' | |||||
7 | import pytest |
|
7 | import pytest | |
8 |
|
8 | |||
9 | from kallithea.lib import vcs |
|
9 | from kallithea.lib import vcs | |
10 |
from kallithea.lib.utils2 import safe_str |
|
10 | from kallithea.lib.utils2 import safe_str | |
11 | from kallithea.model.db import Permission, RepoGroup, Repository, Ui, User, UserRepoToPerm |
|
11 | from kallithea.model.db import Permission, RepoGroup, Repository, Ui, User, UserRepoToPerm | |
12 | from kallithea.model.meta import Session |
|
12 | from kallithea.model.meta import Session | |
13 | from kallithea.model.repo import RepoModel |
|
13 | from kallithea.model.repo import RepoModel | |
@@ -396,9 +396,7 b' class _BaseTestCase(base.TestController)' | |||||
396 | self.log_user() |
|
396 | self.log_user() | |
397 | non_ascii = "ąęł" |
|
397 | non_ascii = "ąęł" | |
398 | repo_name = "%s%s" % (safe_str(self.NEW_REPO), non_ascii) |
|
398 | repo_name = "%s%s" % (safe_str(self.NEW_REPO), non_ascii) | |
399 | repo_name_unicode = safe_unicode(repo_name) |
|
|||
400 | description = 'description for newly created repo' + non_ascii |
|
399 | description = 'description for newly created repo' + non_ascii | |
401 | description_unicode = safe_unicode(description) |
|
|||
402 | response = self.app.post(base.url('repos'), |
|
400 | response = self.app.post(base.url('repos'), | |
403 | fixture._get_repo_create_params(repo_private=False, |
|
401 | fixture._get_repo_create_params(repo_private=False, | |
404 | repo_name=repo_name, |
|
402 | repo_name=repo_name, | |
@@ -410,13 +408,13 b' class _BaseTestCase(base.TestController)' | |||||
410 | assert response.json == {u'result': True} |
|
408 | assert response.json == {u'result': True} | |
411 | self.checkSessionFlash(response, |
|
409 | self.checkSessionFlash(response, | |
412 | u'Created repository <a href="/%s">%s</a>' |
|
410 | u'Created repository <a href="/%s">%s</a>' | |
413 |
% (urllib.parse.quote(repo_name), repo_name |
|
411 | % (urllib.parse.quote(repo_name), repo_name)) | |
414 | # test if the repo was created in the database |
|
412 | # test if the repo was created in the database | |
415 | new_repo = Session().query(Repository) \ |
|
413 | new_repo = Session().query(Repository) \ | |
416 |
.filter(Repository.repo_name == repo_name |
|
414 | .filter(Repository.repo_name == repo_name).one() | |
417 |
|
415 | |||
418 |
assert new_repo.repo_name == repo_name |
|
416 | assert new_repo.repo_name == repo_name | |
419 |
assert new_repo.description == description |
|
417 | assert new_repo.description == description | |
420 |
|
418 | |||
421 | # test if the repository is visible in the list ? |
|
419 | # test if the repository is visible in the list ? | |
422 | response = self.app.get(base.url('summary_home', repo_name=repo_name)) |
|
420 | response = self.app.get(base.url('summary_home', repo_name=repo_name)) | |
@@ -425,22 +423,22 b' class _BaseTestCase(base.TestController)' | |||||
425 |
|
423 | |||
426 | # test if the repository was created on filesystem |
|
424 | # test if the repository was created on filesystem | |
427 | try: |
|
425 | try: | |
428 |
vcs.get_repo |
|
426 | vcs.get_repo(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name)) | |
429 | except vcs.exceptions.VCSError: |
|
427 | except vcs.exceptions.VCSError: | |
430 | pytest.fail('no repo %s in filesystem' % repo_name) |
|
428 | pytest.fail('no repo %s in filesystem' % repo_name) | |
431 |
|
429 | |||
432 | response = self.app.post(base.url('delete_repo', repo_name=repo_name), |
|
430 | response = self.app.post(base.url('delete_repo', repo_name=repo_name), | |
433 | params={'_session_csrf_secret_token': self.session_csrf_secret_token()}) |
|
431 | params={'_session_csrf_secret_token': self.session_csrf_secret_token()}) | |
434 |
self.checkSessionFlash(response, 'Deleted repository %s' % (repo_name |
|
432 | self.checkSessionFlash(response, 'Deleted repository %s' % (repo_name)) | |
435 | response.follow() |
|
433 | response.follow() | |
436 |
|
434 | |||
437 | # check if repo was deleted from db |
|
435 | # check if repo was deleted from db | |
438 | deleted_repo = Session().query(Repository) \ |
|
436 | deleted_repo = Session().query(Repository) \ | |
439 |
.filter(Repository.repo_name == repo_name |
|
437 | .filter(Repository.repo_name == repo_name).scalar() | |
440 |
|
438 | |||
441 | assert deleted_repo is None |
|
439 | assert deleted_repo is None | |
442 |
|
440 | |||
443 |
assert os.path.isdir(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name |
|
441 | assert os.path.isdir(os.path.join(Ui.get_by_key('paths', '/').ui_value, repo_name)) == False | |
444 |
|
442 | |||
445 | def test_delete_repo_with_group(self): |
|
443 | def test_delete_repo_with_group(self): | |
446 | # TODO: |
|
444 | # TODO: |
@@ -2,7 +2,7 b'' | |||||
2 |
|
2 | |||
3 | import urllib.parse |
|
3 | import urllib.parse | |
4 |
|
4 | |||
5 |
from kallithea.lib.utils2 import safe_str |
|
5 | from kallithea.lib.utils2 import safe_str | |
6 | from kallithea.model.db import Repository, User |
|
6 | from kallithea.model.db import Repository, User | |
7 | from kallithea.model.meta import Session |
|
7 | from kallithea.model.meta import Session | |
8 | from kallithea.model.repo import RepoModel |
|
8 | from kallithea.model.repo import RepoModel | |
@@ -161,7 +161,7 b' class _BaseTestCase(base.TestController)' | |||||
161 | response.mustcontain( |
|
161 | response.mustcontain( | |
162 | """<a href="/%s">%s</a>""" % (urllib.parse.quote(fork_name), fork_name) |
|
162 | """<a href="/%s">%s</a>""" % (urllib.parse.quote(fork_name), fork_name) | |
163 | ) |
|
163 | ) | |
164 |
fork_repo = Repository.get_by_repo_name( |
|
164 | fork_repo = Repository.get_by_repo_name(fork_name) | |
165 | assert fork_repo |
|
165 | assert fork_repo | |
166 |
|
166 | |||
167 | # fork the fork |
|
167 | # fork the fork |
@@ -79,8 +79,8 b' class _BackendTestMixin(object):' | |||||
79 | for node in commit.get('removed', []): |
|
79 | for node in commit.get('removed', []): | |
80 | cls.imc.remove(FileNode(node.path)) |
|
80 | cls.imc.remove(FileNode(node.path)) | |
81 |
|
81 | |||
82 |
cls.tip = cls.imc.commit(message= |
|
82 | cls.tip = cls.imc.commit(message=commit['message'], | |
83 |
author= |
|
83 | author=commit['author'], | |
84 | date=commit['date']) |
|
84 | date=commit['date']) | |
85 |
|
85 | |||
86 | @pytest.fixture(autouse=True) |
|
86 | @pytest.fixture(autouse=True) |
@@ -10,7 +10,6 b' import pytest' | |||||
10 | from kallithea.lib.vcs.exceptions import ( |
|
10 | from kallithea.lib.vcs.exceptions import ( | |
11 | EmptyRepositoryError, NodeAlreadyAddedError, NodeAlreadyChangedError, NodeAlreadyExistsError, NodeAlreadyRemovedError, NodeDoesNotExistError, NodeNotChangedError) |
|
11 | EmptyRepositoryError, NodeAlreadyAddedError, NodeAlreadyChangedError, NodeAlreadyExistsError, NodeAlreadyRemovedError, NodeDoesNotExistError, NodeNotChangedError) | |
12 | from kallithea.lib.vcs.nodes import DirNode, FileNode |
|
12 | from kallithea.lib.vcs.nodes import DirNode, FileNode | |
13 | from kallithea.lib.vcs.utils import safe_unicode |
|
|||
14 | from kallithea.tests.vcs.base import _BackendTestMixin |
|
13 | from kallithea.tests.vcs.base import _BackendTestMixin | |
15 |
|
14 | |||
16 |
|
15 | |||
@@ -169,13 +168,11 b' class InMemoryChangesetTestMixin(_Backen' | |||||
169 | # Change node's content |
|
168 | # Change node's content | |
170 | node = FileNode('żółwik/zwierzątko', content='My **changed** content') |
|
169 | node = FileNode('żółwik/zwierzątko', content='My **changed** content') | |
171 | self.imc.change(node) |
|
170 | self.imc.change(node) | |
172 |
self.imc.commit(u'Changed %s' % |
|
171 | self.imc.commit(u'Changed %s' % node.path, u'joe.doe@example.com') | |
173 | u'joe.doe@example.com') |
|
|||
174 |
|
172 | |||
175 | node = FileNode(u'żółwik/zwierzątko_uni', content=u'My **changed** content') |
|
173 | node = FileNode(u'żółwik/zwierzątko_uni', content=u'My **changed** content') | |
176 | self.imc.change(node) |
|
174 | self.imc.change(node) | |
177 |
self.imc.commit(u'Changed %s' % |
|
175 | self.imc.commit(u'Changed %s' % node.path, u'joe.doe@example.com') | |
178 | u'joe.doe@example.com') |
|
|||
179 |
|
176 | |||
180 | newtip = self.repo.get_changeset() |
|
177 | newtip = self.repo.get_changeset() | |
181 | assert tip != newtip |
|
178 | assert tip != newtip |
General Comments 0
You need to be logged in to leave comments.
Login now