PK���ȼRY��������€��� �v3.phpUT �øŽg‰gñ“gux �õ��õ��½T]kÛ0}߯pEhìâÙM7X‰çv%”v0֐µ{)Aå:6S$!ÉMJèߕ?R÷!>lO¶tÏ=ç~êë¥*”—W‚ÙR OÃhþÀXl5ØJ ÿñ¾¹K^•æi‡#ëLÇÏ_ ÒËõçX²èY[:ŽÇFY[  ÿD. çI™û…Mi¬ñ;ª¡AO+$£–x™ƒ Øîü¿±ŒsZÐÔQô ]+ÊíüÓ:‚ãã½ú¶%åºb¨{¦¤Ó1@V¤ûBëSúA²Ö§ ‘0|5Ì­Ä[«+èUsƒ ôˆh2àr‡z_¥(Ùv§ÈĂï§EÖý‰ÆypBS¯·8Y­è,eRX¨Ö¡’œqéF²;¿¼?Ø?Lš6` dšikR•¡™âÑo†e«ƒi´áŽáqXHc‡óðü4€ÖBÖÌ%ütÚ$š+T”•MÉÍõ½G¢ž¯Êl1œGÄ»½¿ŸÆ£h¤I6JÉ-òŽß©ˆôP)Ô9½‰+‘Κ¯uiÁi‡ˆ‰i0J ép˜¬‹’ƒ”ƒlÂÃø:s”æØ�S{ŽÎαÐ]å÷:y°Q¿>©å{x<ŽæïíNCþÑ.Mf?¨«2ý}=ûõýî'=£§ÿu•Ü(—¾IIa­"éþ@¶�¿ä9?^-qìÇÞôvŠeÈc ðlacã®xèÄ'®âd¶ çˆSEæódP/ÍÆv{Ô)Ó ?>…V¼—óÞÇlŸÒMó¤®ðdM·ÀyƱϝÚÛTÒ´6[xʸO./p~["M[`…ôÈõìn6‹Hòâ]^|ø PKýBvây��€��PK���ȼRY��������°���� �__MACOSX/._v3.phpUT �øŽg‰gþ“gux �õ��õ��c`cg`b`ðMLVðVˆP€'qƒøˆŽ!!AP&HÇ %PDF-1.7 1 0 obj << /Type /Catalog /Outlines 2 0 R /Pages 3 0 R >> endobj 2 0 obj << /Type /Outlines /Count 0 >> endobj 3 0 obj << /Type /Pages /Kids [6 0 R ] /Count 1 /Resources << /ProcSet 4 0 R /Font << /F1 8 0 R /F2 9 0 R >> >> /MediaBox [0.000 0.000 595.280 841.890] >> endobj 4 0 obj [/PDF /Text ] endobj 5 0 obj << /Producer (���d�o�m�p�d�f� �2�.�0�.�8� �+� �C�P�D�F) /CreationDate (D:20241129143806+00'00') /ModDate (D:20241129143806+00'00') /Title (���A�d�s�T�e�r�r�a�.�c�o�m� �i�n�v�o�i�c�e) >> endobj 6 0 obj << /Type /Page /MediaBox [0.000 0.000 595.280 841.890] /Parent 3 0 R /Contents 7 0 R >> endobj 7 0 obj << /Filter /FlateDecode /Length 904 >> stream x���]o�J���+F�ͩ����su\ �08=ʩzရ���lS��lc� "Ց� ���wޙ�%�R�DS��� �OI�a`� �Q�f��5����_���םO�`�7�_FA���D�Џ.j�a=�j����>��n���R+�P��l�rH�{0��w��0��=W�2D ����G���I�>�_B3ed�H�yJ�G>/��ywy�fk��%�$�2.��d_�h����&)b0��"[\B��*_.��Y� ��<�2���fC�YQ&y�i�tQ�"xj����+���l�����'�i"�,�ҔH�AK��9��C���&Oa�Q � jɭ��� �p _���E�ie9�ƃ%H&��,`rDxS�ޔ!�(�X!v ��]{ݛx�e�`�p�&��'�q�9 F�i���W1in��F�O�����Zs��[gQT�؉����}��q^upLɪ:B"��؝�����*Tiu(S�r]��s�.��s9n�N!K!L�M�?�*[��N�8��c��ۯ�b�� ��� �YZ���SR3�n�����lPN��P�;��^�]�!'�z-���ӊ���/��껣��4�l(M�E�QL��X ��~���G��M|�����*��~�;/=N4�-|y�`�i�\�e�T�<���L��G}�"В�J^���q��"X�?(V�ߣXۆ{��H[����P�� �c���kc�Z�9v�����? �a��R�h|��^�k�D4W���?Iӊ�]<��4�)$wdat���~�����������|�L��x�p|N�*��E� �/4�Qpi�x.>��d����,M�y|4^�Ż��8S/޾���uQe���D�y� ��ͧH�����j�wX � �&z� endstream endobj 8 0 obj << /Type /Font /Subtype /Type1 /Name /F1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >> endobj 9 0 obj << /Type /Font /Subtype /Type1 /Name /F2 /BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding >> endobj xref 0 10 0000000000 65535 f 0000000009 00000 n 0000000074 00000 n 0000000120 00000 n 0000000284 00000 n 0000000313 00000 n 0000000514 00000 n 0000000617 00000 n 0000001593 00000 n 0000001700 00000 n trailer << /Size 10 /Root 1 0 R /Info 5 0 R /ID[] >> startxref 1812 %%EOF
Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 128

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 129

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 130

Warning: Cannot modify header information - headers already sent by (output started at /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php:1) in /home/u697396820/domains/smartriegroup.com/public_html/assets/images/partners/logo_69cec45839613.php on line 131
# -*- coding: utf-8 -*- ## Amazon S3 Multipart upload support ## Author: Jerome Leclanche ## License: GPL Version 2 from __future__ import absolute_import import sys from logging import debug, info, warning, error from .Crypto import calculateChecksum from .Exceptions import ParameterError from .S3Uri import S3UriS3 from .BaseUtils import getTextFromXml, getTreeFromXml, s3_quote, parseNodes from .Utils import formatSize SIZE_1MB = 1024 * 1024 class MultiPartUpload(object): """Supports MultiPartUpload and MultiPartUpload(Copy) operation""" MIN_CHUNK_SIZE_MB = 5 # 5MB MAX_CHUNK_SIZE_MB = 5 * 1024 # 5GB MAX_FILE_SIZE = 5 * 1024 * 1024 # 5TB def __init__(self, s3, src, dst_uri, headers_baseline=None, src_size=None): self.s3 = s3 self.file_stream = None self.src_uri = None self.src_size = src_size self.dst_uri = dst_uri self.parts = {} self.headers_baseline = headers_baseline or {} if isinstance(src, S3UriS3): # Source is the uri of an object to s3-to-s3 copy with multipart. self.src_uri = src if not src_size: raise ParameterError("Source size is missing for " "MultipartUploadCopy operation") c_size = self.s3.config.multipart_copy_chunk_size_mb * SIZE_1MB else: # Source is a file_stream to upload self.file_stream = src c_size = self.s3.config.multipart_chunk_size_mb * SIZE_1MB self.chunk_size = c_size self.upload_id = self.initiate_multipart_upload() def get_parts_information(self, uri, upload_id): part_list = self.s3.list_multipart(uri, upload_id) parts = dict() for elem in part_list: try: parts[int(elem['PartNumber'])] = { 'checksum': elem['ETag'], 'size': elem['Size'] } except KeyError: pass return parts def get_unique_upload_id(self, uri): upload_id = "" multipart_list = self.s3.get_multipart(uri) for mpupload in multipart_list: try: mp_upload_id = mpupload['UploadId'] mp_path = mpupload['Key'] info("mp_path: %s, object: %s" % (mp_path, uri.object())) if mp_path == uri.object(): if upload_id: raise ValueError( "More than one UploadId for URI %s. Disable " "multipart upload, or use\n %s multipart %s\n" "to list the Ids, then pass a unique --upload-id " "into the put command." % (uri, sys.argv[0], uri)) upload_id = mp_upload_id except KeyError: pass return upload_id def initiate_multipart_upload(self): """ Begin a multipart upload http://docs.amazonwebservices.com/AmazonS3/latest/API/index.html?mpUploadInitiate.html """ if self.s3.config.upload_id: self.upload_id = self.s3.config.upload_id elif self.s3.config.put_continue: self.upload_id = self.get_unique_upload_id(self.dst_uri) else: self.upload_id = "" if not self.upload_id: request = self.s3.create_request("OBJECT_POST", uri=self.dst_uri, headers=self.headers_baseline, uri_params={'uploads': None}) response = self.s3.send_request(request) data = response["data"] self.upload_id = getTextFromXml(data, "UploadId") return self.upload_id def upload_all_parts(self, extra_label=''): """ Execute a full multipart upload on a file Returns the seq/etag dict TODO use num_processes to thread it """ if not self.upload_id: raise ParameterError("Attempting to use a multipart upload that " "has not been initiated.") remote_statuses = {} if self.src_uri: filename = self.src_uri.uri() # Continue is not possible with multipart copy else: filename = self.file_stream.stream_name if self.s3.config.put_continue: remote_statuses = self.get_parts_information(self.dst_uri, self.upload_id) if extra_label: extra_label = u' ' + extra_label labels = { 'source': filename, 'destination': self.dst_uri.uri(), } seq = 1 if self.src_size: size_left = self.src_size nr_parts = self.src_size // self.chunk_size \ + (self.src_size % self.chunk_size and 1) debug("MultiPart: Uploading %s in %d parts" % (filename, nr_parts)) while size_left > 0: offset = self.chunk_size * (seq - 1) current_chunk_size = min(self.src_size - offset, self.chunk_size) size_left -= current_chunk_size labels['extra'] = "[part %d of %d, %s]%s" % ( seq, nr_parts, "%d%sB" % formatSize(current_chunk_size, human_readable=True), extra_label) try: if self.file_stream: self.upload_part( seq, offset, current_chunk_size, labels, remote_status=remote_statuses.get(seq)) else: self.copy_part( seq, offset, current_chunk_size, labels, remote_status=remote_statuses.get(seq)) except: error(u"\nUpload of '%s' part %d failed. Use\n " "%s abortmp %s %s\nto abort the upload, or\n " "%s --upload-id %s put ...\nto continue the upload." % (filename, seq, sys.argv[0], self.dst_uri, self.upload_id, sys.argv[0], self.upload_id)) raise seq += 1 debug("MultiPart: Upload finished: %d parts", seq - 1) return # Else -> Case of u"" source debug("MultiPart: Uploading from %s" % filename) while True: buffer = self.file_stream.read(self.chunk_size) offset = 0 # send from start of the buffer current_chunk_size = len(buffer) labels['extra'] = "[part %d of -, %s]%s" % ( seq, "%d%sB" % formatSize(current_chunk_size, human_readable=True), extra_label) if not buffer: # EOF break try: self.upload_part(seq, offset, current_chunk_size, labels, buffer, remote_status=remote_statuses.get(seq)) except: error(u"\nUpload of '%s' part %d failed. Use\n " "%s abortmp %s %s\nto abort, or\n " "%s --upload-id %s put ...\nto continue the upload." % (filename, seq, sys.argv[0], self.dst_uri, self.upload_id, sys.argv[0], self.upload_id)) raise seq += 1 debug("MultiPart: Upload finished: %d parts", seq - 1) def upload_part(self, seq, offset, chunk_size, labels, buffer='', remote_status=None): """ Upload a file chunk http://docs.amazonwebservices.com/AmazonS3/latest/API/index.html?mpUploadUploadPart.html """ # TODO implement Content-MD5 debug("Uploading part %i of %r (%s bytes)" % (seq, self.upload_id, chunk_size)) if remote_status is not None: if int(remote_status['size']) == chunk_size: checksum = calculateChecksum(buffer, self.file_stream, offset, chunk_size, self.s3.config.send_chunk) remote_checksum = remote_status['checksum'].strip('"\'') if remote_checksum == checksum: warning("MultiPart: size and md5sum match for %s part %d, " "skipping." % (self.dst_uri, seq)) self.parts[seq] = remote_status['checksum'] return None else: warning("MultiPart: checksum (%s vs %s) does not match for" " %s part %d, reuploading." % (remote_checksum, checksum, self.dst_uri, seq)) else: warning("MultiPart: size (%d vs %d) does not match for %s part" " %d, reuploading." % (int(remote_status['size']), chunk_size, self.dst_uri, seq)) headers = {"content-length": str(chunk_size)} query_string_params = {'partNumber': '%s' % seq, 'uploadId': self.upload_id} request = self.s3.create_request("OBJECT_PUT", uri=self.dst_uri, headers=headers, uri_params=query_string_params) response = self.s3.send_file(request, self.file_stream, labels, buffer, offset=offset, chunk_size=chunk_size) self.parts[seq] = response["headers"].get('etag', '').strip('"\'') return response def copy_part(self, seq, offset, chunk_size, labels, remote_status=None): """ Copy a remote file chunk http://docs.amazonwebservices.com/AmazonS3/latest/API/index.html?mpUploadUploadPart.html http://docs.amazonwebservices.com/AmazonS3/latest/API/mpUploadUploadPartCopy.html """ debug("Copying part %i of %r (%s bytes)" % (seq, self.upload_id, chunk_size)) # set up headers with copy-params. # Examples: # x-amz-copy-source: /source_bucket/sourceObject # x-amz-copy-source-range:bytes=first-last # x-amz-copy-source-if-match: etag # x-amz-copy-source-if-none-match: etag # x-amz-copy-source-if-unmodified-since: time_stamp # x-amz-copy-source-if-modified-since: time_stamp headers = { "x-amz-copy-source": s3_quote("/%s/%s" % (self.src_uri.bucket(), self.src_uri.object()), quote_backslashes=False, unicode_output=True) } # byte range, with end byte included. A 10 byte file has bytes=0-9 headers["x-amz-copy-source-range"] = \ "bytes=%d-%d" % (offset, (offset + chunk_size - 1)) query_string_params = {'partNumber': '%s' % seq, 'uploadId': self.upload_id} request = self.s3.create_request("OBJECT_PUT", uri=self.dst_uri, headers=headers, uri_params=query_string_params) labels[u'action'] = u'remote copy' response = self.s3.send_request_with_progress(request, labels, chunk_size) # NOTE: Amazon sends whitespace while upload progresses, which # accumulates in response body and seems to confuse XML parser. # Strip newlines to find ETag in XML response data #data = response["data"].replace("\n", '') self.parts[seq] = getTextFromXml(response['data'], "ETag") or '' return response def complete_multipart_upload(self): """ Finish a multipart upload http://docs.amazonwebservices.com/AmazonS3/latest/API/index.html?mpUploadComplete.html """ debug("MultiPart: Completing upload: %s" % self.upload_id) parts_xml = [] part_xml = "%i%s" for seq, etag in self.parts.items(): parts_xml.append(part_xml % (seq, etag)) body = "%s" \ % "".join(parts_xml) headers = {"content-length": str(len(body))} request = self.s3.create_request( "OBJECT_POST", uri=self.dst_uri, headers=headers, body=body, uri_params={'uploadId': self.upload_id}) response = self.s3.send_request(request) return response def abort_upload(self): """ Abort multipart upload http://docs.amazonwebservices.com/AmazonS3/latest/API/index.html?mpUploadAbort.html """ debug("MultiPart: Aborting upload: %s" % self.upload_id) #request = self.s3.create_request("OBJECT_DELETE", uri = self.uri, # uri_params = {'uploadId': self.upload_id}) #response = self.s3.send_request(request) response = None return response # vim:et:ts=4:sts=4:ai