コード例 #1
0
def build_demand_description(user: User) -> str:
    message = _('{} will take the food.\n').format(
        user.info[UserInfoField.NAME.value])
    is_provided_contact_info = False

    if user.info.get(UserInfoField.PHONE.value):
        message += _('Phone: {}\n').format(
            user.info[UserInfoField.PHONE.value])
        is_provided_contact_info = True

    if (user.info.get(UserInfoField.USERNAME.value)
            and user.info.get(UserInfoField.DISPLAY_USERNAME.value)):
        message += _('Telegram: @{}\n').format(
            user.info[UserInfoField.USERNAME.value])
        is_provided_contact_info = True

    if not is_provided_contact_info:
        message += _('No contact info was provided.\n')

    social_status_verbose = translate_social_status_string(
        user.info.get(UserInfoField.SOCIAL_STATUS.value))
    if social_status_verbose is not None:
        message += (_('Social status: %s') % social_status_verbose)

    return message
コード例 #2
0
ファイル: supply_state.py プロジェクト: demidov91/rest_food
class PostingState(State):
    intro = Reply(buttons=[[{
        'text': _('Set time and send'),
        'data': 'set-time',
    }, {
        'text': _('Cancel'),
        'data': 'cancel',
    }]])

    def get_intro(self):
        reply = super().get_intro()
        reply.text = _('Food you can share:\n{}').format(
            build_active_food_message(self.db_user))
        return reply

    def handle(self, text: str, data: str, *args, **kwargs):
        if data == 'set-time':
            return Reply(next_state=SupplyState.SET_TIME)

        if data == 'cancel':
            cancel_supply_message(self.db_user, provider=self.provider)
            return Reply(
                text=_('Product list is cleared.'),
                next_state=SupplyState.READY_TO_POST,
            )

        if text:
            extend_supply_message(self.db_user, text)
コード例 #3
0
def validate_phone_number(text):
    if len(text) > 100:
        raise ValidationError(_('Please, provide only pone number.'))

    number_of_digits = len(re.findall(r'\d', text))
    if number_of_digits < 7:
        raise ValidationError(_('This is not a valid phone number.'))
コード例 #4
0
ファイル: supply_state.py プロジェクト: demidov91/rest_food
    def handle(self, text: str, data: str, *args, **kwargs):
        if data == 'cancel':
            cancel_supply_message(self.db_user, provider=self.provider)
            return Reply(
                text=_('Product list is cleared.'),
                next_state=SupplyState.READY_TO_POST,
            )

        if text:
            if not self.db_user.info.get(
                    UserInfoField.IS_APPROVED_SUPPLY.value):
                logger.warning(
                    'There is an attempt to post a message by user %s',
                    self.db_user.user_id)
                cancel_supply_message(self.db_user, provider=self.provider)
                return Reply(next_state=SupplyState.READY_TO_POST)

            message_id = self.db_user.editing_message_id
            set_message_time(message_id, text)
            publish_supply_event(self.db_user)
            set_message_publication_time(message_id)
            return Reply(
                text=_(
                    "Information is sent. "
                    "I'll notify you when there is someone to take this food."
                ),
                next_state=SupplyState.READY_TO_POST,
            )
コード例 #5
0
def show_non_demanded_message(user, message_id: str):
    message = _('Not yet booked.\n\n%s') % build_short_message_text_by_id(
        message_id=message_id)

    return Reply(text=message,
                 buttons=[[{
                     'text': _('View all messages'),
                     'data': f'c|{SupplyCommand.LIST_MESSAGES}',
                 }]])
コード例 #6
0
def build_supply_user_description(user: User):
    msg = _("Restaurant name: {name}\n"
            "Address: {address}").format(
                name=user.info[UserInfoField.NAME.value],
                address=user.info[UserInfoField.ADDRESS.value])
    if user.info.get(UserInfoField.PHONE.value):
        msg += _('\nPhone: %s') % user.info[UserInfoField.PHONE.value]

    return msg
コード例 #7
0
ファイル: supply_state.py プロジェクト: demidov91/rest_food
 def get_intro(self) -> Reply:
     return Reply(text=_('What to tell the foodsaver?'),
                  buttons=[[{
                      'text':
                      _('Back to the message'),
                      'data':
                      f'c|{SupplyCommand.SHOW_DEMANDED_MESSAGE}|'
                      f'{self.db_user.context["booking_to_cancel"]}'
                  }]])
コード例 #8
0
ファイル: demand_command.py プロジェクト: demidov91/rest_food
def _handle_info(user: User, provider_str: str, supply_user_id: str,
                 message_id: str):
    supply_user = get_user(supply_user_id,
                           provider=Provider(provider_str),
                           workflow=Workflow.SUPPLY)
    message_record = get_supply_message_record_by_id(message_id=message_id)

    if supply_user is None or message_record is None:
        return Reply(_('Information was not found.'))

    info = build_demand_side_full_message_text(supply_user, message_record)

    if message_record.demand_user_id is not None:
        return build_food_taken_message(user, message_record.demand_user_id,
                                        info)

    set_next_command(
        user,
        Command(
            name=DemandCommandName.INFO.value,
            arguments=[provider_str, supply_user_id, message_id],
        ))

    coordinates = supply_user.approved_coordinates()

    buttons = []

    if coordinates is not None:
        buttons.append([{
            'text':
            _('🌍 Map'),
            'data':
            DemandCommandName.MAP_INFO.build(provider_str, supply_user_id,
                                             message_id),
        }])

    take_it_button = {
        'text':
        _('Take it'),
        'data':
        f'{DemandCommandName.TAKE.value}|'
        f'{supply_user.provider.value}|'
        f'{supply_user.user_id}|'
        f'{message_id}',
    }
    back_button = {
        'text':
        _('Back'),
        'data':
        DemandCommandName.SHORT_INFO.build(provider_str, supply_user_id,
                                           message_id),
    }
    buttons.append([back_button, take_it_button])

    return Reply(text=info, buttons=buttons)
コード例 #9
0
ファイル: supply_reply.py プロジェクト: demidov91/rest_food
def build_new_supplier_notification(supply_user: User) -> Reply:
    return Reply(
        text=build_new_supplier_notification_text(supply_user),
        buttons=[[{
            'text': _('Approve'),
            'data': f'c|{SupplyCommand.APPROVE_SUPPLIER}|{supply_user.id}',
        }, {
            'text': _('Decline'),
            'data': f'c|{SupplyCommand.DECLINE_SUPPLIER}|{supply_user.id}',
        }]]
    )
コード例 #10
0
def view_messages(user):
    messages = list_messages(user)
    buttons = [
        _get_demanded_message_button(x)
        if x.demand_user_id else _get_non_demanded_message_button(x)
        for x in messages
    ]
    buttons.append([{
        'text': _('Go to product posting'),
        'data': f'c|{SupplyCommand.BACK_TO_POSTING}'
    }])
    return Reply(text=_('Last messages'), buttons=buttons)
コード例 #11
0
def notify_supplier_is_approved(user: User):
    queue_messages(
        tg_chat_id=user.chat_id,
        workflow=Workflow.SUPPLY,
        replies=[
            Reply(text=_('Your account is approved!'),
                  buttons=[[{
                      'data': f'c|{SupplyCommand.BACK_TO_POSTING}',
                      'text': _('OK ✅'),
                  }]])
        ],
    )
コード例 #12
0
ファイル: supply_state.py プロジェクト: demidov91/rest_food
    def get_intro(self) -> Reply:
        buttons = [[{
            'text': _('❌ Dismiss')
        }, {
            'text': _('Send phone'),
            'request_contact': True
        }]]

        return Reply(
            text=_('Please, send your contact number.'),
            buttons=buttons,
            is_text_buttons=True,
        )
コード例 #13
0
ファイル: supply_state.py プロジェクト: demidov91/rest_food
 def _build_approve_intro(self):
     return Reply(
         coordinates=self.db_user.info[UserInfoField.COORDINATES.value],
         buttons=[[{
             'text': _('No! Edit! 🌍'),
             'data': 'change-coordinates',
         }], [{
             'text': _('Yes! Approve ✅'),
             'data': 'approve-coordinates',
         }], [{
             'text': _('Cancel'),
             'data': 'cancel',
         }]])
コード例 #14
0
 def _get_action_buttons(self, message_id: str):
     return [{
         'text':
         _('Back'),
         'data':
         DemandCommandName.INFO.build(self.supply_user.provider.value,
                                      self.supply_user.user_id, message_id)
     }, {
         'text':
         _('Take it'),
         'data':
         DemandCommandName.TAKE.build(self.supply_user.provider.value,
                                      self.supply_user.user_id, message_id)
     }]
コード例 #15
0
ファイル: supply_state.py プロジェクト: demidov91/rest_food
    def _get_intro_text(self):
        if self.db_user.info.get(UserInfoField.IS_APPROVED_SUPPLY.value):
            return _('Enter food you can share and click "send"')

        if self.db_user.info.get(
                UserInfoField.IS_APPROVED_SUPPLY.value) is False:
            return (_(
                'Your account was declined. Please, contact %s for any clarifications.'
            ) % FEEDBACK_TG_BOT)

        notify_admin_about_new_supply_user_if_necessary(self.db_user)

        return (_(
            "We'll notify you when your account is approved. Also, you can contact us with %s"
        ) % FEEDBACK_TG_BOT)
コード例 #16
0
ファイル: supply_state.py プロジェクト: demidov91/rest_food
    def _build_set_intro(self):
        reply = Reply(
            text=_('Please, send me your coordinates. (Attach -> Location)'))
        if self.info_field_is_set():
            reply.buttons = [[{
                'text': _('Cancel'),
                'data': 'cancel',
            }]]
        else:
            reply.buttons = [[{
                'text': _('Provide later'),
                'data': 'later',
            }]]

        return reply
コード例 #17
0
def build_demanded_message_text(*, demand_user: User, supply_user: User,
                                message_id: str) -> str:
    demand_description = build_demand_description(demand_user)
    food_description = build_short_message_text_by_id(message_id=message_id)

    return _("{}\n\nYour message was:\n\n{}").format(demand_description,
                                                     food_description)
コード例 #18
0
def build_new_supplier_notification_text(supply_user: User):
    return (_(
        '{user_name} wants to join as a supplier. Provided description is:\n\n{description}'
    ).format(
        user_name=_introduce_new_user(supply_user),
        description=build_supply_user_description(supply_user),
    ))
コード例 #19
0
def message_to_text(message: Message) -> str:
    text_message = '\n'.join([x for x in message.products if x])

    if message.take_time:
        text_message += _('\nTime: {}').format(message.take_time)

    return text_message
コード例 #20
0
ファイル: supply_state.py プロジェクト: demidov91/rest_food
    def get_intro(self) -> Reply:
        buttons = [[{
            'text': _('← Back')
        }, {
            'text': _('Send phone'),
            'request_contact': True
        }]]

        if self.info_field_is_set():
            buttons[0].insert(1, {'text': _('❌ Delete')})

        return Reply(
            text=_('Please, send your contact number.'),
            buttons=buttons,
            is_text_buttons=True,
        )
コード例 #21
0
ファイル: demand_command.py プロジェクト: demidov91/rest_food
def _handle_booked(user: User, supply_provider: str, supply_user_id: str,
                   message_id: str):
    supply_user = get_supply_user(user_id=supply_user_id,
                                  provider=Provider(supply_provider))
    return build_demand_side_message_by_id(supply_user,
                                           message_id,
                                           intro=_("You've booked this"))
コード例 #22
0
    def get_intro(self) -> Reply:
        buttons = [[{
            'text': _('← Back')
        }, {
            'text': _('Send phone'),
            'request_contact': True
        }]]

        if self._info_field.value in self.db_user.info:
            buttons[0].insert(1, {'text': _('❌ Delete')})

        return Reply(
            text=_('Send your phone number'),
            buttons=buttons,
            is_text_buttons=True,
        )
コード例 #23
0
def build_supplier_declined_text(user: User):
    return _('{user_name} was DECLINED as a supplier. '
             'Provided description was:\n\n{description}\n\n'
             'DB id: {id}').format(
                 user_name=_introduce_new_user(user),
                 description=build_supply_user_description(user),
                 id=user.id,
             )
コード例 #24
0
ファイル: supply_state.py プロジェクト: demidov91/rest_food
 def handle(self, text: str, data=None, coordinates=None):
     notify_demand_for_cancel(
         supply_user=self.db_user,
         message_id=self.db_user.context['booking_to_cancel'],
         message=text)
     cancel_booking(supply_user=self.db_user,
                    message_id=self.db_user.context['booking_to_cancel'])
     return Reply(text=_('Cancelled'), next_state=SupplyState.READY_TO_POST)
コード例 #25
0
    def build(self, message_id: str):
        coordinates = self.supply_user.approved_coordinates()

        if coordinates is None:
            logger.error('Map is requested while coordinates where not set.')
            return Reply(text=_('Coordinates where not provided.'))

        buttons = [[{
            'text':
            _('Open in app'),
            'url':
            f'https://dzmitry.by/redirect?to=geo:{coordinates[0]},{coordinates[1]}?z=21',
        }]]

        buttons.append(self._get_action_buttons(message_id))

        return Reply(coordinates=coordinates, buttons=buttons)
コード例 #26
0
def _get_non_demanded_message_button(message: Message):
    return [{
        'text':
        _('%s (not booked)') %
        db_time_to_user(message.dt_published, '%d-%m %H:%M'),
        'data':
        f'c|{SupplyCommand.SHOW_NON_DEMANDED_MESSAGE}|{message.message_id}'
    }]
コード例 #27
0
ファイル: supply_state.py プロジェクト: demidov91/rest_food
    def get_intro(self) -> Reply:
        reply = Reply(text=self._message)
        if self.info_field_is_set():
            reply.buttons = [[{
                'text': _('Cancel'),
                'data': 'cancel',
            }]]

        return reply
コード例 #28
0
ファイル: supply_state.py プロジェクト: demidov91/rest_food
    def handle_text(self, text):
        text = text or ''
        if text.startswith('❌'):
            unset_info(self.db_user, self._info_to_edit)
            return Reply(text=_('OK ✅'), next_state=self.get_next_state())

        if text.startswith('←'):
            return Reply(text=_('OK ✅'), next_state=self.get_next_state())

        try:
            validate_phone_number(text)
        except ValidationError as e:
            return Reply(text=e.message)

        reply = super().handle_text(text)
        reply.text = _(
            'OK ✅'
        )  # Text response is required to clear telegram text keyboard.
        return reply
コード例 #29
0
def build_demand_side_short_message(supply_user: User, message_id: str):
    text_message = build_short_message_text_by_id(message_id=message_id)
    return Reply(
        text=_('{} can share the following:\n{}').format(
            supply_user.info[UserInfoField.NAME.value], text_message),
        buttons=[[{
            'text':
            _('Take it'),
            'data':
            DemandCommandName.TAKE.build(supply_user.provider.value,
                                         supply_user.user_id, message_id),
        }, {
            'text':
            _('Info'),
            'data':
            DemandCommandName.INFO.build(supply_user.provider.value,
                                         supply_user.user_id, message_id)
        }]],
    )
コード例 #30
0
def notify_supplier_is_declined(user: User):
    queue_messages(
        tg_chat_id=user.chat_id,
        workflow=Workflow.SUPPLY,
        replies=[
            Reply(text=(_(
                'Your account was declined. Please, contact %s for any clarifications.'
            ) % FEEDBACK_TG_BOT))
        ],
    )