[Zope3-checkins] CVS: zopeproducts/photoslide/browser -
__init__.py:1.1 add.pt:1.1 configure.zcml:1.1
editPhotos.pt:1.1 photoslide.py:1.1 viewPhoto.pt:1.1
viewThumbnails.pt:1.1
Bjorn Tillenius
bjorn at codeworks.lt
Fri Aug 15 09:15:26 EDT 2003
Update of /cvs-repository/zopeproducts/photoslide/browser
In directory cvs.zope.org:/tmp/cvs-serv26803/browser
Added Files:
__init__.py add.pt configure.zcml editPhotos.pt photoslide.py
viewPhoto.pt viewThumbnails.pt
Log Message:
First checkin of the photoslide product.
This product produces a slide show of photos. It works, although the
views aren't that nice yet.
=== Added File zopeproducts/photoslide/browser/__init__.py ===
=== Added File zopeproducts/photoslide/browser/add.pt ===
<html metal:use-macro="views/standard_macros/dialog" i18n:domain="zope">
<body>
<div metal:fill-slot="body">
<form action="action.html" method="post">
<table class="TypeListing" cellpadding="3">
<caption i18n:translate="">Add Content</caption>
<tbody tal:define="infos view/addingInfo">
<tr tal:repeat="info infos">
<td class="Selector">
<input type="radio" name="type_name"
tal:attributes="value info/action;
id info/action;
checked python:len(infos)==1" />
</td>
<td class="TypeName">
<label style="font-weight: bold;"
tal:attributes="for info/action">
<span tal:replace="info/title" >Folder</span>
</label>
<div class="TypeDescription" tal:content="info/description">
Folders are generic containers for content, including other
folders.
</div>
</td>
</tr>
<tr>
<td><br /></td>
<td>
<input type="text" name="id"
tal:condition="view/namesAccepted"
tal:attributes="value request/id | nothing"
/>
<input type="submit" value=" Add " i18n:attributes="value" />
</td>
</tr>
</tbody>
</table>
</form>
</div>
</body>
</html>
=== Added File zopeproducts/photoslide/browser/configure.zcml ===
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
>
<!-- PhotoSlide -->
<browser:addform
label="Add Photo Slide"
name="AddPhotoSlide"
content_factory="zopeproducts.photoslide.PhotoSlide"
schema="zopeproducts.photoslide.interfaces.IPhotoSlide"
permission="zope.ManageContent"
menu="add_content"
title="Photo Slide"
class="zopeproducts.photo.browser.photo.CurrentDisplayIdFix"
/>
<browser:editform
label="Edit Photo Slide"
name="edit.html"
schema="zopeproducts.photoslide.interfaces.IPhotoSlide"
permission="zope.ManageContent"
menu="zmi_views"
title="Edit"
class="zopeproducts.photo.browser.photo.CurrentDisplayIdFix"
/>
<browser:menu
id="add_photoslide"
title="Menu of objects to be added to the Photo Slide"
/>
<browser:menuItem
menu="add_photoslide"
for="zope.app.interfaces.container.IAdding"
action="AddPhoto"
title="Photo"
/>
<browser:menuItem
menu="zmi_views"
for="zopeproducts.photoslide.interfaces.IPhotoSlide"
action="@@viewThumbnails.html"
title="View Slide Show"
/>
<browser:view
name="+"
for="zopeproducts.photoslide.interfaces.IPhotoSlide"
class=".photoslide.PhotoSlideAdding"
permission="zope.ManageContent"
allowed_attributes="addingInfo"
menu="zmi_actions"
title="Add"
>
<browser:page name="index.html" template="add.pt" />
<browser:page name="action.html" attribute="action" />
</browser:view>
<browser:page
for="zopeproducts.photoslide.interfaces.IPhotoSlide"
name="contents.html"
permission="zope.ManageContent"
class="zope.app.browser.container.contents.Contents"
attribute="contents"
menu="zmi_views"
title="Contents"
/>
<browser:page
for="zopeproducts.photoslide.interfaces.IPhotoSlide"
name="viewThumbnails.html"
permission="zope.Public"
class=".photoslide.PhotoSlideViewThumbnails"
template="viewThumbnails.pt"
menu="zmi_views"
title="View"
/>
<browser:page
for="zopeproducts.photoslide.interfaces.IPhotoSlide"
name="viewPhoto.html"
permission="zope.Public"
class=".photoslide.PhotoSlideViewPhoto"
template="viewPhoto.pt"
/>
<browser:page
for="zopeproducts.photoslide.interfaces.IPhotoSlide"
name="editPhotos.html"
permission="zope.ManageContent"
class=".photoslide.PhotoSlideViewEditPhotos"
template="editPhotos.pt"
menu="zmi_views"
title="Edit Photos"
/>
<browser:defaultView
for="zopeproducts.photoslide.interfaces.IPhotoSlide"
name="viewThumbnails.html"
/>
<!-- PhotoSlideFolder -->
<browser:page
for="zopeproducts.photoslide.interfaces.IPhotoSlideFolder"
name="contents.html"
permission="zope.ManageContent"
class="zope.app.browser.container.contents.Contents"
attribute="contents"
menu="zmi_views"
title="Contents"
/>
<browser:view
name="+"
for="zopeproducts.photoslide.interfaces.IPhotoSlideFolder"
class=".photoslide.PhotoSlideFolderAdding"
permission="zope.ManageContent"
allowed_attributes="addingInfo"
menu="zmi_actions"
title="Add"
>
<browser:page name="index.html" template="add.pt" />
<browser:page name="action.html" attribute="action" />
</browser:view>
<browser:menu
id="add_photoslidefolder"
title="Menu of objects to be added to the Photo Slide Collection"
/>
<browser:menuItem
menu="add_photoslidefolder"
for="zope.app.interfaces.container.IAdding"
action="AddPhoto"
title="Photo"
/>
<browser:menuItem
menu="add_photoslidefolder"
for="zope.app.interfaces.container.IAdding"
action="AddPhotoSlide"
title="Photo Slide"
/>
<browser:menuItem
menu="add_content"
for="zope.app.interfaces.container.IAdding"
title="Photo Slide Folder"
action="PhotoSlideFolder"
description="Photo Slide Collection"
/>
<browser:defaultView
for="zopeproducts.photoslide.interfaces.IPhotoSlideFolder"
name="contents.html"
/>
</configure>
=== Added File zopeproducts/photoslide/browser/editPhotos.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<div metal:fill-slot="body" i18n:domain="photo">
<h3 i18n:translate="">Edit Photos</h3>
<p tal:define="status view/update"
tal:condition="status"
tal:content="status" />
<br>
<form method="POST" tal:attributes="action request/URL">
<center>
<table width="90%" align="center">
<tr tal:repeat="photo context/getPhotos" >
<tal:block
tal:define="photoView python: view.getPhotoView(photo)"
>
<td width="30%" valign="top" align="left">
<span tal:replace="structure photoView/title_widget/row" />
<img src=""
tal:attributes="src python:view.getPhotoURL(photo,'thumbnail')"/>
<span tal:replace="structure photoView/position_widget/row" />
</td>
<td width="70%">
<span
tal:replace="structure photoView/description_widget/row"/>
</td>
</tal:block>
</tr>
</table>
</center>
<div class="controls">
<input type="submit" name="UPDATE_EDIT_PHOTOS"
value="Submit" i18n:attributes="value submit-button" />
</div>
</form>
</div>
</body>
</html>
=== Added File zopeproducts/photoslide/browser/photoslide.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""View classes for PhotoSlide
$Id: photoslide.py,v 1.1 2003/08/15 12:15:17 BjornT Exp $
"""
from datetime import datetime
from zope.app.browser.container.adding import Adding
from zope.app.browser.form.widget import ListWidget
from zope.app import zapi
from zope.publisher.browser import BrowserView
from zope.schema import EnumeratedInt
from zope.i18n import MessageIDFactory
_ = MessageIDFactory("photo")
class PhotoSlideAdding(Adding):
"""Custom adding view for PhotoSlide objects."""
menu_id = "add_photoslide"
class PhotoSlideFolderAdding(Adding):
"""Custom adding view for PhotoSlideFolder objects."""
menu_id = "add_photoslides"
class PhotoSlideViewBase(BrowserView):
"""Photo Slide View base class.
Defines some helper functions for all sub-classes.
"""
def __init__(self, context, request):
self.context = context
self.request = request
self._setAttributes(request)
def getPhotoURL(self, photo, display=None):
"""Returns the relative URL of the current photo"""
photo_name = self._getPhotoName(photo)
if hasattr(self, 'rq_display') and self.rq_display and not display:
display = self.rq_display
if display:
return "%s?display=%s" % (photo_name, display)
else:
return photo_name
def _setAttributes(self, request):
"""Sets all attributes in request to local attributes."""
for attr in ('page', 'display'):
if attr in request:
setattr(self, 'rq_' + attr, request[attr])
def _getPhotoName(self, photo):
return self.context.keys()[self.context.values().index(photo)]
def _createUrl(self, pageName, **kw):
"""Returns the page name concatenated with it's needed parameters.
The value of each parameter is fetch from self, though it can
be overidden by passing it along as a keyword argument.
"""
paramDict = kw
# put all parameters in paramDict
for param in ('page', 'display'):
if param not in paramDict and getattr(self, 'rq_'+param):
paramDict[param] = getattr(self, 'rq_'+param)
# build the url
url = pageName + '?'
for name, value in paramDict.items():
if url[len(url)-1] != '?':
url += '&'
url += name + '=' + str(value)
return url
class PhotoSlideViewThumbnails(PhotoSlideViewBase):
"""View class for viewThumbnails.html"""
def getPhotosPage(self):
"""Returns a list of lists of tuples containing the relative
thumbnail URL and the relative URL the the view page of the
photo
"""
result = []
max_col = 3
row_count = 0
col_count = 0
index = 0
photos = self.context.getPhotos()
# XXX should be possible to get several pages
for photo in photos:
index += 1
if col_count >= max_col:
col_count = 0
row_count += 1
if col_count == 0:
result.append([])
result[row_count].append(('viewPhoto.html?page=%i' % index,
self.getPhotoURL(photo,
'thumbnail')))
col_count += 1
return result
class PhotoSlideViewEditPhotos(PhotoSlideViewBase):
"""View class for editPhotos.html"""
def __init__(self, context, request):
self.context = context
self.request = request
def update(self):
if self.request.get('UPDATE_EDIT_PHOTOS', None):
changed = False
orgPositions = self.context.getPhotoNames()
changedPositions = []
for name in orgPositions:
photo = zapi.traverseName(self.context, name,
request=self.request)
changed = changed or \
self._setPhotoAttribute(photo, name, 'title',
self.request)
changed = changed or \
self._setPhotoAttribute(photo, name, 'description',
self.request)
if self._isPositionChanged(name, orgPositions, self.request):
changed = True
changedPositions.append(name)
self._setPhotoPositions(changedPositions, self.request)
if changed:
formatter = self.request.locale.getDateTimeFormatter('medium')
result = _("Values updated on ${date_time}")
# XXX Should probably not use UTC all the time
result.mapping = {'date_time':
formatter.format(datetime.utcnow())}
else:
result = _("Nothing was changed")
return result
def _setPhotoAttribute(self, photo, photoName, photoAttr, dict):
"""Sets the photo attribute in case it has changed and is in dict"""
widgetName = 'photo_%s_%s' % (photoName, photoAttr)
changed = False
if widgetName in dict:
if getattr(photo, photoAttr) <> dict[widgetName]:
changed = True
setattr(photo, photoAttr, dict[widgetName])
return changed
def _isPositionChanged(self, photoName, orgPositions, dict):
widgetName = 'photo_%s_position' % photoName
return orgPositions.index(photoName)+1 != int(dict[widgetName])
def _setPhotoPositions(self, photoNames, dict):
"""Sets the photo's position in case it has been changed."""
for name in photoNames:
widgetName = 'photo_%s_position' % name
self.context.setPosition(name, dict[widgetName])
def getPhotoView(self, photo):
"""Returns a view for the photo.
This way we can re-use the widget's the photo has.
"""
view = zapi.getView(photo, 'edit.html', self.request)
photoName = self._getPhotoName(photo)
# Add a positions widget
field = EnumeratedInt(
__name__='position',
title=u'Pos',
description=u'The position of the photo.',
allowed_values=range(1, len(self.context)+1),
default=self.context.getPosition(photoName)
)
view.position_widget = ListWidget( field, self.request)
pos = self.context.getPosition(photoName)
view.position_widget.setData(pos)
# Make the widget's names unique
view.title_widget.name = 'photo_%s_title' % photoName
view.position_widget.name = 'photo_%s_position' % photoName
view.position_widget.size = 1
view.description_widget.name = 'photo_%s_description' % photoName
view.description_widget.height = 5
return view
class PhotoSlideViewPhoto(PhotoSlideViewBase):
"""View class for viewPhoto.html"""
rq_page = 1
rq_display = None
def __init__(self, context, request):
super(PhotoSlideViewPhoto, self).__init__(context, request)
self.rq_page = int(self.rq_page)
def getNumberOfPhotos(self):
"""Returns the number of photos in the photo slide."""
return self.context.__len__()
def getCurrentDisplayId(self):
"""Returns the display id that's being used."""
if self.rq_display:
return self.rq_display
else:
photo = self.getCurrentPhoto()
return photo.currentDisplayId
def getDisplayIds(self):
"""Returns a list of tuples consisting of the display id and
the relative URL to it's view page.
It returns all display ids found in the current photo, except
the thumbnail.
It sorts them by their size, smallest first.
"""
photo = self.getCurrentPhoto()
dispIds = list(photo.getDisplayIds())
dispIds.remove('thumbnail')
# XXX should consider the size with regards to aspect ratio
dispIds.sort(
lambda x,y:
photo.getDisplaySize(x)[0].__cmp__(photo.getDisplaySize(y)[0]))
result = map(lambda dispId: (dispId, self._createUrl('viewPhoto.html',
display=dispId)),
dispIds)
return result
def getPageURLs(self):
"""Returns a list of tuples consisting of the position of the
page and the URL to it
"""
startPage = self.rq_page-4
endPage = self.rq_page+4
if startPage < 1:
endPage += 1 - startPage
startPage = 1
if endPage > self.getNumberOfPhotos():
startPage -= (endPage - self.getNumberOfPhotos())
endPage = self.getNumberOfPhotos()
# Last check
if startPage < 1:
startPage = 1
names = self.context.getPhotoNames()
names = names[startPage-1:endPage-1]
positions = range(startPage, endPage+1)
urls = map(lambda pos: self._createUrl('viewPhoto.html', page=pos),
positions)
return zip(positions, urls)
def getNextURL(self):
"""Returns the URL to the next page"""
url = self._createUrl('viewPhoto.html', page=self.rq_page+1)
return url
def getPreviousURL(self):
"""Returns the URL to the previous page"""
url = self._createUrl('viewPhoto.html', page=self.rq_page-1)
return url
def isFirstPhoto(self):
"""Returns true iff the current photo is the first one"""
return self.rq_page == 1
def isLastPhoto(self):
"""Returns true iff the current photo is the last one"""
return self.rq_page == self.getNumberOfPhotos()
def getCurrentPhoto(self):
"""Returns the photo with position self.rq_page"""
photos = self.context.getPhotoNames()
return zapi.traverseName(self.context,
photos[self.rq_page-1],
request=self.request)
=== Added File zopeproducts/photoslide/browser/viewPhoto.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<div metal:fill-slot="body" tal:define="curPhoto view/getCurrentPhoto" >
<h1 tal:content="context/title" />
<center>
<table width="80%" tal:define="n_photos view/getNumberOfPhotos">
<tr>
<td width="20%" align="left">
<a href=""
tal:condition="not: view/isFirstPhoto"
tal:attributes="href view/getPreviousURL"
>
Previous
</a>
</td>
<td width="60%"
align="center"
>
<tal:block tal:repeat="page_url view/getPageURLs"
tal:define="cur_page view/rq_page"
>
<a href=""
tal:condition="python: cur_page != page_url[0]"
tal:content="python: page_url[0]"
tal:attributes="href python: page_url[1]"
/>
<tal:block tal:condition="python: cur_page == page_url[0]"
tal:content="python: page_url[0]"
/>
</tal:block>
</td>
<td width="20%" align="right">
<a href=""
tal:condition="not: view/isLastPhoto"
tal:attributes="href view/getNextURL"
>
Next
</a>
</td>
</tr>
<tr>
<td colspan="3" align="center">
<b tal:content="curPhoto/title" />
</td>
</tr>
</table>
<table width="80%">
<tr>
<td colspan="3" align="center">
<img src=""
tal:attributes="src python: view.getPhotoURL(curPhoto)" />
</td>
</tr>
<tr>
<td colspan="3" align="center">
<tal:block tal:repeat="dispId view/getDisplayIds"
tal:define="curDispId view/getCurrentDisplayId">
<a href="" tal:condition="python: curDispId != dispId[0]"
tal:content="python: '[%s] ' % dispId[0]"
tal:attributes="href python: dispId[1]"
/>
<span tal:condition="python: curDispId == dispId[0]"
tal:replace="python: '%s ' % dispId[0]"
/>
</tal:block>
</td>
</tr>
</table>
</center>
</div>
</body>
</html>
=== Added File zopeproducts/photoslide/browser/viewThumbnails.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<div metal:fill-slot="body">
<h1 tal:content="context/title" />
<table>
<tr tal:repeat="row view/getPhotosPage">
<td tal:repeat="url row">
<a href="" tal:attributes="href python: url[0]">
<img src=""
tal:attributes="src python: url[1]"/>
</a>
</td>
</tr>
</table>
</div>
</body>
</html>
More information about the Zope3-Checkins
mailing list