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