def parse_config(): """ Returns a Python object with CointipBot configuration """ lg.debug('CointipBot::parse_config(): parsing config files...') conf = {} prefix = './conf/' try: for path in glob.glob(prefix + '*.yml'): f = ntpath.basename(path) lg.debug("CointipBot::parse_config(): reading %s", f) conf[f.split('.')[0]] = yaml.load(open(path), Loader=yaml.FullLoader) for folder in ['reddit', 'twitter', 'twitch', 'irc']: conf[folder] = {} for path in glob.glob(prefix + folder + '/*.yml'): f = ntpath.basename(path) lg.debug("CointipBot::parse_config(): reading %s/%s", folder, f) conf[folder][f.split('.')[0]] = yaml.load( open(path), Loader=yaml.FullLoader) except yaml.YAMLError as e: lg.error("CointipBot::parse_config(): error reading config file: %s", e) if hasattr(e, 'problem_mark'): lg.error( "CointipBot::parse_config(): error position: (line %s, column %s)", e.problem_mark.line + 1, e.problem_mark.column + 1) sys.exit(1) lg.info('CointipBot::parse_config(): config files has been parsed') return ctb_misc.DotDict(conf)
def parse_config(self): """ Returns a Python object with CointipBot configuration """ lg.debug('CointipBot::parse_config(): parsing config files...') conf = {} try: prefix = './conf/' for i in [ 'coins', 'db', 'exchanges', 'fiat', 'keywords', 'logs', 'misc', 'reddit', 'regex' ]: lg.debug("CointipBot::parse_config(): reading %s%s.yml", prefix, i) conf[i] = yaml.load(open(prefix + i + '.yml')) except yaml.YAMLError as e: lg.error( "CointipBot::parse_config(): error reading config file: %s", e) if hasattr(e, 'problem_mark'): lg.error( "CointipBot::parse_config(): error position: (line %s, column %s)", e.problem_mark.line + 1, e.problem_mark.column + 1) sys.exit(1) lg.info('CointipBot::parse_config(): config files has been parsed') return ctb_misc.DotDict(conf)
def _parse_direct_message(self, event_data): recipient_id = event_data['message_create']['target']['recipient_id'] sender_id = event_data['message_create']['sender_id'] sender_screen_name = self.get_user_name(sender_id) message_text = event_data['message_create']['message_data']['text'] msg = { 'created_utc': self._timestamp_utc_now(), 'author': { 'name': sender_screen_name }, 'recipient_id': sender_id, 'type': 'direct_message' } msg['id'] = event_data['id'] + str( msg['created_utc'])[(30 - len(event_data['id'])):] text = event_data['message_create']['message_data']['text'] msg['body'] = text.replace('@' + self.user, '').strip() lg.debug(msg) action = ctb_action.eval_message(ctb_misc.DotDict(msg), self.ctb) return action
def on_pubmsg(self, c, e): ch = e.target nick = e.source.nick text = ' '.join(e.arguments) lg.debug('IRCChatBot::on_pubmsg(): %s on %s: %s', nick, ch, text) # ignore my own message if nick == self.username: return None # commands must start with + if text[0] != '+': return None now = datetime.utcnow().replace(tzinfo=pytz.utc) msg = { 'created_utc': calendar.timegm(now.utctimetuple()), 'author': { 'name': nick } } msg['id'] = str(msg['created_utc']) msg['body'] = text print(msg) action = ctb_action.eval_message(ctb_misc.DotDict(msg), self.ctb) if action: lg.info("IRCChatBot::on_pubmsg(): %s from %s", action.type, action.u_from.name) lg.debug("IRCChatBot::on_pubmsg(): comment body: <%s>", action.msg.body) action.do()
def _parse_mention(self, data): # ignore retweets if 'retweeted_status' in data: return None author_name = data['user']['screen_name'] if author_name == self.user or '@' + self.user not in data['text']: return None # we do allow the bot to issue commands msg = { 'created_utc': self._timestamp_utc_now(), 'author': { 'name': author_name }, 'type': 'mention' } msg['id'] = data['id_str'] + str( msg['created_utc'])[(30 - len(data['id_str'])):] text = data['text'] msg['body'] = text.replace('@' + self.user, '').strip() print(msg) action = ctb_action.eval_message(ctb_misc.DotDict(msg), self.ctb) return action
def follow_followers(self): lg.debug('TwitterStreamer::follow_followers(): started') # only get the latest followers but this relies on Twitter returns the latest followers first followers = [] for fid in self.conn.cursor(self.conn.get_followers_ids, count=5000): followers.append(fid) friends = [] for fid in self.conn.cursor(self.conn.get_friends_ids, count=5000): friends.append(fid) pending = [] for fid in self.conn.cursor(self.conn.get_outgoing_friendship_ids): pending.append(fid) lg.debug( 'TwitterStreamer::follow_followers(): looking for new followers') to_follow = [ f for f in followers[:100] if f not in friends and f not in pending ] lg.debug( 'TwitterStreamer::follow_followers(): about to send follow request' ) # only follow 10 at a time actions = [] for user_id in to_follow[:10]: try: resp = self.conn.create_friendship(user_id=user_id) time.sleep(1) except TwythonError as e: # either really failed (e.g. sent request before) or already friends lg.warning( "TwitterStreamer::follow_followers: failed to follow user %s: %s", user_id, e.msg) continue else: lg.debug( 'TwitterStreamer::follow_followers(): just sent request to follow user %s', user_id) msg = { 'id': str(user_id), 'created_utc': self._timestamp_utc_now(), 'author': { 'name': resp['screen_name'] }, 'body': '+register', 'type': 'mention' } # make the msg id unique msg['id'] += ('@' + str(msg['created_utc'])) action = ctb_action.eval_message(ctb_misc.DotDict(msg), self.ctb) actions.append(action) return actions
def _parse_follow(self, event_data): event = event_data['event'] source_id = event['source']['id'] source_name = event['source']['screen_name'] msg = {'id': source_id, 'created_utc': self._timestamp_utc_now(), 'author': {'name': source_name}, 'body': '+register', 'type': 'direct_message'} # make the msg id unique msg['id'] += ('@' + str(msg['created_utc'])) lg.debug(msg) action = ctb_action.eval_message(ctb_misc.DotDict(msg), self.ctb) return action
def _parse_mention(self, event_data): event = event_data['event'] author_name = event['user']['screen_name'] # we do allow the bot to issue commands msg = {'created_utc': self._timestamp_utc_now(), 'author': {'name': author_name}, 'type': 'mention'} msg['id'] = event['id_str'] + str(msg['created_utc'])[(30-len(event['id_str'])):] text = event['text'] msg['body'] = text.replace('@' + self.username, '').strip() lg.debug(msg) action = ctb_action.eval_message(ctb_misc.DotDict(msg), self.ctb) return action
def _parse_direct_msg(self, data): # ignore direct message from the bot itself author_name = data['sender']['screen_name'] if author_name == self.username: return None msg = { 'created_utc': self._timestamp_utc_now(), 'author': { 'name': author_name }, 'type': 'direct_message' } msg['id'] = data['id_str'] + str( msg['created_utc'])[(30 - len(data['id_str'])):] text = data['text'] msg['body'] = text.replace('@' + self.username, '').strip() print(msg) action = ctb_action.eval_message(ctb_misc.DotDict(msg), self.ctb) return action
def parse_config(self): """ Returns a Python object with CointipBot configuration """ lg.debug("CointipBot::parse_config(): parsing config files...") conf = {} try: prefix = "./conf/" for i in [ "coins", "db", "exchanges", "fiat", "keywords", "logs", "misc", "reddit", "regex", ]: lg.debug("CointipBot::parse_config(): reading %s%s.yml", prefix, i) conf[i] = yaml.load(open(prefix + i + ".yml")) except yaml.YAMLError as e: lg.error( "CointipBot::parse_config(): error reading config file: %s", e) if hasattr(e, "problem_mark"): lg.error( "CointipBot::parse_config(): error position: (line %s, column %s)", e.problem_mark.line + 1, e.problem_mark.column + 1, ) sys.exit(1) lg.info("CointipBot::parse_config(): config files has been parsed") return ctb_misc.DotDict(conf)