{ "info": { "author": "Souheil Chelfouh", "author_email": "trollfot@gmail.com", "bugtrack_url": null, "classifiers": [ "Environment :: Web Environment", "Framework :: Zope3", "Intended Audience :: Other Audience", "License :: OSI Approved :: GNU General Public License (GPL)", "Operating System :: OS Independent", "Programming Language :: Python" ], "description": "===========\ndolmen.file\n===========\n\n``dolmen.file`` allows you to manage and store files within the ZODB.\nIt takes the core functionalities of ``zope.app.file``, and simplifies\nthem, using Grok for views and adapters registrations.\n\nCompatibility\n=============\n\nIn order to make sure that our `File` implementation is complete and\nfunctional, we test it against the original ``zope.app.file`` tests::\n\n >>> from dolmen.file import NamedFile, INamedFile, FileChunk\n\nLet's test the constructor::\n\n >>> file = NamedFile()\n >>> file.contentType\n ''\n >>> file.data\n ''\n\n >>> file = NamedFile('Foobar')\n >>> file.contentType\n ''\n >>> file.data\n 'Foobar'\n\n >>> file = NamedFile('Foobar', 'text/plain')\n >>> file.contentType\n 'text/plain'\n >>> file.data\n 'Foobar'\n\n >>> file = NamedFile(data='Foobar', contentType='text/plain')\n >>> file.contentType\n 'text/plain'\n >>> file.data\n 'Foobar'\n\nLet's test the mutators::\n\n >>> file = NamedFile()\n >>> file.contentType = 'text/plain'\n >>> file.contentType\n 'text/plain'\n\n >>> file.data = 'Foobar'\n >>> file.data\n 'Foobar'\n\n >>> file.data = None\n Traceback (most recent call last):\n ...\n TypeError: Cannot set None data on a file.\n\n\nLet's test large data input::\n\n >>> file = NamedFile()\n\n Insert as string:\n\n >>> file.data = 'Foobar'*60000\n >>> file.size\n 360000\n >>> file.data == 'Foobar'*60000\n True\n\nInsert data as FileChunk::\n\n >>> fc = FileChunk('Foobar'*4000)\n >>> file.data = fc\n >>> file.size\n 24000\n >>> file.data == 'Foobar'*4000\n True\n\nInsert data from file object::\n\n >>> import cStringIO\n >>> sio = cStringIO.StringIO()\n >>> sio.write('Foobar'*100000)\n >>> sio.seek(0)\n >>> file.data = sio\n >>> file.size\n 600000\n >>> file.data == 'Foobar'*100000\n True\n\nLast, but not least, verify the interface implementation::\n\n >>> from zope.interface.verify import verifyClass\n >>> INamedFile.implementedBy(NamedFile)\n True\n >>> verifyClass(INamedFile, NamedFile)\n True\n\n\nNaming\n======\n\nWhen no name is provided, the fallback is a simple empty unicode\nstring::\n\n >>> file = NamedFile('Foobar')\n >>> file.contentType\n ''\n >>> file.data\n 'Foobar'\n >>> file.filename\n u''\n\nTo specifiy a filename, we can give it to the constructor::\n \n >>> file = NamedFile('Foobar', filename='foobar.txt')\n >>> file.data\n 'Foobar'\n >>> file.filename\n u'foobar.txt'\n\nThe filename can be both unicode or simple string::\n\n >>> file = NamedFile('Foobar', filename=u'foobar.txt')\n >>> file.data\n 'Foobar'\n >>> file.filename\n u'foobar.txt'\n\nThe filename provided had an extension : 'txt'. This extension is used\nby the NamedFile, while instanciated, to try and guess the mimetype of\nthe data::\n\n >>> file.contentType\n 'text/plain'\n\n The filename can be set later, but this won't trigger the mime\n type guess::\n \n >>> file.filename = u\"something.zip\"\n >>> file.filename\n u'something.zip'\n >>> file.contentType\n 'text/plain'\n\n\nSize\n====\n\nTo represent the size of the stored data, ``dolmen.file`` uses a\nnormalized adaptation, based on ``zope.size`` definitions::\n\n >>> from zope.size import ISized\n >>> sized = ISized(file)\n >>> sized\n \n >>> sized.sizeForSorting()\n ('byte', 6)\n >>> sized.sizeForDisplay()\n u'1 KB'\n\n\nAccess\n======\n\nIn order to access our file, ``dolmen.file`` provides a view called\n`file_publish` that sets the proper headers and returns the\ndata. Let's set up a simple environment to test that behavior::\n\n >>> from zope.component.hooks import getSite\n >>> from zope.component import getMultiAdapter\n >>> from zope.publisher.browser import TestRequest\n\n >>> root = getSite()\n >>> root['myfile'] = NamedFile('Foobar', filename='foobar.txt')\n >>> myfile = root['myfile']\n\n The `file_publish` view will adapt a INamedFile and a request and,\n when called, will return the data.\n\n >>> request = TestRequest()\n >>> view = getMultiAdapter((myfile, request), name='file_publish')\n >>> view\n \n\n\nIn the update of the view, the headers are set properly, using the\ninfo of the file::\n\n >>> view.update()\n >>> for key, value in view.response.getHeaders(): print key, repr(value)\n X-Powered-By 'Zope (www.zope.org), Python (www.python.org)'\n Content-Length '6'\n Content-Type 'text/plain'\n Content-Disposition 'attachment; filename=\"foobar.txt\"'\n >>> view.render()\n 'Foobar'\n\n\nField, download and security\n============================\n\nIn a site, the file object is rarely accessed directly. Often, it's\njust a part of a more complex object. For that matter, we have three\ndedicated components: the field, the property and the traverser.\n\n\nField and Property\n------------------\n\nA property is provided to allow a transparent use of a INamedFile component.\n\nWorking exemple\n~~~~~~~~~~~~~~~\n\n >>> from persistent import Persistent\n >>> from dolmen.file import FileProperty, FileField\n >>> from zope.interface import Interface, implements\n\n >>> class IContent(Interface):\n ... binary = FileField(title=u\"Binary data\")\n\n >>> class MyContent(Persistent):\n ... implements(IContent)\n ... binary = FileProperty(IContent['binary'])\n\n >>> root['mammoth'] = MyContent()\n >>> manfred = root['mammoth']\n >>> manfred.binary = FileChunk('Foobar')\n >>> manfred.binary\n \n\n >>> manfred.binary.data\n 'Foobar'\n\nCustom factory\n~~~~~~~~~~~~~~\n\n >>> class MyFile(NamedFile):\n ... \"\"\"My own file type.\n ... \"\"\"\n\n >>> class CustomContent(object):\n ... implements(IContent)\n ... binary = FileProperty(IContent['binary'], factory=MyFile)\n\n >>> custom = CustomContent()\n >>> custom.binary = FileChunk('Foobar')\n >>> custom.binary\n \n\nError\n~~~~~\n \n >>> class MyFalseFile(object):\n ... \"\"\"My own file type.\n ... \"\"\"\n\n >>> class FaultyContent(object):\n ... implements(IContent)\n ... binary = FileProperty(IContent['binary'], factory=MyFalseFile)\n Traceback (most recent call last):\n ...\n ValueError: Provided factory is not a valid INamedFile\n\nFields\n~~~~~~\n\nThere are two fields provided by `dolmen.file`: the FileField and the\nImageField. They are just logical separation but have a common base:: \n\n >>> from dolmen.file import IImageField, IFileField, ImageField\n >>> IImageField.extends(IFileField)\n True\n >>> isinstance(ImageField(), FileField)\n True\n\n\nTraversal\n---------\n\nThe traverser will take care of both the fetching and the security\nchecking, while accessing your data. The basic permission used to\ncheck the availability of the data, is `zope.View`.\n\nHere, we set up two principals to test this. 'jason' is a logged in\nmember with no rights while 'judith' has the `zope.View` permission\ngranted::\n\n >>> import zope.security.management as security \n >>> from zope.traversing.interfaces import ITraversable\n >>> from zope.security.testing import Principal, Participation\n\n >>> judith = Principal('zope.judith', 'Judith')\n >>> jason = Principal('zope.jason', 'Jason')\n\nWe create the interaction and try to traverse to our binary data::\n\n >>> security.newInteraction(Participation(jason))\n >>> traverser = getMultiAdapter(\n ... (manfred, request), ITraversable, 'download')\n >>> traverser\n \n >>> traverser.traverse('binary')\n Traceback (most recent call last):\n ...\n Unauthorized: binary\n >>> security.endInteraction()\n\nIt fails. An Unauthorized Error is raised. We now try with Judith::\n\n >>> security.newInteraction(Participation(judith))\n >>> traverser.traverse('binary')\n \n\nOur data is returned, wrapped in a `FilePublisher` view, ready to be\nrendered (see the Access section, for more information).\n\nWhat if we traverse to an unknown field ? Let's try::\n\n >>> traverser.traverse('zorglub')\n Traceback (most recent call last):\n ...\n NotFound: Object: , name: 'zorglub'\n\n\nEverything is fine : a NotFound error has been raised. If we try to\naccess a file that is not an INamedFile, we get another error::\n\n >>> traverser.traverse('__name__')\n Traceback (most recent call last):\n ...\n LocationError: '__name__ is not a valid INamedFile'\n\nWe gracefully end our tests::\n\n >>> security.endInteraction()\n\nEnjoy !\n\n\nChangelog\n=========\n\n0.6 (2010-11-17)\n------------------\n\n* Tested for Grok 1.2.\n\n* ``zope.testing`` dependency has been removed.\n\n* The INamedFile factory is now pluggable, in the file property. Tests\n have been added to fix that behavior.\n\n\n0.5.1 (2010-02-28)\n------------------\n\n* Added an `ISized` adapter for `INamedFile` objects. Added tests\n accordingly.\n\n\n0.5.0 (2010-02-28)\n------------------\n\n* Updated code base to be fully pep8 compatible.\n\n* `zope.app` dependencies have been entirely dropped. \n\n* ``dolmen.file`` is no longer a layer above ``zope.app.file``. It\n nows integrates the few features it needed from ``zope.app.file``.\n\n\n0.4.0 (2009-11-18)\n------------------\n\n* Release compatible with ZTK 1.0dev versions. Pinned down the version\n of zope.traversing in the setup.py. It now runs on Python 2.6 !\n\n\n0.3.2 (2009-10-23)\n------------------\n\n* Corrected a bug on the clean_filename util function, that would fail\n on unicode values. Added a test to fix that behavior.\n\n\n0.3.1 (2009-10-23)\n------------------\n\n* Removed the __parent__ attribution in the property. If you relied on\n this, you now have to take care of the location proxying yourself.\n\n\n0.3.0 (2009-10-23)\n------------------\n\n* Changed the filename cleaning method, now exposed in the public\n API. We now use a compiled regexp to get the name.\n\n\n0.2.0 (2009-10-21)\n------------------\n\n* Added an image field with the corresponding interface. This was\n previously part of ``dolmen.imaging``. The ImageField component is a\n simple subclass of the default FileField.\n\n\n0.1.0 (2009-10-16)\n------------------\n\n* Initial release", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "UNKNOWN", "keywords": "Grok Zope3 file download", "license": "GPL", "maintainer": null, "maintainer_email": null, "name": "dolmen.file", "package_url": "https://pypi.org/project/dolmen.file/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/dolmen.file/", "project_urls": { "Download": "UNKNOWN", "Homepage": "UNKNOWN" }, "release_url": "https://pypi.org/project/dolmen.file/0.6/", "requires_dist": null, "requires_python": null, "summary": "A Zope3/Grok File Representation package.", "version": "0.6" }, "last_serial": 791333, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "6a14523a18e2e842e35962df391e9f9c", "sha256": "03527b4055ce72db54dfe7814ad313d382decc90e545cd827009253db2a153a9" }, "downloads": -1, "filename": "dolmen.file-0.1.tar.gz", "has_sig": false, "md5_digest": "6a14523a18e2e842e35962df391e9f9c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7910, "upload_time": "2009-10-16T18:52:05", "url": "https://files.pythonhosted.org/packages/f8/04/bd54e7bf65110d92bd5d1f624970a769cc814063da3e3f7725a688c8710e/dolmen.file-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "5aee256e8e8e9f4efa514695993f739a", "sha256": "b2c1cf0fc87f5bf20fef72d8f8c105b8eb4850cb2586cf32778d51cc650e7884" }, "downloads": -1, "filename": "dolmen.file-0.2.tar.gz", "has_sig": false, "md5_digest": "5aee256e8e8e9f4efa514695993f739a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8297, "upload_time": "2009-10-21T15:25:12", "url": "https://files.pythonhosted.org/packages/cf/f1/230261792347b4aa57d1846c7647369d1b713e2be591fa5e91bd061f8938/dolmen.file-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "9625dd16e4c055768e8cfd8fc519499b", "sha256": "ecddca1fddc4702c04eab76aa8b89b6ea7ecdf3581764eca8d12b2291e584b45" }, "downloads": -1, "filename": "dolmen.file-0.3.tar.gz", "has_sig": false, "md5_digest": "9625dd16e4c055768e8cfd8fc519499b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8521, "upload_time": "2009-10-23T15:26:47", "url": "https://files.pythonhosted.org/packages/70/a6/7f00d52b5111e9ffac1fb6327ed73ef8cb8b3ef029fea252f26138f341a9/dolmen.file-0.3.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "6a51de1f37add8f869790f6ef0571ed9", "sha256": "8a581f68624d518dafd6090f5058877cc36f0c9b51405508e4152db90b321cec" }, "downloads": -1, "filename": "dolmen.file-0.3.1.tar.gz", "has_sig": false, "md5_digest": "6a51de1f37add8f869790f6ef0571ed9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8606, "upload_time": "2009-10-23T15:38:40", "url": "https://files.pythonhosted.org/packages/25/86/28c86f3c5a7977563ddb7b56b998fe1be5315d7fdf86c4ceb6311a911669/dolmen.file-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "20395a466252d955f3642b2daa6db76a", "sha256": "64d9c76e0a8190f4ee3218c3d3b3efc6e2ea4aa4f84a2fb74d2095cb3c826f0e" }, "downloads": -1, "filename": "dolmen.file-0.3.2.tar.gz", "has_sig": false, "md5_digest": "20395a466252d955f3642b2daa6db76a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8715, "upload_time": "2009-10-23T16:04:45", "url": "https://files.pythonhosted.org/packages/1b/e4/89c1a51e23e8ec32379f8d8efb80e8945dc167a31dab64be9323b8ab1b56/dolmen.file-0.3.2.tar.gz" } ], "0.4.0": [ { "comment_text": "", "digests": { "md5": "7f54aa10a22ab8bb68e0fc5ec9e6e526", "sha256": "68d70885c6b986e3c04e51f9c23b1c8c38af5a21bb14f7f7e5d7a2c31d27b2b7" }, "downloads": -1, "filename": "dolmen.file-0.4.0.tar.gz", "has_sig": false, "md5_digest": "7f54aa10a22ab8bb68e0fc5ec9e6e526", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8212, "upload_time": "2009-11-18T15:32:24", "url": "https://files.pythonhosted.org/packages/52/e7/0baefc64f37e329a2d5853d51d31bf46b31e26b245aa22ce7b99998a8d67/dolmen.file-0.4.0.tar.gz" } ], "0.5.0": [ { "comment_text": "", "digests": { "md5": "167ece42c5ddba1c1351fdd4414db3a1", "sha256": "468943c96b1a729c99a918dff4e83a50876d1473674b376690d5072704867b6a" }, "downloads": -1, "filename": "dolmen.file-0.5.0.tar.gz", "has_sig": false, "md5_digest": "167ece42c5ddba1c1351fdd4414db3a1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11725, "upload_time": "2010-02-28T17:31:28", "url": "https://files.pythonhosted.org/packages/c3/38/09404aa9050665d803003b3bf4c5b71ae406f6885b8966161ba4a70225a8/dolmen.file-0.5.0.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "027cb78f24b03660667a1279b0bba1de", "sha256": "5d332e609b90f8121c078038002db699a61733d1b4ae749490b6992853b76e1f" }, "downloads": -1, "filename": "dolmen.file-0.5.1.tar.gz", "has_sig": false, "md5_digest": "027cb78f24b03660667a1279b0bba1de", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12956, "upload_time": "2010-02-28T17:58:41", "url": "https://files.pythonhosted.org/packages/b1/30/01f403a97cc9ce0abd2219fbbd3947f25d91f28a03afd58684abf4a72194/dolmen.file-0.5.1.tar.gz" } ], "0.6": [ { "comment_text": "", "digests": { "md5": "5313a5024bcfac0954d27e19603c2f28", "sha256": "42be8ab0535651908e7b0b60e0fec640dec1524595fdf8756d4b9f8643e4b3ba" }, "downloads": -1, "filename": "dolmen.file-0.6.tar.gz", "has_sig": false, "md5_digest": "5313a5024bcfac0954d27e19603c2f28", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12013, "upload_time": "2010-11-17T10:50:30", "url": "https://files.pythonhosted.org/packages/b6/ad/e15b0e2d882b9bbbb6cebcb1cc0845d0da75230d55af5f5e5f9a5419e30b/dolmen.file-0.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "5313a5024bcfac0954d27e19603c2f28", "sha256": "42be8ab0535651908e7b0b60e0fec640dec1524595fdf8756d4b9f8643e4b3ba" }, "downloads": -1, "filename": "dolmen.file-0.6.tar.gz", "has_sig": false, "md5_digest": "5313a5024bcfac0954d27e19603c2f28", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12013, "upload_time": "2010-11-17T10:50:30", "url": "https://files.pythonhosted.org/packages/b6/ad/e15b0e2d882b9bbbb6cebcb1cc0845d0da75230d55af5f5e5f9a5419e30b/dolmen.file-0.6.tar.gz" } ] }