def create_thumbnail(self, size, quality=None): # invalidate the cache of the thumbnail with the given size first invalidate_cache(self.user, size) try: orig = self.avatar.storage.open(self.avatar.name, 'rb').read() image = Image.open(StringIO(orig)) quality = quality or AVATAR_THUMB_QUALITY (w, h) = image.size if w != size or h != size: if w > h: diff = (w - h) / 2 image = image.crop((diff, 0, w - diff, h)) else: diff = (h - w) / 2 image = image.crop((0, diff, w, h - diff)) if image.mode != "RGB": image = image.convert("RGB") image = image.resize((size, size), AVATAR_RESIZE_METHOD) thumb = StringIO() image.save(thumb, AVATAR_THUMB_FORMAT, quality=quality) thumb_file = ContentFile(thumb.getvalue()) else: thumb_file = ContentFile(orig) thumb = self.avatar.storage.save(self.avatar_name(size), thumb_file) except IOError: return # What should we do here? Render a "sorry, didn't work" img?
def delete(self, *args, **kwargs): invalidate_cache(self.user) for size in self.existing_thumbnail_sizes.split(','): self.avatar.storage.delete(self.avatar_name(size)) self.avatar.storage.delete(self.avatar_name()) super(Avatar, self).delete(*args, **kwargs)
def create_thumbnail(self, size, quality=None): # invalidate the cache of the thumbnail with the given size first invalidate_cache(self.user, size) try: orig = self.avatar.storage.open(self.avatar.name, 'rb') image = Image.open(orig) image = self.transpose_image(image) quality = quality or settings.AVATAR_THUMB_QUALITY w, h = image.size if w != size or h != size: if w > h: diff = int((w - h) / 2) image = image.crop((diff, 0, w - diff, h)) else: diff = int((h - w) / 2) image = image.crop((0, diff, w, h - diff)) if image.mode not in ("RGB", "RGBA"): image = image.convert("RGB") image = image.resize((size, size), settings.AVATAR_RESIZE_METHOD) thumb = six.BytesIO() image.save(thumb, settings.AVATAR_THUMB_FORMAT, quality=quality) thumb_file = ContentFile(thumb.getvalue()) else: thumb_file = File(orig) thumb = self.avatar.storage.save(self.avatar_name(size), thumb_file) except IOError: return # What should we do here? Render a "sorry, didn't work" img?
def save(self, *args, **kwargs): square = kwargs.pop('square', False) avatars = Avatar.objects.filter(user=self.user) if self.pk: avatars = avatars.exclude(pk=self.pk) if AVATAR_MAX_AVATARS_PER_USER > 1: if self.primary: avatars = avatars.filter(primary=True) avatars.update(primary=False) else: # Iterate through each one so that their delete() # functions get called. for av in avatars: av.delete() invalidate_cache(self.user) is_new = False if not self.id: is_new = True super(Avatar, self).save(*args, **kwargs) if is_new: create_default_thumbnails.delay(self, created=True, square=square)
def create_thumbnail(self, width, height, quality=None): # invalidate the cache of the thumbnail with the given size first invalidate_cache(self.user, width, height) try: orig = self.avatar.storage.open(self.avatar.name, 'rb').read() image = Image.open(StringIO(orig)) except IOError: return # What should we do here? Render a "sorry, didn't work" img? quality = quality or AVATAR_THUMB_QUALITY (w, h) = image.size if w != width or h != width: ratioReal = 1.0 * w / h ratioWant = 1.0 * width / height if ratioReal > ratioWant: diff = int((w - ( h * ratioWant) ) / 2) image = image.crop((diff, 0, w - diff, h)) else: diff = int((h - ( w / ratioWant ) ) / 2) image = image.crop((0, diff, w, h - diff)) if image.mode != "RGB": image = image.convert("RGB") image = image.resize((width, height), AVATAR_RESIZE_METHOD) thumb = StringIO() image.save(thumb, AVATAR_THUMB_FORMAT, quality=quality) thumb_file = ContentFile(thumb.getvalue()) else: thumb_file = ContentFile(orig) thumb = self.avatar.storage.save(self.avatar_name(width, height), thumb_file)
def create_thumbnail(self, size, quality=None): # invalidate the cache of the thumbnail with the given size first invalidate_cache(self.user, size) try: orig = self.avatar.storage.open(self.avatar.name, 'rb').read() image = Image.open(StringIO(orig)) except IOError: return # What should we do here? Render a "sorry, didn't work" img? quality = quality or AVATAR_THUMB_QUALITY (w, h) = image.size if w != size or h != size: if w > h: diff = (w - h) / 2 image = image.crop((diff, 0, w - diff, h)) else: diff = (h - w) / 2 image = image.crop((0, diff, w, h - diff)) if image.mode != "RGB": image = image.convert("RGB") image = image.resize((size, size), AVATAR_RESIZE_METHOD) thumb = StringIO() image.save(thumb, AVATAR_THUMB_FORMAT, quality=quality) thumb_file = ContentFile(thumb.getvalue()) else: thumb_file = ContentFile(orig) thumb = self.avatar.storage.save(self.avatar_name(size), thumb_file)
def save(self, *args, **kwargs): try: current = Avatar.objects.get(pk=self.pk) if current.avatar != self.avatar: current.avatar.delete() except: pass invalidate_cache(self.user) super(Avatar, self).save(*args, **kwargs)
def save(self, *args, **kwargs): avatars = Avatar.objects.filter(user=self.user) if self.pk: avatars = avatars.exclude(pk=self.pk) if AVATAR_MAX_AVATARS_PER_USER > 1: if self.primary: avatars = avatars.filter(primary=True) avatars.update(primary=False) else: avatars.delete() invalidate_cache(self.user) super(Avatar, self).save(*args, **kwargs)
def create_thumbnail(self, size, quality=None, square=False): """ Creates a thumbnail for this avatar. If Square is False, the image will retain it's original proportions. Also, when square is false, size then dictates the height of the new image """ if self.primary: square = True # invalidate the cache of the thumbnail with the given size first invalidate_cache(self.user, size) try: orig = self.get_storage().open(self.avatar.name, 'rb').read() image = Image.open(StringIO(orig)) except IOError: return # What should we do here? Render a "sorry, didn't work" img? quality = quality or AVATAR_THUMB_QUALITY (w, h) = image.size if w != size or h != size: if square: if w > h: diff = (w - h) / 2 image = image.crop((diff, 0, w - diff, h)) else: diff = (h - w) / 2 image = image.crop((0, diff, w, h - diff)) w = size h = size else: scaling_ratio = 1.0*size/h h = int(size) w = int(scaling_ratio * w) if image.mode != "RGB": image = image.convert("RGB") image = image.resize((w, h), AVATAR_RESIZE_METHOD) thumb = StringIO() image.save(thumb, AVATAR_THUMB_FORMAT, quality=quality) thumb_file = ContentFile(thumb.getvalue()) else: thumb_file = ContentFile(orig) thumb = self.get_storage().save(self.avatar_name(size), thumb_file) # Save this image size in the database so we know what thumbnails have already been created size_string = str(size) if self.existing_thumbnail_sizes: size_string = ',' + size_string self.existing_thumbnail_sizes += size_string self.save()
def crop(request, avatar_id, extra_context=None, next_override=None, crop_form=CropAvatarForm, *args, **kwargs): if extra_context is None: extra_context = {} avatar = get_object_or_404(request.user.avatar_set, pk=avatar_id) crop_avatar_form = crop_form(request.POST or None) if request.method == "POST": if crop_avatar_form.is_valid(): avatar.set_crop(request.POST) avatar.save() # Invalidate the cache to prevent wrong avatar appearing invalidate_cache(request.user) messages.success(request, _("Successfully edited avatar.") ) if notification: _notification_updated(request, avatar) return HttpResponseRedirect(next_override or _get_next(request)) (w, h) = (avatar.avatar.width, avatar.avatar.height) if w>h: d_w = AVATAR_CROP_VIEW_SIZE d_h = int(AVATAR_CROP_VIEW_SIZE * float(h)/w) else: d_w = int(AVATAR_CROP_VIEW_SIZE * float(w)/h) d_h = AVATAR_CROP_VIEW_SIZE return render_to_response( 'avatar/crop.html', extra_context, context_instance = RequestContext( request, { 'avatar': avatar, 'crop_avatar_form': crop_avatar_form, 'orig_size': (w, h), 'display_size': (d_w, d_h), 'preview_size': (AVATAR_DEFAULT_SIZE,AVATAR_DEFAULT_SIZE), 'initial_crop': min(d_w, d_h), 'next': next_override or _get_next(request), } ) )
def change(request, extra_context=None, next_override=None, upload_form=UploadAvatarForm, primary_form=PrimaryAvatarForm, *args, **kwargs): if extra_context is None: extra_context = {} avatar, avatars = _get_avatars(request.user) if avatar: kwargs = {'initial': {'choice': avatar.id}} else: kwargs = {} upload_avatar_form = upload_form(user=request.user, **kwargs) primary_avatar_form = primary_form(request.POST or None, user=request.user, avatars=avatars, **kwargs) if request.method == "POST": updated = False if 'choice' in request.POST and primary_avatar_form.is_valid(): avatar = Avatar.objects.get( id=primary_avatar_form.cleaned_data['choice']) avatar.primary = True avatar.save() updated = True invalidate_cache(request.user) messages.success(request, _("Successfully updated your avatar.")) if updated: avatar_updated.send(sender=Avatar, user=request.user, avatar=avatar) return redirect(next_override or _get_next(request)) context = { 'avatar': avatar, 'avatars': avatars, 'upload_avatar_form': upload_avatar_form, 'primary_avatar_form': primary_avatar_form, 'next': next_override or _get_next(request) } context.update(extra_context) return render(request, 'avatar/change.html', context)
def change(request, extra_context=None, next_override=None, upload_form=UploadAvatarForm, primary_form=PrimaryAvatarForm, *args, **kwargs): if extra_context is None: extra_context = {} avatar, avatars = _get_avatars(request.user) if avatar: kwargs = {'initial': {'choice': avatar.id}} else: kwargs = {} upload_avatar_form = upload_form(user=request.user, **kwargs) primary_avatar_form = primary_form(request.POST or None, user=request.user, avatars=avatars, **kwargs) if request.method == "POST": updated = False if 'choice' in request.POST and primary_avatar_form.is_valid(): avatar = Avatar.objects.get(id= primary_avatar_form.cleaned_data['choice']) avatar.primary = True avatar.save() updated = True # Invalidate the cache to prevent wrong avatar appearing invalidate_cache(request.user) messages.success(request, _("Successfully updated your avatar.") ) if updated and notification: _notification_updated(request, avatar) return HttpResponseRedirect(next_override or _get_next(request)) return render_to_response( 'avatar/change.html', extra_context, context_instance = RequestContext( request, { 'avatar': avatar, 'avatars': avatars, 'upload_avatar_form': upload_avatar_form, 'primary_avatar_form': primary_avatar_form, 'next': next_override or _get_next(request), } ) )
def delete(request, extra_context=None, next_override=None, *args, **kwargs): if extra_context is None: extra_context = {} avatar, avatars = _get_avatars(request.user) delete_avatar_form = DeleteAvatarForm(request.POST or None, user=request.user, avatars=avatars) if request.method == 'POST': if delete_avatar_form.is_valid(): ids = delete_avatar_form.cleaned_data['choices'] if unicode(avatar.id) in ids and avatars.count() > len(ids): # Find the next best avatar, and set it as the new primary for a in avatars: if unicode(a.id) not in ids: a.primary = True a.save() if notification: _notification_updated(request, a) break Avatar.objects.filter(id__in=ids).delete() # Invalidate the cache to prevent wrong avatar appearing # when only one's left invalidate_cache(request.user) messages.success(request, _("Successfully deleted the requested avatars.") ) return HttpResponseRedirect(next_override or _get_next(request)) return render_to_response( 'avatar/confirm_delete.html', extra_context, context_instance = RequestContext( request, { 'avatar': avatar, 'avatars': avatars, 'delete_avatar_form': delete_avatar_form, 'next': next_override or _get_next(request), } ) )
def delete(self, *args, **kwargs): invalidate_cache(self.user) super(Avatar, self).delete(*args, **kwargs)
def invalidate_avatar_cache(sender, instance, **kwargs): invalidate_cache(instance.contact)
def delete_thumbnail(self, size): # invalidate the cache of the thumbnail with the given size first invalidate_cache(self.user, size) self.avatar.storage.delete(self.avatar_name(size))
def save(self, force_insert=False, force_update=False, *args, **kwargs): # Always invalidate avatar cache, rather than check change in staff status, since this is infrequent invalidate_cache(self) super(CustomUser, self).save(force_insert, force_update, *args, **kwargs)
def invalidate_avatar_cache(sender, instance, **kwargs): if hasattr(instance, 'user'): invalidate_cache(instance.user)
def invalidate_avatar_cache(sender, instance, **kwargs): try: invalidate_cache(instance.user) except User.DoesNotExist: pass
def remove_avatar_thumbnails(instance=None, **kwargs): if instance.avatar: for size in settings.AVATAR_AUTO_GENERATE_SIZES: if instance.thumbnail_exists(size): instance.avatar.storage.delete(instance.avatar_name(size)) invalidate_cache(instance.user)
def invalidate_avatar_cache(sender, instance, **kwargs): try: invalidate_cache(instance.user) except: #logging.error('user does not exist') logger.error('Avatar: user does not exist.')
def invalidate_avatar_cache(sender, instance, **kwargs): try: invalidate_cache(instance.user) except User.DoesNotExist: # Intentional: this can be triggered when deleting users in the admin. pass
def invalidate_avatar_cache(sender, instance, **kwargs): invalidate_cache(instance.user)
def delete(self, *args, **kwargs): invalidate_cache(self.content_object) super(Avatar, self).delete(*args, **kwargs)