def set_broadcast_types(service_user, broadcast_types, force=False):
    for bt in broadcast_types:
        if not bt:
            raise InvalidBroadcastTypeException(bt)

    broadcast_types_set = set()
    unduplicated_broadcast_types = [bt for bt in broadcast_types
                                    if not (bt in broadcast_types_set or broadcast_types_set.add(bt))]

    def trans():
        service_profile = get_service_profile(service_user, False)

        update_scheduled = False
        bc_settings_items = get_broadcast_settings_items(service_user, -1)
        if not unduplicated_broadcast_types:
            if bc_settings_items:
                if not force:
                    raise CanNotDeleteBroadcastTypesException()
                db.delete(bc_settings_items)
                bump_menuGeneration_of_all_identities_and_update_friends(service_user)
                update_scheduled = True

        service_profile.broadcastTypes = unduplicated_broadcast_types
        service_profile.version += 1
        service_profile.put()

        if not update_scheduled and bc_settings_items:
            schedule_update_all_friends_of_service_user(service_profile, force)

    run_in_transaction(trans)
示例#2
0
def put_all_static_content(cursor=None):
    qry = SolutionStaticContent.all()
    qry.with_cursor(cursor)
    models = qry.fetch(200)
    new_models = list()
    if not models:
        return
    for m in models:
        tmp = m.key().name().split("x", 2)
        coords = [int(tmp[1]), int(tmp[2]), int(tmp[0])]
        new_model = SolutionStaticContent(parent=parent_key(
            m.service_user, SOLUTION_COMMON),
                                          coords=coords,
                                          old_coords=coords,
                                          sc_type=m.sc_type,
                                          icon_label=m.icon_label,
                                          icon_name=m.icon_name,
                                          text_color=m.text_color,
                                          background_color=m.background_color,
                                          html_content=m.html_content,
                                          branding_hash=m.branding_hash,
                                          visible=True,
                                          provisioned=True,
                                          deleted=False)
        new_models.append(new_model)

    def trans():
        db.put(new_models)
        db.delete(models)

    run_in_transaction(trans, True)
    deferred.defer(put_all_static_content,
                   qry.cursor(),
                   _queue=MIGRATION_QUEUE)
    def testTransactionActions(self):

        def trans():
            transActionsCount = TransactionActionsCount(key=TransactionActionsCount.create_key())
            transActionsCount.count = 0
            transActionsCount.put()
            on_trans_committed(update_count, False)
            on_trans_committed(update_count, False)
            on_trans_committed(update_count, True)
            on_trans_committed(update_count, False)
            on_trans_committed(update_count, False)

        def update_count(should_raise):
            transActionsCount = TransactionActionsCount.get(TransactionActionsCount.create_key())
            transActionsCount.count += 1
            if should_raise:
                raise TransactionFailedError()
            transActionsCount.put()

        run_in_transaction(trans)


        def check_count():
            transActionsCount = TransactionActionsCount.get(TransactionActionsCount.create_key())
            self.assertEqual(4, transActionsCount.count)
        run_in_transaction(check_count)
def set_service_disabled(service_user):
    """
    Disconnects all connected users, stores them in an archive and deletes the service from search index.
    """
    from rogerthat.bizz.service import _cleanup_search_index, SERVICE_INDEX, SERVICE_LOCATION_INDEX

    def trans():
        to_put = list()
        service_profile = get_service_profile(service_user)
        service_profile.expiredAt = now()
        service_profile.enabled = False
        to_put.append(service_profile)
        service_identity_keys = get_service_identities_query(service_user, True)
        search_configs = db.get(
                [SearchConfig.create_key(create_service_identity_user(users.User(key.parent().name()), key.name())) for
                 key in service_identity_keys])

        svc_index = search.Index(name=SERVICE_INDEX)
        loc_index = search.Index(name=SERVICE_LOCATION_INDEX)

        for search_config in search_configs:
            if search_config:
                search_config.enabled = False
                to_put.append(search_config)
                on_trans_committed(_cleanup_search_index, search_config.service_identity_user.email(), svc_index,
                                   loc_index)

        for objects_to_put in chunks(to_put, 200):
            put_and_invalidate_cache(*objects_to_put)

        deferred.defer(cleanup_sessions, service_user, _transactional=True)
        deferred.defer(cleanup_friend_connections, service_user, _transactional=True)

    run_in_transaction(trans, True)
    def testTransactionActionsWithNestedTrans(self):

        raised = [False]  # we only want to raise 1 time

        def trans():
            transActionsCount = TransactionActionsCount(key=TransactionActionsCount.create_key())
            transActionsCount.count = 0
            transActionsCount.put()
            on_trans_committed(update_count, False)
            on_trans_committed(update_count, False)
            on_trans_committed(update_count, True)
            on_trans_committed(update_count, False)
            on_trans_committed(update_count, False)

        def update_count(should_raise):
            def inner_trans(should_raise):
                transActionsCount = TransactionActionsCount.get(TransactionActionsCount.create_key())
                transActionsCount.count += 1
                if not raised[0] and should_raise:
                    raised[0] = True
                    raise TransactionFailedError()
                transActionsCount.put()
            return run_in_transaction(inner_trans, False, should_raise)

        run_in_transaction(trans)

        def check_count():
            transActionsCount = TransactionActionsCount.get(TransactionActionsCount.create_key())
            self.assertEqual(5, transActionsCount.count)
        run_in_transaction(check_count)
示例#6
0
def create_service_profile(service_user, name, is_trial=False, update_func=None, supported_app_ids=None):
    from rogerthat.bizz.service import create_default_qr_templates
    from rogerthat.bizz.news import create_default_news_settings

    name = _validate_name(name)

    if supported_app_ids is None:
        default_app = app.get_default_app()
        default_app_id = default_app.app_id if default_app else App.APP_ID_ROGERTHAT
        supported_app_ids = [default_app_id]
    else:
        default_app_id = supported_app_ids[0]

    def trans_prepare_create():
        avatar, image = _create_new_avatar(service_user, is_trial)

        from rogerthat.bizz.service import _create_recommendation_qr_code
        share_sid_key = _create_recommendation_qr_code(service_user, ServiceIdentity.DEFAULT, default_app_id)

        return avatar, image, share_sid_key

    def trans_create(avatar, image, share_sid_key):
        azzert(not get_service_profile(service_user, cached=False))
        azzert(not get_default_service_identity_not_cached(service_user))

        profile = ServiceProfile(parent=parent_key(service_user), key_name=service_user.email())
        profile.avatarId = avatar.key().id()
        _calculateAndSetAvatarHash(profile, image)

        service_identity_user = create_service_identity_user(service_user, ServiceIdentity.DEFAULT)
        service_identity = ServiceIdentity(key=ServiceIdentity.keyFromUser(service_identity_user))
        service_identity.inheritanceFlags = 0
        service_identity.name = name
        service_identity.description = "%s (%s)" % (name, service_user.email())
        service_identity.shareSIDKey = share_sid_key
        service_identity.shareEnabled = False
        service_identity.creationTimestamp = now()
        service_identity.defaultAppId = supported_app_ids[0]
        service_identity.appIds = supported_app_ids

        update_result = update_func(profile, service_identity) if update_func else None

        put_and_invalidate_cache(profile, service_identity,
                                 ProfilePointer.create(service_user),
                                 ProfileHashIndex.create(service_user))

        deferred.defer(create_default_qr_templates, service_user, _transactional=True)
        deferred.defer(create_default_news_settings, service_user, profile.organizationType, _transactional=True)

        return profile, service_identity, update_result

    avatar, image, share_sid_key = run_in_transaction(trans_prepare_create, True)
    try:
        profile, service_identity, update_result = run_in_transaction(trans_create, True, avatar, image, share_sid_key)
        return (profile, service_identity, update_result) if update_func else (profile, service_identity)
    except:
        db.delete([avatar, share_sid_key])
        raise
示例#7
0
def save_cityapp_settings(service_user, gather_events, uitdatabank_secret, uitdatabank_key, uitdatabank_regions):
    def trans():
        cap = get_cityapp_profile(service_user)
        cap.uitdatabank_secret = uitdatabank_secret
        cap.uitdatabank_key = uitdatabank_key
        cap.uitdatabank_regions = uitdatabank_regions
        cap.gather_events_enabled = gather_events
        cap.put()
    run_in_transaction(trans, False)
def save_translations(service_translation_set, multi_translation_dict):
    def trans():
        translation_keys = ServiceTranslation.all(keys_only=True).ancestor(service_translation_set).fetch(None)
        db.delete(translation_keys)
        to_put = list()
        for translation_type, translation_dict in multi_translation_dict.iteritems():
            to_put.append(ServiceTranslation.create(service_translation_set, translation_type, translation_dict))
        db.put(to_put)
    run_in_transaction(trans)
def _send_app_broadcast_to_user(user_profile, service_identity_user, message, tag, is_test=False):
    def trans():
        app_user = users.User(user_profile.key().name())
        if user_profile.isCreatedForService:
            logging.debug('%s is created for service(s) %s', app_user, user_profile.owningServiceEmails)
            return

        service_user = get_service_user_from_service_identity_user(service_identity_user)
        fsic_key = FriendServiceIdentityConnection.createKey(app_user, service_identity_user)
        friend_map_key = get_friends_map_key_by_user(app_user)

        fsic, friend_map, si, service_profile = \
            db.get([fsic_key,
                    friend_map_key,
                    ServiceIdentity.keyFromUser(service_identity_user),
                    get_profile_key(service_user)])

        azzert(si and service_profile)

        if fsic and not fsic.deleted:
            # they are friends
            alert_flags = Message.ALERT_FLAG_VIBRATE
            answers = []
            step_id = u'Connected'
        elif friend_map:
            # Fake a deleted connection between service and human user to be able to show the service's avatar on the phone
            fake_friend_connection(friend_map_key, si)

            alert_flags = Message.ALERT_FLAG_SILENT
            answers = create_add_to_services_button(service_profile.defaultLanguage)
            step_id = u'Not connected'
        else:
            logging.warn(u'No FSIC nor FriendMap found for %s', app_user)
            return

        member = UserMemberTO(app_user, alert_flags)
        flags = Message.FLAG_ALLOW_DISMISS | Message.FLAG_AUTO_LOCK
        timeout = 0
        parent_key = None
        sender_answer = None
        branding = si.descriptionBranding

        if is_test:
            step_id = None

        m = sendMessage(service_identity_user, [member], flags, timeout, parent_key, message, answers, sender_answer,
                        branding, tag, check_friends=False, allow_reserved_tag=True, step_id=step_id)
        m.invitor = service_identity_user
        m.invitee = app_user
        m.origin = ORIGIN_SERVICE_INVITE
        m.servicetag = APP_BROADCAST_TAG
        m.put()

    run_in_transaction(trans, xg=True)
def _run_update_friends_by_profile_info(user, friend_type, changed_properties, worker_queue=HIGH_LOAD_WORKER_QUEUE,
                                        clear_broadcast_settings_cache=False):
    def trans(user):
        helper = FriendHelper.serialize(user, friend_type)

        if friend_type == FRIEND_TYPE_SERVICE:
            user = remove_slash_default(user)
        else:
            update_friend_service_identity_connections(UserProfile.createKey(user), changed_properties)

        run_job(get_friends_friends_maps_keys_query, [user], _update_friend, [helper, clear_broadcast_settings_cache],
                worker_queue=worker_queue)

    run_in_transaction(trans, True, user)
def check_i18n_status_of_message_flows(service_user):
    from rogerthat.bizz.service.mfd import render_xml_for_message_flow_design

    def trans():
        translator = get_translator(service_user)
        mfds = get_multilanguage_message_flow_designs_by_status(service_user, MessageFlowDesign.STATUS_VALID)
        for mfd in mfds:
            render_xml_for_message_flow_design(mfd, translator, dict())

        put_and_invalidate_cache(*mfds)

    run_in_transaction(trans, xg=True)

    channel.send_message(service_user, u'rogerthat.mfd.changes')
示例#12
0
def update_service_avatar(service_user, image):
    img = images.Image(image)
    img.im_feeling_lucky()
    img.execute_transforms()
    if img.height != img.width:
        devation = float(img.width) / float(img.height)
        if devation < 0.95 or devation > 1.05:
            from rogerthat.bizz.service import AvatarImageNotSquareException
            logging.debug("Avatar Size: %sx%s" % (img.width, img.height))
            raise AvatarImageNotSquareException()
    img = images.Image(image)
    img.resize(150, 150)
    image = img.execute_transforms(images.PNG, 100)
    if is_trial_service(service_user):
        image = add_trial_service_overlay(image)

    def trans():
        service_profile = get_service_profile(service_user)
        avatar = get_avatar_by_id(service_profile.avatarId)
        if not avatar:
            avatar = Avatar(user=service_profile.user)
        update_avatar_profile(service_profile, avatar, image)
        service_profile.version += 1
        service_profile.put()

        from rogerthat.bizz.job.update_friends import schedule_update_all_friends_of_service_user
        schedule_update_all_friends_of_service_user(service_profile)

    return run_in_transaction(trans, xg=True)
示例#13
0
def update_user_profile(app_user, name, image, language):
    def trans():
        user_profile = get_user_profile(app_user)
        changed_properties = []
        if user_profile.language != language:
            user_profile.language = language
            changed_properties.append(u"language")
            db.delete_async(get_broadcast_settings_flow_cache_keys_of_user(app_user))
        if user_profile.name != name:
            changed_properties.append(u"name")
        user_profile.name = name
        if image:
            _update_avatar(user_profile, image, False)
            changed_properties.append(u"avatar")
        user_profile.version += 1
        user_profile.put()

        update_mobiles(app_user, user_profile)  # update myIdentity
        update_friends(user_profile, changed_properties)  # notify my friends

        return user_profile

    user_profile = run_in_transaction(trans, xg=True)
    schedule_re_index(app_user)
    return user_profile
示例#14
0
def create_user_profile(app_user, name, language=None, ysaaa=False, owncloud_password=None, image=None,
                        tos_version=None, consent_push_notifications_shown=False):
    # type: (users.User, unicode, unicode, bool, unicode, unicode, int, bool) -> UserProfile
    name = _validate_name(name)

    def trans_create(avatar_image):
        azzert(not get_user_profile(app_user, cached=False))

        avatar, image = _create_new_avatar(app_user, False, avatar_image)

        user_profile = UserProfile(parent=parent_key(app_user), key_name=app_user.email())
        user_profile.name = name
        user_profile.language = language
        user_profile.avatarId = avatar.key().id()
        user_profile.app_id = get_app_id_from_app_user(app_user)
        user_profile.owncloud_password = owncloud_password
        if tos_version:
            user_profile.tos_version = tos_version
        if consent_push_notifications_shown:
            user_profile.consent_push_notifications_shown = True
        _calculateAndSetAvatarHash(user_profile, image)

        put_and_invalidate_cache(user_profile, ProfilePointer.create(app_user), ProfileHashIndex.create(app_user))

        return user_profile

    user_profile = run_in_transaction(trans_create, True, image)
    if not ysaaa:
        schedule_re_index(app_user)
    return user_profile
def finish_login_state(state, token):
    def trans():
        login_state = PaymentOauthLoginState.create_key(state).get()
        if not login_state:
            return False
        if login_state.completed:
            return False
        login_state.completed = True
        login_state.put()

        payment_user_key = get_payment_user_key(login_state.app_user)
        payment_user = payment_user_key.get()
        if not payment_user:
            payment_user = PaymentUser(key=payment_user_key)
            payment_user.providers = []
            payment_user.assets = []

        pup = payment_user.get_provider(login_state.provider_id)
        if pup:
            pup.token = token
        else:
            payment_user.providers.append(PaymentUserProvider(provider_id=login_state.provider_id, token=token))
        payment_user.put()

        deferred.defer(sync_payment_assets, login_state.app_user, login_state.provider_id, True, _transactional=True)

        return True
    return run_in_transaction(trans, True)
示例#16
0
def set_logo(service_user, image):
    logging.info('%s: Saving logo' % service_user.email())
    _meta, img_b64 = image.split(',')
    jpg_bytes = base64.b64decode(img_b64)

    def trans():
        logo = get_solution_logo(service_user) or SolutionLogo(
            key=SolutionLogo.create_key(service_user))
        logo.picture = db.Blob(jpg_bytes)
        logo.is_default = False

        settings = get_solution_settings(service_user)
        settings.updates_pending = True

        put_and_invalidate_cache(logo, settings)

        deferred.defer(_regenerate_branding_with_logo,
                       service_user,
                       _transactional=True)

        return settings

    common_settings = run_in_transaction(trans, xg=True)
    send_message(common_settings.service_user,
                 'solutions.common.settings.logo.updated')
    broadcast_updates_pending(common_settings)
示例#17
0
def _regenerate_branding_with_logo(service_user):
    users.set_user(service_user)
    logging.info(
        "%s: Replacing logo.png in the sln main branding zip with the uploaded logo"
        % service_user.email())

    logo = get_solution_logo(service_user)
    sln_main_branding = get_solution_main_branding(service_user)

    zip_content = replace_file_in_zip_blob(sln_main_branding.blob, "logo.jpg",
                                           str(logo.picture))

    def trans():
        sln_main_branding = get_solution_main_branding(service_user)
        sln_main_branding.blob = db.Blob(zip_content)
        sln_main_branding.branding_creation_time = 0

        common_settings = get_solution_settings(service_user)
        common_settings.updates_pending = True
        common_settings.events_branding_hash = None

        put_and_invalidate_cache(sln_main_branding, common_settings)
        return common_settings

    common_settings = run_in_transaction(trans, xg=True)
    broadcast_updates_pending(common_settings)
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)
示例#19
0
def set_avatar(service_user, image):
    logging.info('%s: Saving avatar' % service_user.email())
    _meta, img_b64 = image.split(',')
    jpg_bytes = base64.b64decode(img_b64)

    def trans():
        avatar_key = SolutionAvatar.create_key(service_user)
        avatar, branding_settings, sln_settings = db.get(
            (avatar_key, SolutionBrandingSettings.create_key(service_user),
             SolutionSettings.create_key(service_user)))
        avatar = avatar or SolutionAvatar(key=avatar_key)
        avatar.picture = db.Blob(jpg_bytes)
        avatar.published = False
        avatar.is_default = False

        to_put = [avatar, sln_settings]
        sln_settings.updates_pending = True
        if branding_settings:
            branding_settings.modification_time = now()
            to_put.append(branding_settings)

        put_and_invalidate_cache(*to_put)

        return sln_settings

    sln_settings = run_in_transaction(trans, xg=True)
    send_message(sln_settings.service_user,
                 'solutions.common.settings.avatar.updated')
    broadcast_updates_pending(sln_settings)
 def update_count(should_raise):
     def inner_trans(should_raise):
         transActionsCount = TransactionActionsCount.get(TransactionActionsCount.create_key())
         transActionsCount.count += 1
         if not raised[0] and should_raise:
             raised[0] = True
             raise TransactionFailedError()
         transActionsCount.put()
     return run_in_transaction(inner_trans, False, should_raise)
def _populate_new_editable_set(service_user):
    '''copy active content to editable service translation set'''

    def trans():
        puts = list()
        service_profile = get_service_profile(service_user)
        editable_translation_set_key = db.Key(encoded=service_profile.editableTranslationSet)
        active_translation_set_key = db.Key(encoded=service_profile.activeTranslationSet)
        active_translations = ServiceTranslation.all().ancestor(active_translation_set_key).fetch(None)
        for active_translation in active_translations:
            editable_translation = ServiceTranslation.create(editable_translation_set_key,
                                                             active_translation.translation_type,
                                                             active_translation.translation_dict)
            puts.append(editable_translation)
        db.put(puts)

    logging.debug("Copying active translation set into the new editable translation set")
    run_in_transaction(trans, xg=True)
def store_branding_zip(service_user, zip_, description, skip_meta_file=False):
    # type: (users.User, ZipFile, unicode) -> Branding
    try:
        pokes, html, branding_type, meta_properties = _parse_and_validate_branding_zip(zip_)

        # Remove previously added dimensions:
        html = re.sub("<meta\\s+property=\\\"rt:dimensions\\\"\\s+content=\\\"\\[\\d+,\\d+,\\d+,\\d+\\]\\\"\\s*/>", "",
                      html)

        try:
            zip_content = _create_new_zip(service_user, branding_type, zip_, html, skip_meta_file)
        except BadZipfile, e:
            raise BadBrandingZipException(reason=e.message)

        _validate_branding_size(zip_content, branding_type)

        hash_ = calculate_branding_hash(branding_type, zip_content)
        b = Branding.get_by_key_name(hash_)
        if b and b.user != service_user:
            raise BrandingAlreadyExistsException()

        def trans():
            return _create_branding(hash_, zip_content, description, service_user, branding_type, meta_properties,
                                    pokes)

        branding = run_in_transaction(trans, True)

        #
        # Try to add dimension information
        #

        if "</head>" in html:
            settings = get_server_settings()
            if not settings.brandingRendererUrl or branding_type in (Branding.TYPE_APP, Branding.TYPE_CORDOVA,):
                return branding

            if meta_properties.get('display-type', Branding.DISPLAY_TYPE_WEBVIEW) == Branding.DISPLAY_TYPE_NATIVE:
                return branding

            try:
                url = "%s?%s" % (settings.brandingRendererUrl, urllib.urlencode(
                    (('url', get_server_settings().baseUrl + '/branding/' + hash_ + '/branding.html?xrender=true'),)))
                response = urlfetch.fetch(url, deadline=10)
                if response.status_code != 200:
                    logging.error("Could not render branding to get dimensions.\n%s" % response.content)
                    return branding
            except:
                logging.warn("Failed to render dimensions")
                return branding

            html = html.replace("</head>",
                                '<meta property="rt:dimensions" content="' + response.content + '" /></head>')
        else:
            return branding

        zip_content = _create_new_zip(service_user, branding_type, zip_, html)
示例#23
0
def save_broadcast_types_order(service_user, broadcast_types):
    def trans():
        sln_settings = get_solution_settings(service_user)

        translated_broadcast_types = get_translated_broadcast_types(
            sln_settings)
        diff = set(translated_broadcast_types).symmetric_difference(
            broadcast_types)
        if diff:
            raise InvalidBroadcastTypeException(diff.pop())

        sln_settings.broadcast_types = [
            translated_broadcast_types[bt] for bt in broadcast_types
        ]
        sln_settings.updates_pending = True
        put_and_invalidate_cache(sln_settings)
        broadcast_updates_pending(sln_settings)

    run_in_transaction(trans, True)
示例#24
0
def put_loyalty_user_profile(email, app_id, user_code, short_url_id, language):
    app_user = create_app_user(users.User(email), app_id)
    name = _validate_name(email)

    def trans_create():
        rogerthat_profile = get_service_or_user_profile(users.User(email))
        if rogerthat_profile and isinstance(rogerthat_profile, ServiceProfile):
            from rogerthat.bizz.service import AppFailedToCreateUserProfileWithExistingServiceException
            raise AppFailedToCreateUserProfileWithExistingServiceException(email)

        user_profile = get_user_profile(app_user, cached=False)
        is_new_profile = False
        if not user_profile:
            deactivated_user_profile = get_deactivated_user_profile(app_user)
            if deactivated_user_profile:
                deferred.defer(reactivate_user_profile, deactivated_user_profile, app_user, _transactional=True)
                ActivationLog(timestamp=now(), email=app_user.email(), mobile=None,
                              description="Reactivate user account by registering a paper loyalty card").put()
            else:
                is_new_profile = True
                avatar, image = _create_new_avatar(app_user, add_trial_overlay=False)

                user_profile = UserProfile(parent=parent_key(app_user), key_name=app_user.email())
                user_profile.name = name
                user_profile.language = language
                user_profile.avatarId = avatar.key().id()
                user_profile.app_id = app_id
                _calculateAndSetAvatarHash(user_profile, image)

        pp = ProfilePointer(key=db.Key.from_path(ProfilePointer.kind(), user_code))
        pp.user = app_user
        pp.short_url_id = short_url_id

        if is_new_profile:
            put_and_invalidate_cache(user_profile, pp, ProfilePointer.create(app_user))
        else:
            pp.put()

    run_in_transaction(trans_create, True)
    schedule_re_index(app_user)

    return app_user
def update_translation_of_type(service_user, translation_type, translation_strings):
    """Update service translation of translation_type with new keys

    Args:
        service_user (users.User)
        translation_type (int): e.g. ServiceTranslation.MFLOW_TEXT
        translation_strings (dict):
    """
    def trans():
        editable_translation_set = get_editable_translation_set(service_user)
        should_create = not editable_translation_set
        if should_create:
            editable_translation_set = ServiceTranslationSet.create_editable_set(service_user)
            editable_translation_set.put()
        return should_create, editable_translation_set

    @run_after_transaction
    def update_service_profile(translation_set):
        def inner_trans():
            service_profile = get_service_profile(service_user)
            service_profile.editableTranslationSet = str(translation_set.key())
            service_profile.put()
        run_in_transaction(inner_trans)

    is_new_set, editable_translation_set = run_in_transaction(trans, xg=True)
    if is_new_set:
        update_service_profile(editable_translation_set)
    all_translations = get_all_translations(editable_translation_set)

    type_name = ServiceTranslation.TYPE_MAP[translation_type]
    logging.info('Merging %s translations into the service translations', type_name)
    logging.debug('New %s translation keys: %s', type_name, translation_strings)
    logging.debug('Existing translations: %s', all_translations)

    translations_dict = all_translations.setdefault(translation_type, dict())

    updated = False
    for default_string in translation_strings:
        if default_string not in translations_dict:
            translations_dict[default_string] = None
            updated = True

    if updated:
        logging.debug('Updated translations: %s', all_translations)
        save_translations(editable_translation_set, all_translations)

    # convert "pt-br" keys to "pt_BR" before returning
    for translations in translations_dict.itervalues():
        if translations:
            for lang in translations.keys():
                translations[get_iso_lang(lang)] = translations.pop(lang)

    return translations_dict, updated
示例#26
0
def update_service_profile(service_user, image, add_trial_overlay):
    from rogerthat.bizz.job.update_friends import schedule_update_all_friends_of_service_user

    def trans():
        service_profile = get_service_profile(service_user)
        if image:
            _update_avatar(service_profile, image, add_trial_overlay)
        service_profile.version += 1
        service_profile.put()

        schedule_update_all_friends_of_service_user(service_profile)
    return run_in_transaction(trans, True)
def deploy_translation(service_user):

    def trans():
        to_put = set()

        service_profile = get_service_profile(service_user)
        if not service_profile.editableTranslationSet:
            logging.error("Deploy translation error - no editable translation found for svc %s" % service_user.email())
            return

        # 1. Archive old active translation set
        if service_profile.activeTranslationSet:
            old_active_translation_set = ServiceTranslationSet.get(service_profile.activeTranslationSet)
            old_active_translation_set.status = ServiceTranslationSet.ARCHIVED
            to_put.add(old_active_translation_set)

        # 2. Promote old editable translation set to new active
        service_profile.activeTranslationSet = service_profile.editableTranslationSet
        to_put.add(service_profile)
        new_active_translation_set = ServiceTranslationSet.get(service_profile.activeTranslationSet)
        new_active_translation_set.status = ServiceTranslationSet.ACTIVE
        to_put.add(new_active_translation_set)

        # 3. Create new editable translation set
        new_editable_translation_set = ServiceTranslationSet.create_editable_set(service_user)
        new_editable_translation_set.latest_export_timestamp = new_active_translation_set.latest_export_timestamp
        service_profile.editableTranslationSet = str(new_editable_translation_set.key())
        to_put.add(new_editable_translation_set)

        # 4. Copy existing translations to new
        branding_translations_dict = None
        for tr in ServiceTranslation.all().ancestor(new_active_translation_set).fetch(None):
            translation_dict = tr.translation_dict
            if tr.translation_type == ServiceTranslation.BRANDING_CONTENT:
                branding_translations_dict = translation_dict
            to_put.add(ServiceTranslation.create(new_editable_translation_set, tr.translation_type, translation_dict))

        # 5. Store all in db
        put_and_invalidate_cache(*to_put)

        return service_profile, branding_translations_dict

    service_profile, branding_translations_dict = run_in_transaction(trans, xg=True)

    if len(service_profile.supportedLanguages) > 1:
        if branding_translations_dict:
            deferred.defer(_translate_all_app_brandings, service_user, Branding.TYPE_APP, branding_translations_dict)
            deferred.defer(_translate_all_app_brandings, service_user,
                           Branding.TYPE_CORDOVA, branding_translations_dict)
        deferred.defer(_translate_all_message_flows, service_user)
        deferred.defer(_update_i18n_search_configs, service_user)
    deferred.defer(_populate_new_editable_set, service_user)
示例#28
0
    def test_change_order_to_free(self):
        self.set_datastore_hr_probability(1)
        products_to_order = [(u'MSUP', 12),  # monthly subscription, $50.00
                             (u'KSUP', 12),  # subscription discount, -$15.00
                             (Product.PRODUCT_EXTRA_CITY, 12),  # extra city, $5.00
                             (Product.PRODUCT_EXTRA_CITY, 12),  # extra city, $5.00
                             (Product.PRODUCT_EXTRA_CITY, 12)]  # extra city, $5.00
        old_subscription_order, customer = self._create_customer_and_subscription_order(products_to_order)
        old_subscription_order.next_charge_date -= 12 * 31 * 86400  # Turn back next_charge_date more than 12 months
        old_subscription_order.put()

        self._create_service(customer, [u'be-loc', u'be-berlare', u'be-beveren', u'es-madrid',
                                        App.APP_ID_ROGERTHAT, App.APP_ID_OSA_LOYALTY])

        # Creating some random order with a discount to be sure this discount isn't applied in recurrent billing job
        self._create_order(customer, old_subscription_order.contact_id, self._create_items(customer, [(u'KLUP', 1),
                                                                                                      (u'LSUP', 1)]))

        products_to_order = [(Product.PRODUCT_FREE_SUBSCRIPTION, 1),
                             (Product.PRODUCT_EXTRA_CITY, 1),  # extra city, $5.00
                             (Product.PRODUCT_EXTRA_CITY, 1),  # extra city, $5.00
                             (Product.PRODUCT_EXTRA_CITY, 1)]  # extra city, $5.00
        order_items = self._create_items(customer, products_to_order)
        new_subscription_order, customer = self._create_order(customer, old_subscription_order.contact_id, order_items,
                                                              replace=True)
        new_subscription_order.next_charge_date -= 12 * 31 * 86400  # Turn back next_charge_date more than 12 months
        new_subscription_order.put()

        # Execute recurrent billing code
        products = Product.get_products_dict()
        charge = _create_charge(new_subscription_order.key(), now(), products)
        self.assertIsNotNone(charge)
        expected_charge_amount = 3 * products[Product.PRODUCT_EXTRA_CITY].price  # 3x $5.00
        self.assertEqual(expected_charge_amount, charge.amount)

        def trans_invoice_number():
            return InvoiceNumber.next(get_mobicage_legal_entity())

        invoice_number = run_in_transaction(trans_invoice_number)
        create_invoice(customer.id, new_subscription_order.order_number, charge.id, invoice_number,
                       new_subscription_order.manager, payment_type=Invoice.PAYMENT_ON_SITE)

        dt = datetime.datetime.utcnow()
        invoices = export_invoices(dt.year, dt.month)
        self.assertEqual(1, len(invoices))
        self.assertEqual(len(products_to_order), len(invoices[0]['order_items']))

        order_items_cost = sum(order_item['price'] * order_item['count']
                               for order_item in invoices[0]['order_items'])
        self.assertEqual(expected_charge_amount, order_items_cost)
def hookup(app_user, acs, service_helper):
    # type: (users.User, AutoConnectedService, FriendCloudStorageHelper) -> None
    def trans():
        user_profile = get_user_profile(app_user)
        if user_profile.isCreatedForService:
            return

        ui = get_user_interaction(app_user)
        if acs.service_identity_email not in ui.services:
            service_identity_user = users.User(acs.service_identity_email)
            do_make_friends = True
            if acs.service_roles:
                do_make_friends = False
                # is app_user in one of the roles?
                service_user, si_id = get_service_identity_tuple(service_identity_user)
                synced_roles = list()
                for service_role in get_service_roles_by_ids(service_user, acs.service_roles):
                    if user_profile.has_role(service_identity_user, u'%s' % service_role.role_id):
                        do_make_friends = True
                        break
                    elif service_role.type == ServiceRole.TYPE_SYNCED:
                        synced_roles.append(service_role)
                else:
                    # for loop did not reach BREAK: user_profile does not have any role --> send friend.is_in_roles
                    user_details = [UserDetailsTO.fromUserProfile(user_profile)]
                    send_is_in_roles(app_user, get_service_profile(service_user), si_id, user_details,
                                     map(RoleTO.fromServiceRole, synced_roles), make_friends_if_in_role=True)

            if do_make_friends:
                ui.services.append(acs.service_identity_email)
                ui.put()
                logging.info("Connecting %s with auto-connected service %s", app_user, acs.service_identity_email)
                deferred.defer(makeFriends, service_identity_user, app_user, app_user, None,
                               notify_invitee=False, origin=ORIGIN_USER_INVITE, service_helper=service_helper,
                               _transactional=True, _queue=HIGH_LOAD_WORKER_QUEUE)

    run_in_transaction(trans, True)
示例#30
0
def _delete_static_content(service_user, static_content_id):
    sln_settings, sc = db.get(
        (SolutionSettings.create_key(service_user),
         SolutionStaticContent.create_key(service_user, static_content_id)))

    def trans():
        sc.provisioned = False
        sc.deleted = True
        sln_settings.updates_pending = True
        db.put([sln_settings, sc])
        return sln_settings

    sln_settings = run_in_transaction(trans, True)
    send_message(service_user, u"solutions.common.service_menu.updated")
    broadcast_updates_pending(sln_settings)
示例#31
0
def store_branding_zip(service_user, zip_, description):
    try:
        pokes, html, contains_app_html, meta_properties = _parse_and_validate_branding_zip(zip_)

        # Remove previously added dimensions:
        html = re.sub("<meta\\s+property=\\\"rt:dimensions\\\"\\s+content=\\\"\\[\\d+,\\d+,\\d+,\\d+\\]\\\"\\s*/>", "", html)

        try:
            zip_content, type_ = _create_new_zip(service_user, zip_, html)
        except BadZipfile, e:
            raise BadBrandingZipException(reason=e.message)

        _validate_branding_size(zip_content, type_)

        hash_ = hashlib.sha256(zip_content).hexdigest().upper()
        b = Branding.get_by_key_name(hash_)
        if b and b.user != service_user:
            raise BrandingAlreadyExistsException()

        def trans():
            return _create_branding(hash_, zip_content, description, service_user, contains_app_html, meta_properties, pokes)
        branding = run_in_transaction(trans, True)

        #
        # Try to add dimension information
        #

        if "</head>" in html:
            settings = get_server_settings()
            if not settings.brandingRendererUrl or not type_ == TYPE_BRANDING:
                return branding

            try:
                url = "%s?%s" % (settings.brandingRendererUrl, urllib.urlencode((('url', get_server_settings().baseUrl + '/branding/' + hash_ + '/branding.html?xrender=true'),)))
                response = urlfetch.fetch(url, deadline=10)
                if response.status_code != 200:
                    logging.error("Could not render branding to get dimensions.\n%s" % response.content)
                    return branding
            except:
                logging.exception("Failed to render dimensions")
                return branding

            html = html.replace("</head>", '<meta property="rt:dimensions" content="' + response.content + '" /></head>')
        else:
            return branding

        zip_content, _ = _create_new_zip(service_user, zip_, html)
def revoke_role(service_identity_user, user, role):
    admin = False
    service_identity = get_service_identity(service_identity_user)
    if not service_identity:
        raise ServiceIdentityDoesNotExistException(get_identity_from_service_identity_user(service_identity_user))
    if isinstance(role, unicode):
        admin = True
        azzert(role in ROLES)  # builtin
        role_str = role
    else:
        azzert(role.service_user == service_identity.service_user)
        role_str = u'%s' % role.role_id

    def trans():
        new_look_and_feel = None
        new_look_and_feel_id = None
        look_n_feel_changed = False
        user_profile = get_user_profile(user, False)
        user_profile.revoke_role(service_identity_user, role_str)
        if not admin and user_profile.look_and_feel_id:
            look_and_feel = AppLookAndFeel.get_by_id(user_profile.look_and_feel_id)
            for role_mapping in look_and_feel.roles:  # type: LookAndFeelServiceRoles
                if role.role_id in role_mapping.role_ids:
                    new_look_and_feel = get_look_and_feel_for_user(user_profile, ignore_role=role.role_id)
                    if new_look_and_feel:
                        new_look_and_feel_id = new_look_and_feel.key.id()
                    break

        if user_profile.look_and_feel_id:
            if not new_look_and_feel_id or user_profile.look_and_feel_id != new_look_and_feel_id:
                look_n_feel_changed = True

        user_profile.look_and_feel_id = new_look_and_feel_id
        user_profile.put()
        return new_look_and_feel, look_n_feel_changed

    new_look_n_feel, look_n_feel_changed = run_in_transaction(trans)

    if admin:
        deferred.defer(drop_sessions_of_user, user)
        _send_admin_role_updates(service_identity_user)

    if look_n_feel_changed:
        send_look_and_feel_update(user, new_look_n_feel)
    def serialize(cls, user, friend_type):
        # type: (users.User, int) -> FriendCloudStorageHelper
        if friend_type == FriendTO.TYPE_SERVICE:
            assert '/' in user.email()
        datastore_helper = FriendHelper.from_data_store(user, friend_type)

        def trans():
            data = {}
            flow_keys = []
            for method in ('get_service_profile', 'get_profile_info', 'list_service_menu_items', 'list_roles',
                           'get_share_sid', '_get_all_translations', 'get_service_data', 'get_brandings'):
                logging.debug('Serializing result of %s', method)
                f = getattr(datastore_helper, method)
                obj = f()
                if obj:
                    if isinstance(obj, dict) or not isinstance(obj, collections.Iterable):
                        data[method] = obj
                    else:
                        is_menu_items_method = method == 'list_service_menu_items'
                        for i, model in enumerate(obj):
                            data['%s-%s' % (method, i)] = model
                            if is_menu_items_method and model.staticFlowKey:
                                flow_keys.append(model.staticFlowKey)
            if flow_keys:
                flows = db.get(flow_keys)
                for flow in flows:
                    data['flow-%s' % flow.key()] = flow

            return data

        # TODO: Change xg to False once ServiceTranslationSet uses same parent key as other service data
        data = run_in_transaction(trans, xg=True)
        with closing(StringIO.StringIO()) as stream:
            s_any(stream, data)
            serialized_value = stream.getvalue()
        serialized_length = len(serialized_value)
        logging.info('Size of serialized FriendHelper for %s: %d', user, serialized_length)
        cloud_storage_path = FriendCloudStorageHelper.create_cloudstorage_path(user.email())
        with cloudstorage.open(cloud_storage_path, 'w') as f:
            f.write(serialized_value)
        datastore_helper.add_to_memcache(cloud_storage_path, serialized_value)
        return FriendCloudStorageHelper.from_cloud_storage(user, friend_type, cloud_storage_path)
示例#34
0
def update_service_profile(service_user, tmp_avatar_key, x1, y1, x2, y2, add_trial_overlay, organization_type=None):
    if not tmp_avatar_key and organization_type is None:
        logging.info("No tmp_avatar_key. Service user pressed save without changing his avatar.")
        return get_service_profile(service_user)

    def trans():
        service_profile = get_service_profile(service_user)
        if tmp_avatar_key:
            _update_avatar(service_profile, tmp_avatar_key, x1, y1, x2, y2, add_trial_overlay)
        if organization_type is not None:
            service_profile.organizationType = organization_type
        service_profile.version += 1
        service_profile.put()

        from rogerthat.bizz.job.update_friends import schedule_update_all_friends_of_service_user
        schedule_update_all_friends_of_service_user(service_profile)

        return service_profile

    return run_in_transaction(trans, True)
示例#35
0
def update_user_profile(app_user, name, tmp_avatar_key, x1, y1, x2, y2, language):
    def trans():
        user_profile = get_user_profile(app_user)
        if user_profile.language != language:
            user_profile.language = language
            db.delete_async(get_broadcast_settings_flow_cache_keys_of_user(app_user))
        user_profile.name = name
        if tmp_avatar_key:
            _update_avatar(user_profile, tmp_avatar_key, x1, y1, x2, y2, add_trial_overlay=False)
        user_profile.version += 1
        user_profile.put()

        update_mobiles(app_user, user_profile)  # update myIdentity
        update_friends(user_profile)  # notify my friends

        return user_profile

    user_profile = run_in_transaction(trans, xg=True)
    schedule_re_index(app_user)
    return user_profile
def remove_regio_manager(manager_email):
    logging.info('Removing regional manager %s', manager_email)
    bizz_check(
        manager_email != STORE_MANAGER,
        'Deleting the <Customer shop> regional manager is not allowed.')
    task_list = ShopTask.group_by_assignees([manager_email])
    task_count = len(task_list[manager_email])
    bizz_check(
        task_count == 0,
        'There are still %s tasks assigned to this regional manager' %
        task_count)

    def trans():
        manager_key = RegioManager.create_key(manager_email)
        manager = RegioManager.get(manager_key)
        if not manager.team_id:
            raise BusinessException(
                'Cannot delete regional manager that has no team.')
        team = manager.team
        if not team.support_manager:
            raise BusinessException(
                'Cannot delete regional manager: Team \'%s\' has no support manager'
                % team.name)
        if team.support_manager == manager_email:
            raise BusinessException(
                'You cannot delete the support manager of a team.'
                ' Assign this role to a different regional manager first.')
        team.regio_managers.remove(manager_email)
        db.delete(
            [manager_key,
             RegioManagerStatistic.create_key(manager_email)])
        team.put()
        return team

    team = run_in_transaction(trans, xg=True)
    deferred.defer(_unassign_prospects, manager_email)
    deferred.defer(_change_charges_manager, manager_email,
                   team.support_manager)
    deferred.defer(_change_orders_manager, manager_email, team.support_manager)
    deferred.defer(_change_customers_manager, manager_email)
示例#37
0
def create_user_profile(app_user, name, language=None, ysaaa=False):
    name = _validate_name(name)

    def trans_create():
        azzert(not get_user_profile(app_user, cached=False))

        avatar, image = _create_new_avatar(app_user, add_trial_overlay=False)

        user_profile = UserProfile(parent=parent_key(app_user), key_name=app_user.email())
        user_profile.name = name
        user_profile.language = language
        user_profile.avatarId = avatar.key().id()
        user_profile.app_id = get_app_id_from_app_user(app_user)
        _calculateAndSetAvatarHash(user_profile, image)

        put_and_invalidate_cache(user_profile, ProfilePointer.create(app_user), ProfileHashIndex.create(app_user))

        return user_profile

    user_profile = run_in_transaction(trans_create, True)
    if not ysaaa:
        schedule_re_index(app_user)
    return user_profile
示例#38
0
def store_app_qr_template(app_id, data):
    """
    Args:
        app_id (unicode)
        data (rogerthat.to.app.CreateAppQRTemplateTO)
    """

    from rogerthat.bizz.app import get_app

    def trans():
        app = get_app(app_id)
        picture = base64.b64decode(data.file)
        key_name = QRTemplate.create_key_name(app_id, data.description)
        template = store_template(None, picture, data.description, data.body_color, key_name)
        if data.is_default:
            app.qrtemplate_keys.insert(0, key_name)
        else:
            app.qrtemplate_keys.append(template.key().name())
        app.put()
        return template

    template = run_in_transaction(trans, xg=True)
    return template, data.is_default
def grant_roles(service_identity_user, user, roles):
    service_identity = get_service_identity(service_identity_user)
    if not service_identity:
        raise ServiceIdentityDoesNotExistException(get_identity_from_service_identity_user(service_identity_user))

    admin = False
    role_ids = []
    for role in roles:
        if isinstance(role, unicode):
            admin = True
            azzert(role in ROLES)  # builtin
            role_ids.append(role)
        else:
            azzert(role.service_user == service_identity.service_user)
            role_ids.append(u'%s' % role.role_id)

    def trans():
        look_and_feel = None
        user_profile = get_user_profile(user, False)
        bizz_check(user_profile, 'User %s does not exist' % user.email())
        for role_id in role_ids:
            user_profile.grant_role(service_identity_user, role_id)
        if not user_profile.look_and_feel_id:
            look_n_feel = get_look_and_feel_for_user(user_profile)
            if look_n_feel:
                user_profile.look_and_feel_id = look_n_feel.id
                look_and_feel = look_n_feel
        user_profile.put()
        return look_and_feel

    look_n_feel = run_in_transaction(trans)

    if admin:
        _send_admin_role_updates(service_identity_user)
    if look_n_feel:
        send_look_and_feel_update(user, look_n_feel)
示例#40
0
def _order_received(service_user, message_flow_run_id, member, steps, end_id,
                    end_message_flow_id, parent_message_key, tag, result_key,
                    flush_id, flush_message_flow_id, service_identity,
                    user_details):

    from solutions.common.bizz.messaging import send_inbox_forwarders_message
    for step in steps:
        if step.step_id == u'message_advanced_order':
            order_type = ORDER_TYPE_ADVANCED
            break
    else:
        order_type = ORDER_TYPE_SIMPLE

    def get_extended_details_from_tag(details):
        if tag and tag.startswith('{') and tag.endswith('}'):
            try:
                new_details = u""
                tag_dict = json.loads(tag)
                for k, v in tag_dict.iteritems():
                    if not k.startswith("_"):
                        if new_details:
                            new_details = u"%s\n%s: %s" % (new_details, k, v)
                        else:
                            new_details = u"%s: %s" % (k, v)

                if new_details:
                    return u"%s\n%s" % (new_details, details)
            except:
                pass

        return details

    def trans():
        sln_settings = get_solution_settings(service_user)
        order_settings = get_solution_order_settings(sln_settings)
        lang = sln_settings.main_language
        comment = None
        phone = None
        takeaway_time = None
        if order_type == ORDER_TYPE_SIMPLE:
            details = get_extended_details_from_tag(
                _get_value(steps[0], u'message_details'))
            if steps[1].answer_id == u"positive":
                picture_url = _get_value(steps[1], u'message_picture')
                att = AttachmentTO()
                att.content_type = AttachmentTO.CONTENT_TYPE_IMG_JPG
                att.download_url = picture_url
                att.name = translate(lang, SOLUTION_COMMON, u'picture')
                att.size = 0
                attachments = [att]
            else:
                picture_url = None
                attachments = []
            phone = _get_value(steps[2], u'message_phone')
            msg = common_translate(lang, SOLUTION_COMMON,
                                   'if-order-received') % {
                                       'remarks': details,
                                       'phone_number': phone
                                   }

        elif order_type == ORDER_TYPE_ADVANCED:
            with closing(StringIO()) as order:
                timezone_offset = datetime.datetime.now(
                    pytz.timezone(
                        sln_settings.timezone)).utcoffset().total_seconds()
                has_order_items = False
                for step in steps:
                    if step.step_id == u'message_phone':
                        phone = step.get_value()
                    elif step.step_id == u'message_comment':
                        comment = step.get_value()
                    elif step.step_id == u'message_advanced_order':
                        step_value = step.display_value.encode('utf-8')
                        if step_value:
                            has_order_items = True
                        order.write(step_value)
                    elif step.step_id == u'message_takeaway_time':
                        takeaway_time = int(step.get_value() - timezone_offset)
                picture_url = None
                attachments = []
                if comment:
                    if has_order_items:
                        order.write('\n\n')
                    c = '%s: %s' % (common_translate(
                        lang, SOLUTION_COMMON, 'reservation-comment'), comment)
                    order.write(
                        c.encode('utf-8') if isinstance(c, unicode) else c)
                details = get_extended_details_from_tag(
                    order.getvalue().decode('utf-8'))
                takeaway_datetime = datetime.datetime.fromtimestamp(
                    takeaway_time, tz=get_timezone(sln_settings.timezone))
                takeaway_time_str = format_datetime(takeaway_datetime,
                                                    locale=lang,
                                                    format='d/M/yyyy H:mm')

                msg = '%s:\n%s\n%s: %s\n%s: %s' % (
                    common_translate(lang, SOLUTION_COMMON,
                                     'order_received'), details,
                    common_translate(lang, SOLUTION_COMMON,
                                     'phone_number'), phone,
                    common_translate(lang, SOLUTION_COMMON,
                                     'takeaway_time'), takeaway_time_str)
        else:
            raise BusinessException('Unsupported order type %s', order_type)

        if not order_settings.manual_confirmation:
            # Waiting for follow-up message
            deferred.defer(_send_order_confirmation,
                           service_user,
                           lang,
                           message_flow_run_id,
                           member,
                           steps,
                           end_id,
                           end_message_flow_id,
                           parent_message_key,
                           tag,
                           result_key,
                           flush_id,
                           flush_message_flow_id,
                           service_identity,
                           user_details,
                           details,
                           _transactional=db.is_in_transaction())

        service_identity_user = create_service_identity_user_wo_default(
            service_user, service_identity)
        o = SolutionOrder(
            parent=parent_key_unsafe(service_identity_user, SOLUTION_COMMON))
        o.description = details
        o.phone_number = phone
        o.sender = SolutionUser.fromTO(user_details[0])
        o.timestamp = now()
        o.status = SolutionOrder.STATUS_RECEIVED
        o.picture_url = picture_url
        o.takeaway_time = takeaway_time
        o.user = user_details[0].toAppUser() if user_details else None

        message = create_solution_inbox_message(
            service_user, service_identity,
            SolutionInboxMessage.CATEGORY_ORDER, None, False, user_details,
            steps[2].received_timestamp, msg, True,
            [picture_url] if picture_url else [])
        o.solution_inbox_message_key = message.solution_inbox_message_key
        o.put()
        message.category_key = unicode(o.key())
        message.put()

        sln_i_settings = get_solution_settings_or_identity_settings(
            sln_settings, service_identity)
        sm_data = [{
            u"type": u"solutions.common.orders.update"
        }, {
            u"type":
            u"solutions.common.messaging.update",
            u"message":
            serialize_complex_value(
                SolutionInboxMessageTO.fromModel(message, sln_settings,
                                                 sln_i_settings, True),
                SolutionInboxMessageTO, False)
        }]
        send_message(service_user, sm_data, service_identity=service_identity)

        app_user = user_details[0].toAppUser()

        send_inbox_forwarders_message(
            service_user,
            service_identity,
            app_user,
            msg,
            dict(if_name=user_details[0].name, if_email=user_details[0].email),
            message_key=message.solution_inbox_message_key,
            attachments=attachments,
            reply_enabled=message.reply_enabled)

    run_in_transaction(trans, xg=True)
示例#41
0
def put_static_content(service_user, static_content):
    try:
        if static_content.sc_type == SolutionStaticContent.TYPE_OWN:
            branding_hash = store_static_content_branding(
                service_user, static_content.background_color,
                static_content.text_color, static_content.html_content,
                static_content.icon_label)
        elif static_content.sc_type != SolutionStaticContent.TYPE_WEBSITE:
            raise BusinessException('Invalid static content type')
        else:
            branding_hash = None
    except BrandingValidationException:
        raise
    except ServiceApiException:
        logging.exception('Failed to store static content branding',
                          exc_info=True)
        raise BusinessException(
            translate(
                get_solution_settings(service_user).main_language,
                SOLUTION_COMMON, 'error-occured-unknown-try-again'))

    def trans():
        sln_settings = get_solution_settings(service_user)
        new_coords = map(int, [
            static_content.position.x, static_content.position.y,
            static_content.position.z
        ])
        if static_content.id is MISSING or static_content.id is None:
            sc = SolutionStaticContent(parent=parent_key(
                service_user, SOLUTION_COMMON),
                                       deleted=False)
            sc.old_coords = new_coords
        else:
            sc = SolutionStaticContent.get(
                SolutionStaticContent.create_key(service_user,
                                                 static_content.id))
            if sc.old_coords != new_coords and sc.provisioned:
                sc.old_coords = sc.coords
        sc.icon_label = static_content.icon_label
        sc.icon_name = static_content.icon_name
        if static_content.sc_type == SolutionStaticContent.TYPE_OWN:
            sc.text_color = static_content.text_color
            sc.background_color = static_content.background_color
            sc.html_content = static_content.html_content
            sc.branding_hash = branding_hash
        elif static_content.sc_type == SolutionStaticContent.TYPE_WEBSITE:
            sc.website = static_content.website
        sc.sc_type = static_content.sc_type
        sc.visible = static_content.visible
        sc.provisioned = False
        sc.coords = new_coords
        sc.put()

        sln_settings.updates_pending = True
        put_and_invalidate_cache(sc, sln_settings)
        return sln_settings

    sln_settings = run_in_transaction(trans, True)

    send_message(service_user, u"solutions.common.service_menu.updated")
    broadcast_updates_pending(sln_settings)