From 3c3d26f172cfbde78f60e358b847b541d71c5632 2015-07-21 13:58:00 From: Lance Edgar Date: 2015-07-21 13:58:00 Subject: [PATCH] Add `files.locking_copy_old()` function. Something *did* appear to change regarding the behavior of the newer `locking_copy()` function. Making the old one available again at least temporarily, until the issue is settled. --- diff --git a/rattail/files.py b/rattail/files.py index f63da541d0d892082582f256a369b73ec824808a..5ef4cef846d6440f72ac02d2aba58217665abc52 100644 --- a/rattail/files.py +++ b/rattail/files.py @@ -2,7 +2,7 @@ ################################################################################ # # Rattail -- Retail Software Framework -# Copyright © 2010-2014 Lance Edgar +# Copyright © 2010-2015 Lance Edgar # # This file is part of Rattail. # @@ -30,7 +30,6 @@ from __future__ import unicode_literals import io import os -import os.path import shutil import lockfile import tempfile @@ -133,6 +132,45 @@ def locking_copy(src, destdir, timeout=None): os.rmdir(lockdir) +def locking_copy_old(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 overwriting_move(src, dst): """ Convenience function which is equivalent to ``shutil.move()``, except it