/usr/share/pyshared/zope/app/container/browser/adding.py is in python-zope.app.container 3.9.2-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | ##############################################################################
#
# Copyright (c) 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.
#
##############################################################################
"""Adding View
The Adding View is used to add new objects to a container. It is sort of a
factory screen.
"""
__docformat__ = 'restructuredtext'
from zope.app.container.constraints import checkFactory
from zope.app.container.constraints import checkObject
from zope.app.container.i18n import ZopeMessageFactory as _
from zope.app.container.interfaces import IAdding
from zope.app.container.interfaces import IContainerNamesContainer
from zope.app.container.interfaces import INameChooser
from zope.browsermenu.menu import getMenu
from zope.browserpage.viewpagetemplatefile import ViewPageTemplateFile
from zope.component import getMultiAdapter
from zope.component import getUtility
from zope.component import queryAdapter
from zope.component import queryMultiAdapter
from zope.component import queryUtility
from zope.component.interfaces import IFactory
from zope.event import notify
from zope.exceptions.interfaces import UserError
from zope.i18n.interfaces.locales import ICollator
from zope.i18n.locales.fallbackcollator import FallbackCollator
from zope.interface import implements
from zope.lifecycleevent import ObjectCreatedEvent
from zope.location import LocationProxy
from zope.publisher.browser import BrowserView
from zope.publisher.interfaces import IPublishTraverse
from zope.security.proxy import removeSecurityProxy
from zope.traversing.browser.absoluteurl import absoluteURL
import zope.security.checker
class Adding(BrowserView):
implements(IAdding, IPublishTraverse)
def add(self, content):
"""See zope.app.container.interfaces.IAdding
"""
container = self.context
name = self.contentName
chooser = INameChooser(container)
# check precondition
checkObject(container, name, content)
if IContainerNamesContainer.providedBy(container):
# The container picks its own names.
# We need to ask it to pick one.
name = chooser.chooseName(self.contentName or '', content)
else:
request = self.request
name = request.get('add_input_name', name)
if name is None:
name = chooser.chooseName(self.contentName or '', content)
elif name == '':
name = chooser.chooseName('', content)
chooser.checkName(name, content)
container[name] = content
self.contentName = name # Set the added object Name
return container[name]
contentName = None # usually set by Adding traverser
def nextURL(self):
"""See zope.app.container.interfaces.IAdding"""
return absoluteURL(self.context, self.request) + '/@@contents.html'
# set in BrowserView.__init__
request = None
context = None
def publishTraverse(self, request, name):
"""See zope.publisher.interfaces.IPublishTraverse"""
if '=' in name:
view_name, content_name = name.split("=", 1)
self.contentName = content_name
if view_name.startswith('@@'):
view_name = view_name[2:]
return getMultiAdapter((self, request), name=view_name)
if name.startswith('@@'):
view_name = name[2:]
else:
view_name = name
view = queryMultiAdapter((self, request), name=view_name)
if view is not None:
return view
factory = queryUtility(IFactory, name)
if factory is None:
return super(Adding, self).publishTraverse(request, name)
return factory
def action(self, type_name='', id=''):
if not type_name:
raise UserError(_(u"You must select the type of object to add."))
if type_name.startswith('@@'):
type_name = type_name[2:]
if '/' in type_name:
view_name = type_name.split('/', 1)[0]
else:
view_name = type_name
if queryMultiAdapter((self, self.request),
name=view_name) is not None:
url = "%s/%s=%s" % (
absoluteURL(self, self.request), type_name, id)
self.request.response.redirect(url)
return
if not self.contentName:
self.contentName = id
# TODO: If the factory wrapped by LocationProxy is already a Proxy,
# then ProxyFactory does not do the right thing and the
# original's checker info gets lost. No factory that was
# registered via ZCML and was used via addMenuItem worked
# here. (SR)
factory = getUtility(IFactory, type_name)
if not type(factory) is zope.security.checker.Proxy:
factory = LocationProxy(factory, self, type_name)
factory = zope.security.checker.ProxyFactory(factory)
content = factory()
# Can't store security proxies.
# Note that it is important to do this here, rather than
# in add, otherwise, someone might be able to trick add
# into unproxying an existing object,
content = removeSecurityProxy(content)
notify(ObjectCreatedEvent(content))
self.add(content)
self.request.response.redirect(self.nextURL())
def nameAllowed(self):
"""Return whether names can be input by the user."""
return not IContainerNamesContainer.providedBy(self.context)
menu_id = None
index = ViewPageTemplateFile("add.pt")
def addingInfo(self):
"""Return menu data.
This is sorted by title.
"""
container = self.context
result = []
for menu_id in (self.menu_id, 'zope.app.container.add'):
if not menu_id:
continue
for item in getMenu(menu_id, self, self.request):
extra = item.get('extra')
if extra:
factory = extra.get('factory')
if factory:
factory = getUtility(IFactory, factory)
if not checkFactory(container, None, factory):
continue
elif item['extra']['factory'] != item['action']:
item['has_custom_add_view']=True
# translate here to have a localized sorting
item['title'] = zope.i18n.translate(item['title'],
context=self.request)
result.append(item)
# sort the adding info with a collator instead of a basic unicode sort
collator = queryAdapter(self.request.locale, ICollator)
if collator is None:
collator = FallbackCollator(self.request.locale)
result.sort(key = lambda x: collator.key(x['title']))
return result
def isSingleMenuItem(self):
"Return whether there is single menu item or not."
return len(self.addingInfo()) == 1
def hasCustomAddView(self):
"This should be called only if there is `singleMenuItem` else return 0"
if self.isSingleMenuItem():
menu_item = self.addingInfo()[0]
if 'has_custom_add_view' in menu_item:
return True
return False
|