def _test_rogerthat_app_user(self, human_user, app_id, si): app_user = create_app_user(human_user, app_id) email = human_user.email() if app_id == App.APP_ID_ROGERTHAT: self.assertEqual(email, app_user.email()) else: self.assertEqual("%s:%s" % (email, app_id), app_user.email()) self.assertEqual((human_user, app_id), get_app_user_tuple(app_user)) self.assertEqual((human_user, app_id), get_app_user_tuple_by_email(app_user.email())) self.assertEqual(human_user, get_human_user_from_app_user(app_user)) self.assertEqual(app_id, get_app_id_from_app_user(app_user)) user_profile = create_user_profile(app_user, email) self.assertEqual(app_user, user_profile.user) self.assertEqual(app_id == App.APP_ID_ROGERTHAT, canBeFriends(si, user_profile)) self.assertEqual(app_id == App.APP_ID_ROGERTHAT, canBeFriends(user_profile, si)) if app_id == App.APP_ID_ROGERTHAT: makeFriends(app_user, si.user, None, None, None, False, False) else: self.assertRaises(Exception, makeFriends, app_user, si.user, None, None, None, False, False) self.assertEqual(app_id == App.APP_ID_ROGERTHAT, areFriends(user_profile, si)) breakFriendShip(app_user, si.user) self.assertFalse(areFriends(user_profile, si)) return app_user, user_profile
def export_user_data(app_user, data_export_email): human_user, app_id = get_app_user_tuple(app_user) date = format_datetime(datetime.datetime.now(), locale='en', format='yyyy_MM_dd') result_path = '/%s/users/%s/%s' % (EXPORTS_BUCKET, app_user.email(), date) def update(): user_data_export_key = UserDataExport.create_key(app_user, date) user_data_export = UserDataExport.get(user_data_export_key) if user_data_export: return user_data_export.data_export_email user_data_export = UserDataExport(key=user_data_export_key) user_data_export.creation_time = now() user_data_export.data_export_email = data_export_email user_data_export.put() counter = ExportUserPipeline(result_path, human_user.email(), app_id, data_export_email) task = counter.start(return_task=True) task.add(queue_name=DATA_EXPORT_QUEUE, transactional=True) redirect_url = "%s/status?root=%s" % (counter.base_path, counter.pipeline_id) logging.info("export pipeline url: %s", redirect_url) return None return run_in_transaction(update, xg=True)
def _validate_start_flow(service_identity_user, parent_message_key, members, check_friends=True, tag=None, allow_reserved_tag=False, flow_params=None): if not members: raise NoMembersException() if parent_message_key and len(members) > 1: raise MessageParentKeyCannotBeUsedWithMultipleParents() if tag and not allow_reserved_tag and tag.startswith(MC_RESERVED_TAG_PREFIX): raise ReservedTagException() # Create list with ServiceFriendKeys for the members if check_friends: fsic_keys = [FriendServiceIdentityConnection.createKey(member, service_identity_user) for member in members] fsics = db.get(fsic_keys) # db.get returns a list of found and None non_friends = [] for (member, fsic) in zip(members, fsics): if not fsic or fsic.deleted: m = BaseMemberTO() human_user, m.app_id = get_app_user_tuple(member) m.member = human_user.email() non_friends.append(m) if non_friends: raise NonFriendMembersException(serialize_complex_value(non_friends, BaseMemberTO, True)) if flow_params: try: json.loads(flow_params) except ValueError: raise InvalidFlowParamsException()
def get(self): data_dict, app_user = self.get_user_info() if not data_dict or not app_user: return azzert(data_dict['a'] == "unsubscribe broadcast") broadcast_type = data_dict['bt'] si_user = users.User(data_dict['e']) _, user_profile, si, fsic = run_in_xg_transaction(self._un_subscribe, app_user, si_user, broadcast_type) if fsic or not si: message = '%s,<br><br>%s' % (xml_escape(localize(user_profile.language, u'dear_name', name=user_profile.name)), xml_escape(localize(user_profile.language, u'successfully_unsubscribed_broadcast_type', notification_type=broadcast_type, service=si.name if si else data_dict['n']))) else: language = get_languages_from_request(self.request)[0] if not user_profile: # User already deactivated his account human_user, app_id = get_app_user_tuple(app_user) message = localize(language, u'account_already_deactivated', account=human_user.email(), app_name=get_app_name_by_id(app_id)) else: # User is not connected anymore to this service identity message = localize(language, u'account_already_disconnected_from_service', service_name=si.name) jinja_template = self.get_jinja_environment().get_template('unsubscribe_broadcast_type.html') self.response.out.write(jinja_template.render(dict(message=message)))
def solution_coupon_redeem(service_user, email, method, params, tag, service_identity, user_details): data = json.loads(params) coupon_id = data.get('coupon_id') redeeming_user = users.User(data.get('redeeming_user')) response = SendApiCallCallbackResultTO() lang = get_solution_settings(service_user).main_language service_identity_user = get_and_validate_service_identity_user( service_user, service_identity) try: coupon = redeem_news_coupon(coupon_id, service_identity_user, redeeming_user) with users.set_user(service_user): news_item = news.get(coupon.news_id, service_identity) response.result = u'%s' % json.dumps( serialize_complex_value(news_item, NewsItemTO, False)) except NewsCouponNotFoundException: response.error = t(lang, 'coupon_not_found') except NewsCouponAlreadyUsedException: response.error = t(lang, 'you_have_already_used_this_coupon') user, app_id = get_app_user_tuple(redeeming_user) member = BaseMemberTO(user.email(), app_id) disable_news_with_coupon(coupon_id, service_identity_user, member) except Exception as exception: logging.error(exception) response.error = t(lang, 'error-occured-unknown') return response
def put_loyalty_user(url, email): from rogerthat.bizz.profile import put_loyalty_user as bizz_put_loyalty_user service_user = users.get_current_user() result = PutLoyaltyUserResultTO() result.url, app_user = bizz_put_loyalty_user(service_user, url, email) human_user, result.app_id = get_app_user_tuple(app_user) result.email = human_user.email() return result
def from_profile_info(profile_info): from rogerthat.utils.app import get_app_user_tuple u = UserTO() human_user, app_id = get_app_user_tuple(profile_info.user) u.email = human_user.email() if profile_info else None u.name = profile_info.name if profile_info else None u.avatarId = profile_info.avatarId if profile_info else -1 u.app_id = app_id return u
def _resolve_voucher(service_user, service_identity, url): '''Lookup the provided URL. Can be a city voucher. Else it will be treated as a custom loyalty card.''' # 1/ Check if a custom loyalty card already exists for this URL custom_loyalty_card = CustomLoyaltyCard.get_by_url(url) if custom_loyalty_card and custom_loyalty_card.app_user: human_user, app_id = get_app_user_tuple(custom_loyalty_card.app_user) return _create_resolve_result(CustomLoyaltyCard.TYPE, url, human_user.email(), app_id) # 2/ Check if it's a city voucher si = system.get_identity(service_identity) poke_information, city_service_user = _find_voucher(url, si.app_ids) if not poke_information or not poke_information.tag.startswith( POKE_TAG_CITY_VOUCHER_QR): # 2.1/ Not a city voucher logging.debug( 'Unknown QR code scanned: %s. Loyalty device will create custom paper loyalty card.', url) user_info = GetUserInfoResponseTO() user_info.app_id = user_info.email = user_info.name = user_info.qualifiedIdentifier = u'dummy' return _create_resolve_result(u'unknown', url, u'dummy', u'dummy') # 2.2/ It is a city voucher data = json.loads(poke_information.tag[len(POKE_TAG_CITY_VOUCHER_QR):]) ancestor_key = SolutionCityVoucher.create_parent_key(data["app_id"]) sln_city_voucher = SolutionCityVoucher.get_by_id(data["voucher_id"], ancestor_key) if not sln_city_voucher: logging.debug("Could not find city voucher for data: %s", data) raise Exception("Could not find city voucher") sln_settings = get_solution_settings(service_user) r_dict = dict() r_dict["type"] = SolutionCityVoucher.TYPE r_dict["app_id"] = sln_city_voucher.app_id r_dict["voucher_id"] = sln_city_voucher.key().id() r_dict["uid"] = sln_city_voucher.uid if sln_city_voucher.activated: if sln_city_voucher.expired: raise BusinessException( common_translate(sln_settings.main_language, SOLUTION_COMMON, 'Voucher has expired')) r_dict["status"] = 1 r_dict["value"] = sln_city_voucher.value r_dict["redeemed_value"] = sln_city_voucher.redeemed_value elif service_user == city_service_user: r_dict["status"] = 2 else: raise BusinessException( common_translate(sln_settings.main_language, SOLUTION_COMMON, 'Voucher not activated')) return r_dict
def _create_owncloud_account(app_user, owncloud_base_uri, owncloud_admin_username, owncloud_admin_password, owncloud_password): human_user, app_id = get_app_user_tuple(app_user) post_args = {"userid": "%s_%s" % (human_user.email(), app_id), "password": owncloud_password} post_data = urlencode(post_args) headers = {'Authorization': 'Basic %s' % base64.b64encode("%s:%s" % (owncloud_admin_username, owncloud_admin_password))} url = "%s/ocs/v1.php/cloud/users" % owncloud_base_uri response = urlfetch.fetch(url, post_data, "POST", headers, deadline=55) logging.debug("owncloud response.status_code: %s", response.status_code) logging.debug("owncloud response.content: %s", response.content)
def _re_index(app_user): from rogerthat.bizz.messaging import re_index_conversations_of_member def trans(): user_profile = get_profile_info(app_user, False) fm = get_friends_map(app_user) return user_profile, fm user_profile, fm = db.run_in_transaction(trans) app_user_email = app_user.email() # delete old indexed app user if the doc_id is app_user_email (not encoded) user_index = search.Index(name=USER_INDEX) try: if user_index.get(app_user_email): user_index.delete(app_user_email) except search.InvalidRequest: pass deferred.defer(re_index_conversations_of_member, app_user_email) if not user_profile: logging.info("Tried to index a user who is deactivated") delete_user_index_document(user_index, app_user_email) return if user_profile.isServiceIdentity: logging.error("Tried to index a service into the USER_INDEX") return connections = StringIO() for f in fm.friends: email = f.email().encode('utf8').replace('"', '') connections.write('@@%s@@' % email) if '/' in email: connections.write('@@%s@@' % email.split('/')[0]) human_user, app_id = get_app_user_tuple(app_user) fields = [ search.TextField(name='email', value=human_user.email()), search.TextField(name='name', value=user_profile.name), search.TextField(name='language', value=user_profile.language), search.TextField(name='connections', value=connections.getvalue()), search.TextField(name='app_id', value=app_id) ] if user_profile.profileData: data = json.loads(user_profile.profileData) for key, value in data.iteritems(): fields.append(search.TextField(name='pd_%s' % key.replace(' ', '_'), value=value)) create_user_index_document(user_index, app_user_email, fields)
def get(self): web_user = users.get_current_user() if not web_user and not self.set_user(): self.abort(401) return email, _ = get_app_user_tuple(users.get_current_user()) user_id = get_uid(email.email()) if web_user: token = create_custom_token(user_id, {}) else: token = create_custom_token(user_id, {}, True) response = { 'token': token } self.response.write(json.dumps(response))
def trans(): coupon = get_and_validate_news_coupon(coupon_id, service_identity_user, redeeming_user) if not coupon.redeemed_by: coupon.redeemed_by = KVStore(coupon.key()) kv_store = {'users': []} else: kv_store = coupon.redeemed_by.to_json_dict() redeemed_object = { 'user': redeeming_user.email(), 'redeemed_on': now() } kv_store['users'].append(redeemed_object) coupon.redeemed_by.from_json_dict(kv_store) coupon.put() user, app_id = get_app_user_tuple(redeeming_user) member = BaseMemberTO(user.email(), app_id) news.disable_news(coupon.news_id, [member], get_identity_from_service_identity_user(service_identity_user)) return coupon
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 _re_index(app_user): def trans(): user_profile = get_profile_info(app_user, False) fm = get_friends_map(app_user) return user_profile, fm user_profile, fm = db.run_in_transaction(trans) if not user_profile: logging.info("Tried to index a user who is deactivated") search.Index(name=USER_INDEX).delete(app_user.email()) return if user_profile.isServiceIdentity: logging.error("Tried to index a service into the USER_INDEX") return connections = StringIO() for f in fm.friends: email = f.email().encode('utf8').replace('"', '') connections.write('@@%s@@' % email) if '/' in email: connections.write('@@%s@@' % email.split('/')[0]) human_user, app_id = get_app_user_tuple(app_user) fields = [ search.TextField(name='email', value=human_user.email()), search.TextField(name='name', value=user_profile.name), search.TextField(name='language', value=user_profile.language), search.TextField(name='connections', value=connections.getvalue()), search.TextField(name='app_id', value=app_id) ] if user_profile.profileData: data = json.loads(user_profile.profileData) for key, value in data.iteritems(): fields.append(search.TextField(name='pd_%s' % key.replace(' ', '_'), value=value)) doc = search.Document(doc_id=app_user.email(), fields=fields) search.Index(name=USER_INDEX).put(doc)
def get_identity(app_user, user_profile=None): idTO = IdentityTO() profile = user_profile or get_user_profile(app_user) human_user, app_id = get_app_user_tuple(app_user) idTO.email = human_user.email() idTO.name = profile.name idTO.avatarId = profile.avatarId idTO.qualifiedIdentifier = profile.qualifiedIdentifier idTO.birthdate = profile.birthdate or 0 idTO.gender = profile.gender or 0 idTO.hasBirthdate = profile.birthdate is not None idTO.hasGender = profile.gender is not None idTO.profileData = profile.profileData app = get_app_by_id(get_app_id_from_app_user(app_user)) if app.owncloud_base_uri: idTO.owncloudUri = app.owncloud_base_uri if profile.owncloud_password else None idTO.owncloudUsername = u"%s_%s" % (idTO.email, app_id) idTO.owncloudPassword = profile.owncloud_password else: idTO.owncloudUri = None idTO.owncloudUsername = None idTO.owncloudPassword = None return idTO
def trans(): friendMap = db.get(friend_map_key) if not friendMap: logging.warn("Friendmap not found for key: %s" % friend_map_key) return email = remove_slash_default(profile_info.user).email() if not email in friendMap.friendDetails: logging.warn("Probably friend %s was removed while updating %s" % (email, friendMap.user.email())) return friendDetail = friendMap.friendDetails[email] friendDetail.avatarId = avatarId if profile_info.isServiceIdentity: target_language = get_user_profile(friendMap.user).language friendDetail.name = translator.translate(ServiceTranslation.IDENTITY_TEXT, profile_info.name, target_language) else: friendDetail.name = profile_info.name friendDetail.type = FriendDetail.TYPE_SERVICE if profile_info.isServiceIdentity else FriendDetail.TYPE_USER friendDetail.relationVersion += 1 friendMap.generation += 1 puts = [friendMap] if profile_info.isServiceIdentity: fsic = db.get(FriendServiceIdentityConnection.createKey(friendMap.user, profile_info.user)) for attr in ('disabled_broadcast_types', 'enabled_broadcast_types'): if getattr(fsic, attr) is None: setattr(fsic, attr, list()) _, app_id = get_app_user_tuple(friendMap.user) updated = False enabled_broadcast_types = list(fsic.enabled_broadcast_types) if app_id == App.APP_ID_OSA_LOYALTY: if enabled_broadcast_types: enabled_broadcast_types = list() updated = True else: # Add new broadcast types for broadcast_type in service_profile.broadcastTypes: if broadcast_type not in (fsic.disabled_broadcast_types + fsic.enabled_broadcast_types): enabled_broadcast_types = list(set(enabled_broadcast_types) | set([broadcast_type])) updated = True # Remove deleted broadcast types for broadcast_type in fsic.enabled_broadcast_types: if broadcast_type not in service_profile.broadcastTypes: enabled_broadcast_types.remove(broadcast_type) updated = True if updated: friendDetail.relationVersion += 1 fsic.enabled_broadcast_types = enabled_broadcast_types puts.append(fsic) if updated or clear_broadcast_settings_cache: logging.info("Deleting BroadcastSettingsFlowCache from datastore") db.delete_async(BroadcastSettingsFlowCache.create_key(friendMap.user, profile_info.user)) put_and_invalidate_cache(*puts) # defer updateFriend with countdown=1 to ensure that changes are persisted. deferred.defer(_trigger_update_friend, friendMap.user, friend_map_key, profile_info_key, _transactional=True, _countdown=1, _queue=get_current_queue() or HIGH_LOAD_WORKER_QUEUE)
def make_member_from_app_user(app_user): human_user, app_id = get_app_user_tuple(app_user) member = BaseMemberTO() member.member = human_user.email() member.app_id = app_id return member
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 trans(): # type: () -> FriendMap friend_map = FriendMap.get(friend_map_key) # type: FriendMap if not friend_map: logging.warn("FriendMap not found for key: %s" % friend_map_key) return email = remove_slash_default(profile_info.user).email() if email not in friend_map.friendDetails: logging.warn(list(friend_map.friendDetails)) logging.warn("Probably friend %s was removed while updating %s" % (email, friend_map.user.email())) return friend_detail = friend_map.friendDetails[email] friend_detail.avatarId = avatar_id if profile_info.isServiceIdentity: target_language = get_user_profile(friend_map.user).language friend_detail.name = translator.translate(ServiceTranslation.IDENTITY_TEXT, profile_info.name, target_language) else: friend_detail.name = profile_info.name friend_detail.type = helper.friend_type friend_detail.relationVersion += 1 friend_map.generation += 1 to_put = [friend_map] if profile_info.isServiceIdentity: fsic_key = FriendServiceIdentityConnection.createKey(friend_map.user, profile_info.user) fsic = db.get(fsic_key) if not fsic: logging.warn("FriendServiceIdentityConnection not found for key: %s" % fsic_key) return for attr in ('disabled_broadcast_types', 'enabled_broadcast_types'): if getattr(fsic, attr) is None: setattr(fsic, attr, []) _, app_id = get_app_user_tuple(friend_map.user) updated = False enabled_broadcast_types = list(fsic.enabled_broadcast_types) if app_id == App.APP_ID_OSA_LOYALTY: if enabled_broadcast_types: enabled_broadcast_types = [] updated = True else: # Add new broadcast types for broadcast_type in service_profile.broadcastTypes: if broadcast_type not in (fsic.disabled_broadcast_types + fsic.enabled_broadcast_types): enabled_broadcast_types = list(set(enabled_broadcast_types) | {broadcast_type}) updated = True # Remove deleted broadcast types for broadcast_type in fsic.enabled_broadcast_types: if broadcast_type not in service_profile.broadcastTypes: enabled_broadcast_types.remove(broadcast_type) updated = True if updated: friend_detail.relationVersion += 1 fsic.enabled_broadcast_types = enabled_broadcast_types to_put.append(fsic) if updated or clear_broadcast_settings_cache: logging.info("Deleting BroadcastSettingsFlowCache from datastore") db.delete_async(BroadcastSettingsFlowCache.create_key(friend_map.user, profile_info.user)) logging.info("updating friend to friend_map.generation: %s, friend_detail.relationVersion: %s", friend_map.generation, friend_detail.relationVersion) logging.debug("debugging_branding _update_friend friend_map.gen %s, friend_detail.relv %s", friend_map.generation, friend_detail.relationVersion) to_put.extend(create_update_friend_requests(helper, helper.profile_info_user, friend_map, UpdateFriendRequestTO.STATUS_MODIFIED)) put_and_invalidate_cache(*to_put)
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))
def from_news_item_to(cls, news_item_to, connections, app_user): """ Args: news_item_to (NewsItemTO) connections (tuple of (list of users.User)) app_user (users.User) Returns: app_news_item_to (AppNewsItemTO) """ to = cls() to.id = news_item_to.id to.sender = NewsSenderTO(news_item_to.sender.email, news_item_to.sender.name, news_item_to.sender.avatar_id) to.title = news_item_to.title to.message = news_item_to.message to.image_url = news_item_to.image_url to.media = news_item_to.media to.broadcast_type = news_item_to.broadcast_type to.reach = news_item_to.reach to.users_that_rogered = [] for friend in connections[0]: if friend.email() in news_item_to.users_that_rogered: human_friend, _ = get_app_user_tuple(friend) to.users_that_rogered.append(human_friend.email()) to.buttons = news_item_to.buttons if news_item_to.qr_code_content: try: content = json.loads(news_item_to.qr_code_content) content['u'] = app_user.email() to.qr_code_content = u'%s' % json.dumps(content) except: to.qr_code_content = news_item_to.qr_code_content else: to.qr_code_content = news_item_to.qr_code_content to.qr_code_caption = news_item_to.qr_code_caption to.version = news_item_to.version to.timestamp = news_item_to.timestamp to.flags = news_item_to.flags to.type = news_item_to.type app_id = get_app_id_from_app_user(app_user) for feed_name in news_item_to.feed_names: if feed_name.app_id == app_id: to.feed_name = feed_name.name break else: to.feed_name = None to.sort_timestamp = max(news_item_to.sticky and news_item_to.sticky_until, news_item_to.timestamp) or 0 if news_item_to.sticky: to.sort_priority = 10 else: user_profile = get_user_profile(app_user) if not NewsItem.match_target_audience_of_item(user_profile, news_item_to): to.sort_priority = 45 elif to.users_that_rogered: to.sort_priority = 20 elif users.User(news_item_to.sender.email) in connections[1]: to.sort_priority = 30 else: to.sort_priority = 40 return to
def generate_broadcast_settings_flow_def(helper, user_profile): service_user = helper.service_user service_profile = helper.get_service_profile() if not service_profile.broadcastTypes: logging.debug("%s has no broadcast types", service_user) return None friend_user = user_profile.user _, app_id = get_app_user_tuple(friend_user) if app_id == App.APP_ID_OSA_LOYALTY: logging.debug("No broadcast flow needed for osa loyalty app") return None service_identity_user = helper.service_identity_user broadcast_branding = service_profile.broadcastBranding fsic = get_friend_serviceidentity_connection(friend_user, service_identity_user) if fsic is None: logging.warn('No friend connection between %s and %s', friend_user, service_identity_user) return None if fsic.disabled_broadcast_types is None: fsic.disabled_broadcast_types = list() if fsic.enabled_broadcast_types is None: fsic.enabled_broadcast_types = list() enabled_broadcast_types = fsic.enabled_broadcast_types translator = helper.get_translator() bt_translate = lambda bt: translator.translate(ServiceTranslation.BROADCAST_TYPE, bt, user_profile.language) end = EndSub(id="end_1", waitForFollowUpMessage=False) flush = ResultsFlushSub(id="flush_1", reference=end.id) w = SelectMultiWidgetSub() w.set_extensiontype_('SelectMultiWidget') w.value = [ValueSub(value=bt) for bt in enabled_broadcast_types] w.choice = [ChoiceSub(label=bt_translate(bt), value=bt) for bt in service_profile.broadcastTypes] # set broadcast types via flow code form = FormSub() form.positiveButtonCaption = localize(user_profile.language, u"Save") form.positiveButtonConfirmation = "" form.negativeButtonCaption = localize(user_profile.language, u"Cancel") form.negativeButtonConfirmation = "" form.widget = w js_code_get_broadcast_types_sub = javascriptCodeTypeSub() js_code_get_broadcast_types_sub.valueOf_ = '''function run(rogerthat, messageFlowRun){ var appVersion = rogerthat.system.appVersion.split("."); var supported = false; if(rogerthat.system.os === 'android'){ if (parseInt(appVersion[0]) > 1 || parseInt(appVersion[1]) > %(android_major)s || parseInt(appVersion[2]) >= %(android_minor)s){ supported = true; } }else if(rogerthat.system.os === 'ios'){ if (parseInt(appVersion[0]) > 1 || parseInt(appVersion[1]) > %(ios_major)s || parseInt(appVersion[2]) >= %(ios_minor)s){ supported = true; } } var nextStepResult = {}; if(supported){ var selectedBroadcastTypes = messageFlowRun.steps[messageFlowRun.steps.length - 1].form_result.result.values; var availableBroadcastTypes = rogerthat.service.data.__rt__broadcastTypes; var disabledBroadcastTypes = []; for(var i = 0; i < availableBroadcastTypes.length; i++){ if(selectedBroadcastTypes.indexOf(availableBroadcastTypes[i]) === -1){ disabledBroadcastTypes.push(availableBroadcastTypes[i]); } } rogerthat.user.data.__rt__disabledBroadcastTypes = disabledBroadcastTypes; rogerthat.user.put(); nextStepResult.outlet = "%(end_id)s"; }else{ nextStepResult.outlet = "%(flush_id)s"; } return nextStepResult; } ''' % dict(end_id=end.id, flush_id=flush.id, android_major=Features.BROADCAST_VIA_FLOW_CODE.android.major, # @UndefinedVariable android_minor=Features.BROADCAST_VIA_FLOW_CODE.android.minor, # @UndefinedVariable ios_major=Features.BROADCAST_VIA_FLOW_CODE.ios.major, # @UndefinedVariable ios_minor=Features.BROADCAST_VIA_FLOW_CODE.ios.minor) # @UndefinedVariable flow_code_put_user_data = FlowCodeSub(id='flow_code_put_user_data', exceptionReference=flush.id, javascriptCode=js_code_get_broadcast_types_sub) # use old method on failure flow_code_put_user_data.add_outlet(OutletSub(reference=end.id, name=end.id, value=end.id)) fm = FormMessageSub(id="message_1") fm.brandingKey = broadcast_branding fm.vibrate = False fm.alertType = 'SILENT' fm.alertIntervalType = 'NONE' fm.autoLock = True fm.content = contentType1Sub() fm.content.valueOf_ = xml_escape( localize(user_profile.language, u"Which type of broadcasts do you wish to receive?")).strip() fm.form = form fm.positiveReference = flow_code_put_user_data.id fm.negativeReference = end.id js_code_fill_broadcast_types = '''function run(rogerthat, messageFlowRun){ var availableBroadcastTypes = rogerthat.service.data.__rt__broadcastTypes; var disabledBroadcastTypes = rogerthat.user.data.__rt__disabledBroadcastTypes; var enabledBroadcastTypes = []; for(var i = 0; i < availableBroadcastTypes.length; i++){ if(disabledBroadcastTypes.indexOf(availableBroadcastTypes[i]) === -1){ enabledBroadcastTypes.push(availableBroadcastTypes[i]); } } return { defaultValue: enabledBroadcastTypes, outlet: "flow_code_broadcast_types_outlet" }; }''' flow_code_user_data_sub = javascriptCodeTypeSub() flow_code_user_data_sub.valueOf_ = js_code_fill_broadcast_types flow_code = FlowCodeSub(id="flow_code_fill_broadcast_types", exceptionReference=fm.id, javascriptCode=flow_code_user_data_sub) flow_code.add_outlet(OutletSub(reference=fm.id, name='flow_code_broadcast_types_outlet', value='flow_code_broadcast_types_outlet')) mfd = MessageFlowDefinitionSub() mfd.name = ServiceMenuDef.TAG_MC_BROADCAST_SETTINGS mfd.language = user_profile.language mfd.startReference = flow_code.id mfd.add_flowCode(flow_code) mfd.add_formMessage(fm) mfd.add_flowCode(flow_code_put_user_data) mfd.add_end(end) mfd.add_resultsFlush(flush) mfds = MessageFlowDefinitionSetSub() mfds.add_definition(mfd) return mfds
def redirect_url(base_url, provider_id, app_user): human_user, app_id = get_app_user_tuple(app_user) args = {'email': human_user.email(), 'app_id': app_id} return "%s/payments/login/%s/redirect?%s" % (base_url, provider_id, urllib.urlencode(args))
def from_user(cls, app_user): memberTO = cls() app_user, memberTO.app_id = get_app_user_tuple(app_user) memberTO.member = app_user.email() return memberTO