<s> from __future__ import absolute_import , unicode_literals , division <EOL> import operator <EOL> import six <EOL> from six . moves import map , reduce <EOL> from django . conf import urls <EOL> from django . db . models import Q <EOL> from django . views . decorators import csrf <EOL> from armet import utils <EOL> from . import http <EOL> from armet . query import parser , Query , QuerySegment , constants <EOL> class Resource ( object ) : <EOL> @ classmethod <EOL> @ csrf . csrf_exempt <EOL> def view ( cls , django_request , * args , ** kwargs ) : <EOL> async = cls . meta . asynchronous <EOL> path = kwargs . get ( '<STR_LIT:path>' ) or '<STR_LIT>' <EOL> request = http . Request ( django_request , path = path , asynchronous = async ) <EOL> response = http . Response ( asynchronous = async ) <EOL> if async : <EOL> import gevent <EOL> gevent . spawn ( super ( Resource , cls ) . view , request , response ) <EOL> response . _handle . content = cls . stream ( response , response ) <EOL> return response . _handle <EOL> result = super ( Resource , cls ) . view ( request , response ) <EOL> response . _handle . content = result <EOL> return response . _handle <EOL> @ utils . classproperty <EOL> def urls ( cls ) : <EOL> """<STR_LIT>""" <EOL> return urls . patterns ( '<STR_LIT>' , urls . url ( <EOL> r'<STR_LIT>' . format ( cls . meta . name ) , <EOL> cls . view , <EOL> name = '<STR_LIT>' . format ( cls . meta . name ) , <EOL> kwargs = { '<STR_LIT>' : cls . meta . name } ) ) <EOL> OPERATOR_MAP = { <EOL> constants . OPERATOR_EQUAL : '<STR_LIT>' , <EOL> constants . OPERATOR_IEQUAL : '<STR_LIT>' , <EOL> constants . OPERATOR_LT : '<STR_LIT>' , <EOL> constants . OPERATOR_GT : '<STR_LIT>' , <EOL> constants . OPERATOR_LTE : '<STR_LIT>' , <EOL> constants . OPERATOR_GTE : '<STR_LIT>' , <EOL> } <EOL> OPERATOR_MAP = dict ( <EOL> ( constants . OPERATOR_MAP [ k ] , v ) for k , v in OPERATOR_MAP . items ( ) <EOL> ) <EOL> def segment_query ( seg , attributes ) : <EOL> attribute = attributes [ seg . path [ <NUM_LIT:0> ] ] <EOL> seg . path [ <NUM_LIT:0> : <NUM_LIT:1> ] = attribute . path . split ( '<STR_LIT:.>' ) <EOL> if attribute . type is bool : <EOL> op = '<STR_LIT>' <EOL> else : <EOL> op = OPERATOR_MAP [ seg . operator ] <EOL> path = '<STR_LIT>' . join ( seg . path ) + op <EOL> return reduce ( operator . or_ , <EOL> map ( lambda x : Q ( ( path , x ) ) , <EOL> map ( attribute . try_clean , seg . values ) ) ) <EOL> def noop_query ( * args ) : <EOL> return Q ( ) <EOL> def unary_query ( query , * args ) : <EOL> return query . operation ( build_clause ( query . operand , * args ) ) <EOL> def binary_query ( query , * args ) : <EOL> return query . operation ( <EOL> build_clause ( query . left , * args ) , <EOL> build_clause ( query . right , * args ) ) <EOL> CLAUSE_MAP = { <EOL> parser . NoopQuerySegment : noop_query , <EOL> parser . BinarySegmentCombinator : binary_query , <EOL> parser . UnarySegmentCombinator : unary_query , <EOL> parser . QuerySegment : segment_query , <EOL> } <EOL> def build_clause ( query , attributes ) : <EOL> class_ = type ( query ) if not isinstance ( query , type ) else query <EOL> fn = CLAUSE_MAP . get ( class_ ) <EOL> if fn is not None : <EOL> return fn ( query , attributes ) <EOL> elif issubclass ( class_ , Query ) : <EOL> return build_clause ( query . parsed , attributes ) <EOL> else : <EOL> raise ValueError ( '<STR_LIT>' % str ( query ) ) <EOL> class ModelResource ( object ) : <EOL> def filter ( self , clause , queryset ) : <EOL> return queryset . filter ( clause ) . distinct ( ) <EOL> def count ( self , queryset ) : <EOL> return len ( queryset ) <EOL> def read ( self ) : <EOL> queryset = self . meta . model . objects <EOL> query = None <EOL> if self . slug is not None : <EOL> query = Query ( <EOL> original = None , <EOL> parsed = QuerySegment ( <EOL> path = self . meta . slug . path . split ( '<STR_LIT:.>' ) , <EOL> operator = constants . OPERATOR_MAP [ constants . OPERATOR_EQUAL ] , <EOL> values = [ self . slug ] <EOL> ) <EOL> ) <EOL> elif self . request . query : <EOL> query = parser . parse ( self . request . query ) <EOL> if query is not None : <EOL> clause = build_clause ( query , self . attributes ) <EOL> queryset = self . filter ( clause , queryset ) <EOL> queryset = self . meta . authorization . filter ( <EOL> self . request . user , '<STR_LIT>' , self , queryset ) <EOL> if self . slug is not None : <EOL> result = queryset . all ( ) [ : <NUM_LIT:1> ] <EOL> return result [ <NUM_LIT:0> ] if result else None <EOL> return queryset . all ( ) <EOL> def create ( self , data ) : <EOL> target = self . meta . model ( ) <EOL> for name , attribute in six . iteritems ( self . attributes ) : <EOL> value = data . get ( name ) <EOL> if value is not None : <EOL> attribute . set ( target , value ) <EOL> authz = self . meta . authorization <EOL> if not authz . is_authorized ( self . request . user , '<STR_LIT>' , self , target ) : <EOL> authz . unauthorized ( ) <EOL> target . save ( ) <EOL> return target <EOL> def update ( self , target , data ) : <EOL> for name , attribute in six . iteritems ( self . attributes ) : <EOL> attribute . set ( target , data . get ( name ) ) <EOL> authz = self . meta . authorization <EOL> if not authz . is_authorized ( self . request . user , '<STR_LIT>' , self , target ) : <EOL> authz . unauthorized ( ) <EOL> target . save ( ) <EOL> def destroy ( self ) : <EOL> target = self . read ( ) <EOL> authz = self . meta . authorization <EOL> if not authz . is_authorized ( self . request . user , '<STR_LIT>' , self , target ) : <EOL> authz . unauthorized ( ) <EOL> target . delete ( ) </s>
