Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
**/*.pyc
**/venv/*
**/*venv/*
**/.idea/*
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
FROM python:3-alpine

LABEL author="sathyabhat"
LABEL description="Dockerfile for Python script which prints Hello, Name"

COPY hello-world.py /app/
ENV NAME=Sathya
ENV NAME=Readers
CMD python3 /app/hello-world.py

Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
#!/usr/bin/env python3

from os import getenv

if getenv('NAME') is None:
name = 'World'
else:
name = getenv('NAME')

print("Hello, {}!".format(name))
print(f"Hello, {name}!")
5 changes: 4 additions & 1 deletion source-code/chapter-4/exercise-2/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
### README

This exercise contains the source code for the second exercise of chapter 4. In this exercise, you will build two Docker images, the first one using a standard build process using python:3 as the base image.
This exercise contains the source code for the second exercise of chapter 4. In this exercise, you will build two Docker images

- Using the standard build process using python:3 as the base image (present in [docker-multi-stage/standard-build](docker-multi-stage/standard-build) directory.
- Using Multi-Stage builds (present [docker-multi-stage/multistage-build](docker-multi-stage/multistage-build) directory.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
praw
praw==3.6.0
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
FROM python:3
COPY requirements.txt .
RUN pip install -r requirements.txt

Original file line number Diff line number Diff line change
@@ -1 +1 @@
praw
praw==3.6.0
19 changes: 18 additions & 1 deletion source-code/chapter-4/exercise-3/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
### README

This exercise contains the source code for the third exercise of chapter 4. In this exercise, we’ll try writing the Dockerfile for the project.
This exercise contains the source code for the third exercise of chapter 4. In this exercise, we compose a Dockerfile for Newsbot and then use the Dockerfile to build a Docker image and run the container.


### Building the Docker image

Build the image using the below command

```
docker build -t sathyabhat/newsbot
```

Run the container using

```
docker run -e NBT_ACCESS_TOKEN=<token> sathyabhat/newsbot
```

Replace `<token>` with the Telegram API Token that was generated.
22 changes: 0 additions & 22 deletions source-code/chapter-4/exercise-3/docker-subreddit-fetcher/main.py

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
FROM python:3-alpine

COPY * /apps/subredditfetcher/
WORKDIR /apps/subredditfetcher/
COPY . .
RUN ["pip", "install", "-r", "requirements.txt"]

ENV NBT_ACCESS_TOKEN="495637361:AAHIhiDTX1UeX17KJy0-FsMZEqEtCFYfcP8"

CMD ["python", "newsbot.py"]
Original file line number Diff line number Diff line change
@@ -1,13 +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')
REDDIT_CLIENT_ID = environ.get('REDDIT_CLIENT_ID')
REDDIT_CLIENT_SECRET = environ.get('REDDIT_CLIENT_SECRET')
API_BASE = 'https://api.telegram.org/bot'
UPDATE_PERIOD = 6
FALSE_RESPONSE = {"ok": False}
if not BOT_KEY:
print("Telegram access token not set, exiting.")
exit(1)
API_BASE = f'https://api.telegram.org/bot{BOT_KEY}'
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ def get_last_updated():
f.close()
except FileNotFoundError:
last_updated = 0
log.debug('Last updated id: {0}'.format(last_updated))
log.debug(f"Last updated id: {last_updated}")
return last_updated

if __name__ == '__main__':

try:
log.debug('Starting up')
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')
log.info("Received KeybInterrupt, exiting")
32 changes: 32 additions & 0 deletions source-code/chapter-4/exercise-3/newsbot/reddit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import praw
from states import log

__author__ = 'Sathyajith'


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 clean_up_subreddits(sub_reddits):
log.debug('Got subreddits to clean: {0}'.format(sub_reddits))
return sub_reddits.strip().replace(" ", "").replace(',', '+')
2 changes: 2 additions & 0 deletions source-code/chapter-4/exercise-3/newsbot/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
praw==3.6.0
requests==2.20.0
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@


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
Expand All @@ -23,46 +23,49 @@ 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):
r = get_updates(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()
except KeyError:
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.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)))
post_message(person_id, f"Sources set as {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.")

Expand All @@ -89,5 +92,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()