Ejemplo n.º 1
0
    def __process_genre(self, name, t, g, is_film_object):
        if damerau_levenshtein_distance(de_uncd(name), t) < 2:
            if not self.data.genre:
                self.data.genre = []

            if is_film_object:
                films = get_genres(g.kinohod_id)

                for f in films:
                    film_id = f.get('id')

                    if not film_id or film_id in self.__ids_inside:
                        continue

                    o = Film.get_by_id(film_id)
                    if not o:
                        schedules = get_schedule(film_id)
                        o = set_film_model(f, schedules)
                    self.__ids_inside.append(film_id)
                    self.data.genre.append(o)
            else:
                self.data.genre += get_genres(g.kinohod_id)

            return True
        return False
Ejemplo n.º 2
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)
Ejemplo n.º 3
0
def display_info(bot,
                 payload,
                 cmd,
                 chat_id,
                 full=False,
                 prefix_length=len('/info')):

    t_uid = payload['message']['from']['id']
    movie_id = cmd[prefix_length:len(cmd)]

    if not str(movie_id).isdigit():
        bot.sendMessage(chat_id, settings.INFO_NOT_FULL.format(movie_id))
        return

    film = Film.get_by_id(str(movie_id))
    now = datetime.now()
    two_weeks = timedelta(days=14)

    if not film:
        return bot.sendMessage(chat_id, settings.DONT_UNDERSTAND)

    # poor place of whole code
    film_cinemas, city_id = detect_film_cinemas(chat_id, movie_id, date=None)

    if (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))))):
        return

    message, mark_up, movie_poster = display_movie_info(movie_id,
                                                        t_uid,
                                                        next_url='/location',
                                                        full=full)

    if not message:
        bot.sendMessage(chat_id, settings.SERVER_NOT_VALID)
        return

    if movie_poster:
        bot.sendChatAction(chat_id, 'upload_photo')
        bot.sendPhoto(chat_id, ('poster.jpg', movie_poster))

    bot.sendMessage(chat_id,
                    message,
                    reply_markup=mark_up,
                    parse_mode='Markdown')
Ejemplo n.º 4
0
def display_cinemas_where_film(bot, payload, cmd, chat_id):

    if 'callback_query' not in payload:
        return

    bot.answerCallbackQuery(callback_query_id=int(
        payload['callback_query']['id']),
                            text=':)')

    index_num = cmd.index('num')
    movie_id = int(cmd[len('/where_film'):index_num])
    num = int(cmd[index_num + len('num'):])

    film = Film.get_by_id(str(movie_id))
    send_reply(bot, chat_id, get_cinemas_where_film, film, num)
Ejemplo n.º 5
0
def update_film_table(index_name='films'):

    films, places = get_data('film')

    for k, f in films.iteritems():

        o = Film.get_by_id(f.get('id'))

        if not o:
            o = set_film_model(f)

            ModelSearch.add_document(
                ModelSearch.create_film_document(
                    doc_id=o.key.urlsafe(),
                    film=o
                ), index_name=index_name
            )
Ejemplo n.º 6
0
def display_future_seances(bot, payload, cmd, chat_id):
    if 'callback_query' in payload:
        if '/future' not in cmd:
            bot.sendMessage(chat_id, settings.SERVER_NOT_VALID)
            return

        movie_id = cmd[len('/future'):]
        film = Film.get_by_id(movie_id)

        premier = film.premiereDateRussia
        if not premier or not isinstance(premier, datetime):
            bot.sendMessage(chat_id, settings.SERVER_NOT_VALID)
            return

        send_reply(bot,
                   chat_id,
                   display_seances_all,
                   movie_id,
                   settings.SEANCES_TO_DISPLAY,
                   premier.strftime('%d%m%Y'),
                   success=int(payload['callback_query']['id']))
Ejemplo n.º 7
0
def detect_cinema_seances(cinema_id, movie_id, day):

    if not isinstance(day, datetime):
        day = int(day)
        day_str = _day_of_seance(day)
    else:
        day_str = day.strftime('%d%m%Y')

    url = settings.URL_CINEMA_SEANCES.format(cinema_id,
                                             settings.KINOHOD_API_KEY, day_str)

    try:
        with contextlib.closing(urllib2.urlopen(url)) as hd:
            html_data = json.loads(hd.read())
    except Exception as ex:
        import logging
        logging.debug(ex.message)
        return None, None

    CinemaSeances = namedtuple('CinemaSeances',
                               ['tip', 'time', 'minPrice', 'id', 'format'])

    if html_data is None:
        return settings.NO_SEANCE, None

    place = ''.decode('utf-8')
    if isinstance(html_data, list) and len(html_data) > 0:
        place = html_data[0]['cinema']['title']

    for info in html_data:

        if int(movie_id) != int(info['movie']['id']):
            continue

        seances = []
        for s in info['schedules']:
            m_p = s['minPrice'] if s['minPrice'] else None

            s_f = None
            if s['formatName'] and len(s['formatName']) < 10:
                s_f = s['formatName']

            if _calculate_is_onsale(s['startTime']):
                seances.append(
                    CinemaSeances(settings.SIGN_TIP, s['time'], m_p,
                                  int(s['id']), s_f))
            else:
                seances.append(
                    CinemaSeances(settings.SIGN_TIP, s['time'], m_p, 0, s_f))

        f = html_data[0]['movie']
        premier = f.get('premiereDateRussia')
        if premier:
            premier = datetime.strptime(premier.split('T')[0], '%Y-%m-%d')

        if premier and premier > datetime.now():
            markup = _construct_markup(cinema_id,
                                       movie_id,
                                       day,
                                       only_another=True)
        else:
            markup = _construct_markup(cinema_id, movie_id, day)

        template = settings.JINJA_ENVIRONMENT.get_template('cinema_seances.md')

        if day_str:
            day_str = day_str.decode('utf-8')
            day_str = '{}.{}.{}'.format(day_str[:2], day_str[2:4], day_str[4:])
        else:
            day_str = ''

        return template.render({
            'title': info['movie']['title'],
            'seances': seances,
            'place': place,
            'date': day_str
        }), markup

    cinema = Cinema.get_by_id(str(cinema_id))
    film = Film.get_by_id(str(movie_id))
    markup = _construct_markup(cinema_id, movie_id, day)

    day = day.strftime('%d.%m') if isinstance(day, datetime) else ''
    return settings.NO_FILM_SCHEDULE.format(
        film.title if film else '', day,
        cinema.title if cinema else ''), markup
Ejemplo n.º 8
0
def get_nearest_cinemas(bot,
                        chat_id,
                        number_of_cinemas,
                        movie_id=None,
                        next_url='/show'):

    # TODO: REWRITE THIS PEACE OF SHIT, PLEASE

    u = get_model(UserProfile, chat_id)
    if not u.location:
        bot.sendMessage(chat_id, settings.CANNOT_FIND_YOU)
        return None, None

    l = json.loads(u.location)
    city_id = detect_city_id_by_location(l)
    url = '{}&latitude={}&longitude={}&sort=distance&city={}'.format(
        settings.URL_CINEMAS.format(settings.KINOHOD_API_KEY),
        l.get('latitude'), l.get('longitude'), city_id)

    film = None
    if movie_id:
        film = Film.get_by_id(str(movie_id))

    data = get_data(url)

    if not data:
        return settings.DONT_UNDERSTAND, None

    cinemas = []
    template = settings.JINJA_ENVIRONMENT.get_template('cinema_where_film.md')

    film_cinemas = get_schedule(movie_id, date=None, city_id=city_id)
    if film_cinemas:
        film_cinema_ids = [str(fc['cinema']['id']) for fc in film_cinemas]
    else:
        return settings.DONT_UNDERSTAND, None

    right_border = number_of_cinemas
    for film_counter in xrange(number_of_cinemas - settings.CINEMA_TO_SHOW,
                               right_border):

        if film_counter < len(data):
            cinema = data[film_counter]
        else:

            return (settings.NO_FILMS,
                    InlineKeyboardMarkup(inline_keyboard=[[
                        dict(text=settings.FIRST_THREE,
                             callback_data=(
                                 '/nearest{}'.format(settings.CINEMA_TO_SHOW)))
                    ]]))

        cinema_id = str(cinema.get('id'))
        cinema_title = cinema.get('shortTitle')

        # poor place because of long request

        # poor place because of double getter
        if film and cinema_id:
            if cinema_id not in film_cinema_ids:
                continue

            link = '{}{}m{}'.format(next_url, cinema_id, movie_id)

        else:
            link = '{}{}'.format(next_url, cinema_id)

        cinemas.append(
            settings.RowCinema(cinema_title, cinema.get('address'),
                               cinema.get('mall'), link))

    if film and len(cinemas) < 1:
        return get_cinemas_where_film(film, settings.CINEMAS_TO_DISPLAY,
                                      chat_id)

    if film:
        mark_up = InlineKeyboardMarkup(inline_keyboard=[[
            dict(text=settings.MORE,
                 callback_data='/nearest{}m{}'.format(
                     number_of_cinemas + settings.CINEMA_TO_SHOW, movie_id))
        ]])
    else:
        mark_up = InlineKeyboardMarkup(inline_keyboard=[[
            dict(text=settings.MORE,
                 callback_data='/nearest{}'.format(number_of_cinemas +
                                                   settings.CINEMA_TO_SHOW))
        ]])

    film_name = film.title if film else None
    return template.render({
        'film_name': film_name,
        'seances': cinemas
    }), mark_up
Ejemplo n.º 9
0
def display_movie_info(movie_id,
                       telegram_user_id=None,
                       next_url='/seance',
                       full=False):
    now = datetime.now()

    film = Film.get_by_id(str(movie_id))

    telegram_user_id = telegram_user_id if telegram_user_id else 0
    if not film:
        display_movie_info_api(movie_id, telegram_user_id, next_url='/seance')

    if film.poster:
        movie_poster = _get_movie_poster(film.poster.name)
    else:
        movie_poster = None

    if film.trailers and len(film.trailers) > 0:

        trailer = film.trailers[0].get()

        if trailer is not None:
            video_hash = trailer.videos[0].filename
            trailer_url = _get_movie_trailer_link(video_hash)
        else:
            trailer_url = settings.BASE_KINOHOD

        shorten_url = botan.shorten_url(
            str(telegram_user_id) + trailer_url, settings.BOTAN_TOKEN,
            telegram_user_id if telegram_user_id else 0)

        if film.premiereDateRussia and film.premiereDateRussia > now:
            markup = InlineKeyboardMarkup(inline_keyboard=[[
                dict(text=settings.TREILER, url=shorten_url),
                dict(text=settings.NEAREST_SEANCES,
                     callback_data='/future{}'.format(movie_id))
            ]])
        else:
            markup = InlineKeyboardMarkup(inline_keyboard=[[
                dict(text=settings.TREILER, url=shorten_url),
                dict(text=settings.CHOOSE_SEANCE,
                     callback_data=(
                         '{}{}num{}'.format(next_url, film.kinohod_id,
                                            settings.CINEMAS_TO_DISPLAY))),
            ]])

    else:
        if film.premiereDateRussia and film.premiereDateRussia > now:
            markup = InlineKeyboardMarkup(inline_keyboard=[[
                dict(text=settings.NEAREST_SEANCES,
                     callback_data='/future{}'.format(movie_id))
            ]])
        else:
            markup = InlineKeyboardMarkup(inline_keyboard=[[
                dict(text=settings.CHOOSE_SEANCE,
                     callback_data=(
                         '{}{}num{}'.format(next_url, film.kinohod_id, 20)))
            ]])

    Annotation = namedtuple('Annotation', ['title', 'link'])

    if full:
        template = settings.JINJA_ENVIRONMENT.get_template(
            'movies_info_full.md')

        actors = film.actors
        ann_o = Annotation(film.annotationFull, '')

        return template.render({
            'title':
            film.title,
            'description':
            ann_o,
            'duration':
            film.duration if film.duration else None,
            'premier': (film.premiereDateRussia.strftime('%d.%m.%Y')
                        if film.premiereDateRussia else None),
            'sign_calendar':
            settings.SIGN_CALENDAR,
            'age':
            film.ageRestriction if film.ageRestriction else None,
            'sign_genre':
            settings.SIGN_GENRE,
            'kinder':
            settings.SIGN_CHILD_AGE,
            'sign_time':
            settings.SIGN_ALARM,
            'genres':
            ', '.join([a.get().name.encode('utf-8')
                       for a in film.genres]).decode('utf-8'),
            'sign_actor':
            settings.SIGN_ACTOR,
            'actors':
            ', '.join([a.get().name.encode('utf-8')
                       for a in actors]).decode('utf-8') if actors else None,
            'directors':
            ', '.join([a.get().name.encode('utf-8') for a in film.directors
                       ]).decode('utf-8') if film.directors else None,
            'sign_producer':
            settings.SIGN_PRODUCER,
        }), markup, movie_poster

    else:
        template = settings.JINJA_ENVIRONMENT.get_template('movies_info.md')
        actors = (film.actors[:3]
                  if film.actors and len(film.actors) > 3 else film.actors)

        ann_o = Annotation(
            film.annotationShort,
            'Подробнее: /fullinfo{}'.decode('utf-8').format(movie_id))

        return template.render({
            'title':
            film.title,
            'description':
            ann_o,
            'sign_genre':
            settings.SIGN_GENRE,
            'genres':
            ', '.join([a.get().name.encode('utf-8') for a in film.genres
                       ]).decode('utf-8') if film.genres else None,
            'sign_actor':
            settings.SIGN_ACTOR,
            'actors':
            ', '.join(
                [a.get().name.encode('utf-8') for a in actors
                 if a.get()]).decode('utf-8') if actors else None,
            'directors':
            ', '.join([
                a.get().name.encode('utf-8') for a in film.directors
                if a.get()
            ]).decode('utf-8') if film.directors else None,
            'sign_producer':
            settings.SIGN_PRODUCER,
        }), markup, movie_poster
Ejemplo n.º 10
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
Ejemplo n.º 11
0
def display_seances_part(chat_id, text, movie_id, number_of_seances,
                         date=datetime.now().strftime('%d%m%Y')):

    url = settings.URL_FULL_SEANCES.format(
        str(movie_id), settings.KINOHOD_API_KEY, date
    )

    seances = []

    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]

    html_data = get_data(url)

    if not html_data:
        return settings.DONT_UNDERSTAND

    for info in html_data:

        cinema_json = info.get('cinema')
        cinema_id = cinema_json.get('id')

        if cinema_id not in cinema_ids:
            continue

        if (('shortTitle' in cinema_json and
                cinema_json['shortTitle'].find(text) > -1) or
            ('address' in info['cinema'] and
                cinema_json['address'].find(text) > -1) or
            ('subway_stations' in cinema_json and
                'name' in cinema_json['subway_stations'] and
                cinema_json['subway_stations']['name'].find(text) > -1)):

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

    empty_data(html_data=html_data)
    if len(seances) < 1:
        template = settings.JINJA_ENVIRONMENT.get_template('no_seances.md')
        return template.render({})

    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

    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
    })