Revert "Add a send-to view (fixes #7080)"

This reverts commit 651681aa6e.
This commit is contained in:
Benjamin Dauvergne 2015-05-18 10:48:59 +02:00
parent d6b774ee47
commit 36437f440b
6 changed files with 17 additions and 203 deletions

11
COPYING
View File

@ -1,11 +1,2 @@
Fargo is mainly under the copyright of Entr'ouvert and distributed Fargo is entirely under the copyright of Entr'ouvert and distributed
under the license AGPLv3 or later. under the license AGPLv3 or later.
A file was copied from the project django-multiupload
(https://github.com/Chive/django-multiupload) and licensed under the MIT
license.
The MIT License (MIT)
Copyright (c) 2014 Chive - Kim Thoenen (kim@smuzey.ch)

View File

@ -1,53 +0,0 @@
# -*- coding: utf-8 -*-
# Copied from https://github.com/Chive/django-multiupload/blob/master/multiupload/fields.py
from django import forms
from django.core.exceptions import ValidationError
from django.utils.translation import ugettext_lazy as _
class MultiFileInput(forms.FileInput):
def render(self, name, value, attrs=None):
attrs['multiple'] = 'multiple'
return super(MultiFileInput, self).render(name, value, attrs)
def value_from_datadict(self, data, files, name):
if hasattr(files, 'getlist'):
return files.getlist(name)
else:
return [files.get(name)]
class MultiFileField(forms.FileField):
widget = MultiFileInput
default_error_messages = {
'min_num': _(u'Ensure at least %(min_num)s files are uploaded (received %(num_files)s).'),
'max_num': _(u'Ensure at most %(max_num)s files are uploaded (received %(num_files)s).'),
'file_size': _(u'File %(uploaded_file_name)s exceeded maximum upload size.'),
}
def __init__(self, *args, **kwargs):
self.min_num = kwargs.pop('min_num', 0)
self.max_num = kwargs.pop('max_num', None)
self.maximum_file_size = kwargs.pop('max_file_size', None)
super(MultiFileField, self).__init__(*args, **kwargs)
def to_python(self, data):
ret = []
for item in data:
i = super(MultiFileField, self).to_python(item)
if i:
ret.append(i)
return ret
def validate(self, data):
super(MultiFileField, self).validate(data)
num_files = len(data)
if len(data) and not data[0]:
num_files = 0
if num_files < self.min_num:
raise ValidationError(self.error_messages['min_num'] % {'min_num': self.min_num, 'num_files': num_files})
elif self.max_num and num_files > self.max_num:
raise ValidationError(self.error_messages['max_num'] % {'max_num': self.max_num, 'num_files': num_files})
for uploaded_file in data:
if self.maximum_file_size and uploaded_file.size > self.maximum_file_size:
raise ValidationError(self.error_messages['file_size'] % {'uploaded_file_name': uploaded_file.name})

View File

@ -1,14 +1,8 @@
import base64 from django.forms import ModelForm
from django.utils.text import slugify from . import models
from django.core.exceptions import ValidationError
from django import forms
from django.contrib.auth import get_user_model
from django.core.files.base import ContentFile
from . import models, fields class UploadForm(ModelForm):
class UploadForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user') self.user = kwargs.pop('user')
super(UploadForm, self).__init__(*args, **kwargs) super(UploadForm, self).__init__(*args, **kwargs)
@ -21,31 +15,3 @@ class UploadForm(forms.ModelForm):
class Meta: class Meta:
model = models.Document model = models.Document
fields = ['document_file'] fields = ['document_file']
class SendToForm(forms.Form):
email = forms.EmailField()
documents = fields.MultiFileField()
def clean_email(self):
User = get_user_model()
try:
self.cached_user = User.objects.get(
email=self.cleaned_data['email'])
except User.DoesNotExist:
raise ValidationError('no such user')
return self.cleaned_data['email']
def clean_documents(self):
for i, document in enumerate(self.cleaned_data['documents']):
if not document.name or document.name == 'documents':
raise ValidationError('%d-th document is missing a name' % i)
return self.cleaned_data['documents']
def save(self, *args, **kwargs):
for document in self.cleaned_data['documents']:
document = models.Document(
user=self.cached_user,
document_filename=document.name,
document_file=document)
document.save()

View File

@ -1,13 +1,13 @@
import urlparse import urlparse
import urllib import urllib
import logging import logging
import json from json import dumps
from django.views.generic import CreateView, DeleteView, View, TemplateView from django.views.generic import CreateView, DeleteView, View, TemplateView
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404, resolve_url from django.shortcuts import get_object_or_404, resolve_url
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden, HttpResponseBadRequest from django.http import HttpResponse, HttpResponseRedirect, HttpResponseForbidden
from django.core import signing from django.core import signing
from django.contrib import messages from django.contrib import messages
from django.contrib.auth import get_user_model, REDIRECT_FIELD_NAME from django.contrib.auth import get_user_model, REDIRECT_FIELD_NAME
@ -181,7 +181,7 @@ class JSONP(Documents, View):
def get(self, request): def get(self, request):
callback = request.GET.get('callback', 'callback') callback = request.GET.get('callback', 'callback')
s = '%s(%s)' % (callback.encode('ascii'), s = '%s(%s)' % (callback.encode('ascii'),
json.dumps(self.get_data(request))) dumps(self.get_data(request)))
return HttpResponse(s, content_type='application/javascript') return HttpResponse(s, content_type='application/javascript')
class JSON(JSONP): class JSON(JSONP):
@ -192,22 +192,11 @@ class JSON(JSONP):
request.user = get_object_or_404(User, username=username) request.user = get_object_or_404(User, username=username)
elif not request.user.is_authenticated(): elif not request.user.is_authenticated():
return method_decorator(login_required)(JSON.get)(self, request) return method_decorator(login_required)(JSON.get)(self, request)
response = HttpResponse(json.dumps(self.get_data(request)), response = HttpResponse(dumps(self.get_data(request)),
content_type='application/json') content_type='application/json')
response['Access-Control-Allow-Origin'] = '*' response['Access-Control-Allow-Origin'] = '*'
return response return response
class SendTo(View):
http_method_allowed = ['post']
def post(self, request, *args, **kwargs):
form = forms.SendToForm(request.GET, request.FILES)
if form.is_valid():
form.save()
return HttpResponse('ok', content_type='text/plain')
else:
result = {'errors': form.errors}
return HttpResponseBadRequest(json.dumps(result))
def login(request, *args, **kwargs): def login(request, *args, **kwargs):
if any(get_idps()): if any(get_idps()):
@ -234,8 +223,7 @@ document = login_required(Document.as_view())
download = login_required(Download.as_view()) download = login_required(Download.as_view())
upload = login_required(Upload.as_view()) upload = login_required(Upload.as_view())
remote_download = RemoteDownload.as_view() remote_download = RemoteDownload.as_view()
send_to = SendTo.as_view()
delete = login_required(Delete.as_view()) delete = login_required(Delete.as_view())
pick = login_required(Pick.as_view()) pick = login_required(Pick.as_view())
jsonp_view = login_required(JSONP.as_view()) jsonp = login_required(JSONP.as_view())
json_view = login_required(JSON.as_view()) json = login_required(JSON.as_view())

View File

@ -1,80 +1,3 @@
from django.test import TestCase, Client from django.test import TestCase
import django
import unittest # Create your tests here.
django18_only = unittest.skipUnless(django.VERSION >= (1,8), 'required Django 1.8')
class FargoTestCase(TestCase):
def setUp(self):
import StringIO
from django.contrib.auth import get_user_model
User = get_user_model()
self.email = 'john.doe@example.com'
self.username = 'john.doe'
self.user = User.objects.create(
username=self.username,
email=self.email)
self.filename = 'attachment.pdf'
self.content = 'coucou'
self.contentfile = StringIO.StringIO(self.content)
self.contentfile.content_type = 'application/pdf'
self.contentfile.name = self.filename
@django18_only
def test_send_to(self):
from fargo.models import Document
client = Client()
response = client.post('/send-to/?email=%s' % self.email,
data={'documents': [self.contentfile]})
self.assertEqual(response.status_code, 200)
self.assertEqual(response.content, 'ok')
self.assertEqual(Document.objects.count(), 1, 'no document found')
document = Document.objects.get()
self.assertEqual(document.user, self.user)
self.assertEqual(document.document_filename, self.filename)
self.assertEqual(document.document_file.read(), self.content)
@django18_only
def test_remote_send_to_unknown_user(self):
client = Client()
response = client.post('/send-to/?email=%s' % 'unknown@example.com',
data={'documents': [self.contentfile]})
self.assertEqual(response.status_code, 400)
self.assertJSONEqual(response.content, {
'errors': {
'email': ['no such user'],
}
}
)
def test_remote_upload_missing_fields(self):
client = Client()
response = client.post('/send-to/')
self.assertEqual(response.status_code, 400)
self.assertJSONEqual(response.content, {
'errors': {
'email': ['This field is required.'],
'documents': ['This field is required.'],
}
}
)
@django18_only
def test_remote_upload_missing_name(self):
import StringIO
client = Client()
contentfile = StringIO.StringIO(self.content)
contentfile.content_type = 'application/pdf'
response = client.post('/send-to/?email=%s' % self.email,
data={'documents': [contentfile]})
self.assertEqual(response.status_code, 400)
self.assertJSONEqual(response.content, {
'errors': {
'documents': ['0-th document is missing a name'],
}
}
)

View File

@ -2,25 +2,24 @@ from django.conf import settings
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from django.contrib import admin from django.contrib import admin
from .fargo.views import (home, jsonp_view, json_view, document, download, from .fargo.views import (home, jsonp, json, document, download, pick, delete, upload,
pick, delete, upload, remote_download, send_to, login, remote_download, login, logout)
logout)
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^$', home, name='home'), url(r'^$', home, name='home'),
url(r'^jsonp/$', jsonp_view, name='jsonp'), url(r'^jsonp/$', jsonp, name='jsonp'),
url(r'^json/$', json_view, name='json'), url(r'^json/$', json, name='json'),
url(r'^(?P<pk>\d+)/$', document, name='document'), url(r'^(?P<pk>\d+)/$', document, name='document'),
url(r'^(?P<pk>\d+)/delete/$', delete, name='delete'), url(r'^(?P<pk>\d+)/delete/$', delete, name='delete'),
url(r'^(?P<pk>\d+)/pick/$', pick, name='pick'), url(r'^(?P<pk>\d+)/pick/$', pick, name='pick'),
url(r'^(?P<pk>\d+)/download/(?P<filename>[^/]*)$', download, name='download'), url(r'^(?P<pk>\d+)/download/(?P<filename>[^/]*)$', download, name='download'),
url(r'^upload/$', upload, name='upload'), url(r'^upload/$', upload, name='upload'),
url(r'^remote-download/(?P<filename>[^/]*)$', remote_download, name='remote_download'), url(r'^remote-download/(?P<filename>[^/]*)$', remote_download, name='remote_download'),
url(r'^send-to/$', send_to, name='send_to'),
url(r'^admin/', include(admin.site.urls)), url(r'^admin/', include(admin.site.urls)),
url(r'^login/$', login, name='auth_login'), url(r'^login/$', login, name='auth_login'),
url(r'^logout/$', logout, name='auth_logout'), url(r'^logout/$', logout, name='auth_logout'),
) )
if 'mellon' in settings.INSTALLED_APPS: if 'mellon' in settings.INSTALLED_APPS:
urlpatterns += patterns('', url(r'^accounts/mellon/', include('mellon.urls'))) urlpatterns += patterns('', url(r'^accounts/mellon/', include('mellon.urls')))