def test_form(service_user, form_id, testers): # type: (users.User, int, list[users.User]) -> None form = get_form(form_id, service_user) request = TestFormRequestTO(id=form_id, version=form.version) to_put = [] prof = get_service_profile(service_user) branding = prof.broadcastBranding caption = localize(prof.defaultLanguage, 'forms.test_form') answers = [AnswerTO(id_=u'test', caption=caption, action=u'form://%d?version=%d&test=true' % (form_id, form.version))] flags = Message.FLAG_AUTO_LOCK alert_flags = Message.ALERT_FLAG_VIBRATE tag = None message = localize(prof.defaultLanguage, 'forms.click_button_to_test') for user_profile in get_profile_infos(testers): mobiles = db.get([get_mobile_key_by_account(mobile_detail.account) for mobile_detail in user_profile.mobiles]) has_other = False android_mobile = None for mobile in mobiles: if mobile.is_android: android_mobile = mobile else: has_other = True if has_other: messaging.send(None, None, message, answers, flags, [MemberTO.from_user(user_profile.user)], branding, tag, alert_flags=alert_flags) else: title = localize(prof.defaultLanguage, 'forms.test_form_x', title=form.title) body = localize(prof.defaultLanguage, 'forms.click_to_test_your_form') kwargs = {CAPI_KEYWORD_PUSH_DATA: TestFormNotification(title, body, form.id, form.version)} to_put.extend(testForm(test_form_response_handler, logError, user_profile.user, request=request, MOBILE_ACCOUNT=android_mobile, DO_NOT_SAVE_RPCCALL_OBJECTS=True, **kwargs)) db.put(to_put)
def start_service_location_tracking(service_identity_user, app_user, until, distance_filter): from rogerthat.bizz.friends import areFriends service_profile_info, human_profile_info = get_profile_infos([service_identity_user, app_user]) if not areFriends(service_profile_info, human_profile_info): raise CanOnlyTrackServiceSubscriptionsException() def trans(): slt = get_current_tracker(app_user, service_identity_user) if slt: return slt.encrypted_key() key = ServiceLocationTracker.create_key(app_user, str(uuid.uuid4())) slt = ServiceLocationTracker(key=key, creation_time=now(), until=until, enabled=True, service_identity_user=service_identity_user) slt.put() request = TrackLocationRequestTO() request.high_prio = True request.friend = remove_slash_default(service_identity_user).email() request.target = GetLocationRequestTO.TARGET_SERVICE_LOCATION_TRACKER request.until = until request.distance_filter = distance_filter for capi_call in trackLocation(track_location_response_handler, track_location_response_error_handler, app_user, request=request, DO_NOT_SAVE_RPCCALL_OBJECTS=True): capi_call.tracker = key capi_call.put() return slt.encrypted_key() xg_on = db.create_transaction_options(xg=True) return db.run_in_transaction_options(xg_on, trans)
def _send_notification_about_failed_location_fix(user, friend, friend_mobile_key_name, target, error_status): ''' @param user: The user who sent the location request. @param friend: The user who failed to execute the location request. @param friend_mobile_key_name: The key name of the friend's Mobile model. @param target: The reason of the location request. One of GetLocationRequestTO.TARGET_*. @param error_status: The reason of the failed location request. One of GetLocationErrorTO.STATUS_*. ''' friend_profile, user_profile = get_profile_infos([friend, user], expected_types=[UserProfile, UserProfile]) app_name = get_app_name_by_id(user_profile.app_id) friend_msg = None user_reason_msg = None if error_status in (GetLocationErrorTO.STATUS_AUTHORIZATION_DENIED, GetLocationErrorTO.STATUS_AUTHORIZATION_ONLY_WHEN_IN_USE): if error_status == GetLocationErrorTO.STATUS_AUTHORIZATION_DENIED: friend_msg = localize(friend_profile.language, "_location_services_denied", name=user_profile.name, app_name=app_name) user_reason_msg = localize(user_profile.language, "_friend_denied_location_services", name=friend_profile.name, app_name=app_name) elif error_status == GetLocationErrorTO.STATUS_AUTHORIZATION_ONLY_WHEN_IN_USE: friend_msg = localize(friend_profile.language, "_location_services_denied", name=user_profile.name, app_name=app_name) user_reason_msg = localize(user_profile.language, "_friend_denied_location_services", name=friend_profile.name, app_name=app_name) if friend_msg: friend_mobile = Mobile.get_by_key_name(friend_mobile_key_name) if friend_mobile.is_ios and friend_mobile.osVersion: if friend_mobile.osVersion.startswith('7'): friend_msg += "\n\n" + localize(friend_profile.language, "_enable_location_services_ios7", app_name=app_name) elif friend_mobile.osVersion.startswith('8'): friend_msg += "\n\n" + localize(friend_profile.language, "_enable_location_services_ios8", app_name=app_name) if target == GetLocationRequestTO.TARGET_MOBILE: user_msg = localize(user_profile.language, "We could not determine the location of %(name)s.", name=friend_profile.name) elif target == GetLocationRequestTO.TARGET_MOBILE_FIRST_REQUEST_AFTER_GRANT: user_msg = localize(user_profile.language, "%(name)s accepted your location sharing request. Unfortunately we could not determine his/her location at this moment.", name=friend_profile.name) else: logging.error("Don't know what to do in _send_notification_about_failed_location_fix.\n\nLocals:\n%s" % locals()) return if user_reason_msg: user_msg = u"%s (%s)" % (user_msg, user_reason_msg) if user_msg and not friend_msg: user_msg = u"%s\n\n%s" % (user_msg, localize(user_profile.language, "Please try again later.")) xg_on = db.create_transaction_options(xg=True) db.run_in_transaction_options(xg_on, dashboardNotification, user, user_msg) if friend_msg: db.run_in_transaction_options(xg_on, dashboardNotification, friend, friend_msg)
def restoreUserDataAfterReactivate(app_user): models_to_restore = list() archives_to_delete = list() for avatar_archive in AvatarArchive.all().filter("user ="******"user ="******"len(models_to_restore) %s %r", len(models_to_restore), models_to_restore) logging.info("len(archives_to_delete) %s %r", len(archives_to_delete), archives_to_delete) db.put(models_to_restore) db.delete(archives_to_delete) if not AuthorizedUser.all().filter(u"user =", app_user).get(): au = AuthorizedUser() au.user = app_user au.put() if friend_map_archive: from rogerthat.bizz.friends import makeFriends # Skip friends that unsubscribed in the meantime cleanup_friend_map = False friend_profile_infos = get_profile_infos(friend_map.friends, allow_none_in_results=True) for friend_user, friendProfileInfo in zip(friend_map.friends, friend_profile_infos): if friendProfileInfo: continue logging.debug('User %s must have been deactivated in the mean while. Not executing makeFriends.', friend_user.email()) friend_map.friends.remove(friend_user) friend_map.friendDetails.remove(friend_user.email()) cleanup_friend_map = True if cleanup_friend_map: friend_map.put() # MakeFriends of remaining users in friendMap for f in friend_map.friendDetails: connected_user = users.User(f.email) makeFriends(friend_map.user, connected_user, connected_user, servicetag=None, origin=None, notify_invitee=False, notify_invitor=False, user_data=None)
def _create_unread_messages(stats, language, server_settings, user_profile): sender_users = list({s[0] for s in stats[1] if s[0] != MC_DASHBOARD}) sender_profile_infos = dict(zip(sender_users, get_profile_infos(sender_users, allow_none_in_results=True))) timezone_diff = 0 if user_profile.mobiles: for mobile_detail in user_profile.mobiles: mobile = Mobile.get(Mobile.create_key(mobile_detail.account)) timezone_diff = mobile.timezoneDeltaGMT or 0 break avatars = dict() # { avatar_id : (avatar_data) } def get_avatar_url(avatar_id): avatar = avatars.get(avatar_id) if not avatar: if avatar_id in ('nuntiuz', 'unknown'): if avatar == 'nuntiuz': avatar = UNKNOWN_AVATAR else: avatar = NUNTIUZ_AVATAR else: avatar = get_avatar_cached(avatar_id, size=40) avatars[avatar_id] = avatar return 'cid:%s' % avatar_id unread_messages = list() # sorted by message.creationTimestamp for sender_user, message, broadcast_type, creation_time in sorted(stats[1], key=lambda x: x[3]): sender_profile_info = sender_profile_infos.get(sender_user) if sender_profile_info: name = sender_profile_info.name avatar_url = get_avatar_url(sender_profile_info.avatarId) elif sender_user == MC_DASHBOARD: name = get_profile_info_name(sender_user, user_profile.app_id) avatar_url = get_avatar_url('nuntiuz') else: name = sender_user.email().split(':', 1)[0].split('/', 1)[0] avatar_url = get_avatar_url('unknown') creation_date_time = datetime.datetime.utcfromtimestamp(creation_time + timezone_diff) creation_time_str = '%s, %s' % (format_date(creation_date_time, locale=language, format='short'), format_time(creation_date_time, locale=language, format='short')) if broadcast_type: sender_user = add_slash_default(sender_user) if len(name) > 43: name = name[:40] + u'...' unread_messages.append(UnreadMessage(name, avatar_url, message, broadcast_type, creation_time_str, localize(language, 'email_reminder_unsubscribe_caption', notification_type=xml_escape(broadcast_type) if broadcast_type else None, service=xml_escape(name)), generate_unsubscribe_broadcast_link(user_profile.user, sender_user, name, broadcast_type))) return unread_messages, avatars
def testProfileCache(self): john = users.User(u"*****@*****.**") create_user_profile(john, u"John Doe") jane = users.User(u"*****@*****.**") create_user_profile(jane, u"John Doe") service = users.User(u"*****@*****.**") create_service_profile(service, u"Tha service") flush_request_cache() john_cache_key = _get_db_profile.cache_key(john) # @UndefinedVariable jane_cache_key = _get_db_profile.cache_key(jane) # @UndefinedVariable service_cache_key = _get_db_profile.cache_key(service) # @UndefinedVariable assert MISSING == get_from_request_cache(john_cache_key) assert MISSING == get_from_request_cache(jane_cache_key) # @UndefinedVariable assert MISSING == get_from_request_cache(service_cache_key) # @UndefinedVariable get_user_profile(john) assert MISSING != get_from_request_cache(john_cache_key) rpc.wait_for_rpcs() memcache_result = memcache.get(john_cache_key) # @UndefinedVariable buf = StringIO(memcache_result) success, result = _get_db_profile.deserializer(buf) # @UndefinedVariable assert success assert result.user == john get_profile_infos([john, jane, service], False, False, expected_types=[ UserProfile, UserProfile, ServiceIdentity]) assert MISSING != get_from_request_cache(john_cache_key) assert MISSING == get_from_request_cache(jane_cache_key) # @UndefinedVariable assert MISSING == get_from_request_cache(service_cache_key) # @UndefinedVariable get_profile_infos([john, jane, service], False, True, expected_types=[ UserProfile, UserProfile, ServiceIdentity]) rpc.wait_for_rpcs()
def fromServiceProfile(service_profile, broadcasts): to = ServiceBroadCastConfigurationTO() to.broadcast_types = service_profile.broadcastTypes user_profiles = get_profile_infos(service_profile.broadcastTestPersons, expected_types=len(service_profile.broadcastTestPersons) * [UserProfile], allow_none_in_results=True) to.test_persons = [UserDetailsTO.fromUserProfile(user_profile) for user_profile in filter(None, user_profiles)] to.broadcasts = map(BroadcastTO.fromBroadcast, broadcasts) to.warnings = list() if not get_broadcast_settings_items(service_profile.user, 1): to.warnings.append(u"There is no 'Broadcast settings' service menu item.") return to
def load_city_wide_lottery_detail_customer_points(city_app_id, email, app_id): app_user = create_app_user_by_email(email, app_id) visits = get_solution_city_wide_lottery_loyalty_visits_for_user(city_app_id, app_user) r = LoyaltyCustomerPointsTO() # XXX: don't use get_profile_infos profile_infos = get_profile_infos([app_user], allow_none_in_results=True) for app_user, profile_info in zip([app_user], profile_infos): if not profile_info or profile_info.isServiceIdentity: continue r.user_details = ExtendedUserDetailsTO.fromUserProfile(profile_info, None) app_info = get_app_info_cached(r.user_details.app_id) r.user_details.app_name = app_info.name r.visits = [SolutionLoyaltyVisitTO.fromModel(visit) for visit in visits] return r
def update_location(app_user, service_identity_user, slt_key): from rogerthat.bizz.friends import areFriends slt = db.get(slt_key) if not slt or not slt.enabled or slt.until < now(): return service_profile_info, human_profile_info = get_profile_infos([service_identity_user, app_user]) if not areFriends(service_profile_info, human_profile_info): return request = GetLocationRequestTO() request.high_prio = True request.friend = service_identity_user.email() request.target = GetLocationRequestTO.TARGET_SERVICE_LOCATION_TRACKER for capi_call in getLocation(get_location_response_handler, dismissError, app_user, request=request, DO_NOT_SAVE_RPCCALL_OBJECTS=True): capi_call.tracker = slt_key capi_call.put()
def load_city_wide_lottery_customer_points(city_app_id, cursor=None): result_dict = dict() qry = SolutionCityWideLotteryVisit.load(city_app_id) qry.with_cursor(cursor) visits = qry.fetch(10) cursor_ = qry.cursor() has_more = False if len(visits) != 0: qry.with_cursor(cursor_) if len(qry.fetch(1)) > 0: has_more = True for visit in visits: saved_points = result_dict.get(visit.app_user) if not saved_points: result_dict[visit.app_user] = saved_points = LoyaltyCustomerPointsTO() saved_points.visits = [] saved_points.visits.append(SolutionLoyaltyVisitTO.fromModel(visit)) # XXX: don't use get_profile_infos app_users = result_dict.keys() profile_infos = get_profile_infos(app_users, allow_none_in_results=True) for app_user, profile_info in zip(app_users, profile_infos): if not profile_info or profile_info.isServiceIdentity: logging.info('User %s not found', app_user.email()) del result_dict[app_user] continue saved_points = result_dict[app_user] saved_points.user_details = ExtendedUserDetailsTO.fromUserProfile(profile_info, None) app_info = get_app_info_cached(saved_points.user_details.app_id) saved_points.user_details.app_name = app_info.name saved_points.visits = sorted(saved_points.visits, key=lambda x: -x.timestamp) r = BaseLoyaltyCustomersTO() r.loyalty_type = SolutionLoyaltySettings.LOYALTY_TYPE_LOTTERY r.cursor = cursor_.decode("utf8") r.has_more = has_more r.customers = sorted(result_dict.itervalues(), key=lambda x: -x.visits[0].timestamp) return r
def _send_message_to_inform_user_about_a_new_join_step_2(fb_friend_user, new_user): new_user_profile, fb_friend_profile = get_profile_infos([new_user, fb_friend_user], expected_types=[UserProfile, UserProfile]) azzert(new_user_profile.app_id == fb_friend_profile.app_id) app_name = get_app_name_by_id(new_user_profile.app_id) to_language = fb_friend_profile.language if fb_friend_profile else DEFAULT_LANGUAGE message_text = localize(to_language, "%(name)s just joined %(app_name)s, and we found you in his facebook friends list!", name=new_user_profile.name, app_name=app_name) button = ButtonTO() button.id = INVITE_ID button.caption = localize(to_language, "Invite %(name)s to connect on %(app_name)s", name=new_user_profile.name, app_name=app_name) button.action = None button.ui_flags = 0 def trans(): message = sendMessage(MC_DASHBOARD, [UserMemberTO(fb_friend_user)], Message.FLAG_ALLOW_DISMISS, 0, None, message_text, [button], None, get_app_by_user(fb_friend_user).core_branding_hash, INVITE_FACEBOOK_FRIEND, is_mfr=False) message.invitor = fb_friend_user message.invitee = new_user message.put() xg_on = db.create_transaction_options(xg=True) db.run_in_transaction_options(xg_on, trans)
def add_loyalty_scan(key, loyalty_type, value): service_user = users.get_current_user() try: sls = SolutionLoyaltyScan.get(key) if sls is None: raise BusinessException("Could not find scan") if sls.processed: raise BusinessException("Scan was already processed") if sls.app_user_info: user_details = UserDetailsTO() user_details.email = sls.app_user_info.email user_details.name = sls.app_user_info.name user_details.language = sls.app_user_info.language user_details.avatar_url = sls.app_user_info.avatar_url user_details.app_id = sls.app_user_info.app_id else: # XXX: don't use get_profile_infos profile_info = get_profile_infos([sls.app_user], allow_none_in_results=True)[0] if not profile_info or profile_info.isServiceIdentity: user_details = None else: user_details = UserDetailsTO.fromUserProfile(profile_info) jsondata = {} jsondata['loyalty_type'] = loyalty_type if loyalty_type == SolutionLoyaltySettings.LOYALTY_TYPE_REVENUE_DISCOUNT: jsondata['price'] = value else: jsondata['count'] = value success, _, _ = add_loyalty_for_user( service_user, sls.service_identity, sls.admin_user, sls.app_user, jsondata, now(), user_details) if not success: raise BusinessException("error-occured-unknown") sls.processed = True sls.put() return RETURNSTATUS_TO_SUCCESS except BusinessException, e: sln_settings = get_solution_settings(service_user) return ReturnStatusTO.create(False, common_translate(sln_settings.main_language, SOLUTION_COMMON, e.message))
def list_friends(service_identity=None, cursor=None, app_id=None, batch_count=100): from rogerthat.bizz.service import get_and_validate_service_identity_user, valididate_app_id_for_service_identity_user from rogerthat.dal.service import get_users_connected_to_service_identity bizz_check(batch_count <= 1000, "Cannot batch more than 1000 friends at once.") service_identity_user = get_and_validate_service_identity_user(users.get_current_user(), service_identity) if app_id: valididate_app_id_for_service_identity_user(service_identity_user, app_id) if cursor: try: cursor = decrypt(service_identity_user, cursor) except: from rogerthat.bizz.exceptions import InvalidCursorException raise InvalidCursorException() fsics, cursor = get_users_connected_to_service_identity(service_identity_user, cursor, batch_count, app_id) # prevent extra roundtrip by trying to detect whether there are more results to fetch if len(fsics) < batch_count and cursor: extra_fsics, _ = get_users_connected_to_service_identity(service_identity_user, cursor, 1, app_id) if len(extra_fsics) == 0: cursor = None result = FriendListResultTO() result.cursor = unicode(encrypt(service_identity_user, cursor)) if cursor else None result.friends = list() user_profiles = get_profile_infos([fsic.friend for fsic in fsics], expected_types=[UserProfile] * len(fsics)) app_names = {} for user_profile, fsic in zip(user_profiles, fsics): svc_friend = ServiceFriendTO() human_user, svc_friend.app_id = get_app_user_tuple(fsic.friend) svc_friend.avatar = u"%s/unauthenticated/mobi/cached/avatar/%s" % (get_server_settings().baseUrl, fsic.friend_avatarId) svc_friend.email = human_user.email() svc_friend.language = user_profile.language svc_friend.name = fsic.friend_name if svc_friend.app_id not in app_names: app = get_app_by_id(svc_friend.app_id) app_names[svc_friend.app_id] = app.name svc_friend.app_name = app_names[svc_friend.app_id] result.friends.append(svc_friend) return result
def run(): targets = _validate_capi_call(result_f, error_f, target, alias, f, accept_sub_types=accept_sub_types) if not targets: return cc = dict() cc[API_VERSION] = 1 cc[FUNCTION] = alias cc[PARAMETERS] = dict(map(lambda (arg, type_): (arg, serialize_value(kwargs[arg], *get_type_details(type_))), f.meta["kwarg_types"].iteritems())) skippers = kwargs.get(SKIP_ACCOUNTS) or list() mobile = kwargs.get(MOBILE_ACCOUNT) if mobile: from rogerthat.models.properties.profiles import MobileDetail mobile_detail = MobileDetail() mobile_detail.account = mobile.account mobile_detail.type_ = mobile.type mobile_detail.pushId = mobile.pushId mobile_detail.app_id = mobile.app_id logging.info(u"Sending capi: %s call to %s" % (alias, mobile.user.email())) logging.info(u"Sending to account %s" % mobile_detail.account) yield _send_client_call(mobile_detail, cc, mobile.user, alias) else: from rogerthat.dal.profile import get_profile_infos profile_infos = get_profile_infos(targets, allow_none_in_results=True) for profile_info in profile_infos: if not profile_info: continue if profile_info.isServiceIdentity: logging.warn("Not sending capi call to ServiceIdentity (%s)" % profile_info.user.email()) else: if profile_info.mobiles is None: logging.info(u"%s does not have mobiles registered" % profile_info.user.email()) continue for mobile_detail in profile_info.mobiles: if mobile_detail.account in skippers: logging.info(u"Skipping account %s " % mobile_detail.account) continue logging.info(u"Sending capi: %s call to %s, account: %s" % (alias, profile_info.user.email(), mobile_detail.account)) yield _send_client_call(mobile_detail, cc, profile_info.user, alias)
def load_detail_customer_points(loyalty_type, email, app_id): service_user = users.get_current_user() session_ = users.get_current_session() service_identity = session_.service_identity app_user = create_app_user_by_email(email, app_id) if loyalty_type == SolutionLoyaltySettings.LOYALTY_TYPE_REVENUE_DISCOUNT: visits = get_solution_loyalty_visits_for_revenue_discount(service_user, service_identity, app_user) elif loyalty_type == SolutionLoyaltySettings.LOYALTY_TYPE_LOTTERY: visits = get_solution_loyalty_visits_for_lottery(service_user, service_identity, app_user) else: visits = get_solution_loyalty_visits_for_stamps(service_user, service_identity, app_user) r = LoyaltyCustomerPointsTO() # XXX: don't use get_profile_infos profile_infos = get_profile_infos([app_user], allow_none_in_results=True) for app_user, profile_info in zip([app_user], profile_infos): if not profile_info or profile_info.isServiceIdentity: continue r.user_details = ExtendedUserDetailsTO.fromUserProfile(profile_info, None) app_info = get_app_info_cached(r.user_details.app_id) r.user_details.app_name = app_info.name r.visits = [SolutionLoyaltyVisitTO.fromModel(visit) for visit in visits] return r
def start_local_flow(service_identity_user, thread_key, xml, members, tag=None, context=None, force_language=None, download_attachments_upfront=False, push_message=None, parent_message_key=None): from rogerthat.rpc.calls import HIGH_PRIORITY _validate_start_flow(service_identity_user, thread_key, members, tag=tag) service_user = get_service_user_from_service_identity_user(service_identity_user) js_flow_dict = generate_js_flow(service_user, xml, context, minify=False, parent_message_key=parent_message_key, must_validate=True) # js_flow_dict = { language : (<compiled JS flow>, brandings, attachments) } if force_language and force_language is not MISSING: if force_language not in js_flow_dict: raise InvalidMessageFlowLanguageException(json.dumps(js_flow_dict.keys()), force_language) forced_flow = js_flow_dict[force_language] else: forced_flow = None profile_infos = {profile_info.user: profile_info for profile_info in get_profile_infos(members + [service_identity_user])} mfr = _create_message_flow_run(service_user, service_identity_user, result_callback=False, tag=tag) message_flow_run_id = mfr.messageFlowRunId for app_user in members: if forced_flow: flow_definition, brandings, attachments = forced_flow else: target_language = profile_infos[app_user].language if target_language not in js_flow_dict: # fall back to service default language target_language = get_service_profile(service_user).defaultLanguage if target_language not in js_flow_dict: raise InvalidMessageFlowLanguageException(json.dumps(js_flow_dict.keys()), target_language) flow_definition, brandings, attachments = js_flow_dict[target_language] force_skip_attachments_download = False if push_message: for mobile_detail in profile_infos[app_user].mobiles: if mobile_detail.type_ == Mobile.TYPE_IPHONE_HTTP_APNS_KICK and mobile_detail.pushId: force_skip_attachments_download = True break request = StartFlowRequestTO() request.attachments_to_dwnl = attachments if download_attachments_upfront and not force_skip_attachments_download else list() request.brandings_to_dwnl = brandings request.service = remove_slash_default(service_identity_user).email() request.static_flow = compress_js_flow_definition(flow_definition) request.static_flow_hash = unicode(md5_hex(flow_definition)) request.parent_message_key = thread_key request.message_flow_run_id = message_flow_run_id startFlow(start_flow_response_handler, logError, app_user, request=request) if push_message: sender_name = _ellipsize_for_json(profile_infos[service_identity_user].name, 30, cut_on_spaces=False) for mobile_detail in profile_infos[app_user].mobiles: if mobile_detail.type_ == Mobile.TYPE_IPHONE_HTTP_APNS_KICK and mobile_detail.pushId: cbd = dict(r=mobile_detail.account, p=HIGH_PRIORITY, t=["apns"], kid=str(uuid.uuid4()), a=mobile_detail.app_id) cbd['d'] = mobile_detail.pushId cbd['m'] = base64.encodestring(construct_push_notification('NM', [sender_name, push_message], 'n.aiff', lambda args, too_big: [sender_name, _ellipsize_for_json(args[1], _len_for_json(args[1]) - too_big)])) logging.debug('Sending push notification along with start_local_flow.\n%s', cbd) kicks.append(json.dumps(cbd)) return message_flow_run_id
def run(): def _should_send_capi_call_to_mobile(feature_version, mobile): if not feature_version or DEBUG: return True if mobile.is_ios: version = feature_version.ios elif mobile.is_android: version = feature_version.android else: version = None if version: from rogerthat.bizz.features import Version mobile_settings = get_mobile_settings_cached(mobile) if not mobile_settings: return False if Version(mobile_settings.majorVersion, mobile_settings.minorVersion) < version: return False return True targets = _validate_capi_call(result_f, error_f, target, alias, f, accept_sub_types=accept_sub_types) if not targets: return cc = dict() cc[API_VERSION] = 1 cc[FUNCTION] = alias cc[PARAMETERS] = {arg: serialize_value(kwargs[arg], *get_type_details(type_, kwargs[arg])) for arg, type_ in f.meta["kwarg_types"].iteritems()} skippers = kwargs.get(SKIP_ACCOUNTS) or list() mobile = kwargs.get(MOBILE_ACCOUNT) if mobile: from rogerthat.models.properties.profiles import MobileDetail if not _should_send_capi_call_to_mobile(feature_version, mobile): logging.debug(u'%s is not supported by mobile %s of user %s', alias, mobile.account, mobile.user.email()) return mobile_detail = MobileDetail() mobile_detail.account = mobile.account mobile_detail.type_ = mobile.type mobile_detail.pushId = mobile.pushId mobile_detail.app_id = mobile.app_id logging.info(u"Sending capi: %s call to %s" % (alias, mobile.user.email())) logging.info(u"Sending to account %s" % mobile_detail.account) yield _send_client_call(mobile_detail, cc, mobile.user, alias) else: from rogerthat.dal.profile import get_profile_infos from rogerthat.dal.mobile import get_mobile_key_by_account profile_infos = get_profile_infos(targets, allow_none_in_results=True) for profile_info in profile_infos: if not profile_info: continue if profile_info.isServiceIdentity: logging.warn(u"Not sending capi call to ServiceIdentity (%s)" % profile_info.user.email()) else: if profile_info.mobiles is None: logging.info(u"%s does not have mobiles registered" % profile_info.user.email()) continue mobiles = db.get([get_mobile_key_by_account(mobile_detail.account) for mobile_detail in profile_info.mobiles]) for mobile_detail, mobile in zip(profile_info.mobiles, mobiles): if mobile_detail.account in skippers: logging.info(u"Skipping account %s " % mobile_detail.account) continue if not _should_send_capi_call_to_mobile(feature_version, mobile): logging.debug(u'%s is not supported by mobile %s of user %s', alias, mobile.account, mobile.user.email()) continue logging.info(u"Sending capi: %s call to %s, account: %s" % (alias, profile_info.user.email(), mobile_detail.account)) yield _send_client_call(mobile_detail, cc, profile_info.user, alias)
def load_customer_points(loyalty_type=None, cursor=None): service_user = users.get_current_user() session_ = users.get_current_session() service_identity = session_.service_identity loyalty_settings = SolutionLoyaltySettings.get_by_user(service_user) if not loyalty_type: loyalty_type = loyalty_settings.loyalty_type result_dict = dict() visits = [] cursor_ = None has_more = False if loyalty_type in SolutionLoyaltySettings.LOYALTY_TYPE_MAPPING: qry = SolutionLoyaltySettings.LOYALTY_TYPE_MAPPING[loyalty_type].load(service_user, service_identity) qry.with_cursor(cursor) visits = qry.fetch(10) cursor_ = qry.cursor() if len(visits) != 0: qry.with_cursor(cursor_) if len(qry.fetch(1)) > 0: has_more = True for visit in visits: saved_points = result_dict.get(visit.app_user) if not saved_points: result_dict[visit.app_user] = saved_points = LoyaltyCustomerPointsTO() saved_points.visits = [] saved_points.visits.append(SolutionLoyaltyVisitTO.fromModel(visit)) # XXX: don't use get_profile_infos app_users = result_dict.keys() profile_infos = get_profile_infos(app_users, allow_none_in_results=True) for app_user, profile_info in zip(app_users, profile_infos): if not profile_info or profile_info.isServiceIdentity: logging.info('User %s not found', app_user.email()) del result_dict[app_user] continue saved_points = result_dict[app_user] saved_points.user_details = ExtendedUserDetailsTO.fromUserProfile(profile_info, None) app_info = get_app_info_cached(saved_points.user_details.app_id) saved_points.user_details.app_name = app_info.name saved_points.visits = sorted(saved_points.visits, key=lambda x: -x.timestamp) r = LoyaltyCustomersTO() r.cursor = cursor_.decode("utf8") if cursor_ else None r.has_more = has_more r.loyalty_type = loyalty_type if loyalty_type == SolutionLoyaltySettings.LOYALTY_TYPE_REVENUE_DISCOUNT: r.loyalty_settings = LoyaltyRevenueDiscountSettingsTO.fromModel(loyalty_settings) elif loyalty_type == SolutionLoyaltySettings.LOYALTY_TYPE_LOTTERY: r.loyalty_settings = LoyaltyLotterySettingsTO.fromModel(loyalty_settings) elif loyalty_type == SolutionLoyaltySettings.LOYALTY_TYPE_STAMPS: r.loyalty_settings = LoyaltyStampsSettingsTO.fromModel(loyalty_settings) elif loyalty_type == SolutionLoyaltySettings.LOYALTY_TYPE_CITY_WIDE_LOTTERY: r.loyalty_settings = LoyaltyCityWideLotterySettingsTO.fromModel(loyalty_settings) else: r.loyalty_settings = None r.customers = sorted(result_dict.itervalues(), key=lambda x: -x.visits[0].timestamp) return r
def _create_message_flow_run_xml_doc(service_identity_user, message_flow_design, message_flow_run_record, members, force_language): service_user = get_service_user_from_service_identity_user(service_identity_user) if not message_flow_design.xml: # Must regenerate xml subflowdict = get_message_flow_design_context(message_flow_design) translator = get_translator(service_user, ServiceTranslation.MFLOW_TYPES) definition_doc = parseString(message_flow_design_to_xml( service_user, message_flow_design, translator, subflowdict)[0].encode('utf-8')) message_flow_design.xml = definition_doc.toxml('utf-8') message_flow_design.put() logging.warning("Message flow design with empty xml property discovered!!!\nkey = %s" % message_flow_design.key()) else: definition_doc = parseString(message_flow_design.xml.encode('utf-8')) run = MessageFlowRunSub(launchTimestamp=message_flow_run_record.creationtime) si = get_service_identity(service_identity_user) run.set_serviceName(si.name) run.set_serviceDisplayEmail(si.qualifiedIdentifier or si.user.email()) run.set_serviceEmail(si.user.email()) run.set_flowParams(message_flow_run_record.flow_params) if si.serviceData: run.set_serviceData(json.dumps(si.serviceData.to_json_dict())) else: run.set_serviceData(si.appData) fallback_language = force_language or get_service_profile(service_user).defaultLanguage mf_languages = list() if definition_doc.documentElement.localName == 'messageFlowDefinitionSet': for definition_element in definition_doc.documentElement.childNodes: if definition_element.localName == 'definition': mf_languages.append(definition_element.getAttribute('language')) elif definition_doc.documentElement.localName == 'definition': mf_languages.append(fallback_language) else: azzert(False, "Unexpected tag name: %s" % definition_doc.documentElement.localName) # if force_language supplied, check if it's in mf_languages if force_language: bizz_check(force_language in mf_languages, "Can not run in %s." % get_full_language_string(force_language)) userprofiles = get_profile_infos(members, expected_types=[UserProfile] * len(members)) user_datas = db.get([UserData.createKey(member, service_identity_user) for member in members]) for i, p in enumerate(userprofiles): member_run_language = force_language or (p.language if p.language in mf_languages else fallback_language) human_user, app_id = get_app_user_tuple(p.user) if user_datas[i]: if user_datas[i].userData: user_data = json.dumps(user_datas[i].userData.to_json_dict()) else: user_data = user_datas[i].data else: user_data = None run.add_memberRun(MemberRunSub(status="SUBMITTED", email=human_user.email(), name=p.name, language=member_run_language, appId=app_id, avatarUrl=p.avatarUrl, userData=user_data)) xml = StringIO() xml.write("""<?xml version="1.0" encoding="utf-8"?>\n""") run.export(xml, 0, namespaceprefix_='', namespacedef_='xmlns="https://rogerth.at/api/1/MessageFlow.xsd"', name_='messageFlowRun') xml.reset() xml_doc = parse(xml) for member_run_child_node in xml_doc.documentElement.childNodes: if member_run_child_node.localName == "memberRun": break else: azzert(False, "No child nodes of type 'memberRun' found for xml:\n%s" % xml) # put memberRun in xml if definition_doc.documentElement.localName == 'messageFlowDefinitionSet': for definition_element in definition_doc.documentElement.childNodes: if definition_element.localName == 'definition': xml_doc.documentElement.insertBefore(definition_element, member_run_child_node) elif definition_doc.documentElement.localName == 'definition': xml_doc.documentElement.insertBefore(definition_doc.documentElement, member_run_child_node) else: azzert(False, "Unexpected tag name: %s" % definition_doc.documentElement.localName) return xml_doc
def start_local_flow(service_identity_user, thread_key, xml, members, tag=None, context=None, force_language=None, download_attachments_upfront=False, push_message=None, parent_message_key=None, flow=None, flow_params=None, check_friends=True): _validate_start_flow(service_identity_user, thread_key, members, tag=tag, check_friends=check_friends) service_user = get_service_user_from_service_identity_user(service_identity_user) if flow: if xml: raise InvalidValueException('xml', 'parameter "xml" cannot be set when property "flow" is set') mfd = get_message_flow_by_key_or_name(service_user, flow) if not mfd or not mfd.user == service_user: raise MessageFlowNotFoundException() if mfd.status != MessageFlowDesign.STATUS_VALID: raise MessageFlowNotValidException(mfd.validation_error) xml = mfd.xml js_flow_dict = generate_js_flow_cached(service_user, xml, context, minify=False, parent_message_key=parent_message_key, must_validate=True) # js_flow_dict = { language : (<compiled JS flow>, brandings, attachments) } if force_language and force_language is not MISSING: if force_language not in js_flow_dict: raise InvalidMessageFlowLanguageException(json.dumps(js_flow_dict.keys()), force_language) forced_flow = js_flow_dict[force_language] else: forced_flow = None extra_user = [] if service_user == MC_DASHBOARD else [service_identity_user] profile_infos = {profile_info.user: profile_info for profile_info in get_profile_infos(members + extra_user)} mfr = _create_message_flow_run(service_user, service_identity_user, result_callback=False, tag=tag) message_flow_run_id = mfr.messageFlowRunId for app_user in members: if forced_flow: flow_definition, brandings, attachments = forced_flow else: target_language = profile_infos[app_user].language if target_language not in js_flow_dict: # fall back to service default language target_language = get_service_profile(service_user).defaultLanguage if target_language not in js_flow_dict: if len(js_flow_dict) == 1: target_language = js_flow_dict.keys()[0] else: raise InvalidMessageFlowLanguageException(json.dumps(js_flow_dict.keys()), target_language) flow_definition, brandings, attachments = js_flow_dict[target_language] force_skip_attachments_download = False mobiles = profile_infos[app_user].mobiles if push_message: for mobile_detail in mobiles: if mobile_detail.type_ == Mobile.TYPE_IPHONE_HTTP_APNS_KICK and mobile_detail.pushId: force_skip_attachments_download = True break request = StartFlowRequestTO() request.attachments_to_dwnl = attachments if download_attachments_upfront and not force_skip_attachments_download else list() request.brandings_to_dwnl = brandings request.service = remove_slash_default(service_identity_user).email() request.static_flow = compress_js_flow_definition(flow_definition) request.static_flow_hash = unicode(md5_hex(flow_definition)) request.parent_message_key = thread_key request.message_flow_run_id = message_flow_run_id request.flow_params = flow_params if service_user == MC_DASHBOARD: sender_name = get_app_by_id(get_app_id_from_app_user(app_user)).name else: sender_name = profile_infos[service_identity_user].name kwargs = { CAPI_KEYWORD_PUSH_DATA: StartLocalFlowNotification(sender_name, push_message) } startFlow(start_flow_response_handler, logError, app_user, request=request, **kwargs) if push_message: send_apple_push_message(push_message, sender_name, mobiles) return message_flow_run_id
def _pick_winner(service_user, sln_loyalty_lottery_key): now_ = now() sln_loyalty_lottery = db.get(sln_loyalty_lottery_key) if sln_loyalty_lottery.claimed or sln_loyalty_lottery.redeemed or sln_loyalty_lottery.deleted: return if sln_loyalty_lottery.schedule_loot_time > 0: return service_identity = sln_loyalty_lottery.service_identity service_identity_user = create_service_identity_user_wo_default( service_user, service_identity) sls_key = SolutionLoyaltySettings.create_key(service_user) slls_key = SolutionLoyaltyLotteryStatistics.create_key( service_user, service_identity) sln_settings_key = SolutionSettings.create_key(service_user) sln_loyalty_settings, slls, sln_settings = db.get( [sls_key, slls_key, sln_settings_key]) if sln_loyalty_settings.loyalty_type != SolutionLoyaltySettings.LOYALTY_TYPE_LOTTERY: sln_loyalty_lottery.deleted = True sln_loyalty_lottery.put() return logging.info("loyalty lottery loot: %s", service_user) possible_winners = [] if slls: for i, app_user in enumerate(slls.app_users): if app_user not in sln_loyalty_lottery.skip_winners and app_user != sln_loyalty_lottery.winner: for i in xrange(slls.count[i]): possible_winners.append(app_user) logging.debug("possible winners count: %s", len(possible_winners)) if len(possible_winners) == 0: if sln_loyalty_lottery.winner: logging.debug("can not assign winner, keep old") else: logging.debug("can not assign winner, delete lottery") sln_loyalty_lottery.deleted = True sln_loyalty_lottery.put() return else: winner = random.choice(possible_winners) logging.debug("new winner: %s", winner) slvl = SolutionLoyaltyVisitLottery.all() \ .ancestor(parent_key_unsafe(service_identity_user, SOLUTION_COMMON)) \ .filter('redeemed =', False) \ .filter('app_user ='******'t use get_profile_infos profile_info = get_profile_infos([slvl.app_user], allow_none_in_results=True)[0] if not profile_info or profile_info.isServiceIdentity: azzert(False, "profile_info for app_user %s not found!" % winner) else: user_detail = UserDetailsTO.fromUserProfile(profile_info) loot_datetime_tz = datetime.fromtimestamp( sln_loyalty_lottery.end_timestamp, pytz.timezone(sln_settings.timezone)) loot_date_str = format_datetime(loot_datetime_tz, format='medium', locale=sln_settings.main_language or DEFAULT_LANGUAGE) next_datetime_tz = datetime.fromtimestamp( now() + 24 * 3600, pytz.timezone(sln_settings.timezone)) next_date_str = format_datetime(next_datetime_tz, format='medium', locale=sln_settings.main_language or DEFAULT_LANGUAGE) msg_ok = translate(sln_settings.main_language, SOLUTION_COMMON, 'loyalty-lottery-loot-ok', name=user_detail.name, date_loot=loot_date_str, price=sln_loyalty_lottery.winnings, date=next_date_str) msg_sorry = translate(sln_settings.main_language, SOLUTION_COMMON, 'loyalty-lottery-loot-nok') btn = AnswerTO() btn.id = u'%s' % json.dumps({"key": unicode(sln_loyalty_lottery_key)}) btn.type = u'button' btn.caption = translate(sln_settings.main_language, SOLUTION_COMMON, 'Confirm') btn.action = None btn.ui_flags = 0 message_flags = Message.FLAG_ALLOW_DISMISS sln_i_settings = get_solution_settings_or_identity_settings( sln_settings, service_identity) def trans(): sm_data = [] if sln_loyalty_lottery.winner_timestamp != 0: logging.debug("loyalty lottery loot: update winner %s", sln_loyalty_lottery.winner) sim_parent, _ = add_solution_inbox_message( service_user, sln_loyalty_lottery.solution_inbox_message_key, True, None, now_, msg_sorry, mark_as_read=True) if sim_parent.message_key_by_tag: message_key_by_tag = json.loads(sim_parent.message_key_by_tag) if message_key_by_tag.get(u"loyalty_lottery_loot", None): deferred.defer(_messaging_seal, service_user, message_key_by_tag[u"loyalty_lottery_loot"], sim_parent.message_key, sim_parent.message_key, 1, _transactional=True) send_inbox_forwarders_message( service_user, service_identity, None, msg_sorry, { 'if_name': user_detail.name, 'if_email': user_detail.email }, message_key=sim_parent.solution_inbox_message_key, reply_enabled=sim_parent.reply_enabled, send_reminder=False) deferred.defer(send_email_to_user_for_loyalty_update, service_user, service_identity, sln_loyalty_lottery.winner, msg_sorry, False) sm_data.append({ u"type": u"solutions.common.messaging.update", u"message": serialize_complex_value( SolutionInboxMessageTO.fromModel(sim_parent, sln_settings, sln_i_settings, True), SolutionInboxMessageTO, False) }) logging.debug("loyalty lottery loot: new winner %s", winner) sim_parent = create_solution_inbox_message( service_user, service_identity, SolutionInboxMessage.CATEGORY_LOYALTY, unicode(sln_loyalty_lottery_key), True, [user_detail], now_, msg_ok, True, mark_as_read=True) sln_loyalty_lottery.solution_inbox_message_key = sim_parent.solution_inbox_message_key if sln_loyalty_lottery.winner: if not sln_loyalty_lottery.skip_winners: sln_loyalty_lottery.skip_winners = [] sln_loyalty_lottery.skip_winners.append(sln_loyalty_lottery.winner) sln_loyalty_lottery.pending = False sln_loyalty_lottery.winner = winner sln_loyalty_lottery.winner_info = SolutionUser.fromTO( user_detail) if user_detail else None sln_loyalty_lottery.winner_timestamp = now_ sln_loyalty_lottery.put() send_inbox_forwarders_message( service_user, service_identity, None, msg_ok, { 'if_name': user_detail.name, 'if_email': user_detail.email }, message_key=sim_parent.solution_inbox_message_key, reply_enabled=sim_parent.reply_enabled, send_reminder=False, answers=[btn], store_tag=u"loyalty_lottery_loot", flags=message_flags) deferred.defer(send_email_to_user_for_loyalty_update, service_user, service_identity, sln_loyalty_lottery.winner, msg_ok, False, sim_parent.solution_inbox_message_key) sm_data.append({ u"type": u"solutions.common.messaging.update", u"message": serialize_complex_value( SolutionInboxMessageTO.fromModel(sim_parent, sln_settings, sln_i_settings, True), SolutionInboxMessageTO, False) }) sm_data.append({u"type": u"solutions.common.loyalty.lottery.update"}) send_message(service_user, sm_data, service_identity=service_identity) deferred.defer(_continue, service_user, service_identity, sln_loyalty_lottery_key, _transactional=True) xg_on = db.create_transaction_options(xg=True) db.run_in_transaction_options(xg_on, trans)
def _pick_city_wide_lottery_winner(service_user, sln_cwl_lottery_key): sln_cwl = db.get(sln_cwl_lottery_key) if sln_cwl.winners: return slls = db.get(SolutionCityWideLotteryStatistics.create_key(sln_cwl.app_id)) logging.info("city wide lottery loot: %s", sln_cwl.app_id) possible_winners = [] if slls: for i, app_user in enumerate(slls.app_users): if app_user not in sln_cwl.skip_winners and app_user not in sln_cwl.winners: for i in xrange(slls.count[i]): possible_winners.append(app_user) logging.debug("possible winners count: %s", len(possible_winners)) if len(possible_winners) == 0: if sln_cwl.winners: logging.debug("can not assign winners, keep old") else: logging.debug("can not assign winners, delete city wide lottery") sln_cwl.deleted = True sln_cwl.put() return else: winners_needed = sln_cwl.x_winners logging.debug("winners_needed: %s", winners_needed) if len(possible_winners) < winners_needed: winners_needed = len(possible_winners) winners = [] while True: if not possible_winners: break if len(winners) >= winners_needed: break winner = random.choice(possible_winners) possible_winners = filter(lambda a: a != winner, possible_winners) winners.append(winner) sln_settings = get_solution_settings(service_user) winners_info = [] slvl_parent_key = SolutionCityWideLotteryVisit.create_city_parent_key( sln_cwl.app_id) winner_text = "" for winner in winners: slvl = SolutionCityWideLotteryVisit.all() \ .ancestor(slvl_parent_key) \ .filter('redeemed =', False) \ .filter('app_user ='******'t use get_profile_infos profile_info = get_profile_infos([slvl.app_user], allow_none_in_results=True)[0] if not profile_info or profile_info.isServiceIdentity: continue else: eud = ExtendedUserDetailsTO.fromUserProfile(profile_info, None) with set_user(service_user): app_info = get_app_info_cached(eud.app_id) eud.app_name = app_info.name eud.public_key = None eud.public_keys = [] winners_info.append(eud) winner_text = winner_text + "\n - %s (%s)" % (eud.name, eud.email) def trans(): sln_cwl.pending = False sln_cwl.winners = winners sln_cwl.winners_info = json.dumps( serialize_complex_value(winners_info, ExtendedUserDetailsTO, True)) sln_cwl.put() deferred.defer(_redeem_city_wide_lottery_visits, service_user, sln_cwl_lottery_key, now(), _transactional=True) to_emails = sln_settings.inbox_mail_forwarders if to_emails: solution_server_settings = get_solution_server_settings() subject = 'Winnaars gemeentelijke tombola' body = """Beste, Volgende mensen hebben gewonnen met de tombola: %s Met vriendelijke groeten, Het Onze Stad App Team """ % winner_text send_mail(solution_server_settings.shop_export_email, to_emails, subject, body) xg_on = db.create_transaction_options(xg=True) db.run_in_transaction_options(xg_on, trans)
def post(app_user, location, timestamp, recipients): def parse_location(friend_language, accuracy, geocoded_results): # See https://developers.google.com/maps/documentation/geocoding/#Results if accuracy < 100: for result in results: if "street_address" in result["types"]: return "\n" + localize(friend_language, "Location: %(address)s", address=result["formatted_address"]) return "\n" + localize(friend_language, "Location: %(address)s", address=results[0]["formatted_address"]) address_types = ["neighborhood", "sublocality", "locality", "political", "route"] for adt in address_types: for result in results: if adt in result["types"]: return "\n" + localize(friend_language, "Location: %(address)s", address=result["formatted_address"]) logging.error("Could not parse geo-coded result!") loc = GeoPointWithTimestampTO() loc.latitude = location.latitude loc.longitude = location.longitude loc.accuracy = location.accuracy loc.timestamp = timestamp maps_lat = loc.latitude / 1000000.0 maps_long = loc.longitude / 1000000.0 current_user, app_id = get_app_user_tuple(app_user) for recipient in (r for r in recipients if r.target == GetLocationRequestTO.TARGET_SERVICE_LOCATION_TRACKER): location_with_timestamp = GeoPointWithTimestampTO() location_with_timestamp.latitude = location.latitude location_with_timestamp.longitude = location.longitude location_with_timestamp.accuracy = location.accuracy location_with_timestamp.timestamp = timestamp handle_service_tracker_results(app_user, add_slash_default(users.User(recipient.friend)), location_with_timestamp) to_put = [] for recipient in (r for r in recipients if r.target in (GetLocationRequestTO.TARGET_MOBILE, GetLocationRequestTO.TARGET_MOBILE_FIRST_REQUEST_AFTER_GRANT)): friend_user = create_app_user(users.User(recipient.friend), app_id) def trans(): lr = LocationRequest.get_by_key_name(friend_user.email(), parent=parent_key(app_user)) if not lr: return False lr.delete() return True if not db.run_in_transaction(trans): continue profile, friend_profile = get_profile_infos([app_user, friend_user], expected_types=[UserProfile, UserProfile]) if recipient.target == GetLocationRequestTO.TARGET_MOBILE: m = localize(friend_profile.language, """Received location of %(name)s. Accuracy: %(accuracy)sm""", name=profile.name, accuracy=loc.accuracy) else: m = localize(friend_profile.language, """%(name)s accepted your location sharing request. Latest information: Accuracy: %(accuracy)sm""", name=profile.name, accuracy=loc.accuracy) url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=%s,%s&sensor=true" % (maps_lat, maps_long) logging.info("Fetching URL: %s" % url) result = urlfetch.fetch(url) logging.info("Fetched result: %s" % result.content) logging.info("Result status code: %s" % result.status_code) if result.status_code == 200: results = json.loads(result.content) if results["status"] == "OK" and results["results"]: results = results["results"] location = parse_location(friend_profile.language, loc.accuracy, results) if location: m += location button = ButtonTO() button.id = u"show_map" button.caption = localize(friend_profile.language, "Show map") button.action = u"geo://%s,%s" % (str(maps_lat).replace(',', '.'), str(maps_long).replace(',', '.')) button.ui_flags = 0 msg_model = sendMessage(MC_DASHBOARD, [UserMemberTO(friend_user)], Message.FLAG_ALLOW_DISMISS, 0, None, m, [button], None, get_app_by_user(friend_user).core_branding_hash, None, is_mfr=False) to_put.append(LocationMessage(key=LocationMessage.create_key(app_user, msg_model.key().name()), receiver=recipient.friend)) ndb.put_multi(to_put) mobile_recipients = [create_app_user(users.User(r.friend), app_id) for r in recipients if r.target == GetLocationRequestTO.TARGET_MOBILE_FRIENDS_ON_MAP] request = LocationResultRequestTO() request.friend = current_user.email() request.location = loc locationResult(get_location_result_response_handler, logError, mobile_recipients, request=request) web_recipients = [r for r in recipients if r.target == GetLocationRequestTO.TARGET_WEB] for recipient in web_recipients: friend_user = create_app_user(users.User(recipient.friend), app_id) channel.send_message(friend_user, 'rogerthat.location.location_response', friend=current_user.email(), location=serialize_complex_value(loc, GeoPointWithTimestampTO, False))