An add-on Plone product which provides an extra storage for Archetypes.
ExternalStorage is a storage for Archetypes storing the fields contents outside the ZODB. So it works in a fashion like ExternalFile or similar products.
ExternalStorage is not actively maintained anymore. For new Plone 3.x sites or higher, please have a look at plone.app.blob.
ExternalStorage 0.6 requires an Archetypes version after 1.3.3-final. Older Archetypes versions have critical bugs and won’t work with this version of ExternalStorage.
Simply define one of your field’s storages in a schema as ExternalStorage. (see ExternalExample in examples/).
Copy examples/ExternalExample into your Products dir.
Defining Custom Path Policy
You can provide your own path policy, just write a method on your class called ‘getExternalPath’ (or anything else that you specified at ‘path_method’ when intantiating the storage).
Some common uses include:
- Instance relative path to current portal (default): path = portal_url.getRelativeContentURL(instance)
- Instance absolute path, including portal name and all above path = ‘/’.join(instance.getPhysicalPath())
- Flat Instance UID path = instance(UID())
- Sorted by Portal Type path = instance.getTypeInfo().getId() + ‘/’ + instance.getId()
By default, files are stored accordingly policy (1). If class has multiple fields, then (1) will be a folder and the files are stored inside it, following the field names.
Remember to provide additional code to support multiple fields when providing your custom path policy.
In some previous versions there was some sort of archive support. This was implemented as a copy of the old content in some special folder.
It’s removed from the current version, but will be readded later.
0.8 - 05/11/2011
- Plone 4 compat [davisagli, maurits, SteveM]
- Package cleanup and release [aclark]
2009-11-01 Maurits van Rees <firstname.lastname@example.org> * interfaces/externalstorage.py: Removed import that breaks Plone 4 and is unused anyway. 2008-05-04 Steve McMahon <email@example.com> * Fixed example product to import permissions from CMFCore.permissions so that tests will run under Plone 3.0. Many tests failing, but this doesn't look new (91 tests with 20 failures and 2 errors). 2007-11-25 Dorneles Treméa <firstname.lastname@example.org> * utils.py, config.py, ExternalStorage.py: Removed our half baked cleanupFilename method and replaced it with the one from ATContentTypes. * tests/framework.py, tests/runalltests.py: Removed. * tests/testAdd.py, tests/testContentType.py, tests/testCut.py, tests/testEdit.py, tests/testFilename.py, tests/testImageField.py, tests/testRename.py, tests/testArchive.py, tests/testCopy.py, tests/testDelete.py, tests/testExternalStorage.py, tests/testFunctional.py, tests/testMultiField.py: Removed the old test framework infrastructure in favor of the modern './bin/zopectl test' approach. * config.py, tests/testRename.py: Removed the unnecessary IS_PLONE_2_0 flag, changing tests to use a basic API call (manage_renameObject). * tests/testRename.py: Renamed some tests and added a new one, testOldFolderRemovedFromFileSystem, which currently is failing. 2007-02-16 Jean-Paul Ladage <email@example.com> * ExternalStorage.py: Use normalizeString from plone_utils to make filenames os compatible. (Didn't remove the util.cleanupFilename method yet. Also let ES play nicer with image fields by using shutil.rmtree in the cleanupField method. 2006-09-22 Martijn Pieters <firstname.lastname@example.org> * ExternalStorage.py: Extend filesystem path generation to use directories when a ImageField with scales is used. Also made detection of the image-scale case robuster. * example/ExternalExample/__init__.py, example/ExternalExample/ExternalImage.py: Example type using an ImageField. * tests/ESTestCase.py, tests/testImageField.py, tests/data/sample.png: Tests for ImageField cases. 2006-09-21 Martijn Pieters <email@example.com> * tests/ESTestCase.py: Switched to newstyle transaction savepoints, cleaned up test-file loading. * utils.py: Replaced zLOG with the python logging module * filewrapper.py, ExternalStorage.py: Added support for ImageFields by telling the file wrapper what content class to use based on the field. Includes support for scaling images. 2005-10-25 Dorneles Treméa <firstname.lastname@example.org> * filewrapper: Made sure to not break when mimetype is None. This should fix the migration from old instances and also WebDAV renames. 2005-10-09 Dorneles Treméa <email@example.com> * config.py: Added code to check for CMFPlone version. * tests/testRename.py: Fixed compatibility with CMFPlone 2.1. * README, TODO, AUTHORS: Added '.txt' extension. * version.txt: Bumpped version to 0.7 2005-06-01 Dorneles Treméa <firstname.lastname@example.org> * ExternalStorage.py: Restored compatibility with Archetypes after the large-file fixes. An Archetypes version *after* 1.3.3-final is now officialy required. * README: Added note about the new Archetypes version required. * tests/testAdd.py, tests/testMultiField.py, tests/testFunctional.py, tests/testEdit.py, tests/testRename.py: Updated tests to the new internal format. * version.txt: Bumpped version to 0.6 2005-04-01 Dorneles Treméa <email@example.com> * ExternalStorage.py: Added a completely rewrote version supporting schemas defining multiple fields with ExternalStorage as storage. Removed the archive support for now. Added support to specify the filesystem path through a flexible way. * filewrapper.py: Added a file wrapper class to provide some nice features. Thanks to Tiran for the original idea. * tests/testAdd.py, tests/dummy.py, tests/testCut.py, tests/testFunctional.py, tests/ESTestCase.py, tests/testRename.py, tests/testCopy.py, tests/testEdit.py: Fixed some tests to the new implementation. * tests/testMultiField.py: Added to test the new multiple fields support. * tests/data/sample.zip: Replaced by another file, different from the 'sample (chars).zip' one. * README: Added note about path policy and archive. * example/ExternalExample/ComplexSample.py: Added to demonstrate the multifield support. * AUTHORS: Added note about code rewrite. * TODO: Removed finished items. Added new ones... ;-) * FileUtils.py: Removed. No more foreign code. * LICENSE.txt: Added as BSD license. * version.txt: Bumpped version to 0.5 2005-03-08 Dorneles Treméa <firstname.lastname@example.org> * ExternalStorage.py (__init__, initializeInstance, unset): Fixed a bug when an operation of copy/cut/rename is performed on multiple files at same time. Thanks to Sam Stainsby. * tests/testRename.py: Added a second ExternalArticle instance to tests, so we can demonstrate the multiple copy/cut/rename bug. * tests/testAddChars.py, tests/testEditChars.py: Removed. Fixed tests and merged the important stuff into testAdd.py and testEdit.py files. 2005-01-18 Nate Aune <email@example.com> * config.py: Added GOOD_CHARS and CHAR_MAPPING constant tables. * ExternalStorage.py (cleanupFilename): Added a method to map illegal chars to allowed ones, so we can avoid ZopeCopyError exceptions. * tests/testAddChars.py, tests/testEditChars.py: Added tests to make sure ES supports files with special characters (tests are currently failing). 2005-01-17 Dorneles Treméa <firstname.lastname@example.org> * tests/ESTestCase.py, tests/testFunctional.py: Added FunctionalTestCase class and tests (currently failing). * example/ExternalExample/ExternalArticle.py: Renamed 'file' to 'stream' to avoid a name clash. Added a 'normal_file' field for test propose. 2005-01-10 Dorneles Treméa <email@example.com> * tests/testAdd.py: Added TestMultipleAddFile testsuite. * tests/ESTestCase.py (_addFileByFileUpload): Changed to use the newly added DATAPATH instead of a fixed one. * ExternalStorage.py (initializeInstance, set): Fixed a bug when creating multiple files using ExternalStorage: the last created file was created with the content from the previous one. 2005-01-09 Dorneles Treméa <firstname.lastname@example.org> * TODO: Removed the finished 'rename' item. * tests/testAdd.py: Replaced docstring by comment. * tests/testEdit.py: Added tests for the file rename process on field edit. * example/ExternalExample/ExternalArticle.py (setFile): Removed method, now that rename-on-upload works. * ExternalStorage.py (initializeInstance): Changed to only create the archive when required. (set): Made the rename process works when uploading a file with a different name. (getBasePath, computeFilePath): Fixed to always return a normalized path. 2004-12-08 Dorneles Treméa <email@example.com> * ChangeLog, HISTORY: Added a change log file and removed the old history one. * TODO: Updated note about 'rename'. Added an entry for file stream iterator tests. * example/ExternalExample/ExternalArticle.py: Moved primary and required from 'body' to 'file' field. Added 'rename' parameter to ExternalStorage. * tests/ESTestCase.py: Changed to use a different path based on ENVIRONMENT_VARIABLE, so tests doesn't remove anything by accident. * tests/testAdd.py, tests/testContentType.py, tests/testCopy.py, tests/testCut.py, tests/testDelete.py, tests/testExternalStorage.py, tests/testFilename.py, tests/testRename.py: Splitted into different modules. Added filename/contenttype/delete test suites. * ExternalStorage.py: Reorganized code. Fixed the cleanup of filesystem garbage when deleting/moving/renaming objects at ZODB. Fixed to return the same content that was stored: StringType or File, and thus the correct filename/contenttype. Added initial code for the 'rename' behavior. Renamed _extstorage_* variables to _es_*. 2004-11-30 Dorneles Treméa <firstname.lastname@example.org> * tests/: ESTestCase.py, testArchive.py, testExternalStorage.py: Added multi-field support to tests. 2004-11-29 Dorneles Treméa <email@example.com> * tests/: testExternalStorage.py, ESTestCase.py: Renamed constants for better understanding. Added test for the parent folder rename. 2004-11-26 Dorneles Treméa <firstname.lastname@example.org> * TODO: Updated TODO list. Next features comming soon... ;-) * ExternalStorage.py: Fixed rename process: cleanupField != unset. Fixed mimetype/filename support. Standardized variable names. Renamed some private methods. * AUTHORS, Makefile, config.py, version.txt: Added config/makefile. Updated version/authors. * tests/: ESTestCase.py, testExternalStorage.py: Added tests for ContentType/Filename. Implemented testTitleChanged. * tests/testArchive.py: Added stub file for Archive tests. * FileUtils.py, example/ExternalExample/ExternalArticle.py, example/ExternalExample/StreamingFile.py: Cleaned up whitespaces. * tests/data/sample.zip: Added a ZIP sample file. * iexternalstorage.py, interfaces/__init__.py, interfaces/externalstorage.py: Added interfaces package. 2004-10-20 Dorneles Treméa <email@example.com> * tests/: ESTestCase.py, dummy.py, testExternalStorage.py: Rewrote tests. More to come... ;-) * AUTHORS, ExternalStorage.py, HISTORY, TODO, iexternalstorage.py: Cleaned up code. 2004-10-15 Christian Scholz <firstname.lastname@example.org> * iexternalstorage.py: Changed import of Interface to make it work again with recent AT. 2004-09-05 Christian Scholz <email@example.com> * ExternalStorage.py: Fixed unset() for deleting files. 2004-08-31 Christian Scholz <firstname.lastname@example.org> * example/ExternalExample/: ExternalArticle.py, StreamingFile.py: Example now using FileStream iterator. * ExternalStorage.py, tests/ESTestCase.py, tests/testExternalStorage.py: Copying/moving now working. FileStream iterator can be used (see example). 2004-06-28 Christian Scholz <email@example.com> * tests/ESTestCase.py: No clearance of data anymore right now. 2004-06-27 Christian Scholz <firstname.lastname@example.org> * ExternalStorage.py: Paths are now stored relative. Tried to make it backwards compatible. * tests/testExternalStorage.py: Tests are also working now ;-) * tests/: ESTestCase.py, __init__.py, dummy.py, framework.py, runalltests.py, testExternalStorage.py, data/test.doc: First try on adding tests. 2004-05-22 Christian Scholz <email@example.com> * example/ExternalExample/ExternalArticle.py: Made docstring for setFile() more verbose. * example/ExternalExample/ExternalArticle.py: Added example for automatically renaming the object to the filename of the uploaded field. * ExternalStorage.py: Fixed the "file data removed after object rename" bug and changed the log level from INFO to DEBUG. 2004-05-05 Christian Heimes <firstname.lastname@example.org> * ExternalStorage.py: Added disable archive feature. 2004-04-24 Christian Heimes <email@example.com> * ExternalStorage.py: Changed tab to spaces. Added fixes to the set() method. 2004-04-14 Christian Scholz <firstname.lastname@example.org> * ExternalStorage.py, HISTORY, TODO, example/ExternalExample/ExternalArticle.py: viewing of external files now actually works: - content type is stored - content type can be retrieved - ExternalExample now has some example methods for retrieving the contents of the file. 2004-03-05 Christian Scholz <email@example.com> * AUTHORS, ExternalStorage.py, FileUtils.py, HISTORY, README, TODO, __init__.py, iexternalstorage.py, refresh.txt, version.txt, example/ExternalExample/ExternalArticle.py, example/ExternalExample/README, example/ExternalExample/__init__.py, example/ExternalExample/config.py, example/ExternalExample/refresh.txt, example/ExternalExample/Extensions/Install.py, example/ExternalExample/skins/externalexample/article_view.pt: Initial import.