<s> """<STR_LIT>""" <EOL> __authors__ = [ '<STR_LIT>' , <EOL> '<STR_LIT>' ] <EOL> import base64 <EOL> import logging <EOL> import json <EOL> import time <EOL> import toro <EOL> import validictory <EOL> from copy import deepcopy <EOL> from functools import partial <EOL> from tornado import gen , web <EOL> from tornado . ioloop import IOLoop <EOL> from viewfinder . backend . base import constants , counters , handler , secrets , util <EOL> from viewfinder . backend . base . message import Message , MIN_SUPPORTED_MESSAGE_VERSION , MAX_SUPPORTED_MESSAGE_VERSION <EOL> from viewfinder . backend . base . message import REQUIRED_MIGRATORS , INLINE_INVALIDATIONS , INLINE_COMMENTS <EOL> from viewfinder . backend . base . message import EXTRACT_FILE_SIZES , EXTRACT_ASSET_KEYS , SPLIT_NAMES , EXPLICIT_SHARE_ORDER <EOL> from viewfinder . backend . base . message import SUPPRESS_BLANK_COVER_PHOTO , SUPPORT_MULTIPLE_IDENTITIES_PER_CONTACT <EOL> from viewfinder . backend . base . message import RENAME_PHOTO_LABEL , SUPPORT_REMOVED_FOLLOWERS , SUPPRESS_COPY_TIMESTAMP <EOL> from viewfinder . backend . base . message import SUPPORT_CONTACT_LIMITS , SUPPRESS_EMPTY_TITLE <EOL> from viewfinder . backend . base . exceptions import InvalidRequestError , PermissionError <EOL> from viewfinder . backend . db import db_client <EOL> from viewfinder . backend . db . accounting import Accounting <EOL> from viewfinder . backend . db . activity import Activity <EOL> from viewfinder . backend . db . asset_id import IdPrefix <EOL> from viewfinder . backend . db . comment import Comment <EOL> from viewfinder . backend . db . client_log import ClientLog <EOL> from viewfinder . backend . db . contact import Contact <EOL> from viewfinder . backend . db . episode import Episode <EOL> from viewfinder . backend . db . followed import Followed <EOL> from viewfinder . backend . db . follower import Follower <EOL> from viewfinder . backend . db . identity import Identity <EOL> from viewfinder . backend . db . operation import Operation <EOL> from viewfinder . backend . db . photo import Photo <EOL> from viewfinder . backend . db . post import Post <EOL> from viewfinder . backend . db . subscription import Subscription <EOL> from viewfinder . backend . db . user import User <EOL> from viewfinder . backend . db . user_photo import UserPhoto <EOL> from viewfinder . backend . db . user_post import UserPost <EOL> from viewfinder . backend . db . viewpoint import Viewpoint <EOL> from viewfinder . backend . op . notification_manager import NotificationManager <EOL> from viewfinder . backend . resources . calendar import Calendar <EOL> from viewfinder . backend . resources . message . error_messages import INVALID_JSON_REQUEST , MERGE_COOKIE_NOT_CONFIRMED <EOL> from viewfinder . backend . resources . message . error_messages import MISSING_MERGE_SOURCE , UNSUPPORTED_ASSET_TYPE <EOL> from viewfinder . backend . resources . message . error_messages import UPDATE_PWD_NOT_CONFIRMED , IDENTITY_NOT_CANONICAL <EOL> from viewfinder . backend . services . itunes_store import ITunesStoreClient , VerifyResponse <EOL> from viewfinder . backend . www import base , json_schema , password_util , photo_store , www_util <EOL> _avg_req_time = counters . define_average ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> _req_per_min = counters . define_rate ( '<STR_LIT>' , '<STR_LIT>' , <NUM_LIT> ) <EOL> _fail_per_min = counters . define_rate ( '<STR_LIT>' , '<STR_LIT>' , <NUM_LIT> ) <EOL> @ gen . coroutine <EOL> def AddFollowers ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield Activity . VerifyActivityId ( client , user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> _ValidateContacts ( request [ '<STR_LIT>' ] ) <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , len ( request [ '<STR_LIT>' ] ) ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def AllocateIds ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> prefixes = request [ '<STR_LIT>' ] <EOL> timestamp = util . GetCurrentTimestamp ( ) <EOL> def ValidateId ( prefix ) : <EOL> """<STR_LIT>""" <EOL> if not IdPrefix . IsValid ( prefix ) : <EOL> raise InvalidRequestError ( UNSUPPORTED_ASSET_TYPE , asset_type = prefix ) <EOL> if not prefix in '<STR_LIT>' : <EOL> raise InvalidRequestError ( UNSUPPORTED_ASSET_TYPE , asset_type = IdPrefix . GetAssetName ( prefix ) ) <EOL> def ConstructId ( prefix , uniquifier ) : <EOL> if prefix == '<STR_LIT:a>' : <EOL> asset_id = Activity . ConstructActivityId ( timestamp , device_id , uniquifier ) <EOL> elif prefix == '<STR_LIT:c>' : <EOL> asset_id = Comment . ConstructCommentId ( timestamp , device_id , uniquifier ) <EOL> elif prefix == '<STR_LIT:p>' : <EOL> asset_id = Photo . ConstructPhotoId ( timestamp , device_id , uniquifier ) <EOL> else : <EOL> asset_id = Operation . ConstructOperationId ( device_id , uniquifier ) <EOL> return asset_id <EOL> for prefix in prefixes : <EOL> ValidateId ( prefix ) <EOL> unique_start = yield gen . Task ( User . AllocateAssetIds , client , user_id , len ( prefixes ) ) <EOL> asset_ids = [ ConstructId ( p , u ) for p , u in zip ( prefixes , range ( unique_start , unique_start + len ( prefixes ) ) ) ] <EOL> raise gen . Return ( { '<STR_LIT>' : asset_ids , '<STR_LIT>' : timestamp } ) <EOL> @ gen . coroutine <EOL> def BuildArchive ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> <NUM_LIT:0> , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % ( user_id , device_id ) ) <EOL> raise gen . Return ( { } ) <EOL> def GetCalendar ( client , obj_store , user_id , device_id , request , callback ) : <EOL> """<STR_LIT>""" <EOL> def _OnQueryUser ( user ) : <EOL> calendars = request [ '<STR_LIT>' ] <EOL> response = { '<STR_LIT>' : [ ] } <EOL> for cal in calendars : <EOL> if cal [ '<STR_LIT>' ] == '<STR_LIT>' : <EOL> cal_data = Calendar . GetHolidaysByLocale ( user . locale ) <EOL> else : <EOL> cal_data = Calendar . GetCalendar ( cal [ '<STR_LIT>' ] ) <EOL> response [ '<STR_LIT>' ] . append ( { '<STR_LIT>' : cal_data . calendar_id , <EOL> '<STR_LIT>' : cal [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : cal_data . GetEvents ( year = cal [ '<STR_LIT>' ] ) } ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , <EOL> len ( calendars ) , dict ( [ ( c [ '<STR_LIT>' ] , len ( c [ '<STR_LIT>' ] ) ) for c in response [ '<STR_LIT>' ] ] ) ) ) <EOL> callback ( response ) <EOL> User . Query ( client , user_id , None , _OnQueryUser ) <EOL> @ gen . coroutine <EOL> def HidePhotos ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> num_photos = sum ( len ( ep_dict [ '<STR_LIT>' ] ) for ep_dict in request [ '<STR_LIT>' ] ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , num_photos ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def ListIdentities ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> def _MakeIdentityDict ( ident ) : <EOL> i_dict = { '<STR_LIT>' : ident . key } <EOL> if ident . authority is not None : <EOL> i_dict [ '<STR_LIT>' ] = ident . authority <EOL> return i_dict <EOL> query_expr = '<STR_LIT>' % user_id <EOL> identities = yield gen . Task ( Identity . IndexQuery , client , query_expr , [ '<STR_LIT:key>' , '<STR_LIT>' ] ) <EOL> raise gen . Return ( { '<STR_LIT>' : [ _MakeIdentityDict ( ident ) for ident in identities ] } ) <EOL> @ gen . coroutine <EOL> def MergeAccounts ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> yield Activity . VerifyActivityId ( client , user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> source_user_cookie = request . pop ( '<STR_LIT>' , None ) <EOL> if source_user_cookie is not None : <EOL> merge_cookie = web . decode_signed_value ( secrets . GetSecret ( '<STR_LIT>' ) , <EOL> base . _USER_COOKIE_NAME , <EOL> source_user_cookie , <EOL> base . _USER_COOKIE_EXPIRES_DAYS ) <EOL> if merge_cookie is None : <EOL> raise web . HTTPError ( <NUM_LIT> , '<STR_LIT>' ) <EOL> source_user_dict = json . loads ( merge_cookie ) <EOL> source_user_id = source_user_dict [ '<STR_LIT>' ] <EOL> if not www_util . IsConfirmedCookie ( source_user_dict . get ( '<STR_LIT>' , None ) ) : <EOL> raise PermissionError ( MERGE_COOKIE_NOT_CONFIRMED , user_id = source_user_id ) <EOL> else : <EOL> source_identity_dict = request . pop ( '<STR_LIT>' , None ) <EOL> if source_identity_dict is None : <EOL> raise InvalidRequestError ( MISSING_MERGE_SOURCE ) <EOL> identity = yield Identity . VerifyConfirmedIdentity ( client , <EOL> source_identity_dict [ '<STR_LIT>' ] , <EOL> source_identity_dict [ '<STR_LIT>' ] ) <EOL> source_user_id = identity . user_id <EOL> if source_user_id is not None : <EOL> if source_user_id == user_id : <EOL> raise web . HTTPError ( <NUM_LIT> , '<STR_LIT>' ) <EOL> source_user = yield gen . Task ( User . Query , client , source_user_id , None ) <EOL> if source_user . IsTerminated ( ) : <EOL> raise web . HTTPError ( <NUM_LIT> , '<STR_LIT>' ) <EOL> request [ '<STR_LIT>' ] = source_user_id <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> else : <EOL> request . pop ( '<STR_LIT>' ) <EOL> request [ '<STR_LIT>' ] = identity . key <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , source_user_id or identity . key ) ) <EOL> raise gen . Return ( { } ) <EOL> def NewClientLogUrl ( client , obj_store , user_id , device_id , request , callback ) : <EOL> """<STR_LIT>""" <EOL> kwargs = { '<STR_LIT>' : user_id , <EOL> '<STR_LIT>' : device_id , <EOL> '<STR_LIT>' : request [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : request [ '<STR_LIT>' ] } <EOL> if '<STR_LIT>' in request : <EOL> kwargs [ '<STR_LIT>' ] = request [ '<STR_LIT>' ] <EOL> if '<STR_LIT>' in request : <EOL> kwargs [ '<STR_LIT>' ] = request [ '<STR_LIT>' ] <EOL> if '<STR_LIT>' in request : <EOL> kwargs [ '<STR_LIT>' ] = request [ '<STR_LIT>' ] <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , request [ '<STR_LIT>' ] ) ) <EOL> response = { '<STR_LIT>' : ClientLog . GetPutUrl ( ** kwargs ) } <EOL> callback ( response ) <EOL> @ gen . coroutine <EOL> def OldRemovePhotos ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> remove_episodes = [ ] <EOL> hide_episodes = [ ] <EOL> for ep_dict in request [ '<STR_LIT>' ] : <EOL> episode = yield gen . Task ( Episode . Query , client , ep_dict [ '<STR_LIT>' ] , None , must_exist = False ) <EOL> if episode is None or episode . viewpoint_id == base . ViewfinderContext . current ( ) . user . private_vp_id : <EOL> remove_episodes . append ( ep_dict ) <EOL> else : <EOL> hide_episodes . append ( ep_dict ) <EOL> hide_request = deepcopy ( request ) <EOL> if len ( hide_episodes ) > <NUM_LIT:0> : <EOL> hide_request [ '<STR_LIT>' ] = hide_episodes <EOL> yield HidePhotos ( client , obj_store , user_id , device_id , hide_request ) <EOL> remove_request = deepcopy ( request ) <EOL> remove_request [ '<STR_LIT>' ] = remove_episodes <EOL> yield RemovePhotos ( client , obj_store , user_id , device_id , remove_request ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def PostComment ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> headers = request . pop ( '<STR_LIT>' ) <EOL> activity = request . pop ( '<STR_LIT>' ) <EOL> viewpoint_id = request [ '<STR_LIT>' ] <EOL> yield Activity . VerifyActivityId ( client , user_id , device_id , activity [ '<STR_LIT>' ] ) <EOL> yield Comment . VerifyCommentId ( client , user_id , device_id , request [ '<STR_LIT>' ] ) <EOL> request = { '<STR_LIT>' : headers , <EOL> '<STR_LIT>' : user_id , <EOL> '<STR_LIT>' : activity , <EOL> '<STR_LIT>' : request } <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , viewpoint_id ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def QueryContacts ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> def _MakeContactDict ( contact ) : <EOL> """<STR_LIT>""" <EOL> c_dict = { '<STR_LIT>' : contact . contact_id , <EOL> '<STR_LIT>' : contact . contact_source } <EOL> util . SetIfNotNone ( c_dict , '<STR_LIT:name>' , contact . name ) <EOL> util . SetIfNotNone ( c_dict , '<STR_LIT>' , contact . given_name ) <EOL> util . SetIfNotNone ( c_dict , '<STR_LIT>' , contact . family_name ) <EOL> util . SetIfNotNone ( c_dict , '<STR_LIT>' , contact . rank ) <EOL> if contact . labels is not None and len ( contact . labels ) > <NUM_LIT:0> : <EOL> c_dict [ '<STR_LIT>' ] = list ( contact . labels ) <EOL> identities_list = [ ] <EOL> if contact . identities_properties is not None : <EOL> for identity_properties in contact . identities_properties : <EOL> identity_key = identity_properties [ <NUM_LIT:0> ] <EOL> identity_dict = { '<STR_LIT>' : identity_key } <EOL> util . SetIfNotNone ( identity_dict , '<STR_LIT:description>' , identity_properties [ <NUM_LIT:1> ] ) <EOL> util . SetIfNotNone ( identity_dict , '<STR_LIT>' , identity_key_to_user_id_map [ Identity . Canonicalize ( identity_key ) ] ) <EOL> identities_list . append ( identity_dict ) <EOL> c_dict [ '<STR_LIT>' ] = identities_list <EOL> return c_dict <EOL> start_key = request . get ( '<STR_LIT>' , None ) <EOL> limit = request . get ( '<STR_LIT>' , None ) <EOL> contacts = yield gen . Task ( Contact . RangeQuery , <EOL> client , <EOL> hash_key = user_id , <EOL> range_desc = None , <EOL> limit = limit , <EOL> col_names = None , <EOL> excl_start_key = start_key , <EOL> scan_forward = True ) <EOL> identity_keys = list ( { identity for co in contacts for identity in co . identities } ) <EOL> identity_dbkeys = [ db_client . DBKey ( identity_key , None ) for identity_key in identity_keys ] <EOL> identities = yield gen . Task ( Identity . BatchQuery , client , identity_dbkeys , None , must_exist = False ) <EOL> user_ids = [ identity . user_id if identity is not None else None for identity in identities ] <EOL> identity_key_to_user_id_map = dict ( zip ( identity_keys , user_ids ) ) <EOL> response = { '<STR_LIT>' : len ( contacts ) , <EOL> '<STR_LIT>' : [ _MakeContactDict ( co ) for co in contacts ] } <EOL> if contacts : <EOL> response [ '<STR_LIT>' ] = contacts [ - <NUM_LIT:1> ] . sort_key <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , response [ '<STR_LIT>' ] , start_key , response . get ( '<STR_LIT>' , '<STR_LIT:None>' ) ) ) <EOL> raise gen . Return ( response ) <EOL> @ gen . engine <EOL> def QueryEpisodes ( client , obj_store , user_id , device_id , request , callback ) : <EOL> """<STR_LIT>""" <EOL> def _MakePhotoDict ( post , photo , user_post , user_photo ) : <EOL> ph_dict = photo . MakeMetadataDict ( post , user_post , user_photo ) <EOL> if not post . IsRemoved ( ) : <EOL> _AddPhotoUrls ( obj_store , ph_dict ) <EOL> return ph_dict <EOL> limit = request . get ( '<STR_LIT>' , None ) <EOL> episode_keys = [ db_client . DBKey ( ep_dict [ '<STR_LIT>' ] , None ) for ep_dict in request [ '<STR_LIT>' ] ] <EOL> post_tasks = [ ] <EOL> for ep_dict in request [ '<STR_LIT>' ] : <EOL> if ep_dict . get ( '<STR_LIT>' , False ) : <EOL> post_tasks . append ( gen . Task ( Post . RangeQuery , client , ep_dict [ '<STR_LIT>' ] , None , limit , <EOL> None , excl_start_key = ep_dict . get ( '<STR_LIT>' , None ) ) ) <EOL> else : <EOL> post_tasks . append ( util . GenConstant ( None ) ) <EOL> episodes , posts_list = yield [ gen . Task ( Episode . BatchQuery , client , episode_keys , None , must_exist = False ) , <EOL> gen . Multi ( post_tasks ) ] <EOL> viewpoint_keys = [ db_client . DBKey ( viewpoint_id , None ) <EOL> for viewpoint_id in set ( ep . viewpoint_id for ep in episodes if ep is not None ) ] <EOL> follower_keys = [ db_client . DBKey ( user_id , db_key . hash_key ) for db_key in viewpoint_keys ] <EOL> all_posts = [ post for posts in posts_list if posts is not None for post in posts ] <EOL> photo_keys = [ db_client . DBKey ( post . photo_id , None ) for post in all_posts ] <EOL> user_post_keys = [ db_client . DBKey ( user_id , Post . ConstructPostId ( post . episode_id , post . photo_id ) ) <EOL> for post in all_posts ] <EOL> if user_id : <EOL> user_photo_task = gen . Task ( UserPhoto . BatchQuery , client , <EOL> [ db_client . DBKey ( user_id , post . photo_id ) for post in all_posts ] , <EOL> None , must_exist = False ) <EOL> else : <EOL> user_photo_task = util . GenConstant ( None ) <EOL> viewpoints , followers , photos , user_posts , user_photos = yield [ <EOL> gen . Task ( Viewpoint . BatchQuery , client , viewpoint_keys , None , must_exist = False ) , <EOL> gen . Task ( Follower . BatchQuery , client , follower_keys , None , must_exist = False ) , <EOL> gen . Task ( Photo . BatchQuery , client , photo_keys , None ) , <EOL> gen . Task ( UserPost . BatchQuery , client , user_post_keys , None , must_exist = False ) , <EOL> user_photo_task , <EOL> ] <EOL> viewable_viewpoint_ids = set ( viewpoint . viewpoint_id for viewpoint , follower in zip ( viewpoints , followers ) <EOL> if _CanViewViewpointContent ( viewpoint , follower ) ) <EOL> response_dict = { '<STR_LIT>' : [ ] } <EOL> num_photos = <NUM_LIT:0> <EOL> for ep_dict , episode , posts in zip ( request [ '<STR_LIT>' ] , episodes , posts_list ) : <EOL> photo_info_list = [ ] <EOL> if ep_dict . get ( '<STR_LIT>' , False ) : <EOL> for post in posts : <EOL> photo = photos . pop ( <NUM_LIT:0> ) <EOL> user_post = user_posts . pop ( <NUM_LIT:0> ) <EOL> user_photo = user_photos . pop ( <NUM_LIT:0> ) if user_photos is not None else None <EOL> assert photo . photo_id == post . photo_id , ( episode , post , photo ) <EOL> if user_photo : <EOL> assert user_photo . photo_id == photo . photo_id <EOL> assert user_photo . user_id == user_id <EOL> photo_info_list . append ( ( post , photo , user_post , user_photo ) ) <EOL> if episode is not None and episode . viewpoint_id in viewable_viewpoint_ids : <EOL> response_ep_dict = { '<STR_LIT>' : ep_dict [ '<STR_LIT>' ] } <EOL> if ep_dict . get ( '<STR_LIT>' , False ) : <EOL> response_ep_dict . update ( episode . _asdict ( ) ) <EOL> if ep_dict . get ( '<STR_LIT>' , False ) : <EOL> response_ep_dict [ '<STR_LIT>' ] = [ _MakePhotoDict ( photo , post , user_post , user_photo ) <EOL> for photo , post , user_post , user_photo in photo_info_list ] <EOL> if len ( photo_info_list ) > <NUM_LIT:0> : <EOL> response_ep_dict [ '<STR_LIT>' ] = photo_info_list [ - <NUM_LIT:1> ] [ <NUM_LIT:0> ] . photo_id <EOL> num_photos += len ( photo_info_list ) <EOL> response_dict [ '<STR_LIT>' ] . append ( response_ep_dict ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , len ( response_dict [ '<STR_LIT>' ] ) , num_photos ) ) <EOL> callback ( response_dict ) <EOL> @ gen . coroutine <EOL> def QueryFollowed ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> start_key = request . get ( '<STR_LIT>' , None ) <EOL> limit = request . get ( '<STR_LIT>' , None ) <EOL> followed = yield gen . Task ( Followed . RangeQuery , <EOL> client , <EOL> hash_key = user_id , <EOL> range_desc = None , <EOL> limit = limit , <EOL> col_names = [ '<STR_LIT>' ] , <EOL> excl_start_key = start_key ) <EOL> last_key = followed [ - <NUM_LIT:1> ] . sort_key if len ( followed ) > <NUM_LIT:0> else None <EOL> viewpoint_keys = [ db_client . DBKey ( f . viewpoint_id , None ) for f in followed ] <EOL> follower_keys = [ db_client . DBKey ( user_id , f . viewpoint_id ) for f in followed ] <EOL> viewpoints , followers = yield [ gen . Task ( Viewpoint . BatchQuery , client , viewpoint_keys , None , must_exist = False ) , <EOL> gen . Task ( Follower . BatchQuery , client , follower_keys , None , must_exist = False ) ] <EOL> response = { '<STR_LIT>' : [ _MakeViewpointMetadataDict ( v , f , obj_store ) <EOL> for v , f in zip ( viewpoints , followers ) <EOL> if v is not None ] } <EOL> util . SetIfNotNone ( response , '<STR_LIT>' , last_key ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , len ( response [ '<STR_LIT>' ] ) , start_key , <EOL> response . get ( '<STR_LIT>' , '<STR_LIT:None>' ) ) ) <EOL> raise gen . Return ( response ) <EOL> @ gen . coroutine <EOL> def QueryNotifications ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> MAX_LONG_POLL = <NUM_LIT> <EOL> LONG_POLL_INTERVAL = <NUM_LIT:5> <EOL> start_key = int ( request . get ( '<STR_LIT>' ) ) if '<STR_LIT>' in request else None <EOL> limit = request . get ( '<STR_LIT>' , None ) <EOL> scan_forward = request . get ( '<STR_LIT>' , True ) <EOL> max_long_poll = min ( int ( request . get ( '<STR_LIT>' , <NUM_LIT:0> ) ) , <EOL> MAX_LONG_POLL ) <EOL> if max_long_poll > <NUM_LIT:0> : <EOL> deadline = IOLoop . current ( ) . time ( ) + max_long_poll <EOL> else : <EOL> deadline = None <EOL> while True : <EOL> notifications = yield NotificationManager . QuerySince ( client , <EOL> user_id , <EOL> device_id , <EOL> start_key , <EOL> limit = limit , <EOL> scan_forward = scan_forward ) <EOL> if len ( notifications ) > <NUM_LIT:0> or deadline is None : <EOL> break <EOL> now = IOLoop . current ( ) . time ( ) <EOL> next_try = now + LONG_POLL_INTERVAL <EOL> if next_try >= deadline : <EOL> break <EOL> vf_context = base . ViewfinderContext . current ( ) <EOL> assert vf_context . connection_close_event is not None <EOL> try : <EOL> yield vf_context . connection_close_event . wait ( next_try ) <EOL> except toro . Timeout : <EOL> pass <EOL> else : <EOL> assert vf_context . connection_close_event . is_set ( ) <EOL> break <EOL> activity_keys = [ db_client . DBKey ( n . viewpoint_id , n . activity_id ) <EOL> for n in notifications <EOL> if n . activity_id is not None ] <EOL> activities = yield gen . Task ( Activity . BatchQuery , client , activity_keys , None ) <EOL> response = { '<STR_LIT>' : [ ] } <EOL> if len ( notifications ) > <NUM_LIT:0> : <EOL> response [ '<STR_LIT>' ] = www_util . FormatIntegralLastKey ( notifications [ - <NUM_LIT:1> ] . notification_id ) <EOL> for notification in notifications : <EOL> notification_dict = { '<STR_LIT>' : notification . notification_id , <EOL> '<STR_LIT:name>' : notification . name , <EOL> '<STR_LIT>' : notification . sender_id , <EOL> '<STR_LIT>' : notification . timestamp } <EOL> util . SetIfNotNone ( notification_dict , '<STR_LIT>' , notification . op_id ) <EOL> invalidate = notification . GetInvalidate ( ) <EOL> util . SetIfNotNone ( notification_dict , '<STR_LIT>' , invalidate ) <EOL> if notification . update_seq is not None or notification . viewed_seq is not None : <EOL> vp_dict = notification_dict . setdefault ( '<STR_LIT>' , { } ) . setdefault ( '<STR_LIT>' , { } ) <EOL> vp_dict [ '<STR_LIT>' ] = notification . viewpoint_id <EOL> if notification . update_seq is not None : <EOL> vp_dict [ '<STR_LIT>' ] = notification . update_seq <EOL> if notification . viewed_seq is not None : <EOL> vp_dict [ '<STR_LIT>' ] = notification . viewed_seq <EOL> if notification . activity_id is not None : <EOL> activity = activities . pop ( <NUM_LIT:0> ) <EOL> activity_dict = activity . MakeMetadataDict ( ) <EOL> notification_dict . setdefault ( '<STR_LIT>' , { } ) [ '<STR_LIT>' ] = activity_dict <EOL> if activity . name == '<STR_LIT>' and notification . invalidate is None : <EOL> comment_id = activity_dict [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> comment = yield gen . Task ( Comment . Query , client , notification . viewpoint_id , comment_id , col_names = None ) <EOL> notification_dict [ '<STR_LIT>' ] [ '<STR_LIT>' ] = comment . _asdict ( ) <EOL> response [ '<STR_LIT>' ] . append ( notification_dict ) <EOL> if len ( response [ '<STR_LIT>' ] ) > <NUM_LIT:0> : <EOL> def _AccountingAsDict ( act ) : <EOL> if act is None : <EOL> return None <EOL> act_dict = act . _asdict ( ) <EOL> act_dict . pop ( '<STR_LIT>' , None ) <EOL> act_dict . pop ( '<STR_LIT>' , None ) <EOL> act_dict . pop ( '<STR_LIT>' , None ) <EOL> return act_dict <EOL> owned , shared , visible = yield gen . Task ( Accounting . QueryUserAccounting , client , user_id ) <EOL> usage_dict = { } <EOL> util . SetIfNotNone ( usage_dict , '<STR_LIT>' , _AccountingAsDict ( owned ) ) <EOL> util . SetIfNotNone ( usage_dict , '<STR_LIT>' , _AccountingAsDict ( shared ) ) <EOL> util . SetIfNotNone ( usage_dict , '<STR_LIT>' , _AccountingAsDict ( visible ) ) <EOL> if len ( usage_dict . keys ( ) ) > <NUM_LIT:0> : <EOL> last_notification = response [ '<STR_LIT>' ] [ - <NUM_LIT:1> ] <EOL> last_notification . setdefault ( '<STR_LIT>' , { } ) [ '<STR_LIT:user>' ] = { '<STR_LIT>' : usage_dict } <EOL> num_uploads = len ( [ a for a in activities if a is not None and a . name == '<STR_LIT>' ] ) <EOL> num_shares = len ( [ a for a in activities if a is not None and a . name in [ '<STR_LIT>' , '<STR_LIT>' ] ] ) <EOL> num_unshares = len ( [ a for a in activities if a is not None and a . name == '<STR_LIT>' ] ) <EOL> num_comment_posts = len ( [ a for a in activities if a is not None and a . name == '<STR_LIT>' ] ) <EOL> logging . info ( '<STR_LIT>' <EOL> '<STR_LIT>' % <EOL> ( user_id , device_id , start_key , len ( notifications ) , num_uploads , num_shares , <EOL> num_unshares , num_comment_posts ) ) <EOL> if request [ '<STR_LIT>' ] [ '<STR_LIT>' ] < Message . UPDATE_SHARE_VERSION : <EOL> raise gen . Return ( { '<STR_LIT>' : [ ] } ) <EOL> else : <EOL> raise gen . Return ( response ) <EOL> @ gen . coroutine <EOL> def QueryUsers ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> user_friend_list = yield gen . Task ( User . QueryUsers , client , user_id , request [ '<STR_LIT>' ] ) <EOL> user_dicts = yield [ gen . Task ( user . MakeUserMetadataDict , client , user_id , forward_friend , reverse_friend ) <EOL> for user , forward_friend , reverse_friend in user_friend_list ] <EOL> response = { '<STR_LIT>' : user_dicts } <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , len ( user_dicts ) ) ) <EOL> raise gen . Return ( response ) <EOL> @ gen . coroutine <EOL> def QueryViewpoints ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> @ gen . coroutine <EOL> def _QueryFollowers ( ) : <EOL> """<STR_LIT>""" <EOL> tasks = [ ] <EOL> for vp_dict in request [ '<STR_LIT>' ] : <EOL> if vp_dict . get ( '<STR_LIT>' , False ) : <EOL> start_key = vp_dict . get ( '<STR_LIT>' , None ) <EOL> tasks . append ( Viewpoint . QueryFollowers ( client , <EOL> vp_dict [ '<STR_LIT>' ] , <EOL> excl_start_key = int ( start_key ) if start_key is not None else None , <EOL> limit = limit ) ) <EOL> else : <EOL> tasks . append ( util . GenConstant ( None ) ) <EOL> follower_results = yield tasks <EOL> raise gen . Return ( follower_results ) <EOL> @ gen . coroutine <EOL> def _QueryActivities ( ) : <EOL> """<STR_LIT>""" <EOL> tasks = [ ] <EOL> for vp_dict in request [ '<STR_LIT>' ] : <EOL> if vp_dict . get ( '<STR_LIT>' , False ) : <EOL> tasks . append ( gen . Task ( Viewpoint . QueryActivities , client , vp_dict [ '<STR_LIT>' ] , <EOL> excl_start_key = vp_dict . get ( '<STR_LIT>' , None ) , <EOL> limit = limit ) ) <EOL> else : <EOL> tasks . append ( util . GenConstant ( None ) ) <EOL> activity_results = yield tasks <EOL> raise gen . Return ( activity_results ) <EOL> @ gen . coroutine <EOL> def _QueryEpisodes ( ) : <EOL> """<STR_LIT>""" <EOL> tasks = [ ] <EOL> for vp_dict in request [ '<STR_LIT>' ] : <EOL> if vp_dict . get ( '<STR_LIT>' , False ) : <EOL> tasks . append ( gen . Task ( Viewpoint . QueryEpisodes , client , vp_dict [ '<STR_LIT>' ] , <EOL> excl_start_key = vp_dict . get ( '<STR_LIT>' , None ) , <EOL> limit = limit ) ) <EOL> else : <EOL> tasks . append ( util . GenConstant ( None ) ) <EOL> episode_results = yield tasks <EOL> raise gen . Return ( episode_results ) <EOL> @ gen . coroutine <EOL> def _QueryComments ( ) : <EOL> """<STR_LIT>""" <EOL> tasks = [ ] <EOL> for vp_dict in request [ '<STR_LIT>' ] : <EOL> if vp_dict . get ( '<STR_LIT>' , False ) : <EOL> tasks . append ( gen . Task ( Viewpoint . QueryComments , client , vp_dict [ '<STR_LIT>' ] , <EOL> excl_start_key = vp_dict . get ( '<STR_LIT>' , None ) , <EOL> limit = limit ) ) <EOL> else : <EOL> tasks . append ( util . GenConstant ( None ) ) <EOL> comment_results = yield tasks <EOL> raise gen . Return ( comment_results ) <EOL> limit = request . get ( '<STR_LIT>' , None ) <EOL> viewpoint_keys = [ db_client . DBKey ( vp_dict [ '<STR_LIT>' ] , None ) for vp_dict in request [ '<STR_LIT>' ] ] <EOL> follower_keys = [ db_client . DBKey ( user_id , vp_dict [ '<STR_LIT>' ] ) for vp_dict in request [ '<STR_LIT>' ] ] <EOL> results = yield [ gen . Task ( Viewpoint . BatchQuery , client , viewpoint_keys , None , must_exist = False ) , <EOL> gen . Task ( Follower . BatchQuery , client , follower_keys , None , must_exist = False ) , <EOL> _QueryFollowers ( ) , <EOL> _QueryActivities ( ) , <EOL> _QueryEpisodes ( ) , <EOL> _QueryComments ( ) ] <EOL> viewpoints , followers , follower_id_results , activity_results , episode_results , comment_results = results <EOL> zip_list = zip ( request [ '<STR_LIT>' ] , viewpoints , followers , follower_id_results , activity_results , <EOL> episode_results , comment_results ) <EOL> num_followers = <NUM_LIT:0> <EOL> num_activities = <NUM_LIT:0> <EOL> num_episodes = <NUM_LIT:0> <EOL> num_comments = <NUM_LIT:0> <EOL> response_vp_dicts = [ ] <EOL> for vp_dict , viewpoint , follower , follower_result , activity_result , episode_result , comment_result in zip_list : <EOL> if follower is not None : <EOL> response_vp_dict = { '<STR_LIT>' : viewpoint . viewpoint_id } <EOL> if vp_dict . get ( '<STR_LIT>' , False ) : <EOL> response_vp_dict . update ( _MakeViewpointMetadataDict ( viewpoint , follower , obj_store ) ) <EOL> if not follower . IsRemoved ( ) and vp_dict . get ( '<STR_LIT>' , False ) : <EOL> followers , last_key = follower_result <EOL> response_vp_dict [ '<STR_LIT>' ] = [ foll . MakeFriendMetadataDict ( ) for foll in followers ] <EOL> if last_key is not None : <EOL> response_vp_dict [ '<STR_LIT>' ] = www_util . FormatIntegralLastKey ( last_key ) <EOL> num_followers += len ( followers ) <EOL> if _CanViewViewpointContent ( viewpoint , follower ) : <EOL> if vp_dict . get ( '<STR_LIT>' , False ) : <EOL> activities , last_key = activity_result <EOL> response_vp_dict [ '<STR_LIT>' ] = [ act . MakeMetadataDict ( ) for act in activities ] <EOL> if last_key is not None : <EOL> response_vp_dict [ '<STR_LIT>' ] = last_key <EOL> num_activities += len ( activities ) <EOL> if vp_dict . get ( '<STR_LIT>' , False ) : <EOL> episodes , last_key = episode_result <EOL> response_vp_dict [ '<STR_LIT>' ] = [ ep . _asdict ( ) for ep in episodes ] <EOL> if last_key is not None : <EOL> response_vp_dict [ '<STR_LIT>' ] = last_key <EOL> num_episodes += len ( episodes ) <EOL> if vp_dict . get ( '<STR_LIT>' , False ) : <EOL> comments , last_key = comment_result <EOL> response_vp_dict [ '<STR_LIT>' ] = [ co . _asdict ( ) for co in comments ] <EOL> if last_key is not None : <EOL> response_vp_dict [ '<STR_LIT>' ] = last_key <EOL> num_comments += len ( comments ) <EOL> response_vp_dicts . append ( response_vp_dict ) <EOL> logging . info ( '<STR_LIT>' <EOL> '<STR_LIT>' % <EOL> ( user_id , device_id , len ( response_vp_dicts ) , num_followers , <EOL> num_activities , num_episodes , num_comments ) ) <EOL> raise gen . Return ( { '<STR_LIT>' : response_vp_dicts } ) <EOL> def RecordSubscription ( client , obj_store , user_id , device_id , request , callback ) : <EOL> """<STR_LIT>""" <EOL> def _OnRecord ( verify_response , op ) : <EOL> callback ( { '<STR_LIT>' : Subscription . CreateFromITunes ( user_id , verify_response ) . MakeMetadataDict ( ) } ) <EOL> def _OnVerify ( environment , verify_response ) : <EOL> if ( environment == '<STR_LIT>' and <EOL> verify_response . GetStatus ( ) == VerifyResponse . SANDBOX_ON_PROD_ERROR ) : <EOL> ITunesStoreClient . Instance ( '<STR_LIT>' ) . VerifyReceipt ( receipt_data , partial ( _OnVerify , '<STR_LIT>' ) ) <EOL> return <EOL> if not verify_response . IsValid ( ) : <EOL> logging . warning ( '<STR_LIT>' , request ) <EOL> raise web . HTTPError ( <NUM_LIT> , '<STR_LIT>' ) <EOL> if environment == '<STR_LIT>' : <EOL> op_request = { <EOL> '<STR_LIT>' : request [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : user_id , <EOL> '<STR_LIT>' : verify_response . ToString ( ) , <EOL> } <EOL> Operation . CreateAndExecute ( client , user_id , device_id , <EOL> '<STR_LIT>' , <EOL> op_request , partial ( _OnRecord , verify_response ) ) <EOL> else : <EOL> callback ( { '<STR_LIT>' : Subscription . CreateFromITunes ( user_id , verify_response ) . MakeMetadataDict ( ) } ) <EOL> receipt_data = base64 . b64decode ( request [ '<STR_LIT>' ] ) <EOL> ITunesStoreClient . Instance ( '<STR_LIT>' ) . VerifyReceipt ( receipt_data , partial ( _OnVerify , '<STR_LIT>' ) ) <EOL> @ gen . coroutine <EOL> def RemoveContacts ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , len ( request [ '<STR_LIT>' ] ) ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def RemoveFollowers ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield Activity . VerifyActivityId ( client , user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , len ( request [ '<STR_LIT>' ] ) ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def RemovePhotos ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> num_photos = sum ( len ( ep_dict [ '<STR_LIT>' ] ) for ep_dict in request [ '<STR_LIT>' ] ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , num_photos ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def RemoveViewpoint ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> viewpoint_id = request [ '<STR_LIT>' ] <EOL> if base . ViewfinderContext . current ( ) . user . private_vp_id == viewpoint_id : <EOL> raise PermissionError ( '<STR_LIT>' % viewpoint_id ) <EOL> yield gen . Task ( Operation . CreateAndExecute , client , user_id , device_id , '<STR_LIT>' , request ) <EOL> logging . info ( '<STR_LIT>' % ( user_id , device_id , viewpoint_id ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def ResolveContacts ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> ident_tasks = [ ] <EOL> for ident in request [ '<STR_LIT>' ] : <EOL> Identity . ValidateKey ( ident ) <EOL> if ident . startswith ( ( '<STR_LIT>' , '<STR_LIT>' ) ) : <EOL> ident_tasks . append ( gen . Task ( Identity . Query , client , ident , None , must_exist = False ) ) <EOL> else : <EOL> ident_tasks . append ( util . GenConstant ( None ) ) <EOL> ident_results = yield ident_tasks <EOL> user_tasks = [ ] <EOL> for ident in ident_results : <EOL> if ident is not None and ident . user_id is not None : <EOL> user_tasks . append ( gen . Task ( User . Query , client , ident . user_id , None , must_exist = False ) ) <EOL> else : <EOL> user_tasks . append ( util . GenConstant ( None ) ) <EOL> user_results = yield user_tasks <EOL> results = [ ] <EOL> for request_ident , ident , user in zip ( request [ '<STR_LIT>' ] , ident_results , user_results ) : <EOL> result_contact = { '<STR_LIT>' : request_ident } <EOL> if user is not None : <EOL> assert ident is not None and user . user_id == ident . user_id <EOL> assert ident . key == request_ident <EOL> result_contact [ '<STR_LIT>' ] = ident . user_id <EOL> util . SetIfNotNone ( result_contact , '<STR_LIT:name>' , user . name ) <EOL> util . SetIfNotNone ( result_contact , '<STR_LIT>' , user . given_name ) <EOL> util . SetIfNotNone ( result_contact , '<STR_LIT>' , user . family_name ) <EOL> result_contact [ '<STR_LIT>' ] = user . MakeLabelList ( False ) <EOL> results . append ( result_contact ) <EOL> raise gen . Return ( { '<STR_LIT>' : results } ) <EOL> @ gen . coroutine <EOL> def SavePhotos ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield Activity . VerifyActivityId ( client , user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> vp_ids = request . get ( '<STR_LIT>' , [ ] ) <EOL> ep_dicts = request . get ( '<STR_LIT>' , [ ] ) <EOL> num_photos = <NUM_LIT:0> <EOL> for ep_dict in ep_dicts : <EOL> yield Episode . VerifyEpisodeId ( client , user_id , device_id , ep_dict [ '<STR_LIT>' ] ) <EOL> num_photos += len ( ep_dict [ '<STR_LIT>' ] ) <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , len ( vp_ids ) , len ( ep_dicts ) , num_photos ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def ShareExisting ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield Activity . VerifyActivityId ( client , user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> num_photos = <NUM_LIT:0> <EOL> for ep_dict in request [ '<STR_LIT>' ] : <EOL> yield Episode . VerifyEpisodeId ( client , user_id , device_id , ep_dict [ '<STR_LIT>' ] ) <EOL> num_photos += len ( ep_dict [ '<STR_LIT>' ] ) <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , request [ '<STR_LIT>' ] , len ( request [ '<STR_LIT>' ] ) , num_photos ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def ShareNew ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield Activity . VerifyActivityId ( client , user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> vp_dict = request [ '<STR_LIT>' ] <EOL> yield Viewpoint . VerifyViewpointId ( client , user_id , device_id , vp_dict [ '<STR_LIT>' ] ) <EOL> num_photos = <NUM_LIT:0> <EOL> for ep_dict in request [ '<STR_LIT>' ] : <EOL> yield Episode . VerifyEpisodeId ( client , user_id , device_id , ep_dict [ '<STR_LIT>' ] ) <EOL> num_photos += len ( ep_dict [ '<STR_LIT>' ] ) <EOL> _ValidateContacts ( request [ '<STR_LIT>' ] ) <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , vp_dict [ '<STR_LIT>' ] , len ( request [ '<STR_LIT>' ] ) , <EOL> num_photos ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def TerminateAccount ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % ( user_id , device_id ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def UnlinkIdentity ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> Identity . ValidateKey ( request [ '<STR_LIT>' ] ) <EOL> unlink_ident = yield gen . Task ( Identity . Query , client , request [ '<STR_LIT>' ] , None , must_exist = False ) <EOL> if unlink_ident is not None : <EOL> if unlink_ident . user_id != user_id : <EOL> raise PermissionError ( '<STR_LIT>' % request [ '<STR_LIT>' ] ) <EOL> if unlink_ident . authority is not None : <EOL> query_expr = '<STR_LIT>' % user_id <EOL> all_identities = yield gen . Task ( Identity . IndexQuery , client , query_expr , [ '<STR_LIT:key>' , '<STR_LIT>' ] ) <EOL> if not any ( [ one_identity . authority is not None and one_identity . key != unlink_ident . key <EOL> for one_identity in all_identities ] ) : <EOL> raise PermissionError ( '<STR_LIT>' <EOL> '<STR_LIT>' % unlink_ident . authority ) <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , request [ '<STR_LIT>' ] ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def Unshare ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> yield Activity . VerifyActivityId ( client , user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , request [ '<STR_LIT>' ] , len ( request [ '<STR_LIT>' ] ) , <EOL> sum ( [ len ( ep_dict [ '<STR_LIT>' ] ) for ep_dict in request [ '<STR_LIT>' ] ] ) ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def UpdateDevice ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> device_dict = request [ '<STR_LIT>' ] <EOL> if device_dict . has_key ( '<STR_LIT>' ) and device_dict [ '<STR_LIT>' ] != device_id : <EOL> raise web . HTTPError ( <NUM_LIT> , '<STR_LIT>' % <EOL> ( device_dict [ '<STR_LIT>' ] , device_id ) ) <EOL> request [ '<STR_LIT>' ] = user_id <EOL> request [ '<STR_LIT>' ] = device_id <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % ( user_id , device_id ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def UpdateEpisode ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> yield Activity . VerifyActivityId ( client , user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> headers = request . pop ( '<STR_LIT>' ) <EOL> activity = request . pop ( '<STR_LIT>' ) <EOL> request = { '<STR_LIT>' : headers , <EOL> '<STR_LIT>' : user_id , <EOL> '<STR_LIT>' : activity , <EOL> '<STR_LIT>' : request } <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def UpdateFollower ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def UpdateFriend ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def UpdatePhoto ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> if request [ '<STR_LIT>' ] [ '<STR_LIT>' ] >= Message . ADD_OP_HEADER_VERSION : <EOL> yield Activity . VerifyActivityId ( client , user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> else : <EOL> yield Activity . VerifyActivityId ( client , user_id , <NUM_LIT:0> , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> request = { '<STR_LIT>' : request . pop ( '<STR_LIT>' ) , <EOL> '<STR_LIT>' : request . pop ( '<STR_LIT>' ) , <EOL> '<STR_LIT>' : request } <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def UpdateUser ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> password = request . pop ( '<STR_LIT:password>' , None ) <EOL> if password is not None : <EOL> context = base . ViewfinderContext . current ( ) <EOL> user = context . user <EOL> old_password = request . pop ( '<STR_LIT>' , None ) <EOL> if not context . IsConfirmedUser ( ) : <EOL> if old_password is None and user . pwd_hash is not None : <EOL> raise PermissionError ( UPDATE_PWD_NOT_CONFIRMED ) <EOL> if user . pwd_hash is not None : <EOL> yield password_util . ValidateUserPassword ( client , user , old_password ) <EOL> pwd_hash , salt = password_util . GeneratePasswordHash ( password ) <EOL> request [ '<STR_LIT>' ] = pwd_hash <EOL> request [ '<STR_LIT>' ] = salt <EOL> request = { '<STR_LIT>' : request . pop ( '<STR_LIT>' ) , <EOL> '<STR_LIT>' : request , <EOL> '<STR_LIT>' : request . pop ( '<STR_LIT>' , None ) } <EOL> request [ '<STR_LIT>' ] [ '<STR_LIT>' ] = user_id <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % ( user_id , device_id ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def UpdateUserPhoto ( client , obj_store , user_id , device_id , request ) : <EOL> op_request = { '<STR_LIT>' : request . pop ( '<STR_LIT>' ) , <EOL> '<STR_LIT>' : request } <EOL> op_request [ '<STR_LIT>' ] [ '<STR_LIT>' ] = user_id <EOL> yield gen . Task ( Operation . CreateAndExecute , client , user_id , device_id , '<STR_LIT>' , op_request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , op_request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def UpdateViewpoint ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> yield Activity . VerifyActivityId ( client , user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> headers = request . pop ( '<STR_LIT>' ) <EOL> activity = request . pop ( '<STR_LIT>' ) <EOL> viewpoint_id = request [ '<STR_LIT>' ] <EOL> follower_columns = Follower . _table . GetColumnNames ( ) <EOL> viewpoint_columns = Viewpoint . _table . GetColumnNames ( ) <EOL> if all ( attr in follower_columns for attr in request . keys ( ) ) : <EOL> request = { '<STR_LIT>' : headers , <EOL> '<STR_LIT>' : user_id , <EOL> '<STR_LIT>' : request } <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> elif all ( attr in viewpoint_columns for attr in request . keys ( ) ) : <EOL> request = { '<STR_LIT>' : headers , <EOL> '<STR_LIT>' : user_id , <EOL> '<STR_LIT>' : activity , <EOL> '<STR_LIT>' : request } <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> else : <EOL> raise web . HTTPError ( <NUM_LIT> , '<STR_LIT>' + <EOL> '<STR_LIT>' ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , viewpoint_id ) ) <EOL> raise gen . Return ( { } ) <EOL> @ gen . coroutine <EOL> def UploadContacts ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> request [ '<STR_LIT>' ] = user_id <EOL> contact_count = len ( request [ '<STR_LIT>' ] ) <EOL> result_contact_ids = [ ] <EOL> for contact in request [ '<STR_LIT>' ] : <EOL> canon_identities = set ( ) <EOL> identities_properties = [ ] <EOL> for contact_identity in contact [ '<STR_LIT>' ] : <EOL> identity_key = contact_identity [ '<STR_LIT>' ] <EOL> description = contact_identity . get ( '<STR_LIT:description>' , None ) <EOL> if identity_key != Identity . Canonicalize ( identity_key ) : <EOL> raise InvalidRequestError ( IDENTITY_NOT_CANONICAL , identity_key = identity_key ) <EOL> canon_identities . add ( identity_key ) <EOL> identities_properties . append ( ( identity_key , description ) ) <EOL> contact [ '<STR_LIT>' ] = list ( canon_identities ) <EOL> contact [ '<STR_LIT>' ] = identities_properties <EOL> contact [ '<STR_LIT>' ] = Contact . CalculateContactId ( contact ) <EOL> result_contact_ids . append ( contact [ '<STR_LIT>' ] ) <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % ( user_id , device_id , contact_count ) ) <EOL> raise gen . Return ( { '<STR_LIT>' : result_contact_ids } ) <EOL> @ gen . coroutine <EOL> def UploadEpisode ( client , obj_store , user_id , device_id , request ) : <EOL> """<STR_LIT>""" <EOL> def _GenerateUploadUrl ( obj_store , ph_dict , suffix , md5_attr ) : <EOL> """<STR_LIT>""" <EOL> md5_hex = ph_dict [ md5_attr ] <EOL> try : <EOL> content_md5 = base64 . b64encode ( md5_hex . decode ( '<STR_LIT>' ) ) <EOL> except TypeError : <EOL> raise InvalidRequestError ( '<STR_LIT>' % md5_hex ) <EOL> return obj_store . GenerateUploadUrl ( '<STR_LIT>' % ( ph_dict [ '<STR_LIT>' ] , suffix ) , <EOL> content_type = ph_dict . get ( '<STR_LIT>' , '<STR_LIT>' ) , <EOL> content_md5 = content_md5 ) <EOL> @ gen . coroutine <EOL> def _VerifyAttributeUpdate ( photo , suffix , attr_name , new_value ) : <EOL> """<STR_LIT>""" <EOL> existing_value = getattr ( photo , attr_name ) <EOL> if new_value != existing_value : <EOL> etag = yield gen . Task ( Photo . IsImageUploaded , obj_store , photo . photo_id , suffix ) <EOL> if etag is not None : <EOL> raise PermissionError ( '<STR_LIT>' % <EOL> ( photo . photo_id + suffix ) ) <EOL> @ gen . coroutine <EOL> def _VerifyPhoto ( ph_dict ) : <EOL> """<STR_LIT>""" <EOL> yield Photo . VerifyPhotoId ( client , user_id , device_id , ph_dict [ '<STR_LIT>' ] ) <EOL> photo = yield gen . Task ( Photo . Query , client , ph_dict [ '<STR_LIT>' ] , None , must_exist = False ) <EOL> if photo is not None : <EOL> assert photo . user_id == user_id , ( photo , user_id ) <EOL> yield [ gen . Task ( _VerifyAttributeUpdate , photo , '<STR_LIT>' , '<STR_LIT>' , ph_dict [ '<STR_LIT>' ] ) , <EOL> gen . Task ( _VerifyAttributeUpdate , photo , '<STR_LIT>' , '<STR_LIT>' , ph_dict [ '<STR_LIT>' ] ) , <EOL> gen . Task ( _VerifyAttributeUpdate , photo , '<STR_LIT>' , '<STR_LIT>' , ph_dict [ '<STR_LIT>' ] ) , <EOL> gen . Task ( _VerifyAttributeUpdate , photo , '<STR_LIT>' , '<STR_LIT>' , ph_dict [ '<STR_LIT>' ] ) ] <EOL> yield Activity . VerifyActivityId ( client , user_id , device_id , request [ '<STR_LIT>' ] [ '<STR_LIT>' ] ) <EOL> request [ '<STR_LIT>' ] = user_id <EOL> episode_id = request [ '<STR_LIT>' ] [ '<STR_LIT>' ] <EOL> yield Episode . VerifyEpisodeId ( client , user_id , device_id , episode_id ) <EOL> yield [ gen . Task ( _VerifyPhoto , ph_dict ) for ph_dict in request [ '<STR_LIT>' ] ] <EOL> yield gen . Task ( Operation . CreateAndExecute , <EOL> client , <EOL> user_id , <EOL> device_id , <EOL> '<STR_LIT>' , <EOL> request ) <EOL> logging . info ( '<STR_LIT>' % <EOL> ( user_id , device_id , episode_id , len ( request [ '<STR_LIT>' ] ) ) ) <EOL> response = { '<STR_LIT>' : episode_id , <EOL> '<STR_LIT>' : [ { '<STR_LIT>' : ph_dict [ '<STR_LIT>' ] , <EOL> '<STR_LIT>' : _GenerateUploadUrl ( obj_store , ph_dict , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> '<STR_LIT>' : _GenerateUploadUrl ( obj_store , ph_dict , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> '<STR_LIT>' : _GenerateUploadUrl ( obj_store , ph_dict , '<STR_LIT>' , '<STR_LIT>' ) , <EOL> '<STR_LIT>' : _GenerateUploadUrl ( obj_store , ph_dict , '<STR_LIT>' , '<STR_LIT>' ) } <EOL> for ph_dict in request [ '<STR_LIT>' ] ] } <EOL> raise gen . Return ( response ) <EOL> def _ValidateContacts ( contact_dicts ) : <EOL> """<STR_LIT>""" <EOL> for contact in contact_dicts : <EOL> if '<STR_LIT>' in contact : <EOL> Identity . ValidateKey ( contact [ '<STR_LIT>' ] ) <EOL> def _CanViewViewpointContent ( viewpoint , follower ) : <EOL> """<STR_LIT>""" <EOL> if viewpoint is None or follower is None or not follower . CanViewContent ( ) : <EOL> return False <EOL> if viewpoint . IsSystem ( ) or base . ViewfinderContext . current ( ) . CanViewViewpoint ( viewpoint . viewpoint_id ) : <EOL> return True <EOL> return False <EOL> def _AddPhotoUrls ( obj_store , ph_dict ) : <EOL> """<STR_LIT>""" <EOL> ph_dict [ '<STR_LIT>' ] = photo_store . GeneratePhotoUrl ( obj_store , ph_dict [ '<STR_LIT>' ] , '<STR_LIT>' ) <EOL> ph_dict [ '<STR_LIT>' ] = photo_store . GeneratePhotoUrl ( obj_store , ph_dict [ '<STR_LIT>' ] , '<STR_LIT>' ) <EOL> ph_dict [ '<STR_LIT>' ] = photo_store . GeneratePhotoUrl ( obj_store , ph_dict [ '<STR_LIT>' ] , '<STR_LIT>' ) <EOL> ph_dict [ '<STR_LIT>' ] = photo_store . GeneratePhotoUrl ( obj_store , ph_dict [ '<STR_LIT>' ] , '<STR_LIT>' ) <EOL> def _MakeViewpointMetadataDict ( viewpoint , follower , obj_store ) : <EOL> """<STR_LIT>""" <EOL> metadata_dict = viewpoint . MakeMetadataDict ( follower ) <EOL> if '<STR_LIT>' in metadata_dict : <EOL> _AddPhotoUrls ( obj_store , metadata_dict [ '<STR_LIT>' ] ) <EOL> return metadata_dict <EOL> class ServiceHandler ( base . BaseHandler ) : <EOL> """<STR_LIT>""" <EOL> class Method ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , request , response , handler , allow_prospective = False , <EOL> min_supported_version = MIN_SUPPORTED_MESSAGE_VERSION , <EOL> max_supported_version = MAX_SUPPORTED_MESSAGE_VERSION , <EOL> request_migrators = [ ] , response_migrators = [ ] ) : <EOL> self . request = request <EOL> self . response = response <EOL> self . handler = handler <EOL> self . allow_prospective = allow_prospective <EOL> self . min_supported_version = max ( min_supported_version , MIN_SUPPORTED_MESSAGE_VERSION ) <EOL> self . max_supported_version = min ( max_supported_version , MAX_SUPPORTED_MESSAGE_VERSION ) <EOL> self . request_migrators = sorted ( REQUIRED_MIGRATORS + request_migrators ) <EOL> self . response_migrators = sorted ( REQUIRED_MIGRATORS + response_migrators ) <EOL> SERVICE_MAP = { <EOL> '<STR_LIT>' : Method ( request = json_schema . ADD_FOLLOWERS_REQUEST , <EOL> response = json_schema . ADD_FOLLOWERS_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = AddFollowers ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . ALLOCATE_IDS_REQUEST , <EOL> response = json_schema . ALLOCATE_IDS_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = AllocateIds ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . BUILD_ARCHIVE_REQUEST , <EOL> response = json_schema . BUILD_ARCHIVE_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = BuildArchive ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . GET_CALENDAR_REQUEST , <EOL> response = json_schema . GET_CALENDAR_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = GetCalendar ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . HIDE_PHOTOS_REQUEST , <EOL> response = json_schema . HIDE_PHOTOS_RESPONSE , <EOL> min_supported_version = Message . RENAME_PHOTO_LABEL , <EOL> handler = HidePhotos ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . LIST_IDENTITIES_REQUEST , <EOL> response = json_schema . LIST_IDENTITIES_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = ListIdentities ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . MERGE_ACCOUNTS_REQUEST , <EOL> response = json_schema . MERGE_ACCOUNTS_RESPONSE , <EOL> handler = MergeAccounts ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . NEW_CLIENT_LOG_URL_REQUEST , <EOL> response = json_schema . NEW_CLIENT_LOG_URL_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = NewClientLogUrl ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . POST_COMMENT_REQUEST , <EOL> response = json_schema . POST_COMMENT_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = PostComment ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . QUERY_CONTACTS_REQUEST , <EOL> response = json_schema . QUERY_CONTACTS_RESPONSE , <EOL> response_migrators = [ SUPPORT_MULTIPLE_IDENTITIES_PER_CONTACT ] , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = QueryContacts ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . QUERY_EPISODES_REQUEST , <EOL> response = json_schema . QUERY_EPISODES_RESPONSE , <EOL> response_migrators = [ EXTRACT_ASSET_KEYS , RENAME_PHOTO_LABEL ] , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = QueryEpisodes , <EOL> allow_prospective = True ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . QUERY_FOLLOWED_REQUEST , <EOL> response = json_schema . QUERY_FOLLOWED_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = QueryFollowed , <EOL> allow_prospective = True ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . QUERY_NOTIFICATIONS_REQUEST , <EOL> response = json_schema . QUERY_NOTIFICATIONS_RESPONSE , <EOL> response_migrators = [ INLINE_INVALIDATIONS , INLINE_COMMENTS ] , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = QueryNotifications ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . QUERY_USERS_REQUEST , <EOL> response = json_schema . QUERY_USERS_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = QueryUsers , <EOL> allow_prospective = True ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . QUERY_VIEWPOINTS_REQUEST , <EOL> response = json_schema . QUERY_VIEWPOINTS_RESPONSE , <EOL> response_migrators = [ SUPPORT_REMOVED_FOLLOWERS ] , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = QueryViewpoints , <EOL> allow_prospective = True ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . RECORD_SUBSCRIPTION_REQUEST , <EOL> response = json_schema . RECORD_SUBSCRIPTION_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = RecordSubscription ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . REMOVE_CONTACTS_REQUEST , <EOL> response = json_schema . REMOVE_CONTACTS_RESPONSE , <EOL> min_supported_version = Message . SUPPORT_MULTIPLE_IDENTITIES_PER_CONTACT , <EOL> handler = RemoveContacts ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . REMOVE_FOLLOWERS_REQUEST , <EOL> response = json_schema . REMOVE_FOLLOWERS_RESPONSE , <EOL> handler = RemoveFollowers ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . REMOVE_PHOTOS_REQUEST , <EOL> response = json_schema . REMOVE_PHOTOS_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = RemovePhotos ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . REMOVE_VIEWPOINT_REQUEST , <EOL> response = json_schema . REMOVE_VIEWPOINT_RESPONSE , <EOL> min_supported_version = Message . INLINE_COMMENTS , <EOL> handler = RemoveViewpoint ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . RESOLVE_CONTACTS_REQUEST , <EOL> response = json_schema . RESOLVE_CONTACTS_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = ResolveContacts ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . SAVE_PHOTOS_REQUEST , <EOL> response = json_schema . SAVE_PHOTOS_RESPONSE , <EOL> request_migrators = [ SUPPRESS_COPY_TIMESTAMP ] , <EOL> handler = SavePhotos ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . SHARE_EXISTING_REQUEST , <EOL> response = json_schema . SHARE_EXISTING_RESPONSE , <EOL> request_migrators = [ EXPLICIT_SHARE_ORDER , SUPPRESS_COPY_TIMESTAMP ] , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = ShareExisting ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . SHARE_NEW_REQUEST , <EOL> response = json_schema . SHARE_NEW_RESPONSE , <EOL> request_migrators = [ EXPLICIT_SHARE_ORDER , SUPPRESS_BLANK_COVER_PHOTO , SUPPRESS_COPY_TIMESTAMP ] , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = ShareNew ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . TERMINATE_ACCOUNT_REQUEST , <EOL> response = json_schema . TERMINATE_ACCOUNT_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = TerminateAccount ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . UNLINK_IDENTITY_REQUEST , <EOL> response = json_schema . UNLINK_IDENTITY_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = UnlinkIdentity ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . UNSHARE_REQUEST , <EOL> response = json_schema . UNSHARE_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = Unshare ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . UPDATE_DEVICE_REQUEST , <EOL> response = json_schema . UPDATE_DEVICE_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = UpdateDevice ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . UPDATE_EPISODE_REQUEST , <EOL> response = json_schema . UPDATE_EPISODE_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = UpdateEpisode ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . UPDATE_FOLLOWER_REQUEST , <EOL> response = json_schema . UPDATE_FOLLOWER_RESPONSE , <EOL> handler = UpdateFollower ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . UPDATE_FRIEND_REQUEST , <EOL> response = json_schema . UPDATE_FRIEND_RESPONSE , <EOL> handler = UpdateFriend ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . UPDATE_PHOTO_REQUEST , <EOL> response = json_schema . UPDATE_PHOTO_RESPONSE , <EOL> request_migrators = [ EXTRACT_ASSET_KEYS ] , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = UpdatePhoto ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . UPDATE_USER_REQUEST , <EOL> response = json_schema . UPDATE_USER_RESPONSE , <EOL> request_migrators = [ SPLIT_NAMES ] , <EOL> handler = UpdateUser ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . UPDATE_USER_PHOTO_REQUEST , <EOL> response = json_schema . UPDATE_USER_PHOTO_RESPONSE , <EOL> min_supported_version = Message . EXTRACT_ASSET_KEYS , <EOL> handler = UpdateUserPhoto ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . UPDATE_VIEWPOINT_REQUEST , <EOL> response = json_schema . UPDATE_VIEWPOINT_RESPONSE , <EOL> request_migrators = [ SUPPRESS_EMPTY_TITLE ] , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = UpdateViewpoint ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . UPLOAD_CONTACTS_REQUEST , <EOL> response = json_schema . UPLOAD_CONTACTS_RESPONSE , <EOL> request_migrators = [ SUPPORT_CONTACT_LIMITS ] , <EOL> min_supported_version = Message . SUPPORT_MULTIPLE_IDENTITIES_PER_CONTACT , <EOL> handler = UploadContacts ) , <EOL> '<STR_LIT>' : Method ( request = json_schema . UPLOAD_EPISODE_REQUEST , <EOL> response = json_schema . UPLOAD_EPISODE_RESPONSE , <EOL> request_migrators = [ EXTRACT_FILE_SIZES , EXTRACT_ASSET_KEYS ] , <EOL> min_supported_version = Message . EXTRACT_MD5_HASHES , <EOL> handler = UploadEpisode ) , <EOL> } <EOL> def __init__ ( self , application , request , ** kwargs ) : <EOL> super ( ServiceHandler , self ) . __init__ ( application , request , ** kwargs ) <EOL> @ handler . authenticated ( allow_prospective = True ) <EOL> @ handler . asynchronous ( datastore = True , obj_store = True ) <EOL> def post ( self , method_name ) : <EOL> """<STR_LIT>""" <EOL> def _OnSuccess ( method , start_time , user , device_id , response_dict ) : <EOL> self . set_status ( <NUM_LIT:200> ) <EOL> self . set_header ( '<STR_LIT:Content-Type>' , '<STR_LIT>' ) <EOL> self . write ( json . dumps ( response_dict ) ) <EOL> request_time = time . time ( ) - start_time <EOL> _avg_req_time . add ( request_time ) <EOL> logging . debug ( '<STR_LIT>' % <EOL> ( method_name , request_time , response_dict ) ) <EOL> self . finish ( ) <EOL> self . api_name = method_name <EOL> _req_per_min . increment ( ) <EOL> start_time = time . time ( ) <EOL> if not ServiceHandler . SERVICE_MAP . has_key ( method_name ) : <EOL> _fail_per_min . increment ( ) <EOL> self . send_error ( status_code = <NUM_LIT> ) <EOL> return <EOL> json_request = self . _LoadJSONRequest ( ) <EOL> if json_request is None : <EOL> _fail_per_min . increment ( ) <EOL> return <EOL> user = base . ViewfinderContext . current ( ) . user <EOL> device_id = base . ViewfinderContext . current ( ) . device_id <EOL> method = ServiceHandler . SERVICE_MAP [ method_name ] <EOL> ServiceHandler . InvokeService ( self . _client , self . _obj_store , method_name , user . user_id , device_id , <EOL> json_request , callback = partial ( _OnSuccess , method , start_time , user , device_id ) ) <EOL> def _handle_request_exception ( self , e ) : <EOL> """<STR_LIT>""" <EOL> _fail_per_min . increment ( ) <EOL> super ( ServiceHandler , self ) . _handle_request_exception ( e ) <EOL> @ staticmethod <EOL> @ gen . coroutine <EOL> def InvokeService ( client , obj_store , method_name , user_id , device_id , json_request ) : <EOL> """<STR_LIT>""" <EOL> method = ServiceHandler . SERVICE_MAP [ method_name ] <EOL> if not base . ViewfinderContext . current ( ) . user . IsRegistered ( ) and not method . allow_prospective : <EOL> raise web . HTTPError ( <NUM_LIT> , '<STR_LIT>' ) <EOL> try : <EOL> request_message = yield gen . Task ( base . BaseHandler . _CreateRequestMessage , <EOL> client , <EOL> json_request , <EOL> method . request , <EOL> migrators = method . request_migrators , <EOL> min_supported_version = method . min_supported_version , <EOL> max_supported_version = method . max_supported_version ) <EOL> except Exception as ex : <EOL> logging . warning ( util . FormatLogArgument ( json_request ) ) <EOL> raise InvalidRequestError ( INVALID_JSON_REQUEST , request = ex . message ) <EOL> if method_name == '<STR_LIT>' and request_message . original_version < Message . RENAME_PHOTO_LABEL : <EOL> handler = OldRemovePhotos <EOL> else : <EOL> handler = method . handler <EOL> response_dict = yield gen . Task ( handler , client , obj_store , user_id , device_id , request_message . dict ) <EOL> response_message = yield gen . Task ( base . BaseHandler . _CreateResponseMessage , <EOL> client , <EOL> response_dict , <EOL> method . response , <EOL> request_message . original_version , <EOL> migrators = method . response_migrators ) <EOL> raise gen . Return ( response_message . dict ) </s>
