mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-03-25 08:55:50 +00:00
Use os.fstat wherever possible
This commit is contained in:
parent
d24f3835ef
commit
b3d70a7a93
2 changed files with 17 additions and 27 deletions
|
|
@ -9,8 +9,7 @@ from atomicwrites import atomic_write
|
|||
|
||||
from .base import Item, Storage, normalize_meta_value
|
||||
from .. import exceptions
|
||||
from ..utils import checkdir, expand_path, generate_href, get_etag_from_file, \
|
||||
get_etag_from_fileobject
|
||||
from ..utils import checkdir, expand_path, generate_href, get_etag_from_file
|
||||
from ..utils.compat import text_type, to_native
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
|
@ -137,7 +136,7 @@ class FilesystemStorage(Storage):
|
|||
try:
|
||||
with atomic_write(fpath, mode='wb', overwrite=False) as f:
|
||||
f.write(item.raw.encode(self.encoding))
|
||||
return fpath, get_etag_from_fileobject(f)
|
||||
return fpath, get_etag_from_file(f)
|
||||
except OSError as e:
|
||||
if e.errno == errno.EEXIST:
|
||||
raise exceptions.AlreadyExistingError(existing_href=href)
|
||||
|
|
@ -157,7 +156,7 @@ class FilesystemStorage(Storage):
|
|||
|
||||
with atomic_write(fpath, mode='wb', overwrite=True) as f:
|
||||
f.write(item.raw.encode(self.encoding))
|
||||
etag = get_etag_from_fileobject(f)
|
||||
etag = get_etag_from_file(f)
|
||||
|
||||
if self.post_hook:
|
||||
self._run_post_hook(fpath)
|
||||
|
|
|
|||
|
|
@ -53,35 +53,26 @@ def uniq(s):
|
|||
yield x
|
||||
|
||||
|
||||
def get_etag_from_file(fpath):
|
||||
'''Get mtime-based etag from a filepath.'''
|
||||
stat = os.stat(fpath)
|
||||
def get_etag_from_file(f):
|
||||
'''Get mtime-based etag from a filepath or file-like object.
|
||||
|
||||
This function will flush/sync the file as much as necessary to obtain a
|
||||
correct mtime.
|
||||
'''
|
||||
if hasattr(f, 'read'):
|
||||
f.flush() # Only this is necessary on Linux
|
||||
if sys.platform == 'win32':
|
||||
os.fsync(f.fileno()) # Apparently necessary on Windows
|
||||
stat = os.fstat(f.fileno())
|
||||
else:
|
||||
stat = os.stat(f)
|
||||
|
||||
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):
|
||||
'''
|
||||
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
|
||||
if sys.platform == 'win32':
|
||||
os.fsync(f.fileno()) # Apparently necessary on Windows
|
||||
return get_etag_from_file(f.name)
|
||||
|
||||
|
||||
def get_storage_init_specs(cls, stop_at=object):
|
||||
if cls is stop_at:
|
||||
return ()
|
||||
|
|
|
|||
Loading…
Reference in a new issue