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