[Zope3-checkins] CVS: Zope3/src/zope/products/content/browser -
__init__.py:1.1.2.1 configure.zcml:1.1.2.1
document.gif:1.1.2.1 file.py:1.1.2.1 file_icon.gif:1.1.2.1
file_upload.hlp:1.1.2.1 folder.py:1.1.2.1
folder_icon.gif:1.1.2.1 fromFS.pt:1.1.2.1 fssync.py:1.1.2.1
i18n.py:1.1.2.1 i18n_edit.pt:1.1.2.1 i18nimage.py:1.1.2.1
i18nimageedit.pt:1.1.2.1 image.py:1.1.2.1
image_icon.gif:1.1.2.1 imageedit.pt:1.1.2.1 preview.pt:1.1.2.1
Philipp von Weitershausen
philikon at philikon.de
Sun Feb 8 09:03:49 EST 2004
Update of /cvs-repository/Zope3/src/zope/products/content/browser
In directory cvs.zope.org:/tmp/cvs-serv10229/products/content/browser
Added Files:
Tag: philikon-movecontent-branch
__init__.py configure.zcml document.gif file.py file_icon.gif
file_upload.hlp folder.py folder_icon.gif fromFS.pt fssync.py
i18n.py i18n_edit.pt i18nimage.py i18nimageedit.pt image.py
image_icon.gif imageedit.pt preview.pt
Log Message:
Move zope.app.content,
zope.app.interfaces.content,
and zope.app.browser.content
to zope.products.content and zope.products.codecontent, respectively.
=== Added File Zope3/src/zope/products/content/browser/__init__.py ===
#
# This file is necessary to make this directory a package.
=== Added File Zope3/src/zope/products/content/browser/configure.zcml ===
<zope:configure
xmlns="http://namespaces.zope.org/browser"
xmlns:zope="http://namespaces.zope.org/zope"
xmlns:help="http://namespaces.zope.org/help">
<view
name="_traverse"
for="zope.products.content.interfaces.file.IFileContent"
class="zope.app.publication.traversers.FileContentTraverser"
permission="zope.Public"
/>
<!-- File View Directives -->
<editform
name="edit.html"
schema="zope.products.content.interfaces.file.IFile"
label="Change a file"
usage="objectview"
permission="zope.ManageContent"
class=".file.FileTextEdit"
/>
<menuItem
menu="zmi_views" title="Edit"
for="zope.products.content.interfaces.file.IFile"
action="edit.html"
filter="python:context.contentType.startswith('text/')"
permission="zope.ManageContent" />
<editform
name="upload.html"
menu="zmi_views" title="Upload"
schema="zope.products.content.interfaces.file.IFile"
label="Upload a file"
permission="zope.ManageContent"
/>
<page
for="zope.products.content.interfaces.file.IFile"
name="preview.html"
menu="zmi_views" title="Preview"
template="preview.pt"
permission="zope.ManageContent" />
<page
for="zope.products.content.interfaces.file.IFile"
name="index.html"
permission="zope.View"
class=".file.FileView"
attribute="show" />
<addMenuItem
class="zope.products.content.file.File"
title="File"
permission="zope.ManageContent"
view="zope.products.content.file.File"
/>
<addform
schema="zope.products.content.interfaces.file.IFile"
label="Add a File"
content_factory="zope.products.content.file.File"
name="zope.products.content.file.File"
permission="zope.ManageContent"
/>
<icon
name="zmi_icon"
for="zope.products.content.interfaces.file.IFile"
file="file_icon.gif" />
<help:register
id="file_upload"
title="File Upload Screen"
parent="ui"
for="zope.products.content.interfaces.file.IFile"
view="upload.html"
doc_path="./file_upload.hlp" />
<!-- I18n File View Directives -->
<page
name="index.html"
for="zope.products.content.interfaces.i18nfile.II18nFile"
permission="zope.View"
class=".i18n.I18nFileView" />
<pages
for="zope.products.content.interfaces.i18nfile.II18nFile"
permission="zope.View"
class=".i18n.I18nFileEdit">
<page name="editForm.html" template="i18n_edit.pt" />
<page name="edit.html" attribute="action" />
</pages>
<menuItems menu="zmi_views"
for="zope.products.content.interfaces.i18nfile.II18nFile">
<!-- Keep original edit view, for now -->
<menuItem title="Edit" action="editForm.html" />
<!-- Supress the upload view from file -->
<menuItem title="Upload" action="editForm.html"
filter="python: 0" />
</menuItems>
<menuItem menu="add_content"
for="zope.app.interfaces.container.IAdding"
title="I18n File"
action="zope.products.content.I18nFile"
description="A file that supports multiple locales."
permission="zope.ManageContent"
/>
<!-- Image -->
<editform
schema="zope.products.content.image.IImage"
name="upload.html"
menu="zmi_views" title="Upload"
label="Upload an image"
permission="zope.ManageContent"
class=".image.ImageUpload"
template="imageedit.pt"
/>
<page
name="index.html"
for="zope.products.content.image.IImage"
permission="zope.View"
allowed_attributes="__call__ tag"
class=".image.ImageData"
/>
<page
for="zope.products.content.interfaces.image.IImage"
name="preview.html"
menu="zmi_views" title="Preview"
template="preview.pt"
permission="zope.ManageContent"
/>
<icon
name="zmi_icon"
for="zope.products.content.image.IImage"
file="image_icon.gif"
/>
<addMenuItem
class="zope.products.content.image.Image"
title="Image"
permission="zope.ManageContent"
view="zope.products.content.image.Image"
/>
<addform
schema="zope.products.content.interfaces.image.IImage"
label="Add a Image"
content_factory="zope.products.content.image.Image"
name="zope.products.content.image.Image"
permission="zope.ManageContent"
/>
<!-- I18n Image -->
<page
name="index.html"
for="zope.products.content.interfaces.i18nimage.II18nImage"
permission="zope.View"
allowed_attributes="__call__ tag"
class=".i18nimage.I18nImageData"
/>
<pages
for="zope.products.content.i18nimage.II18nImage"
permission="zope.ManageContent"
class=".i18nimage.I18nImageEdit">
<page name="upload.html" template="i18nimageedit.pt" />
<page name="uploadAction.html" attribute="action" />
</pages>
<menuItems
menu="zmi_views"
for="zope.products.content.i18nimage.II18nImage"
>
<!-- Keep the old "edit" form -->
<menuItem title="Edit" action="upload.html"/>
<!-- Suppress upload form (from IFile) -->
<menuItem title="Upload" action="upload.html"
filter="python: 0" />
</menuItems>
<menuItem
menu="add_content"
for="zope.app.interfaces.container.IAdding"
title="I18n Image"
action="I18nImage"
description="A multi-locale version of an Image."
permission="zope.ManageContent"
/>
<!-- Folder View Directives -->
<icon
name="zmi_icon"
for="zope.app.interfaces.folder.IFolder"
file="folder_icon.gif" />
<addMenuItem
class="zope.app.folder.Folder"
title="Folder"
permission="zope.ManageContent"
/>
<page
name="contents.html"
menu="zmi_views" title="Contents"
for="zope.app.interfaces.folder.IFolder"
permission="zope.ManageContent"
class="zope.app.browser.container.contents.Contents"
attribute="contents" />
<page
name="index.html"
for="zope.app.interfaces.folder.IFolder"
permission="zope.View"
class="zope.app.browser.container.contents.Contents"
attribute="index" />
<page
for="zope.app.interfaces.folder.IFolder"
name="preview.html"
menu="zmi_views" title="Preview"
template="preview.pt"
permission="zope.ManageContent" />
<!-- ApplicationController navigation -->
<menuItem
menu="zmi_actions"
for="zope.app.interfaces.traversing.IContainmentRoot"
title="Manage Process"
action="++etc++process/index.html" />
<!-- toFS.snarf and fromFS.snarf views, for new fssync tools -->
<!-- fssync checkout, update -->
<page
for="zope.interface.Interface"
name="toFS.snarf"
permission="zope.ManageServices"
class=".fssync.SnarfFile"
attribute="show" />
<!-- fssync commit -->
<page
for="zope.interface.Interface"
name="fromFS.snarf"
permission="zope.ManageServices"
class=".fssync.SnarfCommit"
attribute="run" />
<!-- fssync checkin -->
<page
for="zope.interface.Interface"
name="checkin.snarf"
permission="zope.ManageServices"
class=".fssync.SnarfCheckin"
attribute="run" />
</zope:configure>
=== Added File Zope3/src/zope/products/content/browser/document.gif ===
<Binary-ish file>
=== Added File Zope3/src/zope/products/content/browser/file.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 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.
#
##############################################################################
"""File views.
$Id: file.py,v 1.1.2.1 2004/02/08 14:03:44 philikon Exp $
"""
from zope.app.browser.form.widget import BytesAreaWidget
from zope.app.form.widget import CustomWidgetFactory
__metaclass__ = type
class FileView:
def show(self):
"""Call the File"""
request = self.request
if request is not None:
request.response.setHeader('Content-Type',
self.context.getContentType())
request.response.setHeader('Content-Length',
self.context.getSize())
return self.context.getData()
class FileTextEdit:
"""File editing mix-in that uses a file-upload widget."""
data_widget = CustomWidgetFactory(BytesAreaWidget)
=== Added File Zope3/src/zope/products/content/browser/file_icon.gif ===
<Binary-ish file>
=== Added File Zope3/src/zope/products/content/browser/file_upload.hlp ===
This screen allows to upload new file data.
=== Added File Zope3/src/zope/products/content/browser/folder.py ===
##############################################################################
#
# Copyright (c) 2002 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.
#
##############################################################################
"""Felder-spcific view classes
$Id: folder.py,v 1.1.2.1 2004/02/08 14:03:44 philikon Exp $
"""
from zope.interface import implements
from zope.app.browser.container.adding import Adding
from zope.app.interfaces.content.folder import IFolderAdding
class FolderAdding(Adding):
implements(IFolderAdding)
=== Added File Zope3/src/zope/products/content/browser/folder_icon.gif ===
<Binary-ish file>
=== Added File Zope3/src/zope/products/content/browser/fromFS.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<div metal:fill-slot="body">
<h1 i18n:translate="">Commit Action</h1>
<div tal:define="status view/update"
tal:condition="status"
i18n:translate="">
Commit results:
<pre tal:content="status" i18n:name="results">
Status from update method goes here.
</pre>
</div>
<p i18n:translate="">Upload a zipfile in the following form</p>
<form method="post" action="@@fromFS.html" enctype="multipart/form-data">
<input type="file" name="zipfile" size="40" />
<input type="submit" value="Upload"
i18n:attributes="value upload-button"/>
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/products/content/browser/fssync.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.
#
##############################################################################
"""Code for the toFS.snarf view and its inverse, fromFS.snarf.
$Id: fssync.py,v 1.1.2.1 2004/02/08 14:03:44 philikon Exp $
"""
import os
import cgi
import shutil
import tempfile
from transaction import get_transaction
from zope.app.publisher.browser import BrowserView
from zope.app.traversing import getName, getParent, getRoot
from zope.fssync.snarf import Snarfer, Unsnarfer
from zope.app.fssync import syncer
from zope.app.fssync.committer import Committer, Checker
from zope.fssync.metadata import Metadata
from zope.app.i18n import ZopeMessageIDFactory as _
def snarf_dir(response, dirname):
"""Helper to snarf a directory to the response."""
response.setStatus(200)
response.setHeader("Content-Type", "application/x-snarf")
snf = Snarfer(response)
snf.addtree(dirname)
return ""
class SnarfFile(BrowserView):
"""View returning a snarfed representation of an object tree.
This applies to any object (for="zope.interface.Interface").
"""
def show(self):
"""Return the snarfed response."""
dirname = tempfile.mktemp()
try:
os.mkdir(dirname)
syncer.toFS(self.context,
getName(self.context) or "root",
dirname)
return snarf_dir(self.request.response, dirname)
finally:
if os.path.isdir(dirname):
shutil.rmtree(dirname)
class NewMetadata(Metadata):
"""Subclass of Metadata that sets the 'added' flag in all entries."""
def getentry(self, file):
entry = Metadata.getentry(self, file)
if entry:
entry["flag"] = "added"
return entry
class SnarfSubmission(BrowserView):
"""Base class for the commit and checkin views."""
def run(self):
self.check_content_type()
self.set_transaction()
self.parse_args()
self.set_note()
try:
self.make_tempdir()
self.set_arguments()
self.make_metadata()
self.unsnarf_body()
return self.run_submission()
finally:
self.remove_tempdir()
def check_content_type(self):
if not self.request.getHeader("Content-Type") == "application/x-snarf":
raise ValueError(_("Content-Type is not application/x-snarf"))
def set_transaction(self):
self.txn = get_transaction()
def parse_args(self):
# The query string in the URL didn't get parsed, because we're
# getting a POST request with an unrecognized content-type
qs = self.request._environ.get("QUERY_STRING")
if qs:
self.args = cgi.parse_qs(qs)
else:
self.args = {}
def get_arg(self, key):
value = self.request.get(key)
if value is None:
values = self.args.get(key)
if values is not None:
value = " ".join(values)
return value
def set_note(self):
note = self.get_arg("note")
if note:
self.txn.note(note)
tempdir = None
def make_tempdir(self):
self.tempdir = tempfile.mktemp()
os.mkdir(self.tempdir)
def remove_tempdir(self):
if self.tempdir and os.path.exists(self.tempdir):
shutil.rmtree(self.tempdir)
def unsnarf_body(self):
fp = self.request.bodyFile
fp.seek(0)
uns = Unsnarfer(fp)
uns.unsnarf(self.tempdir)
def call_committer(self):
c = Committer(syncer.getSerializer, self.metadata,
getAnnotations=syncer.getAnnotations)
c.synch(self.container, self.name, self.fspath)
class SnarfCheckin(SnarfSubmission):
"""View for checking a new sub-tree into Zope.
The input should be a POST request whose data is a snarf archive.
This creates a brand new tree and doesn't return anything.
"""
def run_submission(self):
# XXX need to make sure the top-level name doesn't already
# exist, or existing site data can get screwed
self.call_committer()
return ""
def set_arguments(self):
# Compute self.{name, container, fspath} for checkin()
name = self.get_arg("name")
if not name:
raise ValueError(_("required argument 'name' missing"))
src = self.get_arg("src")
if not src:
src = name
self.container = self.context
self.name = name
self.fspath = os.path.join(self.tempdir, src)
def make_metadata(self):
self.metadata = NewMetadata()
class SnarfCommit(SnarfSubmission):
"""View for committing changes to an existing tree.
The input should be a POST request whose data is a snarf archive.
It returns an updated snarf archive, or a text document with
errors.
"""
def run_submission(self):
self.call_checker()
if self.errors:
return self.send_errors()
else:
self.call_committer()
self.write_to_filesystem()
return self.send_archive()
def set_arguments(self):
# Compute self.{name, container, fspath} for commit()
self.name = getName(self.context)
self.container = getParent(self.context)
if self.container is None and self.name == "":
# Hack to get loading the root to work
self.container = getRoot(self.context)
self.fspath = os.path.join(self.tempdir, "root")
else:
self.fspath = os.path.join(self.tempdir, self.name)
def make_metadata(self):
self.metadata = Metadata()
def get_checker(self, raise_on_conflicts=False):
return Checker(syncer.getSerializer,
self.metadata,
raise_on_conflicts,
getAnnotations=syncer.getAnnotations)
def call_checker(self):
if self.get_arg("raise"):
c = self.get_checker(True)
else:
c = self.get_checker()
c.check(self.container, self.name, self.fspath)
self.errors = c.errors()
def send_errors(self):
self.txn.abort()
lines = [_("Up-to-date check failed:")]
tempdir_sep = os.path.join(self.tempdir, "") # E.g. foo -> foo/
for e in self.errors:
lines.append(e.replace(tempdir_sep, ""))
lines.append("")
self.request.response.setHeader("Content-Type", "text/plain")
return "\n".join(lines)
def write_to_filesystem(self):
shutil.rmtree(self.tempdir) # Start with clean slate
os.mkdir(self.tempdir)
syncer.toFS(self.context,
getName(self.context) or "root",
self.tempdir)
def send_archive(self):
return snarf_dir(self.request.response, self.tempdir)
=== Added File Zope3/src/zope/products/content/browser/i18n.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 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.
#
##############################################################################
"""I18n versions of several content objects.
$Id: i18n.py,v 1.1.2.1 2004/02/08 14:03:44 philikon Exp $
"""
from zope.i18n.negotiator import negotiator
class I18nFileView:
def __call__(self):
"""Call the File"""
request = self.request
language = None
if request is not None:
langs = self.context.getAvailableLanguages()
language = negotiator.getLanguage(langs, request)
request.response.setHeader('Content-Type',
self.context.getContentType())
request.response.setHeader('Content-Length',
self.context.getSize(language))
return self.context.getData(language)
class I18nFileEdit:
name = 'editForm'
title = 'Edit Form'
description = ('This edit form allows you to make changes to the ' +
'properties of this file.')
def action(self, contentType, data, language, defaultLanguage,
selectLanguage=None, removeLanguage=None,
addLanguage=None, newLanguage=None):
if selectLanguage:
pass
elif removeLanguage:
self.context.removeLanguage(language)
language = self.context.getDefaultLanguage()
else:
if addLanguage:
language = newLanguage
self.context.setDefaultLanguage(defaultLanguage)
self.context.edit(data, contentType, language)
return self.request.response.redirect(self.request.URL[-1] +
"/editForm.html?language=%s" %language) # XXX url_quote
=== Added File Zope3/src/zope/products/content/browser/i18n_edit.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="headers" type="text/css">
<!--
.ContentIcon {
width: 20px;
}
.ContentTitle {
text-align: left;
}
-->
</style>
</head>
<body>
<div metal:fill-slot="body">
<p tal:content="context/msg"
tal:condition="python: hasattr(context, 'msg')">
Message will go here.
</p>
<p tal:content="view/description">
Description of the Form.
</p>
<form action="edit.html" method="post">
<div class="row">
<div class="label" i18n:translate="">Content Type</div>
<div class="field">
<input name="contentType" type="text" size="20"
tal:attributes="value context/getContentType" />
</div>
</div>
<div class="row">
<div class="label" i18n:translate="">Default Language</div>
<div class="field">
<select name="defaultLanguage">
<span tal:repeat="lang context/getAvailableLanguages"
tal:omit-tag="">
<option tal:attributes="
value lang;
selected python:context.getDefaultLanguage() == lang"
tal:content="lang" />
</span>
</select>
</div>
</div>
<hr />
<div class="row">
<div class="label" i18n:translate="">Language</div>
<div class="field">
<select name="language">
<span tal:repeat="lang context/getAvailableLanguages"
tal:omit-tag="">
<option tal:attributes="
value lang;
selected python:request.get('language',
context.getDefaultLanguage()) == lang"
tal:content="lang" />
</span>
</select>
<input type="submit" name="selectLanguage" value="Show"
i18n:attributes="value show-button"/>
<input type="submit" name="removeLanguage"
i18n:attributes="value remove-button"/>
<input type="submit" name="addLanguage"
value="Add new language"
i18n:attributes="value" />
<input type="text" name="newLanguage" size="10" />
</div>
</div>
<div class="row">
<div class="label" i18n:translate="">Data</div>
<div class="field">
<textarea name="data" cols="70" rows="10"
tal:content="python:context.getData(request.get('language'))" />
</div>
</div>
<div class="row">
<div class="controls">
<input type="submit" name="edit" value="Save Changes"
i18n:attributes="value save-changes-button"/>
</div>
</div>
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/products/content/browser/i18nimage.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 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.
#
##############################################################################
"""Define view component for image editing.
$Id: i18nimage.py,v 1.1.2.1 2004/02/08 14:03:44 philikon Exp $
"""
from zope.i18n.negotiator import negotiator
from zope.app.i18n import ZopeMessageIDFactory as _
from image import ImageData
class I18nImageEdit:
name = 'editForm'
title = _('Edit Form')
description = _('This edit form allows you to make changes to the ' +
'properties of this image.')
def getImageSize(self, language=None):
# XXX Change to ISizeable adapter
size = self.context.getImageSize(language)
return "%d x %d" % (size[0], size[1])
def action(self, contentType, data, language, defaultLanguage,
selectLanguage=None, removeLanguage=None,
addLanguage=None, newLanguage=None):
if selectLanguage:
pass
elif removeLanguage:
self.context.removeLanguage(language)
language = self.context.getDefaultLanguage()
else:
if addLanguage:
language = newLanguage
self.context.setDefaultLanguage(defaultLanguage)
self.context.edit(data, contentType, language)
return self.request.response.redirect(self.request.URL[-1] +
"/editForm.html?language=%s" % language) # XXX url_quote
class I18nImageData(ImageData):
def __call__(self):
image = self.context
language = None
if self.request is not None:
langs = self.context.getAvailableLanguages()
language = negotiator.getLanguage(langs, self.request)
self.request.response.setHeader('content-type',
image.getContentType())
# XXX: no content-length? See ImageData.__call__
return image.getData(language)
def tag(self, height=None, width=None, **args):
"""See ImageData.tag."""
language = None
if self.request is not None and \
(width is None or height is None):
langs = self.context.getAvailableLanguages()
language = negotiator.getLanguage(langs, self.request)
if width is None:
width = self.context.getImageSize(language)[0]
if height is None:
height = self.context.getImageSize(language)[1]
return ImageData.tag(self, width=width, height=height, **args)
=== Added File Zope3/src/zope/products/content/browser/i18nimageedit.pt ===
<html metal:use-macro="views/standard_macros/page">
<head>
<style metal:fill-slot="headers" type="text/css">
<!--
.ContentIcon {
width: 20px;
}
.ContentTitle {
text-align: left;
}
-->
</style>
</head>
<body>
<div metal:fill-slot="body">
<p tal:content="options/msg | nothing">
Message will go here.
</p>
<p tal:content="view/description">
Description of the Form.
</p>
<form action="uploadAction.html" method="post"
enctype="multipart/form-data">
<div class="row">
<div class="label" i18n:translate="">Content Type</div>
<div class="field">
<input name="contentType" type="text" size="20"
tal:attributes="value context/getContentType" />
</div>
</div>
<div class="row">
<div class="label" i18n:translate="">Default Language</div>
<div class="field">
<select name="defaultLanguage">
<span tal:repeat="lang context/getAvailableLanguages"
tal:omit-tag="">
<option tal:attributes="
value lang;
selected python:context.getDefaultLanguage() == lang"
tal:content="lang" />
</span>
</select>
</div>
</div>
<hr />
<div class="row">
<div class="label" i18n:translate="">Language</div>
<div class="field">
<select name="language">
<span tal:repeat="lang context/getAvailableLanguages"
tal:omit-tag="">
<option tal:attributes="
value lang;
selected python:request.get('language',
context.getDefaultLanguage()) == lang"
tal:content="lang" />
</span>
</select>
<input type="submit" name="selectLanguage" value="Show"
i18n:attributes="value show-button"/>
<input type="submit" name="removeLanguage"
i18n:attributes="value remove-button"/>
<input type="submit" name="addLanguage"
value="Add new language"
i18n:attributes="value" />
<input type="text" name="newLanguage" size="10" />
</div>
</div>
<div class="row">
<div class="label" i18n:translate="">Data</div>
<div class="field">
<input type="file" name="data" size="20" />
</div>
</div>
<div class="row">
<div class="label" i18n:translate="">Dimensions</div>
<div class="field"
tal:content="python:view.getImageSize(request.get('language'))">
40 x 40
</div>
</div>
<div class="row">
<div class="label" i18n:translate="">Dimensions</div>
<div class="field"
tal:content="python:view.getSize(request.get('language'))">
40 kB
</div>
</div>
<div class="row">
<div class="controls">
<input type="submit" name="edit" value="Save Changes"
i18n:attributes="value save-changes-button"/>
</div>
</div>
</form>
</div>
</body>
</html>
=== Added File Zope3/src/zope/products/content/browser/image.py ===
##############################################################################
#
# Copyright (c) 2001, 2002 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.
#
##############################################################################
"""Define view component for naive file editing.
$Id: image.py,v 1.1.2.1 2004/02/08 14:03:44 philikon Exp $
"""
from zope.app.size import byteDisplay
from zope.app.event.objectevent import ObjectModifiedEvent
from zope.app.event import publish
from zope.app.publisher.browser import BrowserView
class ImageData(BrowserView):
def __call__(self):
image = self.context
if self.request is not None:
self.request.response.setHeader('content-type',
image.getContentType())
return image.getData()
def tag(self, height=None, width=None, alt=None,
scale=0, xscale=0, yscale=0, css_class=None, **args):
"""
Generate an HTML IMG tag for this image, with customization.
Arguments to self.tag() can be any valid attributes of an IMG tag.
'src' will always be an absolute pathname, to prevent redundant
downloading of images. Defaults are applied intelligently for
'height', 'width', and 'alt'. If specified, the 'scale', 'xscale',
and 'yscale' keyword arguments will be used to automatically adjust
the output height and width values of the image tag.
Since 'class' is a Python reserved word, it cannot be passed in
directly in keyword arguments which is a problem if you are
trying to use 'tag()' to include a CSS class. The tag() method
will accept a 'css_class' argument that will be converted to
'class' in the output tag to work around this.
"""
if width is None:
width = self.context.getImageSize()[0]
if height is None:
height = self.context.getImageSize()[1]
# Auto-scaling support
xdelta = xscale or scale
ydelta = yscale or scale
if xdelta and width:
width = str(int(round(int(width) * xdelta)))
if ydelta and height:
height = str(int(round(int(height) * ydelta)))
result = '<img src="%s"' % (self.absolute_url())
if alt is None:
alt = getattr(self, 'title', '')
result = '%s alt="%s"' % (result, alt)
if height is not None:
result = '%s height="%s"' % (result, height)
if width is not None:
result = '%s width="%s"' % (result, width)
if not 'border' in [a.lower() for a in args.keys()]:
result = '%s border="0"' % result
if css_class is not None:
result = '%s class="%s"' % (result, css_class)
for key in args.keys():
value = args.get(key)
result = '%s %s="%s"' % (result, key, value)
return '%s />' % result
class ImageUpload:
"""Image edit view mix-in that provides access to image size info"""
def size(self):
sx, sy = self.context.getImageSize()
if sx < 0:
sx = '?'
if sy < 0:
sy = '?'
return "%s x %s pixels, %s" % (
sx, sy, byteDisplay(self.context.getSize())
)
def apply_update(self, data):
"""Apply user inputs
These inputs have already been validated.
Return a boolean indicating whether we changed anything,
"""
unchanged = True
# if we can compute the content type from the raw data, then
# that overrides what the user provided, so set the content
# type first.
contentType = data.get('contentType')
if contentType and contentType != self.context.contentType:
self.context.contentType = contentType
unchanged = False
if 'data' in data:
self.context.data = data['data']
unchanged = False
if not unchanged:
publish(self.context, ObjectModifiedEvent(self.context))
return unchanged
=== Added File Zope3/src/zope/products/content/browser/image_icon.gif ===
<Binary-ish file>
=== Added File Zope3/src/zope/products/content/browser/imageedit.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<div metal:fill-slot="body">
<div metal:use-macro="view/generated_form/macros/body">
<form action=".">
<table metal:fill-slot="extra_top">
<tr>
<td i18n:translate="">Size</td>
<td tal:content="view/size" i18n:translate=""
>103 x 45 pixels, 43KB</td>
</tr>
</table>
<input type="submit" name="save" value="Save Changes"
i18n:attributes="value save-changes-button"/>
</form>
</div>
</div>
</body>
</html>
=== Added File Zope3/src/zope/products/content/browser/preview.pt ===
<html metal:use-macro="views/standard_macros/page">
<body>
<div metal:fill-slot="body">
<iframe src="." height="98%" width="98%"></iframe>
</div>
</body>
</html>
More information about the Zope3-Checkins
mailing list