<s> """<STR_LIT>""" <EOL> from __future__ import absolute_import , print_function <EOL> import collections <EOL> import logging <EOL> import six <EOL> import warnings <EOL> from django . conf import settings <EOL> from django . db import models <EOL> from django . db . models . signals import post_delete <EOL> from south . modelsinspector import add_introspection_rules <EOL> from sentry . utils . cache import memoize <EOL> from sentry . utils . compat import pickle <EOL> from sentry . utils . strings import decompress , compress <EOL> from . gzippeddict import GzippedDictField <EOL> __all__ = ( '<STR_LIT>' , ) <EOL> logger = logging . getLogger ( '<STR_LIT>' ) <EOL> class NodeUnpopulated ( Exception ) : <EOL> pass <EOL> class NodeIntegrityFailure ( Exception ) : <EOL> pass <EOL> class NodeData ( collections . MutableMapping ) : <EOL> def __init__ ( self , field , id , data = None ) : <EOL> self . field = field <EOL> self . id = id <EOL> self . ref = None <EOL> self . ref_version = None <EOL> self . _node_data = data <EOL> def __getitem__ ( self , key ) : <EOL> return self . data [ key ] <EOL> def __setitem__ ( self , key , value ) : <EOL> self . data [ key ] = value <EOL> def __delitem__ ( self , key ) : <EOL> del self . data [ key ] <EOL> def __iter__ ( self ) : <EOL> return iter ( self . data ) <EOL> def __len__ ( self ) : <EOL> return len ( self . data ) <EOL> def __repr__ ( self ) : <EOL> cls_name = type ( self ) . __name__ <EOL> if self . _node_data : <EOL> return '<STR_LIT>' % ( <EOL> cls_name , self . id , repr ( self . _node_data ) ) <EOL> return '<STR_LIT>' % ( cls_name , self . id , ) <EOL> def get_ref ( self , instance ) : <EOL> ref_func = self . field . ref_func <EOL> if not ref_func : <EOL> return <EOL> return ref_func ( instance ) <EOL> @ memoize <EOL> def data ( self ) : <EOL> from sentry . app import nodestore <EOL> if self . _node_data is not None : <EOL> return self . _node_data <EOL> elif self . id : <EOL> if settings . DEBUG : <EOL> raise NodeUnpopulated ( '<STR_LIT>' ) <EOL> else : <EOL> warnings . warn ( '<STR_LIT>' ) <EOL> self . bind_data ( nodestore . get ( self . id ) or { } ) <EOL> return self . _node_data <EOL> return { } <EOL> def bind_data ( self , data , ref = None ) : <EOL> self . ref = data . pop ( '<STR_LIT>' , ref ) <EOL> self . ref_version = data . pop ( '<STR_LIT>' , None ) <EOL> if self . ref_version == self . field . ref_version and ref is not None and self . ref != ref : <EOL> raise NodeIntegrityFailure ( '<STR_LIT>' % ( <EOL> self . id , ref , self . ref , <EOL> ) ) <EOL> self . _node_data = data <EOL> def bind_ref ( self , instance ) : <EOL> ref = self . get_ref ( instance ) <EOL> if ref : <EOL> self . data [ '<STR_LIT>' ] = ref <EOL> self . data [ '<STR_LIT>' ] = self . field . ref_version <EOL> class NodeField ( GzippedDictField ) : <EOL> """<STR_LIT>""" <EOL> __metaclass__ = models . SubfieldBase <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> self . ref_func = kwargs . pop ( '<STR_LIT>' , None ) <EOL> self . ref_version = kwargs . pop ( '<STR_LIT>' , None ) <EOL> super ( NodeField , self ) . __init__ ( * args , ** kwargs ) <EOL> def contribute_to_class ( self , cls , name ) : <EOL> super ( NodeField , self ) . contribute_to_class ( cls , name ) <EOL> post_delete . connect ( <EOL> self . on_delete , <EOL> sender = self . model , <EOL> weak = False ) <EOL> def on_delete ( self , instance , ** kwargs ) : <EOL> from sentry . app import nodestore <EOL> value = getattr ( instance , self . name ) <EOL> if not value . id : <EOL> return <EOL> nodestore . delete ( value . id ) <EOL> def to_python ( self , value ) : <EOL> if isinstance ( value , six . string_types ) and value : <EOL> try : <EOL> value = pickle . loads ( decompress ( value ) ) <EOL> except Exception as e : <EOL> logger . exception ( e ) <EOL> value = { } <EOL> elif not value : <EOL> value = { } <EOL> if '<STR_LIT>' in value : <EOL> node_id = value . pop ( '<STR_LIT>' ) <EOL> data = None <EOL> else : <EOL> node_id = None <EOL> data = value <EOL> return NodeData ( self , node_id , data ) <EOL> def get_prep_value ( self , value ) : <EOL> from sentry . app import nodestore <EOL> if not value and self . null : <EOL> return None <EOL> if not value . id : <EOL> value . id = nodestore . create ( value . data ) <EOL> else : <EOL> nodestore . set ( value . id , value . data ) <EOL> return compress ( pickle . dumps ( { <EOL> '<STR_LIT>' : value . id <EOL> } ) ) <EOL> add_introspection_rules ( [ ] , [ "<STR_LIT>" ] ) </s>
