Browse files

merge 2.0 into master

  • Loading branch information...
2 parents e0ef40a + 52dd539 commit d4d91f59b14e6a12b2d74e759e1da22092350c2d @toutpt toutpt committed Dec 6, 2012
Showing with 426 additions and 1,439 deletions.
  1. +5 −1 .gitignore
  2. +22 −109 README.rst
  3. +36 −1 buildout.cfg
  4. +0 −12 collective/gallery/Extensions/Install.py
  5. 0 collective/gallery/Extensions/__init__.py
  6. +53 −13 collective/gallery/configure.zcml
  7. +26 −5 collective/gallery/core.py
  8. +0 −89 collective/gallery/folder.txt
  9. +12 −0 collective/gallery/interfaces.py
  10. +39 −78 collective/gallery/link/__init__.py
  11. +70 −0 collective/gallery/link/base.py
  12. +8 −10 collective/gallery/link/facebook.py
  13. +10 −10 collective/gallery/link/flickr.py
  14. +0 −45 collective/gallery/link/link.txt
  15. +2 −14 collective/gallery/link/picasaweb.py
  16. 0 collective/gallery/portlets/__init__.py
  17. +0 −32 collective/gallery/portlets/configure.zcml
  18. +0 −30 collective/gallery/portlets/itemview.pt
  19. +0 −39 collective/gallery/portlets/itemview.py
  20. +0 −41 collective/gallery/portlets/show_galleries.pt
  21. +0 −112 collective/gallery/portlets/show_galleries.py
  22. +0 −12 collective/gallery/profiles/default/cssregistry.xml
  23. +0 −14 collective/gallery/profiles/default/jsregistry.xml
  24. +1 −2 collective/gallery/profiles/default/metadata.xml
  25. +0 −11 collective/gallery/profiles/default/portlets.xml
  26. +0 −7 collective/gallery/profiles/default/propertiestool.xml
  27. +3 −0 collective/gallery/profiles/default/registry.xml
  28. +0 −10 collective/gallery/profiles/default/skins.xml
  29. +0 −6 collective/gallery/profiles/default/types/Folder.xml
  30. +0 −6 collective/gallery/profiles/default/types/Topic.xml
  31. +0 −8 collective/gallery/profiles/uninstall/cssregistry.xml
  32. +0 −16 collective/gallery/profiles/uninstall/jsregistry.xml
  33. +0 −7 collective/gallery/profiles/uninstall/skins.xml
  34. +0 −6 collective/gallery/profiles/uninstall/types/Link.xml
  35. +6 −1 collective/gallery/profiles/{default → zclean}/componentregistry.xml
  36. +6 −0 collective/gallery/profiles/zclean/cssregistry.xml
  37. +7 −0 collective/gallery/profiles/zclean/jsregistry.xml
  38. +4 −0 collective/gallery/profiles/zclean/metadata.xml
  39. +4 −0 collective/gallery/profiles/zclean/portlets.xml
  40. +4 −0 collective/gallery/profiles/zclean/propertiestool.xml
  41. +8 −0 collective/gallery/profiles/zclean/skins.xml
  42. +1 −1 collective/gallery/profiles/{uninstall → zclean}/types/Folder.xml
  43. +1 −1 collective/gallery/profiles/{default → zclean}/types/Link.xml
  44. +1 −1 collective/gallery/profiles/{uninstall → zclean}/types/Topic.xml
  45. +2 −0 collective/gallery/settings.py
  46. +0 −70 collective/gallery/skins/collective_gallery_theme/gallery-portlet.js
  47. +0 −51 collective/gallery/skins/collective_gallery_theme/gallery.css
  48. +0 −46 collective/gallery/skins/collective_gallery_theme/gallery.html.pt
  49. +0 −2 collective/gallery/skins/collective_gallery_theme/gallery.html.pt.metadata
  50. +0 −139 collective/gallery/skins/collective_gallery_theme/gallery.js
  51. BIN collective/gallery/skins/collective_gallery_theme/gallery_tooltip.png
  52. +0 −4 collective/gallery/tests/layer.py
  53. +9 −11 collective/gallery/tests/test_core.py
  54. +11 −15 collective/gallery/tests/test_facebook.py
  55. +13 −18 collective/gallery/tests/test_flickr.py
  56. +1 −3 collective/gallery/tests/test_folder.py
  57. +0 −32 collective/gallery/tests/test_functional.py
  58. +8 −9 collective/gallery/tests/test_link.py
  59. +16 −22 collective/gallery/tests/test_picasa.py
  60. +9 −17 collective/gallery/tests/test_setup.py
  61. +2 −6 collective/gallery/tests/test_topic.py
  62. +0 −14 collective/gallery/tests/test_viewlet.py
  63. +0 −124 collective/gallery/topic.txt
  64. +16 −31 collective/gallery/upgrades.py
  65. +0 −46 collective/gallery/upgrades.zcml
  66. 0 collective/gallery/viewlets/__init__.py
  67. +0 −15 collective/gallery/viewlets/configure.zcml
  68. +0 −1 collective/gallery/viewlets/itemview.pt
  69. +0 −8 collective/gallery/viewlets/itemview.py
  70. +7 −2 docs/HISTORY.txt
  71. +3 −3 setup.py
View
6 .gitignore
@@ -11,6 +11,7 @@ eggs
fake-eggs
parts
dist
+var
.installed.cfg
.mr.developer.cfg
.hg
@@ -19,4 +20,7 @@ dist
*.pyc
*.pyo
*.tmp*
-
+src
+.project
+.pydevproject
+.settings
View
131 README.rst
@@ -1,47 +1,13 @@
-Notes: gdata 2.0.10 doesn't work properly: http://code.google.com/p/gdata-python-client/issues/detail?id=367#c1
-please pin the version to 2.0.9
-
Introduction
============
-This add-on is gallery add-on for Plone.
-
-It is tested with Plone 4 but it is also used with Plone 3.
-
-This add-on is split in two parts: the UI and components
+This add-on contains core controller to build gallery addons for Plone.
The goals are:
-* Have a simple to customize gallery add-on for plone (non intrusive).
-* Use very ligth weight resources
-* Don't embed display configuration inside data
-
-User Interface
-==============
-
-The user interface has been designed to be easy to customize. Files are located
-in the skin directory (easy to customize):
-
-* gallery.html.pt: Zope Page Template to render the html code
-* gallery.css: pure css design to display 400*400 photos
-* gallery.html.pt.metadata: to set the title of the page in display drop down menu
-* gallery.js: the javascript integration of galleriffic_.
-* gallery_tooltip.png: the tooltip used to display the title/description of the photo
-
-The user interface has many feature:
-
-* resize photo if too big by setting the width or height
-* paginate thumbs for navigation (5 by default)
-* opacity on mouse rollover thumbs
-* play / pause (autostart by default)
-* display more than 300 photos without any performance issue
-* display title and description throw a smart jquerytool tooltip
-
-There are also two portets, which can be used:
-
-* "Show Galleries" portlet to display random photos from random galleries.
-* An itemview portlet to display specific photos.
-
+* Have a simple photo fetchers component in one API
+* Support many photos providers (picasa, flickr, ...)
+* Stay as simple as possible
Components (Backend)
====================
@@ -56,17 +22,17 @@ Summary:
* facebook support.
* I18N: english, french, german and italian are available
-collective.gallery use zope.components to provide as much reusable as possible
-components.
+collective.gallery use zope.components to provide as much reusable components
+as possible.
First we have photo resources. Plone already manage this for you:
-* Folder and Large Plone Folder can contains Image
-* Topic can be criterized to list only Image
+* Folder can contains Image
+* Topic can be criterized to list only Image content type
* Link can be sources of photos throw picasaweb.google.com and flickr.com services.
-Next you have the business component: IGallery. This interface is implemented
-at two levels:
+Next you have the business component: IGallery.
+This interface is implemented at two levels:
* As named adapter over IATLink to get photos from picasaweb or flickr.
* As browserview to control the resource (@@gallery)
@@ -154,58 +120,13 @@ The album must be public. Links supported are:
IPhoto.description metadata is not supported
-Galleriffic_
-============
-
-* Smart image preloading after the page is loaded
-* Thumbnail navigation (with pagination)
-* jQuery.history plugin integration to support bookmark-friendly URLs per-image
-* Slideshow (with optional auto-updating url bookmarks)
-* Keyboard navigation
-* Events that allow for adding your own custom transition effects
-* API for controlling the gallery with custom controls
-* Support for image captions
-* Flexible configuration
-* Graceful degradation when javascript is not available
-* Support for multiple galleries per page
-
Integrators
===========
-Because it is easy to customize, lets write some lines about how to fit gallery
-to your needs.
-
-Some advices:
-
-be fixed width. Photo are fixed, you want your gallery to be nice, lets fixed its width.
-
-You can configure in properties the max photo size you want but backends may not support
-this settings.
-
-Most of galleries do not contains every photos in the same size or in the same proportions.
-Take care of this when you are customizing javascript and css.
-
-All controllers can be placed where ever you want because they are accessed by #id
-
-Gallery is not configurable because it needs to generate javascript and css.
-It would make the add-on too much complex to customize. If you want configuration take
-a look at plonetruegallery_
-
-To register the "Show Galleries" portlet, you can add the following xml snippet
-to your portlets.xml Generic Setup file:::
-
- <assignment
- name="gallery-portlet"
- category="context"
- key="/"
- manager="plone.rightcolumn"
- type="collective.gallery.show_galleries"
- visible="True">
- <property name="search_portal">True</property>
- <property name="num_pictures">1</property>
- <property name="image_size">mini</property>
- </assignment>
+You have some examples of addons based on this one:
+* collective.galleria
+* collective.galleriffic
You want more ?
===============
@@ -226,11 +147,6 @@ This add-on is use in production here and there:
* http://www.nantes-developpement.com/search?portal_type=Diaporama
* http://www.recuperateurdepluie.fr/photos-aqualogic
-ROADMAP
-=======
-
-* merge with collective.plonetruegallery
-
Credits
=======
@@ -239,25 +155,22 @@ Companies
|makinacom|_
- * `Planet Makina Corpus <http://www.makina-corpus.org>`_
- * `Contact us <mailto:python@makina-corpus.org>`_
-
-
-Authors
+* `Planet Makina Corpus <http://www.makina-corpus.org>`_
+* `Contact Makina Corpus <mailto:python@makina-corpus.org>`_
- - JeanMichel FRANCOIS aka toutpt <toutpt@gmail.com>
-Contributors
+People
+------
- - Mathieu Le Marec - Pasquet <kiorky@cryptelium.net>
- - Johannes Raggam <raggam-nl@adm.at>
+- JeanMichel FRANCOIS aka toutpt <toutpt@gmail.com>
+- Mathieu Le Marec - Pasquet <kiorky@cryptelium.net>
+- Jean-Philippe Camguilhem <jp.camguilhem@gmail.com>
+- Johannes Raggam <raggam-nl@adm.at>
+- Giacomo Spettoli
.. |makinacom| image:: http://depot.makina-corpus.org/public/logo.gif
.. _makinacom: http://www.makina-corpus.com
-.. _Galleriffic: http://www.twospy.com/galleriffic/
.. _flickr: http://www.flickr.com
.. _picasaweb: http://picasaweb.google.com
.. _jcarousel: http://sorgalla.com/jcarousel
-.. _Pikachoose: http://pikachoose.com
.. _facebook: http://www.facebook.com
-.. _plonetruegallery: http://plone.org/products/plone-true-gallery
View
37 buildout.cfg
@@ -1,5 +1,40 @@
[buildout]
extends =
- http://svn.plone.org/svn/collective/buildout/plonetest/test-4.1.x.cfg
+ https://raw.github.com/collective/buildout.plonetest/master/test-4.x.cfg
package-name = collective.gallery
package-extras = [tests]
+extensions = mr.developer
+auto-checkout=*
+always-checkout=force
+
+[instance]
+eggs+=
+ collective.configviews
+ collective.registry
+ collective.fancyboxgallery
+ collective.galleria
+ collective.galleriffic
+ collective.highslide
+ collective.quickupload
+ collective.portlet.fancyboxgallery
+ collective.js.mousewheel
+ collective.js.imagesloaded
+ collective.oembed
+
+[sources]
+collective.plonetruegallery = git git://github.com/collective/collective.plonetruegallery.git
+#collective.configviews = git git://github.com/collective/collective.configviews.git branch=2.0
+#collective.js.easing = git git://github.com/toutpt/collective.js.easing.git
+#collective.js.fancybox = git git://github.com/toutpt/collective.js.fancybox.git
+#collective.js.galleriffic = git git://github.com/collective/collective.js.galleriffic.git
+#collective.js.galleria = git git://github.com/toutpt/collective.js.galleria.git
+#collective.js.highslide = git git://github.com/toutpt/collective.js.highslide.git
+#collective.js.imagesloaded = git git://github.com/toutpt/collective.js.imagesloaded.git
+#collective.js.mousewheel = git git://github.com/toutpt/collective.js.mousewheel.git
+#collective.galleria = git git://github.com/collective/collective.galleria.git
+collective.galleriffic = git git://github.com/toutpt/collective.galleriffic.git
+#collective.registry = git git://github.com/collective/collective.registry.git
+collective.highslide = git git://github.com/toutpt/collective.highslide.git
+collective.fancyboxgallery = git git://github.com/toutpt/collective.fancyboxgallery.git
+collective.portlet.fancyboxgallery = git git://github.com/toutpt/collective.portlet.fancyboxgallery.git
+collective.oembed = git git://github.com/collective/collective.oembed.git
View
12 collective/gallery/Extensions/Install.py
@@ -1,12 +0,0 @@
-from Products.CMFCore.utils import getToolByName
-
-def install(self):
- setup_tool = getToolByName(self, 'portal_setup')
- setup_tool.runAllImportStepsFromProfile('profile-collective.gallery:default')
- return "Ran all import steps."
-
-def uninstall(self):
- setup_tool = getToolByName(self, 'portal_setup')
- setup_tool.runAllImportStepsFromProfile('profile-collective.gallery:uninstall')
- setup_tool.setBaselineContext('profile-Products.CMFPlone:plone')
- return "Ran all uninstall steps."
View
0 collective/gallery/Extensions/__init__.py
No changes.
View
66 collective/gallery/configure.zcml
@@ -7,15 +7,11 @@
xmlns:i18n="http://namespaces.zope.org/i18n"
i18n_domain="collective.gallery">
+ <include package="Products.CMFCore" file="permissions.zcml" />
+ <include package="plone.app.registry" />
<five:registerPackage package="." initialize=".initialize" />
-
<i18n:registerTranslations directory="locales" />
- <cmf:registerDirectory name="collective_gallery_theme"/>
-
- <include package="plone.app.portlets"/>
- <include package=".portlets" />
-
<utility
component=".vocabularies.ImageScaleVocabulary"
name="collective.gallery.ImageScaleVocabulary"
@@ -25,17 +21,33 @@
name="default"
title="collective.gallery default"
directory="profiles/default"
- description='Install collective.gallery in Plone'
+ description="Install collective.gallery in Plone"
provides="Products.GenericSetup.interfaces.EXTENSION"
/>
<genericsetup:registerProfile
- name="uninstall"
- title="collective.gallery uninstall"
- directory="profiles/uninstall"
- description='Uninstall collective.gallery from Plone'
+ name="zclean"
+ title="collective.gallery cleanup from 1.X"
+ directory="profiles/zclean"
+ description="Cleanup collective.gallery install"
provides="Products.GenericSetup.interfaces.EXTENSION"
/>
+ <genericsetup:upgradeStep
+ title="Upgrade collective.gallery to 2.0"
+ description="uninstall 1.0 releated stuff"
+ source="*"
+ destination="2000"
+ handler=".upgrades.zclean"
+ profile="collective.gallery:default"/>
+
+ <genericsetup:upgradeStep
+ title="Upgrade collective.gallery"
+ description="common upgrade step: apply the profile"
+ source="2000"
+ destination="2001"
+ handler=".upgrades.common"
+ profile="collective.gallery:default"/>
+
<browser:page
name="gallery"
for=".interfaces.ILink"
@@ -76,7 +88,35 @@
permission="zope2.View"
layer=".interfaces.IGalleryLayer"
/>
-
- <include file="upgrades.zcml"/>
+ <browser:page
+ name="collective.gallery.zclean"
+ for="Products.CMFPlone.interfaces.IPloneSiteRoot"
+ class=".upgrades.ZClean"
+ layer=".interfaces.IGalleryLayer"
+ permission="cmf.ManagePortal"
+ />
+ <adapter
+ factory=".brain.Photo"
+ for="Products.ZCatalog.interfaces.ICatalogBrain"
+ provides=".interfaces.IPhoto"
+ />
+ <adapter
+ factory=".link.picasaweb.Link"
+ for=".interfaces.ILink"
+ provides=".interfaces.IGallery"
+ name="picasaweb"
+ />
+ <adapter
+ factory=".link.flickr.Link"
+ for=".interfaces.ILink"
+ provides=".interfaces.IGallery"
+ name="flickr"
+ />
+ <adapter
+ factory=".link.facebook.Link"
+ for=".interfaces.ILink"
+ provides=".interfaces.IGallery"
+ name="facebook"
+ />
</configure>
View
31 collective/gallery/core.py
@@ -1,7 +1,12 @@
-from Products.Five import BrowserView
-from collective.gallery import interfaces
+from zope import component
from zope import interface
+from Products.Five import BrowserView
+
from Products.CMFCore.utils import getToolByName
+from plone.registry.interfaces import IRegistry
+
+from collective.gallery import interfaces
+
class BaseBrowserView(BrowserView):
"""This code is the base code of gallery views.
@@ -15,14 +20,15 @@ class BaseBrowserView(BrowserView):
def __init__(self, context, request):
self.context = context
self.request = request
+ self._settings = None
@property
def width(self):
- return self.settings().getProperty('photo_max_size', 400)
+ return self.settings().photo_max_size
@property
def height(self):
- return self.settings().getProperty('photo_max_size', 400)
+ return self.settings().photo_max_size
@property
def id(self):
@@ -45,7 +51,22 @@ def date(self):
return self.context.Date()
def settings(self):
- return getToolByName(self.context, 'portal_properties').gallery_properties
+ if self._settings is None:
+ registry = component.getUtility(IRegistry)
+ self._settings = registry.forInterface(interfaces.IGallerySettings)
+ return self._settings
def photos(self):
return []
+
+ def get_photo(self, index=0):
+ photos = self.photos()
+
+ if len(photos) == 0:
+ return {'url':'','title':u'', 'description':u'', 'thumb_url':''}
+
+ if index > len(self.photos()):
+ if index!=0:
+ index=0
+
+ return photos[index]
View
89 collective/gallery/folder.txt
@@ -1,89 +0,0 @@
-=========================
-Folder functional doctest
-=========================
-
- >>> from plone.testing.z2 import Browser
- >>> browser = Browser(self.layer['app'])
- >>> browser.handleErrors = False
- >>> portal_url = self.portal.absolute_url()
- >>> self.portal.error_log._ignored_exceptions = ()
- >>> from plone.app import testing
- >>> browser.open(portal_url)
-
-Just login
-
- >>> browser.getLink('Log in').click()
- >>> browser.getControl(name='__ac_name').value = testing.SITE_OWNER_NAME
- >>> browser.getControl(name='__ac_password').value = testing.SITE_OWNER_PASSWORD
- >>> browser.getControl(name='submit').click()
- >>> "You are now logged in" in browser.contents
- True
-
-First we add a folder
-
- >>> browser.getLink("Add new").click()
- >>> browser.getControl('Folder').click()
- >>> browser.getControl('Add').click()
- >>> browser.getControl('Title').value = 'My Gallery'
- >>> browser.getControl('Save').click()
- >>> browser.url
- 'http://nohost/plone/my-gallery/'
-
-Next we add some images inside the folder
-
- >>> browser.getLink("Add new").click()
- >>> browser.getControl('Image').click()
- >>> browser.getControl('Add').click()
- >>> from plone.app.blob.tests.utils import getFile
- >>> control = browser.getControl(name='image_file')
- >>> control.filename = 'bar.gif'
- >>> control.value = getFile('image.gif')
- >>> browser.getControl('Save').click()
- >>> browser.url
- 'http://nohost/plone/my-gallery/bar.gif/view'
-
- >>> browser.getLink("My Gallery").click()
- >>> browser.getLink("Add new").click()
- >>> browser.getControl('Image').click()
- >>> browser.getControl('Add').click()
- >>> from plone.app.blob.tests.utils import getFile
- >>> control = browser.getControl(name='image_file')
- >>> control.filename = 'bar.png'
- >>> control.value = getFile('image.png')
- >>> browser.getControl('Save').click()
- >>> browser.url
- 'http://nohost/plone/my-gallery/bar.png/view'
-
- >>> browser.getLink("My Gallery").click()
- >>> browser.getLink("Add new").click()
- >>> browser.getControl('Image').click()
- >>> browser.getControl('Add').click()
- >>> from plone.app.blob.tests.utils import getFile
- >>> control = browser.getControl(name='image_file')
- >>> control.filename = 'bar.jpg'
- >>> control.value = getFile('image.jpg')
- >>> browser.getControl('Save').click()
- >>> browser.url
- 'http://nohost/plone/my-gallery/bar.jpg/view'
-
-Now we return to the folder and set the default view
-
- >>> browser.getLink("My Gallery").click()
- >>> browser.getLink("Display").click()
- >>> browser.getControl('Gallery view').click()
- >>> browser.getControl('Save').click()
-
-Make some assertions
-
- >>> '<div id="gallery">' in browser.contents
- True
- >>> '<ul class="thumbs noscript">' in browser.contents
- True
-
- >>> import tempfile as tmp
- >>> def contents():
- ... fd, fn = tmp.mkstemp(suffix=".html", prefix="testbrowser-")
- ... file = open(fn, 'w')
- ... file.write(browser.contents)
- ... file.close()
- ... print fn
View
12 collective/gallery/interfaces.py
@@ -40,6 +40,10 @@ class IGallery(interface.Interface):
def photos(scale="default"):
"""Return the list of all IPhoto contained in the gallery"""
+ def get_photo(index=0):
+ """return the photo from at index"""
+
+
class IGalleryTemplateTerm(interface.Interface):
"""Make a utility registred with this interface.
It will be used to build the vocabularies and to make the
@@ -60,6 +64,14 @@ def validate():
the url is a picasa one.
"""
+
+class IGallerySettings(interface.Interface):
+ """Global settings"""
+
+ photo_max_size = schema.Int(title=u"Width",
+ default=400)
+
+
#dependencies
try:
#plone4
View
117 collective/gallery/link/__init__.py
@@ -12,8 +12,17 @@
from collective.gallery import i18n
from collective.gallery import cache
from collective.gallery import core
+from collective.gallery.link.base import BaseResource
from Products.statusmessages.interfaces import IStatusMessage
+from collective.gallery.link.facebook import check as check_facebook
+from collective.gallery.link.flickr import check as check_flickr
+from collective.gallery.link.picasaweb import check as check_picasaweb
+
+from collective.gallery.link.facebook import Link as FacebookLink
+from collective.gallery.link.flickr import Link as FlickrLink
+from collective.gallery.link.picasaweb import Link as PicasawebLink
+
class BaseLinkView(core.BaseBrowserView):
"""A base browser view for link content type"""
interface.implements(interfaces.IGallery)
@@ -23,51 +32,66 @@ def __init__(self, context, request):
self.url = self.context.getRemoteUrl()
self.resource = None
self._baseresource = BaseResource(self.context)
- self._resource()
+# self._resource()
- def _resource(self):
+ def __call__(self):
+ self.update()
+ return self
+# return self.index()
+
+ def update(self):
"""Return the first component find that is valid for this context.
If none are found use a dummy ressource"""
- if not self.resource:
+
+ if self.resource is None:
+ url = self.url
+ #to optimize performance those are hardcoded
+ if check_facebook(url):
+ self.resource = FacebookLink(self.context)
+ elif check_picasaweb(url):
+ self.resource = PicasawebLink(self.context)
+ elif check_flickr(url):
+ self.resource = FlickrLink(self.context)
+
+ if self.resource is None:
resources = component.getAdapters((self.context,),
interfaces.IGallery)
for name,r in resources:
+ #every adapters should have a validate method
if r.validate():
self.resource = r
break
- if self.resource:
- self.resource.width = self.width
- self.resource.height = self.height
- else:
- msg = i18n.message_no_backend_for_link
- self.addmessage(msg, type=u"error")
-
- return self.resource
+ if self.resource:
+ self.resource.width = self.width
+ self.resource.height = self.height
+ else:
+ msg = i18n.message_no_backend_for_link
+ self.addmessage(msg, type=u"error")
def addmessage(self, message, type=u"info"):
try:
IStatusMessage(self.request).addStatusMessage(message, type=type)
except TypeError:
pass
- @ram.cache(cache.cache_key)
+# @ram.cache(cache.cache_key)
def photos(self):
- resource = self._resource()
+ resource = self.resource
if resource is None:
resource = self._baseresource
return resource.photos()
@property
def creator(self):
- resource = self._resource()
+ resource = self.resource
if resource is None:
resource = self._baseresource
return resource.creator
@property
def title(self):
- resource = self._resource()
+ resource = self.resource
if resource is None:
resource = self._baseresource
return resource.title
@@ -94,66 +118,3 @@ def break_url(self):
if key:
query_elems[key] = value
return host, path, query_elems, fragment
-
-
-class BaseResource(object):
- """An IGallery base for all link services"""
- interface.implements(interfaces.IGallery)
- component.adapts(interfaces.ILink)
-
- def __init__(self, context):
- self.context = context
- self.url = context.getRemoteUrl()
- def validator(url):return False
- self.validator = validator
- self._width = None
- self._height = None
-
- def validate(self):
- return self.validator(self.url)
-
- def get_width(self):
- if not self._width:
- return self.settings().getProperty('photo_max_size', 400)
- return self._width
-
- def set_width(self, value):
- self._width = value
-
- width = property(get_width, set_width)
-
- def get_height(self):
- if not self._height:
- return self.settings().getProperty('photo_max_size', 400)
- return self._height
-
- def set_height(self, value):
- self._height = value
-
- height = property(get_height, set_height)
-
- @property
- def id(self):
- return self.context.getId()
-
- @property
- def title(self):
- return self.context.Title()
-
- @property
- def creator(self):
- return self.context.Creators()[0]
-
- @property
- def description(self):
- return self.context.Description()
-
- @property
- def date(self):
- return self.context.Date()
-
- def settings(self):
- return getToolByName(self.context, 'portal_properties').gallery_properties
-
- def photos(self):
- return []
View
70 collective/gallery/link/base.py
@@ -0,0 +1,70 @@
+from zope import component
+from zope import interface
+
+from collective.gallery import interfaces
+
+from Products.CMFCore.utils import getToolByName
+from plone.registry.interfaces import IRegistry
+
+class BaseResource(object):
+ """An IGallery base for all link services
+
+ """
+ interface.implements(interfaces.IGallery)
+ component.adapts(interfaces.ILink)
+
+ def __init__(self, context):
+ self.context = context
+ self.url = context.getRemoteUrl()
+ self._width = None
+ self._height = None
+ self._settings = None
+
+ def get_width(self):
+ if not self._width:
+ return self.settings().photo_max_size
+ return self._width
+
+ def set_width(self, value):
+ self._width = value
+
+ width = property(get_width, set_width)
+
+ def get_height(self):
+ if not self._height:
+ return self.settings().photo_max_size
+ return self._height
+
+ def set_height(self, value):
+ self._height = value
+
+ height = property(get_height, set_height)
+
+ @property
+ def id(self):
+ return self.context.getId()
+
+ @property
+ def title(self):
+ return self.context.Title()
+
+ @property
+ def creator(self):
+ return self.context.Creators()[0]
+
+ @property
+ def description(self):
+ return self.context.Description()
+
+ @property
+ def date(self):
+ return self.context.Date()
+
+ def settings(self):
+ if self._settings is None:
+ registry = component.getUtility(IRegistry)
+ self._settings = registry.forInterface(interfaces.IGallerySettings)
+ return self._settings
+
+ def photos(self):
+ return []
View
18 collective/gallery/link/facebook.py
@@ -16,7 +16,7 @@
from zope import interface
from collective.gallery import interfaces
-from collective.gallery.link import BaseResource
+from collective.gallery.link.base import BaseResource
def check(url):
"""Check if the url is valid"""
@@ -38,13 +38,9 @@ class Link(BaseResource):
def __init__(self, context):
super(Link, self).__init__(context)
- self.validator = check
self._album_id = None
-
- def validate(self):
if self.url.startswith('http://www.facebook.com/album.php?'):
self.update_link()
- return self.validator(self.url)
def update_link(self):
if not self.url.startswith('http://www.facebook.com/album.php?'):
@@ -53,23 +49,25 @@ def update_link(self):
def photos(self):
- if not self.validate(): return super(Link, self).photos()
album = self.album_id()
url = "https://graph.facebook.com/%s/photos?limit=1000"%(album)
try:
data_str = urlopen(url).read()
data = json.loads(data_str)
photos = data.get('data',[])
- return map(Photo, photos)
+ return self._build_structure(photos)
except Exception, e:
logger.error('FACEBOOK backend error: %s'%e)
- return super(Link, self).photos()
-
+
+ return []
+
def album_id(self):
if self._album_id is None:
self._album_id = self.url.split('.')[3]
return self._album_id
+ def _build_structure(self, photos):
+ return map(Photo, photos)
class Photo(object):
"""Photo implementation
@@ -85,7 +83,7 @@ def __init__(self, struct):
self.description = u''
#extra from facebook
- self.position = struct['position']
+ #self.position = struct['position']
self.width=struct['width']
self.height=struct['height']
View
20 collective/gallery/link/flickr.py
@@ -2,7 +2,7 @@
from collective.gallery import interfaces
from collective.gallery import cache
-from collective.gallery.link import BaseResource
+from collective.gallery.link.base import BaseResource
from plone.memoize import ram
from zope import interface
@@ -53,6 +53,7 @@ def extract_data(url):
result[mapping.get(m, m)] = val
return result
+
class Link(BaseResource):
"""Flickr implementation of IGallery over Link content type"""
@@ -61,7 +62,6 @@ def __init__(self, context):
self._flickr = None
self._metadata = {'creator':'', 'albumName':''}
self._user_info = {}
- self.validator = check
@property
@ram.cache(cache.url_cache_key)
@@ -90,7 +90,6 @@ def user_info(self):
raise e
return result
-
def photos(self):
"""it depends on metdatas extracted from the url
but we have different case:
@@ -102,16 +101,15 @@ def photos(self):
"""
- if not self.validate(): return super(Link, self).photos()
-
flickr = self._flickr_service()
metadatas = extract_data(self.url)
- resuts = []
+ results = []
if metadatas['type'] == 'photos':
+
if metadatas['sets']:
set = flickr.walk_set(metadatas['sets'])
- results = [Photo(photo) for photo in set]
+ results = self._build_structure(set)
else:
kw = {}
if self.user_info['user_id']:
@@ -124,9 +122,13 @@ def photos(self):
'invalid search, '
'at least user or tags is needed')
photos = flickr.photos_search(**kw)
- results = [Photo(photo) for photo in photos[0]]
+ results = self._build_structure(photos[0])
+
return results
+ def _build_structure(self, photos):
+ return map(Photo, photos)
+
def _flickr_service(self):
"""Return the flickr service"""
if self._flickr: return self._flickr
@@ -136,8 +138,6 @@ def _flickr_service(self):
@property
def creator(self):
- if not self.validate(): return super(Link, self).creator
-
return self.user_info['username']
@property
View
45 collective/gallery/link/link.txt
@@ -1,45 +0,0 @@
-=========================
-Link functional doctest
-=========================
-
- >>> from plone.testing.z2 import Browser
- >>> browser = Browser(self.layer['app'])
- >>> browser.handleErrors = False
- >>> portal_url = self.portal.absolute_url()
- >>> self.portal.error_log._ignored_exceptions = ()
- >>> from plone.app import testing
- >>> browser.open(portal_url)
-
-Just login
-
- >>> browser.getLink('Log in').click()
- >>> browser.getControl(name='__ac_name').value = testing.SITE_OWNER_NAME
- >>> browser.getControl(name='__ac_password').value = testing.SITE_OWNER_PASSWORD
- >>> browser.getControl(name='submit').click()
- >>> "You are now logged in" in browser.contents
- True
-
-We add a link
-
- >>> browser.getLink("Add new").click()
- >>> browser.getControl('Link').click()
- >>> browser.getControl('Add').click()
- >>> browser.getControl('Title').value = 'My Gallery'
- >>> browser.getControl('URL').value = 'http://picasaweb.google.fr/ceronjeanpierre/PhotosTriEsDuMariage'
- >>> browser.getControl('Save').click()
- >>> browser.url
- 'http://nohost/plone/my-gallery'
-
-Now we return to the folder and set the default view
-
- >>> browser.getLink("Display").click()
- >>> browser.getControl('Gallery view').click()
- >>> browser.getControl('Save').click()
-
-Make some assertions
-
- >>> '<div id="gallery">' in browser.contents
- True
- >>> '<ul class="thumbs noscript">' in browser.contents
- True
-
View
16 collective/gallery/link/picasaweb.py
@@ -9,7 +9,7 @@
from zope import interface
from collective.gallery import interfaces
-from collective.gallery.link import BaseResource
+from collective.gallery.link.base import BaseResource
logger = logging.getLogger('collective.gallery')
@@ -47,13 +47,10 @@ def __init__(self, context):
value = q_splited[1]
query[key] = value
self.query = query
- self.validator = check
@property
def creator(self):
- if not self.validate(): return super(Link, self).creator
-
path = self.url_parsed.path.split('/')
if len(path)>1:
return path[1]
@@ -71,8 +68,6 @@ def authkey(self):
def photos(self):
- if not self.validate(): return super(Link, self).photos()
-
kwargs = {}
kwargs['kind'] = 'photo'
kwargs['imgmax'] = self.imgmax(self.width, self.height)
@@ -103,20 +98,13 @@ def imgmax(self, width=None, height=None):
return imgmax
def _build_structure(self, photos):
- results = []
-
- for photo in photos:
- results.append(Photo(photo))
-
- return results
+ return map(Photo, photos)
@property
def title(self):
"""Return the title of the album. If you want to use link title you can
do it in the tempalte"""
- if not self.validate(): return super(Link, self).title
-
url = '/data/feed/api/user/%s/album/%s'%(self.creator, self.albumName)
if self.authkey:
url += '?' + urlencode({'authkey':self.authkey})
View
0 collective/gallery/portlets/__init__.py
No changes.
View
32 collective/gallery/portlets/configure.zcml
@@ -1,32 +0,0 @@
-<configure
- xmlns="http://namespaces.zope.org/zope"
- xmlns:browser="http://namespaces.zope.org/browser"
- xmlns:plone="http://namespaces.plone.org/plone"
- xmlns:zcml="http://namespaces.zope.org/zcml"
- i18n_domain="collective.gallery">
-
- <plone:portlet
- name="collective.gallery.show_galleries"
- interface=".show_galleries.IShowGalleriesPortlet"
- assignment=".show_galleries.Assignment"
- renderer=".show_galleries.Renderer"
- addview=".show_galleries.AddForm"
- editview=".show_galleries.EditForm"
- />
-
-
- <utility zcml:condition="installed collective.portlet.itemview"
- factory=".itemview.GalleryPortletViewEntry"
- name="gallery"
- />
-
- <browser:page zcml:condition="installed collective.portlet.itemview"
- name="itemview_portlet_gallery"
- for="*"
- class=".itemview.GalleryPortletView"
- template="itemview.pt"
- permission="zope2.View"
- layer="collective.gallery.interfaces.IGalleryLayer"
- />
-
-</configure>
View
30 collective/gallery/portlets/itemview.pt
@@ -1,30 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:tal="http://xml.zope.org/namespaces/tal"
- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
- tal:omit-tag="">
-<dl class="portlet" id="portletgallery" i18n:domain="collective.gallery">
- <dt class="portletHeader">
- <span class="portletTopLeft"></span>
- <span tal:content="view/title">
- GALLERY TITLE
- </span>
- <span class="portletTopRight"></span>
- </dt>
- <dd>
- <div id="slideshow" style="height:250px;"></div>
- <ul class="thumbs noscript" style="display:none;">
- <li tal:repeat="img view/photos">
- <a class="thumb" tal:attributes="title img/title;href img/url; name img/id" title="Title #0">
- <img tal:attributes="src img/thumb_url;alt img/title" />
- </a>
- <div class="caption">
- <h2 tal:content="img/title">Title</h2>
- </div>
- </li>
- </ul>
- </dd>
-</dl>
-<script type="text/javascript">
-init_galleryportlet('#portletgallery', '#slideshow');
-</script>
-</html>
View
39 collective/gallery/portlets/itemview.py
@@ -1,39 +0,0 @@
-from collective.portlet.itemview import vocabulary
-from zope import component
-from zope import interface
-from collective.gallery import interfaces
-from Products.Five.browser import BrowserView
-import logging
-logger = logging.getLogger('collective.gallery')
-
-class GalleryPortletViewEntry(object):
- interface.implements(vocabulary.IPortletView)
-
- id = "itemview_portlet_gallery"
- name = u"Gallery"
-
-class GalleryPortletView(BrowserView):
- interface.implements(interfaces.IGallery)
-
- def __init__(self, context, request):
- self.context = context
- self.request = request
- try:
- self.galleryview = component.getMultiAdapter((self.context, self.request),
- name="gallery")
-
- except component.ComponentLookupError:
- logger.error('no gallery view for %s'%self.context)
- self.galleryview = None
-
- self.id = self.context.getId()
- self.title = self.context.Title()
- self.creator = self.context.Creators()[0]
- self.description = self.context.Description()
-
- def photos(self):
- """Return the list of all IPhoto contained in the gallery"""
- if not self.galleryview: return []
- photos = self.galleryview.photos()
- return photos
-
View
41 collective/gallery/portlets/show_galleries.pt
@@ -1,41 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml"
- xmlns:tal="http://xml.zope.org/namespaces/tal"
- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
- tal:omit-tag="">
-<dl class="portlet portletGallery"
- i18n:domain="collective.gallery"
- tal:define="gallerydict view/get_gallery_pictures"
- tal:condition="gallerydict/pictures">
-
- <dt class="portletHeader">
- <span class="portletTopLeft"></span>
- <span>
- <span tal:omit-tag=""
- i18n:translate="portlet_from_gallery">Gallery</span>
- <tal:repl content="gallerydict/gallery/title">TITLE</tal:repl>
- </span>
- <span class="portletTopRight"></span>
- </dt>
-
- <tal:rep repeat="picture gallerydict/pictures">
- <dd tal:define="oddrow repeat/picture/odd"
- tal:attributes="class python:oddrow and 'portletItem even' or 'portletItem odd'">
- <a href="" tal:attributes="href gallerydict/gallery/absolute_url">
- <tal:img replace="structure python:picture.tag(scale=view.image_scale)" />
- </a><br />
- </dd>
- </tal:rep>
-
- <dd class="portletFooter">
- <span class="portletBottomLeft"></span>
- <a href="#"
- class="tile"
- tal:attributes="href gallerydict/gallery/absolute_url"
- i18n:translate="portlet_more">
- More pictures from this gallery
- </a>
- <span class="portletBottomRight"></span>
- </dd>
-</dl>
-</html>
-
View
112 collective/gallery/portlets/show_galleries.py
@@ -1,112 +0,0 @@
-from zope import schema
-from zope.formlib import form
-from zope.interface import implements
-from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
-from plone.portlets.interfaces import IPortletDataProvider
-from plone.app.portlets.portlets import base
-from plone.memoize.view import memoize
-
-from Acquisition import aq_inner
-from Products.CMFCore.utils import getToolByName
-
-from collective.gallery import messageFactory as _
-
-import random
-from Products.ATContentTypes.interfaces import IATImage
-
-class IShowGalleriesPortlet(IPortletDataProvider):
- search_portal = schema.Bool(
- title=_(u'Search portal for galleries'),
- description=_(u'If selected, search the whole portal for galleries.'\
- 'otherwise search only subfolders of the current path.'),
- required=True,
- default=True)
-
- num_pictures = schema.Int(
- title=_(u'Number of Pictures'),
- description=_(u'Define the number of pictures to show in the portlet'),
- required=True,
- default=1,
- min=1)
-
- image_size = schema.Choice(
- title=_(u'Image Size'),
- description=_(u'Select, which image scale should be used for the portlet.'),
- required=True,
- default=None,
- vocabulary="collective.gallery.ImageScaleVocabulary")
-
-
-class Assignment(base.Assignment):
- implements(IShowGalleriesPortlet)
- image_size = 'mini'
-
- def __init__(self, search_portal=True, num_pictures=1, image_size='mini'):
- self.search_portal= search_portal
- self.num_pictures = num_pictures
- self.image_size = image_size
-
- @property
- def title(self):
- return _(u"Gallery Portlet")
-
-
-class AddForm(base.AddForm):
- form_fields = form.Fields(IShowGalleriesPortlet)
- label = _(u"Add portlet to show pictures from galleries")
- description = _(u"This portlet shows pictures from galleries.")
-
- def create(self, data):
- return Assignment(**data)
-
-
-class EditForm(base.EditForm):
- form_fields = form.Fields(IShowGalleriesPortlet)
- label = _(u"Add portlet to show pictures from galleries")
- description = _(u"This portlet shows pictures from galleries.")
-
-
-class Renderer(base.Renderer):
- render = ViewPageTemplateFile('show_galleries.pt')
-
- @property
- def image_scale(self):
- return getattr(self.data, 'image_size', 'mini')
-
- # TODO: cache me
- def get_galleries(self):
- context = aq_inner(self.context)
- if self.data.search_portal:
- portal_url = getToolByName(context, 'portal_url')
- context = portal_url.getPortalObject()
- cat = getToolByName(context,'portal_catalog')
-
- query = {}
- query['is_folderish'] = True
- query['path'] = {'query': '/'.join(context.getPhysicalPath())}
- brains = cat(**query)
-
- # TODO: import gallery view names from config.py or make this somehow
- # more generic
- return [brain for brain in brains
- if brain.getObject().defaultView() in ('gallery.html',)]
-
- @memoize
- def get_gallery_pictures(self):
- gallery = None
- pictures = []
- num_pictures = self.data.num_pictures
- galleries = self.get_galleries()
- if galleries:
- gallery = random.choice(galleries).getObject()
- pictures = [pic for pic in gallery.contentValues()
- if IATImage.providedBy(pic)]
- if len(pictures) > num_pictures:
- pictures = random.sample(pictures, num_pictures)
- return {'gallery': gallery, 'pictures': pictures}
-
- @property
- def available(self):
- # TODO: if not search_portal, only show me for folderish contexts
- showme = bool(self.get_gallery_pictures()['pictures'])
- return showme
View
12 collective/gallery/profiles/default/cssregistry.xml
@@ -1,12 +0,0 @@
-<?xml version="1.0"?>
-<!-- This file holds the setup configuration for the portal_css tool. -->
-
-<object name="portal_css">
-
- <stylesheet title=""
- id="gallery.css"
- media="screen" rel="stylesheet" rendering="import"
- cacheable="True" compression="safe" cookable="True"
- enabled="1" expression="" />
-
-</object>
View
14 collective/gallery/profiles/default/jsregistry.xml
@@ -1,14 +0,0 @@
-<?xml version="1.0"?>
-<object name="portal_javascripts">
-
- <javascript
- id="gallery.js"
- cacheable="True" compression="safe" cookable="False"
- enabled="True" expression="" inline="False" conditionalcomment=""/>
-
- <javascript
- id="gallery-portlet.js"
- cacheable="True" compression="safe" cookable="False"
- enabled="True" expression="" inline="False" conditionalcomment=""/>
-
-</object>
View
3 collective/gallery/profiles/default/metadata.xml
@@ -1,7 +1,6 @@
<?xml version="1.0"?>
<metadata>
- <version>14</version>
+ <version>2001</version>
<dependencies>
- <dependency>profile-collective.js.galleriffic:default</dependency>
</dependencies>
</metadata>
View
11 collective/gallery/profiles/default/portlets.xml
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<portlets
- xmlns:i18n="http://xml.zope.org/namespaces/i18n"
- i18n:domain="collective.gallery">
- <portlet
- addview="collective.gallery.show_galleries"
- title = "Gallery Portlet"
- description = "Add portlet to show pictures from galleries."
- />
-</portlets>
-
View
7 collective/gallery/profiles/default/propertiestool.xml
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<object name="portal_properties" meta_type="Plone Properties Tool">
- <object name="gallery_properties" meta_type="Plone Property Sheet">
- <property name="photo_max_size" type="int">400</property>
- <property name="thumb_max_size" type="int">80</property>
- </object>
-</object>
View
3 collective/gallery/profiles/default/registry.xml
@@ -0,0 +1,3 @@
+<registry>
+ <records interface="collective.gallery.interfaces.IGallerySettings" />
+</registry>
View
10 collective/gallery/profiles/default/skins.xml
@@ -1,10 +0,0 @@
-<?xml version="1.0"?>
-<object name="portal_skins">
- <object name="collective_gallery_theme"
- meta_type="Filesystem Directory View"
- directory="collective.gallery:skins/collective_gallery_theme"/>
- <skin-path name="*">
- <layer name="collective_gallery_theme"
- insert-after="custom"/>
- </skin-path>
-</object>
View
6 collective/gallery/profiles/default/types/Folder.xml
@@ -1,6 +0,0 @@
-<?xml version="1.0"?>
-<object name="Folder">
- <property name="view_methods" purge="False">
- <element value="gallery.html" />
- </property>
-</object>
View
6 collective/gallery/profiles/default/types/Topic.xml
@@ -1,6 +0,0 @@
-<?xml version="1.0"?>
-<object name="Topic">
- <property name="view_methods" purge="False">
- <element value="gallery.html" />
- </property>
-</object>
View
8 collective/gallery/profiles/uninstall/cssregistry.xml
@@ -1,8 +0,0 @@
-<?xml version="1.0"?>
-<!-- This file holds the setup configuration for the portal_css tool. -->
-
-<object name="portal_css">
-
- <stylesheet title="" id="gallery.css" remove="true" />
-
-</object>
View
16 collective/gallery/profiles/uninstall/jsregistry.xml
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-<object name="portal_javascripts">
-
- <javascript
- id="++resource++jquery.galleriffic.js"
- remove="true" />
-
- <javascript
- id="++resource++jquery.opacityrollover.js"
- remove="true" />
-
- <javascript
- id="++resource++jquery.history.js"
- remove="true" />
-
-</object>
View
7 collective/gallery/profiles/uninstall/skins.xml
@@ -1,7 +0,0 @@
-<?xml version="1.0"?>
-<object name="portal_skins">
- <object name="collective_gallery_theme" remove="true" />
- <skin-path name="*">
- <layer name="collective_gallery_theme" remove="true" />
- </skin-path>
-</object>
View
6 collective/gallery/profiles/uninstall/types/Link.xml
@@ -1,6 +0,0 @@
-<?xml version="1.0"?>
-<object name="Link">
- <property name="view_methods" purge="False">
- <element value="gallery" remove="true" />
- </property>
-</object>
View
7 ...ry/profiles/default/componentregistry.xml → ...ery/profiles/zclean/componentregistry.xml
@@ -4,24 +4,29 @@
<adapter
factory="collective.gallery.brain.Photo"
for="Products.ZCatalog.interfaces.ICatalogBrain"
- provides="collective.gallery.interfaces.IPhoto"/>
+ provides="collective.gallery.interfaces.IPhoto"
+ remove="True"
+ />
<adapter
factory="collective.gallery.link.picasaweb.Link"
for="collective.gallery.interfaces.ILink"
provides="collective.gallery.interfaces.IGallery"
name="picasaweb"
+ remove="True"
/>
<adapter
factory="collective.gallery.link.flickr.Link"
for="collective.gallery.interfaces.ILink"
provides="collective.gallery.interfaces.IGallery"
name="flickr"
+ remove="True"
/>
<adapter
factory="collective.gallery.link.facebook.Link"
for="collective.gallery.interfaces.ILink"
provides="collective.gallery.interfaces.IGallery"
name="facebook"
+ remove="True"
/>
</adapters>
</componentregistry>
View
6 collective/gallery/profiles/zclean/cssregistry.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<object name="portal_css">
+
+ <stylesheet remove="True" id="gallery.css" />
+
+</object>
View
7 collective/gallery/profiles/zclean/jsregistry.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<object name="portal_javascripts">
+
+ <javascript id="gallery.js" remove="True" />
+ <javascript id="gallery-portlet.js" remove="True" />
+
+</object>
View
4 collective/gallery/profiles/zclean/metadata.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<metadata>
+ <version>1</version>
+</metadata>
View
4 collective/gallery/profiles/zclean/portlets.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<portlets xmlns:i18n="http://xml.zope.org/namespaces/i18n" i18n:domain="collective.gallery">
+ <portlet remove="True" addview="collective.gallery.show_galleries" />
+</portlets>
View
4 collective/gallery/profiles/zclean/propertiestool.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<object name="portal_properties" meta_type="Plone Properties Tool">
+ <object name="gallery_properties" remove="True" />
+</object>
View
8 collective/gallery/profiles/zclean/skins.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0"?>
+<object name="portal_skins">
+ <!-- cleanup from 1.0 -->
+ <object name="collective_gallery_theme" remove="True"/>
+ <skin-path name="*">
+ <layer name="collective_gallery_theme" remove="True"/>
+ </skin-path>
+</object>
View
2 ...llery/profiles/uninstall/types/Folder.xml → .../gallery/profiles/zclean/types/Folder.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<object name="Folder">
<property name="view_methods" purge="False">
- <element value="gallery" remove="true" />
+ <element value="gallery.html" remove="True" />
</property>
</object>
View
2 ...e/gallery/profiles/default/types/Link.xml → ...ve/gallery/profiles/zclean/types/Link.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<object name="Link">
<property name="view_methods" purge="False">
- <element value="gallery.html" />
+ <element value="gallery.html" remove="True"/>
</property>
</object>
View
2 ...allery/profiles/uninstall/types/Topic.xml → ...e/gallery/profiles/zclean/types/Topic.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<object name="Topic">
<property name="view_methods" purge="False">
- <element value="gallery" remove="true" />
+ <element value="gallery.html" remove="True"/>
</property>
</object>
View
2 collective/gallery/settings.py
@@ -0,0 +1,2 @@
+from zope import interface
+from zope import schema
View
70 collective/gallery/skins/collective_gallery_theme/gallery-portlet.js
@@ -1,70 +0,0 @@
-// We only want these styles applied when javascript is enabled
-
-var init_galleryportlet = function(id, container){
- var galleryMaxsize = 250;
- var galleryPhoto = $(container);
- var galleryPhotoPosition = galleryPhoto.position();
- var galleryPhotoWidth = galleryPhoto.width();
- var galleryPhotoHeight = galleryPhoto.height();
-
- function galleryResizePhoto(photo) {
- // resize the photo if the scale is greater than our maxsize
- if (!photo)return;
- var dw = photo.width() - galleryMaxsize;
- var dh = photo.height() - galleryMaxsize;
- if (dw > 0 || dh > 0) {
- if (dw > dh){
- photo.width(galleryMaxsize);
- }else{photo.height(galleryMaxsize);}
- }
- }
- function galleryCenterPhoto(photo) {
- // display the photo in the good absolute position
- // fix fast navigation bug (where imgs where added one upon the other)
- if (!photo)return;
- var photoWidth = photo.width();
- var photoHeight = photo.height();
- var photoTop = parseInt(galleryPhotoPosition.top + (galleryPhotoHeight - photoHeight) / 2);
- var photoLeft = parseInt(galleryPhotoPosition.left + (galleryPhotoWidth - photoWidth) / 2);
- photo.parent().parent().css({'position': 'absolute', 'top': photoTop + 'px', 'left': photoLeft + 'px'});
- }
-
- var gallery = $(id).galleriffic({
-
- delay: 3000, // in milliseconds
- //numThumbs: 5, // The number of thumbnails to show page
- //preloadAhead: 40, // Set to -1 to preload all images
- enableTopPager: false,
- enableBottomPager: false,
- //maxPagesToShow: 7, // The maximum number of pages to display in either the top or bottom pager
- imageContainerSel: container, // The CSS selector for the element within which the main slideshow image should be rendered
- //controlsContainerSel: '', // The CSS selector for the element within which the slideshow controls should be rendered
- //captionContainerSel: '#gallerycaption', // The CSS selector for the element within which the captions should be rendered
- //loadingContainerSel: '#galleryloading', // The CSS selector for the element within which should be shown when an image is loading
- renderSSControls: false, // Specifies whether the slideshow's Play and Pause links should be rendered
- renderNavControls: false, // Specifies whether the slideshow's Next and Previous links should be rendered
- //playLinkText: 'Play',
- //pauseLinkText: 'Pause',
- //prevLinkText: 'Previous',
- //nextLinkText: 'Next',
- //nextPageLinkText: 'Next &rsaquo;',
- //prevPageLinkText: '&lsaquo; Prev',
- enableHistory: false, // Specifies whether the url's hash and the browser's history cache should update when the current slideshow image changes
- enableKeyboardNavigation: false, // Specifies whether keyboard navigation is enabled
- autoStart: true, // Specifies whether the slideshow should be playing or paused when the page first loads
- syncTransitions: true, // Specifies whether the out and in transitions occur simultaneously or distinctly
- defaultTransitionDuration: 500, // If using the default transitions, specifies the duration of the transitions
- onTransitionIn: function(newSlide, newCaption, isSync){
- //code kept from galleriffic
- $('.image-caption').hide();
- newSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0);
- if (newCaption)
- newCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0);
- galleryResizePhoto(newSlide.find('img'));
- galleryCenterPhoto(newSlide.find('img'));
-
- }, // accepts a delegate like such: function(slide, caption, isSync) { ... }
-
- });
-
-};
View
51 collective/gallery/skins/collective_gallery_theme/gallery.css
@@ -1,51 +0,0 @@
-#gallerythumbs,
-#galleryphoto{
-/* background-color:#000000;*/
-}
-#gallerythumbs ul.thumbs{
- display:block;
- height:80px; /* thumb_max_size + 8 */
- margin:0px 1em;
-}
-#gallerythumbs ul.thumbs li {
- float: left;
- list-style: none outside none;
- margin: 5px 0 5px 0;
- padding: 0;
-}
-#gallerythumbs a,
-#gallerythumbs a:visited
-{font-weight:bold;text-decoration:none;border:0;line-height:80px;}
-#gallerypageprev{float:left;}
-#gallerypagenext{float:right;}
-
-#galleryphoto {
- height:420px; /* photo_max_size + 20 */
-}
-#gallerycontrol,
-#galleryphoto,
-#gallerythumbs{
- width: 420px; /* photo_max_size + 20 */
-}
-#gallerycontrol #galleryprev{
- float:left;
-}
-#gallerycontrol
-{
- text-align:center;
-}
-#gallerycontrol #gallerynext{
- float:right;
-}
-/*force thumb sizes*/
-.thumb img{width:72px; height:72px;}
-
-/* caption styling */
-#gallerycaption {
- display:none;
- background:url('gallery_tooltip.png');
- height:143px;
- width:240px;
- padding:40px 30px 10px 30px;
- font-size:11px;
-}
View
46 collective/gallery/skins/collective_gallery_theme/gallery.html.pt
@@ -1,46 +0,0 @@
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n" lang="en" metal:use-macro="context/main_template/macros/master" i18n:domain="collective.gallery">
- <body>
- <div metal:fill-slot="main">
- <tal:main-macro metal:define-macro="main"
- tal:define="getToolByName python:modules['Products.CMFCore.utils'].getToolByName;
- plone_utils python:getToolByName(view.context, 'plone_utils');
- galleryview here/@@gallery">
- <div tal:replace="structure provider:plone.abovecontenttitle" />
- <p class="document_date" tal:content="python:plone_utils.toLocalizedTime(context.CreationDate())">
- </p>
- <h1 class="documentFirstHeading">
- <metal:field use-macro="python:here.widget('title', mode='view')">
- Title
- </metal:field>
- </h1>
- <div id="gallery">
- <div id="gallerycontrol">
- <a href="" id="galleryprev" i18n:translate="">Previous</a>
- <a href="" id="galleryplay" i18n:translate="">Play</a>
- <a href="" id="gallerypause" i18n:translate="">Pause</a>
- <a href="" id="gallerynext" i18n:translate="">Next</a>
- </div>
- <div id="galleryloading" style="display:none"><img tal:attributes="src string:${galleryview/context/portal_url}/spinner.gif" /></div>
- <div id="galleryphoto"></div>
- <div id="gallerycaption"></div>
- <div id="gallerythumbs" style="display:none">
- <a href="" id="gallerypageprev">&lt;</a>
- <a href="" id="gallerypagenext">&gt;</a>
- <ul class="thumbs noscript">
- <li tal:repeat="img galleryview/photos">
- <a class="thumb" tal:attributes="title img/title;href img/url; name img/id" title="Title #0">
- <img tal:attributes="src img/thumb_url;alt img/title" />
- </a>
- <div class="caption">
- <h2 tal:content="img/title">Title</h2>
- <p class="galleryphotodesc" tal:content="img/description">Description</p>
- <a tal:attributes="href img/url" target="_blank" i18n:translate="">Download Original</a>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </tal:main-macro>
- </div>
- </body>
-</html>
View
2 collective/gallery/skins/collective_gallery_theme/gallery.html.pt.metadata
@@ -1,2 +0,0 @@
-[default]
-title= Gallery view
View
139 collective/gallery/skins/collective_gallery_theme/gallery.js
@@ -1,139 +0,0 @@
-// We only want these styles applied when javascript is enabled
-
-jQuery(document).ready(function($){
- var galleryMaxsize = 400;
- var galleryMouseOpacity = 0.67;
- var galleryPhoto = $('#galleryphoto');
- var galleryPhotoPosition = galleryPhoto.position();
- var galleryPhotoWidth = galleryPhoto.width();
- var galleryPhotoHeight = galleryPhoto.height();
-
- function galleryResizePhoto(photo) {
- // resize the photo if the scale is greater than our maxsize
- if (!photo)return;
- var dw = photo.width() - galleryMaxsize;
- var dh = photo.height() - galleryMaxsize;
- if (dw > 0 || dh > 0) {
- if (dw > dh){
- photo.width(galleryMaxsize);
- }else{photo.height(galleryMaxsize);}
- }
- }
- function galleryCenterPhoto(photo) {
- // display the photo in the good absolute position
- // fix fast navigation bug (where imgs where added one upon the other)
- if (!photo)return;
- var photoWidth = photo.width();
- var photoHeight = photo.height();
- var photoTop = parseInt(galleryPhotoPosition.top + (galleryPhotoHeight - photoHeight) / 2);
- var photoLeft = parseInt(galleryPhotoPosition.left + (galleryPhotoWidth - photoWidth) / 2);
- photo.parent().parent().css({'position': 'absolute', 'top': photoTop + 'px', 'left': photoLeft + 'px'});
- }
-
- if ($('div#gallerythumbs').length == 0){return;}
- if ($('ul.thumbs li').length == 0){return;}
- $('div#gallerythumbs').css({'display': 'block'});
- $('a.thumb').css({
- 'float': 'left',
- 'margin-right':'5px',
- 'height':'80px', //use ul.thumbs heigth from css
- 'border-bottom':'none'
- });
-
- $('.thumbs li, #gallerypageprev, #gallerypagenext').opacityrollover({
- mouseOutOpacity: galleryMouseOpacity,
- mouseOverOpacity: 1.0,
- fadeSpeed: 'fast',
- exemptionSelector: '.selected'
- });
-
- var gallery = $('#gallerythumbs').galleriffic({
-
- delay: 3000, // in milliseconds
- numThumbs: 5, // The number of thumbnails to show page
- //preloadAhead: 40, // Set to -1 to preload all images
- enableTopPager: false,
- enableBottomPager: false,
- //maxPagesToShow: 7, // The maximum number of pages to display in either the top or bottom pager
- imageContainerSel: '#galleryphoto', // The CSS selector for the element within which the main slideshow image should be rendered
- //controlsContainerSel: '', // The CSS selector for the element within which the slideshow controls should be rendered
- captionContainerSel: '#gallerycaption', // The CSS selector for the element within which the captions should be rendered
- //loadingContainerSel: '#galleryloading', // The CSS selector for the element within which should be shown when an image is loading
- renderSSControls: false, // Specifies whether the slideshow's Play and Pause links should be rendered
- renderNavControls: false, // Specifies whether the slideshow's Next and Previous links should be rendered
- //playLinkText: 'Play',
- //pauseLinkText: 'Pause',
- //prevLinkText: 'Previous',
- //nextLinkText: 'Next',
- //nextPageLinkText: 'Next &rsaquo;',
- //prevPageLinkText: '&lsaquo; Prev',
- enableHistory: false, // Specifies whether the url's hash and the browser's history cache should update when the current slideshow image changes
- enableKeyboardNavigation: false, // Specifies whether keyboard navigation is enabled
- autoStart: true, // Specifies whether the slideshow should be playing or paused when the page first loads
- syncTransitions: true, // Specifies whether the out and in transitions occur simultaneously or distinctly
- defaultTransitionDuration: 500, // If using the default transitions, specifies the duration of the transitions
- onSlideChange: function(prevIndex, nextIndex) {
- if (this.isSlideshowRunning) {
- $('#galleryplay').hide();
- $('#gallerypause').show();
- } else {
- $('#gallerypause').hide();
- $('#galleryplay').show();
- }
- },
- onTransitionOut: undefined, // accepts a delegate like such: function(slide, caption, isSync, callback) { ... }
- onTransitionIn: function(newSlide, newCaption, isSync){
- //code kept from galleriffic
- $('.image-caption').hide();
- newSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0);
- if (newCaption)
- newCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0);
- galleryResizePhoto(newSlide.find('img'));
- galleryCenterPhoto(newSlide.find('img'));
-
- }, // accepts a delegate like such: function(slide, caption, isSync) { ... }
- onPageTransitionOut: undefined, // accepts a delegate like such: function(slide, caption, isSync, callback) { ... }
- onPageTransitionIn: undefined, // accepts a delegate like such: function(slide, caption, isSync) { ... }
- onImageAdded: undefined, // accepts a delegate like such: function(imageData, $li) { ... }
- onImageRemoved: undefined // accepts a delegate like such: function(imageData, $li) { ... }
- });
- if (gallery.autoStart){
- $('#galleryplay').hide();
- $('#gallerypause').show();
- } else {
- $('#gallerypause').hide();
- $('#galleryplay').show();
- }
- $('#gallerypageprev').click(function(e) {
- gallery.previousPage();
- e.preventDefault();
- });
-
- $('#gallerypagenext').click(function(e) {
- gallery.nextPage();
- e.preventDefault();
- });
- $('#galleryprev').click(function(e) {
- gallery.previous();
- e.preventDefault();
- });
- $('#gallerynext').click(function(e) {
- gallery.next();
- e.preventDefault();
- });
-
- $('#galleryplay').click(function(e) {
- $('#galleryplay').hide();
- gallery.play();
- e.preventDefault();
- $('#gallerypause').show();
- });
- $('#gallerypause').click(function(e) {
- $('#gallerypause').hide();
- gallery.pause();
- e.preventDefault();
- $('#galleryplay').show();
- });
- $('#galleryphoto').tooltip({position:'center right', effect:'fade',relative:true});
-
-});
View
BIN collective/gallery/skins/collective_gallery_theme/gallery_tooltip.png
Deleted file not rendered
View
4 collective/gallery/tests/layer.py
@@ -10,13 +10,10 @@ class CollectiveGalleryLayer(PloneSandboxLayer):
def setUpZope(self, app, configurationContext):
# Load ZCML
import collective.gallery
- import collective.js.galleriffic
self.loadZCML(package=collective.gallery)
- self.loadZCML(package=collective.js.galleriffic)
# Install product and call its initialize() function
z2.installProduct(app, 'collective.gallery')
- z2.installProduct(app, 'collective.js.galleriffic')
def setUpPloneSite(self, portal):
# Install into Plone site using portal_setup
@@ -25,7 +22,6 @@ def setUpPloneSite(self, portal):
def tearDownZope(self, app):
# Uninstall product
z2.uninstallProduct(app, 'collective.gallery')
- z2.uninstallProduct(app, 'collective.js.galleriffic')
FIXTURE = CollectiveGalleryLayer()
View
20 collective/gallery/tests/test_core.py
@@ -20,20 +20,18 @@ def testDate(self):
self.assertEqual(self.view.date, "a date")
def testPhotos(self):
- self.failUnless(not self.view.photos())
+ self.assertTrue(not self.view.photos())
self.assertEqual(type(self.view.photos()), list)
class TestIntegration(base.TestCase):
- def testProperties(self):
+ def testRegistry(self):
from collective.gallery import core
+ from plone.registry.interfaces import IRegistry
view = core.BaseBrowserView(self.portal, None)
- self.failUnless(view.width == 400)
- self.portal.portal_properties.gallery_properties._updateProperty('photo_max_size', 500)
- self.failUnless(view.width == 500)
-
-def test_suite():
- """This sets up a test suite that actually runs the tests in the class
- above
- """
- return base.build_test_suite((Test, TestIntegration))
+ registry = self.portal.portal_registry
+ self.assertTrue(view.width == 400)
+ key = 'collective.gallery.interfaces.IGallerySettings.photo_max_size'
+ registry[key] = 500
+ self.assertTrue(view.width == 500)
+
View
26 collective/gallery/tests/test_facebook.py
@@ -18,15 +18,13 @@ def getAdapter(self, url):
def testDefaultWithHeight(self):
#test default values
- self.failUnless(self.adapter.width == 400)
- self.failUnless(self.adapter.height == 400)
+ self.assertTrue(self.adapter.width == 400)
+ self.assertTrue(self.adapter.height == 400)
def testValidate(self):
- self.failUnless(self.adapter.validate())
- adapter = self.getAdapter(URL1)
- self.failUnless(adapter.validate())
- adapter = self.getAdapter("http://no.facebook.com")
- self.failUnless(not adapter.validate())
+ from collective.gallery.link import facebook
+ self.assertTrue(facebook.check(URL1))