# Path: filetracker/utils.py
# def file_digest(source):
#     """Calculates SHA256 digest of a file.
# 
#     Args:
#         source: either a file-like object or a path to file
#     """
#     hash_sha256 = hashlib.sha256()
# 
#     should_close = False
# 
#     if isinstance(source, six.string_types):
#         should_close = True
#         source = open(source, 'rb')
# 
#     for chunk in iter(lambda: source.read(_BUFFER_SIZE), b''):
#         hash_sha256.update(chunk)
# 
#     if should_close:
#         source.close()
# 
#     return hash_sha256.hexdigest()


import contextlib
import email.utils
import errno
import fcntl
import gevent
import gzip
import logging
import os
import shutil
import subprocess
import sys
import tempfile
import bsddb3
import six
from filetracker.utils import file_digest
                If specified, the digest will not be computed again, saving
                resources.
            logical_size: if ``data`` is gzip-compressed, this parameter
                has to be set to decompressed file size.
        """
        with _exclusive_lock(self._lock_path('links', name)):
            logger.debug('Acquired lock to link for %s.', name)
            link_path = self._link_path(name)
            if _path_exists(link_path) and _file_version(link_path) > version:
                logger.info(
                    'Tried to store older version of %s (%d < %d), ignoring.',
                    name,
                    version,
                    _file_version(link_path),
                )
                return _file_version(link_path)

            # data is managed by contents now, and shouldn't be used directly
            with _InputStreamWrapper(data, size) as contents:
                if digest is None or logical_size is None:
                    contents.save()
                    if compressed:
                        # This shouldn't occur if the request came from a proper
                        # filetracker client, so we don't care if it's slow.
                        logger.warning('Storing compressed stream without hints.')
                        with gzip.open(contents.current_path, 'rb') as decompressed:
                            digest = file_digest(decompressed)
                        with gzip.open(contents.current_path, 'rb') as decompressed:
                            logical_size = _read_stream_for_size(decompressed)
                    else:

# Path: filetracker/utils.py
# def file_digest(source):
#     """Calculates SHA256 digest of a file.
# 
#     Args:
#         source: either a file-like object or a path to file
#     """
#     hash_sha256 = hashlib.sha256()
# 
#     should_close = False
# 
#     if isinstance(source, six.string_types):
#         should_close = True
#         source = open(source, 'rb')
# 
#     for chunk in iter(lambda: source.read(_BUFFER_SIZE), b''):
#         hash_sha256.update(chunk)
# 
#     if should_close:
#         source.close()
# 
#     return hash_sha256.hexdigest()


# Path: filetracker/servers/storage.py
import contextlib
import email.utils
import errno
import fcntl
import gevent
import gzip
import logging
import os
import shutil
import subprocess
import sys
import tempfile
import bsddb3
import six
from filetracker.utils import file_digest

                If specified, the digest will not be computed again, saving
                resources.
            logical_size: if ``data`` is gzip-compressed, this parameter
                has to be set to decompressed file size.
        """
        with _exclusive_lock(self._lock_path('links', name)):
            logger.debug('Acquired lock to link for %s.', name)
            link_path = self._link_path(name)
            if _path_exists(link_path) and _file_version(link_path) > version:
                logger.info(
                    'Tried to store older version of %s (%d < %d), ignoring.',
                    name,
                    version,
                    _file_version(link_path),
                )
                return _file_version(link_path)

            # data is managed by contents now, and shouldn't be used directly
            with _InputStreamWrapper(data, size) as contents:
                if digest is None or logical_size is None:
                    contents.save()
                    if compressed:
                        # This shouldn't occur if the request came from a proper
                        # filetracker client, so we don't care if it's slow.
                        logger.warning('Storing compressed stream without hints.')
                        with gzip.open(contents.current_path, 'rb') as decompressed:
                            digest = file_digest(decompressed)
                        with gzip.open(contents.current_path, 'rb') as decompressed:
                            logical_size = _read_stream_for_size(decompressed)
                    else:

                        digest = file_digest(contents.current_path)