<s> from sellmo . core import chaining <EOL> from sellmo . caching . caches import ChainCache <EOL> from sellmo . utils . query import PKIterator <EOL> from sellmo . apps . product . models import Product <EOL> from sellmo . apps . cart . forms import AddToCartForm <EOL> from sellmo . contrib . attribute . models import Attribute <EOL> from . signals import variations_invalidated <EOL> from . models import Variation , VariationQuerySet <EOL> class GroupVariationsCache ( ChainCache ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( GroupVariationsCache , self ) . __init__ ( * args , ** kwargs ) <EOL> variations_invalidated . connect ( self . _on_variations_invalidated ) <EOL> def _on_variations_invalidated ( self , sender , product , ** kwargs ) : <EOL> self . delete ( tags = self . _tags ( product = product ) ) <EOL> def _materialize ( self , cache ) : <EOL> product_qs = Product . objects . all ( ) . polymorphic ( ) <EOL> grouped = [ ] <EOL> if cache : <EOL> all_values = [ group [ '<STR_LIT:value>' ] for group in cache ] <EOL> all_variants = [ group [ '<STR_LIT>' ] for group in cache ] <EOL> all_variants = list ( PKIterator ( product_qs , all_variants ) ) <EOL> attribute = Attribute . objects . get ( pk = cache [ <NUM_LIT:0> ] [ '<STR_LIT>' ] ) <EOL> model = attribute . get_type ( ) . get_model ( ) <EOL> if model : <EOL> all_values = list ( PKIterator ( model , all_values ) ) <EOL> for group in cache : <EOL> variations = Variation . objects . all ( ) <EOL> variations . query = group [ '<STR_LIT>' ] <EOL> value = all_values [ <NUM_LIT:0> ] <EOL> all_values = all_values [ <NUM_LIT:1> : ] <EOL> variant = all_variants [ <NUM_LIT:0> ] <EOL> all_variants = all_variants [ <NUM_LIT:1> : ] <EOL> grouped . append ( <EOL> { <EOL> '<STR_LIT>' : attribute , <EOL> '<STR_LIT:value>' : value , <EOL> '<STR_LIT>' : variations , <EOL> '<STR_LIT>' : variant , <EOL> } <EOL> ) <EOL> return grouped <EOL> def _key ( self , variations ) : <EOL> return '<STR_LIT>' % hash ( variations . query ) <EOL> def _tags ( self , variations = None , product = None ) : <EOL> if variations is None and product is None : <EOL> raise TypeError ( ) <EOL> if variations is not None : <EOL> products = variations . values_list ( '<STR_LIT>' , flat = True ) <EOL> else : <EOL> products = [ product . pk ] <EOL> return [ <EOL> '<STR_LIT>' % product <EOL> for product in products <EOL> ] <EOL> def catch ( self , variations , ** kwargs ) : <EOL> cache = self . get ( self . _key ( variations ) ) <EOL> if cache is not None : <EOL> try : <EOL> yield self . _materialize ( cache ) <EOL> except Exception as ex : <EOL> self . delete ( self . _key ( variations ) ) <EOL> else : <EOL> yield chaining . exit <EOL> return <EOL> grouped = ( yield chaining . forward ) . result <EOL> cache = [ ] <EOL> if grouped is not None : <EOL> for group in grouped : <EOL> attribute = group [ '<STR_LIT>' ] <EOL> value = group [ '<STR_LIT:value>' ] <EOL> if attribute . get_type ( ) . get_model ( ) is not None : <EOL> value = value . pk <EOL> cache . append ( <EOL> { <EOL> '<STR_LIT>' : attribute . pk , <EOL> '<STR_LIT:value>' : value , <EOL> '<STR_LIT>' : group [ '<STR_LIT>' ] . query , <EOL> '<STR_LIT>' : group [ '<STR_LIT>' ] . pk , <EOL> } <EOL> ) <EOL> self . set ( <EOL> self . _key ( variations ) , <EOL> cache , <EOL> tags = self . _tags ( variations = variations ) <EOL> ) <EOL> class VariationChoiceCache ( ChainCache ) : <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( VariationChoiceCache , self ) . __init__ ( * args , ** kwargs ) <EOL> variations_invalidated . connect ( self . _on_variations_invalidated ) <EOL> def _on_variations_invalidated ( self , sender , product , ** kwargs ) : <EOL> self . delete ( tags = self . _tags ( product = product ) ) <EOL> def _key ( self , variation ) : <EOL> return '<STR_LIT>' % variation . pk <EOL> def _tags ( self , variation = None , product = None ) : <EOL> if variation is None and product is None : <EOL> raise TypeError ( ) <EOL> if product is None : <EOL> product = variation . product <EOL> return [ '<STR_LIT>' % product . pk ] <EOL> def catch ( self , variation , ** kwargs ) : <EOL> cache = self . get ( self . _key ( variation ) ) <EOL> if cache is not None : <EOL> yield cache <EOL> yield chaining . exit <EOL> return <EOL> choice = ( yield chaining . forward ) . result <EOL> self . set ( <EOL> self . _key ( variation ) , <EOL> choice , <EOL> tags = self . _tags ( variation = variation ) <EOL> ) <EOL> group_variations_cache = GroupVariationsCache ( VariationQuerySet . group ) <EOL> variation_choice_cache = VariationChoiceCache ( AddToCartForm . variation_choice ) </s>
