ó FRTc@s£ddlZddlZddlZddlmZdZdeZdZed„Zed„Z d„Z dd „Z d „Z d „Z d efd „ƒYZdS(iÿÿÿÿN(tsixiii'cCs•t}|t|kr‹|dtdkr=td|ƒ‚n|d}d}x,||kr{tjt|ƒ}|d7}qPWt|ƒ}n|}|S(s"Calculate the minimum part size needed for a multipart upload. Glacier allows a maximum of 10,000 parts per upload. It also states that the maximum archive size is 10,000 * 4 GB, which means the part size can range from 1MB to 4GB (provided it is one 1MB multiplied by a power of 2). This function will compute what the minimum part size must be in order to upload a file of size ``size_in_bytes``. It will first check if ``default_part_size`` is sufficient for a part size given the ``size_in_bytes``. If this is not the case, then the smallest part size than can accomodate a file of size ``size_in_bytes`` will be returned. If the file size is greater than the maximum allowed archive size of 10,000 * 4GB, a ``ValueError`` will be raised. ii'sFile size too large: %sii(t _MEGABYTEtMAXIMUM_NUMBER_OF_PARTSt ValueErrortmathtldexptint(t size_in_bytestdefault_part_sizet part_sizet min_part_sizetpower((s?/opt/freeware/lib/python2.7/site-packages/boto/glacier/utils.pytminimum_part_size"s cCsttjt|ƒt|ƒƒƒ}g}xOt|ƒD]A}||}|d|}|jtj|||!ƒj ƒƒq8W|s™tjdƒj ƒgS|S(Nit( RRtceiltlentfloattrangetappendthashlibtsha256tdigest(t bytestringt chunk_sizet chunk_countthashestitstarttend((s?/opt/freeware/lib/python2.7/site-packages/boto/glacier/utils.pyt chunk_hashesJs% 'cCsÙg}|j|ƒx»t|ƒdkrÐg}xtr¿t|ƒdkrŠ|jdƒ}|jdƒ}|jtj||ƒjƒƒq1t|ƒdkr»|jdƒ}|j|ƒq1Pq1W|j|ƒqW|dS(s¤ Given a hash of each 1MB chunk (from chunk_hashes) this will hash together adjacent hashes until it ends up with one big one. So a tree of hashes. ii(textendRtTruetpopRRRR(tfoRt new_hashestfirsttsecondtonly((s?/opt/freeware/lib/python2.7/site-packages/boto/glacier/utils.pyt tree_hashVs  #cCs tjr6t|dƒr6d|jkr6tdƒ‚ntjƒ}g}|j|ƒ}xu|rÎt|t ƒs“|j t |ddƒpŠdƒ}n|j |ƒ|j tj|ƒjƒƒ|j|ƒ}qZW|sðtjdƒjƒg}n|jƒtt|ƒƒfS(sÎCompute the linear and tree hash from a fileobj. This function will compute the linear/tree hash of a fileobj in a single pass through the fileobj. :param fileobj: A file like object. :param chunk_size: The size of the chunks to use for the tree hash. This is also the buffer size used to read from `fileobj`. :rtype: tuple :return: A tuple of (linear_hash, tree_hash). Both hashes are returned in hex. tmodetbs/File-like object must be opened in binary mode!tencodingR sutf-8(RtPY3thasattrR'RRRtreadt isinstancetbytestencodetgetattrtupdateRRt hexdigestt bytes_to_hexR&(tfileobjRt linear_hashtchunkstchunk((s?/opt/freeware/lib/python2.7/site-packages/boto/glacier/utils.pytcompute_hashes_from_fileobjns'  $ cCs tj|ƒS(N(tbinasciithexlify(t str_as_bytes((s?/opt/freeware/lib/python2.7/site-packages/boto/glacier/utils.pyR3”scCsttt|ƒƒƒS(s² :type str_as_bytes: str :param str_as_bytes: The string for which to compute the tree hash. :rtype: str :return: The computed tree hash, returned as hex. (R3R&R(R;((s?/opt/freeware/lib/python2.7/site-packages/boto/glacier/utils.pyttree_hash_from_str˜s tResettingFileSendercBseZd„Zd„ZRS(cCs||_|jƒ|_dS(N(t_archivettellt_starting_offset(tselftarchive((s?/opt/freeware/lib/python2.7/site-packages/boto/glacier/utils.pyt__init__¦s cCsBz'|j|||j|ƒ|jƒSWd|jj|jƒXdS(N(trequestR>t getresponsetseekR@(RAt connectiontmethodtpathtbodytheaders((s?/opt/freeware/lib/python2.7/site-packages/boto/glacier/utils.pyt__call__ªs(t__name__t __module__RCRL(((s?/opt/freeware/lib/python2.7/site-packages/boto/glacier/utils.pyR=¥s ii(RRR9t boto.compatRRtDEFAULT_PART_SIZERR RR&R8R3R<tobjectR=(((s?/opt/freeware/lib/python2.7/site-packages/boto/glacier/utils.pyts     (  &