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