def remove_orphan_annotations(context): """Remove annotations left behind after tile removal. The bug was fixed in bf386fee but no upgrade step was provided to clean up the objects. """ catalog = api.portal.get_tool('portal_catalog') results = catalog(object_provides=ICover.__identifier__) logger.info('Checking {0} objects for orphan annotations'.format(len(results))) for brain in results: cover = brain.getObject() tiles = cover.list_tiles() try: orphan_annotations = [ k for k in cover.__annotations__.keys() if k.startswith(PREFIX) and k.split('.')[3] not in tiles ] for k in orphan_annotations: del(cover.__annotations__[k]) if orphan_annotations: msg = 'Removed {0} annotations from "{1}"' logger.info( msg.format(len(orphan_annotations), cover.absolute_url_path())) except AttributeError: pass # cover with no annotations
def remove_orphan_annotations(context): """Remove annotations left behind after tile removal. The bug was fixed in bf386fee but no upgrade step was provided to clean up the objects. """ catalog = api.portal.get_tool('portal_catalog') results = catalog(object_provides=ICover.__identifier__) logger.info('Checking {0} objects for orphan annotations'.format( len(results))) for brain in results: cover = brain.getObject() tiles = cover.list_tiles() try: orphan_annotations = [ k for k in cover.__annotations__.keys() if k.startswith(PREFIX) and k.split('.')[3] not in tiles ] for k in orphan_annotations: del (cover.__annotations__[k]) if orphan_annotations: msg = 'Removed {0} annotations from "{1}"' logger.info( msg.format(len(orphan_annotations), cover.absolute_url_path())) except AttributeError: pass # cover with no annotations
def issue_201(context): """Depend on collective.js.bootstrap See: https://github.com/collective/collective.cover/issues/201 """ # first we take care of the CSS registry css_tool = api.portal.get_tool('portal_css') old_id = '++resource++collective.cover/bootstrap.min.css' if old_id in css_tool.getResourceIds(): css_tool.unregisterResource(old_id) logger.info('"{0}"" resource was removed'.format(old_id)) css_tool.cookResources() logger.info('CSS resources were cooked') # now we mess with the JS registry js_tool = api.portal.get_tool('portal_javascripts') old_id = '++resource++collective.cover/bootstrap.min.js' new_id = '++resource++collective.js.bootstrap/js/bootstrap.min.js' if old_id in js_tool.getResourceIds(): if new_id in js_tool.getResourceIds(): js_tool.unregisterResource(old_id) logger.info('"{0}" resource was removed"'.format(old_id)) else: js_tool.renameResource(old_id, new_id) logger.info('"{0}" resource was renamed to "{1}"'.format( old_id, new_id)) js_tool.cookResources() logger.info('JS resources were cooked')
def issue_201(context): """Depend on collective.js.bootstrap See: https://github.com/collective/collective.cover/issues/201 """ # first we take care of the CSS registry css_tool = api.portal.get_tool('portal_css') old_id = '++resource++collective.cover/bootstrap.min.css' if old_id in css_tool.getResourceIds(): css_tool.unregisterResource(old_id) logger.info('"{0}"" resource was removed'.format(old_id)) css_tool.cookResources() logger.info('CSS resources were cooked') # now we mess with the JS registry js_tool = api.portal.get_tool('portal_javascripts') old_id = '++resource++collective.cover/bootstrap.min.js' new_id = '++resource++collective.js.bootstrap/js/bootstrap.min.js' if old_id in js_tool.getResourceIds(): if new_id in js_tool.getResourceIds(): js_tool.unregisterResource(old_id) logger.info('"{0}" resource was removed"'.format(old_id)) else: js_tool.renameResource(old_id, new_id) logger.info('"{0}" resource was renamed to "{1}"'.format(old_id, new_id)) js_tool.cookResources() logger.info('JS resources were cooked')
def purge_deleted_tiles(context): """Purge all annotations of deleted tiles.""" results = api.content.find(object_provides=ICover.__identifier__) logger.info('About to update {0} objects'.format(len(results))) for b in results: obj = b.getObject() obj.purge_deleted_tiles() logger.info('Purged annotations on ' + b.getPath())
def update_references(setup_tool): """Update references used for link integrity checking.""" catalog = api.portal.get_tool('portal_catalog') query = dict(object_provides=ICover.__identifier__) results = catalog.unrestrictedSearchResults(**query) for brain in results: obj = brain.getObject() update_link_integrity(obj, None) logger.info('References updated on {0} objects.'.format(len(results)))
def update_references(setup_tool): """Update references used for link integrity checking.""" catalog = api.portal.get_tool('portal_catalog') query = dict(object_provides=ICover.__identifier__) results = catalog.unrestrictedSearchResults(**query) for brain in results: obj = brain.getObject() try: update_link_integrity(obj, None) except AssertionError: msg = 'Duplicated tiles in {0} ({1}); skipping' logger.error(msg.format(obj.absolute_url(), obj.list_tiles())) logger.info('References updated on {0} objects.'.format(len(results)))
def deprecate_resource_registries(setup_tool): """Deprecate resource registries.""" js_tool = api.portal.get_tool('portal_javascripts') for js in JS: if js in js_tool.getResourceIds(): js_tool.unregisterResource(id=js) assert js not in js_tool.getResourceIds() # nosec css_tool = api.portal.get_tool('portal_css') for css in CSS: if css in css_tool.getResourceIds(): css_tool.unregisterResource(id=css) assert css not in css_tool.getResourceIds() # nosec logger.info('Static resources successfully removed from registries')
def get_valid_objects(): """Generate a list of objects associated with valid brains.""" results = api.content.find(portal_type='collective.cover.content') logger.info('Found {0} objects in the catalog'.format(len(results))) for b in results: try: obj = b.getObject() except (AttributeError, KeyError): obj = None if obj is None: # warn on broken entries in the catalog msg = 'Invalid object reference in the catalog: {0}' logger.warn(msg.format(b.getPath())) continue yield obj
def register_calendar_tile(setup_tool): """Register calendar tile and make it available for inmediate use.""" tile = u'collective.cover.calendar' record = dict(name='plone.app.tiles') registered_tiles = api.portal.get_registry_record(**record) if tile not in registered_tiles: registered_tiles.append(tile) api.portal.set_registry_record(value=registered_tiles, **record) record = dict(interface=ICoverSettings, name='available_tiles') available_tiles = api.portal.get_registry_record(**record) if tile not in available_tiles: available_tiles.append(tile) api.portal.set_registry_record(value=available_tiles, **record) logger.info('Calendar tile registered and made available')
def show_remote_url_field(setup_tool): """Show remote_url field on Basic tiles.""" logger.info(__doc__) results = get_valid_objects() for cover in results: for tile_id in cover.list_tiles(TILE_TYPES): tile = cover.get_tile(tile_id) data_mgr = ITileDataManager(tile) data = data_mgr.get() remote_url = data.get('remote_url') if not remote_url: continue # show information on possible issue path = cover.absolute_url_path() msg = '{0} ("{1}"): remote_url={2}' logger.info(msg.format(path, tile_id, remote_url))
def fix_resources_references(setup_tool): """Fix resource references after static files reorganization.""" profile = 'profile-{0}:default'.format(PROJECTNAME) css_tool = api.portal.get_tool('portal_css') _rename_resources(css_tool, RESOURCES_TO_FIX) logger.info('Updated css references.') js_tool = api.portal.get_tool('portal_javascripts') _rename_resources(js_tool, RESOURCES_TO_FIX) logger.info('Updated javascript references.') setup_tool.runImportStepFromProfile(profile, 'controlpanel') logger.info('Updated controlpanel icon reference.') setup_tool.runImportStepFromProfile(profile, 'typeinfo') logger.info('Updated content type icon reference.')
def remove_css_class_layout(context): """Remove CSS class from registry and cover layouts.""" logger.info('CSS classes will be removed from Cover layouts.') # Fix registry layouts registry = getUtility(IRegistry) settings = registry.forInterface(ICoverSettings) fixed_layouts = {} for name, layout in settings.layouts.iteritems(): fixed_layouts[name] = _remove_css_class_layout(layout) settings.layouts = fixed_layouts logger.info('Registry layouts were updated.') # Fix cover layouts covers = context.portal_catalog(object_provides=ICover.__identifier__) logger.info('Layout of {0} objects will be updated'.format(len(covers))) for cover in covers: obj = cover.getObject() obj.cover_layout = _remove_css_class_layout(obj.cover_layout) logger.info('"{0}" was updated'.format(obj.absolute_url_path()))
def simplify_layout(context): """Move column-size to parent and remove data attribute from layout.""" logger.info('Cover layouts will be simplified.') # Fix registry layouts registry = getUtility(IRegistry) settings = registry.forInterface(ICoverSettings) fixed_layouts = {} for name, layout in settings.layouts.iteritems(): fixed_layouts[name] = _simplify_layout(layout) settings.layouts = fixed_layouts logger.info('Registry layouts were updated.') # Fix cover layouts covers = context.portal_catalog(object_provides=ICover.__identifier__) logger.info('Layout of {0} objects will be updated'.format(len(covers))) for cover in covers: obj = cover.getObject() obj.cover_layout = _simplify_layout(obj.cover_layout) logger.info('"{0}" was updated'.format(obj.absolute_url_path()))
def fix_image_field_modification_time(context): """Fix image modification time to be float timestamp instead of string.""" covers = context.portal_catalog(object_provides=ICover.__identifier__) logger.info('About to update {0} objects'.format(len(covers))) for cover in covers: obj = cover.getObject() for tile_id in obj.list_tiles(): tile = obj.get_tile(tile_id) dmgr = ITileDataManager(tile) data = dmgr.get() for k, v in data.items(): if not INamedImage.providedBy(v): continue mtime_key = '{0}_mtime'.format(k) data[mtime_key] = float(data[mtime_key]) # need to set changes directly into annotation dmgr.annotations[dmgr.key] = PersistentDict(data) msg = 'Tile {0} at {1} updated' logger.info(msg.format(tile_id, cover.getPath())) logger.info('Done')
def register_resource(setup_tool): """Add layout_edit.js to registered resources.""" js_tool = api.portal.get_tool('portal_javascripts') js_tool.registerScript(id=JS, compression='none', authenticated=True) assert JS in js_tool.getResourceIds() # nosec logger.info('Script registered')
def update_role_map(setup_tool): """Adds new permission to embed code in the Embed tile.""" profile = 'profile-{0}:default'.format(PROJECTNAME) setup_tool.runImportStepFromProfile(profile, 'rolemap') logger.info('Role map updated.')
def cook_css_resources(context): """Cook css resources. """ css_tool = api.portal.get_tool('portal_css') css_tool.cookResources() logger.info('CSS resources were cooked')
def change_configlet_permissions(context): """Allow Site Administrator to access configlet.""" cptool = api.portal.get_tool('portal_controlpanel') configlet = cptool.getActionObject('Products/cover') configlet.permissions = ('collective.cover: Setup', ) logger.info('configlet permissions updated')
def upgrade_carousel_tiles_custom_url(context): """Update structure of tiles inheriting from the list tile.""" # Get covers covers = context.portal_catalog(portal_type='collective.cover.content') logger.info('About to update {0} objects'.format(len(covers))) tiles_to_update = _get_tiles_inherit_from_list(context) logger.info('{0} tile types will be updated ({1})'.format( len(tiles_to_update), ', '.join(tiles_to_update))) for cover in covers: obj = cover.getObject() tile_ids = obj.list_tiles(types=tiles_to_update) for tile_id in tile_ids: tile = obj.get_tile(tile_id) old_data = ITileDataManager(tile).get() uuids = old_data['uuids'] if isinstance(uuids, dict): # This tile is fixed, carry on logger.info( 'Tile %s at %s was already updated' % (tile_id, cover.getPath()) ) continue if not uuids: # This tile did not have data, so ignore logger.info( 'Tile %s at %s did not have any data' % (tile_id, cover.getPath()) ) continue new_data = dict() order = 0 for uuid in uuids: if uuid not in new_data.keys(): entry = dict() entry[u'order'] = unicode(order) new_data[uuid] = entry order += 1 old_data['uuids'] = new_data ITileDataManager(tile).set(old_data) logger.info( 'Tile %s at %s updated' % (tile_id, cover.getPath()) ) logger.info('Done')
def upgrade_carousel_tiles_custom_url(context): """Update structure of tiles inheriting from the list tile.""" # Get covers covers = context.portal_catalog(portal_type='collective.cover.content') logger.info('About to update {0} objects'.format(len(covers))) tiles_to_update = _get_tiles_inherit_from_list(context) msg = '{0} tile types will be updated ({1})' logger.info(msg.format(len(tiles_to_update), ', '.join(tiles_to_update))) for cover in covers: obj = cover.getObject() tile_ids = obj.list_tiles(types=tiles_to_update) for tile_id in tile_ids: tile = obj.get_tile(tile_id) old_data = ITileDataManager(tile).get() uuids = old_data['uuids'] if isinstance(uuids, dict): # This tile is fixed, carry on msg = 'Tile {0} at {1} was already updated' logger.info(msg.format(tile_id, cover.getPath())) continue if not uuids: # This tile did not have data, so ignore msg = 'Tile {0} at {1} did not have any data' logger.info(msg.format(tile_id, cover.getPath())) continue new_data = dict() order = 0 for uuid in uuids: if uuid not in new_data.keys(): entry = dict() entry[u'order'] = unicode(order) new_data[uuid] = entry order += 1 old_data['uuids'] = new_data ITileDataManager(tile).set(old_data) logger.info('Tile {0} at {1} updated'.format( tile_id, cover.getPath())) logger.info('Done')
def cook_javascript_resources(context): """Cook javascript resources. """ js_tool = api.portal.get_tool('portal_javascripts') js_tool.cookResources() logger.info('Javascript resources were cooked')
def change_configlet_permissions(context): """Allow Site Administrator to access configlet.""" cptool = api.portal.get_tool('portal_controlpanel') configlet = cptool.getActionObject('Products/cover') configlet.permissions = ('collective.cover: Setup',) logger.info('configlet permissions updated')
def fix_persistentmap_to_dict(context): """Internal structure was reverted from using PersistentMapping. Fix tiles here""" # Get covers covers = context.portal_catalog(portal_type='collective.cover.content') logger.info('About to update {0} objects'.format(len(covers))) tiles_to_update = _get_tiles_inherit_from_list(context) logger.info('{0} tile types will be updated ({1})'.format( len(tiles_to_update), ', '.join(tiles_to_update))) for cover in covers: obj = cover.getObject() tile_ids = obj.list_tiles(types=tiles_to_update) for tile_id in tile_ids: tile = obj.get_tile(tile_id) old_data = ITileDataManager(tile).get() uuids = old_data['uuids'] if isinstance(uuids, dict): # This tile is fixed, carry on msg = 'Tile {0} at {1} was already updated' logger.info(msg.format(tile_id, cover.getPath())) continue if not uuids: # This tile did not have data, so ignore msg = 'Tile {0} at {1} did not have any data' logger.info(msg.format(tile_id, cover.getPath())) continue new_data = dict() for k, v in uuids.items(): new_data[k] = v old_data['uuids'] = new_data ITileDataManager(tile).set(old_data) msg = 'Tile {0} at {1} updated' logger.info(msg.format(tile_id, cover.getPath())) logger.info('Done')
def cook_css_resources(context): # pragma: no cover """Cook CSS resources.""" css_tool = api.portal.get_tool('portal_css') css_tool.cookResources() logger.info('CSS resources were cooked')
def cook_javascript_resources(context): # pragma: no cover """Cook JavaScript resources.""" js_tool = api.portal.get_tool('portal_javascripts') js_tool.cookResources() logger.info('JavaScript resources were cooked')
def register_calendar_script(setup_tool): """Register script to deal with tile's next/prev events.""" js_tool = api.portal.get_tool('portal_javascripts') js_tool.registerResource('++resource++collective.cover/js/main.js') logger.info('Calendar script registered')