def run(content_config, env, variables): """ content_config schema: Platform dependent message: { 'text': 'blablabla', 'choices': [ { 'title': 'option 1', 'payload': '1', 'acceptable_inputs': ['opt 1'] }, ... ] } """ platform_type = env['platform_type'].value m = Message(buttons_text=content_config['text'], variables=variables) for i, choice in enumerate(content_config['choices']): # Facebook only support 3 buttons if i == 3 and platform_type == SupportedPlatform.Facebook: break b = Message.Button(Message.ButtonType.POSTBACK, choice['title'], payload=TextPayload(choice['payload']), acceptable_inputs=choice['acceptable_inputs'], variables=variables) m.add_button(b) return [m]
def run(unused_content_config, env, unused_variables): user_input = UserInput() msgs = [] # The output messages. # output limit and map size size = (500, 260) if env['platform_type'] == SupportedPlatform.Line: max_count = 3 else: max_count = 5 address = u'' # str. The address user entered. filters_str = u'' # str. The filter used this time. geocoder = GoogleMapsPlaceAPI(api_key=GOOGLE_STATIC_MAP_API_KEY) more_data = user_input.Get('more_data') latlng = Memory.Get('latlng', None) # tuple. User's current location. cached_transaction = Memory.Get('cached_transaction', None) next_data_index = Memory.Get('next_data_index', max_count) if more_data: # Yes, user clicks 'more data', dump data from cache. if not cached_transaction: return [Message(u'請重新輸入地址或條件。')] trans = cached_transaction[next_data_index:next_data_index + max_count] Memory.Set('next_data_index', next_data_index + max_count) if not trans: return [Message(u'沒有更多物件了,請重新輸入地址或條件。')] else: # Nope. User is not entering 'more data'. reset = user_input.Get('reset') location = user_input.Get('location') if reset: latlng = Memory.Get('latlng', None) rules = None # User uploaded current location. elif location and 'coordinates' in location: latlng = (location['coordinates']['lat'], location['coordinates']['long']) rules = Deser(Memory.Get('rules', None)) if rules: rules.AddPureSortingRules(latlng) else: # User entered either an address or criteria; or both. query = user_input.Get('query') rules = twrealprice_rule.Rules.Create() query = rules.ParseQuery(query) address = query.strip() _LOG.info('User query: address=[%s] filters:[%s]', address, rules.filters) if address: if latlng: center = {'lat': latlng[0], 'long': latlng[1]} else: center = None geo_results = geocoder.query_top_n(n=3, address=address, language='zh_TW', region='TW', bounds=[[[20.0, 118.0], [26.0, 123.0]]], center=center) if not geo_results: if rules.filters: msgs.append( Message((u'我不認識這個地址:[%s], 但是我認' u'識條件:[%s]. 請修改一下地址。') % (address, ' '.join(rules.filters)))) address = u'' else: return [Message(u'我不認識這個地址:[%s]' % address)] if len(geo_results) == 1: latlng = (geo_results[0]['location'][0], geo_results[0]['location'][1]) if len(geo_results) > 1: m = Message(buttons_text=u'你指的是以下哪一個地址呢?') for r in geo_results: m.add_button( Message.Button(Message.ButtonType.POSTBACK, r['address'], payload=LocationPayload( r['location'], False))) # If user also entered criteria, save it for later query. if rules.filters: Memory.Set('rules', cPickle.dumps(rules)) # Postpone the AddPureSortingRules until we get latlng. return [m] if not rules.filters: # If user didn't enter filter, use the previous one. rules = Deser(Memory.Get('rules', None)) if rules: _LOG.info('User prev rules: %s', rules.filters) if rules: rules.AddPureSortingRules(latlng) next_data_index = max_count if not latlng: return [Message(u'我還不知道你想查的地方是哪裡。請輸入地址或是送出你的位置。')] Memory.Set('rules', cPickle.dumps(rules)) Memory.Set('latlng', latlng) Memory.Set('next_data_index', next_data_index) twrealprice = TwRealPrice() try: trans = twrealprice.nearby_transaction(max_count, latlng, rules) except IOError: return [Message(u'資料庫找不到,趕快回報給粉絲頁管理員,謝謝。')] if rules and rules.filters: filters_str = u'篩選條件: 「%s」。' % u'」「'.join(rules.filters) if not trans: msg = Message(u'對不起,找不到成交行情喔!試試別的地址或條件。') msgs.append(msg) return msgs # Construct main result cards. main_map = GoogleStaticMapAPIRequestBuilder(GOOGLE_STATIC_MAP_API_KEY, size) style = MarkerStyle() main_map.add_marker(latlng, **style.next()) for s in trans: lat = float(s['latlng'][0]) lng = float(s['latlng'][1]) main_map.add_marker((lat, lng), **style.next()) subtitle = (filters_str + u'搜尋結果僅供參考,詳細完整實價登錄資料,以內政部公佈為準。') msg = Message() b = Message.Bubble(u'%s附近的成交行情' % address, image_url=main_map.build_url(), subtitle=subtitle) msg.add_bubble(b) msgs.append(msg) # At this point, 'trans' must have data to show. i = -1 for s in trans: # In this loop, the strings are concatenated in utf-8 first because the # transaction data come with utf-8 encoded. try: def UnitPrice(s): try: return '%.2f萬' % (float(s['單價每平方公尺']) * twrealprice_rule.M2_PER_PING / 10000) except ValueError: return '--.--' lines = [ ' '.join([ '%d萬' % (int(s['總價元']) / 10000), '(%s * %.2f坪 + %d萬)' % (UnitPrice(s), float(s['建物移轉總面積平方公尺']) / twrealprice_rule.M2_PER_PING, int(s['車位總價元']) / 10000), '%s(%s)' % ( s['建物型態'].split('(')[0], Age(s['建築完成年月']), ), ]).decode('utf-8'), ' '.join([ '%s/共%s' % (s['移轉層次'].replace('層', '樓'), s['總樓層數'].replace('層', '樓')), StreetOnly(s), ]).decode('utf-8'), ' '.join([ RocSlash(s['交易年月日']) + '成交', '%s房%s廳%s衛' % (s['建物現況格局-房'], s['建物現況格局-廳'], s['建物現況格局-衛']), '地坪%.2f' % (float(s['土地移轉總面積平方公尺']) / twrealprice_rule.M2_PER_PING), '車位%.2f坪' % (float(s['車位移轉總面積平方公尺']) / twrealprice_rule.M2_PER_PING), s['車位類別'], s['主要用途'], '備註: ' + s['備註'] if s['備註'] else '', ]).decode('utf-8'), ] if env['platform_type'] == SupportedPlatform.Line: title = lines[0] subtitle = lines[1] + lines[2] else: title = lines[0] + lines[1] subtitle = lines[2] i += 1 msg = Message() msg.add_bubble( Message.Bubble((u'%c: ' % (i + ord('A'))) + title, subtitle=subtitle)) msgs.append(msg) except ValueError: traceback.print_exc() continue return msgs
def run(content_config, unused_env, variables): """ content_config schema: Platform dependent message: { 'send_payload_to_current_node': False, 'api_key': 'google geocoding api key', 'query_term': 'query term', 'language': 'zh_TW', 'region': 'tw', 'bounds': [ {'lat': 23.816576, 'long': 119.781068}, {'lat': 25.314444, 'long': 122.053702} ], 'center': {'lat': 23.816576, 'long': 122.053702} } """ query_term = Resolve(content_config['query_term'], variables) # Remove stop words query_term = re.sub(STOP_WORDS, '', query_term) cfg = content_config api = GoogleMapsPlaceAPI(content_config['api_key']) py_bounds = [] for b in cfg.get('bounds', []): py_bounds.append([(b[0]['lat'], b[0]['long']), (b[1]['lat'], b[1]['long'])]) results = api.query_top_n(3, query_term, cfg['language'], cfg['region'], py_bounds, cfg.get('center', None)) in_currrent = content_config['send_payload_to_current_node'] if not results: m = Message(u'對不起,我找不到這個地址, 請重新輸入 >_<') elif len(results) == 1: m = Message(u'你指的是「%s」嗎?' % results[0]['address']) m.add_quick_reply( Message.QuickReply(Message.QuickReplyType.TEXT, u'是', payload=LocationPayload(results[0]['location'], in_currrent), acceptable_inputs=[u'^對', '(?i)y', '(?i)ok'])) m.add_quick_reply( Message.QuickReply(Message.QuickReplyType.TEXT, u'否', payload=EventPayload('WRONG_ADDRESS', None, in_currrent), acceptable_inputs=[u'不', '(?i)n'])) else: m = Message(buttons_text=u'你指的是以下哪一個地址呢?') for r in results: m.add_button( Message.Button(Message.ButtonType.POSTBACK, r['address'], payload=LocationPayload(r['location'], in_currrent))) return [m]
def run(content_config, unused_env, variables): """ content_config schema: { "bot_admins": { "platform_user_ident_1": ["bot_id_1", "bot_id_2" ..], ... } } """ user = g.user bots = content_config['bot_admins'].get(user.platform_user_ident) if not bots: return [] bot = Memory.Get('bot') if not bot: msgs = [ Message(u'嗨 {{user.first_name}},你想要操作哪隻機器人呢?', variables=variables) ] page = 1 m = Message() msgs.append(m) bubble = Message.Bubble('第 %d 頁' % page) for bot_id in bots: bot = Bot.get_by(id=bot_id, single=True) if not bot: continue bubble.add_button( Message.Button(Message.ButtonType.POSTBACK, title=bot.name, payload=EventPayload('SELECT_BOT', bot_id))) if len(bubble.buttons) == 3: m.add_bubble(bubble) page += 1 bubble = Message.Bubble(u'第 %d 頁' % page) if len(bubble.buttons): m.add_bubble(bubble) msgs[-1].add_quick_reply( Message.QuickReply(Message.QuickReplyType.TEXT, u'放棄', payload=EventPayload('CONTROL_FLOW', 'reset'), acceptable_inputs=['(?i)giveup', '(?i)reset'])) return msgs operation = Memory.Get('operation') if not operation: m = Message(buttons_text=u'你想要執行什麼動作呢?') m.add_button( Message.Button(Message.ButtonType.POSTBACK, title=u'廣播訊息', payload=EventPayload('SELECT_OP', 'broadcast'))) m.add_button( Message.Button(Message.ButtonType.POSTBACK, title=u'放棄', payload=EventPayload('CONTROL_FLOW', 'reset'))) return [m] if operation == 'broadcast': broadcast_message = Memory.Get('broadcast_message') status = Memory.Get('status') if status == 'input_broadcast_message': m = Message(u'你可以繼續輸入下一則訊息:') m.add_quick_reply( Message.QuickReply( Message.QuickReplyType.TEXT, u'完成', payload=EventPayload('MESSAGE_INPUT', 'done'), acceptable_inputs=[u'好了', u'(?i)done', '(?i)y'])) m.add_quick_reply( Message.QuickReply( Message.QuickReplyType.TEXT, u'重來', payload=EventPayload('MESSAGE_INPUT', 'restart'), acceptable_inputs=[u'好了', u'(?i)restart', '(?i)cancel'])) m.add_quick_reply( Message.QuickReply( Message.QuickReplyType.TEXT, u'放棄', payload=EventPayload('CONTROL_FLOW', 'reset'), acceptable_inputs=['(?i)giveup', '(?i)reset'])) return [m] elif not broadcast_message: Memory.Set('status', 'input_broadcast_message') return [Message(u'請輸入你要廣播的訊息:')] elif status == 'preview_message': msgs = [Message(u'請確認你要廣播的訊息:')] for raw_msg in broadcast_message: msgs.append(Message.FromDict(raw_msg)) m = msgs[-1] m.add_quick_reply( Message.QuickReply(Message.QuickReplyType.TEXT, u'確認', payload=EventPayload( 'CONFIRM_MESSAGE', True), acceptable_inputs=[u'是', '(?i)y', '(?i)ok'])) m.add_quick_reply( Message.QuickReply( Message.QuickReplyType.TEXT, u'取消', payload=EventPayload('CONFIRM_MESSAGE', False), acceptable_inputs=[u'是', '(?i)no', '(?i)cancel'])) return msgs return [Message(u'錯誤的操作')]
def run_get_content(news_info, variables, limit): try: event = variables['event'] content, char_offset, total_length = news_info.get_content( event.value['entry_link'], event.value['char_offset'], limit) src, alt, pic_index = news_info.get_picture( event.value['entry_link'], event.value['pic_index']) except KeyError: return [Message(u'抱歉,有些東西出錯了,請再試一次!')] content_ended = char_offset == -1 picture_ended = pic_index == -1 all_ended = content_ended and picture_ended has_picture = src and alt has_content = content != '' progress = float(char_offset) / total_length * 100 \ if char_offset >= 0 else 100.0 msgs = [] if has_content and not all_ended: m = Message(buttons_text=content) m.add_button(Message.Button( Message.ButtonType.POSTBACK, u'繼續讀 ({:.0f}%)'.format(progress), payload=EventPayload('GET_CONTENT', { 'entry_link': event.value['entry_link'], 'char_offset': char_offset, 'pic_index': pic_index, }, False))) m.add_button(Message.Button( Message.ButtonType.WEB_URL, u'去網站讀', url=event.value['entry_link'])) msgs.append(m) elif has_content: msgs.append(Message(content)) if has_picture: src_msg = Message(image_url=src) if alt.strip(): alt_msg = Message() b = Message.Bubble(alt, subtitle=' ') # Only append button to the last message, so only append if # content is empty if not has_content and not all_ended: b.add_button(Message.Button( Message.ButtonType.POSTBACK, u'繼續看圖 (文字已結束)', payload=EventPayload('GET_CONTENT', { 'entry_link': event.value['entry_link'], 'char_offset': char_offset, 'pic_index': pic_index, }, False))) b.add_button(Message.Button( Message.ButtonType.WEB_URL, u'去網站讀', url=event.value['entry_link'])) alt_msg.add_bubble(b) msgs = [src_msg, alt_msg] + msgs else: msgs = [src_msg] + msgs if all_ended: m = Message(u'這則新聞讀完囉!') add_quick_reply_keywords(news_info, m, True) msgs.append(m) return msgs