def ensure_child_ordering_object_ids_are_native_strings(container): """Make sure the ordering stored on parent contains only native_string object ids. This function can be used to fix ordering object ids stored on a parent object in a `DefaultOrdering` ordering adapter. When changing object ordering via PATCH request we used to incorrectly store ids of reordered resouces as unicode instead of a bytestring (on python 2). This lead to mixed types being stored in the ordering annotations and subsequently mixed types being returned when calling `objectIds` of a container. The problem only exists with python 2 so we do nothing when we are called on python 3 by mistake. """ if six.PY3: return if not IAnnotatable.providedBy(container): return annotations = IAnnotations(container) if ORDER_KEY not in annotations: return fixed_ordering = PersistentList( safe_utf8(item_id) for item_id in annotations[ORDER_KEY]) annotations[ORDER_KEY] = fixed_ordering
def upgrade_attribute_storage(context): portal = getSite() catalog = getToolByName(portal, 'portal_catalog') query = {} query[ 'object_provides'] = 'collective.geolocationbehavior.geolocation.IGeolocatableMarker' # noqa results = catalog(**query) log.info('There are {0} in total, stating migration...'.format( len(results))) for result in results: try: obj = result.getObject() except: log.warning('Not possible to fetch object from catalog result for ' 'item: {0}.'.format(result.getPath())) continue if not IAnnotatable.providedBy(obj): log.warning( 'The object at {0} does provide annotation capabilities, ' 'skipping.'.format(obj.absolute_url())) continue annotations = IAnnotations(obj) oldvalue = annotations.get(GEO_ANNOTATION_KEY, None) geolocation = getattr(oldvalue, 'geolocation', None) if geolocation and not IGeolocatable(obj).geolocation: # Only write the old value if there is no new value yet IGeolocatable(obj).geolocation = geolocation notify(ObjectModifiedEvent(obj)) log.info('Set geolocation lat: {0}, lng: {1} for {2}'.format( geolocation.latitude, geolocation.longitude, obj.absolute_url())) if oldvalue: del annotations[GEO_ANNOTATION_KEY] obj.reindexObject( ) # reindex - old IGeolocatableMarker doesn't exist anymore # noqa
def __setattr__(self, attr, value): """ """ if not IAnnotatable.providedBy(self.context): alsoProvides(self.context, IAnnotatable) d = IAnnotations(self.context).get(ANNOTATION_KEY, {}) d[attr] = value IAnnotations(self.context)[ANNOTATION_KEY] = d
def notify_content_object_deleted(obj, event): """Remove all comments of a content object when the content object has been deleted. """ if IAnnotatable.providedBy(obj): conversation = IConversation(obj) while conversation: del conversation[conversation.keys()[0]]
def supports_snapshots(obj): """Checks if the object supports snapshots Only objects which can hold an annotation storage can be auditable :param obj: Content object :returns: True/False """ return IAnnotatable.providedBy(obj)
def outdate_item(ob, *arg, **kw): err = list() value = kw.get("outdated_status", None) value = not not value if IAnnotatable.providedBy(ob): IAnnotations(ob)[ANNOTATION_KEY] = value else: err.append("Object %s does not support annotations" % ob.absolute_url()) return err
def __getattr__(self, key): """ """ context = self.__dict__['context'] if not IAnnotatable.providedBy(context): alsoProvides(context, IAnnotatable) annos = IAnnotations(context).get(ANNOTATION_KEY, {}) if annos.has_key(key): return annos[key] raise AttributeError
def getExisting(self): portal_catalog = getToolByName(self.context, 'portal_catalog') if not IAnnotatable.providedBy(self.context): return '' ann = IAnnotations(self.context) existing_uid = ann.get(config.EXISTING_SWITCHED_CONTENT_UID, '') existing_url = '' if existing_uid: res = portal_catalog(UID=existing_uid) existing = len(res) and res[0].getObject() existing_url = existing and existing.absolute_url() return existing_url
def get(self, name): # first check overrides if exists and is True overrides = getattr(self, '%s_override' % name, True) if not overrides: return None context = aq_inner(self.context) if not IAnnotatable.providedBy(self.context): return None annotations = IAnnotations(context) if annotations.has_key(PERSEO): return annotations[PERSEO].get(name, None) return None
def get(self, name): # first check overrides if exists and is True overrides = getattr(self, "%s_override" % name, True) if not overrides: return None context = aq_inner(self.context) if not IAnnotatable.providedBy(self.context): return None annotations = IAnnotations(context) if PERSEO in annotations: # print "return %s --> %s" % (name, annotations[PERSEO].get(name, None)) return annotations[PERSEO].get(name, None) return None
def _global_unprotect(self): # portal_memberdata._members cache will be written sometimes. if IPloneSiteRoot.providedBy(getSite()): unprotected_write(getToolByName(getSite(), 'portal_memberdata')._members) context = self.getContext() # always allow writes to context's annotations. if IAnnotatable.providedBy(context): annotations = IAnnotations(context) unprotected_write(annotations) if CONTEXT_ASSIGNMENT_KEY in annotations: # also allow writes to context portlet assignments unprotected_write(annotations[CONTEXT_ASSIGNMENT_KEY])
def _global_unprotect(self): # portal_memberdata._members cache will be written sometimes. if IPloneSiteRoot.providedBy(getSite()): unprotected_write( getToolByName(getSite(), 'portal_memberdata')._members) context = self.getContext() # always allow writes to context's annotations. if IAnnotatable.providedBy(context): annotations = IAnnotations(context) unprotected_write(annotations) if CONTEXT_ASSIGNMENT_KEY in annotations: # also allow writes to context portlet assignments unprotected_write(annotations[CONTEXT_ASSIGNMENT_KEY])
def upgrade_attribute_storage(context): portal = getSite() catalog = getToolByName(portal, 'portal_catalog') query = {} query['object_provides'] = IDXEvent.__identifier__ results = catalog(**query) log.info('There are {0} in total, stating migration...'.format( len(results))) for result in results: try: event = result.getObject() except: log.warning( 'Not possible to fetch event object from catalog result for ' 'item: {0}.'.format(result.getPath())) continue if not IAnnotatable.providedBy(event): log.warning( 'The event at {0} does provide annotation capabilities, ' 'skipping.'.format(event.absolute_url())) continue annotations = IAnnotations(event) did_work = False for behavior in BEHAVIOR_LIST: for name in behavior.names(): fullname = '{0}.{1}'.format(behavior.__identifier__, name) oldvalue = annotations.get(fullname, None) # Only write the old value if there is no new value yet if oldvalue and not getattr(event, name, None): setattr(event, name, oldvalue) did_work = True # The old IEventSummary behavior is gone, just look for the old name # inside the annotation storage oldvalue = annotations.get( 'plone.app.event.dx.behaviors.IEventSummary.text', None) if oldvalue and not getattr(event, 'text', None): setattr(event, 'text', oldvalue) did_work = True if did_work: notify(ObjectModifiedEvent(event)) log.debug('Handled event at {0}'.format(event.absolute_url()))
def upgrade_attribute_storage(context): portal = getSite() catalog = getToolByName(portal, 'portal_catalog') query = {} query['object_provides'] = 'collective.geolocationbehavior.geolocation.IGeolocatableMarker' # noqa results = catalog(**query) log.info('There are {0} in total, stating migration...'.format( len(results))) for result in results: try: obj = result.getObject() except: log.warning( 'Not possible to fetch object from catalog result for ' 'item: {0}.'.format(result.getPath())) continue if not IAnnotatable.providedBy(obj): log.warning( 'The object at {0} does provide annotation capabilities, ' 'skipping.'.format(obj.absolute_url())) continue annotations = IAnnotations(obj) oldvalue = annotations.get(GEO_ANNOTATION_KEY, None) geolocation = getattr(oldvalue, 'geolocation', None) if geolocation and not IGeolocatable(obj).geolocation: # Only write the old value if there is no new value yet IGeolocatable(obj).geolocation = geolocation notify(ObjectModifiedEvent(obj)) log.info('Set geolocation lat: {0}, lng: {1} for {2}'.format( geolocation.latitude, geolocation.longitude, obj.absolute_url()) ) if oldvalue: del annotations[GEO_ANNOTATION_KEY] obj.reindexObject() # reindex - old IGeolocatableMarker doesn't exist anymore # noqa
def is_outdated(obj): if IAnnotatable.providedBy(obj): return IAnnotations(obj).get('slc.outdated', False)
def test_object_annotatable(self): self.assertTrue(IAnnotatable.providedBy(self.s1))
def get_actions_for(request): if IAnnotatable.providedBy(request): annotations = IAnnotations(request) else: annotations = {} return annotations.setdefault("collective.gsa64.actions", {})
def set_settings(request, registry): settings = registry.forInterface(IConnectionSettings) if IAnnotatable.providedBy(request): IAnnotations(request).setdefault("collective.gsa64.settings", settings)
def retrieve(self): ST = [] pc = self.portal_catalog link_checker = self.portal_linkchecker async = getUtility(IAsyncService) sm = getSecurityManager() # INitialize the helperattribute to store paths to retrieve objpaths = getattr(link_checker, 'objpaths', None) cleanup = self.REQUEST.get('cleanup', False) if objpaths is None or cleanup=='1': link_checker.objpaths = [] objpaths = [] # Check wheter we start fresh or need to resume resume = self.REQUEST.get('resume') debug = self.REQUEST.get('debug') LOG("LCRetrieveByPath", INFO, "Resuming retrieval with %s paths" % len(objpaths)) if len(objpaths)==0 and not resume: path = self.REQUEST.get('path', '/'.join(self.getPhysicalPath())) alllangs = self.portal_languages.getSupportedLanguages() langs = self.REQUEST.get('langs', alllangs) print "path: %s" %path if "%s" in path: paths = [path%lang for lang in langs] else: paths = [path] LOG("LCRetrieveByPath", INFO, "Starting retrieval") for path in paths: LOG("LCRetrieveByPath", INFO, "> Path %s"%path) results = pc(Language='all', path=path) objpaths = [x.getPath() for x in results] link_checker.objpaths += objpaths LOG("LCRetrieveByPath", INFO, "> %s results found"%len(results)) # DONE Retrieving objpaths, start checkretrieval cnt = 0 objpaths = [x for x in link_checker.objpaths] total = len(objpaths) for path in objpaths: if debug: print path try: ob = self.unrestrictedTraverse(path) except: continue if not ob: continue if not sm.checkPermission(ModifyPortalContent, ob): continue if (not IReferenceable.providedBy(ob)): continue outdated = IAnnotatable.providedBy(ob) and \ IAnnotations(ob).get(ANNOTATION_KEY, False) or False if outdated: LOG("CMFLinkChecker", INFO, "unregistering %s, object is outdated" % path) links = link_checker.database.getLinksForObject(ob) link_ids = [x.getId() for x in links] job = async.queueJob(unregister_async, link_checker, link_ids) job.addCallbacks(failure=job_failure_callback) continue if not is_publically_visible(ob): LOG('CMFLinkChecker', INFO, "Skipping %s, obj is not public" % path) continue job = async.queueJob(retrieve_async, ob, path, online=True) job.addCallbacks(failure=job_failure_callback) LOG("LCRetrieveByPath", INFO, "> Retrieved %s"%path) ST.append("retrieved %s" % path) link_checker.objpaths.remove(path) link_checker._p_changed = 1 cnt += 1 if cnt%10==0: transaction.commit() LOG("LCRetrieveByPath", INFO, "Committing %s of %s" %(cnt, total)) LOG("LCRetrieveByPath", INFO, "Fertig") return "\n".join(ST)
def LCRetrieveByDate(self, skiplist=[]): """Retrieves the links from all objects in the site by Date.""" sincedate = DateTime()-6*30 since = self.REQUEST.get('since') if since is not None: since = DateTime(since) sincedate = since or sincedate offline = self.REQUEST.get('offline', '') pwt = self.portal_workflow lc = self.portal_linkchecker async = getUtility(IAsyncService) sm = getSecurityManager() try: server = lc.database._getWebServiceConnection() except: server = None if server is None and offline!='1': raise RuntimeError, "The site could not be crawled because no " \ "connection to the lms could be established." # # Not actually necessary on every crawl, but it doesn't seem to work # # in the installer, so this seems the next logical place to do it. # self.portal_catalog.reindexIndex('portal_linkchecker_uid', self.REQUEST) if 1: # gather all objects that are of a type we can check for links objects = self.portal_catalog(Language='all', modified={'query':sincedate,'range':'min'}) os_ = len(objects) zLOG.LOG('CMFLinkChecker', zLOG.INFO, "%d objects will be crawled" % os_) i = 0 for res in objects: i += 1 zLOG.LOG("CMFLinkChecker", zLOG.BLATHER, "Site Crawl Status", "%s of %s (%s)" % (i, os_, res.getPath())) ob = res.getObject() if ob is None: # Maybe the catalog isn't up to date continue outdated = IAnnotatable.providedBy(ob) and \ IAnnotations(ob).get(ANNOTATION_KEY, False) or False if outdated: zLOG.LOG("CMFLinkChecker", zLOG.INFO, "unregistering %s, object is outdated" % res.getPath()) links = lc.database.getLinksForObject(ob) link_ids = [x.getId() for x in links] job = async.queueJob(unregister_async, lc, link_ids) callback = job.addCallbacks(failure=job_failure_callback) continue try: state = pwt.getInfoFor(ob, 'review_state') except: state = "undefined" if state not in ALLOWED_STATES: zLOG.LOG("CMFLinkChecker", zLOG.BLATHER, "unregistering, object is not public: %s" % state) links = lc.database.getLinksForObject(ob) link_ids = [x.getId() for x in links] job = async.queueJob(unregister_async, lc, link_ids) callback = job.addCallbacks(failure=job_failure_callback) continue if not sm.checkPermission(ModifyPortalContent, ob): continue if (not IReferenceable.providedBy(ob)): continue job = async.queueJob(retrieve_async, ob, res.getPath(), online=True) callback = job.addCallbacks(failure=job_failure_callback) if not i % 500 : transaction.savepoint() zLOG.LOG('CMFLinkChecker', zLOG.INFO, "Crawling site - commited after %d objects" %(i)) return "finished"
def __set__(self, obj, val): if obj is None: raise AttributeError("Can't set attribute") if IAnnotatable.providedBy(obj.context): IAnnotations(obj.context)[ANNOTATION_KEY] = val
def isAnnotatable(self): """Does the object observed expect to be annotated? """ return IAnnotatable.providedBy(self.obj)
def checkPerseoTabAvailable(self): """ Checks visibility of SEO tab for context """ return not IPloneSiteRoot.providedBy(self.context) and IAnnotatable.providedBy(self.context)
def __get__(self, obj, objtype=None): if obj is None: return self if IAnnotatable.providedBy(obj.context): return IAnnotations(obj.context).get(ANNOTATION_KEY, False) return False