コード例 #1
0
    def on_hook(cls, data):
        text = data.get('text')

        try:
            exchange = Exchange.objects.get(out_id=data.get('from_id'))
        except Exchange.DoesNotExist:
            exchange = Exchange(out_id=data.get('from_id'))
            exchange.save()

        if cls.match_command('/start', text):
            if exchange.title and exchange.phone:
                exchange.active = True
                exchange.save()
            cls.send(
                chat_id=data.get('chat_id'),
                text=Text.format('EX_MSG_WELCOME'),
                reply_markup=ReplyKeyboardHide().to_json()
            )
            return

        if cls.match_command('/id', text):
            cls.send(
                chat_id=data.get('chat_id'),
                text=Text.format('EX_TLGRM_ID', data.get('chat_id')),
                reply_markup=ReplyKeyboardHide().to_json()
            )
            return
        elif cls.match_command('/stop', text):
            exchange.active = False
            exchange.save()
            cls.send(
                chat_id=data.get('chat_id'),
                text=Text.format('EX_MSG_STOP'),
                reply_markup=ReplyKeyboardHide().to_json()
            )
            return

        data['exchange'] = exchange
        data['exchange_id'] = exchange.get_id()

        if cls.match_command('/update', text):
            cls.updating[exchange.get_id()] = {'step': 0}
        elif cls.match_command('/confirm', text):
            data['args'] = cls.match_command('/confirm', text).get('args')
            cls._confirm(data)
            return

        if exchange.get_id() in cls.updating:
            cls._updating(data)
コード例 #2
0
def send_fails(requests=None):
    if requests is None:
        date = datetime.datetime.now(tz=timezone('UTC'))
        date -= datetime.timedelta(seconds=Interval.seconds('fail_timeout'))

        q = (
                Q(exchange__exists=False) |
                Q(exchange=None)
            ) & \
            Q(fail_sended=False) & \
            Q(update_date__lt=date) & \
            Q(step=awa_client.STEP_SEARCH_EXCHANGE)

        requests = Request.objects(q)
        if len(requests) > 0:
            logger.info('Found fails')
        else:
            logger.debug('No fails')
            return

    for request in requests:
        request.fail_sended = True
        request.step = STEP_NO_RESPONSE
        request.user = request.user
        request.save()

        logger.info('Send fail: {0}'.format(request.user.out_id))
        yield DollarublSubBot(chat_id=request.user.out_id,
                              parent_bot=SekonomBot()).send(
                                  Text.format('CL_FAIL_RESERV_TIMEOUT'))
コード例 #3
0
    def _on_confirm(cls, **kwargs):
        text = kwargs.get('text')
        request = kwargs.get('request')
        user = kwargs.get('user')

        if text == Text.format('CL_CONFIRM_YES'):
            request.step = awa_client.STEP_ENTER_GEO
            request.save()

            cls.send(chat_id=kwargs.get('chat_id'),
                     text=Text.format('CL_SEND_GEO'),
                     reply_markup=ReplyKeyboard(keyboard=[[
                         KeyboardButton(text=u'Отправить гео-позицию',
                                        request_location=True)
                     ]]).to_json())
        elif text == Text.format('CL_CONFIRM_NO'):
            user.current_request = None
            user.save()
            cls.send(chat_id=kwargs.get('chat_id'),
                     text=Text.format('CL_OPERATION_CANCEL'),
                     reply_markup=cls._start_keyboard())
        else:
            keyboard = ReplyKeyboard(keyboard=[[
                Text.format('CL_CONFIRM_YES'),
                Text.format('CL_CONFIRM_NO')
            ]])
            cls.send(chat_id=kwargs.get('chat_id'),
                     text=Text.format('CL_CONFIRM_REPEAT'),
                     reply_markup=keyboard.to_json())
コード例 #4
0
    def on_hook(cls, data):
        try:
            user = User.objects.get(out_id=data.get('from_id'))
            user.username = data.get('from_username')
            user.save()
        except User.DoesNotExist:
            user = User(out_id=data.get('from_id'),
                        name=data.get('from_first_name'),
                        surname=data.get('from_last_name'),
                        username=data.get('from_username'))
            user.save()

        if user.current_request is None or Request.objects(
                pk=user.current_request.id).count() == 0:
            request = Request(user=user)
            request.save()

            user.current_request = request
            user.save()
        else:
            request = Request.objects.get(pk=user.current_request.id)

        request.user = user
        data['user'] = user
        data['request'] = request

        text = data.get('text')

        if repr(text) in [
                repr(u'Не менял'),
                repr(emoji.emojize(':star:', True)),
                repr(emoji.emojize(':star::star:', True)),
                repr(emoji.emojize(':star::star::star:', True)),
                repr(emoji.emojize(':star::star::star::star:', True)),
                repr(emoji.emojize(':star::star::star::star::star:', True))
        ]:
            cls._on_rating(**data)
            return

        if cls.match_command('/start', text) or cls.match_command(
                Text.format('CL_NEW_EXCHANGE'), text):
            cls._on_start(**data)
        elif request.step == awa_client.STEP_INPUT_OPERATION:
            cls._on_choose_type(**data)
        elif request.step == awa_client.STEP_INPUT_AMOUNT:
            cls._on_enter_amount(**data)
        elif request.step == awa_client.STEP_CONFIRM:
            cls._on_confirm(**data)
        elif request.step in [
                awa_client.STEP_ENTER_GEO, awa_client.STEP_CONFIRM_NO_TESTING
        ]:
            cls._on_enter_geo(**data)
        else:
            cls._try_get_comment(**data)
コード例 #5
0
    def _on_rating(cls, **kwargs):
        q = Q(rating_request_send=True) & Q(
            step=awa_client.STEP_SEARCH_SUCCESS)

        text = kwargs.get('text')

        request = Request.objects(q).order_by('-update_date').first()
        if not request:
            return

        if repr(text) == repr(u'Не менял'):
            request.rating_value = None
        elif repr(text) == repr(emoji.emojize(':star:', True)):
            request.rating_value = 1
        elif repr(text) == repr(emoji.emojize(':star::star:', True)):
            request.rating_value = 2
        elif repr(text) == repr(emoji.emojize(':star::star::star:', True)):
            request.rating_value = 3
        elif repr(text) == repr(emoji.emojize(':star::star::star::star:',
                                              True)):
            request.rating_value = 4
        elif repr(text) == repr(
                emoji.emojize(':star::star::star::star::star:', True)):
            request.rating_value = 5

        request.user = request.user
        request.save()

        if request.rating_value is not None:
            if request.rating_value < 4:
                AwaClientBot.send(
                    chat_id=kwargs.get('chat_id'),
                    text=Text.format('CL_RATING_COMMENT_REQUEST'))
            else:
                AwaClientBot.send(chat_id=kwargs.get('chat_id'),
                                  text=Text.format('CL_RATING_COMMENT_GOOD'),
                                  reply_markup=cls._start_keyboard())
        else:
            AwaClientBot.send(chat_id=kwargs.get('chat_id'),
                              text=Text.format('CL_RATING_COMMENT_GOOD_DAY'),
                              reply_markup=cls._start_keyboard())
コード例 #6
0
    def _updating(cls, data):
        updating = cls.updating[data.get('exchange_id')]
        step = updating.get('step', 0)
        exchange = data['exchange']
        kwargs = {}
        if step == 0:
            title = str(exchange.title)
            if title != 'None':
                keyboard = ReplyKeyboardHide(keyboard=[[title]])
                kwargs['reply_markup'] = keyboard.to_json()
            cls.send(chat_id=data.get('chat_id'), text=Text.format('EX_MSG_ENTER_TITLE'), **kwargs)
        elif step == 1:
            exchange.title = data.get('text')
            exchange.save()

            phone = str(exchange.phone)
            if phone != 'None':
                keyboard = ReplyKeyboardHide(keyboard=[[phone]])
                kwargs['reply_markup'] = keyboard.to_json()

            cls.send(chat_id=data.get('chat_id'), text=Text.format('EX_MSG_ENTER_PHONE'), **kwargs)
        elif step == 2:
            exchange.phone = data.get('text')
            exchange.save()

            keyboard = ReplyKeyboard(keyboard=[[KeyboardButton(text=u'Отправить гео-позицию', request_location=True)]])
            kwargs['reply_markup'] = keyboard.to_json()

            cls.send(chat_id=data.get('chat_id'), text=Text.format('EX_MSG_ENTER_LOCATION'), **kwargs)
        elif step == 3:
            location = data.get('location')
            if location is None:
                cls.send(chat_id=data.get('chat_id'), text=Text.format('EX_MSG_ENTER_LOCATION'))
                return
            else:
                exchange.geo = [location.get('latitude'), location.get('longitude')]
                exchange.save()

                cls.send(
                    chat_id=data.get('chat_id'),
                    text=Text.format('EX_MSG_ENTER_ADDRESS'),
                    reply_markup=ReplyKeyboardHide().to_json()
                )
        elif step == 4:
            exchange.address = data.get('text')
            exchange.active = True
            exchange.save()
            cls.send(
                chat_id=data.get('chat_id'),
                text=Text.format('EX_MSG_UPDATED'),
                reply_markup=ReplyKeyboardHide().to_json()
            )

            del cls.updating[data.get('exchange_id')]
            return

        updating['step'] = step + 1
        cls.updating[data.get('exchange_id')] = updating
コード例 #7
0
    def _try_get_comment(cls, **kwargs):
        q = Q(rating_request_send=True) & \
            Q(step=awa_client.STEP_SEARCH_SUCCESS) & \
            Q(rating_value__lt=4) & \
            Q(rating_comment='')
        request = Request.objects(q).order_by('-update_date').first()

        if not request:
            request = kwargs.get('request')
            if request and request.step == awa_client.STEP_SEARCH_SUCCESS:
                cls.send(chat_id=kwargs.get('chat_id'),
                         text=Text.format('CL_ORDER_FORMED'),
                         reply_markup=cls._start_keyboard())
            return

        text = kwargs.get('text')

        request.user = request.user
        request.rating_comment = text
        request.save()

        AwaClientBot.send(chat_id=kwargs.get('chat_id'),
                          text=Text.format('CL_RATING_COMMENT_GOOD'),
                          reply_markup=cls._start_keyboard())
コード例 #8
0
def rating_request_send():
    date = datetime.datetime.now(tz=timezone('UTC'))
    date -= datetime.timedelta(
        seconds=Interval.seconds('rating_request_timeout'))

    q = Q(rating_request_send=False) & \
        Q(update_date__lte=date) & \
        Q(step=awa_client.STEP_SEARCH_SUCCESS)

    requests = Request.objects(q).order_by('-update_date')

    users = set()
    for request in requests:
        if request.user.get_id() not in users:
            request.rating_request_send = True
            request.user = request.user
            request.save()

            keyboard = ReplyKeyboard(keyboard=[
                [u'Не менял', emoji.emojize(':star:', True)],
                [
                    emoji.emojize(':star::star:', True),
                    emoji.emojize(':star::star::star:', True)
                ],
                [
                    emoji.emojize(':star::star::star::star:', True),
                    emoji.emojize(':star::star::star::star::star:', True)
                ]
            ])

            yield DollarublSubBot(chat_id=request.user.out_id,
                                  parent_bot=SekonomBot()).send(
                                      Text.format('CL_REQUEST_RATING'),
                                      reply_markup=keyboard)

            users.add(request.user.get_id())
コード例 #9
0
 def keys(self):
     keys = Text.defaults().keys()
     self.send_success_response(data=sorted(keys))
コード例 #10
0
    def _on_start(cls, **kwargs):
        keyboard = []
        currs = {}
        codes = set()

        for item in Currency.objects:
            codes.add(item.code.upper())
            currs[item.code.upper() + '_' + item.direct] = item.value

        codes = sorted(list(codes),
                       key=lambda x: ['USD', 'EUR', 'GBR', 'CHF'].index(x))
        welcome_currencies = []

        for code in codes:
            if code == 'USD':
                keyboard.append([
                    awa_client.CURRENCY_EXCHANGE[Request.TYPE_BUY_USD],
                    awa_client.CURRENCY_EXCHANGE[Request.TYPE_SAIL_USD]
                ])
                welcome_currencies.append('доллар {0}/{1}'.format(
                    currs.get('USD_sale'), currs.get('USD_buy')))
            elif code == 'EUR':
                keyboard.append([
                    awa_client.CURRENCY_EXCHANGE[Request.TYPE_BUY_EUR],
                    awa_client.CURRENCY_EXCHANGE[Request.TYPE_SAIL_EUR]
                ])
                welcome_currencies.append('евро {0}/{1}'.format(
                    currs.get('EUR_sale'), currs.get('EUR_buy')))
            elif code == 'GBR':
                keyboard.append([
                    awa_client.CURRENCY_EXCHANGE[Request.TYPE_BUY_GBR],
                    awa_client.CURRENCY_EXCHANGE[Request.TYPE_SAIL_GBR]
                ])
                welcome_currencies.append('фунт стерлингов {0}/{1}'.format(
                    currs.get('GBR_sale'), currs.get('GBR_buy')))
            elif code == 'CHF':
                keyboard.append([
                    awa_client.CURRENCY_EXCHANGE[Request.TYPE_BUY_CHF],
                    awa_client.CURRENCY_EXCHANGE[Request.TYPE_SAIL_CHF]
                ])
                welcome_currencies.append('швейцарский франк {0}/{1}'.format(
                    currs.get('CHF_sale'), currs.get('CHF_buy')))

        keyboard = ReplyKeyboard(keyboard=keyboard)

        cls.send(chat_id=kwargs.get('chat_id'),
                 text=Text.format('CL_MSG_WELCOME',
                                  "\n".join(welcome_currencies)),
                 reply_markup=keyboard.to_json())

        user = kwargs.get('user')
        request = kwargs.get('request')

        if request.step > awa_client.STEP_ZERO:
            request = Request(user=user)

        request.step = awa_client.STEP_INPUT_OPERATION
        request.save()

        user.current_request = request
        user.save()
コード例 #11
0
 def _start_keyboard(cls):
     return ReplyKeyboard(keyboard=[[Text.format('CL_NEW_EXCHANGE')]],
                          one_time_keyboard=False).to_json()
コード例 #12
0
    def _on_enter_geo(cls, **kwargs):
        request = kwargs.get('request')
        location = kwargs.get('location')
        text = kwargs.get('text')
        user = kwargs.get('user')

        if location is None and request.geo is None:
            cls.send(chat_id=kwargs.get('chat_id'),
                     text=Text.format('CL_SEND_GEO'))
        else:
            if location is not None:
                location = [
                    location.get('latitude'),
                    location.get('longitude')
                ]
                request.geo = location
                request.save()

            if options.enable_testing_question:
                keyboard = ReplyKeyboard(keyboard=[[
                    Text.format('CL_YES_REAL_RESERVE'),
                    Text.format('CL_NO_TESTING')
                ]])

                if request.step == awa_client.STEP_ENTER_GEO:
                    request.step = awa_client.STEP_CONFIRM_NO_TESTING
                    request.save()

                    return cls.send(chat_id=kwargs.get('chat_id'),
                                    text=Text.format('CL_CONFIRM_TESTING'),
                                    reply_markup=keyboard.to_json())
                elif request.step == awa_client.STEP_CONFIRM_NO_TESTING:
                    if text == Text.format('CL_YES_REAL_RESERVE'):
                        pass
                    elif text == Text.format('CL_NO_TESTING'):
                        request.step = awa_client.STEP_TEST_REQUEST
                        request.save()

                        user.current_request = None
                        user.save()

                        return cls.send(chat_id=kwargs.get('chat_id'),
                                        text=Text.format('CL_CANCEL_REQUEST'),
                                        reply_markup=cls._start_keyboard())
                    else:
                        return cls.send(chat_id=kwargs.get('chat_id'),
                                        text=Text.format('CL_CONFIRM_TESTING'),
                                        reply_markup=keyboard.to_json())

            request.step = awa_client.STEP_SEARCH_EXCHANGE
            request.save()

            min_distance = 0
            is_found = False

            logger.info('Location: {0}'.format(repr(location)))
            for max_distance in [Interval.get('max_radius') * 1000.0]:
                exchanges = Exchange.objects(active=True,
                                             geo__near=request.geo,
                                             geo__min_distance=min_distance,
                                             geo__max_distance=max_distance)

                if len(exchanges) > 0:
                    logger.info('Found {0} exchanges in {1} distance'.format(
                        len(exchanges), max_distance))
                    is_found = True
                    for exchange in exchanges:
                        logger.info('Exchange location: {0}'.format(
                            repr(exchange.geo)))

                        from bots.awa_exchange import AwaExchangeBot
                        course = request.course
                        text = Text.format('EX_EXCHANGE_REQUEST',
                                           request.number, request.type,
                                           request.amount, '%.2f' % course)
                        AwaExchangeBot.send(chat_id=exchange.out_id, text=text)
                    break
                else:
                    logger.warning(
                        'Not found exchanges in {0} distance'.format(
                            max_distance))

                min_distance = max_distance

            if not is_found:
                request.step = awa_client.STEP_SEARCH_FAIL
                request.save()

                user.current_request = None
                user.save()

            cls.send(chat_id=kwargs.get('chat_id'),
                     text=Text.format(
                         'CL_RESERV' if is_found else 'CL_FAIL_RESERV'),
                     reply_markup=cls._start_keyboard())
コード例 #13
0
    def _on_enter_amount(cls, **kwargs):
        text = kwargs.get('text')
        amount = utils.to_int(text, None)
        request = kwargs.get('request')

        if amount is None:
            cls.send(chat_id=kwargs.get('chat_id'), text=u'Введите число')
        else:
            request.amount = amount
            request.step = awa_client.STEP_CONFIRM
            request.save()

            keyboard = ReplyKeyboard(keyboard=[[
                Text.format('CL_CONFIRM_YES'),
                Text.format('CL_CONFIRM_NO')
            ]])

            currencies = {}
            for item in Currency.objects:
                currencies[item.code.upper() + '_' + item.direct] = float(
                    item.value)

            if request.type == Request.TYPE_BUY_USD:
                course = str(currencies.get('USD_buy', 0)) + u' руб/$'
                operation = [
                    u'покупаете',
                    cls.num_split(request.amount), u'$', course,
                    cls.num_split(request.amount *
                                  currencies.get('USD_buy', 0))
                ]
            elif request.type == Request.TYPE_SAIL_USD:
                course = str(currencies.get('USD_sale', 0)) + u' руб/$'
                operation = [
                    u'продаете',
                    cls.num_split(request.amount), u'$', course,
                    cls.num_split(request.amount *
                                  currencies.get('USD_sale', 0))
                ]
            elif request.type == Request.TYPE_BUY_EUR:
                course = str(currencies.get('EUR_buy', 0)) + u' руб/€'
                operation = [
                    u'покупаете',
                    cls.num_split(request.amount), u'€', course,
                    cls.num_split(request.amount *
                                  currencies.get('EUR_buy', 0))
                ]
            elif request.type == Request.TYPE_SAIL_EUR:
                course = str(currencies.get('EUR_sale', 0)) + u' руб/€'
                operation = [
                    u'продаете',
                    cls.num_split(request.amount), u'€', course,
                    cls.num_split(request.amount *
                                  currencies.get('EUR_sale', 0))
                ]
            elif request.type == Request.TYPE_BUY_GBR:
                course = str(currencies.get('GBR_buy', 0)) + u' руб/' + GBR
                operation = [
                    u'покупаете',
                    cls.num_split(request.amount), GBR, course,
                    cls.num_split(request.amount *
                                  currencies.get('GBR_buy', 0))
                ]
            elif request.type == Request.TYPE_SAIL_GBR:
                course = str(currencies.get('GBR_sale', 0)) + u' руб/' + GBR
                operation = [
                    u'продаете',
                    cls.num_split(request.amount), GBR, course,
                    cls.num_split(request.amount *
                                  currencies.get('GBR_sale', 0))
                ]

            elif request.type == Request.TYPE_BUY_CHF:
                course = str(currencies.get('CHF_buy', 0)) + u' руб/' + CHF
                operation = [
                    u'покупаете',
                    cls.num_split(request.amount), CHF, course,
                    cls.num_split(request.amount *
                                  currencies.get('CHF_buy', 0))
                ]
            elif request.type == Request.TYPE_SAIL_CHF:
                course = str(currencies.get('CHF_sale', 0)) + u' руб/' + CHF
                operation = [
                    u'продаете',
                    cls.num_split(request.amount), CHF, course,
                    cls.num_split(request.amount *
                                  currencies.get('CHF_sale', 0))
                ]
            else:
                return

            cls.send(chat_id=kwargs.get('chat_id'),
                     text=Text.format('CL_CONFIRM', *operation),
                     reply_markup=keyboard.to_json())
コード例 #14
0
 def t(self, key, *args):
     if isinstance(key, list):
         return [Text.format(item, self.user.lang, *args) for item in key]
     else:
         return Text.format(key, self.user.lang, *args)
コード例 #15
0
 def keys(self):
     keys = list(Text.defaults().keys())
     keys.sort()
     self.send_success_response(data=keys)
コード例 #16
0
    def _confirm(cls, data=None, request=None, exchange=None, external_id=None):
        if data is None:
            data = {}
        if exchange is None and request is None and external_id is None:
            number = utils.to_int(data.get('args')[0], -1)
            if number < 0:
                cls.send(
                    chat_id=data.get('chat_id'),
                    text=Text.format('EX_BAD_NUMBER'),
                    reply_markup=ReplyKeyboardHide().to_json()
                )
                return

            try:
                external_id = utils.to_int(data.get('args')[1], -1)
                if external_id < 0:
                    raise Exception
            except:
                cls.send(
                    chat_id=data.get('chat_id'),
                    text=Text.format('EX_BAD_EXTERNAL_ID'),
                    reply_markup=ReplyKeyboardHide().to_json()
                )
                return

            try:
                request = Request.objects(number=number).get()
            except:
                cls.send(
                    chat_id=data.get('chat_id'),
                    text=Text.format('EX_REQUEST_NOT_FOUND'),
                    reply_markup=ReplyKeyboardHide().to_json()
                )
                return
            if request.fail_sended:
                cls.send(
                    chat_id=data.get('chat_id'),
                    text=Text.format('EX_REQUEST_TIMEOUT'),
                    reply_markup=ReplyKeyboardHide().to_json()
                )
                return

            exchange = data['exchange']

        if request.exchange is None:
            request.exchange = exchange
            request.step = STEP_SEARCH_SUCCESS
            request.external_id = external_id
            try:
                request.distance = vincenty(request.geo.get('coordinates'),
                                            exchange.geo.get('coordinates')).meters / 1000.0
            except:
                pass
            request.user = request.user
            request.save()

            cls.send(
                chat_id=exchange.out_id,
                text=Text.format('EX_SUCCESS', external_id),
                reply_markup=ReplyKeyboardHide().to_json()
            )

            from bots.awa_client import AwaClientBot
            AwaClientBot.send(
                chat_id=request.user.out_id,
                text=Text.format('CL_SUCCESS_RESERV', exchange.address, exchange.phone, request.external_id)
            )
            AwaClientBot.sendLocation(
                chat_id=request.user.out_id,
                latitude=exchange.geo.get('coordinates')[0],
                longitude=exchange.geo.get('coordinates')[1]
            )

            time = datetime.datetime.now()
            time += datetime.timedelta(seconds=Interval.seconds('reserve_time'))

            AwaClientBot.send(
                chat_id=request.user.out_id,
                text=Text.format('CL_SUCCESS_WARNING', time.strftime('%d.%m.%Y %H:%M'))
            )
        else:
            cls.send(
                chat_id=data.get('chat_id'),
                text=Text.format('EX_ALREADY_SEND'),
                reply_markup=ReplyKeyboardHide().to_json()
            )