This is based on an idea from Adrian Jones from the ftputil mailing list. See the thread "Conditional upload/download based on file size".
To upload/download a file after an incomplete upload/download, it should
be possible to compare the sizes in addition to the timestamps of the
files. upload_if_newer
and download_if_newer
only decide based on
the timestamp.
Adrian suggested introducing a condition
callback to let the caller
decide when the file should be transferred again.
I think the
condition
callback argument (maybe with a different name, but let's see) should be added toupload
anddownload
, notupload_if_newer
anddownload_if_newer
. Adding it to the latter methods would mix two ways to define the condition, once by the method name, once by the callback argument. Users might wonder whether a givencondition
argument is applied in addition to the timestamp check or if the callback has to implement the timestamp check on its own.Therefore, I'd add the callback argument to
upload
anddownload
and implementupload_if_newer
anddownload_if_newer
in terms of that. To make the new feature directly useful, ftputil should provide a callback to compare timestamps and one to compare sizes. The*_if_newer
methods would then use the pre-defined timestamp comparison callback.It might be tricky to come up with a good interface for the callbacks. At the moment, the comparison is done on
file_transfer.LocalFile
andfile_transfer.RemoteFile
objects and I'm not sure of how much of this should be exposed to ftputil client code. So far, the module isn't described in the official documentation.When adding the condition callback to
upload
anddownload
, there's a potential source of confusion because these methods already have acallback
argument that works on chunks of the transferred data. (This can be used for GUI progress bars, for example.) For backward compatibility, I wouldn't want to rename the existingcallback
argument.
To change the conditional logic, or to supply a function to provide the conditional logic, it seems
LocalFile
&RemoteFile
objects must exposed for useful properties to be available.If so, perhaps expose the
RemoteFile
object then add atransfer_condition
method containing the existing logic which is called bycopy_file
, this could be subclassed and overridden to extend the conditional logic.e.g.
class MyRemoteFile(ftuputil.file_transfer.Remote_file): def transfer_condition(self, source_file, target_file): return target_file.exists() or \ ... other logic
Although I'm not sure how the FTPHost would then use this subclass, perhaps some kind of file_factory of the FTPHost? And this really depends on the decision whether the
LocalFile
&RemoteFile
objects should be exposed. Otherwise, it seems the only way is to add methods for each conditional case, e.g., checking file size,upload_if_different
?