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)
Exemple #3
0
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)))
Exemple #5
0
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))
Exemple #12
0
    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)
Exemple #17
0
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
Exemple #18
0
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))
Exemple #21
0
    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