Skip to content
This repository has been archived by the owner on Aug 11, 2020. It is now read-only.

Commit

Permalink
Add edit_file support
Browse files Browse the repository at this point in the history
Following what the Perl API does, the edit_file
method is implemented to fetch an existing and
new URL from the tracker, DAV MOVE from one to
the other and then pass back a mutable file.

Upon closing the file, a length of `-1` is
supplied to avoid having to keep an accurate
internal counter in LargeHTTPFile.
  • Loading branch information
insom committed Nov 14, 2011
1 parent f51e9ab commit 3b954c1
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 18 deletions.
28 changes: 27 additions & 1 deletion pymogile/client.py
Expand Up @@ -9,6 +9,8 @@
from pymogile.backend import Backend
from pymogile.exceptions import MogileFSError
from pymogile.file import NormalHTTPFile, LargeHTTPFile
from urlparse import urlparse
import httplib


class Client(object):
Expand Down Expand Up @@ -121,7 +123,31 @@ def edit_file(self, key, overwrite=False):
By default, the file contents are preserved on open, but you may specify the overwrite option to zero the file first.
The seek position is at the beginning of the file, but you may seek to the end to append.
"""
raise NotImplementedError()
params = {'domain': self.domain,
'key': key}
res = self.backend.do_request('edit_file', params)
if not res:
return None
# {'newpath': 'http://.../0000000594.fid', 'devid': '1', 'oldpath': 'http://.../0000000593.fid', 'fid': '594', 'class': '0'}

bits = urlparse(res['oldpath'])

c = httplib.HTTPConnection(bits.netloc)
c.request('MOVE', bits.path, headers={'Destination': res['newpath']})
cres = c.getresponse()
if cres.status != 201:
return None

main_devid, main_path, cls = res['devid'], res['newpath'], res['class']

return LargeHTTPFile(mg=self,
fid=res['fid'],
path=main_path,
devid=main_devid,
cls=cls,
key=key,
overwrite=overwrite,
mutate_file=True)

def read_file(self, key):
"""
Expand Down
5 changes: 4 additions & 1 deletion pymogile/file.py
Expand Up @@ -127,6 +127,7 @@ def __init__(self,
key=None,
readonly=False,
create_close_arg=None,
mutate_file=False,
**kwds):

super(LargeHTTPFile, self).__init__(mg, fid, key, cls, create_close_arg)
Expand Down Expand Up @@ -162,6 +163,8 @@ def __init__(self,
self._pos = 0
self._eof = 0

self.mutate_file = mutate_file

def read(self, n= -1):
if self._is_closed:
return False
Expand Down Expand Up @@ -226,7 +229,7 @@ def close(self):
'fid': self.fid,
'devid': self.devid,
'domain': self.mg.domain,
'size': self.length,
'size': self.mutate_file and -1 or self.length,
'key': self.key,
'path': self.path,
}
Expand Down
32 changes: 16 additions & 16 deletions tests/test_client.py
Expand Up @@ -241,22 +241,22 @@ def test_mkcol(self):
self.assertTrue(paths)


# def test_edit_file(self):
# cl = Client(TEST_NS, HOSTS)
# key = 'test_file_%s_%s' % (random.random(), time.time())
#
# cl.store_content(key, "SPAM")
# assert cl.get_paths(key)
# assert cl.get_file_data(key) == "SPAM"
#
# fp = cl.edit_file(key)
# assert fp
# fp.write("s")
# fp.seek(2)
# fp.write("a")
# fp.close()
#
# assert cl.get_file_data(key) == "sPaM"
def test_edit_file(self):
cl = Client(TEST_NS, HOSTS)
key = 'test_file_%s_%s' % (random.random(), time.time())

cl.store_content(key, "SPAM")
self.assertTrue(cl.get_paths(key))
self.assertEqual("SPAM", cl.get_file_data(key))

fp = cl.edit_file(key)
self.assertTrue(fp)
fp.write("s")
fp.seek(2)
fp.write("a")
fp.close()

self.assertEqual("sPaM", cl.get_file_data(key))

def test_file_like_object(self):
client = Client(TEST_NS, HOSTS)
Expand Down

0 comments on commit 3b954c1

Please sign in to comment.