def _send_ito_agreement_sign_message(agreement_key, app_user, pdf_url, attachment_name, pdf_size): logging.debug('Sending SIGN widget to app user') form = SignFormTO(positive_button_ui_flags=Message.UI_FLAG_EXPECT_NEXT_WAIT_5, widget=SignTO(algorithm=KEY_ALGORITHM, key_name=KEY_NAME, payload=base64.b64encode(pdf_url).decode('utf-8'))) attachment = AttachmentTO(content_type=u'application/pdf', download_url=pdf_url, name=attachment_name, size=pdf_size) tag = json.dumps({ u'__rt__.tag': u'sign_investment_agreement', u'agreement_id': agreement_key.id() }).decode('utf-8') flow_params = json.dumps({ 'form': form.to_dict(), 'attachments': [attachment.to_dict()] }) email, app_id = get_app_user_tuple(app_user) members = [MemberTO(member=email.email(), app_id=app_id, alert_flags=0)] messaging.start_local_flow(get_rogerthat_api_key(), None, members, None, tag=tag, context=None, flow=FLOW_SIGN_INVESTMENT, flow_params=flow_params) deferred.defer(_send_sign_investment_reminder, agreement_key.id(), u'long', _countdown=3600, _queue=SCHEDULED_QUEUE) deferred.defer(_send_sign_investment_reminder, agreement_key.id(), u'short', _countdown=3 * DAY, _queue=SCHEDULED_QUEUE) deferred.defer(_send_sign_investment_reminder, agreement_key.id(), u'short', _countdown=10 * DAY, _queue=SCHEDULED_QUEUE)
def resume_paused_agreement(agreement): azzert(agreement.status == InvestmentAgreement.STATUS_CREATED) message = create_agreement_confirmation_message(agreement) params = { 'token': agreement.token, 'amount': agreement.amount, 'currency': agreement.currency } msg = u'''We are ready to process your purchase. Is the following information correct? You would like to buy %(token)s for a total amount of **%(amount)s %(currency)s**. If you have not done so already, please go through the KYC procedure, which you can find in the service menu. After confirming and going through the KYC procedure, you will receive your personalised purchase agreement.''' % params parent_message_key = None member_user, app_id = get_app_user_tuple(agreement.app_user) member = MemberTO(app_id=app_id, member=member_user.email(), alert_flags=Message.ALERT_FLAG_VIBRATE) messaging.send(get_rogerthat_api_key(), parent_message_key, msg, message.answers, message.flags, [member], message.branding, message.tag, step_id=message.step_id)
def migrate(): for stats_model in GlobalStats.query(): # type: GlobalStats new_value = stats_model.value / 100 currencies = _get_currency_conversions(stats_model.currencies, new_value) stats_model.populate(currencies=currencies, value=new_value) stats_model.put() coords = [2, 1, 0] icon_name = 'fa-suitcase' label = 'Purchase iTokens' flow = BUY_TOKENS_FLOW_V5 api_key = get_rogerthat_api_key() roles = system.list_roles(api_key) menu_item_roles = [] for role in roles: if role.name in ('invited', 'members'): menu_item_roles.append(role.id) system.put_menu_item(api_key, icon_name, BUY_TOKENS_TAG, coords, None, label, static_flow=flow, roles=[] if DEBUG else menu_item_roles, fall_through=True) system.publish_changes(api_key)
def store_iyo_info_in_userdata(username, user_detail): logging.info('Getting the user\'s info from IYO') iyo_user = get_user(username) api_key = get_rogerthat_api_key() user_data_keys = ['name', 'email', 'phone', 'address'] current_user_data = system.get_user_data(api_key, user_detail.email, user_detail.app_id, user_data_keys) user_data = dict() if not current_user_data.get('name') and iyo_user.firstname and iyo_user.lastname: user_data['name'] = '%s %s' % (iyo_user.firstname, iyo_user.lastname) if not current_user_data.get('email') and iyo_user.validatedemailaddresses: user_data['email'] = iyo_user.validatedemailaddresses[0].emailaddress if not current_user_data.get('phone') and iyo_user.validatedphonenumbers: user_data['phone'] = iyo_user.validatedphonenumbers[0].phonenumber if not current_user_data.get('address') and iyo_user.addresses: user_data['address'] = '%s %s' % (iyo_user.addresses[0].street, iyo_user.addresses[0].nr) user_data['address'] += '\n%s %s' % (iyo_user.addresses[0].postalcode, iyo_user.addresses[0].city) user_data['address'] += '\n%s' % iyo_user.addresses[0].country if iyo_user.addresses[0].other: user_data['address'] += '\n\n%s' % iyo_user.addresses[0].other if user_data: system.put_user_data(api_key, user_detail.email, user_detail.app_id, user_data)
def store_invitation_code_in_userdata(username, user_detail): def trans(): profile_key = TffProfile.create_key(username) profile = profile_key.get() if not profile: profile = TffProfile(key=profile_key, app_user=create_app_user_by_email(user_detail.email, user_detail.app_id)) pp_key = ProfilePointer.create_key(username) pp = pp_key.get() if pp: logging.error("Failed to save invitation code of user '%s', we have a duplicate", user_detail.email) deferred.defer(store_invitation_code_in_userdata, username, user_detail, _countdown=10 * 60, _transactional=True) return False profile.put() pp = ProfilePointer(key=pp_key, username=username) pp.put() return True if not ndb.transaction(trans, xg=True): return user_data = { 'invitation_code': user_code(username) } api_key = get_rogerthat_api_key() system.put_user_data(api_key, user_detail.email, user_detail.app_id, user_data)
def store_chat_id_in_user_data(rogerthat_chat_id, user_detail): user_data = { 'support_chat_id': rogerthat_chat_id } api_key = get_rogerthat_api_key() system.put_user_data(api_key, user_detail.email, user_detail.app_id, user_data)
def add_user_to_role(user_detail, role_name): logging.info('Adding user to role "%s"', role_name) api_key = get_rogerthat_api_key() role_id = get_role_id_by_name(api_key, role_name) member = BaseMemberTO() member.member = user_detail.email member.app_id = user_detail.app_id system.add_role_member(api_key, role_id, member)
def remove_user_from_role(user_detail, role_name): logging.info('Deleting user from role "%s"', role_name) api_key = get_rogerthat_api_key() role_id = get_role_id_by_name(api_key, role_name) member = BaseMemberTO() member.member = user_detail.email member.app_id = user_detail.app_id system.delete_role_member(api_key, role_id, member)
def store_referral_in_user_data(profile_key): profile = profile_key.get() user_data = { 'has_referrer': profile.referrer_user is not None } email, app_id = get_app_user_tuple(profile.app_user) api_key = get_rogerthat_api_key() system.put_user_data(api_key, email.email(), app_id, user_data)
def start_invest(email, tag, result_key, context, service_identity, user_details): # type: (unicode, unicode, unicode, unicode, unicode, UserDetailsTO) -> None logging.info('Ignoring start_invest poke tag because this flow is not used atm') return flow = BUY_TOKENS_FLOW_V3_KYC_MENTION logging.info('Starting invest flow %s for user %s', flow, user_details.email) members = [MemberTO(member=user_details.email, app_id=user_details.app_id, alert_flags=0)] flow_params = json.dumps({'currencies': _get_conversion_rates()}) messaging.start_local_flow(get_rogerthat_api_key(), None, members, service_identity, tag=BUY_TOKENS_TAG, context=context, flow=flow, flow_params=flow_params)
def send_kyc_flow(app_user, message=None): email, app_id = get_app_user_tuple(app_user) member = MemberTO(member=email.email(), app_id=app_id, alert_flags=0) push_message = u'KYC procedure has been initiated' # for iOS only messaging.start_local_flow(get_rogerthat_api_key(), None, [member], tag=KYC_FLOW_PART_1_TAG, flow=KYC_FLOW_PART_1, push_message=push_message, flow_params=json.dumps({'message': message}))
def send_rogerthat_flow(member, flow): if isinstance(member, users.User): human_user, app_id = get_app_user_tuple(member) member = MemberTO(member=human_user.email(), app_id=app_id, alert_flags=Message.ALERT_FLAG_VIBRATE) messaging.start_local_flow(api_key=get_rogerthat_api_key(), xml=None, members=[member], flow=flow)
def set_hoster_status_in_user_data(app_user, can_order=None): # type: (users.User, bool) -> None if not isinstance(can_order, bool): can_order = all(o.status == NodeOrderStatus.CANCELED for o in NodeOrder.list_by_user(app_user)) user_data = {'hoster': {'can_order': can_order}} api_key = get_rogerthat_api_key() email, app_id = get_app_user_tuple(app_user) current_user_data = system.get_user_data(api_key, email.email(), app_id, ['hoster']) if current_user_data != user_data: system.put_user_data(api_key, email.email(), app_id, user_data)
def store_kyc_in_user_data(app_user): username = get_iyo_username(app_user) profile = get_tff_profile(username) user_data = { 'kyc': { 'status': profile.kyc.status, 'verified': profile.kyc.status == KYCStatus.VERIFIED } } email, app_id = get_app_user_tuple(app_user) api_key = get_rogerthat_api_key() return system.put_user_data(api_key, email.email(), app_id, user_data)
def _remove_list(email, app_id, list_id): user_data_keys = ['todo_lists'] api_key = get_rogerthat_api_key() current_user_data = system.get_user_data(api_key, email, app_id, user_data_keys) todo_lists = current_user_data.get('todo_lists') or [] if list_id in todo_lists: todo_lists.remove(list_id) user_data = {'todo_lists': todo_lists} system.put_user_data(api_key, email, app_id, user_data) system.del_user_data(api_key, email, app_id, ['todo_%s' % list_id])
def send_rogerthat_message(member, message, answers=None, flags=None): # type: (MemberTO, unicode, list[AnswerTO]) -> unicode flags = flags if flags is not None else Message.FLAG_AUTO_LOCK if not answers: flags = flags | Message.FLAG_ALLOW_DISMISS answers = [] return messaging.send(api_key=get_rogerthat_api_key(), parent_message_key=None, members=[member], message=message, answers=answers or [], flags=flags, alert_flags=Message.ALERT_FLAG_VIBRATE, branding=get_main_branding_hash(), tag=None)
def _send_ito_agreement_to_admin(agreement_key, admin_app_user): logging.debug('Sending SIGN widget to payment admin %s', admin_app_user) agreement = agreement_key.get() # type: InvestmentAgreement widget = SignTO() widget.algorithm = KEY_ALGORITHM widget.caption = u'Sign to mark this investment as paid.' widget.key_name = KEY_NAME widget.payload = base64.b64encode(str(agreement_key.id())).decode('utf-8') form = SignFormTO() form.negative_button = u'Abort' form.negative_button_ui_flags = 0 form.positive_button = u'Accept' form.positive_button_ui_flags = Message.UI_FLAG_EXPECT_NEXT_WAIT_5 form.type = SignTO.TYPE form.widget = widget member_user, app_id = get_app_user_tuple(admin_app_user) message = u"""Enter your pin code to mark purchase agreement %(investment)s (reference %(reference)s as paid. - from: %(user)s\n - amount: %(amount)s %(currency)s - %(token_count_float)s %(token_type)s tokens """ % { 'investment': agreement.reference, 'user': get_iyo_username(agreement.app_user), 'amount': agreement.amount, 'currency': agreement.currency, 'token_count_float': agreement.token_count_float, 'token_type': agreement.token, 'reference': agreement.reference } messaging.send_form(api_key=get_rogerthat_api_key(), parent_message_key=None, member=member_user.email(), message=message, form=form, flags=0, alert_flags=Message.ALERT_FLAG_VIBRATE, branding=get_main_branding_hash(), tag=json.dumps({ u'__rt__.tag': u'sign_investment_agreement_admin', u'agreement_id': agreement_key.id() }).decode('utf-8'), attachments=[], app_id=app_id, step_id=u'sign_investment_agreement_admin')
def add_nodes_to_profile(iyo_username, nodes): profile = TffProfile.create_key(iyo_username).get() existing_ids = [n.id for n in profile.nodes] for node in nodes: if node['id'] not in existing_ids: profile.nodes.append(NodeInfo(**node)) profile.put() user, app_id = get_app_user_tuple(profile.app_user) data = {'nodes': [n.to_dict() for n in profile.nodes]} deferred.defer(system.put_user_data, get_rogerthat_api_key(), user.email(), app_id, data, _transactional=True) return profile
def _update_list(email, app_id, list_id, progress): user_data_keys = ['todo_lists'] api_key = get_rogerthat_api_key() current_user_data = system.get_user_data(api_key, email, app_id, user_data_keys) user_data = {} if not current_user_data.get('todo_lists'): user_data['todo_lists'] = [list_id] elif list_id not in current_user_data.get('todo_lists'): user_data['todo_lists'] = current_user_data.get('todo_lists') + [ list_id ] user_data['todo_%s' % list_id] = progress system.put_user_data(api_key, email, app_id, user_data)
def _send_order_node_sign_message(app_user, order_id, pdf_url, attachment_name, order_name): logging.debug('Sending SIGN widget to app user') widget = SignTO() widget.algorithm = KEY_ALGORITHM widget.caption = u'Please enter your PIN code to digitally sign the terms and conditions' widget.key_name = KEY_NAME widget.payload = base64.b64encode(pdf_url).decode('utf-8') form = SignFormTO() form.negative_button = u'Abort' form.negative_button_ui_flags = 0 form.positive_button = u'Accept' form.positive_button_ui_flags = Message.UI_FLAG_EXPECT_NEXT_WAIT_5 form.type = SignTO.TYPE form.widget = widget attachment = AttachmentTO() attachment.content_type = u'application/pdf' attachment.download_url = pdf_url attachment.name = attachment_name message = u"""Order %(order_name)s Received You have now been approved for hosting duties! We will keep you updated of the Node shipping process through the app. Please review the terms and conditions and press the "Sign" button to accept. """ % {"order_name": order_name} member_user, app_id = get_app_user_tuple(app_user) messaging.send_form(api_key=get_rogerthat_api_key(), parent_message_key=None, member=member_user.email(), message=message, form=form, flags=0, alert_flags=Message.ALERT_FLAG_VIBRATE, branding=get_main_branding_hash(), tag=json.dumps({u'__rt__.tag': u'sign_order_node_tos', u'order_id': order_id}).decode('utf-8'), attachments=[attachment], app_id=app_id, step_id=u'sign_order_node_tos')
def _send_ito_agreement_sign_message(agreement_key, app_user, pdf_url, attachment_name): logging.debug('Sending SIGN widget to app user') widget = SignTO() widget.algorithm = KEY_ALGORITHM widget.caption = u'Please enter your PIN code to digitally sign the purchase agreement' widget.key_name = KEY_NAME widget.payload = base64.b64encode(pdf_url).decode('utf-8') form = SignFormTO() form.negative_button = u'Abort' form.negative_button_ui_flags = 0 form.positive_button = u'Accept' form.positive_button_ui_flags = Message.UI_FLAG_EXPECT_NEXT_WAIT_5 form.type = SignTO.TYPE form.widget = widget attachment = AttachmentTO() attachment.content_type = u'application/pdf' attachment.download_url = pdf_url attachment.name = attachment_name member_user, app_id = get_app_user_tuple(app_user) messaging.send_form( api_key=get_rogerthat_api_key(), parent_message_key=None, member=member_user.email(), message= u'Please review the purchase agreement and press the "Sign" button to accept.', form=form, flags=0, alert_flags=Message.ALERT_FLAG_VIBRATE, branding=get_main_branding_hash(), tag=json.dumps({ u'__rt__.tag': u'sign_investment_agreement', u'agreement_id': agreement_key.id() }).decode('utf-8'), attachments=[attachment], app_id=app_id, step_id=u'sign_investment_agreement')
def send_document_sign_message(document_key, username, pdf_url, attachment_name, pdf_size, tag, flow, push_message): app_user = get_app_user_from_iyo_username(username) logging.debug('Sending sign widget to app user %s for document %s', app_user, document_key) form = SignFormTO( positive_button_ui_flags=Message.UI_FLAG_EXPECT_NEXT_WAIT_5, widget=SignTO(algorithm=KEY_ALGORITHM, key_name=KEY_NAME, payload=base64.b64encode(pdf_url).decode('utf-8'))) attachment = AttachmentTO(content_type=u'application/pdf', download_url=pdf_url, name=attachment_name, size=pdf_size) tag = json.dumps({ u'__rt__.tag': tag, u'document_id': document_key.id() }).decode('utf-8') flow_params = json.dumps({ 'form': form.to_dict(), 'attachments': [attachment.to_dict()] }) email, app_id = get_app_user_tuple(app_user) members = [MemberTO(member=email.email(), app_id=app_id, alert_flags=0)] messaging.start_local_flow(get_rogerthat_api_key(), None, members, None, tag=tag, context=None, flow=flow, push_message=push_message, flow_params=flow_params)
def _send_order_node_sign_message(app_user, order_id, pdf_url, attachment_name, order_name, pdf_size): logging.debug('Sending SIGN widget to app user') widget = SignTO(algorithm=KEY_ALGORITHM, key_name=KEY_NAME, payload=base64.b64encode(pdf_url).decode('utf-8')) form = SignFormTO( positive_button_ui_flags=Message.UI_FLAG_EXPECT_NEXT_WAIT_5, widget=widget) attachment = AttachmentTO(content_type=u'application/pdf', download_url=pdf_url, name=attachment_name, size=pdf_size) member_user, app_id = get_app_user_tuple(app_user) members = [ MemberTO(member=member_user.email(), app_id=app_id, alert_flags=0) ] tag = json.dumps({ u'__rt__.tag': u'sign_order_node_tos', u'order_id': order_id }).decode('utf-8') flow_params = json.dumps({ 'order_name': order_name, 'form': form.to_dict(), 'attachments': [attachment.to_dict()] }) messaging.start_local_flow(get_rogerthat_api_key(), None, members, None, tag=tag, context=None, flow=FLOW_SIGN_HOSTING_AGREEMENT, flow_params=flow_params)
def put_agenda_app_data(): data = {'agenda_events': [event.to_dict() for event in Event.list()]} system.put_service_data(get_rogerthat_api_key(), data) system.publish_changes(get_rogerthat_api_key())
def get(self): api_key = get_rogerthat_api_key() friends.rebuild_synced_roles(api_key, members=[], service_identities=[])
def get_installation(installation_id, **kwargs): return app.get_installation(get_rogerthat_api_key(), installation_id, **kwargs)
def _send_utility_bill_received(app_user): email, app_id = get_app_user_tuple(app_user) members = [MemberTO(member=email.email(), app_id=app_id, alert_flags=0)] messaging.start_local_flow(get_rogerthat_api_key(), None, members, None, flow=FLOW_UTILITY_BILL_RECEIVED)
def list_installation_logs(**kwargs): return app.list_installation_logs(get_rogerthat_api_key(), **kwargs)
def _order_node(order_key, user_email, app_id, steps): logging.info('Receiving order of Zero-Node') app_user = create_app_user_by_email(user_email, app_id) overview_step = get_step(steps, 'message_overview') if overview_step and overview_step.answer_id == u"button_use": api_key = get_rogerthat_api_key() user_data_keys = [ 'name', 'email', 'phone', 'billing_address', 'address', 'shipping_name', 'shipping_email', 'shipping_phone', 'shipping_address' ] user_data = system.get_user_data(api_key, user_email, app_id, user_data_keys) billing_info = ContactInfo(name=user_data['name'], email=user_data['email'], phone=user_data['phone'], address=user_data['billing_address'] or user_data['address']) if user_data['shipping_name']: shipping_info = ContactInfo(name=user_data['shipping_name'], email=user_data['shipping_email'], phone=user_data['shipping_phone'], address=user_data['shipping_address']) else: shipping_info = billing_info updated_user_data = None else: name = get_step_value(steps, 'message_name') email = get_step_value(steps, 'message_email') phone = get_step_value(steps, 'message_phone') billing_address = get_step_value(steps, 'message_billing_address') updated_user_data = { 'name': name, 'email': email, 'phone': phone, 'billing_address': billing_address, } billing_info = ContactInfo(name=name, email=email, phone=phone, address=billing_address) same_shipping_info_step = get_step(steps, 'message_choose_shipping_info') if same_shipping_info_step and same_shipping_info_step.answer_id == u"button_yes": shipping_info = billing_info else: shipping_name = get_step_value(steps, 'message_shipping_name') shipping_email = get_step_value(steps, 'message_shipping_email') shipping_phone = get_step_value(steps, 'message_shipping_phone') shipping_address = get_step_value(steps, 'message_shipping_address') updated_user_data.update({ 'shipping_name': shipping_name, 'shipping_email': shipping_email, 'shipping_phone': shipping_phone, 'shipping_address': shipping_address, }) shipping_info = ContactInfo(name=shipping_name, email=shipping_email, phone=shipping_phone, address=shipping_address) socket_step = get_step(steps, 'message_socket') socket = socket_step and socket_step.answer_id.replace('button_', '') # Only one node is allowed per user, and one per location if NodeOrder.has_order_for_user_or_location( app_user, billing_info.address) and not DEBUG: logging.info('User already has a node order, sending abort message') msg = u'Dear ThreeFold Member, we sadly cannot grant your request to host an additional ThreeFold Node:' \ u' We are currently only allowing one Node to be hosted per ThreeFold Member and location.' \ u' This will allow us to build a bigger base and a more diverse Grid.' subject = u'Your ThreeFold Node request' send_message_and_email(app_user, msg, subject) return # Check if user has invested >= 120 tokens paid_orders = InvestmentAgreement.list_by_status_and_user( app_user, InvestmentAgreement.STATUS_PAID) total_tokens = sum([o.token_count_float for o in paid_orders]) can_host = total_tokens >= REQUIRED_TOKEN_COUNT_TO_HOST def trans(): logging.debug('Storing order in the database') order = NodeOrder(key=order_key, app_user=app_user, tos_iyo_see_id=None, billing_info=billing_info, shipping_info=shipping_info, order_time=now(), status=NodeOrderStatus.APPROVED if can_host else NodeOrderStatus.WAITING_APPROVAL, socket=socket) order.put() if can_host: logging.info( 'User has invested more than %s tokens, immediately creating node order PDF.', REQUIRED_TOKEN_COUNT_TO_HOST) deferred.defer(_create_node_order_pdf, order_key.id(), _transactional=True) else: logging.info( 'User has not invested more than %s tokens, an admin needs to approve this order manually.', REQUIRED_TOKEN_COUNT_TO_HOST) deferred.defer(_inform_support_of_new_node_order, order_key.id(), _transactional=True) deferred.defer(set_hoster_status_in_user_data, order.app_user, False, _transactional=True) if updated_user_data: deferred.defer(put_user_data, app_user, updated_user_data, _transactional=True) ndb.transaction(trans)
def get_main_branding_hash(): api_key = get_rogerthat_api_key() si = system.get_identity(api_key) return si.description_branding