Annotation of kupu/plone/plonelibrarytool.py, revision 1.1

1.1     ! dwinter     1: ##############################################################################
        !             2: #
        !             3: # Copyright (c) 2003-2005 Kupu Contributors. All rights reserved.
        !             4: #
        !             5: # This software is distributed under the terms of the Kupu
        !             6: # License. See LICENSE.txt for license text. For a list of Kupu
        !             7: # Contributors see CREDITS.txt.
        !             8: #
        !             9: ##############################################################################
        !            10: """Plone Kupu library tool
        !            11: 
        !            12: This module contains the Plone specific version of the Kupu library
        !            13: tool.
        !            14: 
        !            15: $Id: plonelibrarytool.py 15693 2005-08-05 14:14:33Z duncan $
        !            16: """
        !            17: import os
        !            18: from ZODB.PersistentList import PersistentList
        !            19: from ZODB.PersistentMapping import PersistentMapping
        !            20: from AccessControl import ClassSecurityInfo
        !            21: from OFS.SimpleItem import SimpleItem
        !            22: import Globals
        !            23: from Globals import InitializeClass
        !            24: 
        !            25: from Products.PageTemplates.PageTemplateFile import PageTemplateFile
        !            26: from Products.CMFCore.utils import UniqueObject, getToolByName
        !            27: 
        !            28: from Products.kupu.plone.librarytool import KupuLibraryTool
        !            29: from Products.kupu.plone import permissions, scanner
        !            30: from Products.kupu import kupu_globals
        !            31: from Products.kupu.config import TOOLNAME, TOOLTITLE
        !            32: 
        !            33: _default_libraries = (
        !            34:     dict(id="root",
        !            35:          title="string:Home",
        !            36:          uri="string:${portal_url}",
        !            37:          src="string:${portal_url}/kupucollection.xml",
        !            38:          icon="string:${portal_url}/misc_/CMFPlone/plone_icon"),
        !            39:     dict(id="current",
        !            40:          title="string:Current folder",
        !            41:          uri="string:${folder_url}",
        !            42:          src="string:${folder_url}/kupucollection.xml",
        !            43:          icon="string:${portal_url}/folder_icon.gif"),
        !            44:     dict(id="myitems",
        !            45:          title="string:My recent items",
        !            46:          uri="string:${portal_url}/kupumyitems.xml",
        !            47:          src="string:${portal_url}/kupumyitems.xml",
        !            48:          icon="string:${portal_url}/kupuimages/kupusearch_icon.gif"),
        !            49:     dict(id="recentitems",
        !            50:          title="string:Recent items",
        !            51:          uri="string:${portal_url}/kupurecentitems.xml",
        !            52:          src="string:${portal_url}/kupurecentitems.xml",
        !            53:          icon="string:${portal_url}/kupuimages/kupusearch_icon.gif")
        !            54:     )
        !            55: 
        !            56: _default_resource_types = {
        !            57:     'collection': ('Plone Site', 'Folder', 'Large Plone Folder'),
        !            58:     'mediaobject': ('Image',),
        !            59:     'linkable': ('Document', 'Image', 'File', 'News Item', 'Event')
        !            60:     }
        !            61: 
        !            62: # Tidy up html by exlcluding lots of things.
        !            63: _excluded_html = [
        !            64:   (('center', 'span', 'tt', 'big', 'small', 'u', 's', 'strike', 'basefont', 'font'), ()),
        !            65:   ((), ('dir','lang','valign','halign','border','frame','rules','cellspacing','cellpadding','bgcolor')),
        !            66:   (('table','th','td'),('width','height')),
        !            67: ]
        !            68: 
        !            69: # Default should list all styles used by Kupu
        !            70: _style_whitelist = ['text-align', 'list-style-type', 'float']
        !            71: 
        !            72: _default_paragraph_styles = (
        !            73:     "Heading|h2|Heading",
        !            74:     "Subheading|h3|Subheading",
        !            75:     "Formatted|pre",
        !            76: )
        !            77: 
        !            78: class PloneKupuLibraryTool(UniqueObject, SimpleItem, KupuLibraryTool):
        !            79:     """Plone specific version of the kupu library tool"""
        !            80: 
        !            81:     id = TOOLNAME
        !            82:     meta_type = "Kupu Library Tool"
        !            83:     title = TOOLTITLE
        !            84:     security = ClassSecurityInfo()
        !            85: 
        !            86:     # protect methods provided by super class KupuLibraryTool
        !            87:     security.declareProtected(permissions.QueryLibraries, "getLibraries",
        !            88:                               "getPortalTypesForResourceType")
        !            89:     security.declareProtected(permissions.ManageLibraries, "addLibrary",
        !            90:                               "deleteLibraries", "updateLibraries",
        !            91:                               "moveUp", "moveDown")
        !            92:     security.declareProtected(permissions.ManageLibraries, "addResourceType",
        !            93:                               "updateResourceTypes", "deleteResourceTypes")
        !            94: 
        !            95:     def __init__(self):
        !            96:         self._libraries = PersistentList()
        !            97:         self._res_types = PersistentMapping()
        !            98:         self.linkbyuid = True
        !            99: 
        !           100:     def manage_afterAdd(self, item, container):
        !           101:         # We load default values here, so __init__ can still be used
        !           102:         # in unit tests. Plus, it only makes sense to load these if
        !           103:         # we're being added to a Plone site anyway
        !           104:         for lib in _default_libraries:
        !           105:             self.addLibrary(**lib)
        !           106:         self._res_types.update(_default_resource_types)
        !           107: 
        !           108:     security.declareProtected('View', "getLinkbyuid")
        !           109:     def getLinkbyuid(self):
        !           110:         """Returns 'is linking by UID enabled'?"""
        !           111:         try:
        !           112:             return self.linkbyuid
        !           113:         except AttributeError:
        !           114:             return 1
        !           115: 
        !           116:     security.declareProtected('View', "getTableClassnames")
        !           117:     def getTableClassnames(self):
        !           118:         """Return a list of classnames supported in tables"""
        !           119:         try:
        !           120:             return self.table_classnames
        !           121:         except AttributeError:
        !           122:             return ('plain', 'listing', 'vertical listing', 'listing nosort')
        !           123: 
        !           124:     security.declareProtected('View', "getParagraphStyles")
        !           125:     def getParagraphStyles(self):
        !           126:         """Return a list of classnames supported in tables"""
        !           127:         try:
        !           128:             return self.paragraph_styles
        !           129:         except AttributeError:
        !           130:             return _default_paragraph_styles
        !           131: 
        !           132:     security.declareProtected('View', "getHtmlExclusions")
        !           133:     def getHtmlExclusions(self):
        !           134:         try:
        !           135:             return self.html_exclusions
        !           136:         except AttributeError:
        !           137:             self.html_exclusions = _excluded_html
        !           138:             return self.html_exclusions
        !           139: 
        !           140:     security.declareProtected('View', "getStyleWhitelist")
        !           141:     def getStyleWhitelist(self):
        !           142:         try:
        !           143:             return self.style_whitelist
        !           144:         except AttributeError:
        !           145:             self.style_whitelist = _style_whitelist
        !           146:             return self.style_whitelist
        !           147: 
        !           148:     security.declareProtected('View', "getClassBlacklist")
        !           149:     def getClassBlacklist(self):
        !           150:         return getattr(self, 'class_blacklist', [])
        !           151: 
        !           152:     security.declareProtected('View', "getClassBlacklist")
        !           153:     def installBeforeUnload(self):
        !           154:         return getattr(self, 'install_beforeunload', True)
        !           155: 
        !           156:     security.declareProtected('View', 'isKupuEnabled')
        !           157:     def isKupuEnabled(self, useragent='', allowAnonymous=False, REQUEST=None):
        !           158:         def numerics(s):
        !           159:             '''Convert a string into a tuple of all digit sequences
        !           160:             '''
        !           161:             seq = ['']
        !           162:             for c in s:
        !           163:                 if c.isdigit():
        !           164:                     seq[-1] = seq[-1] + c
        !           165:                 elif seq[-1]:
        !           166:                     seq.append('')
        !           167:             return tuple([ int(val) for val in seq if val])
        !           168: 
        !           169:         # First check whether the user actually wants kupu
        !           170:         pm = getToolByName(self, 'portal_membership')
        !           171:         if pm.isAnonymousUser() and not allowAnonymous:
        !           172:             return False
        !           173: 
        !           174:         user = pm.getAuthenticatedMember()
        !           175:         if user.getProperty('wysiwyg_editor').lower() != 'kupu':
        !           176:             return False
        !           177: 
        !           178:         # Then check whether their browser supports it.
        !           179:         if not useragent:
        !           180:             useragent = REQUEST['HTTP_USER_AGENT']
        !           181: 
        !           182:         if 'Opera' in useragent or 'BEOS' in useragent:
        !           183:             return False
        !           184: 
        !           185:         if not useragent.startswith('Mozilla/'):
        !           186:             return False
        !           187: 
        !           188:         try:
        !           189:             mozillaver = numerics(useragent[len('Mozilla/'):].split(' ')[0])
        !           190:             if mozillaver > (5,0):
        !           191:                 return True
        !           192:             elif mozillaver == (5,0):
        !           193:                 rv = useragent.find(' rv:')
        !           194:                 if rv >= 0:
        !           195:                     verno = numerics(useragent[rv+4:].split(')')[0])
        !           196:                     return verno >= (1,3,1)
        !           197: 
        !           198:             MSIE = useragent.find('MSIE')
        !           199:             if MSIE >= 0:
        !           200:                 verno = numerics(useragent[MSIE+4:].split(';')[0])
        !           201:                 return verno >= (5,5)
        !           202: 
        !           203:         except:
        !           204:             # In case some weird browser makes the test code blow up.
        !           205:             pass
        !           206:         return False
        !           207: 
        !           208:     # ZMI views
        !           209:     manage_options = (SimpleItem.manage_options[1:] + (
        !           210:          dict(label='Config', action='kupu_config'),
        !           211:          dict(label='Libraries', action='zmi_libraries'),
        !           212:          dict(label='Resource types', action='zmi_resource_types'),
        !           213:          dict(label='Documentation', action='zmi_docs'),
        !           214:          dict(label='Status', action='sanity_check'),
        !           215:          ))
        !           216: 
        !           217: 
        !           218:     security.declarePublic('scanIds')
        !           219:     def scanIds(self):
        !           220:         """Finds the relevant source files and the doller/Id/dollar strings they contain"""
        !           221:         return scanner.scanIds()
        !           222: 
        !           223:     security.declarePublic('scanKWS')
        !           224:     def scanKWS(self):
        !           225:         """Check that kupu_wysiwyg_support is up to date"""
        !           226:         return scanner.scanKWS()
        !           227: 
        !           228:     security.declarePublic('docs')
        !           229:     def docs(self):
        !           230:         """Returns Kupu docs formatted as HTML"""
        !           231:         docpath = os.path.join(Globals.package_home(kupu_globals), 'doc')
        !           232:         f = open(os.path.join(docpath, 'PLONE2.txt'), 'r')
        !           233:         _docs = f.read()
        !           234:         return _docs
        !           235: 
        !           236:     security.declareProtected(permissions.ManageLibraries, "zmi_docs")
        !           237:     zmi_docs = PageTemplateFile("zmi_docs.pt", globals())
        !           238:     zmi_docs.title = 'kupu configuration documentation'
        !           239: 
        !           240:     security.declareProtected(permissions.ManageLibraries, "sanity_check")
        !           241:     sanity_check = PageTemplateFile("sanity_check.pt", globals())
        !           242:     sanity_check.title = 'kupu status'
        !           243: 
        !           244:     security.declareProtected(permissions.ManageLibraries, "kupu_config")
        !           245:     kupu_config = PageTemplateFile("kupu_config.pt", globals())
        !           246:     kupu_config.title = 'kupu configuration'
        !           247: 
        !           248:     security.declareProtected(permissions.ManageLibraries, "zmi_libraries")
        !           249:     zmi_libraries = PageTemplateFile("libraries.pt", globals())
        !           250:     zmi_libraries.title = 'kupu configuration'
        !           251: 
        !           252:     security.declareProtected(permissions.ManageLibraries, "zmi_resource_types")
        !           253:     zmi_resource_types = PageTemplateFile("resource_types.pt", globals())
        !           254:     zmi_resource_types.title = 'kupu configuration'
        !           255: 
        !           256:     security.declareProtected(permissions.ManageLibraries,
        !           257:                               "zmi_get_libraries")
        !           258:     def zmi_get_libraries(self):
        !           259:         """Return the libraries sequence for the ZMI view"""
        !           260:         #return ()
        !           261:         def text(value):
        !           262:             return getattr(value, 'text', value)
        !           263:         return [dict([(key, text(value)) for key, value in lib.items()])
        !           264:                 for lib in self._libraries]
        !           265: 
        !           266:     security.declareProtected(permissions.ManageLibraries,
        !           267:                               "zmi_add_library")
        !           268:     def zmi_add_library(self, id, title, uri, src, icon, REQUEST):
        !           269:         """Add a library through the ZMI"""
        !           270:         self.addLibrary(id, title, uri, src, icon)
        !           271:         REQUEST.RESPONSE.redirect(self.absolute_url() + '/zmi_libraries')
        !           272: 
        !           273:     security.declareProtected(permissions.ManageLibraries,
        !           274:                               "zmi_update_libraries")
        !           275:     def zmi_update_libraries(self, libraries, REQUEST):
        !           276:         """Update libraries through the ZMI"""
        !           277:         self.updateLibraries(libraries)
        !           278:         REQUEST.RESPONSE.redirect(self.absolute_url() + '/zmi_libraries')
        !           279: 
        !           280:     security.declareProtected(permissions.ManageLibraries,
        !           281:                               "zmi_delete_libraries")
        !           282:     def zmi_delete_libraries(self, indices, REQUEST):
        !           283:         """Delete libraries through the ZMI"""
        !           284:         self.deleteLibraries(indices)
        !           285:         REQUEST.RESPONSE.redirect(self.absolute_url() + '/zmi_libraries')
        !           286: 
        !           287:     security.declareProtected(permissions.ManageLibraries,
        !           288:                               "zmi_move_up")
        !           289:     def zmi_move_up(self, indices, REQUEST):
        !           290:         """Move libraries up through the ZMI"""
        !           291:         self.moveUp(indices)
        !           292:         REQUEST.RESPONSE.redirect(self.absolute_url() + '/zmi_libraries')
        !           293: 
        !           294:     security.declareProtected(permissions.ManageLibraries,
        !           295:                               "zmi_move_down")
        !           296:     def zmi_move_down(self, indices, REQUEST):
        !           297:         """Move libraries down through the ZMI"""
        !           298:         self.moveDown(indices)
        !           299:         REQUEST.RESPONSE.redirect(self.absolute_url() + '/zmi_libraries')
        !           300: 
        !           301:     security.declarePublic("zmi_get_default_library")
        !           302:     def zmi_get_default_library(self):
        !           303:         """Return the default selected library for the ZMI view"""
        !           304:         return getattr(self, '_default_library', '')
        !           305: 
        !           306:     security.declareProtected(permissions.ManageLibraries,
        !           307:                               "zmi_set_default_library")
        !           308:     def zmi_set_default_library(self, defid=''):
        !           309:         """Return the libraries sequence for the ZMI view"""
        !           310:         self._default_library = defid
        !           311: 
        !           312:     security.declareProtected(permissions.ManageLibraries,
        !           313:                               "zmi_get_type_mapping")
        !           314:     def zmi_get_type_mapping(self):
        !           315:         """Return the type mapping for the ZMI view"""
        !           316:         return [(res_type, tuple(portal_type)) for res_type, portal_type
        !           317:                 in self._res_types.items()]
        !           318: 
        !           319:     security.declareProtected(permissions.ManageLibraries,
        !           320:                               "zmi_add_resource_type")
        !           321:     def zmi_add_resource_type(self, resource_type, portal_types, REQUEST):
        !           322:         """Add resource type through the ZMI"""
        !           323:         self.addResourceType(resource_type, portal_types)
        !           324:         REQUEST.RESPONSE.redirect(self.absolute_url() + '/zmi_resource_types')
        !           325: 
        !           326:     security.declareProtected(permissions.ManageLibraries,
        !           327:                               "zmi_update_resource_types")
        !           328:     def zmi_update_resource_types(self, type_info, REQUEST):
        !           329:         """Update resource types through the ZMI"""
        !           330:         self.updateResourceTypes(type_info)
        !           331:         REQUEST.RESPONSE.redirect(self.absolute_url() + '/zmi_resource_types')
        !           332: 
        !           333:     security.declareProtected(permissions.ManageLibraries,
        !           334:                               "zmi_delete_resource_types")
        !           335:     def zmi_delete_resource_types(self, resource_types, REQUEST):
        !           336:         """Delete resource types through the ZMI"""
        !           337:         self.deleteResourceTypes(resource_types)
        !           338:         REQUEST.RESPONSE.redirect(self.absolute_url() + '/zmi_resource_types')
        !           339: 
        !           340:     security.declareProtected(permissions.ManageLibraries,
        !           341:                               "configure_kupu")
        !           342:     def configure_kupu(self,
        !           343:         linkbyuid, table_classnames, html_exclusions, style_whitelist, class_blacklist,
        !           344:         installBeforeUnload=None, parastyles=None,
        !           345:         REQUEST=None):
        !           346:         """Delete resource types through the ZMI"""
        !           347:         self.linkbyuid = int(linkbyuid)
        !           348:         self.table_classnames = table_classnames
        !           349:         if installBeforeUnload is not None:
        !           350:             self.install_beforeunload = bool(installBeforeUnload)
        !           351:         if parastyles:
        !           352:             self.paragraph_styles = [ line.strip() for line in parastyles if line.strip() ]
        !           353: 
        !           354:         newex = html_exclusions[-1]
        !           355:             
        !           356:         html_exclusions = [ (tuple(h.get('tags', ())), tuple(h.get('attributes', ())))
        !           357:             for h in html_exclusions[:-1] if h.get('keep')]
        !           358:         
        !           359:         tags, attr = newex.get('tags', ()), newex.get('attributes', ())
        !           360:         if tags or attr:
        !           361:             tags = tuple(tags.replace(',',' ').split())
        !           362:             attr = tuple(attr.replace(',',' ').split())
        !           363:             html_exclusions.append((tags, attr))
        !           364: 
        !           365:         self.html_exclusions = html_exclusions
        !           366: 
        !           367:         self.style_whitelist = list(style_whitelist)
        !           368:         self.class_blacklist = list(class_blacklist)
        !           369: 
        !           370:         if REQUEST:
        !           371:             REQUEST.RESPONSE.redirect(self.absolute_url() + '/kupu_config')
        !           372: 
        !           373: InitializeClass(PloneKupuLibraryTool)

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>