<commit_before>import mimetypes
import os.path
import subprocess

from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.files.uploadedfile import UploadedFile
from django.http import HttpResponse
from django.core.exceptions import PermissionDenied
from django.views.decorators.csrf import csrf_exempt
from django.views.generic.edit import FormMixin
from django.views.generic import View
from django.utils import simplejson as json
from django.utils.decorators import method_decorator
from django.shortcuts import get_object_or_404

from sendfile import sendfile
from sorl.thumbnail import get_thumbnail

from .models import BucketFile
from .forms import BucketUploadForm

from accounts.models import GUPProfile

from .api import BucketFileResource

class JSONResponseMixin(object):
    """
    A mixin that can be used to render a JSON response.
    """
    def render_to_json_response(self, context, **response_kwargs):
        """
        Returns a JSON response, transforming 'context' to make the payload.
        """
        return HttpResponse(
            self.convert_context_to_json(context),
            content_type='application/json',
            **response_kwargs
        )

    def convert_context_to_json(self, context):
        "Convert the context dictionary into a JSON object"
        return json.dumps(context)


class ThumbnailView(View):
    """
    A view for generating thumbnails of documents, pictures and any
    other file supported.
    FIXME: THIS VIEW IS TERRIBLE: NO CACHE AND NOTHING!
    """
    preprocess_uno = ('application/vnd.oasis.opendocument.text',)
    
    def get(self, request, *args, **kwargs):
        file_id = self.kwargs['pk']
        preview_width = self.request.GET.get('width', "150")

        # Lookup bucket file first
        bfile = get_object_or_404(BucketFile, pk=file_id)
        target = bfile.file.name

        # Guess mimetype
        mimetype, encoding = mimetypes.guess_type(bfile.file.url)        
        
        # Convert document to PDF first, if needed
        if mimetype in ThumbnailView.preprocess_uno:
            target = '%s.pdf' % bfile.file.name
            conversion_cmd = "unoconv -f pdf -o %s %s" % (os.path.join(settings.MEDIA_ROOT, target),
                                                          os.path.join(settings.MEDIA_ROOT, bfile.file.name))
            subprocess.check_output(conversion_cmd.split())

        # Generate thumbnail
        try:
            thumbnail = get_thumbnail(target, preview_width, quality=80, format='JPEG')
        except Exception as e:
            raise e

        # Issue a X-Sendfile to the server
        fp = os.path.join(settings.MEDIA_ROOT, thumbnail.name)
        return sendfile(request, fp)
                
class UploadView(JSONResponseMixin, FormMixin, View):
    """
    A generic HTML5 Upload view
    """
    form_class = BucketUploadForm
    template_name = 'multiuploader/form.html'

    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(UploadView, self).dispatch(*args, **kwargs)
    
    def post(self, request, *args, **kwargs):
        res = BucketFileResource()
        try:
            res.is_authenticated(request)
        except:
            raise PermissionDenied()
        
        form_class = self.get_form_class()

        qdict = request.POST.copy()
        qdict['uploaded_by'] = '1' # FIXME!
        form = form_class(qdict, request.FILES)

        if form.is_valid():
            file = request.FILES[u'file']
            wrapped_file = UploadedFile(file)
            
            # writing file manually into model
            # because we don't need form of any type.
            self.bf = BucketFile()
            self.bf.filename = wrapped_file.file.name
            self.bf.file_size = wrapped_file.file.size
            self.bf.file = file
            self.bf.uploaded_by = form.cleaned_data['uploaded_by']
            self.bf.bucket = form.cleaned_data['bucket']
            self.bf.save()
            
            return self.form_valid(form)            
        else:
            return self.form_invalid(form)

    def form_invalid(self, form):
        return self.render_to_json_response({'error': 'error not implemented'})
            
    def form_valid(self, form):
        # generating json response array
        result = [{"id": self.bf.id,
                   "name": self.bf.filename,
                   "size": self.bf.file_size,
                   "url": reverse('multiuploader_file_link', args=[self.bf.pk]),
                   "thumbnail_url": reverse('bucket-thumbnail', args=[self.bf.pk]),
                   "delete_url": reverse('multiuploader_delete', args=[self.bf.pk]),
                   "delete_type": "POST", }]
        
        response_data = json.dumps(result)
        mimetype = 'application/json'
        return HttpResponse(response_data, mimetype=mimetype)            

<commit_msg>when uploading files, check auth, set user and return detailed object<commit_after>import mimetypes
import os.path
import subprocess

from django.conf import settings
from django.core.urlresolvers import reverse
from django.core.files.uploadedfile import UploadedFile
from django.http import HttpResponse
from django.core.exceptions import PermissionDenied
from django.views.decorators.csrf import csrf_exempt
from django.views.generic.edit import FormMixin
from django.views.generic import View
from django.utils import simplejson as json
from django.utils.decorators import method_decorator
from django.shortcuts import get_object_or_404

from sendfile import sendfile
from sorl.thumbnail import get_thumbnail

from .models import BucketFile
from .forms import BucketUploadForm

from accounts.models import GUPProfile

from .api import BucketFileResource

class JSONResponseMixin(object):
    """
    A mixin that can be used to render a JSON response.
    """
    def render_to_json_response(self, context, **response_kwargs):
        """
        Returns a JSON response, transforming 'context' to make the payload.
        """
        return HttpResponse(
            self.convert_context_to_json(context),
            content_type='application/json',
            **response_kwargs
        )

    def convert_context_to_json(self, context):
        "Convert the context dictionary into a JSON object"
        return json.dumps(context)


class ThumbnailView(View):
    """
    A view for generating thumbnails of documents, pictures and any
    other file supported.
    FIXME: THIS VIEW IS TERRIBLE: NO CACHE AND NOTHING!
    """
    preprocess_uno = ('application/vnd.oasis.opendocument.text',)
    
    def get(self, request, *args, **kwargs):
        file_id = self.kwargs['pk']
        preview_width = self.request.GET.get('width', "150")

        # Lookup bucket file first
        bfile = get_object_or_404(BucketFile, pk=file_id)
        target = bfile.file.name

        # Guess mimetype
        mimetype, encoding = mimetypes.guess_type(bfile.file.url)        
        
        # Convert document to PDF first, if needed
        if mimetype in ThumbnailView.preprocess_uno:
            target = '%s.pdf' % bfile.file.name
            conversion_cmd = "unoconv -f pdf -o %s %s" % (os.path.join(settings.MEDIA_ROOT, target),
                                                          os.path.join(settings.MEDIA_ROOT, bfile.file.name))
            subprocess.check_output(conversion_cmd.split())

        # Generate thumbnail
        try:
            thumbnail = get_thumbnail(target, preview_width, quality=80, format='JPEG')
        except Exception as e:
            raise e

        # Issue a X-Sendfile to the server
        fp = os.path.join(settings.MEDIA_ROOT, thumbnail.name)
        return sendfile(request, fp)
                
class UploadView(JSONResponseMixin, FormMixin, View):
    """
    A generic HTML5 Upload view
    """
    form_class = BucketUploadForm
    template_name = 'multiuploader/form.html'

    @method_decorator(csrf_exempt)
    def dispatch(self, *args, **kwargs):
        return super(UploadView, self).dispatch(*args, **kwargs)
    
    def post(self, request, *args, **kwargs):
        self.api_res = BucketFileResource()
        try:
            self.api_res.is_authenticated(request)
        except:
            raise PermissionDenied()

        form_class = self.get_form_class()

        qdict = request.POST.copy()
        qdict['uploaded_by'] = request.user.get_profile().pk
        form = form_class(qdict, request.FILES)

        if form.is_valid():
            file = request.FILES[u'file']
            wrapped_file = UploadedFile(file)
            
            # writing file manually into model
            # because we don't need form of any type.
            self.bf = BucketFile()
            self.bf.filename = wrapped_file.file.name
            self.bf.file_size = wrapped_file.file.size
            self.bf.file = file
            self.bf.uploaded_by = form.cleaned_data['uploaded_by']
            self.bf.bucket = form.cleaned_data['bucket']
            self.bf.save()

            self.bf.thumbnail_url = reverse('bucket-thumbnail', args=[self.bf.pk])
            self.bf.save()
            
            return self.form_valid(form)            
        else:
            return self.form_invalid(form)

    def form_invalid(self, form):
        return self.render_to_json_response({'error': 'error not implemented'})
            
    def form_valid(self, form):
        """
        Once saved, return the object as if we were reading the API (json, ...)
        """
        return self.api_res.get_detail(self.request, pk=self.bf.pk)


{'fraction_non_alphanumeric': 0.09085264900662252, 'fraction_numerical': 0.0025869205298013247, 'mean_word_length': 2.379370629370629, 'pattern_counts': {'":': 7, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '455660', 'n_tokens_mistral': 2782, 'n_tokens_neox': 2716, 'n_words': 688}