Collective files
Project description
collective.zfile is a package for ZODB that allows you to manage files in a distributed way, using multiple storages.
It is still under development
It’s main features are the following:
Multiple storage management The idea is to support a large amount of large files, so it is possible to manage multiple file storages.
Revision control Using zc.vault it supports revisions, similar to SCM system, revisions are seen as transactions, each transaction you make will end up as a revision in the file system.
Lock support Is is possible to lock files and folders in two ways: exclusive locks and shared locks, you can ask for any of this types of locks on any file, in a directory it can be recursive.
Multiple mount points You can mount a zfolder in multiple ZODB mount points, using zc.mountpoint.using zc.mountpoint.
Usage:
In order to use collective.zfile there are four main objects to interact with:
ZStorageManager
ZBase
ZFile
>>> from collective.zfile import ZStorageManager, ZBase >>> import transaction
You can create a storage this way
>>> storage = ZStorageManager() >>> storage.add_storage('test_storage') >>> app['storage'] = storage
Once you have at least one physical storage you can create a base, a base is similar to a complete filesystem.
>>> base = ZBase(storage)
It needs a connection to database so we save it AND commit.
>>> app['base'] = base >>> transaction.commit()
We are ready to go, we can now create a new ZRevision and use get our root folder
>>> revision = base.new_revision() >>> root = revision.root
Now we are good to go! we can keep working with this revision or just save it.
Let’s just save it for now
>>> revision.save_revision()
Let’s add a subdirectory called test
>>> test = root.newdir('test') Traceback (most recent call last): ... FrozenError
Oops!! Error #1, we cannot modify anything after saving a revision.
Lets try again
>>> revision = base.new_revision() >>> root = revision.root
Remember always to get the new root object when creating a revision
>>> test = root.newdir('test')
Newdir gives us a reference to the new created dir, but we could also do:
>>> test = root['test'] >>> test1 = test.newdir('test1')
And we can work with files as well
>>> file = test1.newfile("test.txt") >>> f = file.open("w") >>> f.write('Hello world') >>> f.close()
And we can check it is ok!
>>> file.mimetype() 'text/plain' >>> f = file.open('r') >>> f.read() 'Hello world' >>> f.close()
Let’s try all the process at once.
>>> html = test1.newfile("index.html") >>> f = html.open("w") >>> f.write("<html><head><title>Test</title><body>Hello Test</body></head></html>") >>> f.close()
>>> html.mimetype() 'text/html'
>>> new_file = file.renew() >>> f = new_file.open('a') >>> f.write('\nHello newline') >>> f.close()
>>> f = new_file.open('r') >>> f.read() 'Hello world\nHello newline' >>> f.close()
>>> revision.save_revision() >>> transaction.commit()
TODO: Lock doctests
TODO: Implement mountpoints