diff --git a/source-code/chapter-5/exercise-2/newsbot/telegram.py b/source-code/chapter-5/exercise-2/newsbot/telegram.py index d0fa464..7d212fd 100644 --- a/source-code/chapter-5/exercise-2/newsbot/telegram.py +++ b/source-code/chapter-5/exercise-2/newsbot/telegram.py @@ -98,7 +98,7 @@ def handle_incoming_messages(last_updated): summarized_news = get_latest_news(sub_reddits) post_message(person_id, summarized_news) except peewee.DoesNotExist: - post_message(person_id, 'Could not find a saved subreddit, please try setting sources with /source') + post_message(person_id, ERR_NO_SOURCE) last_updated = req['update_id'] with open('last_updated.txt', 'w') as f: diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/Dockerfile b/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/Dockerfile deleted file mode 100644 index b92eb0d..0000000 --- a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM python:3-alpine -RUN apk add gcc musl-dev python3-dev libffi-dev openssl-dev -COPY * /apps/subredditfetcher/ -WORKDIR /apps/subredditfetcher/ - -VOLUME [ "/apps/subredditfetcher" ] -RUN ["pip", "install", "-r", "requirements.txt"] - -ENV NBT_ACCESS_TOKEN="495637361:AAHIhiDTX1UeX17KJy0-FsMZEqEtCFYfcP8" - -CMD ["python", "newsbot.py"] diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/constants.py b/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/constants.py deleted file mode 100644 index cb189fe..0000000 --- a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/constants.py +++ /dev/null @@ -1,11 +0,0 @@ -__author__ = 'Sathyajith' - -import os -ERR_NO_SOURCE = 'No sources defined! Set a source using /source list, of, sub, reddits' -skip_list = [] -sources_dict = {} - -BOT_KEY = os.environ['NBT_ACCESS_TOKEN'] -API_BASE = 'https://api.telegram.org/bot' -UPDATE_PERIOD = 6 -FALSE_RESPONSE = {"ok": False} \ No newline at end of file diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/docker-compose.yml b/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/docker-compose.yml deleted file mode 100644 index 2c0a4e5..0000000 --- a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/docker-compose.yml +++ /dev/null @@ -1,23 +0,0 @@ -version: '3' -services: - app: - build: . - depends_on: - - mysql - restart: "on-failure" - volumes: - - "appdata:/apps/subredditfetcher" - mysql: - image: mysql - volumes: - - "dbdata:/var/lib/mysql" - environment: - - MYSQL_ROOT_PASSWORD=dontusethisinprod - adminer: - image: adminer - ports: - - "8080:8080" - -volumes: - dbdata: - appdata: diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/main.py b/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/main.py deleted file mode 100644 index bacc165..0000000 --- a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/main.py +++ /dev/null @@ -1,22 +0,0 @@ -from flask import Flask -from newsbot import * -from states import States - -bot = Flask(__name__) - - -@bot.route('/index') -def index(): - return 'Thou shalt not pass!' - - -@bot.route('/telegram-update', methods=['POST']) -def telegram_update(): - handle_incoming_messages(States.last_updated_id) - - -if __name__ == '__main__': - States.last_updated_id = get_last_updated() - bot.run() - - diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/one_time.py b/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/one_time.py deleted file mode 100644 index f7074d9..0000000 --- a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/one_time.py +++ /dev/null @@ -1,11 +0,0 @@ - -from models import * - - -def create_tables(): - db.connect() - db.create_tables([Source, Request, Message], True) - db.close() - -if __name__ == '__main__': - create_tables() diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/requirements.txt b/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/requirements.txt deleted file mode 100644 index 8854d79..0000000 --- a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -praw -peewee==2.10.2 -PyMySQL diff --git a/source-code/chapter-6/exercise-1/newsbot/Dockerfile b/source-code/chapter-6/exercise-1/newsbot/Dockerfile new file mode 100644 index 0000000..7d69914 --- /dev/null +++ b/source-code/chapter-6/exercise-1/newsbot/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3-alpine + +RUN apk add gcc musl-dev python3-dev libffi-dev openssl-dev cargo +WORKDIR /apps/subredditfetcher/ +COPY . . + +RUN pip install --upgrade pip && pip install -r requirements.txt +VOLUME ["/data"] +CMD ["python", "newsbot.py"] diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/LICENSE b/source-code/chapter-6/exercise-1/newsbot/LICENSE similarity index 100% rename from source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/LICENSE rename to source-code/chapter-6/exercise-1/newsbot/LICENSE diff --git a/source-code/chapter-6/exercise-1/newsbot/constants.py b/source-code/chapter-6/exercise-1/newsbot/constants.py new file mode 100644 index 0000000..092cde6 --- /dev/null +++ b/source-code/chapter-6/exercise-1/newsbot/constants.py @@ -0,0 +1,15 @@ +__author__ = 'Sathyajith' + +from os import environ +from sys import exit +ERR_NO_SOURCE = 'No sources defined! Set a source using /source list, of, sub, reddits' +skip_list = [] +sources_dict = {} +UPDATE_PERIOD = 1 +FALSE_RESPONSE = {"ok": False} + +BOT_KEY = environ.get('NBT_ACCESS_TOKEN') +if not BOT_KEY: + print("Telegram access token not set, exiting.") + exit(1) +API_BASE = f'https://api.telegram.org/bot{BOT_KEY}' \ No newline at end of file diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/last_updated.txt b/source-code/chapter-6/exercise-1/newsbot/last_updated.txt similarity index 100% rename from source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/last_updated.txt rename to source-code/chapter-6/exercise-1/newsbot/last_updated.txt diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/models.py b/source-code/chapter-6/exercise-1/newsbot/models.py similarity index 85% rename from source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/models.py rename to source-code/chapter-6/exercise-1/newsbot/models.py index a7834ba..ec73558 100644 --- a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/models.py +++ b/source-code/chapter-6/exercise-1/newsbot/models.py @@ -1,6 +1,8 @@ -from peewee import * -# db = SqliteDatabase('newsbot.db') +from peewee import Model, PrimaryKeyField, IntegerField, CharField, DateTimeField, MySQLDatabase + + db = MySQLDatabase(host="mysql", port=3306, user="root", password="dontusethisinprod", database="newsbot") + class BaseModel(Model): class Meta: database = db diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/newsbot.db b/source-code/chapter-6/exercise-1/newsbot/newsbot.db similarity index 100% rename from source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/newsbot.db rename to source-code/chapter-6/exercise-1/newsbot/newsbot.db diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/newsbot.py b/source-code/chapter-6/exercise-1/newsbot/newsbot.py similarity index 69% rename from source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/newsbot.py rename to source-code/chapter-6/exercise-1/newsbot/newsbot.py index 659bc41..020aba5 100644 --- a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/newsbot.py +++ b/source-code/chapter-6/exercise-1/newsbot/newsbot.py @@ -2,8 +2,7 @@ from telegram import handle_incoming_messages from models import * from time import sleep - -import sys +from peewee import OperationalError import pymysql @@ -28,14 +27,12 @@ def get_last_updated(): 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= 'root', password='dontusethisinprod') - db_connection.cursor().execute('CREATE DATABASE newsbot') - db_connection.close() + except OperationalError as e: + error_code, message = e.args[0], e.args[1] + if error_code == 1049: + db_connection = pymysql.connect(host='mysql', user= 'root', password='dontusethisinprod') + db_connection.cursor().execute('CREATE DATABASE newsbot') + db_connection.close() db.create_tables([Source, Request, Message], True) try: diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/reddit.py b/source-code/chapter-6/exercise-1/newsbot/reddit.py similarity index 63% rename from source-code/chapter-7/exercise-2/subreddit-fetcher-compose/reddit.py rename to source-code/chapter-6/exercise-1/newsbot/reddit.py index 31f8dff..7f065eb 100644 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/reddit.py +++ b/source-code/chapter-6/exercise-1/newsbot/reddit.py @@ -4,35 +4,30 @@ __author__ = 'Sathyajith' -def summarize(url): - log.info('Not yet implemented!') - return url - - def get_latest_news(sub_reddits): log.debug('Fetching news from reddit') - r = praw.Reddit(user_agent='SubReddit Newsfetcher Bot', + 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('Fetching subreddits: {0}'.format(sub_reddits)) + log.info('Fetching subreddits: {sub_reddits}') submissions = r.subreddit(sub_reddits).hot(limit=5) submission_content = '' try: for post in submissions: - submission_content += summarize(post.title + ' - ' + post.url) + '\n\n' + submission_content += post.title + ' - ' + post.url + '\n\n' except praw.errors.Forbidden: - log.debug('subreddit {0} is private'.format(sub_reddits)) + log.debug(f'subreddit {sub_reddits} is private') submission_content = "Sorry couldn't fetch; subreddit is private" except praw.errors.InvalidSubreddit: - log.debug('Subreddit {} is invalid or doesn''t exist.'.format(sub_reddits)) + 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 clean_up_subreddits(sub_reddits): - log.debug('Got subreddits to clean: {0}'.format(sub_reddits)) + log.debug(f'Got subreddits to clean: {sub_reddits}') return sub_reddits.strip().replace(" ", "").replace(',', '+') diff --git a/source-code/chapter-6/exercise-1/newsbot/requirements.txt b/source-code/chapter-6/exercise-1/newsbot/requirements.txt new file mode 100644 index 0000000..0d19ff9 --- /dev/null +++ b/source-code/chapter-6/exercise-1/newsbot/requirements.txt @@ -0,0 +1,4 @@ +peewee==2.10.2 +praw==7.4.0 +PyMySQL +cryptography \ No newline at end of file diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/states.py b/source-code/chapter-6/exercise-1/newsbot/states.py similarity index 100% rename from source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/states.py rename to source-code/chapter-6/exercise-1/newsbot/states.py diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/telegram.py b/source-code/chapter-6/exercise-1/newsbot/telegram.py similarity index 66% rename from source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/telegram.py rename to source-code/chapter-6/exercise-1/newsbot/telegram.py index 5e150c7..d852d72 100644 --- a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/telegram.py +++ b/source-code/chapter-6/exercise-1/newsbot/telegram.py @@ -6,15 +6,16 @@ from constants import * from reddit import get_latest_news from models import * +import peewee __author__ = 'Sathyajith' db = MySQLDatabase(host="mysql", port=3306, user="root", password="dontusethisinprod", database="newsbot") def get_updates(last_updated): - log.debug('Checking for requests, last updated passed is: {}'.format(last_updated)) + log.debug('Checking for requests, last updated passed is: {last_updated}') sleep(UPDATE_PERIOD) - response = requests.get(API_BASE + BOT_KEY + '/getUpdates', params={'offset': last_updated+1}) + 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 @@ -25,14 +26,14 @@ def get_updates(last_updated): except ValueError: sleep(UPDATE_PERIOD*20) get_updates(last_updated) - log.info('received response: {}'.format(json_response)) + log.info(f"received response: {json_response}") return json_response def post_message(chat_id, text): - log.info('posting {} to {}'.format(text, chat_id)) + log.debug(f"posting {text} to {chat_id}") payload = {'chat_id': chat_id, 'text': text} - requests.post(API_BASE + BOT_KEY + '/sendMessage', data=payload) + requests.post(f"{API_BASE}/sendMessage", data=payload) def handle_incoming_messages(last_updated): @@ -40,7 +41,10 @@ def handle_incoming_messages(last_updated): split_chat_text = [] if r['ok']: for req in r['result']: - chat_sender_id = req['message']['chat']['id'] + 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() @@ -48,30 +52,33 @@ def handle_incoming_messages(last_updated): chat_text = '' split_chat_text.append(chat_text) log.debug('Looks like no chat text was detected... moving on') - try: + + if 'message' in req: person_id = req['message']['from']['id'] - except KeyError: - pass + else: + person_id = req['edited_message']['from']['id'] - log.info('Chat text received: {0}'.format(chat_text)) + 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('Sources set for {0} to {1}'.format(person_id, sources_dict[person_id])) - try: - sources = Source.create(person_id = person_id, fetch_from = sources_dict[person_id]) - except IntegrityError: - sources = Source.get(person_id = person_id) - sources.fetch_from = sources_dict[person_id] - sources.save() - log.info(sources.person_id) + 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('Added {0} to skip list'.format(chat_sender_id)) + 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.") @@ -79,19 +86,17 @@ def handle_incoming_messages(last_updated): 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. + 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: + except peewee.DoesNotExist: post_message(person_id, ERR_NO_SOURCE) last_updated = req['update_id'] @@ -99,5 +104,5 @@ def handle_incoming_messages(last_updated): f.write(str(last_updated)) States.last_updated = last_updated log.debug( - 'Updated last_updated to {0}'.format(last_updated)) + f'Updated last_updated to {last_updated}') f.close() diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/Dockerfile b/source-code/chapter-7/exercise-1/docker-compose-adminer/Dockerfile deleted file mode 100644 index 29069bc..0000000 --- a/source-code/chapter-7/exercise-1/docker-compose-adminer/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM python:3-alpine - -RUN apk add gcc musl-dev python3-dev libffi-dev openssl-dev -COPY * /apps/subredditfetcher/ -WORKDIR /apps/subredditfetcher/ - -VOLUME [ "/apps/subredditfetcher" ] -RUN ["pip", "install", "-r", "requirements.txt"] -# RUN ["python", "one_time.py"] - -ENV NBT_ACCESS_TOKEN="495637361:AAHIhiDTX1UeX17KJy0-FsMZEqEtCFYfcP8" - -CMD ["python", "newsbot.py"] diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/constants.py b/source-code/chapter-7/exercise-1/docker-compose-adminer/constants.py deleted file mode 100644 index cb189fe..0000000 --- a/source-code/chapter-7/exercise-1/docker-compose-adminer/constants.py +++ /dev/null @@ -1,11 +0,0 @@ -__author__ = 'Sathyajith' - -import os -ERR_NO_SOURCE = 'No sources defined! Set a source using /source list, of, sub, reddits' -skip_list = [] -sources_dict = {} - -BOT_KEY = os.environ['NBT_ACCESS_TOKEN'] -API_BASE = 'https://api.telegram.org/bot' -UPDATE_PERIOD = 6 -FALSE_RESPONSE = {"ok": False} \ No newline at end of file diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/docker-compose.yml b/source-code/chapter-7/exercise-1/docker-compose-adminer/docker-compose.yml index 2c0a4e5..4fa85f5 100644 --- a/source-code/chapter-7/exercise-1/docker-compose-adminer/docker-compose.yml +++ b/source-code/chapter-7/exercise-1/docker-compose-adminer/docker-compose.yml @@ -1,23 +1,16 @@ -version: '3' -services: - app: - build: . - depends_on: - - mysql - restart: "on-failure" - volumes: - - "appdata:/apps/subredditfetcher" - mysql: - image: mysql - volumes: - - "dbdata:/var/lib/mysql" - environment: - - MYSQL_ROOT_PASSWORD=dontusethisinprod - adminer: - image: adminer - ports: - - "8080:8080" - -volumes: - dbdata: - appdata: +services: + mysql: + image: mysql + environment: + MYSQL_ROOT_PASSWORD: dontusethisinprod + ports: + - 3306:3306 + volumes: + - dbdata:/var/lib/mysql + adminer: + image: adminer + ports: + - 8080:8080 + +volumes: + dbdata: \ No newline at end of file diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/main.py b/source-code/chapter-7/exercise-1/docker-compose-adminer/main.py deleted file mode 100644 index bacc165..0000000 --- a/source-code/chapter-7/exercise-1/docker-compose-adminer/main.py +++ /dev/null @@ -1,22 +0,0 @@ -from flask import Flask -from newsbot import * -from states import States - -bot = Flask(__name__) - - -@bot.route('/index') -def index(): - return 'Thou shalt not pass!' - - -@bot.route('/telegram-update', methods=['POST']) -def telegram_update(): - handle_incoming_messages(States.last_updated_id) - - -if __name__ == '__main__': - States.last_updated_id = get_last_updated() - bot.run() - - diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/newsbot.db b/source-code/chapter-7/exercise-1/docker-compose-adminer/newsbot.db deleted file mode 100644 index 2c5e1e7..0000000 Binary files a/source-code/chapter-7/exercise-1/docker-compose-adminer/newsbot.db and /dev/null differ diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/newsbot.py b/source-code/chapter-7/exercise-1/docker-compose-adminer/newsbot.py deleted file mode 100644 index 659bc41..0000000 --- a/source-code/chapter-7/exercise-1/docker-compose-adminer/newsbot.py +++ /dev/null @@ -1,46 +0,0 @@ -from states import States, log -from telegram import handle_incoming_messages -from models import * -from time import sleep - -import sys -import pymysql - - -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= 'root', password='dontusethisinprod') - db_connection.cursor().execute('CREATE DATABASE newsbot') - db_connection.close() - db.create_tables([Source, Request, Message], True) - - try: - States.last_updated = get_last_updated() - while True: - handle_incoming_messages(States.last_updated) - except KeyboardInterrupt: - log.info('Received KeybInterrupt, exiting') diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/one_time.py b/source-code/chapter-7/exercise-1/docker-compose-adminer/one_time.py deleted file mode 100644 index f7074d9..0000000 --- a/source-code/chapter-7/exercise-1/docker-compose-adminer/one_time.py +++ /dev/null @@ -1,11 +0,0 @@ - -from models import * - - -def create_tables(): - db.connect() - db.create_tables([Source, Request, Message], True) - db.close() - -if __name__ == '__main__': - create_tables() diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/reddit.py b/source-code/chapter-7/exercise-1/docker-compose-adminer/reddit.py deleted file mode 100644 index 31f8dff..0000000 --- a/source-code/chapter-7/exercise-1/docker-compose-adminer/reddit.py +++ /dev/null @@ -1,38 +0,0 @@ -import praw -from states import log - -__author__ = 'Sathyajith' - - -def summarize(url): - log.info('Not yet implemented!') - return url - - -def get_latest_news(sub_reddits): - log.debug('Fetching news from reddit') - r = praw.Reddit(user_agent='SubReddit Newsfetcher Bot', - 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('Fetching subreddits: {0}'.format(sub_reddits)) - submissions = r.subreddit(sub_reddits).hot(limit=5) - submission_content = '' - try: - for post in submissions: - submission_content += summarize(post.title + ' - ' + post.url) + '\n\n' - except praw.errors.Forbidden: - log.debug('subreddit {0} is private'.format(sub_reddits)) - submission_content = "Sorry couldn't fetch; subreddit is private" - except praw.errors.InvalidSubreddit: - log.debug('Subreddit {} is invalid or doesn''t exist.'.format(sub_reddits)) - submission_content = "Sorry couldn't fetch; subreddit doesn't seem to exist" - return submission_content - - -def clean_up_subreddits(sub_reddits): - log.debug('Got subreddits to clean: {0}'.format(sub_reddits)) - return sub_reddits.strip().replace(" ", "").replace(',', '+') diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/requirements.txt b/source-code/chapter-7/exercise-1/docker-compose-adminer/requirements.txt deleted file mode 100644 index 8854d79..0000000 --- a/source-code/chapter-7/exercise-1/docker-compose-adminer/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -praw -peewee==2.10.2 -PyMySQL diff --git a/source-code/chapter-7/exercise-2/newsbot-compose/Dockerfile b/source-code/chapter-7/exercise-2/newsbot-compose/Dockerfile new file mode 100644 index 0000000..7d69914 --- /dev/null +++ b/source-code/chapter-7/exercise-2/newsbot-compose/Dockerfile @@ -0,0 +1,9 @@ +FROM python:3-alpine + +RUN apk add gcc musl-dev python3-dev libffi-dev openssl-dev cargo +WORKDIR /apps/subredditfetcher/ +COPY . . + +RUN pip install --upgrade pip && pip install -r requirements.txt +VOLUME ["/data"] +CMD ["python", "newsbot.py"] diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/LICENSE b/source-code/chapter-7/exercise-2/newsbot-compose/LICENSE similarity index 100% rename from source-code/chapter-7/exercise-1/docker-compose-adminer/LICENSE rename to source-code/chapter-7/exercise-2/newsbot-compose/LICENSE diff --git a/source-code/chapter-7/exercise-2/newsbot-compose/constants.py b/source-code/chapter-7/exercise-2/newsbot-compose/constants.py new file mode 100644 index 0000000..092cde6 --- /dev/null +++ b/source-code/chapter-7/exercise-2/newsbot-compose/constants.py @@ -0,0 +1,15 @@ +__author__ = 'Sathyajith' + +from os import environ +from sys import exit +ERR_NO_SOURCE = 'No sources defined! Set a source using /source list, of, sub, reddits' +skip_list = [] +sources_dict = {} +UPDATE_PERIOD = 1 +FALSE_RESPONSE = {"ok": False} + +BOT_KEY = environ.get('NBT_ACCESS_TOKEN') +if not BOT_KEY: + print("Telegram access token not set, exiting.") + exit(1) +API_BASE = f'https://api.telegram.org/bot{BOT_KEY}' \ No newline at end of file diff --git a/source-code/chapter-7/exercise-2/newsbot-compose/docker-compose.adminer.yml b/source-code/chapter-7/exercise-2/newsbot-compose/docker-compose.adminer.yml new file mode 100644 index 0000000..8132d37 --- /dev/null +++ b/source-code/chapter-7/exercise-2/newsbot-compose/docker-compose.adminer.yml @@ -0,0 +1,34 @@ +services: + newsbot: + build: . + depends_on: + - mysql + restart: "on-failure" + environment: + NBT_ACCESS_TOKEN: ${NBT_ACCESS_TOKEN} + networks: + - newsbot + + mysql: + image: mysql + volumes: + - newsbot-db:/var/lib/mysql + environment: + MYSQL_ROOT_PASSWORD: dontusethisinprod + + networks: + - newsbot + + adminer: + image: adminer + ports: + - 8080:8080 + networks: + - newsbot + +volumes: + newsbot-db: + + +networks: + newsbot: \ No newline at end of file diff --git a/source-code/chapter-7/exercise-2/newsbot-compose/docker-compose.yml b/source-code/chapter-7/exercise-2/newsbot-compose/docker-compose.yml new file mode 100644 index 0000000..20561bc --- /dev/null +++ b/source-code/chapter-7/exercise-2/newsbot-compose/docker-compose.yml @@ -0,0 +1,25 @@ +services: + newsbot: + build: . + depends_on: + - mysql + restart: "on-failure" + environment: + NBT_ACCESS_TOKEN: ${NBT_ACCESS_TOKEN} + networks: + - newsbot + + mysql: + image: mysql + volumes: + - newsbot-db:/var/lib/mysql + environment: + MYSQL_ROOT_PASSWORD: dontusethisinprod + networks: + - newsbot + +volumes: + newsbot-db: + +networks: + newsbot: \ No newline at end of file diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/last_updated.txt b/source-code/chapter-7/exercise-2/newsbot-compose/last_updated.txt similarity index 100% rename from source-code/chapter-7/exercise-1/docker-compose-adminer/last_updated.txt rename to source-code/chapter-7/exercise-2/newsbot-compose/last_updated.txt diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/models.py b/source-code/chapter-7/exercise-2/newsbot-compose/models.py similarity index 85% rename from source-code/chapter-7/exercise-1/docker-compose-adminer/models.py rename to source-code/chapter-7/exercise-2/newsbot-compose/models.py index a7834ba..ec73558 100644 --- a/source-code/chapter-7/exercise-1/docker-compose-adminer/models.py +++ b/source-code/chapter-7/exercise-2/newsbot-compose/models.py @@ -1,6 +1,8 @@ -from peewee import * -# db = SqliteDatabase('newsbot.db') +from peewee import Model, PrimaryKeyField, IntegerField, CharField, DateTimeField, MySQLDatabase + + db = MySQLDatabase(host="mysql", port=3306, user="root", password="dontusethisinprod", database="newsbot") + class BaseModel(Model): class Meta: database = db diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/newsbot.py b/source-code/chapter-7/exercise-2/newsbot-compose/newsbot.py similarity index 69% rename from source-code/chapter-7/exercise-2/subreddit-fetcher-compose/newsbot.py rename to source-code/chapter-7/exercise-2/newsbot-compose/newsbot.py index 659bc41..020aba5 100644 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/newsbot.py +++ b/source-code/chapter-7/exercise-2/newsbot-compose/newsbot.py @@ -2,8 +2,7 @@ from telegram import handle_incoming_messages from models import * from time import sleep - -import sys +from peewee import OperationalError import pymysql @@ -28,14 +27,12 @@ def get_last_updated(): 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= 'root', password='dontusethisinprod') - db_connection.cursor().execute('CREATE DATABASE newsbot') - db_connection.close() + except OperationalError as e: + error_code, message = e.args[0], e.args[1] + if error_code == 1049: + db_connection = pymysql.connect(host='mysql', user= 'root', password='dontusethisinprod') + db_connection.cursor().execute('CREATE DATABASE newsbot') + db_connection.close() db.create_tables([Source, Request, Message], True) try: diff --git a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/reddit.py b/source-code/chapter-7/exercise-2/newsbot-compose/reddit.py similarity index 63% rename from source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/reddit.py rename to source-code/chapter-7/exercise-2/newsbot-compose/reddit.py index 31f8dff..3f6d4b1 100644 --- a/source-code/chapter-6/exercise-1/docker-subreddit-fetcher-network/reddit.py +++ b/source-code/chapter-7/exercise-2/newsbot-compose/reddit.py @@ -4,35 +4,30 @@ __author__ = 'Sathyajith' -def summarize(url): - log.info('Not yet implemented!') - return url - - def get_latest_news(sub_reddits): log.debug('Fetching news from reddit') - r = praw.Reddit(user_agent='SubReddit Newsfetcher Bot', + 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('Fetching subreddits: {0}'.format(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 += summarize(post.title + ' - ' + post.url) + '\n\n' + submission_content += post.title + ' - ' + post.url + '\n\n' except praw.errors.Forbidden: - log.debug('subreddit {0} is private'.format(sub_reddits)) + log.debug(f'subreddit {sub_reddits} is private') submission_content = "Sorry couldn't fetch; subreddit is private" except praw.errors.InvalidSubreddit: - log.debug('Subreddit {} is invalid or doesn''t exist.'.format(sub_reddits)) + 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 clean_up_subreddits(sub_reddits): - log.debug('Got subreddits to clean: {0}'.format(sub_reddits)) + log.debug(f'Got subreddits to clean: {sub_reddits}') return sub_reddits.strip().replace(" ", "").replace(',', '+') diff --git a/source-code/chapter-7/exercise-2/newsbot-compose/requirements.txt b/source-code/chapter-7/exercise-2/newsbot-compose/requirements.txt new file mode 100644 index 0000000..0d19ff9 --- /dev/null +++ b/source-code/chapter-7/exercise-2/newsbot-compose/requirements.txt @@ -0,0 +1,4 @@ +peewee==2.10.2 +praw==7.4.0 +PyMySQL +cryptography \ No newline at end of file diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/states.py b/source-code/chapter-7/exercise-2/newsbot-compose/states.py similarity index 100% rename from source-code/chapter-7/exercise-1/docker-compose-adminer/states.py rename to source-code/chapter-7/exercise-2/newsbot-compose/states.py diff --git a/source-code/chapter-7/exercise-1/docker-compose-adminer/telegram.py b/source-code/chapter-7/exercise-2/newsbot-compose/telegram.py similarity index 66% rename from source-code/chapter-7/exercise-1/docker-compose-adminer/telegram.py rename to source-code/chapter-7/exercise-2/newsbot-compose/telegram.py index 5e150c7..d852d72 100644 --- a/source-code/chapter-7/exercise-1/docker-compose-adminer/telegram.py +++ b/source-code/chapter-7/exercise-2/newsbot-compose/telegram.py @@ -6,15 +6,16 @@ from constants import * from reddit import get_latest_news from models import * +import peewee __author__ = 'Sathyajith' db = MySQLDatabase(host="mysql", port=3306, user="root", password="dontusethisinprod", database="newsbot") def get_updates(last_updated): - log.debug('Checking for requests, last updated passed is: {}'.format(last_updated)) + log.debug('Checking for requests, last updated passed is: {last_updated}') sleep(UPDATE_PERIOD) - response = requests.get(API_BASE + BOT_KEY + '/getUpdates', params={'offset': last_updated+1}) + 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 @@ -25,14 +26,14 @@ def get_updates(last_updated): except ValueError: sleep(UPDATE_PERIOD*20) get_updates(last_updated) - log.info('received response: {}'.format(json_response)) + log.info(f"received response: {json_response}") return json_response def post_message(chat_id, text): - log.info('posting {} to {}'.format(text, chat_id)) + log.debug(f"posting {text} to {chat_id}") payload = {'chat_id': chat_id, 'text': text} - requests.post(API_BASE + BOT_KEY + '/sendMessage', data=payload) + requests.post(f"{API_BASE}/sendMessage", data=payload) def handle_incoming_messages(last_updated): @@ -40,7 +41,10 @@ def handle_incoming_messages(last_updated): split_chat_text = [] if r['ok']: for req in r['result']: - chat_sender_id = req['message']['chat']['id'] + 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() @@ -48,30 +52,33 @@ def handle_incoming_messages(last_updated): chat_text = '' split_chat_text.append(chat_text) log.debug('Looks like no chat text was detected... moving on') - try: + + if 'message' in req: person_id = req['message']['from']['id'] - except KeyError: - pass + else: + person_id = req['edited_message']['from']['id'] - log.info('Chat text received: {0}'.format(chat_text)) + 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('Sources set for {0} to {1}'.format(person_id, sources_dict[person_id])) - try: - sources = Source.create(person_id = person_id, fetch_from = sources_dict[person_id]) - except IntegrityError: - sources = Source.get(person_id = person_id) - sources.fetch_from = sources_dict[person_id] - sources.save() - log.info(sources.person_id) + 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('Added {0} to skip list'.format(chat_sender_id)) + 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.") @@ -79,19 +86,17 @@ def handle_incoming_messages(last_updated): 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. + 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: + except peewee.DoesNotExist: post_message(person_id, ERR_NO_SOURCE) last_updated = req['update_id'] @@ -99,5 +104,5 @@ def handle_incoming_messages(last_updated): f.write(str(last_updated)) States.last_updated = last_updated log.debug( - 'Updated last_updated to {0}'.format(last_updated)) + f'Updated last_updated to {last_updated}') f.close() diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/Dockerfile b/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/Dockerfile deleted file mode 100644 index 29069bc..0000000 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -FROM python:3-alpine - -RUN apk add gcc musl-dev python3-dev libffi-dev openssl-dev -COPY * /apps/subredditfetcher/ -WORKDIR /apps/subredditfetcher/ - -VOLUME [ "/apps/subredditfetcher" ] -RUN ["pip", "install", "-r", "requirements.txt"] -# RUN ["python", "one_time.py"] - -ENV NBT_ACCESS_TOKEN="495637361:AAHIhiDTX1UeX17KJy0-FsMZEqEtCFYfcP8" - -CMD ["python", "newsbot.py"] diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/LICENSE b/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/LICENSE deleted file mode 100644 index 210b49e..0000000 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Sathya - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/constants.py b/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/constants.py deleted file mode 100644 index cb189fe..0000000 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/constants.py +++ /dev/null @@ -1,11 +0,0 @@ -__author__ = 'Sathyajith' - -import os -ERR_NO_SOURCE = 'No sources defined! Set a source using /source list, of, sub, reddits' -skip_list = [] -sources_dict = {} - -BOT_KEY = os.environ['NBT_ACCESS_TOKEN'] -API_BASE = 'https://api.telegram.org/bot' -UPDATE_PERIOD = 6 -FALSE_RESPONSE = {"ok": False} \ No newline at end of file diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/docker-compose.yml b/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/docker-compose.yml deleted file mode 100644 index 2c0a4e5..0000000 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/docker-compose.yml +++ /dev/null @@ -1,23 +0,0 @@ -version: '3' -services: - app: - build: . - depends_on: - - mysql - restart: "on-failure" - volumes: - - "appdata:/apps/subredditfetcher" - mysql: - image: mysql - volumes: - - "dbdata:/var/lib/mysql" - environment: - - MYSQL_ROOT_PASSWORD=dontusethisinprod - adminer: - image: adminer - ports: - - "8080:8080" - -volumes: - dbdata: - appdata: diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/last_updated.txt b/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/last_updated.txt deleted file mode 100644 index 97702fb..0000000 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/last_updated.txt +++ /dev/null @@ -1 +0,0 @@ -865610176 \ No newline at end of file diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/main.py b/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/main.py deleted file mode 100644 index bacc165..0000000 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/main.py +++ /dev/null @@ -1,22 +0,0 @@ -from flask import Flask -from newsbot import * -from states import States - -bot = Flask(__name__) - - -@bot.route('/index') -def index(): - return 'Thou shalt not pass!' - - -@bot.route('/telegram-update', methods=['POST']) -def telegram_update(): - handle_incoming_messages(States.last_updated_id) - - -if __name__ == '__main__': - States.last_updated_id = get_last_updated() - bot.run() - - diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/models.py b/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/models.py deleted file mode 100644 index a7834ba..0000000 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/models.py +++ /dev/null @@ -1,24 +0,0 @@ -from peewee import * -# db = SqliteDatabase('newsbot.db') -db = MySQLDatabase(host="mysql", port=3306, user="root", password="dontusethisinprod", database="newsbot") -class BaseModel(Model): - class Meta: - database = db - -class Source(BaseModel): - person_id = PrimaryKeyField() - fetch_from = CharField() - - -class Request(BaseModel): - id = PrimaryKeyField() - from_id = IntegerField(index=True) - request_text = CharField() - received_time = DateTimeField() - - -class Message(BaseModel): - id = PrimaryKeyField() - sent_to_id = IntegerField(index=True) - sent_message = CharField() - sent_time = DateTimeField() diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/newsbot.db b/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/newsbot.db deleted file mode 100644 index 2c5e1e7..0000000 Binary files a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/newsbot.db and /dev/null differ diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/one_time.py b/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/one_time.py deleted file mode 100644 index f7074d9..0000000 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/one_time.py +++ /dev/null @@ -1,11 +0,0 @@ - -from models import * - - -def create_tables(): - db.connect() - db.create_tables([Source, Request, Message], True) - db.close() - -if __name__ == '__main__': - create_tables() diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/requirements.txt b/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/requirements.txt deleted file mode 100644 index 8854d79..0000000 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -praw -peewee==2.10.2 -PyMySQL diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/states.py b/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/states.py deleted file mode 100644 index c848ff4..0000000 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/states.py +++ /dev/null @@ -1,10 +0,0 @@ -import logging - - -class States(object): - last_updated_id = '' - -logging.basicConfig(level=logging.INFO, - format='%(levelname)s: %(asctime)s - %(funcName)s - %(message)s') - -log = logging.getLogger('nbt') \ No newline at end of file diff --git a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/telegram.py b/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/telegram.py deleted file mode 100644 index 5e150c7..0000000 --- a/source-code/chapter-7/exercise-2/subreddit-fetcher-compose/telegram.py +++ /dev/null @@ -1,103 +0,0 @@ -import re -from time import sleep -import requests - -from states import States, log -from constants import * -from reddit import get_latest_news -from models import * - -__author__ = 'Sathyajith' - -db = MySQLDatabase(host="mysql", port=3306, user="root", password="dontusethisinprod", database="newsbot") - -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 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) - - -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.info('Sources set for {0} to {1}'.format(person_id, sources_dict[person_id])) - try: - sources = Source.create(person_id = person_id, fetch_from = sources_dict[person_id]) - except IntegrityError: - sources = Source.get(person_id = person_id) - sources.fetch_from = sources_dict[person_id] - sources.save() - log.info(sources.person_id) - 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 = Source.get(person_id = person_id).fetch_from.strip() - summarized_news = get_latest_news(sub_reddits) - post_message(person_id, summarized_news) - except: - 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( - 'Updated last_updated to {0}'.format(last_updated)) - f.close()