Show More
@@ -252,7 +252,7 b' def request_view(request):' | |||||
252 | default_empty = types.NotImplementedType |
|
252 | default_empty = types.NotImplementedType | |
253 |
|
253 | |||
254 | # kw arguments required by this method |
|
254 | # kw arguments required by this method | |
255 |
func_kwargs = dict(itertools. |
|
255 | func_kwargs = dict(itertools.zip_longest( | |
256 | reversed(arglist), reversed(defaults), fillvalue=default_empty)) |
|
256 | reversed(arglist), reversed(defaults), fillvalue=default_empty)) | |
257 |
|
257 | |||
258 | # This attribute will need to be first param of a method that uses |
|
258 | # This attribute will need to be first param of a method that uses |
@@ -352,7 +352,7 b' def get_method(request, apiuser, pattern' | |||||
352 | default_empty = '<RequiredType>' |
|
352 | default_empty = '<RequiredType>' | |
353 |
|
353 | |||
354 | # kw arguments required by this method |
|
354 | # kw arguments required by this method | |
355 |
func_kwargs = dict(itertools. |
|
355 | func_kwargs = dict(itertools.zip_longest( | |
356 | reversed(arglist), reversed(defaults), fillvalue=default_empty)) |
|
356 | reversed(arglist), reversed(defaults), fillvalue=default_empty)) | |
357 | args_desc.append(func_kwargs) |
|
357 | args_desc.append(func_kwargs) | |
358 |
|
358 |
@@ -339,7 +339,7 b' class AdminPermissionsView(BaseAppView, ' | |||||
339 | mapper = self.request.registry.queryUtility(IRoutesMapper) |
|
339 | mapper = self.request.registry.queryUtility(IRoutesMapper) | |
340 | c.view_data = [] |
|
340 | c.view_data = [] | |
341 |
|
341 | |||
342 | _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)') |
|
342 | _argument_prog = re.compile(r'\{(.*?)\}|:\((.*)\)') | |
343 | introspector = self.request.registry.introspector |
|
343 | introspector = self.request.registry.introspector | |
344 |
|
344 | |||
345 | view_intr = {} |
|
345 | view_intr = {} |
@@ -18,9 +18,8 b'' | |||||
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 |
|
21 | import io | ||
22 | import uuid |
|
22 | import uuid | |
23 | from io import StringIO |
|
|||
24 | import pathlib2 |
|
23 | import pathlib2 | |
25 |
|
24 | |||
26 |
|
25 | |||
@@ -55,4 +54,4 b' def uid_filename(filename, randomized=Tr' | |||||
55 |
|
54 | |||
56 |
|
55 | |||
57 | def bytes_to_file_obj(bytes_data): |
|
56 | def bytes_to_file_obj(bytes_data): | |
58 |
return |
|
57 | return io.StringIO(bytes_data) |
@@ -147,7 +147,7 b' class TestLoginController(object):' | |||||
147 | h.route_path('repo_summary', repo_name=HG_REPO, _query=kwargs), |
|
147 | h.route_path('repo_summary', repo_name=HG_REPO, _query=kwargs), | |
148 | status=302) |
|
148 | status=302) | |
149 |
|
149 | |||
150 |
response_query = urllib.parse. |
|
150 | response_query = urllib.parse.parse_qsl(response.location) | |
151 | assert 'branch=stable' in response_query[0][1] |
|
151 | assert 'branch=stable' in response_query[0][1] | |
152 |
|
152 | |||
153 | def test_login_form_with_get_args(self): |
|
153 | def test_login_form_with_get_args(self): |
@@ -753,7 +753,7 b' class RepoPullRequestsView(RepoAppView, ' | |||||
753 | c.commit_changes = [] |
|
753 | c.commit_changes = [] | |
754 |
|
754 | |||
755 | def mark(cs, fw): |
|
755 | def mark(cs, fw): | |
756 |
return list(h.itertools. |
|
756 | return list(h.itertools.zip_longest([], cs, fillvalue=fw)) | |
757 |
|
757 | |||
758 | for c_type, raw_id in mark(commit_changes.added, 'a') \ |
|
758 | for c_type, raw_id in mark(commit_changes.added, 'a') \ | |
759 | + mark(commit_changes.removed, 'r') \ |
|
759 | + mark(commit_changes.removed, 'r') \ |
@@ -39,8 +39,6 b' log = logging.getLogger(__name__)' | |||||
39 | class RepoSettingsIssueTrackersView(RepoAppView): |
|
39 | class RepoSettingsIssueTrackersView(RepoAppView): | |
40 | def load_default_context(self): |
|
40 | def load_default_context(self): | |
41 | c = self._get_local_tmpl_context() |
|
41 | c = self._get_local_tmpl_context() | |
42 |
|
||||
43 |
|
||||
44 | return c |
|
42 | return c | |
45 |
|
43 | |||
46 | @LoginRequired() |
|
44 | @LoginRequired() |
@@ -192,7 +192,7 b' class RepoSummaryView(RepoAppView):' | |||||
192 | size += node.size |
|
192 | size += node.size | |
193 | if not _show_stats: |
|
193 | if not _show_stats: | |
194 | continue |
|
194 | continue | |
195 |
ext = |
|
195 | ext = node.extension.lower() | |
196 | ext_info = LANGUAGES_EXTENSIONS_MAP.get(ext) |
|
196 | ext_info = LANGUAGES_EXTENSIONS_MAP.get(ext) | |
197 | if ext_info: |
|
197 | if ext_info: | |
198 | if ext in code_stats: |
|
198 | if ext in code_stats: |
@@ -63,7 +63,7 b' class PamSettingsSchema(AuthnPluginSetti' | |||||
63 | widget='string') |
|
63 | widget='string') | |
64 | gecos = colander.SchemaNode( |
|
64 | gecos = colander.SchemaNode( | |
65 | colander.String(), |
|
65 | colander.String(), | |
66 | default='(?P<last_name>.+),\s*(?P<first_name>\w+)', |
|
66 | default=r'(?P<last_name>.+),\s*(?P<first_name>\w+)', | |
67 | description=_('Regular expression for extracting user name/email etc. ' |
|
67 | description=_('Regular expression for extracting user name/email etc. ' | |
68 | 'from Unix userinfo.'), |
|
68 | 'from Unix userinfo.'), | |
69 | preparer=strip_whitespace, |
|
69 | preparer=strip_whitespace, |
@@ -21,6 +21,7 b'' | |||||
21 | import os |
|
21 | import os | |
22 | import logging |
|
22 | import logging | |
23 | import rhodecode |
|
23 | import rhodecode | |
|
24 | import collections | |||
24 |
|
25 | |||
25 | from rhodecode.config import utils |
|
26 | from rhodecode.config import utils | |
26 |
|
27 | |||
@@ -67,7 +68,7 b' def load_pyramid_environment(global_conf' | |||||
67 |
|
68 | |||
68 | _sorted_backend = sorted(rhodecode.BACKENDS.items(), |
|
69 | _sorted_backend = sorted(rhodecode.BACKENDS.items(), | |
69 | key=lambda item: settings['vcs.backends'].index(item[0])) |
|
70 | key=lambda item: settings['vcs.backends'].index(item[0])) | |
70 |
rhodecode.BACKENDS = |
|
71 | rhodecode.BACKENDS = collections.OrderedDict(_sorted_backend) | |
71 |
|
72 | |||
72 | log.info('Enabled VCS backends: %s', rhodecode.BACKENDS.keys()) |
|
73 | log.info('Enabled VCS backends: %s', rhodecode.BACKENDS.keys()) | |
73 |
|
74 |
@@ -59,7 +59,7 b' import abc' | |||||
59 | from authomatic.core import Response |
|
59 | from authomatic.core import Response | |
60 |
|
60 | |||
61 |
|
61 | |||
62 | class BaseAdapter(object): |
|
62 | class BaseAdapter(object, metaclass=abc.ABCMeta): | |
63 | """ |
|
63 | """ | |
64 | Base class for platform adapters. |
|
64 | Base class for platform adapters. | |
65 |
|
65 | |||
@@ -67,8 +67,6 b' class BaseAdapter(object):' | |||||
67 |
|
67 | |||
68 | """ |
|
68 | """ | |
69 |
|
69 | |||
70 | __metaclass__ = abc.ABCMeta |
|
|||
71 |
|
||||
72 | @abc.abstractproperty |
|
70 | @abc.abstractproperty | |
73 | def params(self): |
|
71 | def params(self): | |
74 | """ |
|
72 | """ |
@@ -139,13 +139,13 b' def _store_log(action_name, action_data,' | |||||
139 | user_log.version = UserLog.VERSION_2 |
|
139 | user_log.version = UserLog.VERSION_2 | |
140 |
|
140 | |||
141 | user_log.action = action_name |
|
141 | user_log.action = action_name | |
142 |
user_log.action_data = action_data or JsonRaw( |
|
142 | user_log.action_data = action_data or JsonRaw('{}') | |
143 |
|
143 | |||
144 | user_log.user_ip = ip_address |
|
144 | user_log.user_ip = ip_address | |
145 |
|
145 | |||
146 | user_log.user_id = user_id |
|
146 | user_log.user_id = user_id | |
147 | user_log.username = username |
|
147 | user_log.username = username | |
148 |
user_log.user_data = user_data or JsonRaw( |
|
148 | user_log.user_data = user_data or JsonRaw('{}') | |
149 |
|
149 | |||
150 | user_log.repository_id = repository_id |
|
150 | user_log.repository_id = repository_id | |
151 | user_log.repository_name = repository_name |
|
151 | user_log.repository_name = repository_name |
@@ -293,11 +293,11 b' def pr_channel(pull_request):' | |||||
293 | def comment_channel(repo_name, commit_obj=None, pull_request_obj=None): |
|
293 | def comment_channel(repo_name, commit_obj=None, pull_request_obj=None): | |
294 | channel = None |
|
294 | channel = None | |
295 | if commit_obj: |
|
295 | if commit_obj: | |
296 |
channel = |
|
296 | channel = '/repo${}$/commit/{}'.format( | |
297 | repo_name, commit_obj.raw_id |
|
297 | repo_name, commit_obj.raw_id | |
298 | ) |
|
298 | ) | |
299 | elif pull_request_obj: |
|
299 | elif pull_request_obj: | |
300 |
channel = |
|
300 | channel = '/repo${}$/pr/{}'.format( | |
301 | repo_name, pull_request_obj.pull_request_id |
|
301 | repo_name, pull_request_obj.pull_request_id | |
302 | ) |
|
302 | ) | |
303 | log.debug('Getting comment channelstream broadcast channel: %s', channel) |
|
303 | log.debug('Getting comment channelstream broadcast channel: %s', channel) |
@@ -158,14 +158,14 b' def render_tokenstream(tokenstream):' | |||||
158 | for token_class, token_ops_texts in rollup_tokenstream(tokenstream): |
|
158 | for token_class, token_ops_texts in rollup_tokenstream(tokenstream): | |
159 |
|
159 | |||
160 | if token_class: |
|
160 | if token_class: | |
161 |
result.append( |
|
161 | result.append('<span class="%s">' % token_class) | |
162 | else: |
|
162 | else: | |
163 |
result.append( |
|
163 | result.append('<span>') | |
164 |
|
164 | |||
165 | for op_tag, token_text in token_ops_texts: |
|
165 | for op_tag, token_text in token_ops_texts: | |
166 |
|
166 | |||
167 | if op_tag: |
|
167 | if op_tag: | |
168 |
result.append( |
|
168 | result.append('<%s>' % op_tag) | |
169 |
|
169 | |||
170 | # NOTE(marcink): in some cases of mixed encodings, we might run into |
|
170 | # NOTE(marcink): in some cases of mixed encodings, we might run into | |
171 | # troubles in the html_escape, in this case we say unicode force on token_text |
|
171 | # troubles in the html_escape, in this case we say unicode force on token_text | |
@@ -183,9 +183,9 b' def render_tokenstream(tokenstream):' | |||||
183 | result.append(escaped_text) |
|
183 | result.append(escaped_text) | |
184 |
|
184 | |||
185 | if op_tag: |
|
185 | if op_tag: | |
186 |
result.append( |
|
186 | result.append('</%s>' % op_tag) | |
187 |
|
187 | |||
188 |
result.append( |
|
188 | result.append('</span>') | |
189 |
|
189 | |||
190 | html = ''.join(result) |
|
190 | html = ''.join(result) | |
191 | return html |
|
191 | return html | |
@@ -555,20 +555,20 b' class DiffSet(object):' | |||||
555 | actions = [] |
|
555 | actions = [] | |
556 | for op_id, op_text in filediff.patch['stats']['ops'].items(): |
|
556 | for op_id, op_text in filediff.patch['stats']['ops'].items(): | |
557 | if op_id == DEL_FILENODE: |
|
557 | if op_id == DEL_FILENODE: | |
558 |
actions.append( |
|
558 | actions.append('file was removed') | |
559 | elif op_id == BIN_FILENODE: |
|
559 | elif op_id == BIN_FILENODE: | |
560 |
actions.append( |
|
560 | actions.append('binary diff hidden') | |
561 | else: |
|
561 | else: | |
562 | actions.append(safe_unicode(op_text)) |
|
562 | actions.append(safe_unicode(op_text)) | |
563 |
action_line = |
|
563 | action_line = 'NO CONTENT: ' + \ | |
564 |
|
|
564 | ', '.join(actions) or 'UNDEFINED_ACTION' | |
565 |
|
565 | |||
566 | hunk_ops = {'source_length': 0, 'source_start': 0, |
|
566 | hunk_ops = {'source_length': 0, 'source_start': 0, | |
567 | 'lines': [ |
|
567 | 'lines': [ | |
568 | {'new_lineno': 0, 'old_lineno': 1, |
|
568 | {'new_lineno': 0, 'old_lineno': 1, | |
569 | 'action': 'unmod-no-hl', 'line': action_line} |
|
569 | 'action': 'unmod-no-hl', 'line': action_line} | |
570 | ], |
|
570 | ], | |
571 |
'section_header': |
|
571 | 'section_header': '', 'target_start': 1, 'target_length': 1} | |
572 |
|
572 | |||
573 | hunkbit = self.parse_hunk(hunk_ops, source_file, target_file) |
|
573 | hunkbit = self.parse_hunk(hunk_ops, source_file, target_file) | |
574 | hunkbit.source_file_path = source_file_path |
|
574 | hunkbit.source_file_path = source_file_path | |
@@ -742,7 +742,7 b' class DiffSet(object):' | |||||
742 | return self.highlighted_filenodes[source][filenode][line_number - 1] |
|
742 | return self.highlighted_filenodes[source][filenode][line_number - 1] | |
743 | except Exception: |
|
743 | except Exception: | |
744 | log.exception('diff rendering error') |
|
744 | log.exception('diff rendering error') | |
745 |
return [('', |
|
745 | return [('', 'L{}: rhodecode diff rendering error'.format(line_number))] | |
746 |
|
746 | |||
747 | def action_to_op(self, action): |
|
747 | def action_to_op(self, action): | |
748 | return { |
|
748 | return { |
@@ -269,7 +269,7 b' class DbManage(object):' | |||||
269 | email = defaults.get('email') |
|
269 | email = defaults.get('email') | |
270 |
|
270 | |||
271 | if username is None: |
|
271 | if username is None: | |
272 | username = input('Specify admin username:') |
|
272 | username = eval(input('Specify admin username:')) | |
273 | if password is None: |
|
273 | if password is None: | |
274 | password = self._get_admin_password() |
|
274 | password = self._get_admin_password() | |
275 | if not password: |
|
275 | if not password: | |
@@ -278,7 +278,7 b' class DbManage(object):' | |||||
278 | if not password: |
|
278 | if not password: | |
279 | sys.exit() |
|
279 | sys.exit() | |
280 | if email is None: |
|
280 | if email is None: | |
281 | email = input('Specify admin email:') |
|
281 | email = eval(input('Specify admin email:')) | |
282 | api_key = self.cli_args.get('api_key') |
|
282 | api_key = self.cli_args.get('api_key') | |
283 | self.create_user(username, password, email, True, |
|
283 | self.create_user(username, password, email, True, | |
284 | strict_creation_check=False, |
|
284 | strict_creation_check=False, | |
@@ -517,10 +517,10 b' class DbManage(object):' | |||||
517 | if _path is not None: |
|
517 | if _path is not None: | |
518 | path = _path |
|
518 | path = _path | |
519 | elif not self.tests and not test_repo_path: |
|
519 | elif not self.tests and not test_repo_path: | |
520 | path = input( |
|
520 | path = eval(input( | |
521 | 'Enter a valid absolute path to store repositories. ' |
|
521 | 'Enter a valid absolute path to store repositories. ' | |
522 | 'All repositories in that path will be added automatically:' |
|
522 | 'All repositories in that path will be added automatically:' | |
523 | ) |
|
523 | )) | |
524 | else: |
|
524 | else: | |
525 | path = test_repo_path |
|
525 | path = test_repo_path | |
526 | path_ok = True |
|
526 | path_ok = True | |
@@ -634,7 +634,7 b' class DbManage(object):' | |||||
634 | strict_creation_check=True, api_key=None): |
|
634 | strict_creation_check=True, api_key=None): | |
635 | log.info('creating user `%s`', username) |
|
635 | log.info('creating user `%s`', username) | |
636 | user = UserModel().create_or_update( |
|
636 | user = UserModel().create_or_update( | |
637 |
username, password, email, firstname= |
|
637 | username, password, email, firstname='RhodeCode', lastname='Admin', | |
638 | active=True, admin=admin, extern_type="rhodecode", |
|
638 | active=True, admin=admin, extern_type="rhodecode", | |
639 | strict_creation_check=strict_creation_check) |
|
639 | strict_creation_check=strict_creation_check) | |
640 |
|
640 | |||
@@ -643,7 +643,7 b' class DbManage(object):' | |||||
643 | UserModel().add_auth_token( |
|
643 | UserModel().add_auth_token( | |
644 | user=user, lifetime_minutes=-1, |
|
644 | user=user, lifetime_minutes=-1, | |
645 | role=UserModel.auth_token_role.ROLE_ALL, |
|
645 | role=UserModel.auth_token_role.ROLE_ALL, | |
646 |
description= |
|
646 | description='BUILTIN TOKEN') | |
647 |
|
647 | |||
648 | def create_default_user(self): |
|
648 | def create_default_user(self): | |
649 | log.info('creating default user') |
|
649 | log.info('creating default user') | |
@@ -651,11 +651,11 b' class DbManage(object):' | |||||
651 | user = UserModel().create_or_update(username=User.DEFAULT_USER, |
|
651 | user = UserModel().create_or_update(username=User.DEFAULT_USER, | |
652 | password=str(uuid.uuid1())[:20], |
|
652 | password=str(uuid.uuid1())[:20], | |
653 | email=User.DEFAULT_USER_EMAIL, |
|
653 | email=User.DEFAULT_USER_EMAIL, | |
654 |
firstname= |
|
654 | firstname='Anonymous', | |
655 |
lastname= |
|
655 | lastname='User', | |
656 | strict_creation_check=False) |
|
656 | strict_creation_check=False) | |
657 | # based on configuration options activate/de-activate this user which |
|
657 | # based on configuration options activate/de-activate this user which | |
658 |
# control |
|
658 | # controls anonymous access | |
659 | if self.cli_args.get('public_access') is False: |
|
659 | if self.cli_args.get('public_access') is False: | |
660 | log.info('Public access disabled') |
|
660 | log.info('Public access disabled') | |
661 | user.active = False |
|
661 | user.active = False |
@@ -1920,7 +1920,7 b' class diff_match_patch:' | |||||
1920 | Raises: |
|
1920 | Raises: | |
1921 | ValueError: If invalid input. |
|
1921 | ValueError: If invalid input. | |
1922 | """ |
|
1922 | """ | |
1923 |
if type(textline) == |
|
1923 | if type(textline) == str: | |
1924 | # Patches should be composed of a subset of ascii chars, Unicode not |
|
1924 | # Patches should be composed of a subset of ascii chars, Unicode not | |
1925 | # required. If this encode raises UnicodeEncodeError, patch is invalid. |
|
1925 | # required. If this encode raises UnicodeEncodeError, patch is invalid. | |
1926 | textline = textline.encode("ascii") |
|
1926 | textline = textline.encode("ascii") |
@@ -73,8 +73,7 b' def get_gitdiff(filenode_old, filenode_n' | |||||
73 | if context > MAX_CONTEXT: |
|
73 | if context > MAX_CONTEXT: | |
74 | context = MAX_CONTEXT |
|
74 | context = MAX_CONTEXT | |
75 |
|
75 | |||
76 |
submodules = |
|
76 | submodules = [o for o in [filenode_new, filenode_old] if isinstance(o, SubModuleNode)] | |
77 | [filenode_new, filenode_old]) |
|
|||
78 | if submodules: |
|
77 | if submodules: | |
79 | return '' |
|
78 | return '' | |
80 |
|
79 | |||
@@ -847,7 +846,7 b' class DiffProcessor(object):' | |||||
847 | if not string: |
|
846 | if not string: | |
848 | return |
|
847 | return | |
849 | elif string == '\n': |
|
848 | elif string == '\n': | |
850 |
yield |
|
849 | yield '\n' | |
851 | else: |
|
850 | else: | |
852 |
|
851 | |||
853 | has_newline = string.endswith('\n') |
|
852 | has_newline = string.endswith('\n') |
@@ -33,7 +33,7 b' http://web.archive.org/web/2011071803522' | |||||
33 |
|
33 | |||
34 |
|
34 | |||
35 | import datetime |
|
35 | import datetime | |
36 | from io import StringIO |
|
36 | import io | |
37 |
|
37 | |||
38 | import pytz |
|
38 | import pytz | |
39 | from six.moves.urllib import parse as urlparse |
|
39 | from six.moves.urllib import parse as urlparse | |
@@ -207,7 +207,7 b' class SyndicationFeed(object):' | |||||
207 | """ |
|
207 | """ | |
208 | Returns the feed in the given encoding as a string. |
|
208 | Returns the feed in the given encoding as a string. | |
209 | """ |
|
209 | """ | |
210 | s = StringIO() |
|
210 | s = io.StringIO() | |
211 | self.write(s, encoding) |
|
211 | self.write(s, encoding) | |
212 | return s.getvalue() |
|
212 | return s.getvalue() | |
213 |
|
213 |
@@ -94,7 +94,7 b' def _get_scm_size(alias, root_path):' | |||||
94 | def repo_size(extras): |
|
94 | def repo_size(extras): | |
95 | """Present size of repository after push.""" |
|
95 | """Present size of repository after push.""" | |
96 | repo = Repository.get_by_repo_name(extras.repository) |
|
96 | repo = Repository.get_by_repo_name(extras.repository) | |
97 |
vcs_part = safe_str( |
|
97 | vcs_part = safe_str('.%s' % repo.repo_type) | |
98 | size_vcs, size_root, size_total = _get_scm_size(vcs_part, |
|
98 | size_vcs, size_root, size_total = _get_scm_size(vcs_part, | |
99 | repo.repo_full_path) |
|
99 | repo.repo_full_path) | |
100 | msg = ('Repository `%s` size summary %s:%s repo:%s total:%s\n' |
|
100 | msg = ('Repository `%s` size summary %s:%s repo:%s total:%s\n' |
@@ -22,7 +22,7 b' import sys' | |||||
22 | import logging |
|
22 | import logging | |
23 |
|
23 | |||
24 |
|
24 | |||
25 | BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(30, 38) |
|
25 | BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = list(range(30, 38)) | |
26 |
|
26 | |||
27 | # Sequences |
|
27 | # Sequences | |
28 | RESET_SEQ = "\033[0m" |
|
28 | RESET_SEQ = "\033[0m" |
@@ -138,7 +138,7 b' def relative_path(path, request_path, is' | |||||
138 | path = safe_unicode(path) |
|
138 | path = safe_unicode(path) | |
139 | request_path = safe_unicode(request_path) |
|
139 | request_path = safe_unicode(request_path) | |
140 |
|
140 | |||
141 |
if path.startswith(( |
|
141 | if path.startswith(('data:', 'javascript:', '#', ':')): | |
142 | # skip data, anchor, invalid links |
|
142 | # skip data, anchor, invalid links | |
143 | return path |
|
143 | return path | |
144 |
|
144 | |||
@@ -149,10 +149,10 b' def relative_path(path, request_path, is' | |||||
149 | if not request_path: |
|
149 | if not request_path: | |
150 | return path |
|
150 | return path | |
151 |
|
151 | |||
152 |
if path.startswith( |
|
152 | if path.startswith('/'): | |
153 | path = path[1:] |
|
153 | path = path[1:] | |
154 |
|
154 | |||
155 |
if path.startswith( |
|
155 | if path.startswith('./'): | |
156 | path = path[2:] |
|
156 | path = path[2:] | |
157 |
|
157 | |||
158 | parts = request_path.split('/') |
|
158 | parts = request_path.split('/') | |
@@ -164,7 +164,7 b' def relative_path(path, request_path, is' | |||||
164 | # one level up |
|
164 | # one level up | |
165 | depth += 1 |
|
165 | depth += 1 | |
166 |
|
166 | |||
167 |
while path.startswith( |
|
167 | while path.startswith('../'): | |
168 | depth += 1 |
|
168 | depth += 1 | |
169 | path = path[3:] |
|
169 | path = path[3:] | |
170 |
|
170 | |||
@@ -172,9 +172,9 b' def relative_path(path, request_path, is' | |||||
172 | parts = parts[:-depth] |
|
172 | parts = parts[:-depth] | |
173 |
|
173 | |||
174 | parts.append(path) |
|
174 | parts.append(path) | |
175 |
final_path = |
|
175 | final_path = '/'.join(parts).lstrip('/') | |
176 |
|
176 | |||
177 |
return |
|
177 | return '/' + final_path | |
178 |
|
178 | |||
179 |
|
179 | |||
180 | _cached_markdown_renderer = None |
|
180 | _cached_markdown_renderer = None |
@@ -123,7 +123,7 b' class SimpleGit(simplevcs.SimpleVCS):' | |||||
123 | path = environ['PATH_INFO'] |
|
123 | path = environ['PATH_INFO'] | |
124 |
|
124 | |||
125 | if path.endswith('/info/refs'): |
|
125 | if path.endswith('/info/refs'): | |
126 |
query = urllib.parse |
|
126 | query = urllib.parse.parse_qs(environ['QUERY_STRING']) | |
127 | service_cmd = query.get('service', [''])[0] |
|
127 | service_cmd = query.get('service', [''])[0] | |
128 | return self._ACTION_MAPPING.get(service_cmd, 'pull') |
|
128 | return self._ACTION_MAPPING.get(service_cmd, 'pull') | |
129 |
|
129 |
@@ -135,8 +135,7 b' class SimpleHg(simplevcs.SimpleVCS):' | |||||
135 | :param environ: |
|
135 | :param environ: | |
136 | """ |
|
136 | """ | |
137 | default = 'push' |
|
137 | default = 'push' | |
138 |
query = urllib.parse. |
|
138 | query = urllib.parse.parse_qs(environ['QUERY_STRING'], keep_blank_values=True) | |
139 | keep_blank_values=True) |
|
|||
140 |
|
139 | |||
141 | if 'cmd' in query: |
|
140 | if 'cmd' in query: | |
142 | cmd = query['cmd'][0] |
|
141 | cmd = query['cmd'][0] |
@@ -25,10 +25,10 b" It's implemented with basic auth functio" | |||||
25 |
|
25 | |||
26 | import os |
|
26 | import os | |
27 | import re |
|
27 | import re | |
|
28 | import io | |||
28 | import logging |
|
29 | import logging | |
29 | import importlib |
|
30 | import importlib | |
30 | from functools import wraps |
|
31 | from functools import wraps | |
31 | from io import StringIO |
|
|||
32 | from lxml import etree |
|
32 | from lxml import etree | |
33 |
|
33 | |||
34 | import time |
|
34 | import time | |
@@ -124,7 +124,7 b' class SimpleVCS(object):' | |||||
124 | shadow_repo_re = re.compile( |
|
124 | shadow_repo_re = re.compile( | |
125 | '(?P<groups>(?:{slug_pat}/)*)' # repo groups |
|
125 | '(?P<groups>(?:{slug_pat}/)*)' # repo groups | |
126 | '(?P<target>{slug_pat})/' # target repo |
|
126 | '(?P<target>{slug_pat})/' # target repo | |
127 | 'pull-request/(?P<pr_id>\d+)/' # pull request |
|
127 | 'pull-request/(?P<pr_id>\\d+)/' # pull request | |
128 | 'repository$' # shadow repo |
|
128 | 'repository$' # shadow repo | |
129 | .format(slug_pat=SLUG_RE.pattern)) |
|
129 | .format(slug_pat=SLUG_RE.pattern)) | |
130 |
|
130 | |||
@@ -595,7 +595,7 b' class SimpleVCS(object):' | |||||
595 | # so we use the txn_id, for this we peek the body, and still save |
|
595 | # so we use the txn_id, for this we peek the body, and still save | |
596 | # it as wsgi.input |
|
596 | # it as wsgi.input | |
597 | data = environ['wsgi.input'].read() |
|
597 | data = environ['wsgi.input'].read() | |
598 | environ['wsgi.input'] = StringIO(data) |
|
598 | environ['wsgi.input'] = io.StringIO(data) | |
599 | txn_id = extract_svn_txn_id(self.acl_repo_name, data) |
|
599 | txn_id = extract_svn_txn_id(self.acl_repo_name, data) | |
600 |
|
600 | |||
601 | callback_daemon, extras = self._prepare_callback_daemon( |
|
601 | callback_daemon, extras = self._prepare_callback_daemon( |
@@ -61,7 +61,7 b' def is_hg(environ):' | |||||
61 | http_accept = environ.get('HTTP_ACCEPT') |
|
61 | http_accept = environ.get('HTTP_ACCEPT') | |
62 |
|
62 | |||
63 | if http_accept and http_accept.startswith('application/mercurial'): |
|
63 | if http_accept and http_accept.startswith('application/mercurial'): | |
64 |
query = urllib.parse |
|
64 | query = urllib.parse.parse_qs(environ['QUERY_STRING']) | |
65 | if 'cmd' in query: |
|
65 | if 'cmd' in query: | |
66 | is_hg_path = True |
|
66 | is_hg_path = True | |
67 |
|
67 |
@@ -146,14 +146,14 b' def make_html_tag(tag, text=None, **para' | |||||
146 | # to be used as a CSS class specification instead of the reserved Python keyword 'class'. |
|
146 | # to be used as a CSS class specification instead of the reserved Python keyword 'class'. | |
147 | key = key.lstrip("_") |
|
147 | key = key.lstrip("_") | |
148 |
|
148 | |||
149 |
params_string += |
|
149 | params_string += ' {0}="{1}"'.format(key, value) | |
150 |
|
150 | |||
151 | # Create the tag string |
|
151 | # Create the tag string | |
152 |
tag_string = |
|
152 | tag_string = "<{0}{1}>".format(tag, params_string) | |
153 |
|
153 | |||
154 | # Add text and closing tag if required. |
|
154 | # Add text and closing tag if required. | |
155 | if text: |
|
155 | if text: | |
156 |
tag_string += |
|
156 | tag_string += "{0}</{1}>".format(text, tag) | |
157 |
|
157 | |||
158 | return tag_string |
|
158 | return tag_string | |
159 |
|
159 | |||
@@ -552,13 +552,13 b' class _Page(list):' | |||||
552 |
|
552 | |||
553 | def _get_edges(self, cur_page, max_page, items): |
|
553 | def _get_edges(self, cur_page, max_page, items): | |
554 | cur_page = int(cur_page) |
|
554 | cur_page = int(cur_page) | |
555 | edge = (items / 2) + 1 |
|
555 | edge = (items // 2) + 1 | |
556 | if cur_page <= edge: |
|
556 | if cur_page <= edge: | |
557 | radius = max(items / 2, items - cur_page) |
|
557 | radius = max(items // 2, items - cur_page) | |
558 | elif (max_page - cur_page) < edge: |
|
558 | elif (max_page - cur_page) < edge: | |
559 | radius = (items - 1) - (max_page - cur_page) |
|
559 | radius = (items - 1) - (max_page - cur_page) | |
560 | else: |
|
560 | else: | |
561 | radius = (items / 2) - 1 |
|
561 | radius = (items // 2) - 1 | |
562 |
|
562 | |||
563 | left = max(1, (cur_page - radius)) |
|
563 | left = max(1, (cur_page - radius)) | |
564 | right = min(max_page, cur_page + radius) |
|
564 | right = min(max_page, cur_page + radius) | |
@@ -726,7 +726,7 b' class _Page(list):' | |||||
726 |
|
726 | |||
727 | nav_items["first_page"] = { |
|
727 | nav_items["first_page"] = { | |
728 | "type": "first_page", |
|
728 | "type": "first_page", | |
729 |
"value": |
|
729 | "value": str(symbol_first), | |
730 | "attrs": self.link_attr, |
|
730 | "attrs": self.link_attr, | |
731 | "number": self.first_page, |
|
731 | "number": self.first_page, | |
732 | "href": self.url_maker(self.first_page), |
|
732 | "href": self.url_maker(self.first_page), | |
@@ -753,7 +753,7 b' class _Page(list):' | |||||
753 | nav_items["range_pages"].append( |
|
753 | nav_items["range_pages"].append( | |
754 | { |
|
754 | { | |
755 | "type": "current_page", |
|
755 | "type": "current_page", | |
756 |
"value": |
|
756 | "value": str(this_page), | |
757 | "number": this_page, |
|
757 | "number": this_page, | |
758 | "attrs": self.curpage_attr, |
|
758 | "attrs": self.curpage_attr, | |
759 | "href": self.url_maker(this_page), |
|
759 | "href": self.url_maker(this_page), | |
@@ -770,7 +770,7 b' class _Page(list):' | |||||
770 | nav_items["range_pages"].append( |
|
770 | nav_items["range_pages"].append( | |
771 | { |
|
771 | { | |
772 | "type": "page", |
|
772 | "type": "page", | |
773 |
"value": |
|
773 | "value": str(this_page), | |
774 | "number": this_page, |
|
774 | "number": this_page, | |
775 | "attrs": self.link_attr, |
|
775 | "attrs": self.link_attr, | |
776 | "href": self.url_maker(this_page), |
|
776 | "href": self.url_maker(this_page), | |
@@ -795,7 +795,7 b' class _Page(list):' | |||||
795 | # page or there would be no need to insert '..' spacers) |
|
795 | # page or there would be no need to insert '..' spacers) | |
796 | nav_items["last_page"] = { |
|
796 | nav_items["last_page"] = { | |
797 | "type": "last_page", |
|
797 | "type": "last_page", | |
798 |
"value": |
|
798 | "value": str(symbol_last), | |
799 | "attrs": self.link_attr, |
|
799 | "attrs": self.link_attr, | |
800 | "href": self.url_maker(self.last_page), |
|
800 | "href": self.url_maker(self.last_page), | |
801 | "number": self.last_page, |
|
801 | "number": self.last_page, | |
@@ -803,7 +803,7 b' class _Page(list):' | |||||
803 |
|
803 | |||
804 | nav_items["previous_page"] = { |
|
804 | nav_items["previous_page"] = { | |
805 | "type": "previous_page", |
|
805 | "type": "previous_page", | |
806 |
"value": |
|
806 | "value": str(symbol_previous), | |
807 | "attrs": self.link_attr, |
|
807 | "attrs": self.link_attr, | |
808 | "number": self.previous_page or self.first_page, |
|
808 | "number": self.previous_page or self.first_page, | |
809 | "href": self.url_maker(self.previous_page or self.first_page), |
|
809 | "href": self.url_maker(self.previous_page or self.first_page), | |
@@ -811,7 +811,7 b' class _Page(list):' | |||||
811 |
|
811 | |||
812 | nav_items["next_page"] = { |
|
812 | nav_items["next_page"] = { | |
813 | "type": "next_page", |
|
813 | "type": "next_page", | |
814 |
"value": |
|
814 | "value": str(symbol_next), | |
815 | "attrs": self.link_attr, |
|
815 | "attrs": self.link_attr, | |
816 | "number": self.next_page or self.last_page, |
|
816 | "number": self.next_page or self.last_page, | |
817 | "href": self.url_maker(self.next_page or self.last_page), |
|
817 | "href": self.url_maker(self.next_page or self.last_page), | |
@@ -835,7 +835,7 b' class _Page(list):' | |||||
835 | # or there would be no need to insert '..' spacers) |
|
835 | # or there would be no need to insert '..' spacers) | |
836 | if self.first_page and self.page != self.first_page and self.first_page < leftmost_page: |
|
836 | if self.first_page and self.page != self.first_page and self.first_page < leftmost_page: | |
837 | page = link_map["first_page"].copy() |
|
837 | page = link_map["first_page"].copy() | |
838 |
page["value"] = |
|
838 | page["value"] = str(page["number"]) | |
839 | nav_items.append(self.link_tag(page)) |
|
839 | nav_items.append(self.link_tag(page)) | |
840 |
|
840 | |||
841 | for item in link_map["range_pages"]: |
|
841 | for item in link_map["range_pages"]: | |
@@ -845,7 +845,7 b' class _Page(list):' | |||||
845 | # page or there would be no need to insert '..' spacers) |
|
845 | # page or there would be no need to insert '..' spacers) | |
846 | if self.last_page and self.page != self.last_page and rightmost_page < self.last_page: |
|
846 | if self.last_page and self.page != self.last_page and rightmost_page < self.last_page: | |
847 | page = link_map["last_page"].copy() |
|
847 | page = link_map["last_page"].copy() | |
848 |
page["value"] = |
|
848 | page["value"] = str(page["number"]) | |
849 | nav_items.append(self.link_tag(page)) |
|
849 | nav_items.append(self.link_tag(page)) | |
850 |
|
850 | |||
851 | return self.separator.join(nav_items) |
|
851 | return self.separator.join(nav_items) | |
@@ -859,7 +859,7 b' class _Page(list):' | |||||
859 | if "$page" not in self.url: |
|
859 | if "$page" not in self.url: | |
860 | raise Exception("The 'url' parameter must contain a '$page' placeholder.") |
|
860 | raise Exception("The 'url' parameter must contain a '$page' placeholder.") | |
861 |
|
861 | |||
862 |
return self.url.replace("$page", |
|
862 | return self.url.replace("$page", str(page_number)) | |
863 |
|
863 | |||
864 | @staticmethod |
|
864 | @staticmethod | |
865 | def default_link_tag(item): |
|
865 | def default_link_tag(item): |
@@ -175,7 +175,7 b' class MemcachedAuthSessions(BaseAuthSess' | |||||
175 | try: |
|
175 | try: | |
176 | slabs = [] |
|
176 | slabs = [] | |
177 | for server, slabs_data in client.get_slabs(): |
|
177 | for server, slabs_data in client.get_slabs(): | |
178 | slabs.extend(slabs_data.keys()) |
|
178 | slabs.extend(list(slabs_data.keys())) | |
179 |
|
179 | |||
180 | host, port = client.servers[0].address |
|
180 | host, port = client.servers[0].address | |
181 | telnet_client = self._get_telnet_client(host, port) |
|
181 | telnet_client = self._get_telnet_client(host, port) |
@@ -215,7 +215,7 b' def _get_dirpaths(p):' | |||||
215 | def _has_correct_type(item): |
|
215 | def _has_correct_type(item): | |
216 | if type(item) is not expected_type: |
|
216 | if type(item) is not expected_type: | |
217 | log.error( |
|
217 | log.error( | |
218 |
|
|
218 | "Ignoring path %s since it cannot be decoded into unicode.", | |
219 | # Using "repr" to make sure that we see the byte value in case |
|
219 | # Using "repr" to make sure that we see the byte value in case | |
220 | # of support. |
|
220 | # of support. | |
221 | repr(item)) |
|
221 | repr(item)) | |
@@ -320,7 +320,7 b' def is_valid_repo_group(repo_group_name,' | |||||
320 |
|
320 | |||
321 | def ask_ok(prompt, retries=4, complaint='[y]es or [n]o please!'): |
|
321 | def ask_ok(prompt, retries=4, complaint='[y]es or [n]o please!'): | |
322 | while True: |
|
322 | while True: | |
323 |
ok = |
|
323 | ok = eval(input(prompt)) | |
324 | if ok.lower() in ('y', 'ye', 'yes'): |
|
324 | if ok.lower() in ('y', 'ye', 'yes'): | |
325 | return True |
|
325 | return True | |
326 | if ok.lower() in ('n', 'no', 'nop', 'nope'): |
|
326 | if ok.lower() in ('n', 'no', 'nop', 'nope'): |
@@ -367,21 +367,21 b' def age(prevdate, now=None, show_short_v' | |||||
367 | # Format the result |
|
367 | # Format the result | |
368 | if short_format: |
|
368 | if short_format: | |
369 | fmt_funcs = { |
|
369 | fmt_funcs = { | |
370 |
'year': lambda d: |
|
370 | 'year': lambda d: '%dy' % d, | |
371 |
'month': lambda d: |
|
371 | 'month': lambda d: '%dm' % d, | |
372 |
'day': lambda d: |
|
372 | 'day': lambda d: '%dd' % d, | |
373 |
'hour': lambda d: |
|
373 | 'hour': lambda d: '%dh' % d, | |
374 |
'minute': lambda d: |
|
374 | 'minute': lambda d: '%dmin' % d, | |
375 |
'second': lambda d: |
|
375 | 'second': lambda d: '%dsec' % d, | |
376 | } |
|
376 | } | |
377 | else: |
|
377 | else: | |
378 | fmt_funcs = { |
|
378 | fmt_funcs = { | |
379 |
'year': lambda d: _pluralize( |
|
379 | 'year': lambda d: _pluralize('${num} year', '${num} years', d, mapping={'num': d}).interpolate(), | |
380 |
'month': lambda d: _pluralize( |
|
380 | 'month': lambda d: _pluralize('${num} month', '${num} months', d, mapping={'num': d}).interpolate(), | |
381 |
'day': lambda d: _pluralize( |
|
381 | 'day': lambda d: _pluralize('${num} day', '${num} days', d, mapping={'num': d}).interpolate(), | |
382 |
'hour': lambda d: _pluralize( |
|
382 | 'hour': lambda d: _pluralize('${num} hour', '${num} hours', d, mapping={'num': d}).interpolate(), | |
383 |
'minute': lambda d: _pluralize( |
|
383 | 'minute': lambda d: _pluralize('${num} minute', '${num} minutes', d, mapping={'num': d}).interpolate(), | |
384 |
'second': lambda d: _pluralize( |
|
384 | 'second': lambda d: _pluralize('${num} second', '${num} seconds', d, mapping={'num': d}).interpolate(), | |
385 | } |
|
385 | } | |
386 |
|
386 | |||
387 | i = 0 |
|
387 | i = 0 | |
@@ -399,13 +399,13 b' def age(prevdate, now=None, show_short_v' | |||||
399 | _val = fmt_funcs[part](value) |
|
399 | _val = fmt_funcs[part](value) | |
400 | if future: |
|
400 | if future: | |
401 | if show_suffix: |
|
401 | if show_suffix: | |
402 |
return _( |
|
402 | return _('in ${ago}', mapping={'ago': _val}) | |
403 | else: |
|
403 | else: | |
404 | return _(_val) |
|
404 | return _(_val) | |
405 |
|
405 | |||
406 | else: |
|
406 | else: | |
407 | if show_suffix: |
|
407 | if show_suffix: | |
408 |
return _( |
|
408 | return _('${ago} ago', mapping={'ago': _val}) | |
409 | else: |
|
409 | else: | |
410 | return _(_val) |
|
410 | return _(_val) | |
411 |
|
411 | |||
@@ -414,21 +414,21 b' def age(prevdate, now=None, show_short_v' | |||||
414 | mapping = {'val': val, 'detail': val_detail} |
|
414 | mapping = {'val': val, 'detail': val_detail} | |
415 |
|
415 | |||
416 | if short_format: |
|
416 | if short_format: | |
417 |
datetime_tmpl = _( |
|
417 | datetime_tmpl = _('${val}, ${detail}', mapping=mapping) | |
418 | if show_suffix: |
|
418 | if show_suffix: | |
419 |
datetime_tmpl = _( |
|
419 | datetime_tmpl = _('${val}, ${detail} ago', mapping=mapping) | |
420 | if future: |
|
420 | if future: | |
421 |
datetime_tmpl = _( |
|
421 | datetime_tmpl = _('in ${val}, ${detail}', mapping=mapping) | |
422 | else: |
|
422 | else: | |
423 |
datetime_tmpl = _( |
|
423 | datetime_tmpl = _('${val} and ${detail}', mapping=mapping) | |
424 | if show_suffix: |
|
424 | if show_suffix: | |
425 |
datetime_tmpl = _( |
|
425 | datetime_tmpl = _('${val} and ${detail} ago', mapping=mapping) | |
426 | if future: |
|
426 | if future: | |
427 |
datetime_tmpl = _( |
|
427 | datetime_tmpl = _('in ${val} and ${detail}', mapping=mapping) | |
428 |
|
428 | |||
429 | return datetime_tmpl |
|
429 | return datetime_tmpl | |
430 | i += 1 |
|
430 | i += 1 | |
431 |
return _( |
|
431 | return _('just now') | |
432 |
|
432 | |||
433 |
|
433 | |||
434 | def age_from_seconds(seconds): |
|
434 | def age_from_seconds(seconds): |
@@ -23,10 +23,10 b' GIT commit module' | |||||
23 | """ |
|
23 | """ | |
24 |
|
24 | |||
25 | import re |
|
25 | import re | |
|
26 | import io | |||
26 | import stat |
|
27 | import stat | |
27 | import configparser |
|
28 | import configparser | |
28 | from itertools import chain |
|
29 | from itertools import chain | |
29 | from io import StringIO |
|
|||
30 |
|
30 | |||
31 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
31 | from zope.cachedescriptors.property import Lazy as LazyProperty | |
32 |
|
32 |
@@ -72,6 +72,7 b' class MercurialCommit(base.BaseCommit):' | |||||
72 | return |
|
72 | return | |
73 |
|
73 | |||
74 | result = self._remote.bulk_request(self.raw_id, pre_load) |
|
74 | result = self._remote.bulk_request(self.raw_id, pre_load) | |
|
75 | ||||
75 | for attr, value in result.items(): |
|
76 | for attr, value in result.items(): | |
76 | if attr in ["author", "branch", "message"]: |
|
77 | if attr in ["author", "branch", "message"]: | |
77 | value = safe_unicode(value) |
|
78 | value = safe_unicode(value) |
@@ -96,16 +96,16 b' class PermissionModel(BaseModel):' | |||||
96 | c_obj.register_choices = [ |
|
96 | c_obj.register_choices = [ | |
97 | ('hg.register.none', _('Disabled')), |
|
97 | ('hg.register.none', _('Disabled')), | |
98 | ('hg.register.manual_activate', _('Allowed with manual account activation')), |
|
98 | ('hg.register.manual_activate', _('Allowed with manual account activation')), | |
99 |
('hg.register.auto_activate', _('Allowed with automatic account activation')) |
|
99 | ('hg.register.auto_activate', _('Allowed with automatic account activation'))] | |
100 |
|
100 | |||
101 | c_obj.password_reset_choices = [ |
|
101 | c_obj.password_reset_choices = [ | |
102 | ('hg.password_reset.enabled', _('Allow password recovery')), |
|
102 | ('hg.password_reset.enabled', _('Allow password recovery')), | |
103 | ('hg.password_reset.hidden', _('Hide password recovery link')), |
|
103 | ('hg.password_reset.hidden', _('Hide password recovery link')), | |
104 |
('hg.password_reset.disabled', _('Disable password recovery')) |
|
104 | ('hg.password_reset.disabled', _('Disable password recovery'))] | |
105 |
|
105 | |||
106 | c_obj.extern_activate_choices = [ |
|
106 | c_obj.extern_activate_choices = [ | |
107 | ('hg.extern_activate.manual', _('Manual activation of external account')), |
|
107 | ('hg.extern_activate.manual', _('Manual activation of external account')), | |
108 |
('hg.extern_activate.auto', _('Automatic activation of external account')) |
|
108 | ('hg.extern_activate.auto', _('Automatic activation of external account'))] | |
109 |
|
109 | |||
110 | c_obj.repo_create_choices = [ |
|
110 | c_obj.repo_create_choices = [ | |
111 | ('hg.create.none', _('Disabled')), |
|
111 | ('hg.create.none', _('Disabled')), | |
@@ -246,7 +246,7 b' class PermissionModel(BaseModel):' | |||||
246 | .all() |
|
246 | .all() | |
247 | return self._clear_object_perm(perms, preserve=preserve) |
|
247 | return self._clear_object_perm(perms, preserve=preserve) | |
248 |
|
248 | |||
249 | def _set_new_object_perms(self, obj_type, object, form_result, preserve=None): |
|
249 | def _set_new_object_perms(self, obj_type, to_object, form_result, preserve=None): | |
250 | # clear current entries, to make this function idempotent |
|
250 | # clear current entries, to make this function idempotent | |
251 | # it will fix even if we define more permissions or permissions |
|
251 | # it will fix even if we define more permissions or permissions | |
252 | # are somehow missing |
|
252 | # are somehow missing | |
@@ -262,9 +262,9 b' class PermissionModel(BaseModel):' | |||||
262 | global_perms, default_user_perms)) |
|
262 | global_perms, default_user_perms)) | |
263 |
|
263 | |||
264 | if obj_type == 'user': |
|
264 | if obj_type == 'user': | |
265 | self._clear_user_perms(object.user_id, preserve) |
|
265 | self._clear_user_perms(to_object.user_id, preserve) | |
266 | if obj_type == 'user_group': |
|
266 | if obj_type == 'user_group': | |
267 | self._clear_user_group_perms(object.users_group_id, preserve) |
|
267 | self._clear_user_group_perms(to_object.users_group_id, preserve) | |
268 |
|
268 | |||
269 | # now kill the keys that we want to preserve from the form. |
|
269 | # now kill the keys that we want to preserve from the form. | |
270 | for key in preserve: |
|
270 | for key in preserve: | |
@@ -395,7 +395,7 b' class PermissionModel(BaseModel):' | |||||
395 | 'default_repo_create_on_write', |
|
395 | 'default_repo_create_on_write', | |
396 | 'default_repo_create', |
|
396 | 'default_repo_create', | |
397 | 'default_fork_create', |
|
397 | 'default_fork_create', | |
398 |
'default_inherit_default_permissions' |
|
398 | 'default_inherit_default_permissions']) | |
399 |
|
399 | |||
400 | self.sa.commit() |
|
400 | self.sa.commit() | |
401 | except (DatabaseError,): |
|
401 | except (DatabaseError,): |
@@ -25,7 +25,7 b' Scm model for RhodeCode' | |||||
25 | import os.path |
|
25 | import os.path | |
26 | import traceback |
|
26 | import traceback | |
27 | import logging |
|
27 | import logging | |
28 | from io import StringIO |
|
28 | import io | |
29 |
|
29 | |||
30 | from sqlalchemy import func |
|
30 | from sqlalchemy import func | |
31 | from zope.cachedescriptors.property import Lazy as LazyProperty |
|
31 | from zope.cachedescriptors.property import Lazy as LazyProperty |
@@ -89,8 +89,8 b' def UniqueList(localizer, convert=None):' | |||||
89 | Unique List ! |
|
89 | Unique List ! | |
90 | """ |
|
90 | """ | |
91 | messages = { |
|
91 | messages = { | |
92 |
'empty': _( |
|
92 | 'empty': _('Value cannot be an empty list'), | |
93 |
'missing_value': _( |
|
93 | 'missing_value': _('Value cannot be an empty list'), | |
94 | } |
|
94 | } | |
95 |
|
95 | |||
96 | def _to_python(self, value, state): |
|
96 | def _to_python(self, value, state): | |
@@ -136,7 +136,7 b' def ValidSvnPattern(localizer, section, ' | |||||
136 |
|
136 | |||
137 | class _validator(formencode.validators.FancyValidator): |
|
137 | class _validator(formencode.validators.FancyValidator): | |
138 | messages = { |
|
138 | messages = { | |
139 |
'pattern_exists': _( |
|
139 | 'pattern_exists': _('Pattern already exists'), | |
140 | } |
|
140 | } | |
141 |
|
141 | |||
142 | def validate_python(self, value, state): |
|
142 | def validate_python(self, value, state): | |
@@ -157,13 +157,13 b' def ValidUsername(localizer, edit=False,' | |||||
157 |
|
157 | |||
158 | class _validator(formencode.validators.FancyValidator): |
|
158 | class _validator(formencode.validators.FancyValidator): | |
159 | messages = { |
|
159 | messages = { | |
160 |
'username_exists': _( |
|
160 | 'username_exists': _('Username "%(username)s" already exists'), | |
161 | 'system_invalid_username': |
|
161 | 'system_invalid_username': | |
162 |
_( |
|
162 | _('Username "%(username)s" is forbidden'), | |
163 | 'invalid_username': |
|
163 | 'invalid_username': | |
164 |
_( |
|
164 | _('Username may only contain alphanumeric characters ' | |
165 |
|
|
165 | 'underscores, periods or dashes and must begin with ' | |
166 |
|
|
166 | 'alphanumeric character or underscore') | |
167 | } |
|
167 | } | |
168 |
|
168 | |||
169 | def validate_python(self, value, state): |
|
169 | def validate_python(self, value, state): | |
@@ -192,8 +192,8 b' def ValidRepoUser(localizer, allow_disab' | |||||
192 |
|
192 | |||
193 | class _validator(formencode.validators.FancyValidator): |
|
193 | class _validator(formencode.validators.FancyValidator): | |
194 | messages = { |
|
194 | messages = { | |
195 |
'invalid_username': _( |
|
195 | 'invalid_username': _('Username %(username)s is not valid'), | |
196 |
'disabled_username': _( |
|
196 | 'disabled_username': _('Username %(username)s is disabled') | |
197 | } |
|
197 | } | |
198 |
|
198 | |||
199 | def validate_python(self, value, state): |
|
199 | def validate_python(self, value, state): | |
@@ -218,12 +218,12 b' def ValidUserGroup(localizer, edit=False' | |||||
218 |
|
218 | |||
219 | class _validator(formencode.validators.FancyValidator): |
|
219 | class _validator(formencode.validators.FancyValidator): | |
220 | messages = { |
|
220 | messages = { | |
221 |
'invalid_group': _( |
|
221 | 'invalid_group': _('Invalid user group name'), | |
222 |
'group_exist': _( |
|
222 | 'group_exist': _('User group `%(usergroup)s` already exists'), | |
223 | 'invalid_usergroup_name': |
|
223 | 'invalid_usergroup_name': | |
224 |
_( |
|
224 | _('user group name may only contain alphanumeric ' | |
225 |
|
|
225 | 'characters underscores, periods or dashes and must begin ' | |
226 |
|
|
226 | 'with alphanumeric character') | |
227 | } |
|
227 | } | |
228 |
|
228 | |||
229 | def validate_python(self, value, state): |
|
229 | def validate_python(self, value, state): | |
@@ -261,15 +261,15 b' def ValidRepoGroup(localizer, edit=False' | |||||
261 |
|
261 | |||
262 | class _validator(formencode.validators.FancyValidator): |
|
262 | class _validator(formencode.validators.FancyValidator): | |
263 | messages = { |
|
263 | messages = { | |
264 |
'group_parent_id': _( |
|
264 | 'group_parent_id': _('Cannot assign this group as parent'), | |
265 |
'group_exists': _( |
|
265 | 'group_exists': _('Group "%(group_name)s" already exists'), | |
266 |
'repo_exists': _( |
|
266 | 'repo_exists': _('Repository with name "%(group_name)s" ' | |
267 |
|
|
267 | 'already exists'), | |
268 |
'permission_denied': _( |
|
268 | 'permission_denied': _("no permission to store repository group" | |
269 |
|
|
269 | "in this location"), | |
270 | 'permission_denied_root': _( |
|
270 | 'permission_denied_root': _( | |
271 |
|
|
271 | "no permission to store repository group " | |
272 |
|
|
272 | "in root location") | |
273 | } |
|
273 | } | |
274 |
|
274 | |||
275 | def _to_python(self, value, state): |
|
275 | def _to_python(self, value, state): | |
@@ -384,7 +384,7 b' def ValidPassword(localizer):' | |||||
384 | class _validator(formencode.validators.FancyValidator): |
|
384 | class _validator(formencode.validators.FancyValidator): | |
385 | messages = { |
|
385 | messages = { | |
386 | 'invalid_password': |
|
386 | 'invalid_password': | |
387 |
_( |
|
387 | _('Invalid characters (non-ascii) in password') | |
388 | } |
|
388 | } | |
389 |
|
389 | |||
390 | def validate_python(self, value, state): |
|
390 | def validate_python(self, value, state): | |
@@ -403,7 +403,7 b' def ValidPasswordsMatch(' | |||||
403 |
|
403 | |||
404 | class _validator(formencode.validators.FancyValidator): |
|
404 | class _validator(formencode.validators.FancyValidator): | |
405 | messages = { |
|
405 | messages = { | |
406 |
'password_mismatch': _( |
|
406 | 'password_mismatch': _('Passwords do not match'), | |
407 | } |
|
407 | } | |
408 |
|
408 | |||
409 | def validate_python(self, value, state): |
|
409 | def validate_python(self, value, state): | |
@@ -423,9 +423,9 b' def ValidAuth(localizer):' | |||||
423 |
|
423 | |||
424 | class _validator(formencode.validators.FancyValidator): |
|
424 | class _validator(formencode.validators.FancyValidator): | |
425 | messages = { |
|
425 | messages = { | |
426 |
'invalid_password': _( |
|
426 | 'invalid_password': _('invalid password'), | |
427 |
'invalid_username': _( |
|
427 | 'invalid_username': _('invalid user name'), | |
428 |
'disabled_account': _( |
|
428 | 'disabled_account': _('Your account is disabled') | |
429 | } |
|
429 | } | |
430 |
|
430 | |||
431 | def validate_python(self, value, state): |
|
431 | def validate_python(self, value, state): | |
@@ -461,18 +461,18 b' def ValidRepoName(localizer, edit=False,' | |||||
461 | class _validator(formencode.validators.FancyValidator): |
|
461 | class _validator(formencode.validators.FancyValidator): | |
462 | messages = { |
|
462 | messages = { | |
463 | 'invalid_repo_name': |
|
463 | 'invalid_repo_name': | |
464 |
_( |
|
464 | _('Repository name %(repo)s is disallowed'), | |
465 | # top level |
|
465 | # top level | |
466 |
'repository_exists': _( |
|
466 | 'repository_exists': _('Repository with name %(repo)s ' | |
467 |
|
|
467 | 'already exists'), | |
468 |
'group_exists': _( |
|
468 | 'group_exists': _('Repository group with name "%(repo)s" ' | |
469 |
|
|
469 | 'already exists'), | |
470 | # inside a group |
|
470 | # inside a group | |
471 |
'repository_in_group_exists': _( |
|
471 | 'repository_in_group_exists': _('Repository with name %(repo)s ' | |
472 |
|
|
472 | 'exists in group "%(group)s"'), | |
473 | 'group_in_group_exists': _( |
|
473 | 'group_in_group_exists': _( | |
474 |
|
|
474 | 'Repository group with name "%(repo)s" ' | |
475 |
|
|
475 | 'exists in group "%(group)s"'), | |
476 | } |
|
476 | } | |
477 |
|
477 | |||
478 | def _to_python(self, value, state): |
|
478 | def _to_python(self, value, state): | |
@@ -563,7 +563,7 b' def CannotHaveGitSuffix(localizer):' | |||||
563 | class _validator(formencode.validators.FancyValidator): |
|
563 | class _validator(formencode.validators.FancyValidator): | |
564 | messages = { |
|
564 | messages = { | |
565 | 'has_git_suffix': |
|
565 | 'has_git_suffix': | |
566 |
_( |
|
566 | _('Repository name cannot end with .git'), | |
567 | } |
|
567 | } | |
568 |
|
568 | |||
569 | def _to_python(self, value, state): |
|
569 | def _to_python(self, value, state): | |
@@ -623,10 +623,10 b' def ValidCloneUri(localizer):' | |||||
623 |
|
623 | |||
624 | class _validator(formencode.validators.FancyValidator): |
|
624 | class _validator(formencode.validators.FancyValidator): | |
625 | messages = { |
|
625 | messages = { | |
626 |
'clone_uri': _( |
|
626 | 'clone_uri': _('invalid clone url or credentials for %(rtype)s repository'), | |
627 | 'invalid_clone_uri': _( |
|
627 | 'invalid_clone_uri': _( | |
628 |
|
|
628 | 'Invalid clone url, provide a valid clone ' | |
629 |
|
|
629 | 'url starting with one of %(allowed_prefixes)s') | |
630 | } |
|
630 | } | |
631 |
|
631 | |||
632 | def validate_python(self, value, state): |
|
632 | def validate_python(self, value, state): | |
@@ -656,7 +656,7 b' def ValidForkType(localizer, old_data=No' | |||||
656 |
|
656 | |||
657 | class _validator(formencode.validators.FancyValidator): |
|
657 | class _validator(formencode.validators.FancyValidator): | |
658 | messages = { |
|
658 | messages = { | |
659 |
'invalid_fork_type': _( |
|
659 | 'invalid_fork_type': _('Fork have to be the same type as parent') | |
660 | } |
|
660 | } | |
661 |
|
661 | |||
662 | def validate_python(self, value, state): |
|
662 | def validate_python(self, value, state): | |
@@ -674,11 +674,11 b' def CanWriteGroup(localizer, old_data=No' | |||||
674 | class _validator(formencode.validators.FancyValidator): |
|
674 | class _validator(formencode.validators.FancyValidator): | |
675 | messages = { |
|
675 | messages = { | |
676 | 'permission_denied': _( |
|
676 | 'permission_denied': _( | |
677 |
|
|
677 | "You do not have the permission " | |
678 |
|
|
678 | "to create repositories in this group."), | |
679 | 'permission_denied_root': _( |
|
679 | 'permission_denied_root': _( | |
680 |
|
|
680 | "You do not have the permission to store repositories in " | |
681 |
|
|
681 | "the root location.") | |
682 | } |
|
682 | } | |
683 |
|
683 | |||
684 | def _to_python(self, value, state): |
|
684 | def _to_python(self, value, state): | |
@@ -736,7 +736,7 b" def ValidPerms(localizer, type_='repo'):" | |||||
736 | class _validator(formencode.validators.FancyValidator): |
|
736 | class _validator(formencode.validators.FancyValidator): | |
737 | messages = { |
|
737 | messages = { | |
738 | 'perm_new_member_name': |
|
738 | 'perm_new_member_name': | |
739 |
_( |
|
739 | _('This username or user group name is not valid') | |
740 | } |
|
740 | } | |
741 |
|
741 | |||
742 | def _to_python(self, value, state): |
|
742 | def _to_python(self, value, state): | |
@@ -849,7 +849,7 b' def ValidPath(localizer):' | |||||
849 |
|
849 | |||
850 | class _validator(formencode.validators.FancyValidator): |
|
850 | class _validator(formencode.validators.FancyValidator): | |
851 | messages = { |
|
851 | messages = { | |
852 |
'invalid_path': _( |
|
852 | 'invalid_path': _('This is not a valid path') | |
853 | } |
|
853 | } | |
854 |
|
854 | |||
855 | def validate_python(self, value, state): |
|
855 | def validate_python(self, value, state): | |
@@ -867,7 +867,7 b' def UniqSystemEmail(localizer, old_data=' | |||||
867 |
|
867 | |||
868 | class _validator(formencode.validators.FancyValidator): |
|
868 | class _validator(formencode.validators.FancyValidator): | |
869 | messages = { |
|
869 | messages = { | |
870 |
'email_taken': _( |
|
870 | 'email_taken': _('This e-mail address is already taken') | |
871 | } |
|
871 | } | |
872 |
|
872 | |||
873 | def _to_python(self, value, state): |
|
873 | def _to_python(self, value, state): | |
@@ -889,7 +889,7 b' def ValidSystemEmail(localizer):' | |||||
889 |
|
889 | |||
890 | class _validator(formencode.validators.FancyValidator): |
|
890 | class _validator(formencode.validators.FancyValidator): | |
891 | messages = { |
|
891 | messages = { | |
892 |
'non_existing_email': _( |
|
892 | 'non_existing_email': _('e-mail "%(email)s" does not exist.') | |
893 | } |
|
893 | } | |
894 |
|
894 | |||
895 | def _to_python(self, value, state): |
|
895 | def _to_python(self, value, state): | |
@@ -910,8 +910,8 b' def NotReviewedRevisions(localizer, repo' | |||||
910 | class _validator(formencode.validators.FancyValidator): |
|
910 | class _validator(formencode.validators.FancyValidator): | |
911 | messages = { |
|
911 | messages = { | |
912 | 'rev_already_reviewed': |
|
912 | 'rev_already_reviewed': | |
913 |
_( |
|
913 | _('Revisions %(revs)s are already part of pull request ' | |
914 |
|
|
914 | 'or have set status'), | |
915 | } |
|
915 | } | |
916 |
|
916 | |||
917 | def validate_python(self, value, state): |
|
917 | def validate_python(self, value, state): | |
@@ -943,10 +943,10 b' def ValidIp(localizer):' | |||||
943 |
|
943 | |||
944 | class _validator(CIDR): |
|
944 | class _validator(CIDR): | |
945 | messages = { |
|
945 | messages = { | |
946 |
'badFormat': _( |
|
946 | 'badFormat': _('Please enter a valid IPv4 or IpV6 address'), | |
947 | 'illegalBits': _( |
|
947 | 'illegalBits': _( | |
948 |
|
|
948 | 'The network size (bits) must be within the range ' | |
949 |
|
|
949 | 'of 0-32 (not %(bits)r)'), | |
950 | } |
|
950 | } | |
951 |
|
951 | |||
952 | # we ovveride the default to_python() call |
|
952 | # we ovveride the default to_python() call | |
@@ -973,8 +973,8 b' def FieldKey(localizer):' | |||||
973 | class _validator(formencode.validators.FancyValidator): |
|
973 | class _validator(formencode.validators.FancyValidator): | |
974 | messages = { |
|
974 | messages = { | |
975 | 'badFormat': _( |
|
975 | 'badFormat': _( | |
976 |
|
|
976 | 'Key name can only consist of letters, ' | |
977 |
|
|
977 | 'underscore, dash or numbers'), | |
978 | } |
|
978 | } | |
979 |
|
979 | |||
980 | def validate_python(self, value, state): |
|
980 | def validate_python(self, value, state): | |
@@ -990,15 +990,15 b' def ValidAuthPlugins(localizer):' | |||||
990 | class _validator(formencode.validators.FancyValidator): |
|
990 | class _validator(formencode.validators.FancyValidator): | |
991 | messages = { |
|
991 | messages = { | |
992 | 'import_duplicate': _( |
|
992 | 'import_duplicate': _( | |
993 |
|
|
993 | 'Plugins %(loaded)s and %(next_to_load)s ' | |
994 |
|
|
994 | 'both export the same name'), | |
995 | 'missing_includeme': _( |
|
995 | 'missing_includeme': _( | |
996 |
|
|
996 | 'The plugin "%(plugin_id)s" is missing an includeme ' | |
997 |
|
|
997 | 'function.'), | |
998 | 'import_error': _( |
|
998 | 'import_error': _( | |
999 |
|
|
999 | 'Can not load plugin "%(plugin_id)s"'), | |
1000 | 'no_plugin': _( |
|
1000 | 'no_plugin': _( | |
1001 |
|
|
1001 | 'No plugin available with ID "%(plugin_id)s"'), | |
1002 | } |
|
1002 | } | |
1003 |
|
1003 | |||
1004 | def _to_python(self, value, state): |
|
1004 | def _to_python(self, value, state): | |
@@ -1065,7 +1065,7 b' def ValidPattern(localizer):' | |||||
1065 |
|
1065 | |||
1066 | class _validator(formencode.validators.FancyValidator): |
|
1066 | class _validator(formencode.validators.FancyValidator): | |
1067 | messages = { |
|
1067 | messages = { | |
1068 |
'bad_format': _( |
|
1068 | 'bad_format': _('Url must start with http or /'), | |
1069 | } |
|
1069 | } | |
1070 |
|
1070 | |||
1071 | def _to_python(self, value, state): |
|
1071 | def _to_python(self, value, state): |
@@ -264,7 +264,7 b' def write_js_routes_if_enabled(event):' | |||||
264 | registry = event.app.registry |
|
264 | registry = event.app.registry | |
265 |
|
265 | |||
266 | mapper = registry.queryUtility(IRoutesMapper) |
|
266 | mapper = registry.queryUtility(IRoutesMapper) | |
267 | _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)') |
|
267 | _argument_prog = re.compile(r'\{(.*?)\}|:\((.*)\)') | |
268 |
|
268 | |||
269 | def _extract_route_information(route): |
|
269 | def _extract_route_information(route): | |
270 | """ |
|
270 | """ |
@@ -670,7 +670,7 b' def get_inline_comments(comments, filena' | |||||
670 | if hasattr(filename, 'unicode_path'): |
|
670 | if hasattr(filename, 'unicode_path'): | |
671 | filename = filename.unicode_path |
|
671 | filename = filename.unicode_path | |
672 |
|
672 | |||
673 |
if not isinstance(filename, |
|
673 | if not isinstance(filename, str): | |
674 | return None |
|
674 | return None | |
675 |
|
675 | |||
676 | if comments and filename in comments: |
|
676 | if comments and filename in comments: | |
@@ -682,7 +682,7 b' def get_comments_for(diff_type, comments' | |||||
682 | if hasattr(filename, 'unicode_path'): |
|
682 | if hasattr(filename, 'unicode_path'): | |
683 | filename = filename.unicode_path |
|
683 | filename = filename.unicode_path | |
684 |
|
684 | |||
685 |
if not isinstance(filename, |
|
685 | if not isinstance(filename, str): | |
686 | return None |
|
686 | return None | |
687 |
|
687 | |||
688 | file_comments = get_inline_comments(comments, filename) |
|
688 | file_comments = get_inline_comments(comments, filename) |
@@ -17,8 +17,7 b'' | |||||
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 | import io | ||
21 | from io import StringIO |
|
|||
22 |
|
21 | |||
23 | import pytest |
|
22 | import pytest | |
24 | from mock import patch, Mock |
|
23 | from mock import patch, Mock | |
@@ -104,7 +103,7 b' class TestSimpleSvn(object):' | |||||
104 | class TestSimpleSvnApp(object): |
|
103 | class TestSimpleSvnApp(object): | |
105 | data = '<xml></xml>' |
|
104 | data = '<xml></xml>' | |
106 | path = '/group/my-repo' |
|
105 | path = '/group/my-repo' | |
107 | wsgi_input = StringIO(data) |
|
106 | wsgi_input = io.StringIO(data) | |
108 | environment = { |
|
107 | environment = { | |
109 | 'HTTP_DAV': ( |
|
108 | 'HTTP_DAV': ( | |
110 | 'http://subversion.tigris.org/xmlns/dav/svn/depth,' |
|
109 | 'http://subversion.tigris.org/xmlns/dav/svn/depth,' |
@@ -20,7 +20,7 b'' | |||||
20 |
|
20 | |||
21 | import json |
|
21 | import json | |
22 | import logging |
|
22 | import logging | |
23 | from io import StringIO |
|
23 | import io | |
24 |
|
24 | |||
25 | import mock |
|
25 | import mock | |
26 | import pytest |
|
26 | import pytest | |
@@ -320,8 +320,8 b' class TestPrepareHooksDaemon(object):' | |||||
320 | class MockRequest(object): |
|
320 | class MockRequest(object): | |
321 | def __init__(self, request): |
|
321 | def __init__(self, request): | |
322 | self.request = request |
|
322 | self.request = request | |
323 | self.input_stream = StringIO(b'{}'.format(self.request)) |
|
323 | self.input_stream = io.StringIO(b'{}'.format(self.request)) | |
324 | self.output_stream = StringIO() |
|
324 | self.output_stream = io.StringIO() | |
325 |
|
325 | |||
326 | def makefile(self, mode, *args, **kwargs): |
|
326 | def makefile(self, mode, *args, **kwargs): | |
327 | return self.output_stream if mode == 'wb' else self.input_stream |
|
327 | return self.output_stream if mode == 'wb' else self.input_stream |
@@ -24,7 +24,7 b' import shutil' | |||||
24 | import tarfile |
|
24 | import tarfile | |
25 | import tempfile |
|
25 | import tempfile | |
26 | import zipfile |
|
26 | import zipfile | |
27 | from io import StringIO |
|
27 | import io | |
28 |
|
28 | |||
29 | import mock |
|
29 | import mock | |
30 | import pytest |
|
30 | import pytest | |
@@ -108,7 +108,7 b' class TestArchives(BackendTestMixin):' | |||||
108 |
|
108 | |||
109 | for x in range(5): |
|
109 | for x in range(5): | |
110 | node_path = '%d/file_%d.txt' % (x, x) |
|
110 | node_path = '%d/file_%d.txt' % (x, x) | |
111 |
decompressed = |
|
111 | decompressed = io.StringIO() | |
112 | decompressed.write(out.read('repo/' + node_path)) |
|
112 | decompressed.write(out.read('repo/' + node_path)) | |
113 | assert decompressed.getvalue() == \ |
|
113 | assert decompressed.getvalue() == \ | |
114 | self.tip.get_node(node_path).content |
|
114 | self.tip.get_node(node_path).content | |
@@ -126,7 +126,7 b' class TestArchives(BackendTestMixin):' | |||||
126 |
|
126 | |||
127 | for x in range(5): |
|
127 | for x in range(5): | |
128 | node_path = '%d/file_%d.txt' % (x, x) |
|
128 | node_path = '%d/file_%d.txt' % (x, x) | |
129 |
decompressed = |
|
129 | decompressed = io.StringIO() | |
130 | decompressed.write(out.read('repo/' + node_path)) |
|
130 | decompressed.write(out.read('repo/' + node_path)) | |
131 | assert decompressed.getvalue() == \ |
|
131 | assert decompressed.getvalue() == \ | |
132 | self.tip.get_node(node_path).content |
|
132 | self.tip.get_node(node_path).content |
General Comments 0
You need to be logged in to leave comments.
Login now