##// END OF EJS Templates
core: make binary envelope behave like bytes type object for serialization and internal API usage....
super-admin -
r1094:0553d498 python3
parent child Browse files
Show More
@@ -1,142 +1,178 b''
1 1 # RhodeCode VCSServer provides access to different vcs backends via network.
2 2 # Copyright (C) 2014-2020 RhodeCode GmbH
3 3 #
4 4 # This program is free software; you can redistribute it and/or modify
5 5 # it under the terms of the GNU General Public License as published by
6 6 # the Free Software Foundation; either version 3 of the License, or
7 7 # (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software Foundation,
16 16 # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 17 import os
18 18 import sys
19 19 import traceback
20 20 import logging
21 21 import urllib.parse
22 22
23 23 from vcsserver.lib.rc_cache import region_meta
24 24
25 25 from vcsserver import exceptions
26 26 from vcsserver.exceptions import NoContentException
27 27 from vcsserver.hgcompat import archival
28 28 from vcsserver.str_utils import safe_bytes
29 29
30 30 log = logging.getLogger(__name__)
31 31
32 32
33 33 class RepoFactory(object):
34 34 """
35 35 Utility to create instances of repository
36 36
37 37 It provides internal caching of the `repo` object based on
38 38 the :term:`call context`.
39 39 """
40 40 repo_type = None
41 41
42 42 def __init__(self):
43 43 self._cache_region = region_meta.dogpile_cache_regions['repo_object']
44 44
45 45 def _create_config(self, path, config):
46 46 config = {}
47 47 return config
48 48
49 49 def _create_repo(self, wire, create):
50 50 raise NotImplementedError()
51 51
52 52 def repo(self, wire, create=False):
53 53 raise NotImplementedError()
54 54
55 55
56 56 def obfuscate_qs(query_string):
57 57 if query_string is None:
58 58 return None
59 59
60 60 parsed = []
61 61 for k, v in urllib.parse.parse_qsl(query_string, keep_blank_values=True):
62 62 if k in ['auth_token', 'api_key']:
63 63 v = "*****"
64 64 parsed.append((k, v))
65 65
66 66 return '&'.join('{}{}'.format(
67 67 k, '={}'.format(v) if v else '') for k, v in parsed)
68 68
69 69
70 70 def raise_from_original(new_type, org_exc: Exception):
71 71 """
72 72 Raise a new exception type with original args and traceback.
73 73 """
74 74
75 75 exc_type, exc_value, exc_traceback = sys.exc_info()
76 76 new_exc = new_type(*exc_value.args)
77 77
78 78 # store the original traceback into the new exc
79 79 new_exc._org_exc_tb = traceback.format_tb(exc_traceback)
80 80
81 81 try:
82 82 raise new_exc.with_traceback(exc_traceback)
83 83 finally:
84 84 del exc_traceback
85 85
86 86
87 87 class ArchiveNode(object):
88 88 def __init__(self, path, mode, is_link, raw_bytes):
89 89 self.path = path
90 90 self.mode = mode
91 91 self.is_link = is_link
92 92 self.raw_bytes = raw_bytes
93 93
94 94
95 95 def archive_repo(walker, archive_dest_path, kind, mtime, archive_at_path,
96 96 archive_dir_name, commit_id, write_metadata=True, extra_metadata=None):
97 97 """
98 98 walker should be a file walker, for example:
99 99 def walker():
100 100 for file_info in files:
101 101 yield ArchiveNode(fn, mode, is_link, ctx[fn].data)
102 102 """
103 103 extra_metadata = extra_metadata or {}
104 104 archive_dest_path = safe_bytes(archive_dest_path)
105 105
106 106 if kind == "tgz":
107 107 archiver = archival.tarit(archive_dest_path, mtime, b"gz")
108 108 elif kind == "tbz2":
109 109 archiver = archival.tarit(archive_dest_path, mtime, b"bz2")
110 110 elif kind == 'zip':
111 111 archiver = archival.zipit(archive_dest_path, mtime)
112 112 else:
113 113 raise exceptions.ArchiveException()(
114 114 f'Remote does not support: "{kind}" archive type.')
115 115
116 116 for f in walker(commit_id, archive_at_path):
117 117 f_path = os.path.join(safe_bytes(archive_dir_name), safe_bytes(f.path).lstrip(b'/'))
118 118 try:
119 119 archiver.addfile(f_path, f.mode, f.is_link, f.raw_bytes())
120 120 except NoContentException:
121 121 # NOTE(marcink): this is a special case for SVN so we can create "empty"
122 122 # directories which arent supported by archiver
123 123 archiver.addfile(os.path.join(f_path, b'.dir'), f.mode, f.is_link, b'')
124 124
125 125 if write_metadata:
126 126 metadata = dict([
127 127 ('commit_id', commit_id),
128 128 ('mtime', mtime),
129 129 ])
130 130 metadata.update(extra_metadata)
131 131
132 132 meta = [safe_bytes(f"{f_name}:{value}") for f_name, value in metadata.items()]
133 133 f_path = os.path.join(safe_bytes(archive_dir_name), b'.archival.txt')
134 134 archiver.addfile(f_path, 0o644, False, b'\n'.join(meta))
135 135
136 136 return archiver.done()
137 137
138 138
139 139 class BinaryEnvelope(object):
140 140 def __init__(self, value, bin_type=True):
141 141 self.value = value
142 142 self.bin_type = bin_type
143
144 def __len__(self):
145 return len(self.value)
146
147 def __getitem__(self, index):
148 return self.value[index]
149
150 def __iter__(self):
151 return iter(self.value)
152
153 def __str__(self):
154 return str(self.value)
155
156 def __repr__(self):
157 return repr(self.value)
158
159 def __eq__(self, other):
160 if isinstance(other, BinaryEnvelope):
161 return self.value == other.value
162 return False
163
164 def __ne__(self, other):
165 return not self.__eq__(other)
166
167 def __add__(self, other):
168 if isinstance(other, BinaryEnvelope):
169 return BinaryEnvelope(self.value + other.value)
170 raise TypeError(f"unsupported operand type(s) for +: 'BinaryEnvelope' and '{type(other)}'")
171
172 def __radd__(self, other):
173 if isinstance(other, BinaryEnvelope):
174 return BinaryEnvelope(other.value + self.value)
175 raise TypeError(f"unsupported operand type(s) for +: '{type(other)}' and 'BinaryEnvelope'")
176
177
178
General Comments 0
You need to be logged in to leave comments. Login now