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