class NoconocoStream: def __init__(self, owner='', conf_path=None): self.__account = Account('noconoco_bot', conf_path) self.__bots = { 'chat': NoconocoChat(), 'horse': NoconocoHorse(owner), 'horse_profile': NoconocoHorseProfile(), 'recipe': NoconocoRecipe(), 'stock': NoconocoStock(), 'weather': NoconocoWeather() } def get_info(self): return self.__account.info() def post(self, message, in_reply_to_status_id=None): self.__account.post(message, in_reply_to_status_id) def get_mentions(self): return self.__account.unread_mention() def stream_user_timeline(self): self.__account.userstream( NoconocoStreamListener(account=self, bots=self.__bots)) def get_error_message(self, target): return target + 'とか,そんな言葉知らないしー' + self.get_datetime() def get_datetime(self): d = datetime.datetime.today() return ' (' + d.strftime("%H:%M:%S") + ')'
class NoconocoHorseProfile: def __init__(self, conf_path=None): self.__account = Account('noconoco_bot', conf_path) def get_info(self): return self.__account.info() def post(self, message, in_reply_to_status_id=None): self.__account.post(message, in_reply_to_status_id) def reply(self, mention): message = self.get_reply_message(mention) self.__account.post(message, mention.id_str) def get_mentions(self): return self.__account.unread_mention() def get_reply_message(self, mention): reply_to = '@' + mention.user.screen_name.encode('utf-8') target = (mention.text.split(' ')[1]).encode('utf-8') return '{0} {1}'.format(reply_to, self.get_horse_message(target)) def get_horse_message(self, target): horse_id = self.get_horse_id(target) if horse_id == None: return '「{0}」なんて名前の馬はいないみたいだしー'. format(target, self.get_datetime()) else: return '「{0}」って馬のデータはこれだよー > {1}/{2}/ {3}'.format( target, horse_profile_url, horse_id, self.get_datetime() ) def get_horse_id(self, target): url = '{0}&pid=horse_list&word={1}'.format( search_url, urllib.quote(unicode(target, 'utf-8').encode('euc-jp')) ) res = urllib.urlopen(url) soup = BeautifulSoup(res.read().decode('euc-jp')) elements = soup.find_all('input', {'name': 'id'}) if len(elements) != 1: return None return elements[0].get('value') def get_datetime(self): d = datetime.datetime.today() return ' (' + d.strftime("%H:%M:%S") + ')'
class NoconocoRecipe: def __init__(self, conf_path=None): self.__account = Account('noconoco_bot', conf_path) self.__application_id = self.__account.conf.get('noconoco_recipe', 'rakuten_application_id') def get_info(self): return self.__account.info() def post(self, message, in_reply_to_status_id=None): self.__account.post(message, in_reply_to_status_id) def reply(self, mention): message = self.get_reply_message(mention) self.__account.post(message, mention.id_str) def get_mentions(self): return self.__account.unread_mention() def get_reply_message(self, mention): return '@{0} {1}'.format(mention.user.screen_name.encode('utf-8'), self.get_recipe_message()) def get_recipe_message(self): recipes = self.get_recipe() index = random.randint(0, len(recipes['result'])-1) indication = unicode.encode(recipes['result'][index]['recipeIndication'], 'utf-8') if indication == '指定なし': indication = 'てきとうにがんばるん' message = '今日のおすすめの献立は「 {0} 」だしー.{1}でできるから,とっても簡単だしー. {2}{3}'.format( unicode.encode(recipes['result'][index]['recipeTitle'], 'utf-8'), indication, unicode.encode(recipes['result'][index]['recipeUrl'], 'utf-8'), self.get_datetime() ) return message def get_recipe(self): category = self.get_recipe_category() url = '{0}?applicationId={1}&categoryId={2}'.format(api_base_url, self.__application_id, category) res = urllib2.urlopen(url) return json.loads(res.read()) def get_recipe_category(self): index = random.randint(0, len(main_dish_categories)-1) return main_dish_categories.items()[index][1] def get_datetime(self): d = datetime.datetime.today() return ' (' + d.strftime("%H:%M:%S") + ')'
class NoconocoChat: def __init__(self, conf_path=None): self.__account = Account('noconoco_bot', conf_path) self.__api_key = self.__account.conf.get('noconoco_chat', 'docomo_api_key') self.__context_expire_seconds = self.__account.conf.get('noconoco_chat', 'context_expire_seconds') self.__context = '' self.__mode = '' self.__last_replied = datetime.datetime(1970, 1, 1) def get_info(self): return self.__account.info() def post(self, message, in_reply_to_status_id=None): self.__account.post(message, in_reply_to_status_id) def reply(self, mention): message = self.get_reply_message(mention) self.__account.post(message, mention.id_str) def get_mentions(self): return self.__account.unread_mention() def get_reply_message(self, mention): if self.is_goodbye(mention): response = 'またねー {0}'.format(self.get_datetime()).decode('utf-8') else: response = self.get_chat_message(mention) return '@{0} {1}'.format( mention.user.screen_name.encode('utf-8'), response.encode('utf-8')) def get_chat_message(self, mention=None): url = '{0}?{1}={2}'.format(api_base_url, 'APIKEY', self.__api_key) data = self.get_request_data(mention) header = {'Content-Type': 'application/json'} try: req = urllib2.Request(url, data, header) res = urllib2.urlopen(req) dic = json.loads(res.read()) if 'context' in dic: self.__context = dic['context'] if 'mode' in dic: self.__mode = dic['mode'] self.__last_replied = datetime.datetime.now() return dic['utt'] except urllib2.HTTPError, e: logging.exception('some error occurred in getting chat response process.') return '意味わかんないしー {0}'.format(self.get_datetime())
class NoconocoWeather: def __init__(self, conf_path=None): lines = open(location_path).readlines() self.__locations = {k:'%06d'%int(v) for k,v in [line.strip().split(',') for line in lines]} self.__account = Account('noconoco_bot', conf_path) def get_info(self): return self.__account.info() def post(self, message, in_reply_to_status_id=None): self.__account.post(message, in_reply_to_status_id) def reply(self, mention): message = self.get_reply_message(mention) self.__account.post(message, mention.id_str) def get_mentions(self): return self.__account.unread_mention() def get_reply_message(self, mention): location = (mention.text.split(' ')[1]).encode('utf-8') return '@' + mention.user.screen_name.encode('utf-8') +\ ' ' + self.get_weather_message(location) def get_weather_message(self, location): location_code = self.encode_location(location) if location_code is None: return self.get_error_message(location) else: info = self.get_weather_info(location_code) message = (info['location']['city']).encode('utf-8') + 'の天気をお知らせするしー\n' for i in range(0, 2): date = (info['forecasts'][i]['dateLabel']).encode('utf-8') weather = (info['forecasts'][i]['telop']).encode('utf-8') temp = info['forecasts'][i]['temperature']['max'] if temp is not None: temp = (temp['celsius']).encode('utf-8') + '度だ' else: temp = 'よくわかんない' message = message + date + 'の天気は「' + weather + '」で最高気温は' + temp + 'し\n' return message + 'そんなことより早くあたしを撫でればいいし' + self.get_datetime() def get_weather_info(self, location): url = api_base_url + '?city=%s' % location res = urllib2.urlopen(url) return json.loads(res.read()) def encode_location(self, location): if location in self.__locations: return self.__locations[location] else: return None def get_error_message(self, location): return location + 'とか,そんな場所知らないしー' + self.get_datetime() def stream_user_timeline(self): self.__account.userstream(NoconocoWeatherStreamListener(bot=self)) def get_datetime(self): d = datetime.datetime.today() return ' (' + d.strftime("%H:%M:%S") + ')'
class NoconocoHorse: def __init__(self, owner, conf_path=None): self.__account = Account('noconoco_bot', conf_path) self.__targets = self.get_target_list(owner) def get_info(self): return self.__account.info() def post(self, message, in_reply_to_status_id=None): self.__account.post(message, in_reply_to_status_id) def reply(self, mention): message = self.get_wait_message(mention) self.__account.post(message, mention.id_str) messages = self.get_reply_messages(mention) for message in messages: self.__account.post(message, mention.id_str) sleep(1) def get_mentions(self): return self.__account.unread_mention() def get_wait_message(self, mention): reply_to = '@{0} '.format(mention.user.screen_name.encode('utf-8')) return '{0} 調べるからちょっと待ってて欲しいのー{1}'.format( reply_to, self.get_datetime() ) def get_reply_messages(self, mention): reply_to = '@{0} '.format(mention.user.screen_name.encode('utf-8')) return self.create_messages(reply_to) def post_messages(self): for message in self.create_messages(): self.post(message) sleep(wait_time) def create_messages(self, reply_to=''): messages = [] for starter, day in self.get_starters().items(): message = '{0}よくわかんないけど,{1}のレースに{2}が出走するみたいだしー{3}'.format( reply_to, day, str(starter.encode('utf-8')), self.get_datetime(), ) messages.append(message) if len(messages) == 0: message = '{0}今週は出走予定の馬がいないみたい.しょぼーん{1}'.format( reply_to, self.get_datetime() ) messages.append(message) return messages def get_target_list(self, owner, n_of_list=100): url = '{0}&owner={1}&list={2}'.format( target_list_url, urllib.quote(unicode(owner, 'utf-8').encode('euc-jp')), n_of_list ) res = urllib.urlopen(url) soup = BeautifulSoup(res.read().decode('euc-jp')) return [e.text for e in soup.find_all('td', {'class': 'bml txt_l'})] def get_race_days(self): res = urllib.urlopen(sports_navi_url) soup = BeautifulSoup(res.read()) race_days = {} for day in soup.find_all('td', {'class': 'fntS txC'}): for link in day.find_all('a'): path = link.get('href') if 'horse' in path: day = re.search(r'[0-9]+', path).group() day = '{0}月{1}日'.format(day[4:6], day[6:8]) race_days[day] = link.get('href') return race_days def get_starters(self): starters = {} for day, path in self.get_race_days().items(): for kana in kanas: url = '{0}{1}&kana={2}'.format( sports_navi_url, path, kana ) res = urllib.urlopen(url) soup = BeautifulSoup(res.read()) horses = [e.text for e in soup.find_all('a') if '/directory/horse/' in e.get('href')] targets = [t for t in self.__targets if t in horses] for t in targets: starters[t] = day sleep(wait_time) return starters def get_datetime(self): d = datetime.datetime.today() return ' (' + d.strftime("%H:%M:%S") + ')'
class NoconocoStock: def __init__(self, conf_path=None): self.__account = Account('noconoco_bot', conf_path) def get_info(self): return self.__account.info() def post(self, message, in_reply_to_status_id=None): self.__account.post(message, in_reply_to_status_id) def reply(self, mention): message = self.get_reply_message(mention) self.__account.post(message, mention.id_str) def get_mentions(self): return self.__account.unread_mention() def get_reply_message(self, mention): reply_to = '@' + mention.user.screen_name.encode('utf-8') target = (mention.text.split(' ')[1]).encode('utf-8') stock_id, stock_name = self.get_stock_id_name(target) return reply_to + ' ' + self.get_stock_message(stock_id, stock_name) def get_stock_message(self, stock_id, stock_name): q = jsm.Quotes() d = q.get_price(stock_id) price = self.get_stock_price(stock_id) if d is None or price is None: return self.get_error_message(stock_name) message = stock_name + '(' + str(stock_id) + ')の株価は' + str(price) + 'だしー\n'\ '前日終値は' + str(d.close) + 'で今日の始値は' + str(d.open) +\ ',高値は' + str(d.high) + ',安値は' + str(d.low) + 'だしー\n' return message + 'そんなことより早くあたしを撫でればいいし' + self.get_datetime() def get_stock_id_name(self, target): stock_id = self.get_stock_id(target) stock_name = self.get_stock_name(target) if stock_id is None and stock_name is None: return None, None elif stock_id is None: stock_id = self.get_stock_id(stock_name) elif stock_name is None: stock_id = int(stock_id) stock_name = self.get_stock_name(stock_id) return stock_id, stock_name def get_stock_price(self, stock_id): try: url = stock_url + 'stocks/detail/?code=' + str(stock_id) soup = BeautifulSoup(urlopen(url)) res = soup.find_all('td', class_='stoksPrice') regex= r'<.+>(.+)<.+>' price = re.search(regex, str(res[1])).group(1) return int(price.replace(',', '')) except: return None def get_stock_id(self, stock_name): try: url = info_url + 'search/?query=' + stock_name soup = BeautifulSoup(urlopen(url)) res = soup.find('span', {'class': 'code highlight'}) regex = r'\[([0-9]+)\]' matches = re.search(regex, str(res)) if matches is not None: return int(matches.group(1)) else: return None except: return None def get_stock_name(self, stock_id): try: url = info_url + 'search/?query=' + str(stock_id) soup = BeautifulSoup(urlopen(url)) title = str(soup.find('title')) regex = r'<title>(.+)【[0-9]+】.+</title>' return re.search(regex, title).group(1) except: return None def get_error_message(self, target): return target + 'とか,そんな銘柄知らないしー' + self.get_datetime() def stream_user_timeline(self): self.__account.userstream(NoconocoStockStreamListener(bot=self)) def get_datetime(self): d = datetime.datetime.today() return ' (' + d.strftime("%H:%M:%S") + ')'