def save_container(container, path): if container.is_dir: return save_dir_container(container, path) temp = PersistentTemporaryFile(prefix=('_' if iswindows else '.'), suffix=os.path.splitext(path)[1], dir=os.path.dirname(path)) if hasattr(os, 'fchmod'): # Ensure file permissions and owner information is preserved fno = temp.fileno() st = None try: st = os.stat(path) except OSError as err: if err.errno != errno.ENOENT: raise # path may not exist if we are saving a copy, in which case we use # the metadata from the original book try: st = os.stat(container.path_to_ebook) except OSError as err: if err.errno != errno.ENOENT: raise # Somebody deleted the original file if st is not None: try: os.fchmod(fno, st.st_mode) except OSError as err: if err.errno != errno.EPERM: raise raise OSError( 'Failed to change permissions of {} to {} ({}), with error: {}. Most likely the {} directory has a restrictive umask' .format(temp.name, oct(st.st_mode), format_permissions(st.st_mode), errno.errorcode[err.errno], os.path.dirname(temp.name))) try: os.fchown(fno, st.st_uid, st.st_gid) except OSError as err: if err.errno not in (errno.EPERM, errno.EACCES): # ignore chown failure as user could be editing file belonging # to a different user, in which case we really can't do anything # about it short of making the file update non-atomic raise temp.close() temp = temp.name try: container.commit(temp) atomic_rename(temp, path) finally: if os.path.exists(temp): os.remove(temp)
def save_container(container, path): if container.is_dir: return save_dir_container(container, path) temp = PersistentTemporaryFile( prefix=('_' if iswindows else '.'), suffix=os.path.splitext(path)[1], dir=os.path.dirname(path)) if hasattr(os, 'fchmod'): # Ensure file permissions and owner information is preserved fno = temp.fileno() st = None try: st = os.stat(path) except EnvironmentError as err: if err.errno != errno.ENOENT: raise # path may not exist if we are saving a copy, in which case we use # the metadata from the original book try: st = os.stat(container.path_to_ebook) except EnvironmentError as err: if err.errno != errno.ENOENT: raise # Somebody deleted the original file if st is not None: try: os.fchmod(fno, st.st_mode) except EnvironmentError as err: if err.errno != errno.EPERM: raise raise EnvironmentError('Failed to change permissions of %s to %s (%s), with error: %s. Most likely the %s directory has a restrictive umask' % ( temp.name, oct(st.st_mode), format_permissions(st.st_mode), errno.errorcode[err.errno], os.path.dirname(temp.name))) try: os.fchown(fno, st.st_uid, st.st_gid) except EnvironmentError as err: if err.errno not in (errno.EPERM, errno.EACCES): # ignore chown failure as user could be editing file belonging # to a different user, in which case we really cant do anything # about it short of making the file update non-atomic raise temp.close() temp = temp.name try: container.commit(temp) atomic_rename(temp, path) finally: if os.path.exists(temp): os.remove(temp)