refactor the base classes a little (bug 846826)
This commit is contained in:
Родитель
f33f6c1b35
Коммит
abf19083f9
|
@ -4,12 +4,12 @@ from tastypie.exceptions import ImmediateHttpResponse
|
|||
from amo.urlresolvers import reverse
|
||||
from mkt.api.authentication import (MarketplaceAuthentication,
|
||||
OwnerAuthorization)
|
||||
from mkt.api.base import MarketplaceResource
|
||||
from mkt.api.base import MarketplaceModelResource
|
||||
from mkt.constants.apps import INSTALL_TYPE_USER
|
||||
from users.models import UserProfile
|
||||
|
||||
|
||||
class AccountResource(MarketplaceResource):
|
||||
class AccountResource(MarketplaceModelResource):
|
||||
installed = fields.ListField('installed_list', readonly=True, null=True)
|
||||
|
||||
class Meta:
|
||||
|
|
|
@ -5,10 +5,9 @@ from django.core.exceptions import ObjectDoesNotExist
|
|||
from tastypie import http
|
||||
from tastypie.bundle import Bundle
|
||||
from tastypie.exceptions import ImmediateHttpResponse
|
||||
from tastypie.resources import ModelResource
|
||||
from tastypie.resources import Resource, ModelResource
|
||||
|
||||
import commonware.log
|
||||
import oauth2
|
||||
from translations.fields import PurifiedField, TranslatedField
|
||||
|
||||
log = commonware.log.getLogger('z.api')
|
||||
|
@ -22,7 +21,47 @@ def get_url(name, pk):
|
|||
return ('api_dispatch_detail', {'resource_name': name, 'pk': pk})
|
||||
|
||||
|
||||
class MarketplaceResource(ModelResource):
|
||||
class Marketplace(object):
|
||||
"""
|
||||
A mixin with some general Marketplace stuff.
|
||||
"""
|
||||
|
||||
def dispatch(self, request_type, request, **kwargs):
|
||||
# OAuth authentication uses the method in the signature. So we need
|
||||
# to store the original method used to sign the request.
|
||||
request.signed_method = request.method
|
||||
if 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
|
||||
request.method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']
|
||||
|
||||
return (super(Marketplace, self)
|
||||
.dispatch(request_type, request, **kwargs))
|
||||
|
||||
def form_errors(self, forms):
|
||||
errors = {}
|
||||
if not isinstance(forms, list):
|
||||
forms = [forms]
|
||||
for f in forms:
|
||||
if isinstance(f.errors, list): # Cope with formsets.
|
||||
for e in f.errors:
|
||||
errors.update(e)
|
||||
continue
|
||||
errors.update(dict(f.errors.items()))
|
||||
|
||||
response = http.HttpBadRequest(json.dumps({'error_message': errors}),
|
||||
content_type='application/json')
|
||||
return ImmediateHttpResponse(response=response)
|
||||
|
||||
|
||||
class MarketplaceResource(Marketplace, Resource):
|
||||
"""
|
||||
Use this if you would like to expose something that is *not* a Django
|
||||
model as an API.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class MarketplaceModelResource(Marketplace, ModelResource):
|
||||
"""Use this if you would like to expose a Django model as an API."""
|
||||
|
||||
def get_resource_uri(self, bundle_or_obj):
|
||||
# Fix until my pull request gets pulled into tastypie.
|
||||
|
@ -49,21 +88,6 @@ class MarketplaceResource(ModelResource):
|
|||
|
||||
return True if getattr(field, 'rel') else False
|
||||
|
||||
def form_errors(self, forms):
|
||||
errors = {}
|
||||
if not isinstance(forms, list):
|
||||
forms = [forms]
|
||||
for f in forms:
|
||||
if isinstance(f.errors, list): # Cope with formsets.
|
||||
for e in f.errors:
|
||||
errors.update(e)
|
||||
continue
|
||||
errors.update(dict(f.errors.items()))
|
||||
|
||||
response = http.HttpBadRequest(json.dumps({'error_message': errors}),
|
||||
content_type='application/json')
|
||||
return ImmediateHttpResponse(response=response)
|
||||
|
||||
def get_object_or_404(self, cls, **filters):
|
||||
"""
|
||||
A wrapper around our more familiar get_object_or_404, for when we need
|
||||
|
@ -86,27 +110,11 @@ class MarketplaceResource(ModelResource):
|
|||
raise ImmediateHttpResponse(response=http.HttpNotFound())
|
||||
return obj
|
||||
|
||||
def dispatch(self, request_type, request, **kwargs):
|
||||
# OAuth authentication uses the method in the signature. So we need
|
||||
# to store the original method used to sign the request.
|
||||
request.signed_method = request.method
|
||||
if 'HTTP_X_HTTP_METHOD_OVERRIDE' in request.META:
|
||||
request.method = request.META['HTTP_X_HTTP_METHOD_OVERRIDE']
|
||||
|
||||
try:
|
||||
auth = (oauth2.Request._split_header(
|
||||
request.META.get('HTTP_AUTHORIZATION', '')))
|
||||
name = auth.get('oauth_consumer_key', 'none')
|
||||
except (AttributeError, IndexError):
|
||||
# Problems parsing the header.
|
||||
name = 'error'
|
||||
log.debug('%s:%s:%s' % (
|
||||
request.META['REQUEST_METHOD'], request.path, name))
|
||||
return (super(MarketplaceResource, self)
|
||||
.dispatch(request_type, request, **kwargs))
|
||||
|
||||
|
||||
class CORSResource(MarketplaceResource):
|
||||
class CORSResource(object):
|
||||
"""
|
||||
A mixin to provide CORS support to your API.
|
||||
"""
|
||||
|
||||
def method_check(self, request, allowed=None):
|
||||
"""
|
||||
|
|
|
@ -23,7 +23,7 @@ from mkt.api.authentication import (AppOwnerAuthorization,
|
|||
OptionalAuthentication,
|
||||
OwnerAuthorization,
|
||||
MarketplaceAuthentication)
|
||||
from mkt.api.base import MarketplaceResource
|
||||
from mkt.api.base import MarketplaceModelResource
|
||||
from mkt.api.forms import (CategoryForm, DeviceTypeForm, NewPackagedForm,
|
||||
PreviewArgsForm, PreviewJSONForm, StatusForm,
|
||||
UploadForm)
|
||||
|
@ -35,7 +35,7 @@ from reviews.models import Review
|
|||
log = commonware.log.getLogger('z.api')
|
||||
|
||||
|
||||
class ValidationResource(MarketplaceResource):
|
||||
class ValidationResource(MarketplaceModelResource):
|
||||
|
||||
class Meta:
|
||||
queryset = FileUpload.objects.all()
|
||||
|
@ -98,7 +98,7 @@ class ValidationResource(MarketplaceResource):
|
|||
return bundle
|
||||
|
||||
|
||||
class AppResource(MarketplaceResource):
|
||||
class AppResource(MarketplaceModelResource):
|
||||
previews = fields.ToManyField('mkt.api.resources.PreviewResource',
|
||||
'previews', readonly=True)
|
||||
|
||||
|
@ -226,7 +226,7 @@ class AppResource(MarketplaceResource):
|
|||
return self._meta.queryset.filter(authors=request.amo_user)
|
||||
|
||||
|
||||
class StatusResource(MarketplaceResource):
|
||||
class StatusResource(MarketplaceModelResource):
|
||||
|
||||
class Meta:
|
||||
queryset = Addon.objects.filter(type=amo.ADDON_WEBAPP)
|
||||
|
@ -275,7 +275,7 @@ class StatusResource(MarketplaceResource):
|
|||
return amo.STATUS_CHOICES_API_LOOKUP[int(bundle.data['status'])]
|
||||
|
||||
|
||||
class CategoryResource(MarketplaceResource):
|
||||
class CategoryResource(MarketplaceModelResource):
|
||||
|
||||
class Meta:
|
||||
queryset = Category.objects.filter(type=amo.ADDON_WEBAPP,
|
||||
|
@ -288,7 +288,7 @@ class CategoryResource(MarketplaceResource):
|
|||
serializer = Serializer(formats=['json'])
|
||||
|
||||
|
||||
class PreviewResource(MarketplaceResource):
|
||||
class PreviewResource(MarketplaceModelResource):
|
||||
image_url = fields.CharField(attribute='image_url', readonly=True)
|
||||
thumbnail_url = fields.CharField(attribute='thumbnail_url', readonly=True)
|
||||
|
||||
|
@ -357,7 +357,7 @@ def collect_replies(bundle):
|
|||
return Review.objects.filter(reply_to=bundle.obj.pk)
|
||||
|
||||
|
||||
class RatingResource(MarketplaceResource):
|
||||
class RatingResource(MarketplaceModelResource):
|
||||
|
||||
app = fields.ToOneField(AppResource, 'addon', readonly=True)
|
||||
replies = fields.ToManyField('self', collect_replies,
|
||||
|
@ -385,7 +385,7 @@ class RatingResource(MarketplaceResource):
|
|||
ordering = ['created']
|
||||
|
||||
def get_object_list(self, request):
|
||||
qs = MarketplaceResource.get_object_list(self, request)
|
||||
qs = MarketplaceModelResource.get_object_list(self, request)
|
||||
# Mature regions show only reviews from within that region.
|
||||
if not request.REGION.adolescent:
|
||||
qs = qs.filter(client_data__region=request.REGION.id)
|
||||
|
|
|
@ -17,7 +17,7 @@ from amo.tests import TestCase
|
|||
from amo.helpers import urlparams
|
||||
from amo.urlresolvers import reverse
|
||||
|
||||
from mkt.api.base import CORSResource
|
||||
from mkt.api.base import CORSResource, MarketplaceResource
|
||||
from mkt.api.models import Access, generate
|
||||
from mkt.site.fixtures import fixture
|
||||
|
||||
|
@ -141,7 +141,7 @@ class BaseOAuth(TestCase):
|
|||
return json.loads(response.content)['error_message']
|
||||
|
||||
|
||||
class Resource(CORSResource):
|
||||
class Resource(CORSResource, MarketplaceResource):
|
||||
|
||||
class Meta:
|
||||
list_allowed_method = ['get']
|
||||
|
|
|
@ -5,14 +5,14 @@ from django.db import transaction
|
|||
|
||||
from mkt.api.authentication import (MarketplaceAuthentication,
|
||||
PermissionAuthorization)
|
||||
from mkt.api.base import MarketplaceResource
|
||||
from mkt.api.base import MarketplaceModelResource
|
||||
|
||||
from .models import MonolithRecord
|
||||
|
||||
logger = logging.getLogger('z.monolith')
|
||||
|
||||
|
||||
class MonolithData(MarketplaceResource):
|
||||
class MonolithData(MarketplaceModelResource):
|
||||
|
||||
class Meta:
|
||||
queryset = MonolithRecord.objects.all()
|
||||
|
|
|
@ -5,13 +5,13 @@ from amo.urlresolvers import reverse
|
|||
from amo.utils import send_mail_jinja
|
||||
from mkt.api.authentication import (PermissionAuthorization,
|
||||
MarketplaceAuthentication)
|
||||
from mkt.api.base import CORSResource, MarketplaceResource
|
||||
from mkt.api.base import CORSResource, MarketplaceModelResource
|
||||
from mkt.webpay.forms import FailureForm
|
||||
from market.models import Price
|
||||
from stats.models import Contribution
|
||||
|
||||
|
||||
class PriceResource(CORSResource):
|
||||
class PriceResource(CORSResource, MarketplaceModelResource):
|
||||
prices = fields.ListField(attribute='prices', readonly=True)
|
||||
localized = fields.DictField(attribute='suggested', readonly=True,
|
||||
blank=True, null=True)
|
||||
|
@ -23,7 +23,6 @@ class PriceResource(CORSResource):
|
|||
resource_name = 'prices'
|
||||
fields = ['name', 'suggested']
|
||||
|
||||
|
||||
def _get_prices(self, bundle):
|
||||
"""
|
||||
Both localized and prices need access to this. But we whichever
|
||||
|
@ -63,7 +62,7 @@ class PriceResource(CORSResource):
|
|||
return self._get_prices(bundle)
|
||||
|
||||
|
||||
class FailureNotificationResource(MarketplaceResource):
|
||||
class FailureNotificationResource(MarketplaceModelResource):
|
||||
|
||||
class Meta:
|
||||
queryset = Contribution.objects.filter(uuid__isnull=False)
|
||||
|
|
Загрузка…
Ссылка в новой задаче