{ "info": { "author": "Souheil Chelfouh", "author_email": "trollfot@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "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.thumbnailer\n==================\n\n`dolmen.thumbnailer` is package specialized in Thumbnail\ngeneration. Using the `dolmen.storage` mechanisms, it allows a\npluggable and flexible thumbnail storage.\n\n\nThumbnailer\n===========\n \nThe thumbnailer is the component in charge of effectively scaling down\nthe image. This component is defined by the `IThumbnailer` interface::\n\n >>> from dolmen.thumbnailer import IThumbnailer\n >>> print IThumbnailer['scale'].__doc__\n Returns a StringIO that is a data representation of an image,\n scaled down to the given size.\n\nOut-of-the-box, an `IThumbnailer` implementation is proposed, as an\nadapter. In order to test it, we need both a model and an image. The\nmodel will serve as a base for the adaptation::\n\n >>> fd = open(IMAGE_PATH, 'r')\n >>> data = fd.read()\n >>> fd.close()\n\n >>> class BasicContent(object):\n ... pass\n >>> mycontext = BasicContent()\n\n >>> thumbnailer = IThumbnailer(mycontext)\n >>> thumbnailer\n \n\nWe can now test the scaling method. This method, as specified in the\nIThumbnailer interface, requires the data, given as a PIL Image, and a\nscale (a tuple of width and height)::\n\n >>> from PIL import Image\n >>> from cStringIO import StringIO\n\n >>> image = Image.open(StringIO(data))\n >>> scale = thumbnailer.scale(image, (100, 100))\n >>> scale\n \n\n >>> Image.open(scale).size\n (100, 100)\n\nThe scale method returns a `cStringIO.StringIO` that can be used to\nrecreate a PIL.Image or to save in an object, as a binary string.\n\nThis implementation of `IThumbnailer` is *not* modifying the original\nimage::\n\n >>> image.size\n (280, 280)\n\nThe thumbnailer handles some basic errors for you::\n\n >>> thumbnailer.scale(None, (100, 100))\n Traceback (most recent call last):\n ...\n TypeError: Scaling can only occur using a PIL Image\n\n >>> thumbnailer.scale(image, None)\n Traceback (most recent call last):\n ...\n ValueError: Size must be a (width, height) tuple\n\n.. attention::\n\n The next component, the Miniaturizer, will query a named\n IThumbnailer for each thumbnail scale, using the scale name. If no\n named IThumbnailer is found, it fallbacks to the base one.\n\n\nMiniaturizer\n============\n\nThe Miniaturizer is the component in charge of the thumbnailing\npolicy. It handles the name and size, the storage class used as\nthe file-wrapper and provides a collection of methods to manage the\ngeneration, retrieval and deletion of the thumbnails.\n\nDefault policy\n--------------\n\nThe default policy is defined in the interface `IImageMiniaturizer`,\nimplemented by the Miniaturizer component. Let's have a quick\noverview::\n\n >>> from dolmen.thumbnailer import IImageMiniaturizer\n\n >>> print IImageMiniaturizer['scales'].default\n {'large': (700, 700), 'mini': (250, 250), 'small': (128, 128), 'preview': (400, 400), 'thumb': (150, 150)}\n\n >>> print IImageMiniaturizer['factory'].default\n \n\n\nStorage and adapter\n-------------------\n\nOut-of-the-box, `dolmen.thumbnailer` provides a IImageMiniaturizer\nimplementation as an adapter. While it uses the default scales and\nfactory, it queries a `dolmen.storage.IDelegatedStorage` component\nfor the storage. This storage is a `dolmen.storage.AnnotationStorage`\nnamed 'thumbnail', in order to write the store the thumbnails in the\nobject annotations.\n\nThis means, we need a IAttributeAnnotatable object::\n\n >>> miniaturizer = IImageMiniaturizer(mycontext)\n Traceback (most recent call last):\n ...\n TypeError: ('Could not adapt', , )\n\n >>> from zope.annotation import IAttributeAnnotatable\n >>> from zope.interface import alsoProvides\n\n >>> alsoProvides(mycontext, IAttributeAnnotatable)\n >>> miniaturizer = IImageMiniaturizer(mycontext)\n >>> miniaturizer\n \n\nNow we obtain a Miniaturizer object. We can verify its conformity with\nthe interface that describes it::\n\n >>> from zope.interface import verify\n >>> verify.verifyObject(IImageMiniaturizer, miniaturizer)\n True\n\n >>> miniaturizer.storage\n \n\n >>> from dolmen.storage import IDelegatedStorage\n >>> IDelegatedStorage.providedBy(miniaturizer.storage)\n True\n\n\nGeneration\n-----------\n\nThe Miniaturizer assumes that your data is stored on a field of the\nobject. The methods provided by the component will use the fieldname\nto trigger their action.\n\nLet's add an image attribute to our content object::\n\n >>> from dolmen.file import file\n >>> mycontext.image = file.NamedFile(data=data)\n >>> mycontext.image\n \n\nOur image is persisted on our object, in an attribute called\n'image'. Let's trigger the thumbnails generation::\n\n >>> miniaturizer.generate(fieldname=\"image\")\n True\n\nThe return value is a boolean representing the success of the\ngeneration. Let's have a look at our storage, after the generation::\n\n >>> list(miniaturizer.storage.keys())\n ['image.large', 'image.mini', 'image.preview', 'image.small', 'image.thumb']\n\nSome errors are handled for you::\n \n >>> miniaturizer.generate(fieldname=\"nonexisting\")\n False\n\n >>> miniaturizer.generate(fieldname=\"__class__\")\n Traceback (most recent call last):\n ...\n IOError: cannot identify image file\n\n\nRetrieval\n---------\n\nThe thumbnails can be retrieved easily, using the scale name and the\nfield name::\n\n >>> scale = miniaturizer.retrieve('mini', fieldname=\"image\")\n >>> scale\n \n\nAs we can see, the thumbnails data is wrapped in a\n`dolmen.file.file.NamedFile` object, which is the factory defined in your\ndefault policy::\n\n >>> isinstance(scale, IImageMiniaturizer['factory'].default)\n True\n\nThe Miniaturizer can fetch a thumbnail using a \"fieldname.scalename\"\nkey::\n\n >>> print miniaturizer['image.mini']\n \n\n >>> print miniaturizer.get('image.small')\n \n\n >>> print miniaturizer.get('image.nonexistance')\n None\n >>> print miniaturizer.get('image.nonexistance', 'nothing !')\n nothing !\n\nAs usual, some error situations are handled for you::\n \n >>> print miniaturizer.retrieve('manfred', fieldname=\"image\")\n None\n >>> print miniaturizer.retrieve('manfred', fieldname=\"not there\")\n None\n\n\nDeletion\n--------\n\nThe deletion action will use the fieldname to delete *all* the\nthumbnails generated for the given field::\n\n >>> miniaturizer.delete(fieldname=\"image\")\n >>> list(miniaturizer.storage.keys())\n []\n\n\nAccess and security\n===================\n\nThe thumbnails are generated and stored. Logically, we now want to\npublish the thumbnails in order to make them accessible through a URL.\nThe `dolmen.thumbnailer` provides a traverser based on\n`dolmen.file.access.FilePublisher`::\n\n >>> from zope.component import getMultiAdapter\n >>> from zope.publisher.browser import TestRequest\n >>> from zope.traversing.interfaces import ITraversable\n\n >>> miniaturizer.generate(fieldname=\"image\")\n True\n\n >>> request = TestRequest()\n >>> traverser = getMultiAdapter((mycontext, request),\n ... ITraversable, name='thumbnail')\n \nThe basic permission used to check the availability of the data is\n`zope.View`. 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.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 thumbnail::\n\n >>> security.newInteraction(Participation(jason))\n >>> traverser.traverse('image.small')\n Traceback (most recent call last):\n ...\n Unauthorized: image.small\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('image.small')\n \n >>> security.endInteraction()\n\nOur thumbnail is returned, wrapped in a `FilePublisher` view, which is\nready to be rendered (see `dolmen.file` access documentation for\nmore information).\n\n\nChangelog\n=========\n\n0.3 (2010-02-27)\n----------------\n\n* Cleaned dependencies. We no longer have zope.app dependencies.\n\n* We now use ``dolmen.file.file.File`` as base files for the thumbnails.\n\n\n0.2.3 (2010-02-19)\n------------------\n\n* Corrected the PIL version to 1.1.7\n\n\n0.2.2 (2010-02-19)\n------------------\n\n* Updated dependency : PILwoTK to PIL.\n\n\n0.2.1 (2009-10-25)\n------------------\n\n* Updated to the latest version of `dolmen.field`.\n\n\n0.2 (2009-10-23)\n----------------\n\n* Now thumbnails can be named, if the factory implements\n `dolmen.file.INamedFile`.\n\n* Corrected a bug where the specified mimeType was not a valid one.\n\n\n0.1 (2009-10-21)\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": "http://gitweb.dolmen-project.org", "keywords": "Grok Zope3 Dolmen Thumbnails", "license": "GPL", "maintainer": null, "maintainer_email": null, "name": "dolmen.thumbnailer", "package_url": "https://pypi.org/project/dolmen.thumbnailer/", "platform": "Any", "project_url": "https://pypi.org/project/dolmen.thumbnailer/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://gitweb.dolmen-project.org" }, "release_url": "https://pypi.org/project/dolmen.thumbnailer/0.3/", "requires_dist": null, "requires_python": null, "summary": "Dolmen thumbnailing library", "version": "0.3" }, "last_serial": 791340, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "12b15abffd027d37df80f933c4c6e914", "sha256": "539c92d296161f0a646e463e150c6d1bc09901e9b3ce446dba379441bcb61c63" }, "downloads": -1, "filename": "dolmen.thumbnailer-0.1.tar.gz", "has_sig": false, "md5_digest": "12b15abffd027d37df80f933c4c6e914", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16093, "upload_time": "2009-10-21T20:36:05", "url": "https://files.pythonhosted.org/packages/8b/59/6bb5c65c02b90798f503928d2e2115cd88b8f094114b68bb6ff9e0db864b/dolmen.thumbnailer-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "11cad8faf1854ca76cbc96edacf54c02", "sha256": "04689f84bafb621fc6667a6d767e7f6dfc371094605df54b602ff27496555acc" }, "downloads": -1, "filename": "dolmen.thumbnailer-0.2.tar.gz", "has_sig": false, "md5_digest": "11cad8faf1854ca76cbc96edacf54c02", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16914, "upload_time": "2009-10-23T16:36:47", "url": "https://files.pythonhosted.org/packages/d8/28/91b9eb2f7cbf7c63495b5277aef91670a19b40b5cf50115230c303122081/dolmen.thumbnailer-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "a4314b10783ca1decdd053ed897e8b43", "sha256": "df3ecca8d5ec2b377b393ed9dd5965e1685a20a53759aabdb66602427a0270ff" }, "downloads": -1, "filename": "dolmen.thumbnailer-0.2.1.tar.gz", "has_sig": false, "md5_digest": "a4314b10783ca1decdd053ed897e8b43", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17027, "upload_time": "2009-10-26T15:39:03", "url": "https://files.pythonhosted.org/packages/8f/f5/7424f5d2cb97948caa70eb1c6914bd4faf0f23a8c79e84bc47e179d6a129/dolmen.thumbnailer-0.2.1.tar.gz" } ], "0.2.2": [ { "comment_text": "", "digests": { "md5": "caf8d6a1bb9180614d95c55df23ee062", "sha256": "4f51924596f336ad3c5b7e205b483a46bc4c48caa72e35466575a6134bc45045" }, "downloads": -1, "filename": "dolmen.thumbnailer-0.2.2.tar.gz", "has_sig": false, "md5_digest": "caf8d6a1bb9180614d95c55df23ee062", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17088, "upload_time": "2010-02-19T14:08:04", "url": "https://files.pythonhosted.org/packages/84/30/93b277f3b56569662dcd0b41e277bb425eb3089f1fba0beb499f3322e62e/dolmen.thumbnailer-0.2.2.tar.gz" } ], "0.2.3": [ { "comment_text": "", "digests": { "md5": "ca87bf387767a826396c4dc27f4ab9ee", "sha256": "bb93121691c5bb2c5ce592f0b1ff74aea2ef27f4f0bb60b18af03121cbe5493b" }, "downloads": -1, "filename": "dolmen.thumbnailer-0.2.3.tar.gz", "has_sig": false, "md5_digest": "ca87bf387767a826396c4dc27f4ab9ee", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17147, "upload_time": "2010-02-19T14:23:58", "url": "https://files.pythonhosted.org/packages/ae/be/53b2168d4977bf932c2e99b5a0d01bb84c3a65d9bdaa34acb26226241459/dolmen.thumbnailer-0.2.3.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "a139ca6fcd58dbe585088b1713dce4cb", "sha256": "3eaf6ee0ef09d7b4c26d3149e9b3a8771c4c3b94af80f08d53e511ecf4e0042c" }, "downloads": -1, "filename": "dolmen.thumbnailer-0.3.tar.gz", "has_sig": false, "md5_digest": "a139ca6fcd58dbe585088b1713dce4cb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17494, "upload_time": "2010-02-27T20:30:07", "url": "https://files.pythonhosted.org/packages/fb/d3/577b7e644a1e799244f9f718492394cbd9275f7bf966aa3c86b691434c15/dolmen.thumbnailer-0.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "a139ca6fcd58dbe585088b1713dce4cb", "sha256": "3eaf6ee0ef09d7b4c26d3149e9b3a8771c4c3b94af80f08d53e511ecf4e0042c" }, "downloads": -1, "filename": "dolmen.thumbnailer-0.3.tar.gz", "has_sig": false, "md5_digest": "a139ca6fcd58dbe585088b1713dce4cb", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17494, "upload_time": "2010-02-27T20:30:07", "url": "https://files.pythonhosted.org/packages/fb/d3/577b7e644a1e799244f9f718492394cbd9275f7bf966aa3c86b691434c15/dolmen.thumbnailer-0.3.tar.gz" } ] }