Exemplo n.º 1
0
def handle_special_words(recipient_id, message):
    for word in all_types_of_films:
        if (damerau_levenshtein_distance(word,
                                         settings.uncd(message).lower()) < 3):
            payload = display_running_movies(recipient_id,
                                             settings.FB_FILMS_TO_DISPLAY)
            return payload

    for word in on_screens:
        if (damerau_levenshtein_distance(word,
                                         settings.uncd(message).lower()) < 3):
            payload = display_running_movies(recipient_id,
                                             settings.FB_FILMS_TO_DISPLAY,
                                             only_on_scr=True)
            return payload

    for word in premieres:
        if (damerau_levenshtein_distance(word,
                                         settings.uncd(message).lower()) < 3):
            payload = display_premieres(
                recipient_id,
                settings.FB_FILMS_TO_DISPLAY,
            )
            return payload

    return None
Exemplo n.º 2
0
def construct_cinema_generic(cinema, recipient_id=None):
    if 'kinohod_id' in cinema:
        my_key = 'kinohod_id'
    else:
        my_key = 'id'
    if recipient_id:
        u_info = (UserProfile.query(
            UserProfile.facebook_id == recipient_id).get())
        if u_info and u_info.cur_movie_id:
            button = {
                'type':
                'postback',
                'title':
                'Сеансы',
                'payload':
                '/c{}m{}d{}'.format(cinema[my_key], u_info.cur_movie_id,
                                    settings.TODAY)
            }
        else:
            button = {
                'type': 'postback',
                'title': 'Расписание',
                'payload': 'cinema{}'.format(cinema[my_key])
            }
    else:
        button = {
            'type': 'postback',
            'title': 'Расписание',
            'payload': 'cinema{}'.format(cinema[my_key])
        }

    stations_str = ', '.join(
        map(lambda x: x.get('name', ''), cinema.get(
            'subway_stations'))) if 'subway_stations' in cinema else ''

    if cinema.get('mall'):
        subtitle = u'Адрес: {}\n{}\nМетро: {}'.format(
            settings.uncd(cinema['address']), settings.uncd(cinema['mall']),
            settings.uncd(stations_str))

    else:
        subtitle = u'Адрес: {}\nМетро: {}'.format(
            settings.uncd(cinema['address']), settings.uncd(stations_str))

    c_info = {
        'title': cinema['shortTitle'],
        'subtitle': subtitle,
        'buttons': [button]
    }
    return c_info
Exemplo n.º 3
0
def _construct_film_info(poster, description, trailer_url, movie, cinema_id,
                         day):

    if not trailer_url or not poster:
        f_info = {
            "title":
            settings.uncd(movie['title']),
            "subtitle":
            description,
            "buttons": [{
                "type":
                "postback",
                "title":
                "Сеансы",
                "payload":
                "/c{}m{}d{}".format(cinema_id, movie['id'], day)
            }]
        }
    else:
        f_info = {
            "title":
            settings.uncd(movie['title']),
            "image_url":
            poster,
            "subtitle":
            description,
            "buttons": [
                {
                    "type": "web_url",
                    "url": trailer_url,
                    "title": "Трейлер"
                },
                {
                    "type": "postback",
                    "title": "Сеансы",
                    "payload": "/c{}m{}d{}".format(cinema_id, movie['id'], day)
                },
                {
                    "type": "postback",
                    "title": "Подробнее",
                    "payload": "info{}cinema{}".format(movie['id'], cinema_id)
                },
            ]
        }

    return f_info
Exemplo n.º 4
0
def _construct_film_info(poster, description, trailer_url, movie):
    if 'kinohod_id' in movie:
        my_id = 'kinohod_id'
    else:
        my_id = 'id'
    if not trailer_url or not poster:
        f_info = {
            'title':
            settings.uncd(movie['title']),
            'subtitle':
            description,
            'buttons': [{
                'type': 'postback',
                'title': 'Сеансы',
                'payload': 'seances{}'.format(movie[my_id])
            }]
        }
    else:
        f_info = {
            'title':
            settings.uncd(movie['title']),
            'image_url':
            poster,
            'subtitle':
            description,
            'buttons': [
                {
                    'type': 'postback',
                    'title': 'Сеансы',
                    'payload': 'seances{}num{}'.format(movie[my_id], 0)
                },
                {
                    'type': 'web_url',
                    'url': trailer_url,
                    'title': 'Трейлер'
                },
                {
                    'type': 'postback',
                    'title': 'Подробнее',
                    'payload': 'info{}'.format(movie[my_id])
                },
            ]
        }

    return f_info
Exemplo n.º 5
0
def construct_cinema_movie_generic(cinema, movie_id):
    my_id = 'kinohod_id' if 'kinohod_id' in cinema else 'id'

    stations_str = ', '.join(
        map(lambda x: x.get('name', ''), cinema.get(
            'subway_stations'))) if 'subway_stations' in cinema else ''

    button = {
        'type': 'postback',
        'title': 'Сеансы',
        'payload': '/c{}m{}d{}'.format(cinema[my_id], movie_id, settings.TODAY)
    }
    c_info = {
        'title':
        cinema['shortTitle'],
        'subtitle':
        u'{}\n{}'.format(settings.uncd(cinema['address']),
                         settings.uncd(stations_str)),
        'buttons': [button]
    }
    return c_info
Exemplo n.º 6
0
def _construct_premiere_info(poster, description, trailer_url, movie):
    my_id = 'kinohod_id' if 'kinohod_id' in movie else 'id'
    if not trailer_url or not poster:
        p_info = {
            'title':
            settings.uncd('Премьера: {}'.decode('utf-8').format(
                movie['title'])),
            'subtitle':
            description,
            'buttons': [{
                'type': 'postback',
                'title': 'Подробнее',
                'payload': 'info{}'.format(movie[my_id])
            }]
        }
    else:
        p_info = {
            'title':
            settings.uncd('Премьера: {}'.decode('utf-8').format(
                movie['title'])),
            'image_url':
            poster,
            'subtitle':
            description,
            'buttons': [{
                'type': 'postback',
                'title': 'Сеансы',
                'payload': 'seances{}num{}'.format(movie[my_id], 0)
            }, {
                'type': 'web_url',
                'url': trailer_url,
                'title': 'Трейлер'
            }, {
                'type': 'postback',
                'title': 'Подробнее',
                'payload': 'info{}'.format(movie[my_id])
            }]
        }

    return p_info
Exemplo n.º 7
0
def _construct_seances_generic_short(info, buttons, date=None):

    stations_str = ', '.join(
        [a['name'] for a in info['cinema']['subway_stations']])

    if info['cinema'] and info['cinema']['mall']:
        subtitle = u'Адрес: {}\n{}\nМетро: {}'.format(
            settings.uncd(info['cinema']['address']),
            settings.uncd(info['cinema']['mall']), settings.uncd(stations_str))
    else:
        subtitle = u'Адрес: {}\nМетро: {}'.format(
            settings.uncd(info['cinema']['address']),
            settings.uncd(stations_str))

    if date:
        my_date = datetime(year=date.year, month=date.month,
                           day=date.day).date()
        days_shift = (my_date - datetime.now().date()).days
    else:
        days_shift = settings.TODAY
    last_button = {
        'type':
        'postback',
        'title':
        'Больше сеансов',
        'payload':
        '/c{}m{}d{}'.format(info['cinema']['id'], info['movie']['id'],
                            days_shift)
    }
    buttons.append(last_button)
    f_info = {
        'title': info['cinema']['shortTitle'],
        'subtitle': subtitle,
        'buttons': buttons
    }
    return f_info
Exemplo n.º 8
0
    def post(self):
        income_json = json.loads(self.request.body)
        events = income_json['entry'][0]['messaging']
        for event in events:
            recipient_id = int(event['sender']['id'])
            if event.get('message') and event['message'].get('attachments'):
                try:
                    typing = _typing_payload(recipient_id)
                    _send_payload(typing)
                    payloads = handle_attachments(event)
                    if isinstance(payloads, list):
                        for payload in payloads:
                            resp = _send_payload(payload)
                    else:
                        resp = _send_payload(payloads)
                    self.response.write(resp)
                    return
                except:
                    self.response.write('200')

            if event.get('message') and event['message'].get('quick_reply'):
                try:
                    update_last_callback(recipient_id)
                    payload = event['message']['quick_reply']['payload']
                    recipient_id = int(event['sender']['id'])
                    typing = _typing_payload(recipient_id)
                    _send_payload(typing)

                    payloads = handle_quick_reply(payload, recipient_id)
                    if isinstance(payloads, list):
                        for payload in payloads:
                            resp = _send_payload(payload)
                    else:
                        resp = _send_payload(payloads)
                    self.response.write(resp)
                    return
                except:
                    self.response.write('200')

            if event.get('postback') and event['postback'].get('payload'):
                try:
                    typing = _typing_payload(recipient_id)
                    _send_payload(typing)
                    update_last_callback(recipient_id)
                    back_payload = event['postback']['payload']
                    recipient_id = int(event['sender']['id'])
                    payloads = handle_back_payload(back_payload, recipient_id)
                    if isinstance(payloads, list):
                        for payload in payloads:
                            resp = _send_payload(payload)
                    else:
                        resp = _send_payload(payloads)
                    self.response.write(resp)
                    return
                except:
                    self.response.write('200')

            if event.get('message') and event['message'].get('text'):
                message = event['message']['text']
                typing = _typing_payload(recipient_id)
                _send_payload(typing)
                try:
                    payload = handle_special_words(recipient_id, message)
                    if payload:
                        self.response.write(_send_payload(payload))
                        return

                    if settings.uncd(message).find(u'В прокате') != -1:
                        update_last_callback(recipient_id)

                        payload = display_running_movies(
                            recipient_id, settings.FB_FILMS_TO_DISPLAY)
                        self.response.write(_send_payload(payload))
                        return

                    u_info = get_by_recipient_id(recipient_id)
                    if u_info and u_info.last_callback:
                        payload = u_info.last_callback

                        payloads = handle_text_with_payload(
                            u_info, recipient_id, payload, message)
                        if isinstance(payloads, list):
                            for payload in payloads:
                                resp = _send_payload(payload)
                        else:
                            resp = _send_payload(payloads)
                        self.response.write(resp)
                        return
                    else:
                        typing = _typing_payload(recipient_id)
                        _send_payload(typing)
                        payload = handle_text_message(recipient_id, message)
                        self.response.write(_send_payload(payload))
                        return
                except:
                    self.response.write('200')
Exemplo n.º 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
Exemplo n.º 10
0
def process_movies(data,
                   number_of_movies,
                   callback_url,
                   date,
                   city_id,
                   next_url='/info',
                   **kwargs):

    cinema_id = kwargs.get('cinema_id')
    separator = kwargs.get('separator')
    next_info_url = kwargs.get('info_url')
    title = kwargs.get('title')

    now = datetime.now()

    videos, premiers = [], []

    to_show = settings.FILMS_TO_DISPLAY
    if len(data) == 0:
        to_show = 0

    elif len(data) < settings.FILMS_TO_DISPLAY:
        to_show = len(data)

    dformat = '%d%m%Y'
    tomorrow_str = (datetime.now() + timedelta(days=1)).strftime(dformat)
    now_str = now.strftime(dformat)

    markup_tomorrow_text = (settings.ON_TOMORROW if now.date() == date.date()
                            else settings.ON_TODAY)

    markup_tomorrow_date = (tomorrow_str
                            if now.date() == date.date() else now_str)

    more_date = now_str if now.date() == date.date() else tomorrow_str

    expanded_info = False
    if number_of_movies - to_show > len(data):
        left_border = 0
        right_border = len(data)
    else:
        left_border = number_of_movies - to_show
        right_border = number_of_movies

    for film_counter in xrange(left_border, right_border):

        if film_counter < len(data):
            movie = data[film_counter]

        else:

            return (settings.NO_FILMS,
                    _process_movies_markup(settings.FIRST_TEN, callback_url, 0,
                                           more_date, markup_tomorrow_text,
                                           markup_tomorrow_date))

        # TODO: DO SOMETHING WITH THIS STUFF, DOUBLE DATA GETTER
        film = ndb.Key('Film', str(movie['id'])).get()
        # film = Film.get_by_id(movie['id'])
        two_weeks = timedelta(days=14)

        film_cinemas = get_schedule(movie['id'], date, city_id)

        if (film and
            (len(film_cinemas) < 1 and not ((film.premiereDateRussia and
                                             (now < film.premiereDateRussia <
                                              (now + two_weeks))) or
                                            (film.premiereDateWorld and
                                             (now < film.premiereDateWorld <
                                              (now + two_weeks)))))):
            continue
        # END OF STUFF

        if cinema_id and separator and next_info_url:
            expanded_info = True

            link = '{}{}{}{}'.format(next_url, cinema_id, separator,
                                     movie['id'])
            f_info = IMovieCinema(movie['title'], link,
                                  '{}{}'.format(next_info_url, movie['id']))

        else:
            link = '{}{}'.format(next_url, movie['id'])
            f_info = settings.Row(settings.uncd(movie['title']), link)

        if movie['premiereDateRussia']:
            t_str = movie['premiereDateRussia']
            if 'T' in t_str:
                t_str = t_str.split('T')[0]

            prem_date = datetime.strptime(t_str, '%Y-%m-%d')
            now = datetime.utcnow()
            if prem_date > now:
                premiers.append(f_info)
            else:
                videos.append(f_info)
        else:
            premiers.append(f_info)

    mark_up = _process_movies_markup(settings.MORE, callback_url,
                                     number_of_movies, more_date,
                                     markup_tomorrow_text,
                                     markup_tomorrow_date)
    if expanded_info:
        template = (
            settings.JINJA_ENVIRONMENT.get_template('running_movies_ext.md'))

        msg = template.render({
            'videos': videos,
            'premiers': premiers,
            'sign_video': settings.SIGN_VIDEO,
            'sign_tip': settings.SIGN_TIP,
            'title': title,
            'sign_point': settings.SIGN_POINT,
            'sign_calendar': settings.SIGN_CALENDAR,
            'sign_newspaper': settings.SIGN_NEWSPAPER,
            'sign_premier': settings.SIGN_PREMIER
        })
    else:
        template = settings.JINJA_ENVIRONMENT.get_template('running_movies.md')
        msg = template.render({
            'videos': videos,
            'premiers': premiers,
            'sign_video': settings.SIGN_VIDEO,
            'sign_point': settings.SIGN_POINT,
            'title': title,
            'sign_tip': settings.SIGN_TIP,
            'sign_premier': settings.SIGN_PREMIER
        })

    return msg, mark_up
Exemplo n.º 11
0
def process_movies_db(number_of_movies,
                      callback_url,
                      next_url='/info',
                      **kwargs):

    data = Film.query().order(-Film.rating).fetch(
        offset=(number_of_movies - settings.FILMS_TO_DISPLAY
                if number_of_movies > settings.FILMS_TO_DISPLAY else
                number_of_movies),
        limit=settings.FILMS_TO_DISPLAY)

    cinema_id = kwargs.get('cinema_id')
    separator = kwargs.get('separator')
    next_info_url = kwargs.get('info_url')

    videos, premiers = [], []

    expanded_info = False
    for f in data:

        if cinema_id and separator and next_info_url:
            expanded_info = True

            link = '{}{}{}{}'.format(next_url, cinema_id, separator,
                                     f.kinohod_id)
            f_info = IMovieCinema(f.title, link,
                                  '{}{}'.format(next_info_url, f.kinohod_id))

        else:
            link = '{}{}'.format(next_url, f.kinohod_id)
            f_info = settings.Row(settings.uncd(f.title), link)

        if f.premiereDateRussia:
            now = datetime.utcnow()
            if f.premiereDateRussia > now:
                premiers.append(f_info)
            else:
                videos.append(f_info)
        else:
            premiers.append(f_info)

    mark_up = InlineKeyboardMarkup(inline_keyboard=[[
        dict(text=settings.MORE,
             callback_data=(
                 callback_url.format(number_of_movies +
                                     2 * settings.FILMS_TO_DISPLAY)))
    ]])

    if expanded_info:
        template = (
            settings.JINJA_ENVIRONMENT.get_template('running_movies_ext.md'))

        msg = template.render({
            'videos': videos,
            'premiers': premiers,
            'sign_video': settings.SIGN_VIDEO,
            'sign_tip': settings.SIGN_TIP,
            'sign_calendar': settings.SIGN_CALENDAR,
            'sign_newspaper': settings.SIGN_NEWSPAPER,
            'sign_premier': settings.SIGN_PREMIER
        })
    else:
        template = settings.JINJA_ENVIRONMENT.get_template('running_movies.md')
        msg = template.render({
            'videos': videos,
            'premiers': premiers,
            'sign_video': settings.SIGN_VIDEO,
            'sign_tip': settings.SIGN_TIP,
            'sign_premier': settings.SIGN_PREMIER
        })

    return msg, mark_up
Exemplo n.º 12
0
def get_seances(chat_id, movie_id, number_of_seances,
                date=datetime.now().strftime('%d%m%Y')):

    u = get_model(UserProfile, chat_id)

    f = Film.get_by_id(str(movie_id))

    f_cinemas, city_id = detect_film_cinemas(chat_id, movie_id, date=date)

    if f and not f_cinemas:
        return settings.NO_FILM_SEANCE

    cinema_ids = [k['cinema']['id'] for k in f_cinemas]

    if u:
        l = json.loads(u.location)
        latitude, longitude = l['latitude'], l['longitude']

        url = '{}?lat={}&long={}&sort=distance&cityId=1'.format(
            settings.URL_WIDGET_CINEMAS,
            latitude,
            longitude,
        )

        seances = []

        html_data = get_data(url)

        if not html_data:
            return settings.DONT_UNDERSTAND, None

        if 'data' not in html_data:
            return settings.CANNOT_FIND_SEANCE, None

        for info in html_data['data']:

            cinema_id = info.get('id')

            if str(cinema_id) not in cinema_ids:
                continue

            seances.append(
                settings.RowDist(
                    settings.uncd(info['shortTitle']),
                    info['distance'],
                    '/c{}m{}'.format(cinema_id, movie_id)
                )
            )

        if len(seances) < 1:
            return settings.NO_FILM_SEANCE, None

        correct, n = False, settings.SEANCES_TO_DISPLAY
        while not correct:
            if len(seances) > number_of_seances:
                n = settings.SEANCES_TO_DISPLAY
                seances = seances[number_of_seances - n: number_of_seances]
                correct = True
            elif len(seances) > (number_of_seances - n):
                seances = seances[number_of_seances - n:]
                correct = True
            else:
                number_of_seances = n

        empty_data(html_data=html_data)
        mark_up = gen_markup(movie_id, number_of_seances)
        template = settings.JINJA_ENVIRONMENT.get_template(
            'seances_distance.md'
        )

    else:

        url = settings.URL_SEANCES.format(
            str(movie_id), settings.KINOHOD_API_KEY,
            (number_of_seances - settings.SEANCES_TO_DISPLAY),
            number_of_seances
        )

        seances = []
        html_data = get_data(url)

        if not html_data:
            return settings.DONT_UNDERSTAND, None

        for info in html_data:

            cinema_json = info.get('cinema')
            cinema_id = cinema_json.get('id')
            if str(cinema_id) not in cinema_ids:
                continue

            seances.append(
                settings.RowCinema(
                    settings.uncd(cinema_json['shortTitle']),
                    cinema_json.get('address'),
                    cinema_json.get('mall'),
                    '/c{}m{}'.format(cinema_id, info['movie']['id']))
            )

        empty_data(html_data=html_data)
        mark_up = gen_markup(movie_id, number_of_seances)
        template = settings.JINJA_ENVIRONMENT.get_template('seances.md')

    return template.render({
        'date': datetime.strptime(date, '%d%m%Y').strftime('%d.%m.%Y'),
        'sign_point': settings.SIGN_POINT,
        'sign_tip': settings.SIGN_TIP,
        'seances': seances
    }), mark_up