Skip to content

Add support for ipfs files (MFS) APIs #40

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 63 additions & 3 deletions ipfsApi/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,17 @@ def __init__(self,
self._config_show = Command('/config/show')
self._config_replace = ArgCommand('/config/replace')
self._version = Command('/version')

# MFS COMMANDS
self._files_cp = ArgCommand('/files/cp')
self._files_ls = ArgCommand('/files/ls')
self._files_mkdir = ArgCommand('/files/mkdir')
self._files_stat = ArgCommand('/files/stat')
self._files_rm = ArgCommand('/files/rm')
self._files_read = ArgCommand('/files/read')
self._files_write = FileCommand('/files/write')
self._files_mv = ArgCommand('/files/mv')


def add(self, files, recursive=False, **kwargs):
"""
Expand All @@ -102,7 +113,7 @@ def add(self, files, recursive=False, **kwargs):
{u'Hash': u'QmZfF6C9j4VtoCsTp4KSrhYH47QMd3DNXVZBKaxJdhaPab',
u'Name': u'nurseryrhyme.txt'}
"""
return self._add.request(self._client, files,
return self._add.request(self._client, (), files,
recursive=recursive, **kwargs)

def get(self, multihash, **kwargs):
Expand Down Expand Up @@ -181,7 +192,7 @@ def block_put(self, file, **kwargs):
{u'Key': u'QmeV6C6XVt1wf7V7as7Yak3mxPma8jzpqyhtRtCvpKcfBb',
u'Size': 22}
"""
return self._block_put.request(self._client, file, **kwargs)
return self._block_put.request(self._client, (), file, **kwargs)

def object_data(self, multihash, **kwargs):
r"""
Expand Down Expand Up @@ -240,7 +251,7 @@ def object_get(self, multihash, **kwargs):
def object_put(self, file, **kwargs):
"""
"""
return self._object_put.request(self._client, file, **kwargs)
return self._object_put.request(self._client, (), file, **kwargs)

def object_stat(self, multihash, **kwargs):
"""
Expand Down Expand Up @@ -486,6 +497,55 @@ def version(self, **kwargs):
{u'Version': u'0.3...'}
"""
return self._version.request(self._client, **kwargs)

def files_cp(self, source, dest, **kwargs):
"""
MFS - Copy files into mfs
"""
return self._files_cp.request(self._client, source, dest, **kwargs)

def files_ls(self, path, **kwargs):
"""
MFS - List directory contents
"""
return self._files_ls.request(self._client, path, **kwargs)

def files_mkdir(self, path, **kwargs):
"""
MFS - Create directory
"""
return self._files_mkdir.request(self._client, path, **kwargs)

def files_stat(self, path, **kwargs):
"""
MFS - Display file status (including it's hash)
"""
return self._files_stat.request(self._client, path, **kwargs)

def files_rm(self, path, **kwargs):
"""
MFS - Remove a file
"""
return self._files_rm.request(self._client, path, **kwargs)

def files_read(self, path, **kwargs):
"""
MFS - Read a file stored in MFS
"""
return self._files_read.request(self._client, path, **kwargs)

def files_write(self, path, file, **kwargs):
"""
MFS - Write to a mutable file
"""
return self._files_write.request(self._client, (path,), file, **kwargs)

def files_mv(self, source, dest, **kwargs):
"""
MFS - Move MFS files
"""
return self._files_mv.request(self._client, source, dest, **kwargs)


###########
# HELPERS #
Expand Down
16 changes: 8 additions & 8 deletions ipfsApi/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,29 @@ def request(self, client, *args, **kwargs):

class FileCommand(Command):

def request(self, client, f, **kwargs):
def request(self, client, args, f, **kwargs):
"""
Takes either a file object, a filename, an iterable of filenames, an
iterable of file objects, or a heterogeneous iterable of file objects
and filenames. Can only take one directory at a time, which will be
traversed (optionally recursive).
"""
if kwargs.pop('recursive', False):
return self.directory(client, f, recursive=True, **kwargs)
return self.directory(client, args, f, recursive=True, **kwargs)
if isinstance(f, six.string_types) and os.path.isdir(f):
return self.directory(client, f, **kwargs)
return self.directory(client, args, f, **kwargs)
else:
return self.files(client, f, **kwargs)
return self.files(client, args, f, **kwargs)

def files(self, client, files, chunk_size=default_chunk_size, **kwargs):
def files(self, client, args, files, chunk_size=default_chunk_size, **kwargs):
"""
Adds file-like objects as a multipart request to IPFS.
"""
body, headers = multipart.stream_files(files,
chunk_size=chunk_size)
return client.request(self.path, data=body, headers=headers, **kwargs)
return client.request(self.path, args=args, data=body, headers=headers, **kwargs)

def directory(self, client, dirname,
def directory(self, client, args, dirname,
match='*', recursive=False,
chunk_size=default_chunk_size, **kwargs):
"""
Expand All @@ -66,7 +66,7 @@ def directory(self, client, dirname,
fnpattern=match,
recursive=recursive,
chunk_size=chunk_size)
return client.request(self.path, data=body, headers=headers, **kwargs)
return client.request(self.path, args=args, data=body, headers=headers, **kwargs)


class DownloadCommand(Command):
Expand Down
39 changes: 39 additions & 0 deletions test/functional/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,45 @@ def test_add_get_pyobject(self):
self.assertEqual(data,
self.api.get_pyobj(res))

class IpfsApiMFSTest(unittest.TestCase):

test_files = {
'/test_file1': {
u'Name': u'fake_dir/popoiopiu',
u'Stat': {u'Type': 'file',
u'Hash': 'QmUvobKqcCE56brA8pGTRRRsGy2SsDEKSxFLZkBQFv7Vvv',
u'Blocks': 1,
u'CumulativeSize': 73,
u'Size': 15}
}
}

def setUp(self):
self.api = ipfsApi.Client()
self._olddir = os.getcwd()
os.chdir(HERE)

def tearDown(self):
os.chdir(self._olddir)

def test_write_stat_read_delete(self):
for target, desc in self.test_files.items():
# Create target file
self.api.files_write(target, desc[u'Name'], opts={'create':True})

# Verify stat information of file
stat = self.api.files_stat(target)
self.assertEqual(sorted(desc[u'Stat'].items()), sorted(stat.items()))

# Read back (and compare file contents)
with open(desc[u'Name'], 'r') as file:
content = self.api.files_read(target)
self.assertEqual(content, file.read())

# Delete file
self.api.files_rm(target)



if __name__ == "__main__":
unittest.main()