예제 #1
0
def rest_get_news_promoted_count(app_ids):
    service_user = users.get_current_user()
    session_ = users.get_current_session()
    service_identity = session_.service_identity
    if is_default_service_identity(service_identity):
        service_identity_user = create_service_identity_user(service_user)
    else:
        service_identity_user = create_service_identity_user(
            service_user, service_identity)
    return get_sponsored_news_count(service_identity_user, app_ids)
예제 #2
0
    def get(self):
        customer_id = int(self.request.get("customer_id"))
        try:
            customer = Customer.get_by_id(customer_id)
        except CustomerNotFoundException:
            self.abort(404)

        current_user = users.get_current_user()
        current_customer = get_customer(current_user)
        sln_settings = get_solution_settings(current_user)
        if not sln_settings.can_edit_services(
                current_customer) or not current_customer.can_edit_service(
                    customer):
            logging.warn(
                'Service or user %s is trying to login to the dashboard of %s',
                current_user.email(), customer.name)
            self.abort(401)

        service_identity_user = create_service_identity_user(
            users.User(customer.service_email))
        current_session = users.get_current_session()
        new_secret, new_session = create_session(service_identity_user,
                                                 ignore_expiration=True)
        set_cookie(self.response,
                   get_server_settings().cookieSessionName, new_secret)
        new_session = switch_to_service_identity(new_session,
                                                 service_identity_user,
                                                 read_only=False,
                                                 shop=current_session.shop,
                                                 layout_only=True)
        new_session.parent_session_secret = current_session.secret
        new_session.put()
        self.redirect("/")
예제 #3
0
def solution_remind_event(service_user, email, method, params, tag,
                          service_identity, user_details):
    settings = get_solution_settings(service_user)
    jsondata = json.loads(params)

    app_user = create_app_user_by_email(email, user_details[0].app_id)
    event_id = long(jsondata['eventId'])
    remind_before = int(jsondata['remindBefore'])
    if jsondata.get("eventStartEpoch", None):
        event_start_epoch = int(jsondata['eventStartEpoch'])
    else:
        event_start_epoch = get_event_by_id(service_user, settings.solution,
                                            event_id).start_dates[0]

    r = SendApiCallCallbackResultTO()
    if is_reminder_set(app_user, event_id, event_start_epoch,
                       remind_before) is False:
        er = EventReminder()
        er.service_identity_user = create_service_identity_user(
            users.get_current_user(), service_identity)
        er.human_user = app_user
        er.remind_before = remind_before
        er.event_id = event_id
        er.event_start_epoch = event_start_epoch
        er.put()
        r.result = u"successfully reminded"
    else:
        r.result = u"already reminded"
    r.error = None
    return r
예제 #4
0
    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)
예제 #5
0
    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.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)

        return profile, service_identity, update_result
예제 #6
0
    def post(self):
        uuid = self.request.get('uuid')
        major = self.request.get('major')
        minor = self.request.get('minor')
        tag = self.request.get('tag')
        service = self.request.get('service')
        identity = self.request.get('identity')

        if not (uuid and major and minor and service and identity):
            return self.redirect(result='Please supply all parameters.')

        logging.info("New beacon added uuid: %s major: %s minor: %s for: %s/%s" % (uuid, major, minor, service, identity))
        try:
            service_user = users.User(service)
            service_identity_user = create_service_identity_user(service_user, identity)
            si = get_service_identity(service_identity_user)
            if not si:
                self.redirect(result='Service not found.')
                return
            name = "%s|%s" % (major, minor)

            added = add_new_beacon(uuid, name, tag, service_identity_user)
            if added:
                self.redirect(result='Added beacon with name: %s for: %s' % (name, service_identity_user))
            else:
                self.redirect(result='Beacon already exists: %s for: %s' % (name, service_identity_user))
        except Exception, e:
            logging.warn(str(e), exc_info=1)
            self.redirect(result=str(e))
def _build_job(job_guid, cursor):
    job = db.get(RebuildRolesJob.create_key(job_guid))
    start = time.time()
    qry = get_all_service_friend_keys_query(create_service_identity_user(job.service_user))
    while True:
        qry.with_cursor(cursor)
        fsic_keys = qry.fetch(100)
        cursor = qry.cursor()
        logging.debug("Fetched %s FriendServiceIdentityConnection keys", len(fsic_keys))
        if not fsic_keys:  # Query reached its end
            deferred.defer(_start_job, job_guid, _queue=HIGH_LOAD_CONTROLLER_QUEUE)
            return
        work = list()
        for fsic_key in fsic_keys:
            app_user = users.User(fsic_key.parent().name())
            if job.app_users and not app_user in job.app_users:
                continue
            service_identity_user = users.User(fsic_key.name())
            if job.service_identity_users and not service_identity_user in job.service_identity_users:
                continue
            work.append(RebuildRolesJobMember(
                key=RebuildRolesJobMember.create_key(job, app_user, service_identity_user)))
        db.put(work)
        if time.time() - start > 500:
            deferred.defer(_build_job, job_guid, cursor, _queue=HIGH_LOAD_CONTROLLER_QUEUE)
            return
def get_service_identity_details(identifier):
    azzert(identifier)
    service_user = users.get_current_user()
    service_identity_user = create_service_identity_user(service_user, identifier)
    service_identity = get_service_identity_not_cached(service_identity_user)
    service_profile = get_service_profile(service_user, cached=False)
    return ServiceIdentityDetailsTO.fromServiceIdentity(service_identity, service_profile)
예제 #9
0
def new_inbox_message(sln_settings,
                      message,
                      parent_chat_key=None,
                      service_identity=None,
                      **kwargs):
    service_identity = service_identity or ServiceIdentity.DEFAULT
    service_user = sln_settings.service_user
    language = sln_settings.main_language
    si = get_service_identity(
        create_service_identity_user(service_user, service_identity))
    user_details = UserDetailsTO.create(service_user.email(), si.name,
                                        language, si.avatarUrl, si.app_id)

    if not parent_chat_key:
        category = kwargs.get('category')
        category_key = kwargs.get('category_key')
        reply_enabled = kwargs.get('reply_enabled', False)
        message = create_solution_inbox_message(service_user, service_identity,
                                                category, category_key, True,
                                                [user_details], now(), message,
                                                reply_enabled)
    else:
        message, _ = add_solution_inbox_message(service_user, parent_chat_key,
                                                False, [user_details], now(),
                                                message, **kwargs)
    return message
예제 #10
0
def _5000_migrate_non_ancestor_models(job_key):
    phase = MigrateServiceJob.PHASE_5000_MIGRATE_NON_ANCESTOR_MODELS
    next_phase = MigrateServiceJob.PHASE_6000_MIGRATE_ANCESTOR_MODELS

    # Validate that the job still exists
    job = _get_job(job_key, phase)

    # Do the work
    _log_progress(job)

    models = list()
    logging.debug("1/ Collecting TrialServiceAccounts")
    for model in TrialServiceAccount.all().filter("service", job.from_service_user):
        model.service = job.to_service_user
        models.append(model)

    logging.info("2/ Collecting MessageFlowRunRecords")
    for model in MessageFlowRunRecord.all().filter("service_identity >=", job.from_service_user.email() + '/').filter("service_identity <", job.from_service_user.email() + u"/\ufffd"):
        identity = get_identity_from_service_identity_user(users.User(model.service_identity))
        model.service_identity = create_service_identity_user(job.to_service_user, identity).email()
        models.append(model)

    logging.info("3/ Collecting Avatar, Branding, SIKKey, APIKey")
    for model_class in (Avatar, Branding, SIKKey, APIKey):
        for model in model_class.all().filter("user", job.from_service_user):
            model.user = job.to_service_user
            models.append(model)

    logging.info('Putting %s non-ancestor models', len(models))
    _put_and_invalidate_cache_and_allocate_ids(*models)

    # Set the next phase
    _set_job_in_next_phase(job_key, phase, next_phase)
예제 #11
0
def has_role(service_identity, user, role):
    if isinstance(service_identity, users.User):
        service_identity_user = service_identity
        service_identity = get_service_identity(service_identity_user)
        azzert(service_identity, "Service identity %s not found" % service_identity_user)
    else:
        service_identity_user = service_identity.service_identity_user

    if isinstance(user, users.User):
        user_profile = get_user_profile(user, True)
    else:
        user_profile = user
        user = user_profile.user

    if isinstance(role, unicode):
        # Admin role, just fallback on UserProfile.has_role
        return user_profile.has_role(service_identity_user, role)

    azzert(role.service_user == service_identity.service_user)
    role = u'sr:%s' % role.role_id
    # check on the service identity itself
    if user_profile.has_role(service_identity_user, role):
        return True
    if service_identity.is_default:
        return False
    # check on the default service identity
    return user_profile.has_role(create_service_identity_user(service_identity.service_user, ServiceIdentity.DEFAULT),
                                 role)
예제 #12
0
 def get(self):
     service_user = users.get_current_user()
     session_ = users.get_current_session()
     service_identity = session_.service_identity
     slide_id = self.request.get('i')
     if not slide_id:
         self.redirect("/ourcityapp")
         return
     slide_id = long(slide_id)
     if is_default_service_identity(service_identity):
         service_identity_user = service_user
     else:
         service_identity_user = create_service_identity_user(service_user, service_identity)
     def trans():
         slide = SolutionLoyaltySlide.get_by_id(slide_id, parent=parent_key_unsafe(service_identity_user, SOLUTION_COMMON))
         return slide
     slide = db.run_in_transaction(trans)
     if not slide:
         self.redirect("/ourcityapp")
         return
     server_settings = get_server_settings()
     jinja_template = JINJA_ENVIRONMENT.get_template('loyalty_preview.html')
     self.response.out.write(jinja_template.render({'slide_id': slide_id,
                                                    'full_url': slide.slide_url(),
                                                    'overlay_url': '%s/common/loyalty/slide/overlay' % (server_settings.baseUrl)}))
예제 #13
0
def _9000_reconnect_friends(job_key, initial_run=True):
    phase = MigrateServiceJob.PHASE_9000_RECONNECT_FRIENDS
    next_phase = MigrateServiceJob.PHASE_DONE

    # Validate that the job still exists
    job = _get_job(job_key, phase)

    # Do the work
    if initial_run:
        _log_progress(job)
        # Schedule breakup
        for fsic_str_key in job.fsic_keys:
            fsic_key = db.Key(fsic_str_key)
            app_user = users.User(fsic_key.parent().name())
            old_si_user = users.User(fsic_key.name())
            new_si_user = create_service_identity_user(job.to_service_user,
                                                       get_identity_from_service_identity_user(old_si_user))
            deferred.defer(_make_friends, job_key, app_user, new_si_user, fsic_str_key, _queue=MIGRATION_QUEUE)
    else:
        # Check the friend count
        current_friend_count = get_all_service_friend_keys_query(job.to_service_user).count(limit=None)
        expected_friend_count = len(job.fsic_keys)
        logging.info('Friend count: %s/%s', current_friend_count, expected_friend_count)
        if current_friend_count == expected_friend_count:
            # Set the next phase
            _set_job_in_next_phase(job_key, phase, next_phase)
            return

    deferred.defer(_9000_reconnect_friends, job_key, False,
                   _countdown=5, _queue=HIGH_LOAD_CONTROLLER_QUEUE)
예제 #14
0
def _make_friends(job_key, app_user, si_user, fsic_str_key=None):
    profile_info = get_profile_info(app_user)
    if not isinstance(profile_info, UserProfile):
        logging.warn("%s was no UserProfile but %s", app_user.email(), profile_info)

        def trans():
            job = db.get(job_key)
            job.fsic_keys.remove(fsic_str_key)
            job.put()
        db.run_in_transaction(trans)
        return

    user_data_str = None
    job = db.get(job_key)
    if job:
        user_datas = job.get_user_datas()
        # { app_user : { si_user : user_data } }
        user_datas_for_app_user = user_datas.get(app_user.email())
        if user_datas_for_app_user is not None:
            old_si_user = create_service_identity_user(job.from_service_user,
                                                       get_identity_from_service_identity_user(si_user))
            user_data_str = user_datas_for_app_user.get(old_si_user.email())

    makeFriends(si_user, app_user, original_invitee=None, servicetag=None, origin=None, notify_invitee=False,
                notify_invitor=False, user_data=user_data_str)
예제 #15
0
def delete_service_role(service_user, role_id, cleanup_members=False):
    service_role = get_service_role_by_id(service_user, role_id)
    if not service_role:
        raise RoleNotFoundException(role_id)

    if bool(ServiceMenuDef.all().ancestor(parent_key(service_user)).filter('roles =', role_id).count(1)):
        raise DeleteRoleFailedHasSMDException(role_id)

    if cleanup_members:
        service_identity_user = create_service_identity_user(service_user)
        role = u'%s' % role_id
        for srg in get_service_role_grants(service_user, role_id):
            app_user = create_app_user_by_email(srg.user_email, srg.app_id)

            def trans():
                user_profile = get_user_profile(app_user, False)
                user_profile.revoke_role(service_identity_user, role)
                user_profile.put()

            if db.is_in_transaction():
                trans()
            else:
                db.run_in_transaction(trans)
    else:
        has_grants = any(get_service_role_grants(service_user, role_id))
        if has_grants:
            raise DeleteRoleFailedHasMembersException(role_id)

    db.delete(service_role)
    _send_service_role_updates(service_user)
def get_menu(identifier):
    service_user = users.get_current_user()
    service_identity_user = create_service_identity_user(service_user, identifier)
    service_identity = get_service_identity(service_identity_user)
    dummy_translator = DummyTranslator(get_service_profile(service_user).defaultLanguage)
    sm = WebServiceMenuTO.fromServiceIdentity(service_identity, dummy_translator.default_language, dummy_translator)
    return sm
예제 #17
0
    def _handle_service_interaction_based_invitation(self, entry_point, code, language, su, user_agent, version):
        match = re.match("^/q/s/(.+)/(\\d+)$", su.full)
        if not match:
            self.response.out.write(_TMPL % su.full)
        else:
            user_code = match.group(1)

            service_profile = get_service_profile_via_user_code(user_code)

            if not service_profile:  # Profile of usercode not found. Sorry we can't help you :(
                logging.info("Profile of usercode not found. Sorry we can't help you :(")
                self.response.out.write(_TMPL % "/")
                return

            service_user = service_profile.user

            if entry_point == "S":  # It's a QR-Code
                logging.info("It's a QR-Code")
                sid = int(match.group(2))
                service_interaction_def = get_service_interaction_def(service_user, int(sid))
                service_identity_user = create_service_identity_user(service_user, service_interaction_def.service_identity)
                service_identity = get_service_identity(service_identity_user)
                self._handle_after_qr_code_scan(user_agent, service_identity, language, sid)
                return

            if entry_point == "M":
                logging.info("It's a Message")
            else:
                logging.warn("Expected entry_point 'M' but got '%s'." % entry_point)

            # Get service identity by sid
            sid = int(match.group(2))
            service_interaction_def = get_service_interaction_def(service_user, int(sid))
            service_identity_user = create_service_identity_user(service_user, service_interaction_def.service_identity)
            service_identity = get_service_identity(service_identity_user)
            supported_platform = determine_if_platform_supports_rogerthat_by_user_agent(user_agent)
            if (version and version == "web") or not supported_platform:
                logging.info("Unsupported platform ===> Show sorry page with install instructions for android & iphone")

                variables = {'profile': service_identity,
                             'payload': urllib.urlencode([("chl", "%s/S/%s" % (get_server_settings().baseUrl, code))]),
                             'app_name': get_app_name_by_id(service_identity.app_id)}
                # Unsupported platform ===> Show sorry page with install instructions for android & iphone
                self.response.out.write(render('sorry_step2', language, variables, 'web'))
            else:
                fallback_url = "%s/%s/%s?v=web" % (get_server_settings().baseUrl, entry_point, code)
                redirect_to_app(self, user_agent.lower(), service_identity.app_id, su.full, fallback_url)
def _set_content_branding(sln_settings):
    users.set_user(sln_settings.service_user)
    try:
        sln_main_branding = get_solution_main_branding(sln_settings.service_user)
        populate_identity(sln_settings, sln_main_branding.branding_key)

        identities = [None]
        if sln_settings.identities:
            identities.extend(sln_settings.identities)
        for service_identity in identities:
            if is_default_service_identity(service_identity):
                service_identity_user = create_service_identity_user(sln_settings.service_user)
            else:
                service_identity_user = create_service_identity_user(sln_settings.service_user, service_identity)
            deferred.defer(_update_tablets, service_identity_user, None, _queue=HIGH_LOAD_CONTROLLER_QUEUE)
    finally:
        users.clear_user()
예제 #19
0
def search_users(term, app_id=None, admin=False):
    from rogerthat.bizz.profile import search_users_via_name_or_email
    service_user = users.get_current_user()
    default_service_identity_user = create_service_identity_user(service_user, ServiceIdentity.DEFAULT)
    if not admin and app_id is not None:
        validate_app_id_for_service_identity_user(default_service_identity_user, app_id)
    return sorted(search_users_via_name_or_email(term, app_id),
                  key=lambda x: (x.app_id, x.name.upper()))
예제 #20
0
def revoke_service_role(service_user, identity, user, role_id):
    service_role = get_service_role_by_id(service_user, role_id)
    if not service_role:
        raise RoleNotFoundException(role_id)
    service_identity_user = create_service_identity_user(service_user, identity)
    revoke_role(service_identity_user, user, service_role)
    _send_service_role_grants_updates(service_user)
    _send_update_friend(service_user, identity, user, force=True)
예제 #21
0
def grant_service_roles(service_user, identity, user, role_ids):
    service_roles = get_service_roles_by_ids(service_user, role_ids)
    for role_id, service_role in zip(role_ids, service_roles):
        if not service_role:
            raise RoleNotFoundException(role_id)
    service_identity_user = create_service_identity_user(service_user, identity)
    grant_roles(service_identity_user, user, service_roles)
    _send_service_role_grants_updates(service_user)
    _send_update_friend(service_user, identity, user, force=True)
예제 #22
0
def grant_admin_role(user_email, role, identity):
    service_user = users.get_current_user()
    service_identity_user = create_service_identity_user(service_user, identity)
    from rogerthat.bizz.roles import grant_role as grant_role_bizz
    try:
        grant_role_bizz(service_identity_user, users.User(user_email), role)
        return RETURNSTATUS_TO_SUCCESS
    except BusinessException, e:
        return ReturnStatusTO.create(False, e.message)
예제 #23
0
def get_users(service_identity, cursor):
    service_user = users.get_current_user()
    service_identity_user = create_service_identity_user(service_user, service_identity)

    fsics, cursor = get_users_connected_to_service_identity(service_identity_user, cursor)
    result = GetServiceUsersResponseTO()
    result.users = [ServiceUserTO.fromFriendServiceIdentityConnection(fsic) for fsic in fsics]
    result.cursor = unicode(cursor)
    return result
def _run_update_all_friends_of_service_user(service_user, clear_broadcast_settings_cache,
                                            worker_queue=HIGH_LOAD_WORKER_QUEUE):
    should_clear = db.run_in_transaction(_should_clear_broadcast_settings_flag, service_user,
                                         clear_broadcast_settings_cache)

    for si_key in get_service_identities_query(service_user, keys_only=True):
        si_user = create_service_identity_user(users.User(si_key.parent().name()), si_key.name())
        deferred.defer(_run_update_friends_by_profile_info, si_user, FRIEND_TYPE_SERVICE, None,
                       worker_queue, should_clear or clear_broadcast_settings_cache, _queue=worker_queue)
def _friend_trial_service(user, service):
    logging.info("Hooking up %s with %s" % (user, service))
    service_identity_user = create_service_identity_user(service, ServiceIdentity.DEFAULT)
    def trans():
        makeFriends(service_identity_user, user, user, None, notify_invitee=True, origin=ORIGIN_USER_INVITE)
        grant_role(service_identity_user, user, roles.ROLE_ADMIN)

    xg_on = db.create_transaction_options(xg=True)
    db.run_in_transaction_options(xg_on, trans)
예제 #26
0
def _send_update_friend(service_user, identity, user, force=False):
    if identity == ServiceIdentity.DEFAULT:
        # schedule update for all identities
        from rogerthat.bizz.job.update_friends import schedule_update_a_friend_of_service_user
        schedule_update_a_friend_of_service_user(service_user, user, force=force)
    else:
        from rogerthat.bizz.job.update_friends import schedule_update_a_friend_of_a_service_identity_user
        schedule_update_a_friend_of_a_service_identity_user(create_service_identity_user(service_user, identity), user,
                                                            force=force)
def _run_update_friend_for_service_identities(service_user, clear_broadcast_settings_cache, target_user,
                                              worker_queue=HIGH_LOAD_WORKER_QUEUE):
    should_clear = db.run_in_transaction(_should_clear_broadcast_settings_flag, service_user,
                                         clear_broadcast_settings_cache)

    for si_key in get_service_identities_query(service_user, keys_only=True):
        si_user = create_service_identity_user(users.User(si_key.parent().name()), si_key.name())
        deferred.defer(_serialize_and_update_friend_for_service_identity, si_user, should_clear,
                       get_one_friend_service_identity_connection_keys_query, [si_user, target_user],
                       worker_queue=worker_queue)
예제 #28
0
 def trans4():
     p = get_user_profile(users.User(app_user_email), cached=False)
     for old_si_email, service_roles in service_grant_dict.iteritems():
         old_si_user = users.User(old_si_email)
         new_si_user = create_service_identity_user(job.to_service_user,
                                                    get_identity_from_service_identity_user(old_si_user))
         for role in service_roles:
             logging.debug("Granting role %s to %s for %s", role, app_user_email, new_si_user)
             p.grant_role(new_si_user, role)
     p.put()
예제 #29
0
def rm_broadcast_test_person(email, app_id=None):
    from rogerthat.bizz.service.broadcast import delete_broadcast_test_person
    service_user = users.get_current_user()
    default_service_identity_user = create_service_identity_user(service_user, ServiceIdentity.DEFAULT)
    app_id = get_and_validate_app_id_for_service_identity_user(default_service_identity_user, app_id, email)
    try:
        delete_broadcast_test_person(users.get_current_user(), create_app_user(users.User(email), app_id))
        return RETURNSTATUS_TO_SUCCESS
    except BusinessException, be:
        return ReturnStatusTO.create(False, be.message)
예제 #30
0
def search_connected_users(name_or_email_term, app_id=None, service_identity=None):
    from rogerthat.bizz.profile import search_users_via_friend_connection_and_name_or_email
    service_user = users.get_current_user()
    if service_identity is None:
        service_identity = ServiceIdentity.DEFAULT
    service_identity_user = create_service_identity_user(service_user, service_identity)
    if app_id is not None:
        validate_app_id_for_service_identity_user(service_identity_user, app_id)

    return search_users_via_friend_connection_and_name_or_email(service_user.email() if service_identity is None else service_identity_user.email(), name_or_email_term, app_id)
def _delete_roles(parent_service_user, service_user):
    for gto in get_service_grants(service_user):
        if gto.role_type == roles.ROLE_TYPE_ADMIN and gto.role == roles.ROLE_ADMIN and gto.identity == ServiceIdentity.DEFAULT:
            revoke_role(create_service_identity_user(service_user, gto.identity),
                        create_app_user(users.User(gto.user_email), gto.app_id),
                        gto.role)
        else:
            azzert(False, "This should not happen.")

    deferred.defer(_delete_non_ancestor_models, parent_service_user, service_user)
    deferred.defer(_delete_ownership_users, service_user.email())
    def test_user_data(self):
        service_user = self._prepare_svc()

        friend_email = u"*****@*****.**" % time.time()

        data = json.dumps(dict(test="hihihi")).decode('utf8')

        self.assertRaises(FriendNotFoundException, put_user_data, friend_email, data)  # non-existing user

        human_user = users.User(friend_email)
        create_user_profile(human_user, friend_email, language=u'nl')
        self.assertRaises(FriendNotFoundException, put_user_data, friend_email, data)  # user is no friend

        makeFriends(human_user, service_user, None, None, None)

        data = json.dumps(dict(test="ikkel", moe="hahaha")).decode('utf8')
        put_user_data(friend_email, data)

        data = json.dumps(dict(test="tikkel", john="doe")).decode('utf8')
        put_user_data(friend_email, data)

        get_helper = lambda: FriendHelper.from_data_store(service_user, FRIEND_TYPE_SERVICE)
        get_friendto = lambda: run_in_xg_transaction(lambda: FriendTO.fromDBFriendMap(get_helper(),
                                                                                      get_friends_map(human_user),
                                                                                      service_user,
                                                                                      True,
                                                                                      True,
                                                                                      human_user))

        ud = db.get(UserData.createKey(human_user, create_service_identity_user(service_user)))
        ud_dict = ud.userData.to_json_dict()
        ud_dict['__rt__disabledBroadcastTypes'] = ud_dict.get('__rt__disabledBroadcastTypes', [])
        self.assertDictEqual(dict(test="tikkel", moe="hahaha", john="doe", __rt__disabledBroadcastTypes=[]),
                             ud_dict)
        self.assertTrue(get_friendto().hasUserData)

        self.assertRaises(InvalidJsonStringException, put_user_data, friend_email, "invalid user data")
        self.assertRaises(InvalidJsonStringException, put_user_data, friend_email, "")

        del_user_data(friend_email, ["test"])
        self.assertTrue(get_friendto().hasUserData)

        del_user_data(friend_email, ["moe", "john"])
        self.assertFalse(get_friendto().hasUserData)

        japanese = u"スキーに行くのが好きです。"
        data_dict = dict(test="ikkel", moe="hahaha", japanese=japanese)
        data = json.dumps(data_dict).decode('utf8')
        put_user_data(friend_email, data)
        data = json.loads(get_user_data(friend_email, ["japanese"]))
        self.assertEqual(japanese, data["japanese"])

        data = json.loads(get_user_data(friend_email, ["japanese", "test", "moe"]))
        self.assertDictEqual(data, data_dict)
예제 #33
0
def test_message_flow(message_flow_design_name, member, force_language=None, app_id=None):
    from rogerthat.bizz.service.mfr import start_flow, MessageFlowNotValidException, NonFriendMembersException
    service_user = users.get_current_user()
    default_service_identity_user = create_service_identity_user(service_user, ServiceIdentity.DEFAULT)
    app_id = get_and_validate_app_id_for_service_identity_user(default_service_identity_user, app_id, member)
    app_user = create_app_user(users.User(member), app_id)
    try:
        start_flow(default_service_identity_user, None, unicode(get_service_message_flow_design_key_by_name(service_user, message_flow_design_name)),
                   [app_user], True, False, force_language=force_language)
    except MessageFlowNotValidException, e:
        return "Message flow could not be started!\n%s" % (e.fields['error'] or '')
예제 #34
0
    def get(self):
        identifier = self.request.GET.get('identifier')
        azzert(identifier)
        cursor = self.request.GET.get('cursor')

        si = get_service_identity(create_service_identity_user(users.get_current_user(), identifier))

        params = {'service_identity': identifier,
                  'service_identity_name': si.name,
                  'container_id': 'serviceUsersContainer_%s' % md5_hex(identifier),
                  'cursor': cursor}
        self.response.out.write(render('service_users', [DEFAULT_LANGUAGE], params, 'web'))
예제 #35
0
    def get_default_app_id(self, user_hash, identity):
        index = ProfileHashIndex.get(ProfileHashIndex.create_key(user_hash))
        if not index:
            logging.debug('No profile found with user_hash %s', user_hash)
            return None

        si_user = create_service_identity_user(index.user, identity)
        si = get_service_identity(si_user)
        if not si:
            logging.debug('Service identity not found: %s', si_user.email())
            return None
        return si.app_id
예제 #36
0
def breakFriendship(friend, service_identity=None, app_id=None):
    # service_identity & app_id are set when a service does a breakFriendship
    from rogerthat.bizz.friends import breakFriendShip as bizzBreakFriendship
    user = users.get_current_user()
    if service_identity and service_identity != MISSING:
        user = create_service_identity_user(user, service_identity)
    friend_user = users.User(friend)
    if app_id:
        friend_user = create_app_user(friend_user, app_id)
    else:
        pass  # the bizz layer will handle the app_id stuff
    return bizzBreakFriendship(user, friend_user)
예제 #37
0
def get_app_statistics(service_identity):
    service_user = users.get_current_user()
    if not service_identity or service_identity == MISSING:
        service_identity = ServiceIdentity.DEFAULT
    service_identity_user = create_service_identity_user(service_user, service_identity)
    si = get_service_identity(service_identity_user)
    default_app = get_app(si.defaultAppId)
    customer = get_customer(service_user)
    available_apps = [a.app_id for a in get_available_apps_for_customer(customer, default_app.demo)]
    if not available_apps:
        # Customer does not exist or has no app ids
        available_apps = sorted(si.appIds)
    return app.get_app_statistics(available_apps)
def get_target_info(app_user, provider_id, target, currency):
    target_user = users.User(target)

    if '/' not in target:
        target_service_user = create_service_identity_user(target_user)
    else:
        target_service_user = target_user
    target_info_service = _get_target_info_service(target_service_user, provider_id, currency)
    if target_info_service:
        return target_info_service

    if ':' not in target:
        target_user = create_app_user_by_email(target, get_app_id_from_app_user(app_user))
    return _get_target_info_user(target_user, provider_id, currency)
예제 #39
0
def _create_news_item(message,
                      service_identity,
                      service_user,
                      broadcast_type,
                      urls=None):
    if service_identity:
        service_identity_user = create_service_identity_user(
            service_user, service_identity)
        si = get_service_identity(service_identity_user)
    else:
        si = get_default_service_identity(service_user)
        service_identity_user = si.service_identity_user
    if '\n' in message:
        split = message.splitlines()
        title = limit_string(split[0], NewsItem.MAX_TITLE_LENGTH)
        message = '\n'.join(split[1:])
    else:
        title = limit_string(message, NewsItem.MAX_TITLE_LENGTH)
    news_buttons = []
    if urls:
        for url in urls:
            if url.get('url') and url.get('name'):
                id_ = u'url'
                caption = u'%s' % url['name']
                action = u'%s' % url['url']
                if len(caption) > NewsItem.MAX_BUTTON_CAPTION_LENGTH:
                    sln_settings = get_solution_settings(service_user)
                    caption = translate(sln_settings.main_language,
                                        SOLUTION_COMMON, u'read_more')
                news_buttons.append(NewsActionButtonTO(id_, caption, action))
                break

    app_ids = [
        app_id for app_id in si.appIds if app_id != App.APP_ID_OSA_LOYALTY
    ]
    return put_news(service_identity_user,
                    sticky=False,
                    sticky_until=0,
                    title=title,
                    message=message,
                    image=None,
                    news_type=NewsItem.TYPE_NORMAL,
                    broadcast_type=broadcast_type,
                    news_buttons=news_buttons,
                    qr_code_content=None,
                    qr_code_caption=None,
                    app_ids=app_ids,
                    news_id=None,
                    accept_missing=True)
예제 #40
0
def add_broadcast_test_person(email, app_id=None):
    from rogerthat.bizz.service.broadcast import add_broadcast_test_person as bizz_add_broadcast_test_person
    r = BroadcastTestPersonReturnStatusTO()
    service_user = users.get_current_user()
    default_service_identity_user = create_service_identity_user(service_user, ServiceIdentity.DEFAULT)
    app_id = get_and_validate_app_id_for_service_identity_user(default_service_identity_user, app_id, email)
    try:
        user_profile = bizz_add_broadcast_test_person(service_user, create_app_user(users.User(email), app_id))
        r.user_details = UserDetailsTO.fromUserProfile(user_profile)
        r.success = True
        r.errormsg = None
    except BusinessException, be:
        r.user_details = None
        r.success = False
        r.errormsg = be.message.decode('UTF-8') if be.message is not None else None
예제 #41
0
def rebuild_synced_roles(members, service_identities):
    """
    Rebuilds access to service_identies based on SYNCED roles.
    If members is empty or None, access for all members of service_identities will be checked.
    If service_identies is empty or None, access for members of all service_identities will be checked.
    """
    from rogerthat.bizz.job.rebuild_synced_roles import schedule_rebuild_synced_roles
    service_user = users.get_current_user()

    if members in (None, MISSING):
        members = list()
    if service_identities in (None, MISSING):
        service_identities = list()

    schedule_rebuild_synced_roles(service_user, [create_app_user(users.User(m.member), m.app_id) for m in members],
                                  [create_service_identity_user(service_user, si_id) for si_id in service_identities])
예제 #42
0
def messageFlowMemberResult(request):
    # type: (MessageFlowMemberResultRequestTO) -> None
    from rogerthat.bizz.messaging import send_message_flow_member_result, send_message_flow_results_email
    from rogerthat.dal import parent_key
    from rogerthat.dal.service import get_service_interaction_def
    app_user = users.get_current_user()
    run = request.run
    sender = add_slash_default(users.User(run.sender))
    svc_user, service_identity = get_service_identity_tuple(sender)
    tag = None
    if run.hashed_tag != MISSING:
        mapped_tag = ServiceMenuDefTagMap.get_by_key_name(run.hashed_tag, parent=parent_key(svc_user))
        if mapped_tag:
            tag = mapped_tag.tag
    elif run.service_action != MISSING:
        if "?" in run.service_action:
            # strip off the query parameters added by shortner.py
            run.service_action = run.service_action[:run.service_action.index("?")]
        sid = get_service_interaction_def(svc_user, int(run.service_action))
        if sid:
            tag = sid.tag
    elif run.message_flow_run_id:
        message_flow_run = MessageFlowRunRecord.get_by_key_name(
            MessageFlowRunRecord.createKeyName(svc_user, run.message_flow_run_id))
        if message_flow_run:
            tag = message_flow_run.tag

    if request.end_id:
        from rogerthat.bizz.messaging import check_test_flow_broadcast_ended
        check_test_flow_broadcast_ended(app_user, create_service_identity_user(svc_user, service_identity),
                                        run.parent_message_key, tag)

    if run.steps and run.steps[-1].acknowledged_timestamp is MISSING:
        logging.warn('Last step is not yet ACKed! Patching...')
        run.steps = run.steps[:-1]

    if request.results_email and request.results_email is not MISSING:
        send_message_flow_results_email(request.message_flow_name, request.emails, request.email_admins,
                                        run.steps, app_user, service_identity, svc_user, run.parent_message_key, tag)
    else:
        flow_params = run.flow_params if run.flow_params is not MISSING else None
        send_message_flow_member_result(svc_user, service_identity, run.message_flow_run_id, run.parent_message_key,
                                        app_user, run.steps, request.end_id, request.flush_id,
                                        tag=tag, flow_params=flow_params,
                                        timestamp=MISSING.default(request.timestamp, now()))
예제 #43
0
def set_service_enabled(customer_id):
    customer = Customer.get_by_id(customer_id)
    if not customer.service_email:
        raise NoSubscriptionException(customer)

    service_user = users.User(customer.service_email)
    service_identity_user = create_service_identity_user(service_user)
    si = get_service_identity(service_identity_user)
    sln_settings = get_solution_settings(service_user)
    sln_settings.service_disabled = False
    customer.service_disabled_at = 0
    customer.disabled_reason = u''
    customer.disabled_reason_int = 0
    customer.subscription_cancel_pending_date = 0
    # restore app ids
    customer.app_ids = si.sorted_app_ids
    customer.default_app_id = si.app_id
    db.put([customer, sln_settings])

    rogerthat_re_enable_service(service_user)
예제 #44
0
def _4500_migrate_qrs(job_key):
    phase = MigrateServiceJob.PHASE_4500_MIGRATE_QRS
    next_phase = MigrateServiceJob.PHASE_5000_MIGRATE_NON_ANCESTOR_MODELS

    # Validate that the job still exists
    job = _get_job(job_key, phase)

    # Do the work
    _log_progress(job)

    logging.info("1/ Migrate recommendation QR codes")

    def trans_migrate_recommend_qrs():
        # Get SIs with recommend enabled
        service_identities = [si for si in get_service_identities_query(job.from_service_user) if si.shareSIDKey]
        if service_identities:
            old_sid_keys = map(db.Key, [si.shareSIDKey for si in service_identities])
            old_sid_keys = [k for k in old_sid_keys if k.parent().name() != job.to_service_user.email()]
            logging.info('Old recommendation QR codes: %s', old_sid_keys)
            if old_sid_keys:
                old_sids = db.get(old_sid_keys)

                new_sids = _migrate_sids(job, old_sids)
                for si, new_sid in zip(service_identities, new_sids):
                    si.shareSIDKey = str(new_sid.key())
                put_and_invalidate_cache(*service_identities)
                logging.info('New recommendation QR codes: %s', [new_sid.key() for new_sid in new_sids])
        else:
            logging.debug("No ServiceIdentity with recommendation enabled")

    xg_on = db.create_transaction_options(xg=True)
    db.run_in_transaction_options(xg_on, trans_migrate_recommend_qrs)

    logging.info("2/ Migrate all other QR codes")
    qry = ServiceInteractionDef.all().ancestor(parent_key(job.from_service_user))

    def trans_migrate_other_qrs():
        old_sids = qry.fetch(100)
        if not old_sids:
            return False

        _migrate_sids(job, old_sids)
        return True

    while db.run_in_transaction_options(xg_on, trans_migrate_other_qrs):
        pass  # run trans until it returns False

    logging.info("3/ Migrate all ProfilePointers")
    old_pp_keys = list()
    new_pps = list()
    for si_key in get_service_identities_query(job.from_service_user, keys_only=True):
        identity = si_key.name()
        old_si_user = create_service_identity_user(job.from_service_user, identity)
        new_si_user = create_service_identity_user(job.to_service_user, identity)
        old_pp_keys.append(ProfilePointer.create_key(old_si_user))
        new_pps.append(ProfilePointer.create(new_si_user))

    put_and_invalidate_cache(*new_pps)
    db.delete(old_pp_keys)

    # Set the next phase
    _set_job_in_next_phase(job_key, phase, next_phase)
예제 #45
0
def _7000_migrate_solution(job_key):
    phase = MigrateServiceJob.PHASE_7000_MIGRATE_SOLUTION
    next_phase = MigrateServiceJob.PHASE_8000_FINISH_MODELS

    # Validate that the job still exists
    job = _get_job(job_key, phase)

    # Do the work
    _log_progress(job)

    if job.solution:
        logging.info('0/ Migrate the solution models without ancestor, but with service_user as key name.')

        def trans0():
            new_models = list()
            old_models = list()

            for model_class in (SolutionMainBranding, SolutionLogo, SolutionAvatar):
                old_model = db.get(model_class.create_key(job.from_service_user))
                if old_model:
                    kwargs = copy_model_properties(old_model)
                    new_model = model_class(key=model_class.create_key(job.to_service_user),
                                            **kwargs)
                    new_models.append(new_model)
                    old_models.append(old_model)

            if new_models:
                put_and_invalidate_cache(*new_models)
            if old_models:
                db.delete(old_models)

        xg_on = db.create_transaction_options(xg=True)
        db.run_in_transaction_options(xg_on, trans0)

        old_sln_settings = get_solution_settings(job.from_service_user)
        identities = [None]
        if old_sln_settings.identities:
            identities.extend(old_sln_settings.identities)

        logging.info('1/ Migrate RestaurantReservations')
        for service_identity in identities:
            from_si_user = create_service_identity_user_wo_default(job.from_service_user, service_identity)
            to_si_user = create_service_identity_user_wo_default(job.to_service_user, service_identity)
            while True:
                reservations = RestaurantReservation.all().filter('service_user', from_si_user).fetch(300)
                if not reservations:
                    break
                for r in reservations:
                    r.service_user = to_si_user
                _put_and_invalidate_cache_and_allocate_ids(*reservations)

        logging.info('2/ Migrate EventReminders')
        for service_identity in identities:
            from_si_user = create_service_identity_user(job.from_service_user)
            to_si_user = create_service_identity_user(job.to_service_user)
            while True:
                reminders = EventReminder.all().filter('service_identity_user', from_si_user).fetch(300)
                if not reminders:
                    break
                for r in reminders:
                    r.service_identity_user = to_si_user
                _put_and_invalidate_cache_and_allocate_ids(*reminders)

        logging.info('3/ Migrate RestaurantProfile.reserve_flow_part2')
        restaurant_profile = db.get(RestaurantProfile.create_key(job.from_service_user))
        if restaurant_profile and restaurant_profile.reserve_flow_part2:
            old_part2_key = db.Key(restaurant_profile.reserve_flow_part2)
            new_part2_key = db.Key.from_path(old_part2_key.kind(), old_part2_key.id_or_name(),
                                             parent=parent_key(job.to_service_user))
            logging.debug('New key: %r', new_part2_key)
            restaurant_profile.reserve_flow_part2 = str(new_part2_key)
            _put_and_invalidate_cache_and_allocate_ids(restaurant_profile)

        logging.info('4/ Delete all SolutionQRs. They will be recreated when provisioning.')
        for service_identity in identities:
            service_identity_user = create_service_identity_user_wo_default(job.from_service_user, service_identity)
            db.delete(SolutionQR.all(keys_only=True).ancestor(parent_key_unsafe(service_identity_user, job.solution)))

        logging.info('5/ Delete Loyalty QR. It will be recreated when provisioning.')
        if SolutionModule.LOYALTY in old_sln_settings.modules:
            for service_identity in identities:
                if is_default_service_identity(service_identity):
                    loyalty_i_settings = db.get(SolutionLoyaltySettings.create_key(job.from_service_user))
                else:
                    loyalty_i_settings = db.get(
                        SolutionLoyaltyIdentitySettings.create_key(job.from_service_user, service_identity))
                if loyalty_i_settings:
                    loyalty_i_settings.image_uri = None
                    loyalty_i_settings.content_uri = None
                    _put_and_invalidate_cache_and_allocate_ids(loyalty_i_settings)

        logging.info('6/ Change ancestor keys of solution models.')
        for solution in ['common', job.solution]:
            for service_identity in identities:
                if is_default_service_identity(service_identity):
                    _migrate_ancestor_models(job, parent_key(job.from_service_user, solution))
                else:
                    service_identity_user = create_service_identity_user_wo_default(
                        job.from_service_user, service_identity)
                    _migrate_ancestor_models(job, parent_key_unsafe(service_identity_user, solution))

        sln_settings = get_solution_settings(job.to_service_user)
        sln_main_branding = get_solution_main_branding(job.to_service_user)
        users.set_user(job.to_service_user)
        try:
            populate_identity(sln_settings, sln_main_branding.branding_key)
        finally:
            users.clear_user()

    # Set the next phase
    _set_job_in_next_phase(job_key, phase, next_phase)
예제 #46
0
def _re_index_service_identity(si_key):
    service_user = users.User(si_key.parent().name())
    si_user = create_service_identity_user(service_user, si_key.name())
    re_index(si_user)
예제 #47
0
def _delete_search_indexes(service_user):
    for si_key in ServiceIdentity.all(keys_only=True).ancestor(parent_key(service_user)):
        deferred.defer(remove_service_identity_from_index,
                       create_service_identity_user(service_user, si_key.name()), _queue=MIGRATION_QUEUE)
예제 #48
0
def rest_put_news_item(
        title,
        message,
        broadcast_type,
        image,
        sponsored=False,
        action_button=None,
        order_items=None,
        type=MISSING,
        qr_code_caption=MISSING,
        app_ids=MISSING,  # @ReservedAssignment
        scheduled_at=MISSING,
        news_id=None,
        broadcast_on_facebook=False,
        broadcast_on_twitter=False,
        facebook_access_token=None,
        target_audience=None,
        role_ids=None):
    """
    Args:
        title (unicode)
        message (unicode)
        broadcast_type (unicode)
        sponsored (bool)
        image (unicode)
        action_button (NewsButtonTO)
        order_items (list of OrderItemTO)
        type (int)
        qr_code_caption (unicode)
        app_ids (list of unicode)
        scheduled_at (long)
        news_id (long): id of the news to update. When not specified a new item is created
        broadcast_on_facebook (bool)
        broadcast_on_twitter (bool)
        facebook_access_token (unicode): user or page access token
        target_audience (NewsTargetAudienceTO)
        role_ids (list of long)
    """
    service_user = users.get_current_user()
    session_ = users.get_current_session()
    service_identity = session_.service_identity
    if is_default_service_identity(service_identity):
        service_identity_user = create_service_identity_user(service_user)
    else:
        service_identity_user = create_service_identity_user(
            service_user, service_identity)

    try:
        host = get_current_http_host()
        return put_news_item(service_identity_user,
                             title,
                             message,
                             broadcast_type,
                             sponsored,
                             image,
                             action_button,
                             order_items,
                             type,
                             qr_code_caption,
                             app_ids,
                             scheduled_at,
                             news_id,
                             broadcast_on_facebook,
                             broadcast_on_twitter,
                             facebook_access_token,
                             target_audience=target_audience,
                             role_ids=role_ids,
                             host=host,
                             accept_missing=True)
    except BusinessException as e:
        sln_settings = get_solution_settings(service_user)
        try:
            message = common_translate(sln_settings.main_language,
                                       SOLUTION_COMMON, e.message)
        except ValueError:
            message = e.message
        return ReturnStatusTO.create(False, message)
예제 #49
0
 def service_identity_user(self):
     return create_service_identity_user(self.service_user,
                                         self.service_identity)
예제 #50
0
def get_broadcast_statistics_excel(service_user, service_identity):
    """
    Generates an excel file containing the broadcast statistics.

    Format: Date | Sent to | Received | Read | Acknowledged | Message

    Args:
        service_user(users.User): Service user

    Returns: Excel file

    """
    sln_settings = get_solution_settings(service_user)
    lang = sln_settings.main_language

    def transl(key):
        return translate(lang, SOLUTION_COMMON, key)

    if is_default_service_identity(service_identity):
        service_identity_user = create_service_identity_user(service_user, ServiceIdentity.DEFAULT)
    else:
        service_identity_user = create_service_identity_user(service_user, service_identity)
    bc_stats = BroadcastStatistic.get_all_by_service_identity_user(service_identity_user).order('timestamp')
    column_timestamp = 0
    column_sent = 1
    column_received = 2
    column_read = 3
    # column_acknowledged = 4
    column_message = 4
    bold_style = xlwt.XFStyle()
    bold_style.font.bold = True
    book = xlwt.Workbook(encoding="utf-8")

    messages_sheet = book.add_sheet(transl('broadcast_statistics')[0:31])
    messages_sheet.write(0, column_timestamp, transl('Date'), bold_style)
    messages_sheet.write(0, column_sent, transl('sent_to'), bold_style)
    messages_sheet.write(0, column_received, transl('received'), bold_style)
    messages_sheet.write(0, column_read, transl('Read'), bold_style)
    # messages_sheet.write(0, column_acknowledged, transl('acknowledged'), bold_style)
    messages_sheet.write(0, column_message, transl('inbox-message'), bold_style)
    messages_sheet.col(column_timestamp).width = 6000
    messages_sheet.col(column_sent).width = 5000
    messages_sheet.col(column_received).width = 5000
    messages_sheet.col(column_read).width = 5000
    # messages_sheet.col(column_acknowledged).width = 5000
    messages_sheet.col(column_message).width = 20000

    for i, statistic in enumerate(bc_stats):
        i += 1
        if statistic.timestamp:
            datetime_string = format_datetime(datetime.datetime.utcfromtimestamp(statistic.timestamp), locale=lang,
                                          tzinfo=sln_settings.tz_info)
        else:
            datetime_string = ''
        messages_sheet.write(i, column_timestamp, datetime_string)
        messages_sheet.write(i, column_message, statistic.message or '')
        messages_sheet.write(i, column_sent, statistic.sent or 0)
        messages_sheet.write(i, column_received, statistic.received or 0)
        messages_sheet.write(i, column_read, statistic.read or 0)
        # messages_sheet.write(i, column_acknowledged, statistic.acknowledged or 0)

    excel_file = StringIO()
    book.save(excel_file)
    return excel_file.getvalue()