diff --git a/ipfshttpclient/client/files.py b/ipfshttpclient/client/files.py index 2dcbd8e7..2e9b4923 100644 --- a/ipfshttpclient/client/files.py +++ b/ipfshttpclient/client/files.py @@ -329,7 +329,7 @@ def file_ls(self, multihash, **kwargs): return self._client.request('/file/ls', args, decoder='json', **kwargs) - def get(self, multihash, **kwargs): + def get(self, multihash, filepath=None, filename=None, **kwargs): """Downloads a file, or directory of files from IPFS. Files are placed in the current working directory. @@ -338,9 +338,16 @@ def get(self, multihash, **kwargs): ---------- multihash : str The path to the IPFS object(s) to be outputted + filepath : str + The local directory where IPFS will store downloaded files + + Defaults to the current working directory. + If the directory does not exist, it will be created. + filename : str + The filename to store the file as. """ args = (multihash,) - return self._client.download('/get', args, **kwargs) + return self._client.download('/get', args, filepath=filepath, filename=filename, **kwargs) def cat(self, multihash, offset=0, length=-1, **kwargs): @@ -406,4 +413,4 @@ def ls(self, multihash, **kwargs): dict : Directory information and contents """ args = (multihash,) - return self._client.request('/ls', args, decoder='json', **kwargs) \ No newline at end of file + return self._client.request('/ls', args, decoder='json', **kwargs) diff --git a/ipfshttpclient/http.py b/ipfshttpclient/http.py index 2d5f0ddf..24a7a4a4 100644 --- a/ipfshttpclient/http.py +++ b/ipfshttpclient/http.py @@ -11,6 +11,7 @@ import functools import re import tarfile +import shutil from six.moves import http_client import requests @@ -247,7 +248,7 @@ def request(self, path, files, headers, data) @pass_defaults - def download(self, path, args=[], filepath=None, opts={}, + def download(self, path, args=None, filepath=None, filename=None, opts={}, compress=True, **kwargs): """Makes a request to the IPFS daemon to download a file. @@ -267,9 +268,12 @@ def download(self, path, args=[], filepath=None, opts={}, path : str The REST command path to send filepath : str - The local path where IPFS will store downloaded files + The local directory where IPFS will store downloaded files Defaults to the current working directory. + If the directory does not exist, it will be created. + filename : str + The filename to store the file as. args : list Positional parameters to be sent along with the HTTP request opts : dict @@ -280,6 +284,8 @@ def download(self, path, args=[], filepath=None, opts={}, kwargs : dict Additional arguments to pass to :mod:`requests` """ + if not args: + args = [] url = self.base + path wd = filepath or '.' @@ -307,6 +313,11 @@ def download(self, path, args=[], filepath=None, opts={}, with tarfile.open(fileobj=res.raw, mode=mode) as tf: tf.extractall(path=wd) + if type(filename) is str: + # Assume that arg 0 is multihash. Not great. + old_name = args[0] + shutil.move((wd + '/' + old_name), (wd + '/' + filename)) + @contextlib.contextmanager def session(self): """A context manager for this client's session. diff --git a/test/functional/test_files.py b/test/functional/test_files.py index 5c64faba..2e9600b5 100644 --- a/test/functional/test_files.py +++ b/test/functional/test_files.py @@ -165,6 +165,32 @@ def test_get_file(client, cleanup_pins): assert test_hash not in os.listdir(os.getcwd()) +def test_get_file_filepath(client, cleanup_pins): + client.add(FAKE_FILE1_PATH) + + test_hash = FAKE_DIR_HASH[1]["Hash"] + filepath = os.getcwd() + "/test_downloads" + try: + client.get(test_hash, filepath=filepath) + assert test_hash in os.listdir(filepath) + finally: + os.remove(filepath + "/" + test_hash) + assert test_hash not in os.listdir(filepath) + + +def test_get_file_filename(client, cleanup_pins): + client.add(FAKE_FILE1_PATH) + + test_hash = FAKE_DIR_HASH[1]["Hash"] + filename = "foo" + try: + client.get(test_hash, filename=filename) + assert filename in os.listdir(os.getcwd()) + finally: + os.remove(filename) + assert filename not in os.listdir(os.getcwd()) + + def test_get_dir(client, cleanup_pins): client.add(FAKE_DIR_PATH, recursive=True) @@ -267,4 +293,4 @@ def test_mfs_dir_make_fill_list_delete(client): client.files.rm(TEST_MFS_DIRECTORY, recursive=True) with pytest.raises(ipfshttpclient.exceptions.Error): - client.files.stat(TEST_MFS_DIRECTORY) \ No newline at end of file + client.files.stat(TEST_MFS_DIRECTORY)