def test_no_registry(self): context = FauxContext() request = FauxRequest() alsoProvides(request, IAttributeAnnotatable) setRequest(request) @implementer(IPurgePaths) @adapter(FauxContext) class FauxPurgePaths(object): def __init__(self, context): self.context = context def getRelativePaths(self): return ['/foo', '/bar'] def getAbsolutePaths(self): return [] provideAdapter(FauxPurgePaths, name="test1") notify(Purge(context)) self.assertEqual({}, dict(IAnnotations(request)))
def __call__(self): direction = self.request.get("direction", None) if not direction: return 0 elif direction == 'right' or direction == '90': method = 6 elif direction == 'left' or direction == '270' or direction == '-90': method = 8 else: method = 1 image_data = self.context.image._getData() new_image_data, width, height, exif_data = rotate_image(image_data, method=method) self.context.image._setData(new_image_data) # Throw away saved scales and cropping info annotations = IAnnotations(self.context) if 'plone.scale' in annotations: del annotations['plone.scale'] if 'plone.app.imagecropping' in annotations: del annotations['plone.app.imagecropping'] # Purge caches if needed notify(Purge(self.context)) return 1
def test_enabled(self): context = FauxContext() request = FauxRequest() alsoProvides(request, IAttributeAnnotatable) setRequest(request) registry = Registry() registry.registerInterface(ICachePurgingSettings) provideUtility(registry, IRegistry) settings = registry.forInterface(ICachePurgingSettings) settings.enabled = True settings.cachingProxies = ('http://localhost:1234',) @implementer(IPurgePaths) @adapter(FauxContext) class FauxPurgePaths(object): def __init__(self, context): self.context = context def getRelativePaths(self): return ['/foo', '/bar'] def getAbsolutePaths(self): return [] provideAdapter(FauxPurgePaths, name="test1") notify(Purge(context)) self.assertEqual({'plone.cachepurging.urls': set(['/foo', '/bar'])}, dict(IAnnotations(request)))
def test_request_not_annotatable(self): context = FauxContext() request = FauxRequest() setRequest(request) registry = Registry() registry.registerInterface(ICachePurgingSettings) provideUtility(registry, IRegistry) settings = registry.forInterface(ICachePurgingSettings) settings.enabled = True settings.cachingProxies = ('http://localhost:1234',) @implementer(IPurgePaths) @adapter(FauxContext) class FauxPurgePaths(object): def __init__(self, context): self.context = context def getRelativePaths(self): return ['/foo', '/bar'] def getAbsolutePaths(self): return [] provideAdapter(FauxPurgePaths, name="test1") try: notify(Purge(context)) except: self.fail()
def __call__(self): if not isCachePurgingEnabled(): return "Caching not enabled" notify(Purge(self.context)) return "Queued"
def purgeOnMovedOrRemoved(object, event): request = getRequest() confirmed_delete = ('delete_confirmation' in request.URL and request.REQUEST_METHOD == 'POST' and 'form.submitted' in request.form) if IObjectRemovedEvent.providedBy(event) and not confirmed_delete: # ignore extra delete events return # Don't purge when added if IObjectAddedEvent.providedBy(event): return if isPurged(object) and 'portal_factory' not in request.URL: notify(Purge(object)) parent = object.getParentNode() if parent: notify(Purge(parent))
def set(self, data): # when setting data, we need to purge scales/image data... # XXX hack? try: scale_key = self.key.replace('.data.', '.scale.') del self.annotations[scale_key] except KeyError: pass for k, v in data.items(): if INamedImage.providedBy(v): mtime_key = '{0}_mtime'.format(k) if (self.key not in self.annotations or k not in self.annotations[self.key] or (self.key in self.annotations and data[k] != self.annotations[self.key][k])): # set modification time of the image notify(Purge(self.tile)) data[mtime_key] = repr(time.time()) else: data[mtime_key] = self.annotations[self.key].get( mtime_key, '') self.annotations[self.key] = PersistentDict(data) notify(ObjectModifiedEvent(self.context))
def purgeTranslationsOnModified(object, event): """ When the canonical is purged, also purge the translations. This is for content with language independent fields. """ if isPurged(object) and object.isCanonical(): translations = object.getTranslations(include_canonical=False) for translation, state in translations.values(): notify(Purge(translation))
def remove(self, fieldname, scale, surpress_event=False): # remove info from annotation key = self._key(fieldname, scale) if key in list(self._storage.keys()): del self._storage[key] self._invalidate_scale(fieldname, scale) if not surpress_event: notify(CroppingInfoRemovedEvent(self.context)) notify(Purge(self.context))
def __call__(self): obj = self.event.object if hasLinguaPloneInstalled and ITranslatable.providedBy(obj): translations = obj.getTranslations() if len(translations) > 1: for trans, _state in translations.values(): logging.info("*** PURGING VARNISH CACHE: %s", trans.absolute_url()) notify(Purge(trans))
def set(self, data): for k, v in data.items(): if INamedImage.providedBy(v): if (self.key not in self.annotations or k not in self.annotations[self.key] or (self.key in self.annotations and data[k] != self.annotations[self.key][k])): # set modification time of the image notify(Purge(self.tile)) data['%s_mtime' % k] = '%f' % time.time() self.annotations[self.key] = PersistentDict(data)
def unarchive(self, context, custom_message=None, initiator=None, reason=None): """ Unarchive the object :param context: object which is going to be unarchived :param custom_message: Custom message explaining why the object was unarchived :param initiator: the user id or name which commissioned the archival :param reason: reason id for which the object was archived """ noLongerProvides(context, IObjectArchived) now = DateTime() context.setExpirationDate(None) date = DateTime() wftool = getToolByName(context, 'portal_workflow') has_workflow = wftool.getChainFor(context) mtool = getToolByName(context, 'portal_membership') if not has_workflow: # NOP return state = wftool.getInfoFor(context, 'review_state') actor = mtool.getAuthenticatedMember().getId() if custom_message: reason += u" (%s)" % custom_message comments = (u"Unarchived by %(actor)s on %(date)s by request " u"from %(initiator)s with reason: %(reason)s" % { 'actor': actor, 'initiator': initiator, 'reason': reason, 'date': date.ISO8601() }) for wfname in context.workflow_history.keys(): history = context.workflow_history[wfname] history += ({ 'action': 'UnArchive', 'review_state': state, 'actor': actor, 'comments': comments, 'time': now, }, ) context.workflow_history[wfname] = history context.workflow_history._p_changed = True context.reindexObject() notify(Purge(context))
def set(self, data): for k, v in data.items(): if INamedImage.providedBy(v): if (self.key not in self.annotations or k not in self.annotations[self.key] or (self.key in self.annotations and data[k] != self.annotations[self.key][k])): # set modification time of the image notify(Purge(self.tile)) data['{0}_mtime'.format(k)] = '%f' % time.time() self.annotations[self.key] = PersistentDict(data) notify(ObjectModifiedEvent(self.context))
def getSlotAndSignUserUpForIt(self, slotIDLabel): status = 'error' error = '' allowSignupForMultipleSlots = self.context.allowSignupForMultipleSlots (date, time) = slotIDLabel.split(' @ ') day = self.context.getDay(date) timeSlot = day.getTimeSlot(time, True) slotTitleLabel = timeSlot.getLabel() allowWaitingList = timeSlot.allowWaitingList numberOfAvailableSlots = timeSlot.getNumberOfAvailableSlots() if (not allowSignupForMultipleSlots ) and self.context.countSlotsByEmail(self.email) > 0: error = _( 'You are already signed up for a slot in this signup sheet.') elif timeSlot.isUserSignedUpForThisSlot(self.email): error = _('You are already signed up for this slot.') elif allowWaitingList or numberOfAvailableSlots > 0: person = self.createPersonObject(timeSlot) if numberOfAvailableSlots > 0: if self.context.signupsRequireConfirmation: if self.isEmailValid(): self.sendWaitForConfirmationEmail( self.context, slotTitleLabel, person) status = 'unconfirmed' else: # sign up user directly if there are available slots and # no confirmation by the manager is required self.signupPerson(person) status = 'signedup' else: self.putPersonOnWaitingList(person) status = 'waiting' # purge signup view to make sure everybody sees updated info notify(Purge(self.context)) else: error = _( 'The slot you selected is already full. Please select a different one.' ) result = dict() result['slotLabel'] = slotTitleLabel result['status'] = status result['error'] = error self.results.append(result)
def cancelReservation(self): selectedSlots = self.request.get('selectedSlot', None) if type(selectedSlots) != list: selectedSlots = [selectedSlots] if selectedSlots != [None]: for slot in selectedSlots: self.signOffCurrentUserFromSlot(slot) # purge request to refresh view for everyone notify(Purge(self.context)) self.request.response.redirect(self.context.absolute_url() + '/@@show-reservations')
def test_enabled_no_paths(self): context = FauxContext() request = FauxRequest() alsoProvides(request, IAttributeAnnotatable) setRequest(request) registry = Registry() registry.registerInterface(ICachePurgingSettings) provideUtility(registry, IRegistry) settings = registry.forInterface(ICachePurgingSettings) settings.enabled = True settings.cachingProxies = ('http://localhost:1234',) notify(Purge(context)) self.assertEqual({'plone.cachepurging.urls': set()}, dict(IAnnotations(request)))
def _crop(self): def coordinate(x): return int(round(float(self.request.form.get(x)))) x1 = coordinate('x1') y1 = coordinate('y1') x2 = coordinate('x2') y2 = coordinate('y2') box = (x1, y1, x2, y2) field = getattr(self.context, self.fieldname, None) image_size = field.getImageSize() # short-cut: if the "crop" contains the whole image, do nothing if (0, 0, image_size[0], image_size[1]) == box: return data = field.data original_file = StringIO(data) image = PIL.Image.open(original_file) image_format = image.format or self.DEFAULT_FORMAT cropped_image = image.crop(box) cropped_image_file = StringIO() cropped_image.save(cropped_image_file, image_format, quality=100) cropped_image_file.seek(0) # Overwrite the image field data field.data = cropped_image_file.read() # Throw away saved scales and cropping info annotations = IAnnotations(self.context) if 'plone.scale' in annotations: del annotations['plone.scale'] if 'plone.app.imagecropping' in annotations: del annotations['plone.app.imagecropping'] # Purge caches if needed notify(Purge(self.context))
def purgeOnMovedOrRemoved(object, event): # Don't purge when added if event.oldName is not None and event.oldParent is not None: if isPurged(object): notify(Purge(object))
def purge(obj): """ Purge object """ if isPurged(obj): notify(Purge(obj))
def archive(self, context, initiator=None, reason=None, custom_message=None, archive_date=None): """Archive the object :param context: given object that should be archived :param initiator: the user id or name which commissioned the archival :param reason: reason id for which the object was archived :param custom_message: Custom message explaining why the object was archived :param archive_date: DateTime object which sets the expiration date of the object """ initiator = safe_unicode(initiator) reason = safe_unicode(reason) custom_message = safe_unicode(custom_message) wftool = getToolByName(context, 'portal_workflow') has_workflow = wftool.getChainFor(context) if not has_workflow: # NOP return date = archive_date and archive_date or DateTime() alsoProvides(context, IObjectArchived) context.setExpirationDate(date) # refactor this setting from here, without these assignments to self # the test for is_archived fails self.archive_date = date self.initiator = initiator self.custom_message = custom_message self.reason = reason state = wftool.getInfoFor(context, 'review_state') mtool = getToolByName(context, 'portal_membership') actor = mtool.getAuthenticatedMember().getId() rv = NamedVocabulary('eea.workflow.reasons') vocab = rv.getVocabularyDict(context) reason = vocab.get(reason, "Other") if custom_message: reason += u" (%s)" % custom_message comments = (u"Archived by %(actor)s on %(date)s by request " u"from %(initiator)s with reason: %(reason)s" % { 'actor': actor, 'initiator': initiator, 'reason': reason, 'date': date.ISO8601() }) for wfname in context.workflow_history.keys(): history = context.workflow_history[wfname] history += ({ 'action': 'Archive', 'review_state': state, 'actor': actor, 'comments': comments, 'time': date, }, ) context.workflow_history[wfname] = history context.workflow_history._p_changed = True context.reindexObject() notify(Purge(context))
def purgeOnModified(object, event): if isPurged(object): notify(Purge(object))