<s> """<STR_LIT>""" <EOL> __authors__ = [ '<STR_LIT>' , <EOL> '<STR_LIT>' ] <EOL> import logging <EOL> import math <EOL> from functools import partial <EOL> from tornado import gen <EOL> from viewfinder . backend . base import util <EOL> from viewfinder . backend . base . exceptions import NotFoundError <EOL> from viewfinder . backend . db import db_client , vf_schema <EOL> from viewfinder . backend . db . base import DBObject <EOL> from viewfinder . backend . db . range_base import DBRangeObject <EOL> from viewfinder . backend . op . notification_manager import NotificationManager <EOL> @ DBObject . map_table_attributes <EOL> class Friend ( DBRangeObject ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = [ ] <EOL> _table = DBObject . _schema . GetTable ( vf_schema . FRIEND ) <EOL> FRIEND = '<STR_LIT>' <EOL> MUTED = '<STR_LIT>' <EOL> BLOCKED = '<STR_LIT>' <EOL> FRIEND_ATTRIBUTES = set ( [ '<STR_LIT>' ] ) <EOL> """<STR_LIT>""" <EOL> _SHARE_HALF_LIFE = <NUM_LIT> * <NUM_LIT> * <NUM_LIT> * <NUM_LIT:30> <EOL> def __init__ ( self , user_id = None , friend_id = None ) : <EOL> super ( Friend , self ) . __init__ ( ) <EOL> self . user_id = user_id <EOL> self . friend_id = friend_id <EOL> self . status = Friend . FRIEND <EOL> def IsBlocked ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . status == Friend . BLOCKED <EOL> def DecayShares ( self , timestamp ) : <EOL> """<STR_LIT>""" <EOL> def _ComputeDecay ( shares , last_time ) : <EOL> if last_time is None : <EOL> assert shares is None , shares <EOL> return <NUM_LIT:0> <EOL> decay = math . exp ( - math . log ( <NUM_LIT:2> ) * ( timestamp - last_time ) / <EOL> Friend . _SHARE_HALF_LIFE ) <EOL> return shares * decay <EOL> self . total_shares = _ComputeDecay ( self . total_shares , self . last_share ) <EOL> self . last_share = timestamp <EOL> self . colocated_shares = _ComputeDecay ( self . colocated_shares , self . last_colocated ) <EOL> self . last_colocated = timestamp <EOL> def IncrementShares ( self , timestamp , shared , colocated ) : <EOL> """<STR_LIT>""" <EOL> self . DecayShares ( timestamp ) <EOL> self . total_shares += ( <NUM_LIT:1.0> if shared else - <NUM_LIT:1.0> ) <EOL> if colocated : <EOL> self . colocated_shares += ( <NUM_LIT:1.0> if shared else - <NUM_LIT:1.0> ) <EOL> @ classmethod <EOL> @ gen . engine <EOL> def MakeFriends ( cls , client , user_id , friend_id , callback ) : <EOL> """<STR_LIT>""" <EOL> from viewfinder . backend . db . user import User <EOL> forward_friend , reverse_friend = yield [ gen . Task ( Friend . Query , client , user_id , friend_id , None , must_exist = False ) , <EOL> gen . Task ( Friend . Query , client , friend_id , user_id , None , must_exist = False ) ] <EOL> if forward_friend is None : <EOL> forward_friend = Friend . CreateFromKeywords ( user_id = user_id , friend_id = friend_id , status = Friend . FRIEND ) <EOL> yield gen . Task ( forward_friend . Update , client ) <EOL> if reverse_friend is None : <EOL> reverse_friend = Friend . CreateFromKeywords ( user_id = friend_id , friend_id = user_id , status = Friend . FRIEND ) <EOL> yield gen . Task ( reverse_friend . Update , client ) <EOL> callback ( ( forward_friend , reverse_friend ) ) <EOL> @ classmethod <EOL> @ gen . engine <EOL> def MakeFriendsWithGroup ( cls , client , user_ids , callback ) : <EOL> """<STR_LIT>""" <EOL> yield [ gen . Task ( Friend . MakeFriends , client , user_id , friend_id ) <EOL> for index , user_id in enumerate ( user_ids ) <EOL> for friend_id in user_ids [ index + <NUM_LIT:1> : ] <EOL> if user_id != friend_id ] <EOL> callback ( ) <EOL> @ classmethod <EOL> @ gen . engine <EOL> def MakeFriendAndUpdate ( cls , client , user_id , friend_dict , callback ) : <EOL> """<STR_LIT>""" <EOL> from viewfinder . backend . db . user import User <EOL> friend = yield gen . Task ( Friend . Query , client , user_id , friend_dict [ '<STR_LIT>' ] , None , must_exist = False ) <EOL> if friend is None : <EOL> friend_user = yield gen . Task ( User . Query , client , friend_dict [ '<STR_LIT>' ] , None , must_exist = False ) <EOL> if friend_user is None : <EOL> raise NotFoundError ( '<STR_LIT>' % friend_dict [ '<STR_LIT>' ] ) <EOL> friend = Friend . CreateFromKeywords ( user_id = user_id , friend_id = friend_dict [ '<STR_LIT>' ] , status = Friend . FRIEND ) <EOL> assert friend_dict [ '<STR_LIT>' ] == friend . friend_id , ( friend_dict , friend ) <EOL> for key , value in friend_dict . iteritems ( ) : <EOL> if key != '<STR_LIT>' : <EOL> assert key in Friend . FRIEND_ATTRIBUTES , friend_dict <EOL> setattr ( friend , key , value ) <EOL> yield gen . Task ( friend . Update , client ) <EOL> callback ( ) <EOL> @ classmethod <EOL> @ gen . engine <EOL> def UpdateOperation ( cls , client , callback , user_id , friend ) : <EOL> """<STR_LIT>""" <EOL> yield gen . Task ( Friend . MakeFriendAndUpdate , client , user_id , friend ) <EOL> yield NotificationManager . NotifyUpdateFriend ( client , friend ) <EOL> callback ( ) </s>
