pax_global_header 0000666 0000000 0000000 00000000064 13037641750 0014520 g ustar 00root root 0000000 0000000 52 comment=ecfd7b1ba9be51c39311e008d6487512cfdbabd7
Zope-2.13/ 0000775 0000000 0000000 00000000000 13037641750 0012362 5 ustar 00root root 0000000 0000000 Zope-2.13/.gitignore 0000664 0000000 0000000 00000000243 13037641750 0014351 0 ustar 00root root 0000000 0000000
*.dll
*.pyc
*.pyo
*.so
*.egg-info
.installed.cfg
.mr.developer.cfg
bin/
build/
develop/
develop-eggs/
dist/
eggs/
etc/
include/
lib/
log/
parts/
var/
doc/_build/
Zope-2.13/.travis.yml 0000664 0000000 0000000 00000000364 13037641750 0014476 0 ustar 00root root 0000000 0000000 language: python
sudo: false
python:
- "2.6"
- "2.7"
notifications:
email:
- tseaver@palladion.com
install:
- python bootstrap.py
- bin/buildout
script:
- bin/alltests
cache:
pip: true
directories:
- eggs/
Zope-2.13/COPYRIGHT.txt 0000664 0000000 0000000 00000000040 13037641750 0014465 0 ustar 00root root 0000000 0000000 Zope Foundation and Contributors Zope-2.13/LICENSE.txt 0000664 0000000 0000000 00000004026 13037641750 0014207 0 ustar 00root root 0000000 0000000 Zope Public License (ZPL) Version 2.1
A copyright notice accompanies this license document that identifies the
copyright holders.
This license has been certified as open source. It has also been designated as
GPL compatible by the Free Software Foundation (FSF).
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions in source code must retain the accompanying copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the accompanying copyright
notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Names of the copyright holders must not be used to endorse or promote
products derived from this software without prior written permission from the
copyright holders.
4. The right to distribute this software or to use it for any purpose does not
give you the right to use Servicemarks (sm) or Trademarks (tm) of the
copyright
holders. Use of them is covered by separate agreement with the copyright
holders.
5. If any files are modified, you must cause the modified files to carry
prominent notices stating that you changed the files and the date of any
change.
Disclaimer
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Zope-2.13/MANIFEST.in 0000664 0000000 0000000 00000000241 13037641750 0014115 0 ustar 00root root 0000000 0000000 include *.txt
include *.rst
recursive-include doc *
recursive-include src *
global-exclude *.dll
global-exclude *.pyc
global-exclude *.pyo
global-exclude *.so
Zope-2.13/README.txt 0000664 0000000 0000000 00000002315 13037641750 0014061 0 ustar 00root root 0000000 0000000 .. contents::
Introduction
============
Zope2 is an open-source web application server.
This document provides some general information about Zope2 and provides
links to other documents.
Installation information can be found in ``doc/INSTALL.rst``. Other
documentation is also in the "doc" directory and in the zope.org
documentation section at http://docs.zope.org/ .
General Zope information is available at http://www.zope.org/
Installation
============
Follow the instructions in ``doc/INSTALL.rst`` to install Zope.
License
=======
The Zope License is included in ``ZopePublicLicense.txt``. Send your
feedback about the license to zope-dev@zope.org.
Bug tracker
===========
Bugs reports should be made through the Zope bugtracker at
https://bugs.launchpad.net/zope2. A bug report should contain detailed
information about how to reproduce the bug, error messages (see
``/error_log`` within the ZMI or ``var/event.log``).
Mailing list
============
You can contact and discuss Zope2 on the Zope mailing list (zope@zope.org).
To subscribe to the list send mail to zope-request@zope.org with ``subscribe``
in the subject line.
You can also subscribe online from here:
http://mail.zope.org/mailman/listinfo/zope
Zope-2.13/bootstrap.py 0000664 0000000 0000000 00000014545 13037641750 0014762 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2006 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""Bootstrap a buildout-based project
Simply run this script in a directory containing a buildout.cfg.
The script accepts buildout command-line options, so you can
use the -c option to specify an alternate configuration file.
"""
import os
import shutil
import sys
import tempfile
from optparse import OptionParser
tmpeggs = tempfile.mkdtemp()
usage = '''\
[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
Bootstraps a buildout-based project.
Simply run this script in a directory containing a buildout.cfg, using the
Python that you want bin/buildout to use.
Note that by using --find-links to point to local resources, you can keep
this script from going over the network.
'''
parser = OptionParser(usage=usage)
parser.add_option("-v", "--version", help="use a specific zc.buildout version")
parser.add_option("-t", "--accept-buildout-test-releases",
dest='accept_buildout_test_releases',
action="store_true", default=False,
help=("Normally, if you do not specify a --version, the "
"bootstrap script and buildout gets the newest "
"*final* versions of zc.buildout and its recipes and "
"extensions for you. If you use this flag, "
"bootstrap and buildout will get the newest releases "
"even if they are alphas or betas."))
parser.add_option("-c", "--config-file",
help=("Specify the path to the buildout configuration "
"file to be used."))
parser.add_option("-f", "--find-links",
help=("Specify a URL to search for buildout releases"))
parser.add_option("--allow-site-packages",
action="store_true", default=False,
help=("Let bootstrap.py use existing site packages"))
parser.add_option("--setuptools-version",
help="use a specific setuptools version")
options, args = parser.parse_args()
######################################################################
# load/install setuptools
try:
if options.allow_site_packages:
import setuptools
import pkg_resources
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
ez = {}
exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez)
if not options.allow_site_packages:
# ez_setup imports site, which adds site packages
# this will remove them from the path to ensure that incompatible versions
# of setuptools are not in the path
import site
# inside a virtualenv, there is no 'getsitepackages'.
# We can't remove these reliably
if hasattr(site, 'getsitepackages'):
for sitepackage_path in site.getsitepackages():
sys.path[:] = [x for x in sys.path if sitepackage_path not in x]
setup_args = dict(to_dir=tmpeggs, download_delay=0)
if options.setuptools_version is not None:
setup_args['version'] = options.setuptools_version
ez['use_setuptools'](**setup_args)
import setuptools
import pkg_resources
# This does not (always?) update the default working set. We will
# do it.
for path in sys.path:
if path not in pkg_resources.working_set.entries:
pkg_resources.working_set.add_entry(path)
######################################################################
# Install buildout
ws = pkg_resources.working_set
cmd = [sys.executable, '-c',
'from setuptools.command.easy_install import main; main()',
'-mZqNxd', tmpeggs]
find_links = os.environ.get(
'bootstrap-testing-find-links',
options.find_links or
('http://downloads.buildout.org/'
if options.accept_buildout_test_releases else None)
)
if find_links:
cmd.extend(['-f', find_links])
setuptools_path = ws.find(
pkg_resources.Requirement.parse('setuptools')).location
requirement = 'zc.buildout'
version = options.version
if version is None and not options.accept_buildout_test_releases:
# Figure out the most recent final version of zc.buildout.
import setuptools.package_index
_final_parts = '*final-', '*final'
def _final_version(parsed_version):
try:
return not parsed_version.is_prerelease
except AttributeError:
# Older setuptools
for part in parsed_version:
if (part[:1] == '*') and (part not in _final_parts):
return False
return True
index = setuptools.package_index.PackageIndex(
search_path=[setuptools_path])
if find_links:
index.add_find_links((find_links,))
req = pkg_resources.Requirement.parse(requirement)
if index.obtain(req) is not None:
best = []
bestv = None
for dist in index[req.project_name]:
distv = dist.parsed_version
if _final_version(distv):
if bestv is None or distv > bestv:
best = [dist]
bestv = distv
elif distv == bestv:
best.append(dist)
if best:
best.sort()
version = best[-1].version
if version:
requirement = '=='.join((requirement, version))
cmd.append(requirement)
import subprocess
if subprocess.call(cmd, env=dict(os.environ, PYTHONPATH=setuptools_path)) != 0:
raise Exception(
"Failed to execute command:\n%s" % repr(cmd)[1:-1])
######################################################################
# Import and run buildout
ws.add_entry(tmpeggs)
ws.require(requirement)
import zc.buildout.buildout
if not [a for a in args if '=' not in a]:
args.append('bootstrap')
# if -c was provided, we push it back into args for buildout' main function
if options.config_file is not None:
args[0:0] = ['-c', options.config_file]
zc.buildout.buildout.main(args)
shutil.rmtree(tmpeggs)
Zope-2.13/buildout.cfg 0000664 0000000 0000000 00000003021 13037641750 0014666 0 ustar 00root root 0000000 0000000 [buildout]
extensions = mr.developer
allow-hosts =
*.python.org
*.zope.org
argparse.googlecode.com
show-picked-versions = true
always-accept-server-certificate = true
develop = .
extends =
sources.cfg
version_ranges.cfg
parts =
test
scripts
zopepy
alltests
allpy
docs
checkversions
wsgi
sources-dir = develop
auto-checkout =
versions = versions
[test]
recipe = zc.recipe.testrunner
initialization =
import sys
import warnings
if sys.version_info >= (2, 7): warnings.simplefilter('default')
eggs = Zope2
[scripts]
recipe = zc.recipe.egg
eggs = Zope2
[zopepy]
recipe = zc.recipe.egg
eggs = Zope2
interpreter = zopepy
scripts = zopepy
[alltests]
recipe = zc.recipe.testrunner
eggs =
Zope2
AccessControl
Acquisition
DateTime
DocumentTemplate
ExtensionClass
Missing
MultiMapping
Persistence
Products.BTreeFolder2
Products.ExternalMethod
Products.MailHost
Products.OFSP
Products.PythonScripts
Products.StandardCacheManagers
Products.ZCatalog
Products.ZCTextIndex
Record
RestrictedPython
initgroups
tempstorage
zExceptions
zLOG
ZopeUndo
[allpy]
recipe = zc.recipe.egg
eggs = ${alltests:eggs}
interpreter = allpy
scripts = allpy
[docs]
recipe = zc.recipe.egg
eggs = Sphinx
[checkversions]
recipe = zc.recipe.egg
eggs = z3c.checkversions [buildout]
[wsgi]
recipe = zc.recipe.egg
eggs =
Zope2
repoze.who
repoze.tm2
repoze.retry
Paste
PasteDeploy
PasteScript
Zope-2.13/doc/ 0000775 0000000 0000000 00000000000 13037641750 0013127 5 ustar 00root root 0000000 0000000 Zope-2.13/doc/CHANGES.rst 0000664 0000000 0000000 00000073725 13037641750 0014747 0 ustar 00root root 0000000 0000000 Changelog
=========
This file contains change information for the current Zope release.
Change information for previous versions of Zope can be found at
http://docs.zope.org/zope2/
2.13.26 (unreleased)
--------------------
- Fixed reflective XSS in findResult.
This applies PloneHotfix20170117. [maurits]
2.13.25 (2017-01-13)
--------------------
- Add a dependency on the empty `ZServer` project.
- Patch zope.interface to remove docstrings and avoid publishing.
From Products.PloneHotfix20161129. [maurits]
- Don't copy items the user is not allowed to view.
From Products.PloneHotfix20161129. [maurits]
- Quote variables in manage_tabs and manage_container to avoid XSS.
From Products.PloneHotfix20160830. [maurits]
- Add a dependency on the empty `Products.TemporaryFolder` project.
- Add a dependency on the empty `Products.Sessions` project.
- Removed docstrings from some methods to avoid publishing them. From
Products.PloneHotfix20160419. [maurits]
- Add support to SameSite cookie in ``ZPublisher.HTTPResponse``:
https://tools.ietf.org/html/draft-west-first-party-cookies-07
2.13.24 (2016-02-29)
--------------------
- Issue #44: Ensure that iterators declared as implementing
``IUnboundStreamIterator`` are handled properly.
- Issue #43: Fix Zope failing to start if a zoperunner is configured.
- PR #51: Harden debug control panel's module-crawling against trickery
performed by ``six``.
- Issue #34: Fix ``NameError`` exception for ``WindowsError`` which could
happen on non-windows systems.
- Updated distributions:
- AccessControl = 2.13.14
2.13.23 (2015-06-29)
--------------------
- Provide a pip-compatible ``requirements.txt`` file for the release. E.g.::
$ /path/to/venv/bin/pip install -r \
https://raw.githubusercontent.com/zopefoundation/Zope/2.13.23/requirements.txt
- LP #789863: Ensure that Request objects cannot be published / traversed
directly via a URL.
- Issue #27: Fix publishing of ``ZPublisher.Iterators.IStreamIterator`` under
WSGI. This interface does not have ``seek`` or ``tell``. Introduce
``ZPublisher.Iterators.IUnboundStreamIterator`` to support publishing
iterators of unknown length under WSGI.
- Document running Zope as a WSGI application. See
https://github.com/zopefoundation/Zope/issues/30
- LP #1465432: Ensure that WSGIPublisher starts / ends interaction at
request boundaries (analogous to ZPublisher). Backport from master.
- Fix: Queue additional warning filters at the beginning of the queue in order
to allow overrides.
- Issue #16: prevent leaked connections when broken ``EndRequestEvent``
subscribers raise exceptions.
- LP #1387225: Zope 2.13.x w/ zope.browserpage 4.x doesn't start.
- LP #1387138: Zope 2.13.x w/ zope.pagetemplate 4.x doesn't start.
- LP #1386795: Fix ``zopectl start`` with zdaemon 3 and newer.
- Updated distributions:
- Acquisition = 2.13.9
- DateTime = 2.12.8
- Products.BTreeFolder2 = 2.13.5
- Products.ExternalMethod = 2.13.1
- Products.Mailhost = 2.13.2
- Products.StandardCacheManagers = 2.13.1
- ZConfig = 2.9.3
- zLOG = 2.11.2
- zope.dublincore = 3.7.1
- zope.mkzeoinstance = 3.9.6
2.13.22 (2014-02-19)
--------------------
- Merge hotfixes from https://pypi.python.org/pypi/Products.PloneHotfix20131210
- LP #143352: Logging of client IP rather than the IP of the Proxy.
Please be aware that this only logs the real client ips to Z2.log,
if you set you proxy as a trusted-proxy in zope.conf.
- Updated distributions:
- Products.ZCatalog = 2.13.27
- Products.ZCTextIndex = 2.13.5
2.13.21 (2013-07-16)
--------------------
- LP #1095343: Prevent sandbox escape via ``BaseRequest.traverseName``.
- LP #1094144: Prevent arbitrary redirections via faked "CANCEL" buttons.
- LP #1094221: Add permissions to some unprotected methods of
``OFS.ObjectManager``.
- LP #1094049: Prevent zlib-based DoS when parsing the cookie containing
paste tokens.
- Updated distributions:
- AccessControl = 2.13.13
2.13.20 (2013-05-01)
--------------------
- LP #1114688: Defend against minidom-based DoS in webdav. (Patch from
Christian Heimes).
- LP #978980: Protect views of ZPT source with 'View Management Screens'
permision.
- Make sure the generated classes for simple browser pages (SimpleViewClasses)
have a str ``__name__``. See LP #1129030.
- In PageTemplate.pt_errors accept the check_macro_expansion argument.
This is added for compatibility with zope.pagetemplate 4.0.0. The
argument is ignored. See LP #732972.
- Updated to Zope Toolkit 1.0.8.
- Updated distributions:
- Products.ZCTextIndex = 2.13.4
- ZConfig = 2.9.1
2.13.19 (2012-10-31)
--------------------
- Updated distributions:
- AccessControl = 2.13.12
- distribute = 0.6.29
- mr.developer = 1.22
- pytz = 2012g
- repoze.retry = 1.2
- repoze.tm2 = 1.0
- tempstorage = 2.12.2
- LP #1071067: Use a stronger random number generator and a constant time
comparison function.
- LP #1061247: Fix ZMI properties edit form for properties named `method`.
- LP #1058049: Fix support for zoperunner section in zope.conf.
- Explicitly close all databases on shutdown, which ensures `Data.fs.index`
gets written to the file system.
- LP #930812: Scrub headers a bit more.
- Fix lock and pid file handling on Windows. On other platforms
starting Zope tolerated existing or locked files, this now also
works on Windows.
2.13.18 (2012-09-18)
--------------------
- Explicitly declared ZTUtils APIs as public (repairs breakages in apps
following fix for LP #1047318).
2.13.17 (2012-09-09)
--------------------
- Updated distributions:
- AccessControl = 2.13.10
- Products.PythonScripts = 2.13.2
2.13.16 (2012-08-11)
--------------------
- Updated distributions:
- AccessControl = 2.13.8
- DateTime = 2.12.7
- OFS: Fixed TypeError handling in unrestrictedTraverse.
- ZPublisher: Do not assume that you can iterate over a publishable object.
- ZPublisher: Do not guess it is a webdav request if the HTTP method is purge.
2.13.15 (2012-06-22)
--------------------
- Fix lock file cleanup if there's an error early in startup.
- Updated distributions:
- zdaemon = 2.0.7
2.13.14 (2012-05-31)
--------------------
- LP #950689: Fix HTTPS detection under mod_wsgi.
- LP #975039: Don't translate interface names in edit_markers ZMI view.
- LP #838978: Fixed TypeError in cache_detail ZMI view.
- Cleanup lock and pid files if the process dies early in startup.
- Added PubStart, PubBeforeCommit and PubAfterTraversal events to the
WSGI publisher.
- ZPublisher: Fixed a traversal regression introduced in 2.13.12.
- Updated to Zope Toolkit 1.0.7.
- Updated distributions:
- Products.ZCatalog = 2.13.23
2.13.13 (2012-02-20)
--------------------
- LP #933307: Fixed ++skin++ namespace handling.
Ported the ``shiftNameToApplication`` implementation from zope.publisher to
ZPublisher.HTTPRequest.HTTPRequest.
- Ensure that the ``WSGIPublisher`` begins and ends an *interaction*
at the request/response barrier. This is required for instance for
the ``checkPermission`` call to function without an explicit
``interaction`` parameter.
- Ensure that ObjectManager's ``get`` and ``__getitem__`` methods return only
"items" (no attributes / methods from the class or from acquisition).
Thanks to Richard Mitchell at Netsight for the report.
- Updated to Zope Toolkit 1.0.6.
- Removed HTML tags from exception text of ``Unauthorized`` exception
because these tags get escaped since CVE-2010-1104 (see 2.13.12) got
fixed.
2.13.12 (2012-01-18)
--------------------
- Prevent a cross-site-scripting attack against the default standard
error message handling. (CVE-2010-1104).
- Use ``in`` operator instead of deprecated ``has_key`` method (which
is not implemented by ``OFS.ObjectManager``). This fixes an issue
with WebDAV requests for skin objects.
- Updated distributions:
- Products.ZCatalog = 2.13.22
2.13.11 (2011-12-12)
--------------------
- LP #1079238: Turn `UndoSupport.get_request_var_or_attr` helper into a
private API.
- LP #902068: Fixed missing security declaration for `ObjectManager` class.
- Avoid conflicting signal registrations when run under mod_wsgi.
Allows the use of `WSGIRestrictSignal Off` (LP #681853).
- Make it possible to use WSGI without repoze.who.
- Fixed serious authentication vulnerability in stock configuration.
- Updated distributions:
- AccessControl = 2.13.7
- DocumentTemplate = 2.13.2
- Products.BTreeFolder2 = 2.13.4
- python-gettext = 1.2
- repoze.who = 2.0
- ZODB3 = 3.10.5
- Zope Toolkit 1.0.5
2.13.10 (2011-10-04)
--------------------
- Fixed serious arbitrary code execution issue (CVE 2011-3587)
http://zope2.zope.org/news/security-vulnerability-announcement-cve-2011-3587
- Fixed a regression of 2.13.9 in webdav support that broke external editor
feature.
- `undoMultiple` was still broken as transactions were not undone in the proper
order : tids were stored and retrieved as dictionary keys.
- Updated distributions:
- Products.ZCatalog = 2.13.20
2.13.9 (2011-08-20)
-------------------
Bugs Fixed
++++++++++
- Restore ability to undo multiple transactions from the ZMI by using the
`undoMultiple` API. Backported from trunk (r122087).
- Fixed Chameleon compatibility in templates.
- Updated distributions:
- Products.ZCatalog = 2.13.19
- Products.ZCTextIndex = 2.13.3
- repoze.tm2 = 1.0b2
- Zope Toolkit 1.0.4
2.13.8 (2011-06-28)
-------------------
Bugs Fixed
++++++++++
- Fixed a serious privilege escalation issue. For more information see:
http://plone.org/products/plone/security/advisories/20110622
- Ensure __name__ is not None as well as __name__ existing. For example, object
could be a widget within a z3c.form MultiWidget, which do not have __name__ set.
- Testing: Re-added 'extra' argument to Functional.publish.
Removing it in Zope 2.13.0a1 did break backwards compatibility.
- LP #787541: Fix WSGIPublisher to close requests on abort unconditionally.
Previously an addAfterCommitHook was used, but this is not run on transaction
aborts. Now a Synchronizer is used which unconditionally closes the request
after a transaction is finished.
Features Added
++++++++++++++
- Updated distributions:
- Acquisition = 2.13.8
- Products.ZCatalog = 2.13.14
- repoze.who = 2.0b1
- ZODB3 = 3.10.3
- Zope Toolkit 1.0.3
2.13.7 (2011-05-08)
-------------------
Features Added
++++++++++++++
- Added forward compatibility with DateTime 3.
- ZPublisher: HTTPResponse.appendHeader now keeps header values to a single
line by default to avoid causing problems for proxy servers which do not
correctly handle multi-line headers.
- Updated distributions:
- Products.ZCatalog = 2.13.13
- Products.ZCTextIndex = 2.13.2
2.13.6 (2011-04-03)
-------------------
Bugs Fixed
++++++++++
- Fix `WSGIResponse` and `publish_module` functions such that they
support the `IStreamIterator` interface in addition to `file` (as
supported by `ZServer.HTTPResponse`).
- Corrected copyright information shown in the ZMI.
- OFS: Fixed editing offset-naive 'date' properties in the ZMI.
The "Properties" tab no longer shows the time zone of offset-naive dates.
Features Added
++++++++++++++
- Add preliminary IPv6 support to ZServer.
- Updated to Zope Toolkit 1.0.2.
- Updated distributions:
- Acquisition = 2.13.7
- mechanize = 0.2.5
- Products.BTreeFolder2 = 2.13.3
- Products.ZCatalog = 2.13.8
- python-gettext = 1.1.1
- pytz = 2011e
- repoze.tm2 = 1.0b1
- repoze.who = 2.0a4
- ZConfig = 2.9.0
- zope.testbrowser = 3.11.1
2.13.5 (2011-02-23)
-------------------
Bugs Fixed
++++++++++
- Five: Corrected a method name in the IReadInterface interface.
Features Added
++++++++++++++
- Updated distributions:
- Acquisition = 2.13.6
- Products.ZCatalog = 2.13.6
- ZODB3 = 3.10.2
2.13.4 (2011-02-06)
-------------------
Bugs Fixed
++++++++++
- Applied missing bit of the code merge for LP #713253.
2.13.3 (2011-02-06)
-------------------
Features Added
++++++++++++++
- Updated distributions:
- Products.ZCatalog = 2.13.5
Bugs Fixed
++++++++++
- LP #713253: Prevent publication of acquired attributes, where the acquired
object does not have a docstring.
2.13.2 (2011-01-19)
-------------------
Bugs Fixed
++++++++++
- HelpSys: Fixed some permission checks.
- OFS: Fixed permission check in ObjectManager.
- webdav: Fixed permission check and error handling in DeleteCollection.
- LP 686664: WebDAV Lock Manager ZMI view wasn't accessible.
Features Added
++++++++++++++
- Report success or failure (when known) of creating a new user with the
`addzope2user` script.
- Added `addzope2user` script, suitable for adding an admin user directly to
the root acl_users folder.
- Updated distributions:
- AccessControl = 2.13.4
- Products.ZCatalog = 2.13.3
Restructuring
+++++++++++++
- Factored out the `Products.ZCatalog` and `Products.PluginIndexes` packages
into a new `Products.ZCatalog` distribution.
2.13.1 (2010-12-07)
-------------------
Bugs Fixed
++++++++++
- Fixed argument parsing for entrypoint based zopectl commands.
- Fixed the usage of ``pstats.Stats()`` output stream. The
`Control_Panel/DebugInfo/manage_profile` ZMI view was broken in Python 2.5+.
Features Added
++++++++++++++
- Report success or failure (when known) of creating a new user with
the addzope2user script.
- Moved subset id calculation in `OFS.OrderSupport.moveObjectsByDelta` to a
new helper method, patch by Tom Gross.
- Updated to Zope Toolkit 1.0.1.
- Use cProfile where possible for the `Control_Panel/DebugInfo/manage_profile`
ZMI view.
Restructuring
+++++++++++++
- Stopped testing non-overridden ZTK eggs in ``bin/alltests``.
2.13.0 (2010-11-05)
-------------------
- No changes.
2.13.0c1 (2010-10-28)
---------------------
Bugs Fixed
++++++++++
- LP #628448: Fix ``zopectl start`` on non-Windows platforms.
Features Added
++++++++++++++
- Updated to Zope Toolkit 1.0.
- Updated distributions:
- DateTime = 2.12.6
- mechanize = 0.2.3
- ZODB3 = 3.10.1
- zope.sendmail = 3.7.4
- zope.testbrowser = 3.10.3
2.13.0b1 (2010-10-09)
---------------------
Bugs Fixed
++++++++++
- Avoid iterating over the list of packages to initialize while it is being
mutated, which was skipping some packages.
- Fixed two unit tests that failed on fast Windows machines.
- Fixed OverflowError in Products.ZCatalog.Lazy on 64bit Python on Windows.
- Fixed ``testZODBCompat`` tests in ZopeTestCase to match modern ZODB
semantics.
- LP #634942: Only require ``nt_svcutils`` on Windows.
Features Added
++++++++++++++
- Avoid conflict error hotspot in PluginIndexes' Unindex class by using
IITreeSets instead of simple ints from the start. Idea taken from
``enfold.fixes``.
- Added date range index improvements from ``experimental.catalogqueryplan``.
- Changed policy on handling exceptions during ZCML parsing in ``Products``.
We no longer catch any exceptions in non-debug mode.
- Added a new BooleanIndex to the standard PluginIndexes.
- Update to Zope Toolkit 1.0c3.
- Add ability to define extra zopectl commands via setuptools entrypoints.
- Updated distributions:
- Acquisition = 2.13.5
- Products.MailHost = 2.13.1
- Products.ZCTextIndex = 2.13.1
- repoze.retry = 1.0
- tempstorage = 2.12.1
- ZODB3 = 3.10.0
- zope.testbrowser = 3.10.1
2.13.0a4 (2010-09-09)
---------------------
Restructuring
+++++++++++++
- Removed deprecated
``Products.Five.security.create_permission_from_permission_directive``
event handler. Its code was moved into the Zope 2 version of the permission
directive in ``AccessControl.security``.
Features Added
++++++++++++++
- LP #193122: New method getVirtualRoot added to the Request class.
- Updated test assertions to use unittest's ``assert*`` methods in favor of
their deprecated `fail*` aliases.
- Update to Zope Toolkit 1.0a3.
- Updated distributions:
- AccessControl = 2.13.3
- Acquisition = 2.13.4
- ZODB3 = 3.10.0b6
2.13.0a3 (2010-08-04)
---------------------
Bugs Fixed
++++++++++
- Adjusted overflow logic in DateIndex and DateRangeIndex to work with latest
ZODB 3.10.0b4.
- Made sure to exclude a number of meta ZCML handlers from ``zope.*`` packages
where Zope2 provides its own implementations.
- LP #599378: Fixed accumulated_headers not appending to headers correctly.
- Fix support for non-public permission attributes in the
browser:view directive so that attributes which are not included in
allowed_interface or allowed_attributes but which have declarations from a
base class's security info don't get their security overwritten to be
private.
- LP #143755: Also catch TypeError when trying to determine an
indexable value for an object in PluginIndexes.common.UnIndex
- LP #143533: Instead of showing "0.0.0.0" as the SERVER_NAME
request variable when no specific listening IP is configured for
the HTTP server, do a socket lookup to show the current server's
fully qualified name.
- LP #143722: Added missing permission to ObjectManager.manage_hasId,
which prevented renaming files and folders via FTP.
- LP #143564: Request.resolve_url did not correctly re-raise
exceptions encountered during path traversal.
Restructuring
+++++++++++++
- Removed catalog length migration code. You can no longer directly upgrade a
Zope 2.7 or earlier database to Zope 2.13. Please upgrade to an earlier
release first.
- Deprecated the ``Products.ZCatalog.CatalogAwareness`` and
``CatalogPathAwareness`` modules.
- Removed deprecated ``catalog-getObject-raises`` zope.conf option.
- Removed unmaintained HelpSys documents from ZCatalog and PluginIndexes.
Useful explanations are given inside the form templates.
- Deprecate Products.ZCatalog's current behavior of returning the entire
catalog content if no query restriction applied. In Zope 2.14 this will
result in an empty LazyCat to be returned instead.
- Deprecate acquiring the request inside Products.ZCatalog's searchResults
method if no explicit query argument is given.
- Cleaned up the Products.ZCatalog search API's. The deprecated support for
using `_usage` arguments in the request has been removed. Support
for overriding operators via the `_operator` syntax has been
limited to the query value for each index and no longer works directly on
the request. The query is now brought into a canonical form before being
passed into the `_apply_index` method of each index.
- Factored out the `Products.MailHost` package into its own distributions. It
will no longer be included by default in Zope 2.14 but live on as an
independent add-on.
Features Added
++++++++++++++
- Merged the query plan support from both ``unimr.catalogqueryplan`` and
``experimental.catalogqueryplan`` into ZCatalog. On sites with large number of
objects in a catalog (in the 100000+ range) this can significantly speed up
catalog queries. A query plan monitors catalog queries and keeps detailed
statistics about their execution. Currently the plan keeps track of execution
time, result set length and support for the ILimitedResultIndex per index for
each query. It uses this information to devise a better query execution plan
the next time the same query is run. Statistics and the resulting plan are
continuously updated. The plan is per running Zope process and not persisted.
You can inspect the plan using the ``Query Plan`` ZMI tab on each catalog
instance. The representation can be put into a Python module and the Zope
process be instructed to load this query plan on startup. The location of the
query plan is specified by providing the dotted name to the query plan
dictionary in an environment variable called ``ZCATALOGQUERYPLAN``.
- Various optimizations to indexes _apply_index and the catalog's search
method inspired by experimental.catalogqueryplan.
- Added a new ILimitedResultIndex to Products.PluginIndexes and made most
built-in indexes compatible with it. This allows indexes to consider the
already calculated result set inside their own calculations.
- Changed the internals of the DateRangeIndex to always use IITreeSet and do
an inline migration from IISet. Some datum tend to have large number of
documents, for example when using default floor or ceiling dates.
- Added a new reporting tab to `Products.ZCatalog` instances. You can use this
to get an overview of slow catalog queries, as specified by a configurable
threshold value.
- Warn when App.ImageFile.ImageFile receives a relative path with no prefix,
and then has to assume the path to be relative to "software home". This
behaviour is deprecated as packages can be factored out to their own
distribution, making the "software home" relative path meaningless.
- Updated distributions:
- AccessControl = 2.13.2
- DateTime = 2.12.5
- DocumentTemplate = 2.13.1
- Products.BTreeFolder2 = 2.13.1
- Products.OFSP = 2.13.2
- ZODB3 = 3.10.0b4
2.13.0a2 (2010-07-13)
---------------------
Bugs Fixed
++++++++++
- Made ZPublisher tests compatible with Python 2.7.
- LP #143531: Fix broken object so they give access to their state.
- LP #578326: Add support for non-public permission attributes in the
browser:view directive.
Restructuring
+++++++++++++
- No longer use HelpSys pages from ``Products.OFSP`` in core Zope 2.
- No longer create an `Extensions` folder in the standard instance skeleton.
External methods will become entirely optional in Zope 2.14.
- Avoid using the ``Products.PythonScripts.standard`` module inside the
database manager ZMI.
- Factored out the `Products.BTreeFolder2`, `Products.ExternalMethod`,
`Products.MIMETools`, `Products.OFSP`, `Products.PythonScripts` and
`Products.StandardCacheManagers` packages into their own distributions. They
will no longer be included by default in Zope 2.14 but live on as independent
add-ons.
- Factored out the `Products.ZSQLMethods` into its own distribution. The
distribution also includes the `Shared.DC.ZRDB` code. The Zope2 distribution
no longer includes the code automatically. Please depend on the new
distribution yourself, if you use the functionality. To make the transition
easier this change has been backported to Zope 2.12.9, so you can depend on
the new distribution already in packages requiring at least that version of
Zope 2.
- Made both `Shared` and `Shared.DC` namespace packages.
- Removed fallback code for old Python versions from
`ZServer.FTPServer.zope_ftp_channel.push`.
- Removed fallback code for old `ZCatalog.catalog_object` function signatures
from `Products.ZCatalog.ZCatalog.reindexIndex`.
Features Added
++++++++++++++
- Added official support for Python 2.7.
- Added a new API ``get_packages_to_initialize`` to ``OFS.metaconfigure``.
This replaces any direct access to ``Products._packages_to_initialize``.
The OFS.Application.install_package function takes care of removing entries
from this list now.
- Added notification of ``IDatabaseOpenedWithRoot``.
- Added a new API's ``get_registered_packages, set_registered_packages`` to
``OFS.metaconfigure`` which replace any direct access to
``Products._registered_packages``.
- Changed product install so it won't write persistent changes only to abort
them. Instead we don't make any database changes in the first place.
- Disabled persistent product installation in the default test configuration.
- Directly extend and use the Zope Toolkit KGS release 1.0a2 from
http://download.zope.org/zopetoolkit/index/.
- Updated distributions:
- DateTime = 2.12.4
- nt_svcutils = 2.13.0
2.13.0a1 (2010-06-25)
---------------------
This release includes all bug fixes and features of the
`Zope 2.12.8 `_ release.
Distribution changes
++++++++++++++++++++
- Moved AccessControl, DocumentTemplate (incl. TreeDisplay) and
Products.ZCTextIndex to their own distributions. This removes the last direct
C extensions from the Zope2 distribution.
- Moved the ``zExceptions`` package into its own distribution.
- Drop the dependency on the ThreadLock distribution, by using Python's thread
module instead.
- Integrated the Products.signalstack / z3c.deadlockdebugger packages. You can
now send a SIGUSR1 signal to a Zope process and get a stack trace of all
threads printed out on the console. This works even if all threads are stuck.
Instance skeleton
+++++++++++++++++
- Changed the default for ``enable-product-installation`` to off. This matches
the default behavior of buildout installs via plone.recipe.zope2instance.
Disabling the persistent product installation also disabled the ZMI help
system.
- Removed Zope2's own mkzeoinstance script. If you want to set up ZEO instances
please install the zope.mkzeoinstance and use its script.
- Removed deprecated ``read-only-database`` option from zope.conf.
- LP #143232: Added option to 'zope.conf' to specify an additional directory to
be searched for 'App.Extensions' lookups. Thanks to Rodrigo Senra for the
patch.
- LP #143604: Removed top-level database-quota-size from zope.conf, some
storages support a quota option instead.
- LP #143089: Removed the top-level zeo-client-name option from zope.conf, as it
had no effect since ZODB 3.2.
- Removed no longer maintained ``configure, make, make install`` related
installation files. Zope2 can only be installed via its setup.py.
- Removed the unmaintained and no longer functioning ZopeTutorialExamples from
the instance skeleton.
Deprecated and Removed
++++++++++++++++++++++
- Finished the move of five.formlib to an extra package and removed it from Zope
2 itself. Upgrade notes have been added to the news section of the release
notes.
- ZPublisher: Removed 'Main' and 'Zope' wrappers for Test.publish. If anybody
really used them, he can easily use ZPublisher.test instead. In the long run
ZPublisher.test and ZPublisher.Test might also be removed.
- ZPublisherExceptionHook: Removed ancient backwards compatibility code.
Customized raise_standardErrorMessage methods have to implement the signature
introduced in Zope 2.6.
- Removed ancient App.HotFixes module.
- Removed the deprecated ``hasRole`` method from user objects.
- Removed deprecated support for specifying ``__ac_permissions__``,
``meta_types`` and ``methods`` in a product's ``__init__``.
- Remove remaining support classes for defining permissions TTW.
- Removed the deprecated ``five:containerEvents`` directive, which had been a
no-op for quite a while.
- Removed Products.Five.fivedirectives.IBridgeDirective - a leftover from the
Interface to zope.interface bridging code.
- Marked the ```` as officially deprecated. The standard
```` directive allows the same.
Refactoring
+++++++++++
- Completely refactored ``ZPublisher.WSGIResponse`` in order to provide
non-broken support for running Zope under arbitrary WSGI servers. In this
(alternate) scenario, transaction handling, request retry, error handling,
etc. are removed from the publisher, and become the responsibility of
middleware.
- Moved the code handling ZCML loading into the ``Zope2.App`` package. The
component architecture is now setup before the application object is created
or any database connections are opened. So far the CA was setup somewhat
randomly in the startup process, when the ``Five`` product was initialized.
- Moved Products.Sessions APIs from ``SessionInterfaces`` to ``interfaces``,
leaving behind the old module / names for backward compatibility.
- Centralize interfaces defined in Products.ZCTextIndex, leaving BBB imports
behind in old locations.
- Moved ``cmf.*`` permissions into Products.CMFCore.
- Moved ``TaintedString`` into the new AccessControl.tainted module.
- Testing: Functional.publish now uses the real publish_module function instead
of that from ZPublisher.Test. The 'extra' argument of the publish method is no
longer supported.
- Moved ``testbrowser`` module into the Testing package.
- Moved general OFS related ZCML directives from Products.Five into the OFS
package.
- Moved the ``absoluteurl`` views into the OFS package.
- Moved ``Products/Five/event.zcml`` into the OFS package.
- Moved ``Products/Five/security.py`` and security related ZCML configuration
into the AccessControl package.
- Moved ``Products/Five/traversing.zcml`` directly into the configure.zcml.
- Moved ``Products/Five/i18n.zcml`` into the ZPublisher package.
- Moved ``Products/Five/publisher.zcml`` into the ZPublisher package.
- Ported the lazy expression into zope.tales and require a new version of it.
General
+++++++
- Updated copyright and license information to conform with repository policy.
- LP #143410: Removed unnecessary color definition in ZMI CSS.
- LP #374810: ``__bobo_traverse__`` implementation can raise
``ZPublisher.interfaces.UseTraversalDefault`` to indicate that there is no
special casing for the given name and that standard traversal logic should
be applied.
- LP #142464: Make undo log easier to read. Thanks to Toby Dickinson for the
patch.
- LP #142401: Added a link in the ZMI tree pane to make the tree state
persistent. Thanks to Lalo Martins for the patch.
- LP #142502: Added a knob to the Debug control panel for resetting profile
data. Thanks to Vladimir Patukhov for the patch.
- ZCTextIndex query parser treats fullwidth space characters defined in Unicode
as valid white space.
Updated distributions
+++++++++++++++++++++
- Jinja2 = 2.5.0
- RestrictedPython = 3.6.0a1
- Sphinx = 1.0b2
- transaction = 1.1.0
- ZConfig = 2.8.0
- ZODB3 = 3.10.0b1
- zope.annotation = 3.5.0
- zope.broken = 3.6.0
- zope.browsermenu = 3.9.0
- zope.browserpage = 3.12.2
- zope.browserresource = 3.10.3
- zope.component = 3.9.4
- zope.configuration = 3.7.2
- zope.container = 3.11.1
- zope.contentprovider = 3.7.2
- zope.contenttype = 3.5.1
- zope.event = 3.5.0-1
- zope.exceptions = 3.6.0
- zope.filerepresentation = 3.6.0
- zope.i18nmessageid = 3.5.0
- zope.interface = 3.6.1
- zope.location = 3.9.0
- zope.lifecycleevent = 3.6.0
- zope.ptresource = 3.9.0
- zope.publisher = 3.12.3
- zope.schema = 3.6.4
- zope.sendmail = 3.7.2
- zope.site = 3.9.1
- zope.structuredtext = 3.5.0
- zope.tales = 3.5.1
- zope.testbrowser = 3.9.0
- zope.testing = 3.9.3
- zope.traversing = 3.12.1
- zope.viewlet = 3.7.2
Bugs Fixed
++++++++++
- LP #143391: Protect against missing acl_users.hasUsers on quick start page.
Zope-2.13/doc/DEBUGGING.rst 0000664 0000000 0000000 00000001550 13037641750 0015155 0 ustar 00root root 0000000 0000000 Running Zope in Debug Mode
==========================
A utility known as 'zopectl' is installed into generated instance homes.
If you wish to run Zope in debug mode, run zopectl in foreground mode::
$ bin/zopectl fg
You can also use it to inspect a Zope instance's running state via an
interactive Python interpreter by passing zopectl the 'debug' parameter on the
command line.
The 'top-level' Zope object (the root folder) will be bound to the name 'app'
within the interpreter. You can then use normal Python method calls against app
and use the Python interpreter normally to inspect results::
$ bin/zopectl debug
Starting debugger (the name "app" is bound to the top-level Zope object)
>>> app.keys()
['acl_users', 'Control_Panel', 'temp_folder', 'browser_id_manager', 'session_data_manager', 'error_log', 'index_html', 'standard_error_message']
>>>
Zope-2.13/doc/INSTALL-buildout.rst 0000664 0000000 0000000 00000013675 13037641750 0016630 0 ustar 00root root 0000000 0000000 Installing Zope with ``zc.buildout``
====================================
.. highlight:: bash
This document describes how to get going with Zope using ``zc.buildout``.
About ``zc.buildout``
---------------------
`zc.buildout `_ is a powerful tool for creating
repeatable builds of a given software configuration and environment. The
Zope developers use ``zc.buildout`` to develop Zope itself, as well as
the underlying packages it uses.
Prerequisites
-------------
In order to use Zope, you must have the following pre-requisites
available:
- A supported version of Python, including the development support if
installed from system-level packages. Supported versions include:
* 2.6.x
* 2.7.x
- Zope needs the Python ``zlib`` module to be importable. If you are
building your own Python from source, please be sure that you have the
headers installed which correspond to your system's ``zlib``.
- A C compiler capable of building extension modules for your Python
(gcc recommended). This is not necessary for Windows as binary
releases of the parts that would need compiling are always made
available.
- If you wish to install Zope as a Service on Windows, you will need
to have the `pywin32`__ package installed.
__ https://sourceforge.net/projects/pywin32/
Installing standalone Zope using zc.buildout
--------------------------------------------
In this configuration, we use ``zc.buildout`` to install the Zope software,
but then generate server "instances" outside the buildout environment.
Installing the Zope software
::::::::::::::::::::::::::::
Installing the Zope software using ``zc.buildout`` involves the following
steps:
- Download the Zope 2 source distribution from `PyPI`__
__ http://pypi.python.org/pypi/Zope2
- If your Python has ``setuptools`` installed, create a virtual environment
*without setuptools* (newer ``setuptools`` versions in the base Python
break the version of buildout we use).
- Bootstrap the buildout using the virtual environment's Python.
- Run the buildout
On Linux, this can be done as follows::
$ wget https://pypi.python.org/packages/source/Z/Zope2/Zope2-.tar.gz
$ tar xfvz Zope2-.tar.gz
$ cd Zope2-
Then, either::
$ /path/to/your/python bootstrap/bootstrap.py
or (if you have ``setuptools`` installed already)::
$ /path/to/your/virtualenv --no-setuptools .
$ bin/python bootstrap/bootstrap.py
Finally::
$ bin/buildout
Creating a Zope instance
::::::::::::::::::::::::
Once you've installed Zope, you will need to create an "instance
home". This is a directory that contains configuration and data for a
Zope server process. The instance home is created using the
``mkzopeinstance`` script::
$ bin/mkzopeinstance
You can specify the Python interpreter to use for the instance
explicitly::
$ bin/mkzopeinstance --python=$PWD/bin/zopepy
You will be asked to provide a user name and password for an
administrator's account during ``mkzopeinstance``. To see the available
command-line options, run the script with the ``--help`` option::
$ bin/mkzopeinstance --help
.. note::
The traditional "inplace" build is no longer supported. If using
``mkzopeinstance``, always do so outside the buildout environment.
Creating a buildout-based Zope instance
---------------------------------------
Rather than installing Zope separately from your instance, you may wish
to use ``zc.buildout`` to create a self-contained environment, containing
both the Zope software and the configuration and data for your server.
This procedure involves the following steps:
- Create the home directory for the buildout, including
``etc``, ``log`` and ``var`` subdirectories.
- Fetch the buildout bootstrap script into the environment.
- Fetch the version files into the environment, for example:
https://raw.github.com/zopefoundation/Zope/2.13.22/versions.cfg
https://raw.github.com/zopefoundation/Zope/2.13.22/ztk-versions.cfg
- Create a buildout configuration as follows:
.. topic:: buildout.cfg
:class: file
::
[buildout]
parts = instance
extends = versions.cfg
[instance]
recipe = zc.recipe.egg
eggs = Zope2
interpreter = py
scripts = runzope zopectl
initialization =
import sys
sys.argv[1:1] = ['-C',r'${buildout:directory}/etc/zope.conf']
This is the minimum but all the usual buildout techniques can be
used.
- Bootstrap the buildout
- Run the buildout
- Create a Zope configuration file. A minimal version would be:
.. topic:: etc/zope.cfg
:class: file
::
%define INSTANCE
python $INSTANCE/bin/py[.exe on Windows]
instancehome $INSTANCE
A fully-annotated sample can be found in the Zope2 egg::
$ cat eggs/Zope2--*/Zope2/utilities/skel/etc/zope.conf.in
.. highlight:: bash
An example session::
$ mkdir /path/to/instance
$ cd /path/to/instance
$ mkdir etc logs var
$ wget https://svn.zope.org/zc.buildout/trunk/bootstrap/bootstrap.py
$ vi buildout.cfg
$ /path/to/your/python bootstrap.py # assumes no setuptools installed
$ bin/buildout
$ cat eggs/Zope2--*/Zope2/utilities/skel/etc/zope.conf.in > etc/zope.conf
$ vi etc/zope.conf # replace <> with buildout directory
$ bin/zopectl start
In the ``bin`` subdirectory of your instance directory, you will
find ``runzope`` and ``zopectl`` scripts that can be used as
normal.
You can use ``zopectl`` interactively as a command shell by just
calling it without any arguments. Try ``help`` there and ``help ``
to find out about additionally commands of zopectl. These commands
also work at the command line.
Note that there are there are recipes such as `plone.recipe.zope2instance
`_ which can be
used to automate this whole process.
After installation, refer to :doc:`operation` for documentation on
configuring and running Zope.
Zope-2.13/doc/INSTALL-virtualenv.rst 0000664 0000000 0000000 00000003433 13037641750 0017167 0 ustar 00root root 0000000 0000000 Installing Zope with ``virtualenv``
===================================
.. highlight:: bash
This document describes how to install Zope into a ``virtualenv``.
Create a Virtual Environment
----------------------------
.. code-block:: sh
$ /opt/Python-2.7.9/bin/virtualenv z213
New python executable in z213/bin/python
Installing setuptools, pip, wheel...done.
$ cd z213
Install the Zope2 2.13.22 Software Packages
-------------------------------------------
.. code-block:: sh
$ bin/pip install \
--trusted-host download.zope.org \
--index http://download.zope.org/Zope2/index/2.13.22/ Zope2
Collecting Zope2
...
Successfully installed ...
Creating a Zope instance
------------------------
Once you've installed Zope, you will need to create an "instance
home". This is a directory that contains configuration and data for a
Zope server process. The instance home is created using the
``mkzopeinstance`` script:
.. code-block:: sh
$ bin/mkzopeinstance
You can specify the Python interpreter to use for the instance
explicitly:
.. code-block:: sh
$ bin/mkzopeinstance --python=bin/python
You will be asked to provide a user name and password for an
administrator's account during ``mkzopeinstance``. To see the available
command-line options, run the script with the ``--help`` option:
.. code-block:: sh
$ bin/mkzopeinstance --help
Using the ``virtualenv`` as the Zope Instance
---------------------------------------------
You can choose to use the ``virtualenv`` as your Zope instance:
.. code-block:: sh
$ bin/mkzopeinstance -d .
In this case, the instance files will be located in the
subdirectories of the ``virtualenv``:
- ``etc/`` will hold the configuration files.
- ``log/`` will hold the log files.
- ``var/`` will hold the database files.
Zope-2.13/doc/Makefile 0000664 0000000 0000000 00000004506 13037641750 0014574 0 ustar 00root root 0000000 0000000 # Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = ../bin/sphinx-build
PAPER =
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
help:
@echo "Please use \`make ' where is one of"
@echo " html to make standalone HTML files"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview over all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
clean:
-rm -rf _build/*
html:
mkdir -p _build/html _build/doctrees
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) _build/html
@echo
@echo "Build finished. The HTML pages are in _build/html."
pickle:
mkdir -p _build/pickle _build/doctrees
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
@echo
@echo "Build finished; now you can process the pickle files."
web: pickle
json:
mkdir -p _build/json _build/doctrees
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) _build/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
mkdir -p _build/htmlhelp _build/doctrees
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) _build/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in _build/htmlhelp."
latex:
mkdir -p _build/latex _build/doctrees
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) _build/latex
@echo
@echo "Build finished; the LaTeX files are in _build/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
changes:
mkdir -p _build/changes _build/doctrees
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) _build/changes
@echo
@echo "The overview file is in _build/changes."
linkcheck:
mkdir -p _build/linkcheck _build/doctrees
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) _build/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in _build/linkcheck/output.txt."
Zope-2.13/doc/SECURITY.rst 0000664 0000000 0000000 00000001440 13037641750 0015127 0 ustar 00root root 0000000 0000000 Filesytem Permissions
=====================
You need to set permissions on the directory Zope uses to store its
data. This will normally be the `var` directory in the instance home.
Zope needs to read and write data to this directory. Before
running Zope you should ensure that you give adequate permissions
to this directory for the userid Zope will run under.
Depending on how you choose to run Zope you will need to give
different permissions to the directory. If you use Zope with an
existing web server, it will probably run Zope as 'nobody'. In this
case 'nobody' needs read and write permissions to the var directory.
If you change the way you run Zope, you may need to modify the permissions
of the directory and the files in it to allow Zope to read and write
under its changed userid.
Zope-2.13/doc/SETUID.rst 0000664 0000000 0000000 00000003325 13037641750 0014661 0 ustar 00root root 0000000 0000000 Zope effective user support
===========================
.. note::
It is best practice to run Zope behind a reverse proxy like
Apache, Squid or Varnish. In this case, you do not need to run
or install Zope with root privileges, since the reverse proxy
will bind to port 80 and proxy back all request to Zope running
on an unprivileged port.
Zope can bind its network service to low ports such as 21 (FTP) and
80 (HTTP). In order to bind to low ports, Zope must be started as
the root user. However, Zope will only run as root long enough to
bind to these low ports. It will then attempt to setuid to a less
privileged user.
You must specify the user to which Zope will attempt to setuid by
changing the 'effective-user' parameter in the zope.conf
configuration file to an existing username or UID. All runtime
files will be written as this user. If you do not specify an
'effective-user' in the configuration file, and you attempt to start
Zope, it will refuse to start.
Zope additionally emits a warning if you specify 'nobody' as the
'effective-user'. The rationale for this warning stems from the
fact that, historically, many other UNIX services dropped privileges
to the 'nobody' account after starting as root. Any security
defects in these services could cause someone to gain access as the
'nobody' account on your system. If someone was to gain control of
your 'nobody' account they could compromise your Zope files.
The most important thing to remember about effective user support is
that you don't have to start Zope as root unless you want to listen
for requests on low ports (ports beneath 1024). In fact, if you
don't have this need, you are much better off just starting Zope
under a dedicated user account.
Zope-2.13/doc/SIGNALS.rst 0000664 0000000 0000000 00000002033 13037641750 0014757 0 ustar 00root root 0000000 0000000 Signals (POSIX only)
====================
Signals are a POSIX inter-process communications mechanism.
If you are using Windows then this documentation does not apply.
Zope responds to signals which are sent to the process id
specified in the file '$INSTANCE_HOME/var/Z2.pid'::
SIGHUP - close open database connections, then restart the server
process. A idiom for restarting a Zope server is:
kill -HUP `cat $INSTANCE_HOME/var/z2.pid`
SIGTERM - close open database connections then shut down. A common
idiom for shutting down Zope is:
kill -TERM `cat $INSTANCE_HOME/var/Z2.pid`
SIGINT - same as SIGTERM
SIGUSR1 - dump a stack trace of all threads to stdout. This can help
diagnosing `stuck` Zope processes if all threads are stuck.
SIGUSR2 - close and re-open all Zope log files (z2.log, event log,
detailed log.) A common idiom after rotating Zope log files
is:
kill -USR2 `cat $INSTANCE_HOME/var/z2.pid`
Zope-2.13/doc/USERS.rst 0000664 0000000 0000000 00000005757 13037641750 0014600 0 ustar 00root root 0000000 0000000 Special Users
=============
Because Zope is managed through the web, user names and passwords must be
used to assure that only authorized people can make changes to a Zope
installation.
Adding Managers
---------------
If you need to add a Manager to an existing Zope instance, you can do
this using `zopectl` as follows::
zopectl adduser `name` `password`
The Initial User
----------------
An initial username and password is needed to "bootstrap" the creation of
normal managers of your Zope site. This is accomplished through the
use of the 'inituser' file in the directory specified as the instance
home.
The first time Zope starts, it will detect
that no users have been defined in the root user folder. It will search
for the 'inituser' file and, if it exists, will add the user defined
in the file to the root user folder.
Normally, 'inituser' is created by the Zope install scripts. Either
the installer prompts for the password or a randomly generated
password is created and displayed at the end of the build script.
You can use the 'zpasswd.py' script to create 'inituser' yourself.
Execute 'zpasswd.py' like this::
python zpasswd.py inituser
The script will prompt you for the name, password, and allowed
domains. The default is to encode the password with SHA, so please
remember this password as there is no way to recover it (although
'zpasswd.py' lets you reset it.)
The Emergency User
------------------
In some situations you may need to bypass normal security controls
because you have lost your password or because the security settings
have been mixed up. Zope provides a facility called an "emergency
user" so that you can reset passwords and correct security
settings.
The emergency user password must be defined outside the application
user interface. It is defined in the 'access' file located
in the Zope directory. It should be readable only by the user
as which your web server runs.
To create the emergency user, use 'zpasswd.py' to create the
'access' file like this::
python zpasswd.py access
In order to provide a somewhat higher level of security, various
encoding schemes are supported which provide access to either SHA-1
encryption or the standard UNIX crypt facility if it has been compiled
into Python. Unless you have some special requirements (see below),
you should use the SHA-1 facility, which is the default.
Format of 'inituser' and 'access'
---------------------------------
A password file should consist of a single line of the form::
name:password
Note that you may also add an optional third component to the line in the
access file to restrict access by domain. For example, the line::
mario:nintendoRules:*.mydomain.com
in your 'access' file will only allow permit emergency user access
from `*.mydomain.com` machines. Attempts to access the system from
other domains will fail, even if the correct emergency user name
and password are used.
Please note that if you use the ZServer monitor capability, you will
need to run with a clear text password.
Zope-2.13/doc/WHATSNEW.rst 0000664 0000000 0000000 00000017051 13037641750 0015125 0 ustar 00root root 0000000 0000000 What's new in Zope 2.13
=======================
The article explains the new high-level features and changes found in this
version of Zope 2.
You can have a look at the `detailed change log `_ to learn
about all minor new features and bugs being solved in this release.
Python 2.7
----------
This release of Zope 2 adds support for
`Python 2.7 `_. Please refer to
the `What's new in Python 2.7 `_
document, if you want to know more about the changes.
Zope 2.13 is continuing to support Python 2.6.4 or any later maintenance release
of it. There's currently no support for any Python 3.x version. Work has begun
in the Zope Toolkit to port some of the lower level packages to Python 3.
ZODB 3.10
---------
This version of Zope includes ZODB 3.10 - a new major version of the ZODB.
Among the notable changes are a variety of performance improvements. The ZEO
server process is now multi-threaded. If the underlying file system and disk
storage can handle concurrent disk I/O efficiently a throughput increase by a
factor of up to four has been seen. On a related note using solid state disks
for the ZEO server has a similar effect and can increase throughput by the
same factor. Both of these effects combined can lead to an increase of up to
sixteen times the throughput in high load scenarios.
File storage indexes use a new format, which is both smaller in size and can
be read much faster. The repozo backup script now also backs up the index files
in addition to the actual data, so in a restore scenario the index doesn't have
to be recreated. For large databases this can bring down the total downtime in
a restore scenario by a significant amount of time.
The ZODB has added support for wrapper storages that transform pickle data.
Applications for this include compression and encryption. A storage using
standard zlib compression is available as a new package called
`zc.zlibstorage `_. In content
management scenarios where strings constitute the most of the non-blob data,
this can reduce the Data.fs size by a factor of two or more. The overhead of
compressing and uncompressing is negligible. This saves both network I/O and
disk space. More importantly the database has better chances of fitting into
the operating systems disk cache and thus into memory. The second advantage is
less important when using solid state disks.
Databases now warn when committing very large records (> 16MB). This is to try
to warn people of likely design mistakes. There is a new option
(large_record_size/large-record-size) to control the record size at which the
warning is issued. This should help developers to better understand the storage
implications of their code, which has been rather transparent so far.
The mkzeoinst script has been moved to a separate project
`zope.mkzeoinstance `_ and is
no-longer included with ZODB. You will need to use this new package to set up
ZEO servers or use the
`plone.recipe.zeoserver `_
recipe if you use `buildout `_.
More information can be found in the detailed
`change log `_.
WSGI
----
See :doc:`WSGI`.
This Zope release comes with native WSGI support. First pioneered in the
repoze.zope2 project, this capability finally found its way back into the core
and obsoletes the externally managed project. With WSGI Zope 2 can natively talk
to a variety of web servers and isn't restricted to its own ZServer anymore. It
also opens up new possibilities for writing or reusing middleware in Zope 2 or
factoring out capabilities into WSGI endware. It's expected that this new
deployment model will over time become the default and the old ZServer
implementation will be deprecated. There's no concrete timeline for this yet.
.. note::
Due to the way logic is split out into WSGI middleware, some of the
`ZPublisher.pubevents` aren't emitted by the WSGI publisher. These are:
`PubSuccess`, `PubFailure`, `PubBeforeCommit` and `PubBeforeAbort`.
Zope Toolkit
------------
Zope 2.13 has neither direct nor indirect ``zope.app.*`` dependencies anymore.
This finishes the transition from the hybrid Zope 2 + 3 codebase. Zope 3 itself
has been split up into two projects, the underlying Zope Toolkit consisting of
foundation libraries and the application server part. The application server
part has been renamed BlueBream. Zope 2 only depends and ships with the Zope
Toolkit now.
Large parts of code inside Zope 2 and specifically Products.Five have been
refactored to match this new reality. The goal is to finally remove the Five
integration layer and make the Zope Toolkit a normal integral part of Zope 2.
ZCatalog
--------
The ZCatalog and the default set of indexes as found in the PluginIndexes
package have seen a large number of changes. Most of these have been pioneered
in add-on packages in the Zope community over the last years and now have found
their way back into the core. The largest change is added query plan support for
the catalog. A standard feature in all relation databases, the job of a query
plan is to monitor queries in a live system and based on execution metrics
devise optimized plans for executing the low level instructions which lead to a
query result. In sites with large number of indexed objects this can make a
tremendous difference and significantly speed up all queries.
The query plan support is completely transparent to all users, though ways exist
for developers to predefine it and store it across server restarts. The plan
itself can be introspected in a tab in the ZMI. There's also a new ZMI tab to
report slow catalog queries which can help developers to tune the remaining slow
queries in their applications.
In addition to these larger changes there's been a high number of smaller
changes to the search logic and the catalog implementations. All of these
should result in better query execution and reduced number of conflict error
potential.
Refactoring
-----------
There's an ongoing effort to refactor Zope 2 into more independent modularized
distributions. Zope 2.12 has already seen a lot of this, with the use of zope.*
packages as individual distributions and the extraction of packages like
Acquisition, DateTime or tempstorage to name a few. Zope 2.13 continues this
trend and has moved all packages containing C extensions to external
distributions. Among those are AccessControl, DocumentTemplate and
Products.ZCTextIndex.
Optional Formlib support
------------------------
Zope 2 made a number of frameworks available through its integration layer
Products.Five. Among these has been direct support for an automated form
generation framework called zope.formlib with its accompanying widget library
zope.app.form.
This form generation framework has seen only minor adoption throughout the Zope
community and more popular alternatives like z3c.form exist. To reflect this
status Zope 2 no longer directly contains formlib support.
If you rely on formlib, you need to add a dependency to the new five.formlib
distribution and change all related imports pointing to Products.Five.form or
Products.Five.formlib to point to the new package instead.
In order to ease the transition, five.formlib has been backported to the 2.12
release series. Starting in 2.12.3 you can already use the new five.formlib
package, but backwards compatibility imports are left in place in Products.Five.
This allows you to easily adapt your packages to work with both 2.12 and 2.13.
Zope-2.13/doc/WSGI.rst 0000664 0000000 0000000 00000012135 13037641750 0014434 0 ustar 00root root 0000000 0000000 Running Zope2 as a WSGI Application
===================================
This document assumes you have installed Zope into a ``virtualenv`` (see
:doc:`INSTALL-virtualenv`).
Install the Supporting Software
-------------------------------
To run as a WSGI application, you need to install some additional software.
.. code-block:: sh
$ bin/pip install \
--trusted-host download.zope.org \
--index http://download.zope.org/Zope2/index/2.13.22/ \
repoze.who repoze.tm2 repoze.retry Paste PasteDeploy PasteScript
Collecting repoze.who
...
Successfully installed Paste-1.7.5.1 PasteDeploy-1.3.4 PasteScript-1.7.5 repoze.retry-1.2 repoze.tm2-1.0 repoze.who-2.0
Update the Zope Application Configuration
-----------------------------------------
The generated ``etc/zope.conf`` file assumes that Zope will be running
using the built-in ``ZServer``.
.. code-block:: sh
$ vim etc/zope.conf
Update the contents as follows.
.. code-block:: apacheconf
%define INSTANCE /path/to/virtualenv
instancehome $INSTANCE
.. note::
The ``%define instance /path/to/virtualenv`` element must
point to the environment: there is no "relative to this file" support
built in.
Set up logging for the application.
.. code-block:: apacheconf
level info
path $INSTANCE/log/event.log
level info
level WARN
path $INSTANCE/log/Z2.log
format %(message)s
Configure the database (note that you could use ``ZEO`` or ``Relstorage``
rather than a bare ``FileStorage``):
.. code-block:: apacheconf
# Main FileStorage database
# See .../ZODB/component.xml for directives (sectiontype
# "filestorage").
path $INSTANCE/var/Data.fs
mount-point /
# Temporary storage database (for sessions)
name temporary storage for sessioning
mount-point /temp_folder
container-class Products.TemporaryFolder.TemporaryContainer
Because we will be running a separately-configured WSGI server, remove any
```` configuration from the file.
Create the WSGI Server Configuration
------------------------------------
.. code-block:: sh
$ vim etc/zope.wsgi
First, configure the "application" endpoint for Zope:
.. code-block:: ini
[app:zope]
use = egg:Zope2#main
zope_conf = %(here)s/zope.conf
Next, set up the WSGI middleware pipeline:
.. code-block:: ini
[pipeline:main]
pipeline =
egg:paste#evalerror
egg:repoze.retry#retry
egg:repoze.tm2#tm
zope
The middleware layers are "wrapped" around the application endpoint as follows:
- ``paste#evalerror`` is debugging middleware, which shows tracebacks for
errors raised from the application. It should **not** be configured for
production use.
- ``repoze.retry#retry`` is middleware which retries requests when retriable
exceptions are raised. By default, it retries 3 times, and only for
requests which raise ``ZODB.ConflictError``. See
http://repozeretry.rtfd.org/ for details on configuring it otherwise.
- ``repoze.tm2#tm`` is middleware which begins a new transaction for each
request, and then either aborts the transaction (if the request raises an
exception) or commits it (if not). See
http://repozetm2.rtfd.org/ for details on configuring it.
Finally, configure the WSGI server:
.. code-block:: ini
[server:main]
use = egg:paste#http
host = localhost
port = 8080
.. note::
Any server conforming to PEP 333/3333 should work, although the parameters
could change.
Set up the Admin User
---------------------
Before starting the WSGI server, run the ``addzope2user`` script to configure
the administrative user.
.. code-block:: sh
$ bin/addzope2user admin
No handlers could be found for logger "ZODB.FileStorage"
User admin created.
Start the WSGI Server
---------------------
.. code-block:: sh
$ bin/paster serve etc/zope.wsgi
Starting server in PID 24934.
serving on http://127.0.0.1:8080
Running Other Applications in the same WSGI Server Process
----------------------------------------------------------
You can use any of the normal ``Paste`` WSGI features to combine Zope and
other WSGI applications inside the same server process. E.g., the following
configuration uses the
`composite application `_
support offered by ``PasteDeploy`` to host Zope at the ``/`` prefix,
with static files served from disk at ``/static``:
.. code-block:: ini
[app:zope-app]
use = egg:Zope2#main
zope_conf = %(here)s/zope.conf
[pipeline:zope-pipeline]
pipeline =
egg:paste#evalerror
egg:repoze.retry#retry
egg:repoze.tm2#tm
zope-app
[app:static]
use = egg:Paste#static
document_root = %(here)s/static
[composite:main]
use = egg:Paste#urlmap
/ = zope-pipeline
/static = static
Zope-2.13/doc/_static/ 0000775 0000000 0000000 00000000000 13037641750 0014555 5 ustar 00root root 0000000 0000000 Zope-2.13/doc/_static/placeholder.txt 0000664 0000000 0000000 00000000046 13037641750 0017600 0 ustar 00root root 0000000 0000000 Preserve "empty" directory under git.
Zope-2.13/doc/_templates/ 0000775 0000000 0000000 00000000000 13037641750 0015264 5 ustar 00root root 0000000 0000000 Zope-2.13/doc/_templates/placeholder.txt 0000664 0000000 0000000 00000000046 13037641750 0020307 0 ustar 00root root 0000000 0000000 Preserve "empty" directory under git.
Zope-2.13/doc/conf.py 0000664 0000000 0000000 00000013651 13037641750 0014434 0 ustar 00root root 0000000 0000000 # -*- coding: utf-8 -*-
#
# Zope docs documentation build configuration file, created by
# sphinx-quickstart on Fri Feb 20 16:22:03 2009.
#
# This file is execfile()d with the current directory set to its containing dir.
#
# The contents of this file are pickled, so don't put values in the namespace
# that aren't pickleable (module imports are okay, they're removed automatically).
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
import sys, os
# If your extensions are in another directory, add it here. If the directory
# is relative to the documentation root, use os.path.abspath to make it
# absolute, like shown here.
#sys.path.append(os.path.abspath('.'))
# General configuration
# ---------------------
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = []
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
# The encoding of source files.
#source_encoding = 'utf-8'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'Zope 2 documentation'
copyright = u'2009-2010, The Zope Developers Community'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '2.13'
# The full version, including alpha/beta/rc tags.
release = '2.13'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#today = ''
# Else, today_fmt is used as the format for a strftime call.
#today_fmt = '%B %d, %Y'
# List of documents that shouldn't be included in the build.
#unused_docs = []
# List of directories, relative to source directory, that shouldn't be searched
# for source files.
exclude_trees = ['.build']
# The reST default role (used for this markup: `text`) to use for all documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# Options for HTML output
# -----------------------
# The style sheet to use for HTML and HTML Help pages. A file of that name
# must exist either in Sphinx' static/ path, or in one of the custom paths
# given in html_static_path.
html_style = 'default.css'
# The name for this set of Sphinx documents. If None, it defaults to
# " v documentation".
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#html_logo = None
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#html_favicon = None
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
#html_last_updated_fmt = '%b %d, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
#html_additional_pages = {}
# If false, no module index is generated.
#html_use_modindex = True
# If false, no index is generated.
#html_use_index = True
# If true, the index is split into individual pages for each letter.
#html_split_index = False
# If true, the reST sources are included in the HTML build as _sources/.
#html_copy_source = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
#html_use_opensearch = ''
# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
#html_file_suffix = ''
# Output file base name for HTML help builder.
htmlhelp_basename = 'Zopedocsdoc'
# Options for LaTeX output
# ------------------------
# The paper size ('letter' or 'a4').
#latex_paper_size = 'letter'
# The font size ('10pt', '11pt' or '12pt').
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title, author, document class [howto/manual]).
latex_documents = [
('index', 'Zope2docs.tex', ur'Zope 2 Documentation',
ur'Zope Developers Community', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#latex_use_parts = False
# Additional stuff for the LaTeX preamble.
#latex_preamble = ''
# Documents to append as an appendix to all manuals.
#latex_appendices = []
# If false, no module index is generated.
#latex_use_modindex = True
Zope-2.13/doc/index.rst 0000664 0000000 0000000 00000000600 13037641750 0014764 0 ustar 00root root 0000000 0000000
Zope 2.13 specific documentation
================================
.. Note::
The Zope 2.13.x release series is in bug-fix-only mode. It will see
security and bug fixes until further notice.
Contents:
.. toctree::
:maxdepth: 2
WHATSNEW
INSTALL-buildout
INSTALL-virtualenv
operation
WSGI
USERS
SECURITY
SETUID
SIGNALS
DEBUGGING
CHANGES
Zope-2.13/doc/maintainers/ 0000775 0000000 0000000 00000000000 13037641750 0015441 5 ustar 00root root 0000000 0000000 Zope-2.13/doc/maintainers/RELEASING.rst 0000664 0000000 0000000 00000007272 13037641750 0017514 0 ustar 00root root 0000000 0000000 Makeing a 2.13.x Release
========================
Make a branch for release prepration.
-------------------------------------
We need to make a number of changes for the release which we do *not* want
checked in on the ``2.13`` branch. Therefore, create a release-preparation
branch, based on the ``2.13`` branch, as the locus for those changes:
.. code-block:: bash
$ git checkout -b 2.13.23-prep 2.13
Update the release version in ``setup.py``
------------------------------------------
Set the new release version, and commit:
.. code-block:: bash
$ vim setup.py
$ git commit -m "Update version for 2.13.23 release" setup.py
Pin versions in ``buildout.cfg``
--------------------------------
For a release, we want to switch away from the range-based version constraints
we use for the development branch, and pin the specific versions.
First, re-run the buildout, which will dump the currently-selected versions
on standard output. E.g.:
.. code-block:: bash
$ bin/buildout
...
[versions]
AccessControl = 2.13.13
Acquisition = 2.13.9
...
setuptools = 18.0.1
Next, update the ``buildout.cfg`` settings as follows:
- Copy the ``[versions]`` section from the buildout run at the bottom.
- In the ``[buildout]`` secttion, remove ``show-picked-verions = true``,
add ``allow-picked-versions = false``, and remove the ``version_ranges``
from the ``extends``.
.. code-block:: bash
$ vim buildout.cfg
Re-run the buildout and test:
.. code-block:: bash
$ rm -rf bin/ develop-eggs/ eggs/ include/ lib/
$ /opt/Python-2.7.9/bin/virtualenv .
$ bin/python bootstrap.py && bin/buildout && bin/alltest --all
Pin versions in a ``pip`` requirements file
-------------------------------------------
Copy the version pins from the ``[versions]`` section of ``buildout.cfg``
into a ``requirements.txt`` file, to enable ``pip`` users to install
without buildout (be sure to add the new ``Zope2`` release version to
``requirements.txt``).
.. note::
Update the single equal signs used in ``buildout.cfg`` to pip-compatible
double-equal signs.
.. code-block:: bash
$ vim requirements.txt
$ git add requirements.txt
$ git commit -m "Pin versions for 2.13.23 release" buildout.cfg requirements.txt
Review / update the changelog
-----------------------------
Add today's date to the current release.
.. code-block:: bash
$ vim doc/CHANGES.rst
$ git commit -m "Finalize changelog 2.13.23 release" doc/CHANGES.rst
.. note::
Keep track of the hash for this commit: you will want to cherry-pick
it to the ``2.13`` branch later.
Tag the release
---------------
.. code-block:: bash
$ git tag -sm "Tag 2.13.23 release" 2.13.23
.. note::
The ``-s`` signs the tag using PGP.
Register and upload the release to PyPI
---------------------------------------
.. code-block:: bash
$ bin/python setup.py sdist upload --sign
.. note::
The ``upload --sign`` signs the sdist using PGP and uploads the signature
to PyPI along with the distribution file.
Push the git release artefacts
------------------------------
.. code-block:: bash
$ git push origin 2.13.23-prep && git push --tags
Update the ``2.13`` branch for the next release
-----------------------------------------------
.. code-block:: bash
$ git checkout 2.13
Cherry-pick the changelog update from above:
.. code-block:: bash
$ git cherry-pick -x ^..
Add the next release to the changelog, with "(unreleased)" as its release
date and a "TBD" bullet, and update the next development release in
``setup.py``.
.. code-block:: bash
$ vim doc/CHANGES.rst
$ vim setup.py
$ git commit -m svb doc/CHANGES.rst setup.py
$ git push origin 2.13
Zope-2.13/doc/make.bat 0000664 0000000 0000000 00000004762 13037641750 0014545 0 ustar 00root root 0000000 0000000 @ECHO OFF
REM Command file for Sphinx documentation
set SPHINXBUILD=..\bin\sphinx-build
set ALLSPHINXOPTS=-d .build/doctrees %SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^` where ^ is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (.build\*) do rmdir /q /s %%i
del /q /s .build\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% .build/html
echo.
echo.Build finished. The HTML pages are in .build/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% .build/dirhtml
echo.
echo.Build finished. The HTML pages are in .build/dirhtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% .build/pickle
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% .build/json
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% .build/htmlhelp
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in .build/htmlhelp.
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% .build/latex
echo.
echo.Build finished; the LaTeX files are in .build/latex.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% .build/changes
echo.
echo.The overview file is in .build/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% .build/linkcheck
echo.
echo.Link check complete; look for any errors in the above output ^
or in .build/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% .build/doctest
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in .build/doctest/output.txt.
goto end
)
:end
Zope-2.13/doc/operation.rst 0000664 0000000 0000000 00000013454 13037641750 0015670 0 ustar 00root root 0000000 0000000 Configuring and Running Zope
============================
.. highlight:: bash
Whichever method you used to install Zope and create a server instance (see
:doc:`INSTALL-buildout` and :doc:`INSTALL-virtualenv`), the end result is
configured and operated the same way.
Configuring Zope
----------------
Your instance's configuration is defined in its ``etc/zope.conf`` file.
Unless you created the file manually, that file should contain fully-
annotated examples of each directive.
You can also pass an explicit configuration file on the command line::
$ /path/to/zope/instance/bin/zopectl -c /tmp/other.conf show
...
Config file: /tmp/other.conf
When starting Zope, if you see errors indicating that an address is in
use, then you may have to change the ports Zope uses for HTTP or FTP.
The default HTTP and FTP ports used by Zope are
8080 and 8021 respectively. You can change the ports used by
editing ./etc/zope.conf appropriately.
The section in the configuration file looks like this::
# valid keys are "address" and "force-connection-close"
address 8080
# force-connection-close on
The address can just be a port number as shown, or a host:port
pair to bind only to a specific interface.
After making any changes to the configuration file, you need to restart any
running Zope server for the affected instance before changes are in effect.
Running Zope in the Foreground
------------------------------
To run Zope without detaching from the console, use the ``fg``
command (short for ``foreground``)::
$ /path/to/zope/instance/bin/zopectl fg
In this mode, Zope emits its log messages to the console, and does not
detach from the terminal. This also automatically enables debug-mode. Do
not use this for production servers.
Running Zope as a Daemon
------------------------
Once an instance home has been created, the Zope server can now be
started using this command::
$ /path/to/zope/instance/bin/zopectl start
During startup, Zope emits log messages into
`/path/to/zope/instance/log/event.log`. You can examine it with the usual
tools (``cat``, ``more``, ``tail``, etc) and see if there are any errors
preventing Zope from starting.
.. highlight:: none
.. note::
For this to work on Windows, the Zope instance must be installed as
a Service. This is done with::
bin\zopectl install
If you later want to remove this Service, do the following::
bin\zopectl remove
For the full list of options available for setting up Zope as a
Windows Service, do::
bin\zopectl install --help
.. highlight:: bash
Integrating with System Startup
-------------------------------
zopectl can be linked as rc-script in the usual start directories
on linux or other System V unix variants.
You can use ``zopectl`` interactively as a command shell by just
calling it without any arguments. Try ``help`` there and ``help ``
to find out about additionally commands of zopectl. These commands
also work at the command line.
.. note::
On Windows, a Service can be installed and set to start
automatically with the following:
.. code-block:: none
bin\zopectl install --startup=auto
Logging In To Zope
------------------
Once you've started Zope, you can then connect to the Zope webserver
by directing your browser to::
http://yourhost:8080/manage
where 'yourhost' is the DNS name or IP address of the machine
running Zope. If you changed the HTTP port as described, use the port
you configured.
You will be prompted for a user name and password. Use the user name
and password you provided in response to the prompts issued during
the "make instance" process.
Now you're off and running! You should be looking at the Zope
management screen which is divided into two frames. On the left you
can navigate between Zope objects and on the right you can edit them
by selecting different management functions with the tabs at the top
of the frame.
If you haven't used Zope before, you should head to the Zope web
site and read some documentation. The Zope Documentation section is
a good place to start. You can access it at http://docs.zope.org/
Troubleshooting
---------------
- This version of Zope requires Python 2.6.4 or better.
It will *not* run with Python 3.x.
- The Python you run Zope with *must* have threads compiled in,
which is the case for a vanilla build. Warning: Zope will not run
with a Python version that uses ``libpth``. You *must* use
``libpthread``.
- To build Python extensions you need to have Python configuration
information available. If your Python comes from an RPM you may
need the python-devel (or python-dev) package installed too. If
you built Python from source all the configuration information
should already be available.
- See the :doc:`CHANGES` for important notes on this version of Zope.
Adding extra commands to Zope
-----------------------------
It is possible to add extra commands to ``zopectl`` by defining *entry points*
in ``setup.py``. Commands have to be put in the ``zopectl.command`` group:
.. code-block:: python
setup(name="MyPackage",
....
entry_points="""
[zopectl.command]
init_app = mypackage.commands:init_application
""")
.. note::
Due to an implementation detail of ``zopectl`` you can not use a minus
character (``-``) in the command name.
This adds a ``init_app`` command that can be used directly from the command
line::
bin\zopectl init_app
The command must be implemented as a Python callable. It will be called with
two parameters: the Zope2 application and a list with all command line
arguments. Here is a basic example:
.. code-block:: python
def init_application(app, args):
print 'Initializing the application'
Make sure the callable can be imported without side-effects, such as setting
up the database connection used by Zope 2.
Zope-2.13/setup.cfg 0000664 0000000 0000000 00000000065 13037641750 0014204 0 ustar 00root root 0000000 0000000 [check-manifest]
ignore =
*.cfg
bootstrap.py
Zope-2.13/setup.py 0000664 0000000 0000000 00000010274 13037641750 0014100 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
import os
import sys
from setuptools import setup, find_packages
additional_install_requires = []
if sys.platform[:3].lower() == "win":
additional_install_requires += ['nt_svcutils']
setup(
name='Zope2',
version='2.13.26.dev0',
url='http://zope2.zope.org',
license='ZPL 2.1',
description='Zope2 application server / web framework',
author='Zope Foundation and Contributors',
author_email='zope-dev@zope.org',
long_description=(open("README.txt").read() + "\n" +
open(os.path.join("doc", "CHANGES.rst")).read()),
classifiers=[
'Development Status :: 6 - Mature',
"Environment :: Web Environment",
"Framework :: Zope2",
"License :: OSI Approved :: Zope Public License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 2 :: Only",
"Programming Language :: Python :: 2.6",
"Programming Language :: Python :: 2.7",
"Programming Language :: Python :: Implementation :: CPython",
],
packages=find_packages('src'),
namespace_packages=['Products', 'Shared', 'Shared.DC'],
package_dir={'': 'src'},
install_requires=[
'AccessControl>=2.13.2',
'Acquisition',
'DateTime',
'DocumentTemplate',
'ExtensionClass',
'Missing',
'MultiMapping',
'Persistence',
'Products.OFSP >= 2.13.2', # folded back into Zope 4.0
'RestrictedPython',
'ZConfig',
'ZODB3',
'ZopeUndo',
'docutils',
'pytz',
'setuptools',
'tempstorage',
'transaction',
'zdaemon',
'zExceptions',
'zLOG',
'zope.browser',
'zope.browsermenu',
'zope.browserpage',
'zope.browserresource',
'zope.component',
'zope.configuration',
'zope.container',
'zope.contentprovider',
'zope.contenttype',
'zope.deferredimport',
'zope.event',
'zope.exceptions',
'zope.i18n [zcml]',
'zope.i18nmessageid',
'zope.interface',
'zope.lifecycleevent',
'zope.location',
'zope.pagetemplate',
'zope.processlifetime',
'zope.proxy',
'zope.ptresource',
'zope.publisher',
'zope.schema',
'zope.security',
'zope.sendmail',
'zope.sequencesort',
'zope.site',
'zope.size',
'zope.structuredtext',
'zope.tal',
'zope.tales >= 3.5.0',
'zope.testbrowser',
'zope.testing',
'zope.traversing',
'zope.viewlet',
# BBB optional dependencies to be removed in Zope 4.0
'initgroups',
'Products.BTreeFolder2',
'Products.ExternalMethod',
'Products.MailHost',
'Products.MIMETools',
'Products.PythonScripts',
'Products.Sessions',
'Products.StandardCacheManagers',
'Products.TemporaryFolder',
'Products.ZCatalog',
'Products.ZCTextIndex',
'Record',
'ZServer',
] + additional_install_requires,
include_package_data=True,
zip_safe=False,
entry_points={
'paste.app_factory': [
'main=Zope2.Startup.run:make_wsgi_app',
],
'console_scripts': [
'mkzopeinstance=Zope2.utilities.mkzopeinstance:main',
'runzope=Zope2.Startup.run:run',
'zopectl=Zope2.Startup.zopectl:run',
'zpasswd=Zope2.utilities.zpasswd:main',
'addzope2user=Zope2.utilities.adduser:main',
],
},
)
Zope-2.13/sources.cfg 0000664 0000000 0000000 00000005330 13037641750 0014527 0 ustar 00root root 0000000 0000000 [remotes]
github = git://github.com/zopefoundation
github_push = git@github.com:zopefoundation
[sources]
AccessControl = git ${remotes:github}/AccessControl pushurl=${remotes:github_push}/AccessControl branch=2.13
Acquisition = git ${remotes:github}/Acquisition pushurl=${remotes:github_push}/Acquisition branch=2.13
DateTime = git ${remotes:github}/DateTime pushurl=${remotes:github_push}/DateTime branch=2.12
DocumentTemplate = git ${remotes:github}/DocumentTemplate pushurl=${remotes:github_push}/DocumentTemplate branch=2.13
ExtensionClass = git ${remotes:github}/ExtensionClass pushurl=${remotes:github_push}/ExtensionClass branch=2.13
initgroups = git ${remotes:github}/initgroups pushurl=${remotes:github_push}/initgroups
Missing = git ${remotes:github}/Missing pushurl=${remotes:github_push}/Missing branch=2.13
MultiMapping = git ${remotes:github}/MultiMapping pushurl=${remotes:github_push}/MultiMapping branch=2.13
nt_svcutils = git ${remotes:github}/nt_svcutils pushurl=${remotes:github_push}/nt_svcutils branch=2.13
Persistence = git ${remotes:github}/Persistence pushurl=${remotes:github_push}/Persistence branch=2.13
Products.BTreeFolder2 = git ${remotes:github}/Products.BTreeFolder2 pushurl=${remotes:github_push}/Products.BTreeFolder2 branch=2.13
Products.ExternalMethod = git ${remotes:github}/Products.ExternalMethod pushurl=${remotes:github_push}/Products.ExternalMethod branch=2.13
Products.MailHost = git ${remotes:github}/Products.MailHost pushurl=${remotes:github_push}/Products.MailHost branch=2.13
Products.MIMETools = git ${remotes:github}/Products.MIMETools pushurl=${remotes:github_push}/Products.MIMETools branch=2.13
Products.OFSP = git ${remotes:github}/Products.OFSP pushurl=${remotes:github_push}/Products.OFSP branch=2.13
Products.PythonScripts = git ${remotes:github}/Products.PythonScripts pushurl=${remotes:github_push}/Products.PythonScripts branch=2.13
Products.StandardCacheManagers = git ${remotes:github}/Products.StandardCacheManagers pushurl=${remotes:github_push}/Products.StandardCacheManagers branch=2.13
Products.ZCatalog = git ${remotes:github}/Products.ZCatalog pushurl=${remotes:github_push}/Products.ZCatalog branch=2.13
Products.ZCTextIndex = git ${remotes:github}/Products.ZCTextIndex pushurl=${remotes:github_push}/Products.ZCTextIndex branch=2.13
Record = git ${remotes:github}/Record pushurl=${remotes:github_push}/Record branch=2.13
tempstorage = git ${remotes:github}/tempstorage pushurl=${remotes:github_push}/tempstorage branch=2.12
zExceptions = git ${remotes:github}/zExceptions pushurl=${remotes:github_push}/zExceptions branch=2.13
zLOG = git ${remotes:github}/zLOG pushurl=${remotes:github_push}/zLOG branch=2.11
ZopeUndo = git ${remotes:github}/ZopeUndo pushurl=${remotes:github_push}/ZopeUndo branch=2.12
Zope-2.13/src/ 0000775 0000000 0000000 00000000000 13037641750 0013151 5 ustar 00root root 0000000 0000000 Zope-2.13/src/App/ 0000775 0000000 0000000 00000000000 13037641750 0013671 5 ustar 00root root 0000000 0000000 Zope-2.13/src/App/ApplicationManager.py 0000664 0000000 0000000 00000034270 13037641750 0020007 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""System management components"""
from cgi import escape
from cStringIO import StringIO
from logging import getLogger
import os
import sys
import time
import urllib
from AccessControl.class_init import InitializeClass
from AccessControl.requestmethod import requestmethod
from AccessControl.SecurityManagement import getSecurityManager
from Acquisition import Implicit
from App.CacheManager import CacheManager
from App.config import getConfiguration
from App.DavLockManager import DavLockManager
from App.special_dtml import DTMLFile
from App.Undo import UndoSupport
from App.version_txt import version_txt
from DateTime.DateTime import DateTime
from Lifetime import shutdown
from OFS.Folder import Folder
from OFS.SimpleItem import Item
from OFS.SimpleItem import SimpleItem
from Product import ProductFolder
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from zExceptions import Redirect
from ZPublisher import Publish
LOG = getLogger('ApplicationManager')
try:
from thread import get_ident
except ImportError:
def get_ident():
return 0
class DatabaseManager(Item, Implicit):
"""Database management (legacy)
"""
manage = manage_main = DTMLFile('dtml/dbMain', globals())
manage_main._setName('manage_main')
id = 'DatabaseManagement'
name = title = 'Database Management'
meta_type = 'Database Management'
icon = 'p_/DatabaseManagement_icon'
manage_options=((
{'label':'Database', 'action':'manage_main'},
{'label':'Activity', 'action':'manage_activity'},
{'label':'Cache Parameters', 'action':'manage_cacheParameters'},
{'label':'Flush Cache', 'action':'manage_cacheGC'},
))
# These need to be here rather to make tabs work correctly. This
# needs to be revisited.
manage_activity = DTMLFile('dtml/activity', globals())
manage_cacheParameters = DTMLFile('dtml/cacheParameters', globals())
manage_cacheGC = DTMLFile('dtml/cacheGC', globals())
InitializeClass(DatabaseManager)
class FakeConnection:
# Supports the methods of Connection that CacheManager needs
def __init__(self, db, parent_jar):
self._db = db
def db(self):
return self._db
class DatabaseChooser(SimpleItem):
""" Choose which database to view
"""
meta_type = 'Database Management'
name = title = 'Database Management'
icon = 'p_/DatabaseManagement_icon'
isPrincipiaFolderish = 1
manage_options=(
{'label':'Databases', 'action':'manage_main'},
)
manage_main = PageTemplateFile('www/chooseDatabase.pt', globals())
def __init__(self, id):
self.id = id
def getDatabaseNames(self, quote=False):
configuration = getConfiguration()
names = configuration.dbtab.listDatabaseNames()
names.sort()
if quote:
return [(name, urllib.quote(name)) for name in names]
return names
def __getitem__(self, name):
configuration = getConfiguration()
db = configuration.dbtab.getDatabase(name=name)
m = AltDatabaseManager()
m.id = name
m._p_jar = FakeConnection(db, self.getPhysicalRoot()._p_jar)
return m.__of__(self)
def __bobo_traverse__(self, request, name):
configuration = getConfiguration()
if configuration.dbtab.hasDatabase(name):
return self[name]
return getattr(self, name)
def tpValues(self):
names = self.getDatabaseNames()
res = []
for name in names:
m = AltDatabaseManager()
m.id = name
# Avoid opening the database just for the tree widget.
m._p_jar = None
res.append(m.__of__(self))
return res
InitializeClass(DatabaseChooser)
# refcount snapshot info
_v_rcs = None
_v_rst = None
class DebugManager(Item, Implicit):
""" Debug and profiling information
"""
manage = manage_main = DTMLFile('dtml/debug', globals())
manage_main._setName('manage_main')
id ='DebugInfo'
name = title = 'Debug Information'
meta_type = name
icon = 'p_/DebugManager_icon'
manage_options=((
{'label':'Debugging Info', 'action':'manage_main'},
{'label':'Profiling', 'action':'manage_profile'},
))
manage_debug = DTMLFile('dtml/debug', globals())
def refcount(self, n=None, t=(type(Implicit), )):
# return class reference info
counts = {}
for m in sys.modules.values():
if m is None:
continue
if 'six.' in m.__name__:
continue
for sym in dir(m):
ob = getattr(m, sym)
if type(ob) in t:
counts[ob] = sys.getrefcount(ob)
pairs = []
for ob, v in counts.items():
if hasattr(ob, '__module__'):
name = '%s.%s' % (ob.__module__, ob.__name__)
else:
name = '%s' % ob.__name__
pairs.append((v, name))
pairs.sort()
pairs.reverse()
if n is not None:
pairs = pairs[:n]
return pairs
def refdict(self):
counts = {}
for v, n in self.refcount():
counts[n] = v
return counts
def rcsnapshot(self):
global _v_rcs
global _v_rst
_v_rcs = self.refdict()
_v_rst = DateTime()
def rcdate(self):
return _v_rst
def rcdeltas(self):
if _v_rcs is None:
self.rcsnapshot()
nc = self.refdict()
rc = _v_rcs
rd = []
for n, c in nc.items():
try:
prev = rc.get(n, 0)
if c > prev:
rd.append((c - prev, (c, prev, n)))
except Exception:
pass
rd.sort()
rd.reverse()
return [{'name': n[1][2],
'delta': n[0],
'pc': n[1][1],
'rc': n[1][0],
} for n in rd]
def dbconnections(self):
import Globals # for data
return Globals.DB.connectionDebugInfo()
# Profiling support
manage_profile = DTMLFile('dtml/profile', globals())
def manage_profile_stats(self, sort='time',
limit=200, stripDirs=1, mode='stats'):
"""Return profile data if available
"""
stats = getattr(sys, '_ps_', None)
if stats is None:
return None
if stripDirs:
from copy import copy
stats = copy(stats)
stats.strip_dirs()
stats.sort_stats(sort)
stats.stream = output = StringIO()
getattr(stats, 'print_%s' % mode)(limit)
return output.getvalue()
def manage_profile_reset(self):
""" Reset profile data
"""
Publish._pstat = sys._ps_ = None
def manage_getSysPath(self):
return list(sys.path)
InitializeClass(DebugManager)
class ApplicationManager(Folder,CacheManager):
"""System management
"""
__roles__ = ('Manager',)
isPrincipiaFolderish = 1
Database = DatabaseChooser('Database') #DatabaseManager()
DebugInfo = DebugManager()
DavLocks = DavLockManager()
manage = manage_main = DTMLFile('dtml/cpContents', globals())
manage_main._setName('manage_main')
_objects=(
{'id': 'Database',
'meta_type': Database.meta_type},
{'id': 'DavLocks',
'meta_type': DavLocks.meta_type},
{'id': 'Products',
'meta_type': 'Product Management'},
{'id': 'DebugInfo',
'meta_type': DebugInfo.meta_type},
)
manage_options=(
({'label':'Contents', 'action':'manage_main'}, ) +
UndoSupport.manage_options
)
id = 'Control_Panel'
name = title = 'Control Panel'
meta_type = 'Control Panel'
icon = 'p_/ControlPanel_icon'
process_id = os.getpid()
process_start = int(time.time())
# Disable some inappropriate operations
manage_addObject = None
manage_delObjects = None
manage_addProperty = None
manage_editProperties = None
manage_delProperties = None
def __init__(self):
self.Products = ProductFolder()
def _canCopy(self, op=0):
return 0
def _init(self):
pass
def version_txt(self):
if not hasattr(self, '_v_version_txt'):
self._v_version_txt = version_txt()
return self._v_version_txt
def sys_version(self):
return sys.version
def sys_platform(self):
return sys.platform
def manage_app(self, URL2):
"""Return to the main management screen"""
raise Redirect, URL2+'/manage'
def process_time(self, _when=None):
if _when is None:
_when = time.time()
s = int(_when) - self.process_start
d = int(s / 86400)
s = s - (d * 86400)
h = int(s / 3600)
s = s -(h * 3600)
m = int(s / 60)
s = s - (m * 60)
d = d and ('%d day%s' % (d, (d != 1 and 's' or ''))) or ''
h = h and ('%d hour%s' % (h, (h != 1 and 's' or ''))) or ''
m = m and ('%d min' % m) or ''
s = '%d sec' % s
return '%s %s %s %s' % (d, h, m, s)
def thread_get_ident(self):
return get_ident()
def db_name(self):
return self._p_jar.db().getName()
def db_size(self):
s = self._p_jar.db().getSize()
if type(s) is str:
return s
if s >= 1048576.0:
return '%.1fM' % (s/1048576.0)
return '%.1fK' % (s/1024.0)
if 'ZMANAGED' in os.environ:
manage_restartable = 1
@requestmethod('POST')
def manage_restart(self, URL1, REQUEST=None):
""" Shut down the application for restart.
"""
try:
user = '"%s"' % getSecurityManager().getUser().getUserName()
except:
user = 'unknown user'
LOG.info("Restart requested by %s" % user)
shutdown(1)
return """
Zope is restarting
""" % escape(URL1, 1)
@requestmethod('POST')
def manage_shutdown(self, REQUEST=None):
"""Shut down the application"""
try:
user = '"%s"' % getSecurityManager().getUser().getUserName()
except:
user = 'unknown user'
LOG.info("Shutdown requested by %s" % user)
shutdown(0)
return """
Zope is shutting down
"""
@requestmethod('POST')
def manage_pack(self, days=0, REQUEST=None, _when=None):
"""Pack the database"""
if _when is None:
_when = time.time()
t = _when - (days * 86400)
db = self._p_jar.db()
t = db.pack(t)
if REQUEST is not None:
REQUEST['RESPONSE'].redirect(
REQUEST['URL1'] + '/manage_workspace')
return t
def revert_points(self):
return ()
def version_list(self):
# Return a list of currently installed products/versions
cfg = getConfiguration()
product_dir = os.path.join(cfg.softwarehome,'Products')
product_names = os.listdir(product_dir)
product_names.sort()
info = []
for product_name in product_names:
package_dir = os.path.join(product_dir, product_name)
if not os.path.isdir(package_dir):
continue
version_txt = None
for name in ('VERSION.TXT', 'VERSION.txt', 'version.txt'):
v = os.path.join(package_dir, name)
if os.path.exists(v):
version_txt = v
break
if version_txt is not None:
file = open(version_txt, 'r')
data = file.readline()
file.close()
info.append(data.strip())
return info
def getSOFTWARE_HOME(self):
cfg = getConfiguration()
return getattr(cfg, 'softwarehome', None)
def getZOPE_HOME(self):
cfg = getConfiguration()
return getattr(cfg, 'zopehome', None)
def getINSTANCE_HOME(self):
return getConfiguration().instancehome
def getCLIENT_HOME(self):
return getConfiguration().clienthome
def getServers(self):
# used only for display purposes
# return a sequence of two-tuples. The first element of
# each tuple is the service name, the second is a string repr. of
# the port/socket/other on which it listens
from asyncore import socket_map
l = []
for k,v in socket_map.items():
# this is only an approximation
if hasattr(v, 'port'):
type = str(getattr(v, '__class__', 'unknown'))
port = v.port
l.append((str(type), 'Port: %s' % port))
return l
def objectIds(self, spec=None):
""" this is a patch for pre-2.4 Zope installations. Such
installations don't have an entry for the WebDAV LockManager
introduced in 2.4.
"""
meta_types = [x.get('meta_type', None) for x in self._objects]
if not self.DavLocks.meta_type in meta_types:
lst = list(self._objects)
lst.append({'id': 'DavLocks',
'meta_type': self.DavLocks.meta_type})
self._objects = tuple(lst)
return Folder.objectIds(self, spec)
class AltDatabaseManager(DatabaseManager, CacheManager):
""" Database management DBTab-style
"""
db_name = ApplicationManager.db_name.im_func
db_size = ApplicationManager.db_size.im_func
manage_pack = ApplicationManager.manage_pack.im_func
Zope-2.13/src/App/CacheManager.py 0000664 0000000 0000000 00000021324 13037641750 0016543 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
'''Cache management support.
This class is mixed into the database manager in App.ApplicationManager.
'''
from AccessControl.class_init import InitializeClass
from App.special_dtml import DTMLFile
from App.ImageFile import ImageFile
from DateTime.DateTime import DateTime
class CacheManager:
"""Cache management mix-in
"""
_cache_age = 60
_vcache_age = 60
_history_length = 3600 # Seconds
manage_cacheParameters = DTMLFile('dtml/cacheParameters', globals())
manage_cacheGC = DTMLFile('dtml/cacheGC', globals())
transparent_bar = ImageFile('www/transparent_bar.gif', globals())
store_bar = ImageFile('www/store_bar.gif', globals())
load_bar = ImageFile('www/load_bar.gif', globals())
def _getDB(self):
return self._p_jar.db()
def cache_length(self):
return self._getDB().cacheSize()
def cache_length_bytes(self):
return self._getDB().getCacheSizeBytes()
def cache_detail_length(self):
return self._getDB().cacheDetailSize()
def database_size(self):
return self._getDB().objectCount()
def cache_age(self):
return self._cache_age
def manage_cache_age(self,value,REQUEST):
"set cache age"
db = self._getDB()
self._cache_age = value
db.setCacheDeactivateAfter(value)
if REQUEST is not None:
response=REQUEST['RESPONSE']
response.redirect(REQUEST['URL1']+'/manage_cacheParameters')
def cache_size(self):
db = self._getDB()
return db.getCacheSize()
def manage_cache_size(self,value,REQUEST):
"set cache size"
db = self._getDB()
db.setCacheSize(value)
if REQUEST is not None:
response=REQUEST['RESPONSE']
response.redirect(REQUEST['URL1']+'/manage_cacheParameters')
def manage_full_sweep(self,value,REQUEST):
"Perform a full sweep through the cache"
db = self._getDB()
db.cacheFullSweep(value)
if REQUEST is not None:
response=REQUEST['RESPONSE']
response.redirect(REQUEST['URL1']+'/manage_cacheGC')
def manage_minimize(self,value=1,REQUEST=None):
"Perform a full sweep through the cache"
# XXX Add a deprecation warning about value?
self._getDB().cacheMinimize()
if REQUEST is not None:
response=REQUEST['RESPONSE']
response.redirect(REQUEST['URL1']+'/manage_cacheGC')
def cache_detail(self, REQUEST=None):
"""
Returns the name of the classes of the objects in the cache
and the number of objects in the cache for each class.
"""
detail = self._getDB().cacheDetail()
if REQUEST is not None:
# format as text
REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain')
return '\n'.join(
['%6d %s' % (count, name) for name, count in detail])
# raw
return detail
def cache_extreme_detail(self, REQUEST=None):
"""
Returns information about each object in the cache.
"""
detail = self._getDB().cacheExtremeDetail()
if REQUEST is not None:
# sort the list.
lst = [((dict['conn_no'], dict['oid']), dict) for dict in detail]
# format as text.
res = [
'# Table shows connection number, oid, refcount, state, '
'and class.',
'# States: L = loaded, G = ghost, C = changed']
for sortkey, dict in lst:
id = dict.get('id', None)
if id:
idinfo = ' (%s)' % id
else:
idinfo = ''
s = dict['state']
if s == 0:
state = 'L' # loaded
elif s == 1:
state = 'C' # changed
else:
state = 'G' # ghost
res.append('%d %-34s %6d %s %s%s' % (
dict['conn_no'], `dict['oid']`, dict['rc'],
state, dict['klass'], idinfo))
REQUEST.RESPONSE.setHeader('Content-Type', 'text/plain')
return '\n'.join(res)
else:
# raw
return detail
def _getActivityMonitor(self):
db = self._getDB()
if not hasattr(db, 'getActivityMonitor'):
return None
am = db.getActivityMonitor()
if am is None:
return None
return am
def getHistoryLength(self):
am = self._getActivityMonitor()
if am is None:
return 0
return am.getHistoryLength()
def manage_setHistoryLength(self, length, REQUEST=None):
"""Change the length of the activity monitor history.
"""
am = self._getActivityMonitor()
length = int(length)
if length < 0:
raise ValueError, 'length can not be negative'
if am is not None:
am.setHistoryLength(length)
self._history_length = length # Restore on startup
if REQUEST is not None:
response = REQUEST['RESPONSE']
response.redirect(REQUEST['URL1'] + '/manage_activity')
def getActivityChartData(self, segment_height, REQUEST=None):
"""Returns information for generating an activity chart.
"""
am = self._getActivityMonitor()
if am is None:
return None
if REQUEST is not None:
start = float(REQUEST.get('chart_start', 0))
end = float(REQUEST.get('chart_end', 0))
divisions = int(REQUEST.get('chart_divisions', 10))
analysis = am.getActivityAnalysis(start, end, divisions)
else:
analysis = am.getActivityAnalysis()
total_load_count = 0
total_store_count = 0
total_connections = 0
limit = 0
divs = []
for div in analysis:
total_store_count = total_store_count + div['stores']
total_load_count = total_load_count + div['loads']
total_connections = total_connections + div['connections']
sum = div['stores'] + div['loads']
if sum > limit:
limit = sum
if analysis:
segment_time = analysis[0]['end'] - analysis[0]['start']
else:
segment_time = 0
for div in analysis:
stores = div['stores']
if stores > 0:
store_len = max(int(segment_height * stores / limit), 1)
else:
store_len = 0
loads = div['loads']
if loads > 0:
load_len = max(int(segment_height * loads / limit), 1)
else:
load_len = 0
t = div['end'] - analysis[-1]['end'] # Show negative numbers.
if segment_time >= 3600:
# Show hours.
time_offset = '%dh' % (t / 3600)
elif segment_time >= 60:
# Show minutes.
time_offset = '%dm' % (t / 60)
elif segment_time >= 1:
# Show seconds.
time_offset = '%ds' % t
else:
# Show fractions.
time_offset = '%.2fs' % t
divs.append({
'store_len': store_len,
'load_len': load_len,
'trans_len': max(segment_height - store_len - load_len, 0),
'store_count': div['stores'],
'load_count': div['loads'],
'connections': div['connections'],
'start': div['start'],
'end': div['end'],
'time_offset': time_offset,
})
if analysis:
start_time = DateTime(divs[0]['start']).aCommonZ()
end_time = DateTime(divs[-1]['end']).aCommonZ()
else:
start_time = ''
end_time = ''
res = {'start_time': start_time,
'end_time': end_time,
'divs': divs,
'total_store_count': total_store_count,
'total_load_count': total_load_count,
'total_connections': total_connections,
}
return res
InitializeClass(CacheManager)
Zope-2.13/src/App/Common.py 0000664 0000000 0000000 00000011011 13037641750 0015465 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Commonly used utility functions."""
import os
import sys
import time
# Legacy API for this module; 3rd party code may use this.
from os.path import realpath
# These are needed because the various date formats below must
# be in english per the RFCs. That means we can't use strftime,
# which is affected by different locale settings.
weekday_abbr = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
weekday_full = ['Monday', 'Tuesday', 'Wednesday', 'Thursday',
'Friday', 'Saturday', 'Sunday']
monthname = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
def iso8601_date(ts=None):
# Return an ISO 8601 formatted date string, required
# for certain DAV properties.
# '2000-11-10T16:21:09-08:00
if ts is None: ts=time.time()
return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(ts))
def rfc850_date(ts=None):
# Return an HTTP-date formatted date string.
# 'Friday, 10-Nov-00 16:21:09 GMT'
if ts is None: ts=time.time()
year, month, day, hh, mm, ss, wd, y, z = time.gmtime(ts)
return "%s, %02d-%3s-%2s %02d:%02d:%02d GMT" % (
weekday_full[wd],
day, monthname[month],
str(year)[2:],
hh, mm, ss)
def rfc1123_date(ts=None):
# Return an RFC 1123 format date string, required for
# use in HTTP Date headers per the HTTP 1.1 spec.
# 'Fri, 10 Nov 2000 16:21:09 GMT'
if ts is None: ts=time.time()
year, month, day, hh, mm, ss, wd, y, z = time.gmtime(ts)
return "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (weekday_abbr[wd],
day, monthname[month],
year,
hh, mm, ss)
def absattr(attr, callable=callable):
# Return the absolute value of an attribute,
# calling the attr if it is callable.
if callable(attr):
return attr()
return attr
def aq_base(ob, getattr=getattr):
# Return the aq_base of an object.
return getattr(ob, 'aq_base', ob)
def is_acquired(ob, hasattr=hasattr, aq_base=aq_base, absattr=absattr):
# Return true if this object is not considered to be
# a direct subobject of its acquisition parent
# Used to prevent acquisition side-affects in FTP traversal
# Note that this method is misnamed since parents can (and do)
# spoof it. It is not a true measure of whether something is
# acquired, it relies on the parent's parent-ness exclusively
if not hasattr(ob, 'aq_parent'):
# We can't be acquired if we don't have an aq_parent
return 0
parent = aq_base(ob.aq_parent)
absId = absattr(ob.id)
if hasattr(parent, absId):
# Consider direct attributes not acquired
return 0
if hasattr(parent, '__getitem__'):
# Use __getitem__ as opposed to has_key to avoid TTW namespace
# issues, and to support the most minimal mapping objects
try:
# We assume that getitem will not acquire which
# is the standard behavior for Zope objects
if aq_base(ob.aq_parent[absId]) is aq_base(ob):
# This object is an item of the aq_parent, its not acquired
return 0
except KeyError:
pass
if hasattr(aq_base(ob), 'isTopLevelPrincipiaApplicationObject') and \
ob.isTopLevelPrincipiaApplicationObject:
# This object the top level
return 0
return 1 # This object is acquired by our measure
def package_home(globals_dict):
__name__=globals_dict['__name__']
m=sys.modules[__name__]
if hasattr(m,'__path__'):
r=m.__path__[0]
elif "." in __name__:
r=sys.modules[__name__[:__name__.rfind('.')]].__path__[0]
else:
r=__name__
return os.path.abspath(r)
# We really only want the 3-argument version of getattr:
attrget = getattr
def Dictionary(**kw): return kw # Sorry Guido
Zope-2.13/src/App/DavLockManager.py 0000664 0000000 0000000 00000007642 13037641750 0017072 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
from AccessControl.class_init import InitializeClass
from AccessControl.SecurityInfo import ClassSecurityInfo
from Acquisition import aq_base
from Acquisition import Implicit
from App.special_dtml import DTMLFile
from OFS.SimpleItem import Item
from webdav.Lockable import wl_isLocked
class DavLockManager(Item, Implicit):
id = 'DavLockManager'
name = title = 'WebDAV Lock Manager'
meta_type = 'WebDAV Lock Manager'
icon = 'p_/davlocked'
security = ClassSecurityInfo()
security.declareProtected('Manage WebDAV Locks',
'findLockedObjects', 'manage_davlocks',
'manage_unlockObjects')
security.declarePrivate('unlockObjects')
manage_davlocks = manage_main = manage = DTMLFile(
'dtml/davLockManager', globals())
manage_davlocks._setName('manage_davlocks')
manage_options = ({'label': 'Write Locks', 'action': 'manage_main'}, )
def findLockedObjects(self, frompath=''):
app = self.getPhysicalRoot()
if frompath:
if frompath[0] == '/':
frompath = frompath[1:]
# since the above will turn '/' into an empty string, check
# for truth before chopping a final slash
if frompath and frompath[-1] == '/':
frompath= frompath[:-1]
# Now we traverse to the node specified in the 'frompath' if
# the user chose to filter the search, and run a ZopeFind with
# the expression 'wl_isLocked()' to find locked objects.
obj = app.unrestrictedTraverse(frompath)
lockedobjs = self._findapply(obj, path=frompath)
return lockedobjs
def unlockObjects(self, paths=[]):
app = self.getPhysicalRoot()
for path in paths:
ob = app.unrestrictedTraverse(path)
ob.wl_clearLocks()
def manage_unlockObjects(self, paths=[], REQUEST=None):
" Management screen action to unlock objects. "
if paths:
self.unlockObjects(paths)
if REQUEST is not None:
m = '%s objects unlocked.' % len(paths)
return self.manage_davlocks(self, REQUEST, manage_tabs_message=m)
def _findapply(self, obj, result=None, path=''):
# recursive function to actually dig through and find the locked
# objects.
if result is None:
result = []
base = aq_base(obj)
if not hasattr(base, 'objectItems'):
return result
try:
items = obj.objectItems()
except Exception:
return result
addresult = result.append
for id, ob in items:
if path:
p = '%s/%s' % (path, id)
else:
p = id
dflag = hasattr(ob, '_p_changed') and (ob._p_changed == None)
bs = aq_base(ob)
if wl_isLocked(ob):
li = []
addlockinfo = li.append
for token, lock in ob.wl_lockItems():
addlockinfo({'owner': lock.getCreatorPath(),
'token': token})
addresult((p, li))
dflag = 0
if hasattr(bs, 'objectItems'):
self._findapply(ob, result, p)
if dflag:
ob._p_deactivate()
return result
InitializeClass(DavLockManager)
Zope-2.13/src/App/Dialogs.py 0000664 0000000 0000000 00000004111 13037641750 0015622 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Common HTML dialog boxes
MessageDialog(title, message, action, [target])
A very simple dialog used to display an HTML page titled title,
displaying message message and an OK button. Clicking the OK
button will take the browser to the URL specified in action.
The *optional* target argument can be used to force a (frames
capable) browser to load the URL specified in action into a specific
frame. (Specifying '_new' will cause the browser to load the
specified URL into a new window, for example).
example usage:
return MessageDialog(title='Just thought you should know...',
message='You have wiped out your data.',
action='/paid_tech_support/prices.html',
target='_top')
"""
from App.special_dtml import HTML
MessageDialog = HTML("""
&dtml-title;
""", target='', action='manage_main', title='Changed')
Zope-2.13/src/App/Extensions.py 0000664 0000000 0000000 00000015463 13037641750 0016413 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Standard routines for handling extensions.
Extensions currently include external methods and pluggable brains.
"""
import imp
import os
import Products
from zExceptions import NotFound
class FuncCode:
def __init__(self, f, im=0):
self.co_varnames = f.func_code.co_varnames[im:]
self.co_argcount = f.func_code.co_argcount - im
def __cmp__(self, other):
if other is None:
return 1
try:
return cmp((self.co_argcount, self.co_varnames),
(other.co_argcount, other.co_varnames))
except:
return 1
def _getPath(home, prefix, name, suffixes):
dir = os.path.join(home, prefix)
if dir == prefix:
raise ValueError('The prefix, %s, should be a relative path' % prefix)
fn = os.path.join(dir, name)
if fn == name:
# Paranoia
raise ValueError('The file name, %s, should be a simple file name'
% name)
for suffix in suffixes:
if suffix:
fqn = "%s.%s" % (fn, suffix)
else:
fqn = fn
if os.path.exists(fqn):
return fqn
def getPath(prefix, name, checkProduct=1, suffixes=('',), cfg=None):
"""Find a file in one of several relative locations
Arguments:
prefix -- The location, relative to some home, to look for the
file
name -- The name of the file. This must not be a path.
checkProduct -- a flag indicating whether product directories
should be used as additional hope ares to be searched. This
defaults to a true value.
If this is true and the name contains a dot, then the
text before the dot is treated as a product name and
the product package directory is used as anothe rhome.
suffixes -- a sequences of file suffixes to check.
By default, the name is used without a suffix.
cfg -- ease testing (not part of the API)
The search takes on multiple homes which are the instance home,
the directory containing the directory containing the software
home, and possibly product areas.
"""
dir, ignored = os.path.split(name)
if dir:
raise ValueError('The file name, %s, should be a simple file name'
% name)
result = None
if checkProduct:
dot = name.find('.')
if dot > 0:
product = name[:dot]
extname = name[dot + 1:]
for product_dir in Products.__path__:
found = _getPath(product_dir, os.path.join(product, prefix),
extname, suffixes)
if found is not None:
return found
if cfg is None:
import App.config
cfg = App.config.getConfiguration()
if prefix == "Extensions" and getattr(cfg, 'extensions', None) is not None:
found = _getPath(cfg.extensions, '', name, suffixes)
if found is not None:
return found
locations = [cfg.instancehome]
softwarehome = getattr(cfg, 'softwarehome', None)
if softwarehome is not None:
zopehome = os.path.dirname(softwarehome)
locations.append(zopehome)
for home in locations:
found = _getPath(home, prefix, name, suffixes)
if found is not None:
return found
try:
dot = name.rfind('.')
if dot > 0:
realName = name[dot+1:]
toplevel = name[:dot]
rdot = toplevel.rfind('.')
if rdot > -1:
module = __import__(toplevel, globals(), {}, toplevel[rdot+1:])
else:
module = __import__(toplevel)
prefix = os.path.join(module.__path__[0], prefix, realName)
for suffix in suffixes:
if suffix:
fn = "%s.%s" % (prefix, suffix)
else:
fn = prefix
if os.path.exists(fn):
return fn
except:
pass
def getObject(module, name, reload=0,
# The use of a mutable default is intentional here,
# because modules is a module cache.
modules={}
):
# The use of modules here is not thread safe, however, there is
# no real harm in a race condition here. If two threads
# update the cache, then one will have simply worked a little
# harder than need be. So, in this case, we won't incur
# the expense of a lock.
old = modules.get(module)
if old is not None and name in old and not reload:
return old[name]
base, ext = os.path.splitext(module)
if ext in ('py', 'pyc'):
# XXX should never happen; splitext() keeps '.' with the extension
prefix = base
else:
prefix = module
path = getPath('Extensions', prefix, suffixes=('','py','pyc'))
if path is None:
raise NotFound("The specified module, '%s', couldn't be found."
% module)
__traceback_info__= path, module
base, ext = os.path.splitext(path)
if ext=='.pyc':
file = open(path, 'rb')
binmod = imp.load_compiled('Extension', path, file)
file.close()
module_dict = binmod.__dict__
else:
try:
execsrc = open(path)
except:
raise NotFound("The specified module, '%s', "
"couldn't be opened." % module)
module_dict = {}
exec execsrc in module_dict
if old is not None:
# XXX Accretive??
old.update(module_dict)
else:
modules[module] = module_dict
try:
return module_dict[name]
except KeyError:
raise NotFound("The specified object, '%s', was not found "
"in module, '%s'." % (name, module))
class NoBrains:
pass
def getBrain(module, class_name, reload=0, modules=None):
""" Check/load a class from an extension.
"""
if not module and not class_name:
return NoBrains
if modules is None:
c=getObject(module, class_name, reload)
else:
c=getObject(module, class_name, reload, modules=modules)
if getattr(c, '__bases__', None) is None:
raise ValueError('%s, is not a class' % class_name)
return c
Zope-2.13/src/App/FactoryDispatcher.py 0000664 0000000 0000000 00000012155 13037641750 0017665 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
# Implement the manage_addProduct method of object managers
import sys
import types
from AccessControl.class_init import InitializeClass
from AccessControl.owner import UnownableOwner
from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.PermissionMapping import aqwrap
from Acquisition import Acquired
from Acquisition import aq_base
from Acquisition import Implicit
from ExtensionClass import Base
from OFS.metaconfigure import get_registered_packages
def _product_packages():
"""Returns all product packages including the regularly defined
zope2 packages and those without the Products namespace package.
"""
import Products
packages = {}
for x in dir(Products):
m = getattr(Products, x)
if isinstance(m, types.ModuleType):
packages[x] = m
for m in get_registered_packages():
packages[m.__name__] = m
return packages
class Product(Base):
"""Model a non-persistent product wrapper.
"""
security = ClassSecurityInfo()
meta_type='Product'
icon='p_/Product_icon'
version=''
configurable_objects_=()
import_error_=None
thisIsAnInstalledProduct = True
title = 'This is a non-persistent product wrapper.'
def __init__(self, id):
self.id=id
security.declarePublic('Destination')
def Destination(self):
"Return the destination for factory output"
return self
def getProductHelp(self):
"""Returns the ProductHelp object associated with the Product.
"""
from HelpSys.HelpSys import ProductHelp
return ProductHelp('Help', self.id).__of__(self)
InitializeClass(Product)
class ProductDispatcher(Implicit):
" "
# Allow access to factory dispatchers
__allow_access_to_unprotected_subobjects__=1
def __getitem__(self, name):
return self.__bobo_traverse__(None, name)
def __bobo_traverse__(self, REQUEST, name):
# Try to get a custom dispatcher from a Python product
dispatcher_class=getattr(
_product_packages().get(name, None),
'__FactoryDispatcher__',
FactoryDispatcher)
productfolder = self.aq_acquire('_getProducts')()
try:
product = productfolder._product(name)
except AttributeError:
# If we do not have a persistent product entry, return
product = Product(name)
dispatcher=dispatcher_class(product, self.aq_parent, REQUEST)
return dispatcher.__of__(self)
class FactoryDispatcher(Implicit):
"""Provide a namespace for product "methods"
"""
security = ClassSecurityInfo()
_owner=UnownableOwner
def __init__(self, product, dest, REQUEST=None):
product = aq_base(product)
self._product=product
self._d=dest
if REQUEST is not None:
try:
v=REQUEST['URL']
except KeyError: pass
else:
v=v[:v.rfind('/')]
self._u=v[:v.rfind('/')]
security.declarePublic('Destination')
def Destination(self):
"Return the destination for factory output"
return self.__dict__['_d'] # we don't want to wrap the result!
security.declarePublic('this')
this=Destination
security.declarePublic('DestinationURL')
def DestinationURL(self):
"Return the URL for the destination for factory output"
url=getattr(self, '_u', None)
if url is None:
url=self.Destination().absolute_url()
return url
def __getattr__(self, name):
p=self.__dict__['_product']
d=p.__dict__
if hasattr(p,name) and d.has_key(name):
m=d[name]
w=getattr(m, '_permissionMapper', None)
if w is not None:
m=aqwrap(m, aq_base(w), self)
return m
# Waaa
m = 'Products.%s' % p.id
if sys.modules.has_key(m) and sys.modules[m]._m.has_key(name):
return sys.modules[m]._m[name]
raise AttributeError, name
# Provide acquired indicators for critical OM methods:
_setObject = _getOb = Acquired
# Make sure factory methods are unowned:
_owner=UnownableOwner
# Provide a replacement for manage_main that does a redirection:
def manage_main(trueself, self, REQUEST, update_menu=0):
"""Implement a contents view by redirecting to the true view
"""
d = update_menu and '/manage_main?update_menu=1' or '/manage_main'
REQUEST['RESPONSE'].redirect(self.DestinationURL()+d)
InitializeClass(FactoryDispatcher)
Zope-2.13/src/App/FindHomes.py 0000664 0000000 0000000 00000005367 13037641750 0016132 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Stick directory information in the built-in namespace."""
import __builtin__
import os
import sys
import Products
try:
home = os.environ['SOFTWARE_HOME']
except KeyError:
pass
else:
home = os.path.realpath(home)
__builtin__.SOFTWARE_HOME = SOFTWARE_HOME = home
try:
zhome = os.environ['ZOPE_HOME']
except KeyError:
pass
else:
zhome = os.path.realpath(zhome)
__builtin__.ZOPE_HOME = ZOPE_HOME = zhome
try:
chome = os.environ['INSTANCE_HOME']
except KeyError:
import Zope2
base = os.path.dirname(Zope2.__file__)
base = os.path.join(base, os.path.pardir, os.path.pardir)
chome = os.path.realpath(base)
else:
chome = os.path.realpath(chome)
inst_ppath = os.path.join(chome, 'lib', 'python')
if os.path.isdir(inst_ppath):
sys.path.insert(0, inst_ppath)
__builtin__.INSTANCE_HOME = INSTANCE_HOME = chome
# CLIENT_HOME allows ZEO clients to easily keep distinct pid and
# log files. This is currently an *experimental* feature, as I expect
# that increasing ZEO deployment will cause bigger changes to the
# way that z2.py works fairly soon.
try:
CLIENT_HOME = os.environ['CLIENT_HOME']
except KeyError:
CLIENT_HOME = os.path.join(INSTANCE_HOME, 'var')
__builtin__.CLIENT_HOME = CLIENT_HOME
# If there is a Products package in INSTANCE_HOME, add it to the
# Products package path
ip = os.path.join(INSTANCE_HOME, 'Products')
ippart = 0
ppath = Products.__path__
if os.path.isdir(ip) and ip not in ppath:
disallow = os.environ.get('DISALLOW_LOCAL_PRODUCTS', '').lower()
if disallow in ('no', 'off', '0', ''):
ppath.insert(0, ip)
ippart = 1
ppathpat = os.environ.get('PRODUCTS_PATH', None)
if ppathpat is not None:
psep = os.pathsep
if ppathpat.find('%(') >= 0:
newppath = (ppathpat % {
'PRODUCTS_PATH': psep.join(ppath ),
'SOFTWARE_PRODUCTS': psep.join(ppath[ippart:] ),
'INSTANCE_PRODUCTS': ip,
}).split(psep)
else:
newppath = ppathpat.split(psep)
del ppath[:]
for p in filter(None, newppath):
p = os.path.abspath(p)
if os.path.isdir(p) and p not in ppath:
ppath.append(p)
Zope-2.13/src/App/ImageFile.py 0000664 0000000 0000000 00000012465 13037641750 0016075 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Image object that is stored in a file"""
import os
import os.path
import stat
import time
import warnings
from AccessControl.class_init import InitializeClass
from AccessControl.SecurityInfo import ClassSecurityInfo
from Acquisition import Explicit
from App.Common import package_home
from App.Common import rfc1123_date
from App.config import getConfiguration
from DateTime.DateTime import DateTime
from zope.contenttype import guess_content_type
from ZPublisher.Iterators import filestream_iterator
import Zope2
PREFIX = os.path.realpath(
os.path.join(os.path.dirname(Zope2.__file__), os.path.pardir))
NON_PREFIX_WARNING = ('Assuming image location to be present in the Zope2 '
'distribution. This is deprecated and might lead to '
'broken code if the directory in question is moved '
'to another distribution. Please provide either an '
'absolute file system path or a prefix. Support for '
'relative filenames without a prefix might be '
'dropped in a future Zope2 release.')
class ImageFile(Explicit):
"""Image objects stored in external files."""
security = ClassSecurityInfo()
def __init__(self, path, _prefix=None):
import Globals # for data
if _prefix is None:
_prefix=getattr(getConfiguration(), 'softwarehome', None) or PREFIX
if not os.path.isabs(path):
warnings.warn(NON_PREFIX_WARNING, UserWarning, 2)
elif type(_prefix) is not str:
_prefix=package_home(_prefix)
# _prefix is ignored if path is absolute
path = os.path.join(_prefix, path)
self.path=path
if Globals.DevelopmentMode:
# In development mode, a shorter time is handy
max_age = 60 # One minute
else:
# A longer time reduces latency in production mode
max_age = 3600 # One hour
self.cch = 'public,max-age=%d' % max_age
# First try to get the content_type by name
content_type, enc=guess_content_type(path, default='failed')
if content_type == 'failed':
# This failed, lets look into the file content
img = open(path, 'rb')
data = img.read(1024) # 1k should be enough
img.close()
content_type, enc=guess_content_type(path, data)
if content_type:
self.content_type=content_type
else:
ext = os.path.splitext(path)[-1].replace('.', '')
self.content_type = 'image/%s' % ext
self.__name__ = os.path.split(path)[-1]
stat_info = os.stat(path)
self.size = stat_info[stat.ST_SIZE]
self.lmt = float(stat_info[stat.ST_MTIME]) or time.time()
self.lmh = rfc1123_date(self.lmt)
def index_html(self, REQUEST, RESPONSE):
"""Default document"""
# HTTP If-Modified-Since header handling. This is duplicated
# from OFS.Image.Image - it really should be consolidated
# somewhere...
RESPONSE.setHeader('Content-Type', self.content_type)
RESPONSE.setHeader('Last-Modified', self.lmh)
RESPONSE.setHeader('Cache-Control', self.cch)
RESPONSE.setHeader('Content-Length', str(self.size).replace('L', ''))
header = REQUEST.get_header('If-Modified-Since', None)
if header is not None:
header=header.split(';')[0]
# Some proxies seem to send invalid date strings for this
# header. If the date string is not valid, we ignore it
# rather than raise an error to be generally consistent
# with common servers such as Apache (which can usually
# understand the screwy date string as a lucky side effect
# of the way they parse it).
try:
mod_since = long(DateTime(header).timeTime())
except:
mod_since = None
if mod_since is not None:
if getattr(self, 'lmt', None):
last_mod = long(self.lmt)
else:
last_mod = long(0)
if last_mod > 0 and last_mod <= mod_since:
RESPONSE.setStatus(304)
return ''
return filestream_iterator(self.path, mode='rb')
security.declarePublic('HEAD')
def HEAD(self, REQUEST, RESPONSE):
""" """
RESPONSE.setHeader('Content-Type', self.content_type)
RESPONSE.setHeader('Last-Modified', self.lmh)
return ''
def __len__(self):
# This is bogus and needed because of the way Python tests truth.
return 1
def __str__(self):
return '' % self.__name__
InitializeClass(ImageFile)
Zope-2.13/src/App/Management.py 0000664 0000000 0000000 00000015132 13037641750 0016321 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Standard management interface support
"""
from cgi import escape
import sys
import urllib
from zope.interface import implements
from AccessControl import getSecurityManager, Unauthorized
from AccessControl import ClassSecurityInfo
from AccessControl.class_init import InitializeClass
from AccessControl.Permissions import view_management_screens
from App.interfaces import INavigation
from App.special_dtml import HTMLFile
from App.special_dtml import DTMLFile
from ExtensionClass import Base
from zExceptions import Redirect
class Tabs(Base):
"""Mix-in provides management folder tab support."""
security = ClassSecurityInfo()
security.declarePublic('manage_tabs')
manage_tabs=DTMLFile('dtml/manage_tabs', globals())
manage_options =()
security.declarePublic('filtered_manage_options')
def filtered_manage_options(self, REQUEST=None):
validate=getSecurityManager().validate
result=[]
try:
options=tuple(self.manage_options)
except TypeError:
options=tuple(self.manage_options())
for d in options:
filter=d.get('filter', None)
if filter is not None and not filter(self):
continue
path=d.get('path', None)
if path is None:
path=d['action']
o=self.restrictedTraverse(path, None)
if o is None:
continue
result.append(d)
return result
manage_workspace__roles__=('Authenticated',)
def manage_workspace(self, REQUEST):
"""Dispatch to first interface in manage_options
"""
options=self.filtered_manage_options(REQUEST)
try:
m=options[0]['action']
if m=='manage_workspace':
raise TypeError
except (IndexError, KeyError):
raise Unauthorized, (
'You are not authorized to view this object.')
if m.find('/'):
raise Redirect, (
"%s/%s" % (REQUEST['URL1'], m))
return getattr(self, m)(self, REQUEST)
def tabs_path_default(self, REQUEST,
# Static var
unquote=urllib.unquote,
):
steps = REQUEST._steps[:-1]
script = REQUEST['BASEPATH1']
linkpat = '%s'
out = []
url = linkpat % (escape(script, 1), ' /')
if not steps:
return url
last = steps.pop()
for step in steps:
script = '%s/%s' % (script, step)
out.append(linkpat % (escape(script, 1), escape(unquote(step))))
script = '%s/%s' % (script, last)
out.append('%s'%
(escape(script, 1), escape(unquote(last))))
return '%s%s' % (url, '/'.join(out))
def tabs_path_info(self, script, path,
# Static vars
quote=urllib.quote,
):
out=[]
while path[:1]=='/':
path = path[1:]
while path[-1:]=='/':
path = path[:-1]
while script[:1]=='/':
script = script[1:]
while script[-1:]=='/':
script = script[:-1]
path=path.split('/')[:-1]
if script:
path = [script] + path
if not path:
return ''
script=''
last=path[-1]
del path[-1]
for p in path:
script="%s/%s" % (script, quote(p))
out.append('%s' % (script, p))
out.append(last)
return '/'.join(out)
InitializeClass(Tabs)
class Navigation(Base):
"""Basic navigation UI support"""
implements(INavigation)
security = ClassSecurityInfo()
security.declareProtected(view_management_screens, 'manage')
manage =DTMLFile('dtml/manage', globals())
security.declareProtected(view_management_screens, 'manage_menu')
manage_menu =DTMLFile('dtml/menu', globals())
security.declareProtected(view_management_screens, 'manage_top_frame')
manage_top_frame =DTMLFile('dtml/manage_top_frame', globals())
security.declareProtected(view_management_screens, 'manage_page_header')
manage_page_header=DTMLFile('dtml/manage_page_header', globals())
security.declareProtected(view_management_screens, 'manage_page_footer')
manage_page_footer=DTMLFile('dtml/manage_page_footer', globals())
security.declarePublic('manage_form_title')
manage_form_title =DTMLFile('dtml/manage_form_title', globals(),
form_title='Add Form',
help_product=None,
help_topic=None)
manage_form_title._setFuncSignature(
varnames=('form_title', 'help_product', 'help_topic') )
security.declarePublic('zope_quick_start')
zope_quick_start=DTMLFile('dtml/zope_quick_start', globals())
security.declarePublic('manage_copyright')
manage_copyright=DTMLFile('dtml/copyright', globals())
security.declarePublic('manage_zmi_logout')
def manage_zmi_logout(self, REQUEST, RESPONSE):
"""Logout current user"""
p = getattr(REQUEST, '_logout_path', None)
if p is not None:
return apply(self.restrictedTraverse(p))
realm=RESPONSE.realm
RESPONSE.setStatus(401)
RESPONSE.setHeader('WWW-Authenticate', 'basic realm="%s"' % realm, 1)
RESPONSE.setBody("""
Logout
You have been logged out.
""")
return
security.declarePublic('manage_zmi_prefs')
manage_zmi_prefs=DTMLFile('dtml/manage_zmi_prefs', globals())
# Navigation doesn't have an inherited __class_init__ so doesn't get
# initialized automatically.
file = DTMLFile('dtml/manage_page_style.css', globals())
Navigation.security.declarePublic('manage_page_style.css')
setattr(Navigation, 'manage_page_style.css', file)
InitializeClass(Navigation)
Zope-2.13/src/App/Permission.py 0000664 0000000 0000000 00000002616 13037641750 0016400 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
'''Zope registerable permissions
'''
from AccessControl.class_init import InitializeClass
from AccessControl.SecurityInfo import ClassSecurityInfo
from Acquisition import Implicit
from OFS.role import RoleManager
from OFS.SimpleItem import Item
from Persistence import Persistent
class Permission(RoleManager,
Persistent,
Implicit,
Item
):
"""Model Permission meta-data
"""
meta_type = 'Zope Permission'
icon = 'p_/Permission_icon'
index_html = None
security = ClassSecurityInfo()
manage_options=(
RoleManager.manage_options
+ Item.manage_options
)
def __init__(self, id, title, name):
self.id=id
self.title=title
self.name=name
InitializeClass(Permission)
Zope-2.13/src/App/PersistentExtra.py 0000664 0000000 0000000 00000002626 13037641750 0017415 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Patch for Persistent to support IPersistentExtra.
"""
from DateTime.DateTime import DateTime
class PersistentUtil:
def bobobase_modification_time(self):
jar = self._p_jar
oid = self._p_oid
if jar is None or oid is None:
return DateTime()
try:
t = self._p_mtime
except AttributeError:
t = 0
return DateTime(t)
_patched = False
def patchPersistent():
global _patched
if _patched:
return
_patched = True
from zope.interface import classImplements
from Persistence import Persistent
from App.interfaces import IPersistentExtra
for k, v in PersistentUtil.__dict__.items():
if k[0] != '_':
setattr(Persistent, k, v)
classImplements(Persistent, IPersistentExtra)
Zope-2.13/src/App/Product.py 0000664 0000000 0000000 00000021567 13037641750 0015676 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Product objects
"""
# The new Product model:
#
# Products may be defined in the Products folder or by placing directories
# in lib/python/Products.
#
# Products in lib/python/Products may have up to three sources of information:
#
# - Static information defined via Python. This information is
# described and made available via __init__.py.
#
# - Dynamic object data that gets copied into the Bobobase.
# This is contained in product.dat (which is obfuscated).
#
# - Static extensions supporting the dynamic data. These too
# are obfuscated.
#
# Products may be copied and pasted only within the products folder.
#
# If a product is deleted (or cut), it is automatically recreated
# on restart if there is still a product directory.
import os
from AccessControl.class_init import InitializeClass
from AccessControl.owner import UnownableOwner
from AccessControl.SecurityInfo import ClassSecurityInfo
from AccessControl.unauthorized import Unauthorized
from App.special_dtml import DTMLFile
from OFS.Folder import Folder
class ProductFolder(Folder):
"Manage a collection of Products"
id = 'Products'
name = title = 'Product Management'
meta_type = 'Product Management'
icon = 'p_/ProductFolder_icon'
all_meta_types=()
meta_types=()
# This prevents subobjects from being owned!
_owner = UnownableOwner
def _product(self, name):
return getattr(self, name)
def _canCopy(self, op=0):
return 0
InitializeClass(ProductFolder)
class Product(Folder):
"""Model a product that can be created through the web.
"""
security = ClassSecurityInfo()
meta_type='Product'
icon='p_/Product_icon'
version=''
configurable_objects_=()
import_error_=None
manage_options = (
(Folder.manage_options[0],) +
tuple(Folder.manage_options[2:])
)
_properties = Folder._properties+(
{'id':'version', 'type': 'string'},
)
_reserved_names=('Help',)
def __init__(self, id, title):
from HelpSys.HelpSys import ProductHelp
self.id = id
self.title = title
self._setObject('Help', ProductHelp('Help', id))
security.declarePublic('Destination')
def Destination(self):
"Return the destination for factory output"
return self
security.declarePublic('DestinationURL')
def DestinationURL(self):
"Return the URL for the destination for factory output"
return self.REQUEST['BASE4']
manage_traceback = DTMLFile('dtml/traceback', globals())
manage_readme = DTMLFile('dtml/readme', globals())
def manage_get_product_readme__(self):
for name in ('README.txt', 'README.TXT', 'readme.txt'):
path = os.path.join(self.home, name)
if os.path.isfile(path):
return open(path).read()
return ''
def permissionMappingPossibleValues(self):
return self.possible_permissions()
def getProductHelp(self):
"""Returns the ProductHelp object associated with the Product.
"""
from HelpSys.HelpSys import ProductHelp
if not hasattr(self, 'Help'):
self._setObject('Help', ProductHelp('Help', self.id))
return self.Help
#
# Product refresh
#
_refresh_dtml = DTMLFile('dtml/refresh', globals())
def _readRefreshTxt(self, pid=None):
import Products
refresh_txt = None
if pid is None:
pid = self.id
for productDir in Products.__path__:
found = 0
for name in ('refresh.txt', 'REFRESH.txt', 'REFRESH.TXT'):
p = os.path.join(productDir, pid, name)
if os.path.exists(p):
found = 1
break
if found:
try:
file = open(p)
text = file.read()
file.close()
refresh_txt = text
break
except:
# Not found here.
pass
return refresh_txt
def manage_performRefresh(self, REQUEST=None):
""" Attempts to perform a refresh operation.
"""
from App.RefreshFuncs import performFullRefresh
if self._readRefreshTxt() is None:
raise Unauthorized, 'refresh.txt not found'
message = None
if performFullRefresh(self._p_jar, self.id):
from ZODB import Connection
Connection.resetCaches() # Clears cache in future connections.
message = 'Product refreshed.'
else:
message = 'An exception occurred.'
if REQUEST is not None:
return self.manage_refresh(REQUEST, manage_tabs_message=message)
def manage_enableAutoRefresh(self, enable=0, REQUEST=None):
""" Changes the auto refresh flag for this product.
"""
from App.RefreshFuncs import enableAutoRefresh
if self._readRefreshTxt() is None:
raise Unauthorized, 'refresh.txt not created'
enableAutoRefresh(self._p_jar, self.id, enable)
if enable:
message = 'Enabled auto refresh.'
else:
message = 'Disabled auto refresh.'
if REQUEST is not None:
return self.manage_refresh(REQUEST, manage_tabs_message=message)
def manage_selectDependentProducts(self, selections=(), REQUEST=None):
""" Selects which products to refresh simultaneously.
"""
from App.RefreshFuncs import setDependentProducts
if self._readRefreshTxt() is None:
raise Unauthorized, 'refresh.txt not created'
setDependentProducts(self._p_jar, self.id, selections)
if REQUEST is not None:
return self.manage_refresh(REQUEST)
InitializeClass(Product)
def initializeProduct(productp, name, home, app):
# Initialize a persistent product
assert doInstall()
import Globals # to set data
fver = ''
if hasattr(productp, '__import_error__'):
ie = productp.__import_error__
else:
ie = None
# Retrieve version number from any suitable version.txt
for fname in ('version.txt', 'VERSION.txt', 'VERSION.TXT'):
try:
fpath = os.path.join(home, fname)
fhandle = open(fpath, 'r')
fver = fhandle.read().strip()
fhandle.close()
break
except IOError:
continue
old = None
products = app.Control_Panel.Products
try:
if ihasattr(products, name):
old=getattr(products, name)
if ihasattr(old,'version') and old.version==fver:
if hasattr(old, 'import_error_') and \
old.import_error_==ie:
# Version hasn't changed. Don't reinitialize.
return old
except:
pass
f = fver and (" (%s)" % fver)
product=Product(name, 'Installed product %s%s' % (name, f))
if old is not None:
app._manage_remove_product_meta_type(product)
products._delObject(name)
for id, v in old.objectItems():
try:
product._setObject(id, v)
except:
pass
products._setObject(name, product)
product.home = home
if ie:
product.import_error_=ie
product.title='Broken product %s' % name
product.icon='p_/BrokenProduct_icon'
product.manage_options=(
{'label':'Traceback', 'action':'manage_traceback'},
)
for name in ('README.txt', 'README.TXT', 'readme.txt'):
path = os.path.join(home, name)
if os.path.isfile(path):
product.manage_options=product.manage_options+(
{'label':'README', 'action':'manage_readme'},
)
break
# Ensure this product has a refresh tab.
found = 0
for option in product.manage_options:
if option.get('label') == 'Refresh':
found = 1
break
if not found:
product.manage_options = product.manage_options + (
{'label':'Refresh', 'action':'manage_refresh'},
)
return product
def ihasattr(o, name):
return hasattr(o, name) and o.__dict__.has_key(name)
def doInstall():
from App.config import getConfiguration
return getConfiguration().enable_product_installation
Zope-2.13/src/App/ProductContext.py 0000664 0000000 0000000 00000030251 13037641750 0017231 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""Objects providing context for product initialization
"""
from logging import getLogger
import os
import re
import stat
from AccessControl.Permission import registerPermissions
from AccessControl.PermissionRole import PermissionRole
from App.Common import package_home
from App.ImageFile import ImageFile
from DateTime.DateTime import DateTime
from HelpSys import APIHelpTopic
from HelpSys import HelpTopic
from OFS.misc_ import Misc_
from OFS.misc_ import misc_
from OFS.ObjectManager import ObjectManager
from zope.interface import implementedBy
from App.FactoryDispatcher import FactoryDispatcher
# Waaaa
import Products
if not hasattr(Products, 'meta_types'):
Products.meta_types=()
if not hasattr(Products, 'meta_classes'):
Products.meta_classes={}
Products.meta_class_info={}
_marker = [] # Create a new marker object
LOG = getLogger('ProductContext')
class ProductContext:
def __init__(self, product, app, package):
self.__prod = product
# app is None by default which signals disabled product installation
self.__app = app
self.__pack = package
def registerClass(self, instance_class=None, meta_type='',
permission=None, constructors=(),
icon=None, permissions=None, legacy=(),
visibility="Global", interfaces=_marker,
container_filter=None
):
"""Register a constructor
Keyword arguments are used to provide meta data:
instance_class -- The class of the object that will be created.
This is not currently used, but may be used in the future to
increase object mobility.
meta_type -- The kind of object being created
This appears in add lists. If not specified, then the class
meta_type will be used.
permission -- The permission name for the constructors.
If not specified, then a permission name based on the
meta type will be used.
constructors -- A list of constructor methods
A method can me a callable object with a __name__
attribute giving the name the method should have in the
product, or the method may be a tuple consisting of a
name and a callable object. The method must be picklable.
The first method will be used as the initial method called
when creating an object.
icon -- The name of an image file in the package to
be used for instances. Note that the class icon
attribute will be set automagically if an icon is
provided.
permissions -- Additional permissions to be registered
If not provided, then permissions defined in the
class will be registered.
legacy -- A list of legacy methods to be added to ObjectManager
for backward compatibility
visibility -- "Global" if the object is globally visible, None else
interfaces -- a list of the interfaces the object supports
container_filter -- function that is called with an ObjectManager
object as the only parameter, which should return a true object
if the object is happy to be created in that container. The
filter is called before showing ObjectManager's Add list,
and before pasting (after object copy or cut), but not
before calling an object's constructor.
"""
pack=self.__pack
initial=constructors[0]
productObject=self.__prod
pid=productObject.id
if icon and instance_class is not None:
setattr(instance_class, 'icon', 'misc_/%s/%s' %
(pid, os.path.split(icon)[1]))
if permissions:
if isinstance(permissions, basestring): # You goofed it!
raise TypeError, ('Product context permissions should be a '
'list of permissions not a string', permissions)
for p in permissions:
if isinstance(p, tuple):
p, default= p
registerPermissions(((p, (), default),))
else:
registerPermissions(((p, ()),))
############################################################
# Constructor permission setup
if permission is None:
permission="Add %ss" % (meta_type or instance_class.meta_type)
if isinstance(permission, tuple):
permission, default = permission
else:
default = ('Manager',)
pr = PermissionRole(permission,default)
registerPermissions(((permission, (), default),))
############################################################
OM = ObjectManager
for method in legacy:
if isinstance(method, tuple):
name, method = method
aliased = 1
else:
name=method.__name__
aliased = 0
if name not in OM.__dict__:
setattr(OM, name, method)
setattr(OM, name+'__roles__', pr)
if aliased:
# Set the unaliased method name and its roles
# to avoid security holes. XXX: All "legacy"
# methods need to be eliminated.
setattr(OM, method.__name__, method)
setattr(OM, method.__name__+'__roles__', pr)
if isinstance(initial, tuple):
name, initial = initial
else:
name = initial.__name__
fd = getattr(pack, '__FactoryDispatcher__', None)
if fd is None:
class __FactoryDispatcher__(FactoryDispatcher):
"Factory Dispatcher for a Specific Product"
fd = pack.__FactoryDispatcher__ = __FactoryDispatcher__
if not hasattr(pack, '_m'):
pack._m = AttrDict(fd)
m = pack._m
if interfaces is _marker:
if instance_class is None:
interfaces = ()
else:
interfaces = tuple(implementedBy(instance_class))
Products.meta_types = Products.meta_types + (
{ 'name': meta_type or instance_class.meta_type,
# 'action': The action in the add drop down in the ZMI. This is
# currently also required by the _verifyObjectPaste
# method of CopyContainers like Folders.
'action': ('manage_addProduct/%s/%s' % (pid, name)),
# 'product': Used by ProductRegistry for TTW products and by
# OFS.Application for refreshing products.
# This key might not be available.
'product': pid,
# 'permission': Guards the add action.
'permission': permission,
# 'visibility': A silly name. Doesn't have much to do with
# visibility. Allowed values: 'Global', None
'visibility': visibility,
# 'interfaces': A tuple of oldstyle and/or newstyle interfaces.
'interfaces': interfaces,
'instance': instance_class,
'container_filter': container_filter
},)
m[name]=initial
m[name+'__roles__']=pr
for method in constructors[1:]:
if isinstance(method, tuple):
name, method = method
else:
name=os.path.split(method.__name__)[-1]
if name not in productObject.__dict__:
m[name]=method
m[name+'__roles__']=pr
if icon:
name = os.path.split(icon)[1]
icon = ImageFile(icon, self.__pack.__dict__)
icon.__roles__=None
if not hasattr(misc_, pid):
setattr(misc_, pid, Misc_(pid, {}))
getattr(misc_, pid)[name]=icon
def getProductHelp(self):
"""
Returns the ProductHelp associated with the current Product.
"""
if self.__app is None:
return self.__prod.getProductHelp()
return self.__prod.__of__(self.__app.Control_Panel.Products).getProductHelp()
def registerHelpTopic(self, id, topic):
"""
Register a Help Topic for a product.
"""
self.getProductHelp()._setObject(id, topic)
def registerHelpTitle(self, title):
"""
Sets the title of the Product's Product Help
"""
h = self.getProductHelp()
if getattr(h, 'title', None) != title:
h.title = title
def registerHelp(self, directory='help', clear=1,
title_re=re.compile(r'(.+?)', re.I)):
"""
Registers Help Topics for all objects in a directory.
Nothing will be done if the files in the directory haven't
changed since the last registerHelp call.
'clear' indicates whether or not to delete all existing
Topics from the Product.
HelpTopics are created for these kind of files
.dtml -- DTMLHelpTopic
.html .htm -- TextHelpTopic
.stx .txt -- STXHelpTopic
.jpg .png .gif -- ImageHelpTopic
.py -- APIHelpTopic
"""
if not self.__app:
return
help=self.getProductHelp()
path=os.path.join(package_home(self.__pack.__dict__),
directory)
# If help directory does not exist, log a warning and return.
try:
dir_mod_time=DateTime(os.stat(path)[stat.ST_MTIME])
except OSError, (errno, text):
LOG.warn('%s: %s' % (text, path))
return
# test to see if nothing has changed since last registration
if help.lastRegistered is not None and \
help.lastRegistered >= dir_mod_time:
return
help.lastRegistered=DateTime()
if clear:
for id in help.objectIds(['Help Topic','Help Image']):
help._delObject(id)
for file in os.listdir(path):
ext=os.path.splitext(file)[1]
ext=ext.lower()
if ext in ('.dtml',):
contents = open(os.path.join(path,file),'rb').read()
m = title_re.search(contents)
if m:
title = m.group(1)
else:
title = ''
ht=HelpTopic.DTMLTopic(file, '', os.path.join(path,file))
self.registerHelpTopic(file, ht)
elif ext in ('.html', '.htm'):
contents = open(os.path.join(path,file),'rb').read()
m = title_re.search(contents)
if m:
title = m.group(1)
else:
title = ''
ht=HelpTopic.TextTopic(file, title, os.path.join(path,file))
self.registerHelpTopic(file, ht)
elif ext in ('.stx', '.txt'):
title=(open(os.path.join(path,file),'rb').readline()).split(':')[0]
ht=HelpTopic.STXTopic(file, title, os.path.join(path, file))
self.registerHelpTopic(file, ht)
elif ext in ('.jpg', '.gif', '.png'):
ht=HelpTopic.ImageTopic(file, '', os.path.join(path, file))
self.registerHelpTopic(file, ht)
elif ext in ('.py',):
if file[0] == '_': # ignore __init__.py
continue
ht=APIHelpTopic.APIHelpTopic(file, '', os.path.join(path, file))
self.registerHelpTopic(file, ht)
class AttrDict:
def __init__(self, ob):
self.ob = ob
def __setitem__(self, name, v):
setattr(self.ob, name, v)
Zope-2.13/src/App/ProductRegistry.py 0000664 0000000 0000000 00000011165 13037641750 0017420 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
# Product registry and new product factory model. There will be a new
# mechanism for defining actions for meta types. If an action is of
# the form:
#
# manage_addProduct-name-factoryid
#
# Then the machinery that invokes an add-product form
# will return:
# ....what?
class ProductRegistryMixin:
# This class implements a protocol for registering products that
# are defined through the web.
# This class is a mix-in class for the top-level application object.
def _manage_remove_product_meta_type(self, product,
id=None, meta_type=None):
r=[]
pid=product.id
for mt in self._getProductRegistryMetaTypes():
if 'product' in mt:
if mt['product']==pid and (
meta_type is None or meta_type==mt['name']):
continue
elif meta_type==mt['name']: continue
r.append(mt)
self._setProductRegistryMetaTypes(tuple(r))
def _constructor_prefix_string(self, pid):
return 'manage_addProduct/%s/' % pid
def _manage_add_product_meta_type(self, product, id, meta_type,
permission=''):
pid=product.id
meta_types=self._getProductRegistryMetaTypes()
for mt in meta_types:
if mt['name']==meta_type:
if 'product' not in mt: mt['product']=pid
if mt['product'] != pid:
raise ValueError, (
'The type %s is already defined.' % meta_type)
mt['action']='%s%s' % (
self._constructor_prefix_string(pid), id)
if permission: mt['permission']=permission
return
mt={
'name': meta_type,
'action': ('%s%s' % (
self._constructor_prefix_string(pid), id)),
'product': pid
}
if permission: mt['permission']=permission
self._setProductRegistryMetaTypes(meta_types+(mt,))
# HACK - sometimes an unwrapped App object seems to be passed as
# self to these methods, which means that they dont have an aq_aquire
# method. Until Jim has time to look into this, this aq_maybe method
# appears to be an effective work-around...
def aq_maybe(self, name):
if hasattr(self, name):
return getattr(self, name)
return self.aq_acquire(name)
def _manage_add_product_data(self, type, product, id, **data):
values=filter(
lambda d, product=product, id=id:
not (d['product']==product and d['id']==id),
list(self.aq_maybe('_getProductRegistryData')(type))
)
data['product']=product
data['id']=id
values.append(data)
self.aq_maybe('_setProductRegistryData')(type, tuple(values))
def _manage_remove_product_data(self, type, product, id):
values=filter(
lambda d, product=product, id=id:
not (d['product']==product and d['id']==id),
self.aq_maybe('_getProductRegistryData')(type)
)
self.aq_maybe('_setProductRegistryData')(type, tuple(values))
class ProductRegistry(ProductRegistryMixin):
# This class implements a protocol for registering products that
# are defined through the web. It also provides methods for
# getting hold of the Product Registry, Control_Panel.Products.
# This class is a mix-in class for the top-level application object.
def _getProducts(self): return self.Control_Panel.Products
_product_meta_types=()
def _getProductRegistryMetaTypes(self):
return self._product_meta_types
def _setProductRegistryMetaTypes(self, v):
self._product_meta_types=v
def _getProductRegistryData(self, name):
return getattr(self, '_product_%s' % name)
def _setProductRegistryData(self, name, v):
name='_product_%s' % name
if hasattr(self, name):
return setattr(self, name, v)
else:
raise AttributeError, name
Zope-2.13/src/App/RefreshFuncs.py 0000664 0000000 0000000 00000023450 13037641750 0016644 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
'''
Functions for refreshing products.
'''
from logging import getLogger
import os
import sys
from time import time
from traceback import format_exception
from ExtensionClass import Base
from Persistence import PersistentMapping
LOG = getLogger('RefreshFuncs')
global_classes_timestamp = 0
products_mod_times = {}
_marker = [] # create a new marker object.
refresh_exc_info = {}
class dummyClass:
pass
class dummyClass2(Base):
pass
def dummyFunc():
pass
ClassTypes = (type(dummyClass), type(dummyClass2))
ModuleType = type(sys)
FuncType = type(dummyFunc)
next_auto_refresh_check = 0
AUTO_REFRESH_INTERVAL = 2 # 2 seconds.
# Functions for storing and retrieving the auto-refresh state for
# each product.
def _getCentralRefreshData(jar, create=0):
root = jar.root()
if root.has_key('RefreshData'):
rd = root['RefreshData']
else:
rd = PersistentMapping()
if create:
root['RefreshData'] = rd
return rd
def isAutoRefreshEnabled(jar, productid):
rd = _getCentralRefreshData(jar)
ids = rd.get('auto', None)
if ids:
return ids.get(productid, 0)
else:
return 0
def enableAutoRefresh(jar, productid, enable):
productid = str(productid)
rd = _getCentralRefreshData(jar, 1)
ids = rd.get('auto', None)
if ids is None:
if enable:
rd['auto'] = ids = PersistentMapping()
else:
return
if enable:
ids[productid] = 1
else:
if ids.has_key(productid):
del ids[productid]
def listAutoRefreshableProducts(jar):
rd = _getCentralRefreshData(jar)
auto = rd.get('auto', None)
if auto:
ids = []
for k, v in auto.items():
if v:
ids.append(k)
return ids
else:
return ()
def getDependentProducts(jar, productid):
rd = _getCentralRefreshData(jar)
products = rd.get('products', None)
if products is None:
return ()
product = products.get(productid, None)
if product is None:
return ()
return product.get('dependent_products', ())
def setDependentProducts(jar, productid, dep_ids):
productid = str(productid)
rd = _getCentralRefreshData(jar, 1)
products = rd.get('products', None)
if products is None:
rd['products'] = products = PersistentMapping()
product = products.get(productid, None)
if product is None:
products[productid] = product = PersistentMapping()
product['dependent_products'] = tuple(map(str, dep_ids))
# Functions for performing refresh.
def getReloadVar(module):
reload_var = getattr(module, '__refresh_module__', _marker)
if reload_var is _marker:
reload_var = getattr(module, '__reload_module__', _marker)
if reload_var is _marker:
reload_var = 1
return reload_var
def listRefreshableModules(productid):
prefix = "Products.%s" % productid
prefixdot = prefix + '.'
lpdot = len(prefixdot)
rval = []
for name, module in sys.modules.items():
if module and (name == prefix or name[:lpdot] == prefixdot):
reload_var = getReloadVar(module)
if reload_var:
rval.append((name, module))
return rval
def logBadRefresh(productid):
exc = sys.exc_info()
try:
LOG.error('Exception while refreshing %s' % productid, exc_info=exc)
if hasattr(exc[0], '__name__'):
error_type = exc[0].__name__
else:
error_type = str(exc[0])
error_value = str(exc[1])
info = ''.join(format_exception(exc[0], exc[1], exc[2], limit=200))
refresh_exc_info[productid] = (error_type, error_value, info)
finally:
exc = None
def performRefresh(jar, productid):
'''Attempts to perform a refresh operation.
'''
refresh_exc_info[productid] = None
setupModTimes(productid) # Refresh again only if changed again.
modlist = listRefreshableModules(productid)
former_modules = {}
try:
# Remove modules from sys.modules but keep a handle
# on the old modules in case there's a problem.
for name, module in modlist:
m = sys.modules.get(name, None)
if m is not None:
former_modules[name] = m
del sys.modules[name]
# Reimport and reinstall the product.
from OFS import Application
Application.reimport_product(productid)
app = jar.root()['Application']
Application.reinstall_product(app, productid)
return 1
except:
# Couldn't refresh. Reinstate removed modules.
for name, module in former_modules.items():
sys.modules[name] = module
raise
def performSafeRefresh(jar, productid):
try:
LOG.info('Refreshing product %s' % productid)
if not performRefresh(jar, productid):
return 0
except:
logBadRefresh(productid)
return 0
else:
return 1
def performFullRefresh(jar, productid):
# Refresh dependent products also.
if performSafeRefresh(jar, productid):
dep_ids = getDependentProducts(jar, productid)
for dep_id in dep_ids:
if isAutoRefreshEnabled(jar, dep_id):
if not performSafeRefresh(jar, dep_id):
return 0
else:
return 0
return 1
def getLastRefreshException(productid):
return refresh_exc_info.get(productid, None)
# Functions for quickly scanning the dates of product modules.
def tryFindProductDirectory(productid):
import Products
path_join = os.path.join
isdir = os.path.isdir
exists = os.path.exists
for products_dir in Products.__path__:
product_dir = path_join(products_dir, productid)
if not isdir(product_dir): continue
if not exists(path_join(product_dir, '__init__.py')):
if not exists(path_join(product_dir, '__init__.pyc')):
continue
return product_dir
return None
def tryFindModuleFilename(product_dir, filename):
# Try different variations of the filename of a module.
path_join = os.path.join
isdir = os.path.isdir
exists = os.path.exists
found = None
fn = path_join(product_dir, filename + '.py')
if exists(fn):
found = fn
if not found:
fn = fn + 'c'
if exists(fn):
found = fn
if not found:
fn = path_join(product_dir, filename)
if isdir(fn):
fn = path_join(fn, '__init__.py')
if exists(fn):
found = fn
else:
fn = fn + 'c'
if exists(fn):
found = fn
return found
def setupModTimes(productid):
mod_times = []
product_dir = tryFindProductDirectory(productid)
if product_dir is not None:
modlist = listRefreshableModules(productid)
path_join = os.path.join
exists = os.path.exists
for name, module in modlist:
splitname = name.split( '.')[2:]
if not splitname:
filename = '__init__'
else:
filename = apply(path_join, splitname)
found = tryFindModuleFilename(product_dir, filename)
if found:
try: mtime = os.stat(found)[8]
except: mtime = 0
mod_times.append((found, mtime))
products_mod_times[productid] = mod_times
def checkModTimes(productid):
# Returns 1 if there were changes.
mod_times = products_mod_times.get(productid, None)
if mod_times is None:
# Initialize the mod times.
setupModTimes(productid)
return 0
for filename, mod_time in mod_times:
try: mtime = os.stat(filename)[8]
except: mtime = 0
if mtime != mod_time:
# Something changed!
return 1
return 0
# Functions for performing auto-refresh.
def checkAutoRefresh(jar):
'''
Returns the IDs of products that need to be auto-refreshed.
'''
# Note: this function is NOT allowed to change the database!
global next_auto_refresh_check
now = time()
if next_auto_refresh_check and next_auto_refresh_check > now:
# Not enough time has passed.
return ()
next_auto_refresh_check = now + AUTO_REFRESH_INTERVAL
rd = _getCentralRefreshData(jar)
ids = rd.get('auto', None)
if not ids:
return ()
auto_refresh_ids = []
for productid in ids.keys():
if checkModTimes(productid):
auto_refresh_ids.append(productid)
return auto_refresh_ids
def finishAutoRefresh(jar, productids):
# This function is allowed to change the database.
for productid in productids:
performFullRefresh(jar, productid)
def autoRefresh(jar):
# Must be called before there are any changes made
# by the connection to the database!
import transaction
auto_refresh_ids = checkAutoRefresh(jar)
if auto_refresh_ids:
finishAutoRefresh(jar, auto_refresh_ids)
from ZODB import Connection
Connection.resetCaches()
transaction.commit()
jar._resetCache()
transaction.begin()
def setupAutoRefresh(jar):
# Install hook.
from App.ZApplication import connection_open_hooks
connection_open_hooks.append(autoRefresh)
# Init mod times.
checkAutoRefresh(jar)
Zope-2.13/src/App/Undo.py 0000664 0000000 0000000 00000012601 13037641750 0015150 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Undo support.
"""
from Acquisition import aq_inner
from Acquisition import aq_parent
from AccessControl import getSecurityManager
from AccessControl import ClassSecurityInfo
from AccessControl.class_init import InitializeClass
from AccessControl.Permissions import undo_changes
from App.interfaces import IUndoSupport
from App.special_dtml import DTMLFile
from DateTime.DateTime import DateTime
import ExtensionClass
import transaction
from ZopeUndo.Prefix import Prefix
from zope.interface import implements
class UndoSupport(ExtensionClass.Base):
implements(IUndoSupport)
security = ClassSecurityInfo()
manage_options=(
{'label': 'Undo', 'action': 'manage_UndoForm'},
)
security.declareProtected(undo_changes, 'manage_UndoForm')
manage_UndoForm = DTMLFile(
'dtml/undo',
globals(),
PrincipiaUndoBatchSize=20,
first_transaction=0,
last_transaction=20,
)
def _get_request_var_or_attr(self, name, default):
if hasattr(self, 'REQUEST'):
REQUEST=self.REQUEST
if REQUEST.has_key(name):
return REQUEST[name]
if hasattr(self, name):
v = getattr(self, name)
else:
v = default
REQUEST[name] = v
return v
else:
if hasattr(self, name):
v = getattr(self, name)
else:
v = default
return v
security.declareProtected(undo_changes, 'undoable_transactions')
def undoable_transactions(self, first_transaction=None,
last_transaction=None,
PrincipiaUndoBatchSize=None):
if first_transaction is None:
first_transaction = self._get_request_var_or_attr(
'first_transaction', 0)
if PrincipiaUndoBatchSize is None:
PrincipiaUndoBatchSize = self._get_request_var_or_attr(
'PrincipiaUndoBatchSize', 20)
if last_transaction is None:
last_transaction = self._get_request_var_or_attr(
'last_transaction',
first_transaction+PrincipiaUndoBatchSize)
spec = {}
# A user is allowed to undo transactions that were initiated
# by any member of a user folder in the place where the user
# is defined.
user = getSecurityManager().getUser()
user_parent = aq_parent(user)
if user_parent is not None:
path = '/'.join(user_parent.getPhysicalPath()[1:-1])
else:
path = ''
if path:
spec['user_name'] = Prefix(path)
if getattr(aq_parent(aq_inner(self)), '_p_jar', None) == self._p_jar:
# We only want to undo things done here (and not in mounted
# databases)
opath = '/'.join(self.getPhysicalPath())
else:
# Special case: at the root of a database,
# allow undo of any path.
opath = None
if opath:
spec['description'] = Prefix(opath)
r = self._p_jar.db().undoInfo(
first_transaction, last_transaction, spec)
for d in r:
d['time'] = t = DateTime(d['time'])
desc = d['description']
tid = d['id']
if desc:
desc = desc.split()
d1 = desc[0]
desc = ' '.join(desc[1:])
if len(desc) > 60:
desc = desc[:56] + ' ...'
tid = "%s %s %s %s" % (encode64(tid), t, d1, desc)
else:
tid = "%s %s" % (encode64(tid), t)
d['id'] = tid
return r
security.declareProtected(undo_changes, 'manage_undo_transactions')
def manage_undo_transactions(self, transaction_info=(), REQUEST=None):
"""
"""
tids = []
descriptions = []
for tid in transaction_info:
tid = tid.split()
if tid:
tids.append(decode64(tid[0]))
descriptions.append(tid[-1])
if tids:
transaction.get().note("Undo %s" % ' '.join(descriptions))
self._p_jar.db().undoMultiple(tids)
if REQUEST is None:
return
REQUEST['RESPONSE'].redirect("%s/manage_UndoForm" % REQUEST['URL1'])
return ''
InitializeClass(UndoSupport)
########################################################################
# Blech, need this cause binascii.b2a_base64 is too pickly
import binascii
def encode64(s, b2a=binascii.b2a_base64):
if len(s) < 58:
return b2a(s)
r = []
a = r.append
for i in range(0, len(s), 57):
a(b2a(s[i:i+57])[:-1])
return ''.join(r)
def decode64(s, a2b=binascii.a2b_base64):
__traceback_info__=len(s), `s`
return a2b(s+'\n')
del binascii
Zope-2.13/src/App/ZApplication.py 0000664 0000000 0000000 00000004705 13037641750 0016646 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
"""Implement an bobo_application object that is BoboPOS3 aware
This module provides a wrapper that causes a database connection to be created
and used when bobo publishes a bobo_application object.
"""
import transaction
connection_open_hooks = []
class ZApplicationWrapper:
def __init__(self, db, name, klass= None, klass_args=()):
self._stuff = db, name
if klass is not None:
conn=db.open()
root=conn.root()
if not root.has_key(name):
root[name]=klass()
transaction.commit()
conn.close()
self._klass=klass
# This hack is to overcome a bug in Bobo!
def __getattr__(self, name):
return getattr(self._klass, name)
def __bobo_traverse__(self, REQUEST=None, name=None):
db, aname = self._stuff
conn = db.open()
if connection_open_hooks:
for hook in connection_open_hooks:
hook(conn)
# arrange for the connection to be closed when the request goes away
cleanup = Cleanup(conn)
REQUEST._hold(cleanup)
conn.setDebugInfo(REQUEST.environ, REQUEST.other)
v=conn.root()[aname]
if name is not None:
if hasattr(v, '__bobo_traverse__'):
return v.__bobo_traverse__(REQUEST, name)
if hasattr(v,name): return getattr(v,name)
return v[name]
return v
def __call__(self, connection=None):
db, aname = self._stuff
if connection is None:
connection=db.open()
elif isinstance(connection, basestring):
connection=db.open(connection)
return connection.root()[aname]
class Cleanup:
def __init__(self, jar):
self._jar = jar
def __del__(self):
transaction.abort()
self._jar.close()
Zope-2.13/src/App/__init__.py 0000664 0000000 0000000 00000001144 13037641750 0016002 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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
#
##############################################################################
Zope-2.13/src/App/class_init.py 0000664 0000000 0000000 00000001471 13037641750 0016376 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""Class initialization.
"""
# BBB
from AccessControl.Permission import ApplicationDefaultPermissions
from AccessControl.class_init import InitializeClass
default__class_init__ = InitializeClass # BBB: old name
Zope-2.13/src/App/config.py 0000664 0000000 0000000 00000006673 13037641750 0015524 0 ustar 00root root 0000000 0000000 ##############################################################################
#
# Copyright (c) 2003 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (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.
#
##############################################################################
"""Simple access to configuration values.
The configuration values are represented as a single object with
attributes for each bit of information.
"""
import sys
_config = None
def getConfiguration():
"""Return the global Zope configuration object.
If a configuration hasn't been set yet, generates a simple
configuration object and uses that. Once generated, it may not be
overridden by calling ``setConfiguration()``.
"""
if _config is None:
setConfiguration(DefaultConfiguration())
return _config
def setConfiguration(cfg):
"""Set the global configuration object.
Legacy sources of common configuration values are updated to
reflect the new configuration; this may be removed in some future
version.
"""
global _config
_config = cfg
if cfg is None:
return
from App import FindHomes
import __builtin__
import os
import Globals # to set data
__builtin__.CLIENT_HOME = FindHomes.CLIENT_HOME = cfg.clienthome
os.environ["CLIENT_HOME"] = cfg.clienthome
# Globals does not export CLIENT_HOME
Globals.data_dir = cfg.clienthome
__builtin__.INSTANCE_HOME = FindHomes.INSTANCE_HOME = cfg.instancehome
os.environ["INSTANCE_HOME"] = cfg.instancehome
Globals.INSTANCE_HOME = cfg.instancehome
if hasattr(cfg, 'softwarehome') and cfg.softwarehome is not None:
__builtin__.SOFTWARE_HOME = FindHomes.SOFTWARE_HOME = cfg.softwarehome
os.environ["SOFTWARE_HOME"] = cfg.softwarehome
Globals.SOFTWARE_HOME = cfg.softwarehome
if hasattr(cfg, 'zopehome') and cfg.zopehome is not None:
__builtin__.ZOPE_HOME = FindHomes.ZOPE_HOME = cfg.zopehome
os.environ["ZOPE_HOME"] = cfg.zopehome
Globals.ZOPE_HOME = cfg.zopehome
Globals.DevelopmentMode = cfg.debug_mode
class DefaultConfiguration:
"""
This configuration should be used effectively only during unit tests
"""
def __init__(self):
from App import FindHomes
self.clienthome = FindHomes.CLIENT_HOME
self.instancehome = FindHomes.INSTANCE_HOME
if hasattr(FindHomes, 'SOFTWARE_HOME'):
self.softwarehome = FindHomes.SOFTWARE_HOME
if hasattr(FindHomes, 'ZOPE_HOME'):
self.zopehome = FindHomes.ZOPE_HOME
self.dbtab = None
self.debug_mode = True
self.enable_product_installation = False
self.locale = None
# restructured text
default_enc = sys.getdefaultencoding()
self.rest_input_encoding = default_enc
self.rest_output_encoding = default_enc
self.rest_header_level = 3
self.rest_language_code = 'en'
# ZServer.HTTPServer
self.http_header_max_length = 8196
# VerboseSecurity
self.skip_ownership_checking = False
self.skip_authentication_checking = False
Zope-2.13/src/App/dtml/ 0000775 0000000 0000000 00000000000 13037641750 0014631 5 ustar 00root root 0000000 0000000 Zope-2.13/src/App/dtml/activity.dtml 0000664 0000000 0000000 00000005021 13037641750 0017345 0 ustar 00root root 0000000 0000000
This license has been certified as open source. It has also
been designated as GPL compatible by the Free Software
Foundation (FSF).
Redistribution and use in source and binary forms, with or
without modification, are permitted provided that the
following conditions are met:
Redistributions in source code must retain the
accompanying copyright notice, this list of conditions,
and the following disclaimer.
Redistributions in binary form must reproduce the accompanying
copyright notice, this list of conditions, and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
Names of the copyright holders must not be used to
endorse or promote products derived from this software
without prior written permission from the copyright
holders.
The right to distribute this software or to use it for
any purpose does not give you the right to use
Servicemarks (sm) or Trademarks (tm) of the copyright
holders. Use of them is covered by separate agreement
with the copyright holders.
If any files are modified, you must cause the modified
files to carry prominent notices stating that you changed
the files and the date of any change.
Disclaimer
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS''
AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
NO EVENT SHALL THE COPYRIGHT HOLDERS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
This software consists of contributions made by Zope
Corporation and many individuals on behalf of Zope
Corporation. Specific attributions are listed in the
accompanying credits file.
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI or Corporation for National Research Initiatives or
CNRI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.
While CWI is the initial source for this software, a modified version
is made available by the Corporation for National Research Initiatives
(CNRI) at the Internet address
ftp://ftp.python.org.
STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
Andrew M. Kuchling wrote the initial version of mod_pcgi, making
him extremely cool in our book.
Jephte CLAIN made some patches to European TimeZope.
All the other Zopistas far and wide that stuck with us during
the Bobo/Principia days and politely push us to make the best damn
app server on this or any other planet.
Of course the list of credits would be quite incomplete without
mentioning Guido van Rossum, benevolent dictator of Python and
long-time friend of Zope Corporation. Zope Power is Python
Power.
Special thanks to Richard Stallman and the Free Software
Foundation for their assistance and feedback on the GPL-compatible
2.0 version of the Zope Public License.
The Database Manager allows you to view database status information.
It also allows you to perform maintenance tasks such as database packing
and cache management.
The initial method is the method that will be invoked
when a user adds a new object. This must be one of the objects in the
product, typically a Document.
Zope-2.13/src/App/dtml/manage.dtml 0000664 0000000 0000000 00000002275 13037641750 0016751 0 ustar 00root root 0000000 0000000
Zope on &dtml-BASE0;
/manage_top_frame" name="manage_top_frame"
marginheight="0" scrolling="no"/>
/manage_menu" name="manage_menu"
marginwidth="2" marginheight="2" scrolling="auto"/>
/manage_workspace" name="manage_main"
marginwidth="2" marginheight="2" scrolling="auto"/>
Management interfaces require the use of a frames-capable web browser.
Zope-2.13/src/App/dtml/manage_form_title.dtml 0000664 0000000 0000000 00000001070 13037641750 0021165 0 ustar 00root root 0000000 0000000
This is small-st.
This is small-st.
This is small-st.
This is small-st.
This is small-un.
This is small-un.
This is small-un.
This is small-un.
This is small-em.
This is small-em.
This is small-em.
This is small-em.
This is small-tx.
This is small-tx.
This is small-tx.
This is small-tx.
This is normal-st.
This is normal-st.
This is normal-st.
This is normal-st.
This is normal-un.
This is normal-un.
This is normal-un.
This is normal-un.
This is normal-em.
This is normal-em.
This is normal-em.
This is normal-em.
This is normal-tx.
This is normal-tx.
This is normal-tx.
This is normal-tx.
This is large-st.
This is large-st.
This is large-st.
This is large-st.
This is large-un.
This is large-un.
This is large-un.
This is large-un.
This is large-em.
This is large-em.
This is large-em.
This is large-em.
This is large-tx.
This is large-tx.
This is large-tx.
This is large-tx.
This is some text. This is some text. This is some text.
This is some text. This is some text. This is some text.
This is some text. This is some text. This is some text.
This is some text. This is some text. This is some text.
This is some text. This is some text. This is some text.
This is some text. This is some text. This is some text.