Changeset - d9b506352a89
[Not reviewed]
0 1 0
Lance Edgar - 9 years ago 2015-07-04 14:31:33
ledgar@sacfoodcoop.com
Change behavior of `files.locking_copy()` function.

The test function has been doing its job well, I'm calling it the better
function at this point.
1 file changed with 7 insertions and 40 deletions:
0 comments (0 inline, 0 general)
rattail/files.py
Show inline comments
 
@@ -26,24 +26,25 @@ File Utilities
 
This module contains various utility functions for use with the filesystem.
 
"""
 

	
 
from __future__ import unicode_literals
 

	
 
import io
 
import os
 
import os.path
 
import shutil
 
import lockfile
 
import tempfile
 
import errno
 
import warnings
 
from datetime import datetime
 

	
 
import pkg_resources
 

	
 
from rattail.exceptions import PathNotFound
 

	
 

	
 
def count_lines(path, encoding=None):
 
    """
 
    Counts the number of lines in a text file.  Some attempt is made to ensure
 
    cross-platform compatibility.
 

	
 
@@ -68,80 +69,46 @@ def creation_time(path):
 

	
 
    :param path: Path to the file.
 
    :type path: string
 

	
 
    :returns: The creation timestamp for the file.
 
    :rtype: ``datetime.datetime`` instance
 
    """
 

	
 
    time = os.path.getctime(path)
 
    return datetime.fromtimestamp(time)
 

	
 

	
 
def locking_copy(src, dst, timeout=None):
 
    """
 
    Implements a "locking" version of the standard library's
 
    :func:`python:shutil.copy()` function.
 

	
 
    This exists to provide a more atomic method for copying a file into a
 
    folder which is being watched by a file monitor.  The assumption is that
 
    the monitor is configured to watch for file "locks" and therefore only
 
    process files once they have had their locks removed.  See also
 
    :ref:`filemon-profile-watchlocks`.
 

	
 
    :param src: Path to the source file.
 
    :type src: string
 

	
 
    :param dst: Path to the destination file (or directory).
 
    :type dst: string
 

	
 
    :type timeout: float
 
    :param timeout: Number of seconds to wait for the file lock to clear, if it
 
       already exists.  This value may be specified as an integer or float, or
 
       string (which will be coerced to a float).
 

	
 
       .. note::
 
          There is no default value for the timeout, which means that by
 
          default, the function will wait indefinitely for the lock to clear.
 
    """
 
    # Coerce timeout to float in case it isn't already, e.g. in the case of
 
    # being called as a filemon action.
 
    if timeout is not None:
 
        timeout = float(timeout)
 

	
 
    if os.path.isdir(dst):
 
        fn = os.path.basename(src)
 
        dst = os.path.join(dst, fn)
 

	
 
    with lockfile.LockFile(dst, timeout=timeout):
 
        shutil.copy(src, dst)
 

	
 

	
 
def locking_copy_test(src, destdir):
 
def locking_copy(src, destdir, timeout=None):
 
    """
 
    Implements a "locking" version of the standard library's
 
    :func:`python:shutil.copy()` function.
 

	
 
    This exists to provide a more atomic method for copying a file into a
 
    folder which is being watched by a file monitor.  The assumption is that
 
    the monitor is configured to watch for file "locks" and therefore only
 
    process files once they have had their locks removed.  See also
 
    :ref:`filemon-profile-watchlocks`.
 

	
 
    :param src: Path to the source file.
 
    :type src: string
 

	
 
    :param destdir: Path to the destination directory.
 
    :type destdir: string
 
    """
 
    # TODO: Remove the timeout arg altogether.
 
    if timeout is not None:
 
        warnings.warn("The 'timeout' arg is deprecated and will be ignored.",
 
                      DeprecationWarning)
 

	
 
    fn = os.path.basename(src)
 
    dst = os.path.join(destdir, fn)
 
    lockdir = '{0}.lock'.format(dst)
 

	
 
    # Note that we normalize two separate errors to PathNotFound below.  This
 
    # is because the file monitor retry mechanism will fail if two distinct
 
    # error types are encountered.  Since this function needs to be somewhat
 
    # robust in the face of network problems, raising a common error type will
 
    # give us a better chance at being retried (if so configured).
 

	
 
    # Attempt to create the lock dir.  We ignore "file exists" error here since
 
    # it's possible this function may be called mutliple times as part of a
0 comments (0 inline, 0 general)