From 32a4bd9c16271a477e2c7e3c01487009d6054bac Mon Sep 17 00:00:00 2001 From: Markus Unterwaditzer Date: Sat, 14 Feb 2015 18:14:39 +0100 Subject: [PATCH] Better documentation for mtime-helpers --- vdirsyncer/utils/__init__.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/vdirsyncer/utils/__init__.py b/vdirsyncer/utils/__init__.py index 522daeb..84cfba0 100644 --- a/vdirsyncer/utils/__init__.py +++ b/vdirsyncer/utils/__init__.py @@ -256,12 +256,30 @@ def request(method, url, session=None, latin1_fallback=True, def get_etag_from_file(fpath): - return '{:.9f}'.format(os.path.getmtime(fpath)) + '''Get mtime-based etag from a filepath.''' + stat = os.stat(fpath) + mtime = getattr(stat, 'st_mtime_ns', None) + if mtime is None: + mtime = stat.st_mtime + return '{:.9f}'.format(mtime) def get_etag_from_fileobject(f): - f.flush() - os.fsync(f.fileno()) + ''' + Get mtime-based etag from a local file's fileobject. + + This function will flush/sync the file as much as necessary to obtain a + correct mtime. + + In filesystem-based storages, this is used instead of + :py:func:`get_etag_from_file` to determine the correct etag *before* + writing the temporary file to the target location. + + This works because, as far as I've tested, moving and linking a file + doesn't change its mtime. + ''' + f.flush() # Only this is necessary on Linux + os.fsync(f.fileno()) # Apparently necessary on Windows return get_etag_from_file(f.name)