def handle_incoming_messages(last_updated): r = get_updates(last_updated) split_chat_text = [] if r['ok']: for req in r['result']: chat_sender_id = req['message']['chat']['id'] try: chat_text = req['message']['text'] split_chat_text = chat_text.split() except KeyError: chat_text = '' split_chat_text.append(chat_text) log.debug('Looks like no chat text was detected... moving on') try: person_id = req['message']['from']['id'] except KeyError: pass log.info('Chat text received: {0}'.format(chat_text)) r = re.search('(source+)(.*)', chat_text) if (r is not None and r.group(1) == 'source'): if r.group(2): sources_dict[person_id] = r.group(2) log.debug('Sources set for {0} to {1}'.format(sources_dict[person_id], r.group(2))) post_message(person_id, 'Sources set as {0}!'.format(r.group(2))) else: post_message(person_id, 'We need a comma separated list of subreddits! No subreddit, no news :-(') if chat_text == '/stop': log.debug('Added {0} to skip list'.format(chat_sender_id)) skip_list.append(chat_sender_id) post_message(chat_sender_id, "Ok, we won't send you any more messages.") if chat_text in ('/start', '/help'): helptext = ''' Hi! This is a News Bot which fetches news from subreddits. Use "/source" to select a subreddit source. Example "/source programming,games" fetches news from r/programming, r/games. Use "/fetch for the bot to go ahead and fetch the news. At the moment, bot will fetch total of 5 posts from all sub reddits I will have this configurable soon. ''' post_message(chat_sender_id, helptext) if split_chat_text[0] == '/fetch' and (person_id not in skip_list): post_message(person_id, 'Hang on, fetching your news..') try: sub_reddits = sources_dict[person_id] except KeyError: post_message(person_id, ERR_NO_SOURCE) else: summarized_news = get_latest_news(sources_dict[person_id]) post_message(person_id, summarized_news) last_updated = req['update_id'] with open('last_updated.txt', 'w') as f: f.write(str(last_updated)) States.last_updated = last_updated log.debug( 'Updated last_updated to {0}'.format(last_updated)) f.close()
def get_updates(last_updated): log.debug('Checking for requests, last updated passed is: {last_updated}') sleep(UPDATE_PERIOD) response = requests.get(f"{API_BASE}/getUpdates", params={'offset': last_updated+1}) json_response = FALSE_RESPONSE if response.status_code != 200: # wait for a bit, try again sleep(UPDATE_PERIOD*20) get_updates(last_updated) try: json_response = response.json() except ValueError: sleep(UPDATE_PERIOD*20) get_updates(last_updated) log.info(f"received response: {json_response}") return json_response
def get_updates(last_updated): log.debug('Checking for requests, last updated passed is: {}'.format(last_updated)) sleep(UPDATE_PERIOD) response = requests.get(API_BASE + BOT_KEY + '/getUpdates', params={'offset': last_updated+1}) json_response = FALSE_RESPONSE if response.status_code != 200: # wait for a bit, try again sleep(UPDATE_PERIOD*20) get_updates(last_updated) try: json_response = response.json() except ValueError: sleep(UPDATE_PERIOD*20) get_updates(last_updated) log.info('received response: {}'.format(json_response)) return json_response
def get_latest_news(sub_reddits): log.debug('Fetching news from reddit') r = praw.Reddit(user_agent='NewsBot', client_id='ralalsYuEJXKDg', client_secret="16DD-6O7VVaYVMlkUPZWLhdluhU") r.read_only = True # Can change the subreddit or add more. sub_reddits = clean_up_subreddits(sub_reddits) log.info(f'Fetching subreddits: {sub_reddits}') submissions = r.subreddit(sub_reddits).hot(limit=5) submission_content = '' try: for post in submissions: submission_content += post.title + ' - ' + post.url + '\n\n' except praw.errors.Forbidden: log.debug(f'subreddit {sub_reddits} is private') submission_content = "Sorry couldn't fetch; subreddit is private" except praw.errors.InvalidSubreddit: log.debug(f'Subreddit {sub_reddits} is invalid or doesn' 't exist') submission_content = "Sorry couldn't fetch; subreddit doesn't seem to exist" return submission_content
def get_latest_news(sub_reddits): log.debug('Fetching news from reddit') r = praw.Reddit(user_agent='Practical Docker With Python tutorial') # Can change the subreddit or add more. sub_reddits = clean_up_subreddits(sub_reddits) log.debug(f"Fetching subreddits: {sub_reddits}") submissions = r.get_subreddit(sub_reddits).get_top(limit=5) submission_content = '' try: for post in submissions: submission_content += f"{post.title} - {post.url} \n\n" except praw.errors.Forbidden: log.info(f"subreddit {sub_reddits} is private".format()) submission_content = "Sorry couldn't fetch; subreddit is private" except praw.errors.InvalidSubreddit: log.info(f"Subreddit {sub_reddits} is invalid or doesn''t exist.") submission_content = "Sorry couldn't fetch; subreddit doesn't seem to exist" except praw.errors.NotFound : log.info(f"Subreddit {sub_reddits} is invalid or doesn''t exist.") submission_content = "Sorry couldn't fetch; something went wrong, please do send a report to @sathyabhat" return submission_content
def summarize(url): log.info('Not yet implemented!') return url
def handle_incoming_messages(last_updated): r = get_updates(last_updated) split_chat_text = [] if r['ok']: for req in r['result']: if 'message' in req: chat_sender_id = req['message']['chat']['id'] else: chat_sender_id = req['edited_message']['chat']['id'] try: chat_text = req['message']['text'] split_chat_text = chat_text.split() except KeyError: chat_text = '' split_chat_text.append(chat_text) log.debug('Looks like no chat text was detected... moving on') if 'message' in req: person_id = req['message']['from']['id'] else: person_id = req['edited_message']['from']['id'] log.info(f"Chat text received: {chat_text}") r = re.search('(source+)(.*)', chat_text) if (r is not None and r.group(1) == 'source'): if r.group(2): sources_dict[person_id] = r.group(2) log.info( f'Sources set for {person_id} to {sources_dict[person_id]}' ) with db.atomic() as txn: try: sources = Source.create( person_id=person_id, fetch_from=sources_dict[person_id]) log.debug(f'Inserted row id: {sources.person_id}') except peewee.IntegrityError: sources = Source.update( fetch_from=sources_dict[person_id]).where( person_id == person_id) rows_updated = sources.execute() log.info(f'Updated {rows_updated} rows') txn.commit() post_message(person_id, 'Sources set as {0}!'.format(r.group(2))) else: post_message( person_id, 'We need a comma separated list of subreddits! No subreddit, no news :-(' ) if chat_text == '/stop': log.debug(f'Added {chat_sender_id} to skip list') skip_list.append(chat_sender_id) post_message(chat_sender_id, "Ok, we won't send you any more messages.") if chat_text in ('/start', '/help'): helptext = ''' Hi! This is a News Bot which fetches news from subreddits. Use "/source" to select a subreddit source. Example "/source programming,games" fetches news from r/programming, r/games. Use "/fetch for the bot to go ahead and fetch the news. At the moment, bot will fetch total of 5 posts from the selected subreddit. ''' post_message(chat_sender_id, helptext) if split_chat_text[0] == '/fetch' and (person_id not in skip_list): post_message(person_id, 'Hang on, fetching your news..') try: sub_reddits = Source.get( person_id=person_id).fetch_from.strip() summarized_news = get_latest_news(sub_reddits) post_message(person_id, summarized_news) except peewee.DoesNotExist: post_message(person_id, ERR_NO_SOURCE) last_updated = req['update_id'] with open('last_updated.txt', 'w') as f: f.write(str(last_updated)) States.last_updated = last_updated log.debug(f'Updated last_updated to {last_updated}') f.close()
def post_message(chat_id, text): log.info('posting {} to {}'.format(text, chat_id)) payload = {'chat_id': chat_id, 'text': text} requests.post(API_BASE + BOT_KEY + '/sendMessage', data=payload)
from states import States, log from telegram import handle_incoming_messages def get_last_updated(): try: with open('last_updated.txt', 'r') as f: try: last_updated = int(f.read()) except ValueError: last_updated = 0 f.close() except FileNotFoundError: last_updated = 0 log.debug('Last updated id: {0}'.format(last_updated)) return last_updated if __name__ == '__main__': try: log.debug('Starting up') States.last_updated = get_last_updated() while True: handle_incoming_messages(States.last_updated) except KeyboardInterrupt: log.info('Received KeybInterrupt, exiting')
from states import States, log from telegram import handle_incoming_messages def get_last_updated(): try: with open('last_updated.txt', 'r') as f: try: last_updated = int(f.read()) except ValueError: last_updated = 0 f.close() except FileNotFoundError: last_updated = 0 log.debug(f"Last updated id: {last_updated}") return last_updated if __name__ == '__main__': try: log.info("Starting up") States.last_updated = get_last_updated() while True: handle_incoming_messages(States.last_updated) except KeyboardInterrupt: log.info("Received KeybInterrupt, exiting")
def get_last_updated(): try: with open('last_updated.txt', 'r') as f: try: last_updated = int(f.read()) except ValueError: last_updated = 0 f.close() except FileNotFoundError: last_updated = 0 log.debug('Last updated id: {0}'.format(last_updated)) return last_updated if __name__ == '__main__': log.info('Starting up') log.info('Waiting for 60 seconds for db to come up') sleep(60) log.info('Checking on dbs') try: db.connect() except OperationalError as o: print("Could not connect to db, please check db parameters") sys.exit(-1) except InternalError as e: # 1049 is MySQL error code for db doesn't exist - so we create it. db_connection = pymysql.connect(host='mysql', user='******', password='******') db_connection.cursor().execute('CREATE DATABASE newsbot')