예제 #1
0
def callback_seance_text(tuid, bot, chat_id, text, cmd, profile):

    # in profile.cmd should be movie id
    # need concatenate movie with place

    if 'num' not in profile.cmd:
        return

    i_n = profile.cmd.index('num')
    movie_id = profile.cmd[len('/location'):i_n]

    film = Film.get_by_id(movie_id)

    cmd = cmd.encode('utf-8')

    # poor place of the code - every time new request to kinohod db
    film_cinemas, city_id = detect_film_cinemas(chat_id, movie_id, date=None)

    if not film_cinemas or len(film_cinemas) < 1:
        bot.sendMessage(chat_id, settings.NO_FILM_SEANCE)
        return

    parser = Parser(request=cmd, state='cinema', city_id=city_id)
    parser.parse()

    bot.sendChatAction(chat_id, action='typing')

    seances = []

    if not parser.data.place:
        pass
        # bot.sendMessage(chat_id, settings.CINEMA_NOT_FOUND)
    else:
        for p in parser.data.place:
            if not p or p.key not in film_cinemas:
                continue

            seances.append(
                settings.RowCinema(p.shortTitle, p.address, p.mall,
                                   '/c{}m{}'.format(p.kinohod_id, movie_id)))

    if len(seances) < 1:
        bot.sendMessage(chat_id, settings.NO_FILM_SEANCE)
        send_reply(bot, chat_id, get_cinemas_where_film, film,
                   settings.CINEMAS_TO_DISPLAY, chat_id)
        return

    template = settings.JINJA_ENVIRONMENT.get_template('cinema_where_film.md')
    msg = template.render({'film_name': film.title, 'seances': seances})

    mark_up = InlineKeyboardMarkup(inline_keyboard=[[
        dict(text=settings.MORE,
             callback_data='/where_film{}num{}'.format(
                 film.kinohod_id, settings.CINEMAS_TO_DISPLAY))
    ]])

    bot.sendMessage(chat_id, msg, parse_mode='Markdown', reply_markup=mark_up)
예제 #2
0
    def preprocess_when(self, info):
        for text, r in info.iteritems():
            parser = Parser(text, 'time')
            time = parser.parse()

            parser.data.when = time[0]
            self.assertIsNotNone(parser.data.when)

            self.assertTrue(
                parser.data.when.strftime('%d%m') == r.strftime('%d%m'),
                msg='recognition is not correct {} {} in msg={}'.format(
                    parser.data.when.strftime('%d%m'), r.strftime('%d%m'),
                    text))
예제 #3
0
    def preprocess_for_place(self, info):
        for text, r in info.iteritems():
            parser = Parser(text, 'base')
            parser.parse()

            self.assertIsNotNone(parser.data.place,
                                 msg='does not detect place correctly')

            for p in parser.data.place:
                place = p['shortTitle'], p['address'], p['mall']
                place = [c.lower().encode('utf-8') for c in place if c]
                self.assertTrue(sum([(1 if c.find(r.lower()) > -1 else 0)
                                     for c in place]) > 0,
                                msg='error, result: {} enter: {}'.format(
                                    r, ' '.join(place)))
예제 #4
0
    def test_combination_what_place(self):
        info = {
            'хочу билет на {} на павелецкой': [{}, 'павелецк'],
            '{} на арбате': ['{}', 'арбат'],
            '{} в пионер завтра': ['{}', 'пионер']
        }

        info = self.gen_info_film(info)
        for text, r in info.iteritems():
            parser = Parser(text, 'base')
            parser.parse()

            self.assertIsNotNone(parser.data.what, 'film cannot be detected')
            self.assertIsNotNone(parser.data.place, 'place cannot be detected')

            # make soft film detection - it is mean only that one of
            #  result illustrates true results

        self.preprocess_fo_what(self.gen_info(info, 0))
        self.preprocess_for_place(self.gen_info(info, 1))
예제 #5
0
    def preprocess_fo_what(self, info):
        for text, r in info.iteritems():
            parser = Parser(text, 'film')
            parser.parse()

            self.assertTrue(len(parser.data.what) > 0,
                            msg='cannot recognize text')

            count = 0
            for w in parser.data.what:
                title = w['title'].lower().encode('utf-8')
                # not soft variant
                # self.assertTrue(
                #     title.find(r.lower()) > -1,
                #     msg='title={} does not consist text={}'.format(title, r)
                # )

                if title.find(r.lower()) > -1:
                    count += 1

            self.assertTrue(count > 0, msg='true variant does not exist')
예제 #6
0
    def test_time_detection(self):

        texts = {
            '1.10': datetime.now().replace(day=1, month=10),
            '01:10': datetime.now().replace(day=1, month=10),
            '1:09': datetime.now().replace(day=1, month=9),
            '1 сентября': datetime.now().replace(day=1, month=9),
            'завтра': datetime.now() + timedelta(days=1),
            '3.10': datetime.now().replace(day=3, month=10),
        }

        for t, v in texts.iteritems():
            predict = Parser.detect_time(t)
            self.assertTrue(predict.date() == v.date(),
                            msg='error text: {} != {} predicted: {}'.format(
                                t, v, predict))
예제 #7
0
def callback_movie_time_selection(tuid, bot, chat_id, text, cmd, profile):
    from processing.parser import Parser

    prev_cmd = profile.cmd[len('/anytime') - 1:]
    index_of_m = prev_cmd.index('m')
    cinema_id = prev_cmd[2:index_of_m]
    index_of_d = prev_cmd.index('d')
    movie_id = prev_cmd[index_of_m + 1:index_of_d]

    deferred.defer(set_model, UserProfile, chat_id, cmd=cmd)

    cmd, d = cmd.encode('utf-8'), None
    try:
        d = Parser.detect_time(cmd)
    except:
        bot.sendMessage(chat_id, settings.DAY_CHANGED)

    send_reply(bot, chat_id, detect_cinema_seances, cinema_id, movie_id,
               d if d else 1)
    return True
예제 #8
0
def display_afisha(request, bot, chat_id, tuid, city_id):

    def film_iteraction(category_name, data):
        flag = False

        category = getattr(data, category_name)
        two_weeks = timedelta(days=14)

        if category:
            now = datetime.now()
            new_category = []
            for f in category:

                f_cinemas = get_schedule(
                    int(f.kinohod_id), date=now, city_id=int(city_id)
                )

                if f_cinemas is None:
                    continue

                if len(f_cinemas) > 0:
                    new_category.append(f)

                elif (f.premiereDateRussia and
                      now < f.premiereDateRussia < (now + two_weeks)):
                    new_category.append(f)

                elif (f.premiereDateWorld and
                      now < f.premiereDateWorld < (now + two_weeks)):
                    new_category.append(f)

            category = new_category

        if category and data.place:

            no_display = {}

            now = datetime.now()
            time = data.when if data.when is not None else now

            for p in data.place:
                for w in category:

                    if w.premiereDateRussia and w.premiereDateRussia > time:
                        continue

                    if send_reply(bot, chat_id, detect_cinema_seances,
                                  int(p.kinohod_id), int(w.kinohod_id), time):
                        flag = True

                    if not flag:
                        w_cinemas = get_schedule(
                            int(w.kinohod_id), date=time, city_id=int(city_id)
                        )

                        w_cinemas_ids = [k['cinema']['id'] for k in w_cinemas]

                        if (p.kinohod_id not in w_cinemas_ids and
                                w.premiereDateRussia < now):

                            if p.shortTitle not in no_display:
                                no_display[p.shortTitle] = [(w, p)]
                            else:
                                no_display[p.shortTitle].append((w, p))
                            continue

            display_film_no_any_seances(bot, chat_id, no_display)

            if flag:
                return True
            else:
                bot.sendMessage(chat_id, settings.CINEMA_IS_NOT_SHOWN)

        if category and not flag:
            process_what(bot, chat_id, tuid, category, next_url='/location')
            return True

        if data.place and not flag:
            if len(data.place) > 1:
                send_reply(bot, chat_id, cinemas_from_data, data.place)
            else:
                send_reply(bot, chat_id, get_cinema_movies,
                           int(data.place[0].kinohod_id),
                           settings.CINEMA_TO_SHOW,
                           datetime.now().strftime('%d%m%Y'),
                           data.place[0].shortTitle)
            return True
        return False

    bot.sendChatAction(chat_id, action='typing')
    parser = Parser(request=request, state='base', city_id=city_id)
    parser.parse()

    if film_iteraction('what', parser.data):
        return True

    parser.parser_special()
    for c in ['genre', 'actors']:
        if film_iteraction(c, parser.data):
            return True
    return False
예제 #9
0
def handle_text_with_payload(u_info, recipient_id, payload, message):
    if payload.startswith('/c'):
        seance_date = Parser.detect_time(message.encode('utf-8'))
        index_of_m, index_of_d = (payload.index('m'), payload.index('d'))
        cinema_id = payload[2:index_of_m]
        movie_id = (payload[index_of_m + 1:index_of_d])
        payloads = display_cinema_seances(recipient_id, cinema_id, movie_id,
                                          seance_date)

        text = _construct_payload(settings.DISCOUNT, recipient_id)
        update_last_callback(recipient_id)
        return [text] + payloads

    elif payload.startswith('seances'):
        if 'num' in payload:
            i_n = payload.index('num')
        else:
            return
        movie_id = payload[len('seances'):i_n]
        city_id = 1
        u_f = get_by_recipient_id(recipient_id)
        if u_f and u_f.cur_lat and u_f.cur_lng:
            l = {'latitude': u_f.cur_lat, 'longitude': u_f.cur_lng}
            city_id = detect_city_id_by_location(l)

        parser = Parser(message.encode('utf-8'), 'cinema', city_id=city_id)

        parser.parse()
        data = parser.data.place
        cinemas = []
        if not data:
            res = _construct_payload('К сожалению, мы ничего не нашли',
                                     recipient_id)
            return res
        for c in data:
            if not isinstance(c, dict):
                c = c.to_dict()

            c_info = _construct_cinema_movie_generic(c, movie_id)
            cinemas.append(c_info)
        payload = contruct_cinemas(recipient_id, cinemas, 10)
        payload = json.dumps(payload)
        update_last_callback(recipient_id)
        return payload

    elif payload.startswith('s_short'):
        seance_date = Parser.detect_time(message.encode('utf-8'))
        i_d = payload.index('d')
        movie_id = payload[len('s_short'):i_d]

        if u_info and u_info.cur_lat and u_info.cur_lng:
            payload = display_cinema_seances_short(recipient_id,
                                                   movie_id,
                                                   lat=u_info.cur_lat,
                                                   lng=u_info.cur_lng,
                                                   date=seance_date.date())
        else:
            payload = display_cinema_seances_short(recipient_id,
                                                   movie_id,
                                                   date=seance_date.date())
        return payload

    elif payload == 'bug':
        if len(message) > 2:
            u_info.bug_description = message
            u_info.last_callback = 'bug_email'
            u_info.put()

            resp = _construct_payload('Введите ваш email', recipient_id)
            return resp

        else:
            resp = _construct_payload('Опишите проблему', recipient_id)
            return resp

    elif validate_email(settings.uncd(message)):
        email = settings.uncd(message)
        u_info = get_by_recipient_id(recipient_id)

        if (u_info.last_callback == NO_AGAIN_CALLBACK
                or u_info.last_callback == NO_MAIL_SENDED_CALLBACK
                or u_info.last_callback == ANOTHER_PAY_ER_CALLBACK):
            last_callback = u_info.last_callback
            deferred.deffer(send_email, email, last_callback)
            our_spec = 'Наш специалист скоро свяжется с Вами'
            payload = _construct_payload(our_spec, recipient_id)

            return payload

        elif u_info.last_callback == 'bug_email':
            deferred.defer(send_email, email, u_info.bug_description)
            our_spec = 'Спасибо :)'
            payload = _construct_payload(our_spec, recipient_id)
            return payload

        else:
            payload = _construct_payload(settings.SORRY_I_DONT_UNDERSTAND,
                                         recipient_id)
            return payload

    else:
        payload = handle_text_message(recipient_id, message)
        return payload
예제 #10
0
def handle_text_message(recipient_id, message):
    city_id = 1
    u_f = get_by_recipient_id(recipient_id)
    if u_f and u_f.cur_lat and u_f.cur_lng:
        l = {'latitude': u_f.cur_lat, 'longitude': u_f.cur_lng}
        city_id = detect_city_id_by_location(l)
    parser = Parser(message.encode('utf-8'), 'base', city_id=city_id)
    parser.parse()
    film = parser.data.what
    place = parser.data.place
    if not check_film_screens(film) or (not film and not place):
        parser.parser_special()
        film = parser.data.genre

    if film:
        movies = []

        for f in film:

            if not isinstance(f, dict):
                f = f.to_dict()
            my_id = 'kinohod_id' if 'kinohod_id' in f else 'id'

            (description, poster, trailer_url) = display_movie_info(f[my_id])

            f_info = construct_film_info(poster, description, trailer_url, f)

            movies.append(f_info)

            if len(movies) == settings.FILMS_TO_DISPLAY:
                break

        if len(movies) == 0:
            res = _construct_payload(settings.SORRY_FOUND_NOTHING,
                                     recipient_id)

            return res

        payload = json.dumps(
            construct_final_payload(recipient_id, movies,
                                    settings.FB_FILMS_TO_DISPLAY))
        return payload

    elif place:

        place = parser.data.place
        cinemas = []
        for c in place:
            c_info = construct_cinema_generic(c.to_dict(), recipient_id)
            cinemas.append(c_info)
        payload = contruct_cinemas(recipient_id, cinemas, 10)
        payload = json.dumps(payload)
        return payload

    else:
        search_dict = {'search': message.encode('utf-8')}
        url_encoded_dict = urllib.urlencode(search_dict)
        query_url = settings.QUERY_SEARCH_URL.format(settings.KINOHOD_API_KEY,
                                                     url_encoded_dict)

        film_kinohod_api = get_data(query_url)

        query_url_soon = query_url + '&filter=soon'
        film_kinohod_api_soon = get_data(query_url_soon)

        if film_kinohod_api:
            movies = construct_movies_list(film_kinohod_api)
            payload = json.dumps(
                construct_final_payload(recipient_id, movies,
                                        settings.FB_FILMS_TO_DISPLAY))

            return payload

        elif film_kinohod_api_soon:
            movies = construct_movies_list(film_kinohod_api_soon)
            payload = json.dumps(
                construct_final_payload(recipient_id, movies,
                                        settings.FB_FILMS_TO_DISPLAY))
            return payload

        else:
            payload = _construct_payload(settings.SORRY_I_DONT_UNDERSTAND,
                                         recipient_id)
            return payload
예제 #11
0
def query_text(query):

    def process_what(whats, next_url='/seance'):
        whats = (whats[:settings.FILMS_DISPLAY_INFO]
                 if len(whats) > settings.FILMS_DISPLAY_INFO else whats)

        inline_display_films = []
        for w in whats:

            message, mark_up, poster = display_movie_info(
                w.kinohod_id, next_url=next_url
            )

            message = message if message else w.annotationShort
            message = telebot.types.InputTextMessageContent(
                message_text=message,
                parse_mode='Markdown'
            )

            inline_display_films.append(
                types.InlineQueryResultArticle(
                    id=w.kinohod_id,
                    title=w.title,
                    description=w.title,
                    input_message_content=message,
                    thumb_url=poster if poster else None,
                    thumb_width=48 if poster else None,
                    thumb_height=48 if poster else None
                )
            )

        return inline_display_films

    def film_iteraction(category_name, data):
        flag = False

        category = getattr(data, category_name)
        two_weeks = timedelta(days=14)

        if category:
            now = datetime.now()
            new_category = []
            for f in category:
                new_category.append(f)

            category = new_category

        if category and not flag:
            inline_display_films = process_what(category)
            # bot_inline.answer_inline_query(
            #     query.id, inline_display_films, cache_time=CASHE_TIME
            # )

            return True

        return False

    text = query.query.lower()

    try:
        parser = Parser(request=text, state='base')
        parser.parse()

        if film_iteraction('what', parser.data):
            return True

    except Exception as e:
        print("{!s}\n{!s}".format(type(e), str(e)))