From 37931f892c7d095d0639c0b32404e036a907c30a Mon Sep 17 00:00:00 2001 From: "Saurabh S. Chaturvedi" Date: Fri, 27 Oct 2017 22:05:08 +0530 Subject: [PATCH 1/4] Python email CLI --- Awesome-Scripts/myMail_client.py | 112 +++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 Awesome-Scripts/myMail_client.py diff --git a/Awesome-Scripts/myMail_client.py b/Awesome-Scripts/myMail_client.py new file mode 100644 index 0000000..6130196 --- /dev/null +++ b/Awesome-Scripts/myMail_client.py @@ -0,0 +1,112 @@ +#!/usr/bin/env python3 +# Requires a secret.pyc file containing email credentials for running +""" +Manage your gmail right from your inbox! +Ensure that you have a secret.pyc file for your credentials, with format: +### +who = "your_username@gmail.com" +PASSWD = "your gmail password" +### +You might need to enable access to less secure apps in your gmail settings. +""" + +from imaplib import IMAP4_SSL +from smtplib import SMTP_SSL, SMTPAuthenticationError +from poplib import POP3_SSL, error_proto +import pydoc +from secret import * # Gets credentials for gmail account. +from socket import gaierror +import subprocess +from time import sleep + +SMTPSVR = 'smtp.gmail.com' +IMAPSVR = 'imap.gmail.com' +who = MAILBOX + '@gmail.com' +def send_msg(): + with open('email', 'w') as msg: + msg.write('From: YOUR_NAME_HERE <%s>\n' % who) + msg.write('To: RECIPIENTS_HERE\n') + msg.write('Subject: YOUR_SUBJECT_HERE\n\n') + subprocess.call(['nano', 'email']) + + with open('email', 'rb') as msg: + body = msg.read().decode('unicode_escape') # INCLUDES HEADERS + + body_list = body.split('\n') + breaker = body_list.index('') + origHeaders = body_list[:breaker] # List + recipients = origHeaders[1].split(', ') + origBody = '\n'.join(body_list[breaker+1:]) + try: + sendSvr = SMTP_SSL(SMTPSVR, 465) + except gaierror: + print("Can't connect to %s." % SMTPSVR) + exit() + sendSvr.ehlo() + #sendSvr.starttls() + try: + sendSvr.login(who, PASSWD) + except SMTPAuthenticationError: + print("Invalid SMTP credentials.") + exit() + errs = sendSvr.sendmail(who, recipients, body) + sendSvr.quit() + assert len(errs) == 0, errs + print("Email sent!") + +wanna_mail = input("Welcome to your email client. Would you like to compose an email? (Y/N) ") +if wanna_mail == 'Y': + send_msg() +else: + print("Alright. Now your inbox will be displayed.") + # IMAP stuff below. + try: + recvSvr = IMAP4_SSL(IMAPSVR, 993) + except gaierror: + print("Can't connect to %s." % IMAPSVR) + exit() + try: + recvSvr.login(who, PASSWD) + except Exception: + print("Can't login. Check your credentials and try again.") + exit() + rsp, msgs = recvSvr.select('INBOX', True) + length = input("How many latest email would you like to be displayed? ") + low = int(msgs[0]) - int(length) + if low <= 0: + low = 1 + #try: + rsp, data = recvSvr.fetch("%s:%s" % (low, int(msgs[0])), '(BODY[HEADER])') + #except Exception: + # print("Can't fetch email.") + # exit() + titles = [] + for item in data: + if isinstance(item, tuple): + mid = item[0].decode('unicode_escape').split()[0] + for line in item[1].decode('unicode_escape').split('\r\n'): + if line.startswith('Subject:'): + sub = line + break + titles.append(mid + ' - ' + sub) + + string = '\n'.join(titles[::-1]) + string = 'Use message id to access a specific email.\n\n' + string + print(string) + while 1: + mid = input("Enter the mid of the message you want to read, or skip to quit: ") + if not mid: + break + + rsp, data = recvSvr.fetch(mid, '(RFC822)') + stuff = data[0][1].decode('unicode_escape').split('\r\n') + for i in range(len(stuff)): + if stuff[i].startswith('From:'): + break + headers = stuff[i:i+3] + breaker = stuff.index('') + body = stuff[breaker:] #includes the empty string + msg_to_be_displayed = '\n'.join(headers + body) + pydoc.pager(msg_to_be_displayed) + +print("Thanks for using the client. Exit done.") From 506cbf65d72fcc4868eccfb8cbe26521e970a305 Mon Sep 17 00:00:00 2001 From: "Saurabh S. Chaturvedi" Date: Fri, 27 Oct 2017 22:07:03 +0530 Subject: [PATCH 2/4] Fix typo --- Awesome-Scripts/myMail_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Awesome-Scripts/myMail_client.py b/Awesome-Scripts/myMail_client.py index 6130196..1f5fef8 100644 --- a/Awesome-Scripts/myMail_client.py +++ b/Awesome-Scripts/myMail_client.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # Requires a secret.pyc file containing email credentials for running """ -Manage your gmail right from your inbox! +Manage your gmail right from your terminal! Ensure that you have a secret.pyc file for your credentials, with format: ### who = "your_username@gmail.com" From 44d6ac49283a7c7e30d68552219c18756e55c9e7 Mon Sep 17 00:00:00 2001 From: "Saurabh S. Chaturvedi" Date: Fri, 27 Oct 2017 22:13:38 +0530 Subject: [PATCH 3/4] Add better exception handling --- Awesome-Scripts/myMail_client.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Awesome-Scripts/myMail_client.py b/Awesome-Scripts/myMail_client.py index 1f5fef8..32bd5f4 100644 --- a/Awesome-Scripts/myMail_client.py +++ b/Awesome-Scripts/myMail_client.py @@ -4,7 +4,7 @@ Manage your gmail right from your terminal! Ensure that you have a secret.pyc file for your credentials, with format: ### -who = "your_username@gmail.com" +MAILBOX = "your_gmail_username" PASSWD = "your gmail password" ### You might need to enable access to less secure apps in your gmail settings. @@ -14,7 +14,13 @@ from smtplib import SMTP_SSL, SMTPAuthenticationError from poplib import POP3_SSL, error_proto import pydoc -from secret import * # Gets credentials for gmail account. + +try: + from secret import * # Gets credentials for gmail account. +except ImportError: + print("Please create a secret.pyc file for your credentials.") + exit() + from socket import gaierror import subprocess from time import sleep From 8de831c4feeba55aeadf7c77ffcf30e23bf763a5 Mon Sep 17 00:00:00 2001 From: "Saurabh S. Chaturvedi" Date: Sat, 28 Oct 2017 11:05:28 +0530 Subject: [PATCH 4/4] Fix silly issues in some scripts and make PEP8-compliant --- .../{Rolling a dice => dice_roll.py} | 0 Awesome-Scripts/get_xkcd_comic.py | 15 +++++--- Awesome-Scripts/hackernews.py | 34 +++++++++---------- 3 files changed, 27 insertions(+), 22 deletions(-) rename Awesome-Scripts/{Rolling a dice => dice_roll.py} (100%) diff --git a/Awesome-Scripts/Rolling a dice b/Awesome-Scripts/dice_roll.py similarity index 100% rename from Awesome-Scripts/Rolling a dice rename to Awesome-Scripts/dice_roll.py diff --git a/Awesome-Scripts/get_xkcd_comic.py b/Awesome-Scripts/get_xkcd_comic.py index 83c42e1..1f9faf2 100644 --- a/Awesome-Scripts/get_xkcd_comic.py +++ b/Awesome-Scripts/get_xkcd_comic.py @@ -1,24 +1,29 @@ #!/usr/bin/python +"""Scrapes xkcd comics and saves their images.""" +import io import sys import requests from bs4 import BeautifulSoup -import io from PIL import Image - def crawler(max_pages): + """Main function for this script; crawls xkcd.com and fetches the images.""" + page = 1 next_url = '' while page <= max_pages: url = 'https://xkcd.com' + next_url soup = BeautifulSoup(requests.get(url).text, "lxml") - next_url = soup.findAll('a', {'rel': 'prev', 'accesskey': 'p'})[0].get('href') + next_url = soup.findAll( + 'a', + {'rel': 'prev', 'accesskey': 'p'} + )[0].get('href') image_source = str(soup.findChild('div', {'id': 'comic'})) soup2 = BeautifulSoup(image_source, "lxml") image_url = 'https:' + soup2.findAll('img')[0].get('src') - im = requests.get(image_url) - image = Image.open(io.BytesIO(im.content)) + img = requests.get(image_url) + image = Image.open(io.BytesIO(img.content)) image.save(sys.argv[2]+image_url.split('/')[4]) page += 1 diff --git a/Awesome-Scripts/hackernews.py b/Awesome-Scripts/hackernews.py index 5f1c8d9..df5bc75 100755 --- a/Awesome-Scripts/hackernews.py +++ b/Awesome-Scripts/hackernews.py @@ -1,30 +1,30 @@ #!/usr/bin/env python +"""Script to scrape Hackernews and retrieve top 10 links.""" from __future__ import print_function import requests from bs4 import BeautifulSoup -# get the front page from hacker news +# Get the front page from hacker news. response = requests.request("GET", "https://news.ycombinator.com/") - -# convert the response to soup +# Convert the response to soup. soup = BeautifulSoup(response.text, "lxml") - -# count the things that get processed +# Count the things that get processed. count = 0 -# process all of the things! :D -for things in soup("tr", { "class" : "athing" }): - # get at the rank of each thing - for rank in things("span", { "class" : "rank" }): - print( rank.text, end=' ' ) +# Process all of the things! :D +for things in soup("tr", {"class": "athing"}): + # Get at the rank of each thing. + for rank in things("span", {"class": "rank"}): + print(rank.text, end=' ') - # get the title of each thing - for title in things("a", { "class" : "storylink" }): - print( title.text ) - print( title['href'] ) - print( " " ) + # Get the title of each thing. + for title in things("a", {"class": "storylink"}): + print(title.text) + print(title['href']) + print() - count = count + 1 + count += 1 - if count == 10: break + if count == 10: + break