{ "info": { "author": "Martijn Faassen, Infrae", "author_email": "faassen@startifact.com", "bugtrack_url": null, "classifiers": [ "Framework :: Zope3", "Programming Language :: Python", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "hurry.file fields\n=================\n\nThe file widget is built on top of the HurryFile object:\n\n >>> from hurry.file import HurryFile\n >>> file = HurryFile('foo.txt', 'mydata')\n >>> file.filename\n 'foo.txt'\n >>> file.data\n 'mydata'\n >>> file.size\n 6\n >>> f = file.file\n >>> f.read()\n 'mydata'\n\nHurryFile objects are equal if data and filename of two of them match:\n\n >>> file1 = HurryFile('foo.txt', 'mydata')\n >>> file2 = HurryFile('foo.txt', 'mydata')\n >>> file3 = HurryFile('bar.txt', 'otherdata')\n >>> file1 == file2\n True\n\n >>> file1 != file2\n False\n\n >>> file1 == file3\n False\n\n >>> file1 != file3\n True\n\nWe can also create HurryFile objects from file-like objects:\n\n >>> from StringIO import StringIO\n >>> from zope import component\n >>> from hurry.file.interfaces import IFileRetrieval\n >>> fileretrieval = component.getUtility(IFileRetrieval)\n >>> file = fileretrieval.createFile('bar.txt', StringIO('test data'))\n >>> file.filename\n 'bar.txt'\n >>> file.size\n 9\n >>> file.data\n 'test data'\n >>> f = file.file\n >>> f.read()\n 'test data'\n\nThis does exactly the same, but may be easier to use:\n\n >>> from hurry.file import createHurryFile\n >>> file = createHurryFile('test2.txt', StringIO('another test file'))\n >>> file.filename\n 'test2.txt'\n >>> file.size\n 17\n\nThe HurryFile object normally stores the file data using ZODB\npersistence. Files can however also be stored by tramline. If\ntramline is installed in Apache, the Tramline takes care of generating\nids for files and storing the file on the filesystem directly. The ids\nare then passed as file data to be stored in the ZODB.\n\nLet's first enable tramline.\n\nThe tramline directory structure is a directory with two subdirectories,\none called 'repository' and the other called 'upload':\n\n >>> import tempfile, os\n >>> dirpath = tempfile.mkdtemp()\n >>> repositorypath = os.path.join(dirpath, 'repository')\n >>> uploadpath = os.path.join(dirpath, 'upload')\n >>> os.mkdir(repositorypath)\n >>> os.mkdir(uploadpath)\n\nWe create a TramlineFileRetrieval object knowing about this directory,\nand register it as a utility:\n\n >>> from hurry.file.file import TramlineFileRetrievalBase\n >>> class TramlineFileRetrieval(TramlineFileRetrievalBase):\n ... def getTramlinePath(self):\n ... return dirpath\n >>> retrieval = TramlineFileRetrieval()\n >>> component.provideUtility(retrieval, IFileRetrieval)\n\nNow let's store a file the way tramline would during upload:\n\n >>> f = open(os.path.join(repositorypath, '1'), 'wb')\n >>> f.write('test data')\n >>> f.close()\n\nThe file with underlying name '1' (the data stored in the ZODB will be\njust '1') will now be created:\n\n >>> file = HurryFile('foo.txt', '1')\n\nThe data is now '1', referring to the real file:\n\n >>> file.data\n '1'\n\nRetrieving the file results in the real file:\n\n >>> f = file.file\n >>> f.read()\n 'test data'\n\nWe can also retrieve its size:\n\n >>> file.size\n 9L\n\nIt should be possible to create Hurry File objects that are stored in\nthe directory structure directly:\n\n >>> file = retrieval.createFile('test.txt', StringIO('my test data'))\n >>> file.filename\n 'test.txt'\n\nWe get an id for the data now:\n\n >>> file.data != 'my test data'\n True\n\nAnd we can retrieve the file itself:\n\n >>> f = file.file\n >>> f.read()\n 'my test data'\n >>> file.size\n 12L\n\nNow let's disable tramline in our utility:\n\n >>> class TramlineFileRetrieval(TramlineFileRetrievalBase):\n ... def getTramlinePath(self):\n ... return dirpath\n ... def isTramlineEnabled(self):\n ... return False\n >>> component.provideUtility(TramlineFileRetrieval(), IFileRetrieval)\n\nWe expect the same behavior as when tramline is not installed:\n\n >>> file = HurryFile('foo.txt', 'data')\n >>> f = file.file\n >>> f.read()\n 'data'\n >>> file.size\n 4\n\nClean up:\n\n >>> import shutil\n >>> shutil.rmtree(dirpath)\n\nhurry.file widgets\n==================\n\nThis is an infrastructure to create a file widget that behaves as much\nas possible like a normal text widget in formlib. Normally a file\nwidget loses its file data when a form is re-presented for reasons of\nfailing form validation. A ``hurry.file`` widget retains the file, for\nexample by storing it in a session.\n\nIn order to do this, we have a special way to store file data along with\nits filename::\n\n >>> from hurry.file import HurryFile\n >>> some_file = HurryFile('foo.txt', 'the contents')\n >>> some_file.filename\n 'foo.txt'\n >>> some_file.data\n 'the contents'\n\nWe can provide a download widget. In this case, there's nothing\nto download::\n\n >>> from hurry.file.browser import DownloadWidget\n >>> from hurry.file.schema import File\n >>> from zope.publisher.browser import TestRequest\n >>> field = File(__name__='foo', title=u'Foo')\n >>> field = field.bind(None)\n >>> request = TestRequest()\n >>> widget = DownloadWidget(field, request)\n >>> widget()\n u'