Exemplo n.º 1
0
def json_response(f, *args, **kwargs):
    """Wrap a view in JSON.

    This decorator runs the given function and looks out for ajax.AJAXError's,
    which it encodes into a proper HttpResponse object. If an unknown error
    is thrown it's encoded as a 500.

    All errors are then packaged up with an appropriate Content-Type and a JSON
    body that you can inspect in JavaScript on the client. They look like:

    {
        "message": "Error message here.",
        "code": 500
    }

    Please keep in mind that raw exception messages could very well be exposed
    to the client if a non-AJAXError is thrown.
    """
    try:
        result = f(*args, **kwargs)
        if isinstance(result, AJAXError):
            raise result
    except AJAXError as e:
        result = e.get_response()

        request = args[0]
        logger.warn('AJAXError: %d %s - %s', e.code, request.path, e.msg,
            exc_info=True,
            extra={
                'status_code': e.code,
                'request': request
            }
        )
    except Http404 as e:
        result = AJAXError(404, e.__str__()).get_response()
    except Exception as e:
        import sys
        exc_info = sys.exc_info()
        type, message, trace = exc_info
        if settings.DEBUG:
            import traceback
            tb = [{'file': l[0], 'line': l[1], 'in': l[2], 'code': l[3]} for
                l in traceback.extract_tb(trace)]
            result = AJAXError(500, message, traceback=tb).get_response()
        else:
            result = AJAXError(500, "Internal server error.").get_response()

        request = args[0]
        logger.error('Internal Server Error: %s' % request.path,
            exc_info=exc_info,
            extra={
                'status_code': 500,
                'request': request
            }
        )

    result['Content-Type'] = 'application/json'
    return result
Exemplo n.º 2
0
    def _get_record(self):
        """Fetch a given record.

        Handles fetching a record from the database along with throwing an
        appropriate instance of ``AJAXError`.
        """
        if not self.pk:
            raise AJAXError(400, _('Invalid request for record.'))

        try:
            return self.model.objects.get(pk=self.pk)
        except self.model.DoesNotExist:
            raise AJAXError(404, _('%s with id of "%s" not found.') % (
                self.model.__name__, self.pk))
Exemplo n.º 3
0
def endpoint_loader(request, application, model, **kwargs):
    """Load an AJAX endpoint.

    This will load either an ad-hoc endpoint or it will load up a model 
    endpoint depending on what it finds. It first attempts to load ``model``
    as if it were an ad-hoc endpoint. Alternatively, it will attempt to see if
    there is a ``ModelEndpoint`` for the given ``model``.
    """
    if request.method != "POST":
        raise AJAXError(400, _('Invalid HTTP method used.'))

    try:
        module = import_module('%s.endpoints' % application)
    except ImportError, e:
        raise AJAXError(404, _('AJAX endpoint does not exist.'))
Exemplo n.º 4
0
 def delete(self, request):
     record = self._get_record()
     if self.can_delete(request.user, record):
         record.delete()
         return {'pk': int(self.pk)}
     else:
         raise AJAXError(403, _("Access to endpoint is forbidden"))
Exemplo n.º 5
0
def json_response(response_type='application/json'):
    @decorator
    def inner_response(f, *args, **kwargs):
        """Wrap a view in JSON.

        This decorator runs the given function and looks out for ajax.AJAXError's,
        which it encodes into a proper HttpResponse object. If an unknown error
        is thrown it's encoded as a 500.

        All errors are then packaged up with an appropriate Content-Type and a JSON
        body that you can inspect in JavaScript on the client. They look like:

        {
            "message": "Error message here.", 
            "code": 500
        }

        Please keep in mind that raw exception messages could very well be exposed
        to the client if a non-AJAXError is thrown.
        """
        try:
            result = f(*args, **kwargs)
            if isinstance(result, AJAXError):
                raise result
            else:
                if not 'status' in result and isinstance(result, dict):
                    result['status'] = 'ok'
                result = HttpResponse(json.dumps(result, indent=4))
        except AJAXError, e:
            result = e.get_response()
        except Http404, e:
            result = AJAXError(e.__str__()).get_response()
Exemplo n.º 6
0
    def update(self, request):
        record = self._get_record()
        modified = self._get_record()

        update_record = False
        for key, val in six.iteritems(self._extract_data(request)):

            # Only setattr and save the model when a change has happened.
            if val != getattr(record, key):
                setattr(modified, key, val)
                update_record = True

        if self.can_update(request.user, record, modified=modified):

            if update_record:
                self._save(modified)

            try:
                tags = self._extract_tags(request)
                if tags:
                    modified.tags.set(*tags)
                else:
                    # If tags were in the request and set to nothing, we will
                    # clear them all out.
                    modified.tags.clear()
            except KeyError:
                pass

            ajax_updated.send(sender=record.__class__, instance=record)
            return encoder.encode(modified)
        else:
            raise AJAXError(403, _("Access to endpoint is forbidden"))
Exemplo n.º 7
0
def upload_profile_image(request):
	form = ProfileImageForm(files=request.FILES or None)
	if form.is_valid():
		img = form.save(request.user.get_profile())
		return {'thumbnail': get_thumbnail(img, "160").url}
	else:
		raise AJAXError(_("Uploaded file is not valid!"))
Exemplo n.º 8
0
 def delete(self, request):
     record = self._get_record()
     if self.can_delete(request.user, record):
         record.delete()
         ajax_deleted.send(sender=record.__class__, instance=record)
         return {'pk': int(self.pk)}
     else:
         raise AJAXError(403, _("Access to endpoint is forbidden"))
Exemplo n.º 9
0
 def create(self, request):
     record = self.model(**self._extract_data(request))
     if self.can_create(request.user, record):
         record = self._save(record)
         self._set_tags(request, record)
         return encoder.encode(record)
     else:
         raise AJAXError(403, _("Access to endpoint is forbidden"))
Exemplo n.º 10
0
 def _save(self, record):
     try:
         record.full_clean()
         record.save()
         return record
     except ValidationError, e:
         raise AJAXError(400, _("Could not save model."),
             errors=e.message_dict)
Exemplo n.º 11
0
    def update(self, request):
        record = self._get_record()
        if self.can_update(request.user, record):
            for key, val in self._extract_data(request).iteritems():
                setattr(record, key, val)

            return self._encode_record(self._save(record))
        else:
            raise AJAXError(403, _("Access to endpoint is forbidden"))
Exemplo n.º 12
0
def upload_pin(request):
    form = UploadPinForm(files=request.FILES or None)
    if form.is_valid():
        pin = form.save(commit=False)
        pin.is_active = False
        pin.save()
        return {
            'pin_pk': pin.pk,
            'thumbnail': get_thumbnail(pin.image, "100x100", crop="center").url
        }
    else:
        raise AJAXError(_("Uploaded file is not valid!"))
Exemplo n.º 13
0
 def create(self, request):
     record = self.model(**self._extract_data(request))
     if self.can_create(request.user, record):
         record = self._save(record)
         try:
             tags = self._extract_tags(request)
             record.tags.set(*tags)
         except KeyError:
             pass
         return encoder.encode(record)
     else:
         raise AJAXError(403, _("Access to endpoint is forbidden"))
Exemplo n.º 14
0
    def tags(self, request):
        cmd = self.options.get('taggit_command', None)
        if not cmd:
            raise AJAXError(400, _("Invalid or missing taggit command."))

        record = self._get_record()
        if cmd == 'similar':
            result = record.tags.similar_objects()
        else:
            tags = self._extract_tags(request)
            getattr(record.tags, cmd)(*tags)
            result = record.tags.all()

        return encoder.encode(result)
Exemplo n.º 15
0
def like_pin(request):
    """
	AJAX view which increments number of likes for pin and returns the new number of likes.
	"""
    form = PinLikeForm(request.POST or None)
    if form.is_valid():
        pin = form.cleaned_data['pin']
        Like.objects.like_pin(pin, request.user)
        pin = Pin.objects.select_related().get(pk=pin.pk)
        return {
            'number_of_likes': pin.get_number_of_likes(),
        }
    else:
        raise AJAXError(_("Could not like the pin!"))
Exemplo n.º 16
0
def website_media(request):
    """
	Returns a list of media for given URL (from POST['url'])
	@TODO: We should be checking dimensions of images in URL and return only those 
	which are larger than n pixels.	However, if it needs to be done,
	it needs to be done in asynchronous/multithreaded fashion.

	For now, only images larger than 15KiB when lossy and 25KiB when lossless are returned.
	Returned structure is:
	{
	'images': ['http://example.org/image.jpeg',..],

	 'videos': [{'thumbnail':'<url of thumbnail shown to user>','parser':'<parser class name>',
				'video_id': '<video id>'}, 
				...]
	}
	"""
    form = WebsiteURLForm(request.POST or None)
    if form.is_valid():
        pool = urllib3.PoolManager(
            headers={
                'User-Agent':
                'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'
            })
        url = form.cleaned_data['url']
        images = []
        website_request = pool.request('GET', url, timeout=4, retries=3)
        if website_request.status == 200:
            content_type = website_request.headers['content-type'].split(
                '/')[1]
            if content_type in SIZE_LIMITS.keys():
                #the given URL is image
                images.append(url)
            else:
                soup = BeautifulSoup(website_request.data)
                images.extend(find_images(soup, url))

            videos = parser_pool.get_results(url)
            if len(videos) == 0:
                videos = parser_pool.get_results(website_request.data)

        return {'images': images, 'videos': convert_videos_to_json(videos)}
    else:
        raise AJAXError(msg=_("Could not fetch images."))
Exemplo n.º 17
0
    def update(self, request):
        record = self._get_record()
        if self.can_update(request.user, record):
            for key, val in self._extract_data(request).iteritems():
                setattr(record, key, val)

            self._save(record)

            try:
                tags = self._extract_tags(request)
                if tags:
                    record.tags.set(*tags)
                else:
                    # If tags were in the request and set to nothing, we will
                    # clear them all out.
                    record.tags.clear()
            except KeyError:
                pass

            return encoder.encode(record)
        else:
            raise AJAXError(403, _("Access to endpoint is forbidden"))
Exemplo n.º 18
0
    def list(self, request):
        """
        List objects of a model. By default will show page 1 with 20 objects on it. 
        
        **Usage**::
        
            params = {"items_per_page":10,"page":2} //all params are optional
            $.post("/ajax/{app}/{model}/list.json"),params)
        
        """

        max_items_per_page = getattr(
            self, 'max_per_page', getattr(settings, 'AJAX_MAX_PER_PAGE', 100))
        requested_items_per_page = request.POST.get("items_per_page", 20)
        items_per_page = min(max_items_per_page, requested_items_per_page)
        current_page = request.POST.get("current_page", 1)

        if not self.can_list(request.user):
            raise AJAXError(403, _("Access to this endpoint is forbidden"))

        objects = self.get_queryset(request)

        paginator = Paginator(objects, items_per_page)

        try:
            page = paginator.page(current_page)
        except PageNotAnInteger:
            # If page is not an integer, deliver first page.
            page = paginator.page(1)
        except EmptyPage:
            # If page is out of range (e.g. 9999), return empty list.
            page = EmptyPageResult()

        data = [encoder.encode(record) for record in page.object_list]
        return EnvelopedResponse(data=data,
                                 metadata={'total': paginator.count})
Exemplo n.º 19
0
 def update(self, request):
     raise AJAXError(404, _("Endpoint does not exist."))
Exemplo n.º 20
0
def login_required(f, *args, **kwargs):
    if not args[0].user.is_authenticated():
        raise AJAXError(403, _('User must be authenticated.'))

    return f(*args, **kwargs)
Exemplo n.º 21
0
    {
        "message": "Error message here.", 
        "code": 500
    }

    Please keep in mind that raw exception messages could very well be exposed
    to the client if a non-AJAXError is thrown.
    """ 
    try:
        result = f(*args, **kwargs)
        if isinstance(result, AJAXError):
            raise result
    except AJAXError, e:
        result = e.get_response()
    except Http404, e:
        result = AJAXError(404, e.__str__()).get_response()
    except Exception, e:
        import sys
        exc_info = sys.exc_info()
        type, message, trace = exc_info
        if settings.DEBUG:
            import traceback 
            tb = [{'file': l[0], 'line': l[1], 'in': l[2], 'code': l[3]} for 
                l in traceback.extract_tb(trace)]
            result = AJAXError(500, message, traceback=tb).get_response()
        else:
            result = AJAXError(500, "Internal server error.").get_response()

        request = args[0]
        logger.error('Internal Server Error: %s' % request.path,
            exc_info=exc_info,
Exemplo n.º 22
0
    try:
        result = f(*args, **kwargs)
    except AJAXError, e:
        result = e.get_response()
    except Exception, e:
        import sys
        type, message, trace = sys.exc_info()
        if settings.DEBUG:
            import traceback
            tb = [{
                'file': l[0],
                'line': l[1],
                'in': l[2],
                'code': l[3]
            } for l in traceback.extract_tb(trace)]
            result = AJAXError(500, message, traceback=tb).get_response()
        else:
            result = AJAXError(500, message).get_response()

    result['Content-Type'] = 'application/json'
    return result


@json_response
def endpoint_loader(request, application, model, **kwargs):
    """Load an AJAX endpoint.

    This will load either an ad-hoc endpoint or it will load up a model 
    endpoint depending on what it finds. It first attempts to load ``model``
    as if it were an ad-hoc endpoint. Alternatively, it will attempt to see if
    there is a ``ModelEndpoint`` for the given ``model``.
Exemplo n.º 23
0
 def parse_tags(tagstring):
     raise AJAXError(500, 'Taggit required: http://bit.ly/RE0dr9')
Exemplo n.º 24
0
def right_back_at_you(request):
    if len(request.POST):
        return request.POST
    else:
        raise AJAXError(500, 'Nothing to echo back.')
Exemplo n.º 25
0
def endpoint_loader(request, application, model, **kwargs):
    """Load an AJAX endpoint.

    This will load either an ad-hoc endpoint or it will load up a model
    endpoint depending on what it finds. It first attempts to load ``model``
    as if it were an ad-hoc endpoint. Alternatively, it will attempt to see if
    there is a ``ModelEndpoint`` for the given ``model``.
    """
    if request.method != "POST":
        raise AJAXError(400, _('Invalid HTTP method used.'))

    try:
        module = import_module('%s.endpoints' % application)
    except ImportError as e:
        if settings.DEBUG:
            raise e
        else:
            raise AJAXError(404, _('AJAX endpoint does not exist.'))

    if hasattr(module, model):
        # This is an ad-hoc endpoint
        endpoint = getattr(module, model)
    else:
        # This is a model endpoint
        method = kwargs.get('method', 'create').lower()
        try:
            del kwargs['method']
        except:
            pass

        try:
            model_endpoint = ajax.endpoint.load(model, application, method,
                **kwargs)
            if not model_endpoint.authenticate(request, application, method):
                raise AJAXError(403, _('User is not authorized.'))

            endpoint = getattr(model_endpoint, method, False)

            if not endpoint:
                raise AJAXError(404, _('Invalid method.'))
        except NotRegistered:
            raise AJAXError(500, _('Invalid model.'))

    data = endpoint(request)
    if isinstance(data, HttpResponse):
        return data

    if isinstance(data, EnvelopedResponse):
        envelope = data.metadata
        payload = data.data
    else:
        envelope = {}
        payload = data

    envelope.update({
        'success': True,
        'data': payload,
    })

    return HttpResponse(json.dumps(envelope, cls=DjangoJSONEncoder,
        separators=(',', ':')))
Exemplo n.º 26
0
            raise result
    except AJAXError, e:
        result = e.get_response()

        request = args[0]
        logger.warn('AJAXError: %d %s - %s',
                    e.code,
                    request.path,
                    e.msg,
                    exc_info=True,
                    extra={
                        'status_code': e.code,
                        'request': request
                    })
    except Http404, e:
        result = AJAXError(404, e.__str__()).get_response()
    except Exception, e:
        import sys
        exc_info = sys.exc_info()
        type, message, trace = exc_info
        if settings.DEBUG:
            import traceback
            tb = [{
                'file': l[0],
                'line': l[1],
                'in': l[2],
                'code': l[3]
            } for l in traceback.extract_tb(trace)]
            result = AJAXError(500, message, traceback=tb).get_response()
        else:
            result = AJAXError(500, "Internal server error.").get_response()
Exemplo n.º 27
0
 def inner(request, *args, **kwargs):
     if request.method not in request_method_list:
         raise AJAXError(403, _('Access denied.'))
     return func(request, *args, **kwargs)
Exemplo n.º 28
0
    if hasattr(module, model):
        # This is an ad-hoc endpoint
        endpoint = getattr(module, model)
    else:
        # This is a model endpoint
        method = kwargs.get('method', 'create').lower()
        try:
            del kwargs['method']
        except:
            pass

        try:
            model_endpoint = ajax.endpoint.load(model, application, method,
                                                **kwargs)
            if not model_endpoint.authenticate(request, application, method):
                raise AJAXError(403, _('User is not authorized.'))

            endpoint = getattr(model_endpoint, method, False)

            if not endpoint:
                raise AJAXError(404, _('Invalid method.'))
        except NotRegistered:
            raise AJAXError(500, _('Invalid model.'))

    data = endpoint(request)
    if isinstance(data, HttpResponse):
        return data
    else:
        payload = {
            'success': True,
            'data': data,
Exemplo n.º 29
0
 def get(self, request):
     record = self._get_record()
     if self.can_get(request.user, record):
         return encoder.encode(record)
     else:
         raise AJAXError(403, _("Access to endpoint is forbidden"))
Exemplo n.º 30
0
            result = f(*args, **kwargs)
            if isinstance(result, AJAXError):
                raise result
            else:
                if not 'status' in result and isinstance(result, dict):
                    result['status'] = 'ok'
                result = HttpResponse(json.dumps(result, indent=4))
        except AJAXError, e:
            result = e.get_response()
        except Http404, e:
            result = AJAXError(e.__str__()).get_response()
        except Exception, e:
            import sys
            type, message, trace = sys.exc_info()
            if settings.DEBUG:
                import traceback
                tb = [{
                    'file': l[0],
                    'line': l[1],
                    'in': l[2],
                    'code': l[3]
                } for l in traceback.extract_tb(trace)]
                result = AJAXError(message, traceback=tb).get_response()
            else:
                result = AJAXError(message).get_response()

        result['Content-Type'] = response_type
        return result

    return inner_response