<s> """<STR_LIT>""" <EOL> __authors__ = [ '<STR_LIT>' ] <EOL> import json <EOL> from tornado import gen <EOL> from viewfinder . backend . base import util <EOL> from viewfinder . backend . base . exceptions import InvalidRequestError , PermissionError <EOL> from viewfinder . backend . db . accounting import AccountingAccumulator <EOL> from viewfinder . backend . db . db_client import DBKey <EOL> from viewfinder . backend . db . episode import Episode <EOL> from viewfinder . backend . db . follower import Follower <EOL> from viewfinder . backend . db . operation import Operation <EOL> from viewfinder . backend . db . post import Post <EOL> from viewfinder . backend . db . viewpoint import Viewpoint <EOL> from viewfinder . backend . op . notification_manager import NotificationManager <EOL> from viewfinder . backend . op . viewfinder_op import ViewfinderOperation <EOL> class UpdateViewpointOperation ( ViewfinderOperation ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , client , act_dict , user_id , vp_dict ) : <EOL> super ( UpdateViewpointOperation , self ) . __init__ ( client ) <EOL> self . _act_dict = act_dict <EOL> self . _user_id = user_id <EOL> self . _vp_dict = vp_dict <EOL> self . _viewpoint_id = vp_dict [ '<STR_LIT>' ] <EOL> @ classmethod <EOL> @ gen . coroutine <EOL> def Execute ( cls , client , activity , user_id , viewpoint ) : <EOL> """<STR_LIT>""" <EOL> yield UpdateViewpointOperation ( client , activity , user_id , viewpoint ) . _UpdateViewpoint ( ) <EOL> @ gen . coroutine <EOL> def _UpdateViewpoint ( self ) : <EOL> """<STR_LIT>""" <EOL> lock = yield gen . Task ( Viewpoint . AcquireLock , self . _client , self . _viewpoint_id ) <EOL> try : <EOL> yield self . _Check ( ) <EOL> self . _client . CheckDBNotModified ( ) <EOL> yield self . _Update ( ) <EOL> yield self . _Account ( ) <EOL> yield Operation . TriggerFailpoint ( self . _client ) <EOL> yield self . _Notify ( ) <EOL> finally : <EOL> yield gen . Task ( Viewpoint . ReleaseLock , self . _client , self . _viewpoint_id , lock ) <EOL> @ gen . coroutine <EOL> def _Check ( self ) : <EOL> """<STR_LIT>""" <EOL> self . _viewpoint , self . _follower = yield gen . Task ( Viewpoint . QueryWithFollower , <EOL> self . _client , <EOL> self . _user_id , <EOL> self . _viewpoint_id ) <EOL> if self . _viewpoint is None : <EOL> raise InvalidRequestError ( '<STR_LIT>' % <EOL> ( self . _viewpoint_id ) ) <EOL> if self . _follower is None or not self . _follower . CanContribute ( ) : <EOL> raise PermissionError ( '<STR_LIT>' % <EOL> ( self . _user_id , self . _viewpoint_id ) ) <EOL> self . _followers , _ = yield gen . Task ( Viewpoint . QueryFollowers , <EOL> self . _client , <EOL> self . _viewpoint_id , <EOL> limit = Viewpoint . MAX_FOLLOWERS ) <EOL> cover_photo = self . _vp_dict . get ( '<STR_LIT>' , None ) <EOL> if cover_photo is not None : <EOL> if self . _viewpoint . IsDefault ( ) : <EOL> raise InvalidRequestError ( '<STR_LIT>' ) <EOL> cover_photo_episode , cover_photo_post = yield [ gen . Task ( Episode . Query , <EOL> self . _client , <EOL> cover_photo [ '<STR_LIT>' ] , <EOL> None , <EOL> must_exist = False ) , <EOL> gen . Task ( Post . Query , <EOL> self . _client , <EOL> cover_photo [ '<STR_LIT>' ] , <EOL> cover_photo [ '<STR_LIT>' ] , <EOL> None , <EOL> must_exist = False ) ] <EOL> if cover_photo_post is None : <EOL> raise InvalidRequestError ( '<STR_LIT>' ) <EOL> if cover_photo_post . IsUnshared ( ) : <EOL> raise PermissionError ( '<STR_LIT>' ) <EOL> if cover_photo_episode . viewpoint_id != self . _viewpoint_id : <EOL> raise InvalidRequestError ( '<STR_LIT>' % self . _viewpoint_id ) <EOL> if self . _op . checkpoint is None : <EOL> self . _revive_follower_ids = self . _GetRevivableFollowers ( self . _followers ) <EOL> self . _prev_values = { } <EOL> if '<STR_LIT:title>' in self . _vp_dict : <EOL> util . SetIfNotNone ( self . _prev_values , '<STR_LIT>' , self . _viewpoint . title ) <EOL> if '<STR_LIT>' in self . _vp_dict : <EOL> util . SetIfNotNone ( self . _prev_values , '<STR_LIT>' , self . _viewpoint . cover_photo ) <EOL> checkpoint = { '<STR_LIT>' : self . _revive_follower_ids } <EOL> util . SetIfNotEmpty ( checkpoint , '<STR_LIT>' , self . _prev_values ) <EOL> yield self . _op . SetCheckpoint ( self . _client , checkpoint ) <EOL> else : <EOL> self . _revive_follower_ids = self . _op . checkpoint [ '<STR_LIT>' ] <EOL> self . _prev_values = self . _op . checkpoint . get ( '<STR_LIT>' , { } ) <EOL> @ gen . coroutine <EOL> def _Update ( self ) : <EOL> """<STR_LIT>""" <EOL> yield gen . Task ( Follower . ReviveRemovedFollowers , self . _client , self . _followers ) <EOL> assert '<STR_LIT>' not in self . _vp_dict , self . _vp_dict <EOL> self . _viewpoint . UpdateFromKeywords ( ** self . _vp_dict ) <EOL> yield gen . Task ( self . _viewpoint . Update , self . _client ) <EOL> @ gen . coroutine <EOL> def _Account ( self ) : <EOL> """<STR_LIT>""" <EOL> acc_accum = AccountingAccumulator ( ) <EOL> yield acc_accum . ReviveFollowers ( self . _client , self . _viewpoint_id , self . _revive_follower_ids ) <EOL> yield acc_accum . Apply ( self . _client ) <EOL> @ gen . coroutine <EOL> def _Notify ( self ) : <EOL> """<STR_LIT>""" <EOL> yield NotificationManager . NotifyReviveFollowers ( self . _client , <EOL> self . _viewpoint_id , <EOL> self . _revive_follower_ids , <EOL> self . _op . timestamp ) <EOL> yield NotificationManager . NotifyUpdateViewpoint ( self . _client , <EOL> self . _vp_dict , <EOL> self . _followers , <EOL> self . _prev_values , <EOL> self . _act_dict ) </s>
