def save(self): request = self.context['request'] upload = self.validated_data['upload'] self.instance = Attachment( secret=Attachment.generate_new_secret(), filetype=self.filetype, size=upload.size, uploader=request.user, uploader_name=request.user.username, uploader_slug=request.user.slug, uploader_ip=request.user_ip, filename=upload.name, ) if self.is_upload_image(upload): try: self.instance.set_image(upload) except IOError: raise serializers.ValidationError({ 'upload': [_("Uploaded image was corrupted or invalid.")], }) else: self.instance.set_file(upload) self.instance.save() return self.instance
def test_attachments_sync(self): """command synchronizes attachments""" filetype = AttachmentType.objects.order_by('id').last() # create 5 expired orphaned attachments cutoff = timezone.now() - timedelta(minutes=settings.MISAGO_ATTACHMENT_ORPHANED_EXPIRE) cutoff -= timedelta(minutes=5) for _ in range(5): Attachment.objects.create( secret=Attachment.generate_new_secret(), filetype=filetype, size=1000, uploaded_on=cutoff, uploader_name='bob', uploader_slug='bob', uploader_ip='127.0.0.1', filename='testfile_{}.zip'.format(Attachment.objects.count() + 1), ) # create 5 expired non-orphaned attachments category = Category.objects.get(slug='first-category') post = testutils.post_thread(category).first_post for _ in range(5): Attachment.objects.create( secret=Attachment.generate_new_secret(), filetype=filetype, size=1000, uploaded_on=cutoff, post=post, uploader_name='bob', uploader_slug='bob', uploader_ip='127.0.0.1', filename='testfile_{}.zip'.format(Attachment.objects.count() + 1), ) # create 5 fresh orphaned attachments for _ in range(5): Attachment.objects.create( secret=Attachment.generate_new_secret(), filetype=filetype, size=1000, uploader_name='bob', uploader_slug='bob', uploader_ip='127.0.0.1', filename='testfile_{}.zip'.format(Attachment.objects.count() + 1), ) command = clearattachments.Command() out = StringIO() call_command(command, stdout=out) command_output = out.getvalue().splitlines()[-1].strip() self.assertEqual(command_output, "Cleared 5 attachments") self.assertEqual(Attachment.objects.count(), 10)
def create_attachment(self, request): upload = request.FILES.get('upload') if not upload: raise UploadError(_("No file has been uploaded.")) user_roles = set(r.pk for r in request.user.get_roles()) filetype = validate_filetype(upload, user_roles) validate_filesize(upload, filetype, request.user.acl_cache['max_attachment_size']) attachment = Attachment( secret=Attachment.generate_new_secret(), filetype=filetype, size=upload.size, uploader=request.user, uploader_name=request.user.username, uploader_slug=request.user.slug, uploader_ip=request.user_ip, filename=upload.name, ) if is_upload_image(upload): try: attachment.set_image(upload) except IOError: raise UploadError(_("Uploaded image was corrupted or invalid.")) else: attachment.set_file(upload) attachment.save() add_acl(request.user, attachment) return Response(AttachmentSerializer(attachment, context={'user': request.user}).data)
def test_attachments_sync(self): """command synchronizes attachments""" filetype = AttachmentType.objects.order_by('id').last() # create 5 expired orphaned attachments cutoff = timezone.now() - timedelta(minutes=settings.MISAGO_ATTACHMENT_ORPHANED_EXPIRE) cutoff -= timedelta(minutes=5) for _ in range(5): Attachment.objects.create( secret=Attachment.generate_new_secret(), filetype=filetype, size=1000, uploaded_on=cutoff, uploader_name='bob', uploader_slug='bob', filename='testfile_{}.zip'.format(Attachment.objects.count() + 1), ) # create 5 expired non-orphaned attachments category = Category.objects.get(slug='first-category') post = testutils.post_thread(category).first_post for _ in range(5): Attachment.objects.create( secret=Attachment.generate_new_secret(), filetype=filetype, size=1000, uploaded_on=cutoff, post=post, uploader_name='bob', uploader_slug='bob', filename='testfile_{}.zip'.format(Attachment.objects.count() + 1), ) # create 5 fresh orphaned attachments for _ in range(5): Attachment.objects.create( secret=Attachment.generate_new_secret(), filetype=filetype, size=1000, uploader_name='bob', uploader_slug='bob', filename='testfile_{}.zip'.format(Attachment.objects.count() + 1), ) command = clearattachments.Command() out = StringIO() call_command(command, stdout=out) command_output = out.getvalue().splitlines()[-1].strip() self.assertEqual(command_output, "Cleared 5 attachments") self.assertEqual(Attachment.objects.count(), 10)
def create_attachment(self, request): upload = request.FILES.get('upload') if not upload: raise ValidationError(_("No file has been uploaded.")) user_roles = set(r.pk for r in request.user.get_roles()) filetype = validate_filetype(upload, user_roles) validate_filesize(upload, filetype, request.user.acl_cache['max_attachment_size']) attachment = Attachment( secret=Attachment.generate_new_secret(), filetype=filetype, size=upload.size, uploader=request.user, uploader_name=request.user.username, uploader_slug=request.user.slug, uploader_ip=request.user_ip, filename=upload.name, ) if is_upload_image(upload): try: attachment.set_image(upload) except IOError: raise ValidationError(_("Uploaded image was corrupted or invalid.")) else: attachment.set_file(upload) attachment.save() add_acl(request.user, attachment) return Response(AttachmentSerializer(attachment, context={'user': request.user}).data)
def mock_attachment(self, user=True, post=None): return Attachment.objects.create( secret=Attachment.generate_new_secret(), filetype=self.filetype, post=post, size=1000, uploader=self.user if user else None, uploader_name=self.user.username, uploader_slug=self.user.slug, filename='testfile_{}.zip'.format(Attachment.objects.count() + 1), )
def mock_attachment(self, user=True, post=None): return Attachment.objects.create( secret=Attachment.generate_new_secret(), filetype=self.filetype, post=post, size=1000, uploader=self.user if user else None, uploader_name=self.user.username, uploader_slug=self.user.slug, uploader_ip='127.0.0.1', filename='testfile_{}.zip'.format(Attachment.objects.count() + 1), )
def mock_attachment(self, post=None, file=None, image=None, thumbnail=None): return Attachment.objects.create( secret=Attachment.generate_new_secret(), filetype=self.filetype, post=post, size=1000, uploader=self.user, uploader_name=self.user.username, uploader_slug=self.user.slug, filename='testfile_%s.zip' % (Attachment.objects.count() + 1), file=None, image=None, thumbnail=None, )
class NewAttachmentSerializer(serializers.Serializer): upload = serializers.FileField() def validate_upload(self, upload): user = self.context['request'].user user_roles = set(r.pk for r in user.get_roles()) max_attachment_size = user.acl_cache['max_attachment_size'] self.filetype = self.validate_filetype(upload, user_roles) self.validate_filesize(upload, self.filetype, max_attachment_size) return upload def validate_filetype(self, upload, user_roles): filename = upload.name.strip().lower() queryset = AttachmentType.objects.filter(status=AttachmentType.ENABLED) for filetype in queryset.prefetch_related('limit_uploads_to'): for extension in filetype.extensions_list: if filename.endswith('.%s' % extension): break else: continue if filetype.mimetypes_list and upload.content_type not in filetype.mimetypes_list: continue if filetype.limit_uploads_to.exists(): allowed_roles = set(r.pk for r in filetype.limit_uploads_to.all()) if not user_roles & allowed_roles: continue return filetype raise serializers.ValidationError( _("You can't upload files of this type.")) def validate_filesize(self, upload, filetype, hard_limit): if upload.size > hard_limit * 1024: message = _( "You can't upload files larger than %(limit)s (your file has %(upload)s)." ) raise serializers.ValidationError( message % { 'upload': filesizeformat(upload.size).rstrip('.0'), 'limit': filesizeformat(hard_limit * 1024).rstrip('.0'), }) if filetype.size_limit and upload.size > filetype.size_limit * 1024: message = _( "You can't upload files of this type larger than %(limit)s (your file has %(upload)s)." ) raise serializers.ValidationError( message % { 'upload': filesizeformat(upload.size).rstrip('.0'), 'limit': filesizeformat(filetype.size_limit * 1024).rstrip('.0'), }) def is_upload_image(self, upload): filename = upload.name.strip().lower() for extension in IMAGE_EXTENSIONS: if filename.endswith('.%s' % extension): return True return False def save(self): request = self.context['request'] upload = self.validated_data['upload'] self.instance = Attachment( secret=Attachment.generate_new_secret(), filetype=self.filetype, size=upload.size, uploader=request.user, uploader_name=request.user.username, uploader_slug=request.user.slug, uploader_ip=request.user_ip, filename=upload.name, ) if self.is_upload_image(upload): try: self.instance.set_image(upload) except IOError: raise serializers.ValidationError({ 'upload': [_("Uploaded image was corrupted or invalid.")], }) else: self.instance.set_file(upload) self.instance.save() return self.instance
def move_attachments(stdout, style): query = 'SELECT * FROM misago_attachment ORDER BY id' posts = [] attachment_types = {} for attachment_type in AttachmentType.objects.all(): for mimetype in attachment_type.mimetypes_list: attachment_types[mimetype] = attachment_type for attachment in fetch_assoc(query): if attachment['content_type'] not in attachment_types: stdout.write( style.WARNING("Skipping attachment: %s (invalid type)" % attachment['name'])) continue if not attachment['post_id']: stdout.write( style.WARNING("Skipping attachment: %s (orphaned)" % attachment['name'])) continue filetype = attachment_types[attachment['content_type']] post_pk = movedids.get('post', attachment['post_id']) post = Post.objects.get(pk=post_pk) if post_pk not in posts: posts.append(post_pk) uploader = None if attachment['user_id']: uploader_pk = movedids.get('user', attachment['user_id']) uploader = UserModel.objects.get(pk=uploader_pk) file_path = os.path.join(OLD_FORUM['ATTACHMENTS'], attachment['path']) upload = OldAttachmentFile(open(file_path, 'rb'), attachment) new_attachment = Attachment( secret=Attachment.generate_new_secret(), filetype=filetype, post=post, uploaded_on=localise_datetime(attachment['date']), uploader=uploader, uploader_name=attachment['user_name'], uploader_slug=attachment['user_name_slug'], uploader_ip=attachment['ip'], filename=attachment['name'], size=attachment['size'], ) if attachment['content_type'] in IMAGE_TYPES: new_attachment.set_image(upload) else: new_attachment.set_file(upload) new_attachment.save() movedids.set('attachment', attachment['id'], new_attachment.pk) update_attachments_caches(posts)