more Python3 fixes (browser, resource)

This commit is contained in:
Helmut Merz 2024-09-24 11:47:59 +02:00
parent 98bd9b0a46
commit 7a9be5d79b
3 changed files with 42 additions and 86 deletions

View file

@ -1,47 +1,28 @@
# # loops.browser.common
# Copyright (c) 2016 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
""" """ Common base class for loops browser view classes.
Common base class for loops browser view classes.
""" """
from cgi import parse_qsl
#import mimetypes # use more specific assignments from cybertools.text #import mimetypes # use more specific assignments from cybertools.text
from datetime import date, datetime from datetime import date, datetime
from logging import getLogger from logging import getLogger
import re import re
from time import strptime from time import strptime
from urllib import urlencode from urllib.parse import parse_qs, parse_qsl, urlencode
from urlparse import parse_qs
from zope import component from zope import component
from zope.app.form.browser.interfaces import ITerms from zope.authentication.interfaces import IAuthentication, IUnauthenticatedPrincipal
from zope.app.i18n.interfaces import ITranslationDomain from zope.authentication.interfaces import IUnauthenticatedPrincipal
from zope.app.security.interfaces import IAuthentication, IUnauthenticatedPrincipal from zope.authentication.interfaces import PrincipalLookupError
from zope.app.pagetemplate import ViewPageTemplateFile from zope.browser.interfaces import ITerms
from zope.app.security.interfaces import IUnauthenticatedPrincipal from zope.browserpage import ViewPageTemplateFile
from zope.app.security.interfaces import PrincipalLookupError
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope.dottedname.resolve import resolve from zope.dottedname.resolve import resolve
from zope.dublincore.interfaces import IZopeDublinCore from zope.dublincore.interfaces import IZopeDublinCore
from zope.formlib import form from zope.formlib import form
from zope.formlib.form import FormFields from zope.formlib.form import FormFields
from zope.formlib.namedtemplate import NamedTemplate from zope.formlib.namedtemplate import NamedTemplate
from zope.interface import Interface, implements from zope.i18n.interfaces import ITranslationDomain
from zope.interface import Interface, implementer
from zope.proxy import removeAllProxies from zope.proxy import removeAllProxies
from zope.publisher.browser import applySkin from zope.publisher.browser import applySkin
from zope.publisher.interfaces.browser import IBrowserSkinType, IBrowserView from zope.publisher.interfaces.browser import IBrowserSkinType, IBrowserView
@ -1092,13 +1073,12 @@ class LoggedIn(object):
# vocabulary stuff # vocabulary stuff
@implementer(ITerms)
class SimpleTerms(object): class SimpleTerms(object):
""" Provide the ITerms interface, e.g. for usage in selection """ Provide the ITerms interface, e.g. for usage in selection
lists. lists.
""" """
implements(ITerms)
def __init__(self, source, request): def __init__(self, source, request):
# the source parameter is a list of tuples (token, title). # the source parameter is a list of tuples (token, title).
self.source = source self.source = source
@ -1113,13 +1093,12 @@ class SimpleTerms(object):
return (token, self.terms[token]) return (token, self.terms[token])
@implementer(ITerms)
class LoopsTerms(object): class LoopsTerms(object):
""" Provide the ITerms interface, e.g. for usage in selection """ Provide the ITerms interface, e.g. for usage in selection
lists. lists.
""" """
implements(ITerms)
def __init__(self, source, request): def __init__(self, source, request):
# the source parameter is a view or adapter of a real context object: # the source parameter is a view or adapter of a real context object:
self.source = source self.source = source
@ -1141,12 +1120,11 @@ class LoopsTerms(object):
return self.loopsRoot.loopsTraverse(token) return self.loopsRoot.loopsTraverse(token)
@implementer(ITerms)
class InterfaceTerms(object): class InterfaceTerms(object):
""" Provide the ITerms interface for source list of interfaces. """ Provide the ITerms interface for source list of interfaces.
""" """
implements(ITerms)
def __init__(self, source, request): def __init__(self, source, request):
self.source = source self.source = source
self.request = request self.request = request

View file

@ -1,33 +1,16 @@
# # loops.resource
# Copyright (c) 2016 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
""" """ Definition of the Concept class.
Definition of the Concept class.
""" """
from cStringIO import StringIO from io import BytesIO
from logging import getLogger from logging import getLogger
from persistent import Persistent from persistent import Persistent
from zope import component, schema from zope import component, schema
from zope.app.container.btree import BTreeContainer
from zope.app.container.contained import Contained
from zope.app.file.image import Image from zope.app.file.image import Image
from zope.app.security.interfaces import IAuthentication from zope.authentication.interfaces import IAuthentication
from zope.container.btree import BTreeContainer
from zope.container.contained import Contained
from zope.contenttype import guess_content_type from zope.contenttype import guess_content_type
from zope.filerepresentation.interfaces import IReadFile, IWriteFile from zope.filerepresentation.interfaces import IReadFile, IWriteFile
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
@ -35,7 +18,7 @@ from zope.component import adapts
from zope.dublincore.interfaces import IZopeDublinCore from zope.dublincore.interfaces import IZopeDublinCore
from zope.filerepresentation.interfaces import IFileFactory from zope.filerepresentation.interfaces import IFileFactory
from zope.i18nmessageid import MessageFactory from zope.i18nmessageid import MessageFactory
from zope.interface import implements from zope.interface import implementer
from zope.size.interfaces import ISized from zope.size.interfaces import ISized
from zope.security.proxy import removeSecurityProxy from zope.security.proxy import removeSecurityProxy
from zope.traversing.api import getName, getParent from zope.traversing.api import getName, getParent
@ -69,10 +52,9 @@ logger = getLogger('loops.resource')
_ = MessageFactory('loops') _ = MessageFactory('loops')
@implementer(IResourceManager, ILoopsContained)
class ResourceManager(BTreeContainer): class ResourceManager(BTreeContainer):
implements(IResourceManager, ILoopsContained)
def getLoopsRoot(self): def getLoopsRoot(self):
return getParent(self) return getParent(self)
@ -86,13 +68,11 @@ class ResourceManager(BTreeContainer):
return Jeep() return Jeep()
@implementer(IBaseResource, IResource, IResourceManagerContained, IRelatable, ISized)
class Resource(Image, Contained): class Resource(Image, Contained):
# TODO: remove dependency on Image # TODO: remove dependency on Image
implements(IBaseResource, IResource, IResourceManagerContained,
IRelatable, ISized)
proxyInterface = IMediaAssetView # obsolete! proxyInterface = IMediaAssetView # obsolete!
storageName = None storageName = None
@ -149,7 +129,7 @@ class Resource(Image, Contained):
self.resourceType = value self.resourceType = value
def _setData(self, data): def _setData(self, data):
dataFile = StringIO(data) # let File tear it into pieces dataFile = BytesIO(data) # let File tear it into pieces
super(Resource, self)._setData(dataFile) super(Resource, self)._setData(dataFile)
if not self.contentType: if not self.contentType:
self.guessContentType(data) self.guessContentType(data)
@ -158,7 +138,7 @@ class Resource(Image, Contained):
def guessContentType(self, data): def guessContentType(self, data):
# probably obsolete, use zope.contenttype.guess_content_type() # probably obsolete, use zope.contenttype.guess_content_type()
if not isinstance(data, str): # seems to be a file object if not isinstance(data, (bytes, str)): # seems to be a file object
data = data.read(20) data = data.read(20)
if data.startswith('%PDF'): if data.startswith('%PDF'):
self.contentType = 'application/pdf' self.contentType = 'application/pdf'
@ -305,10 +285,9 @@ class Resource(Image, Contained):
# Document and MediaAsset are legacy classes, will become obsolete # Document and MediaAsset are legacy classes, will become obsolete
@implementer(IDocument)
class Document(Resource): class Document(Resource):
implements(IDocument)
proxyInterface = IDocumentView proxyInterface = IDocumentView
def __init__(self, title=u''): def __init__(self, title=u''):
@ -323,19 +302,19 @@ class Document(Resource):
data = property(getData, setData) data = property(getData, setData)
@implementer(IMediaAsset)
class MediaAsset(Resource): class MediaAsset(Resource):
implements(IMediaAsset) pass
# type adapters # type adapters
@implementer(IFile)
class FileAdapter(ResourceAdapterBase): class FileAdapter(ResourceAdapterBase):
""" A type adapter for providing file functionality for resources. """ A type adapter for providing file functionality for resources.
""" """
implements(IFile)
_contextAttributes = list(IFile) + list(IBaseResource) _contextAttributes = list(IFile) + list(IBaseResource)
_adapterAttributes = ResourceAdapterBase._adapterAttributes + ('data',) _adapterAttributes = ResourceAdapterBase._adapterAttributes + ('data',)
@ -361,10 +340,9 @@ class FileAdapter(ResourceAdapterBase):
storageName = property(getStorageName, setStorageName) storageName = property(getStorageName, setStorageName)
@implementer(IExternalFile)
class ExternalFileAdapter(FileAdapter): class ExternalFileAdapter(FileAdapter):
implements(IExternalFile)
_adapterAttributes = (FileAdapter._adapterAttributes _adapterAttributes = (FileAdapter._adapterAttributes
+ ('storageParams', 'externalAddress', 'uniqueAddress', + ('storageParams', 'externalAddress', 'uniqueAddress',
'processingErrors')) 'processingErrors'))
@ -458,19 +436,19 @@ class DocumentAdapter(ResourceAdapterBase):
data = property(getData, setData) data = property(getData, setData)
@implementer(ITextDocument)
class TextDocumentAdapter(DocumentAdapter): class TextDocumentAdapter(DocumentAdapter):
""" A type adapter for providing text document functionality for resources. """ A type adapter for providing text document functionality for resources.
""" """
implements(ITextDocument)
_contextAttributes = list(ITextDocument) + list(IBaseResource) _contextAttributes = list(ITextDocument) + list(IBaseResource)
@implementer(INote)
class NoteAdapter(DocumentAdapter): class NoteAdapter(DocumentAdapter):
""" A note is a short text document with an associated link. """ A note is a short text document with an associated link.
""" """
implements(INote)
_contextAttributes = list(INote) + list(IBaseResource) _contextAttributes = list(INote) + list(IBaseResource)
@property @property
@ -480,9 +458,9 @@ class NoteAdapter(DocumentAdapter):
# other adapters # other adapters
@implementer(IWriteFile)
class DocumentWriteFileAdapter(object): class DocumentWriteFileAdapter(object):
implements(IWriteFile)
adapts(IResource) adapts(IResource)
def __init__(self, context): def __init__(self, context):
@ -502,9 +480,9 @@ class DocumentWriteFileAdapter(object):
notify(ObjectModifiedEvent(self.context, Attributes(IResource, 'data'))) notify(ObjectModifiedEvent(self.context, Attributes(IResource, 'data')))
@implementer(IReadFile)
class DocumentReadFileAdapter(object): class DocumentReadFileAdapter(object):
implements(IReadFile)
adapts(IResource) adapts(IResource)
def __init__(self, context): def __init__(self, context):
@ -525,9 +503,9 @@ class DocumentReadFileAdapter(object):
return len(self.data) return len(self.data)
@implementer(IFileFactory)
class ExternalFileFactory(object): class ExternalFileFactory(object):
implements(IFileFactory)
adapts(IResourceManager) adapts(IResourceManager)
def __init__(self, context): def __init__(self, context):
@ -546,9 +524,9 @@ class ExternalFileFactory(object):
return res return res
@implementer(IIndexAttributes)
class IndexAttributes(object): class IndexAttributes(object):
implements(IIndexAttributes)
adapts(IResource) adapts(IResource)
def __init__(self, context): def __init__(self, context):
@ -573,7 +551,7 @@ class IndexAttributes(object):
if not actx.contentType.startswith('text'): if not actx.contentType.startswith('text'):
return u'' return u''
data = actx.data data = actx.data
if type(data) != unicode: if type(data) != str:
try: try:
data = data.decode('UTF-8') data = data.decode('UTF-8')
except UnicodeDecodeError: except UnicodeDecodeError:
@ -590,14 +568,14 @@ class IndexAttributes(object):
if transform is not None: if transform is not None:
rfa = component.queryAdapter(IReadFile, adapted) rfa = component.queryAdapter(IReadFile, adapted)
if rfa is None: if rfa is None:
data = transform(StringIO(adapted.data)) data = transform(BytesOP(adapted.data))
return data return data
else: else:
return transform(rfa) return transform(rfa)
if not context.contentType.startswith('text'): if not context.contentType.startswith('text'):
return u'' return u''
data = context.data data = context.data
if type(data) != unicode: if type(data) != str:
data = data.decode('UTF-8') data = data.decode('UTF-8')
return data return data
@ -635,10 +613,10 @@ def transformToText(obj, data=None, contentType=None):
#rfa = component.queryAdapter(IReadFile, obj) #rfa = component.queryAdapter(IReadFile, obj)
rfa = IReadFile(obj, None) rfa = IReadFile(obj, None)
if rfa is None: if rfa is None:
if isinstance(data, unicode): if isinstance(data, str):
data = data.encode('UTF-8') data = data.encode('UTF-8')
try: try:
return transform(StringIO(data)) return transform(BytesIO(data))
except: except:
import traceback import traceback
logger.warn(traceback.format_exc()) logger.warn(traceback.format_exc())
@ -647,10 +625,9 @@ def transformToText(obj, data=None, contentType=None):
return transform(rfa) return transform(rfa)
@implementer(schema.interfaces.IIterableSource)
class ResourceTypeSourceList(object): class ResourceTypeSourceList(object):
implements(schema.interfaces.IIterableSource)
def __init__(self, context): def __init__(self, context):
self.context = context self.context = context

View file

@ -18,6 +18,7 @@ dependencies = [
"python-dotenv", "python-dotenv",
"zope.app.renderer", "zope.app.renderer",
"zope.browsermenu", "zope.browsermenu",
"zope.i18n",
"zope.securitypolicy", "zope.securitypolicy",
"zope.site", "zope.site",
"zope.thread", "zope.thread",