From 30697b3a904a9c518f3b025941326cc5b8852ffb Mon Sep 17 00:00:00 2001 From: aakash30jan Date: Thu, 17 Sep 2020 18:05:56 +0200 Subject: [PATCH] Released after minor changes - v20.9a2 --- README.md | 117 +++++++++++++++++++- pydispo/__init__.py | 14 +++ pydispo/pydispo.py | 252 +++++++++++++++++++++++++++++++++++++++++++- setup.cfg | 5 + setup.py | 29 +++++ 5 files changed, 414 insertions(+), 3 deletions(-) create mode 100644 pydispo/__init__.py create mode 100644 setup.cfg create mode 100644 setup.py diff --git a/README.md b/README.md index 82acf9f..244491f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,115 @@ -# pydispo -A Disposable Mailbox Powered by Pure-Python + +

+pydispo +

+

A Disposable Mailbox Powered by Pure-Python


+ +![language](https://img.shields.io/github/languages/top/aakash30jan/pydispo) +![release](https://img.shields.io/github/v/release/aakash30jan/pydispo) +![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg) + +`pydispo` is a pure-pythonic way of managing disposable mailbox that allows users to create several disposable email addresses and receive emails on those. It can be directly used from the command line or imported as a python module for advanced usage. `pydispo` is platform-independent and uses python standard libraries, so if you have python installed you don't need to satisfy any additional dependencies. + +Optionally, `pydispo` can fetch attached files and there's also a provision to save emails as HTML. By default, the emails are shown as text, optionally any standard web browser can be used to view the emails. Currently, it uses 1secmail API to receive emails, and soon it would support some other APIs. If you want a bash-like implementation with some dependencies, please check the [tmpmail](https://github.com/sdushantha/tmpmail) script. + + +## Installation +### Standalone +Download the `pydispo` standalone script and make it executable +```bash +$ curl -L "https://git.io/pydispo" > pydispo && chmod +x pydispo +``` + +### PyPI +`pydispo` is also available as a python package from [https://pypi.org/project/pydispo/](https://pypi.org/project/pydispo/). +Download and install it as a system or environment package with pip +```bash +$ pip install pydispo +``` + +### Source +Alternatively, the `pydispo` package source tarball can be downloaded from [here](https://github.com/aakash30jan/pydispo/blob/master/pydispo-20.9a1.tar.gz?raw=true) + +## Usage +```console +Usage: pydispo [-h] [-a] [-r] [-g] [-s] [-b BROWSER] [-e EMAIL] [id] + +Positional arguments: + id Check email with message ID (default shows mailbox) +Optional arguments: + -h, --help show this help message and exit + -a, --attached Download all attached files in the email + -r, --recent Check the recent email + -g, --generate Generate a new email address + -s, --save Save email in an HTML file + -b, --browser Browser to check the email in HTML + -e, --email Check mailbox of a particular email + +``` + +### Examples +Generate a disposable email address +```console +$ pydispo -g +Generated: ma4x8pgolq@1secmail.org +``` + +Check the mailbox +```console +$ pydispo +Mailbox: ma4x8pgolq@1secmail.org Mails in Inbox: 1 +Message ID Sender Subject Date +84784986 yourfriend@mail.com About pydispo 2020-09-16 17:34:13 +``` + +Check a particular email +```console +$ pydispo 84784986 +ID: 84784986 +To: ma4x8pgolq@1secmail.org +From: yourfriend@mail.com +Date: 2020-09-16 17:34:13 +Subject: About pydispo +Attachments: ['pydispo_leaflet.pdf (application/pdf) 0.2 MB '] +-------------------- +Check this out +Cheers. +-------------------- +``` + +Check the recent email +```console +$ pydispo -r +``` + +Check a particular email, get attached files, and save email as HTML +```console +$ pydispo -a -s 84784986 +``` + +Check a particular email in a browser of choice +```console +$ pydispo 84784986 -b elinks +``` + +Check mailbox of another disposable email +```console +$ pydispo -e g6cqog5utd@1secmail.net +``` + +## Issues: +Problems? Please raise an issue at "https://github.com/aakash30jan/pydispo/issues" and I will get back to you soon. + +## Why disposable emails? +To avoid SPAM. To protect your PRIVACY. Lots of web pages, blogs, forums and services would ask you to register or provide email addresses to read comments, download content, or register account or profile. And a lot of them will use your private email address to send you spam. Disposable emails are perfect for any transaction where you want to improve your online privacy, like when you trade cryptocurrencies. These are also used by developers and testers for several time-saving reasons. +Read More : [How-To Geek](https://www.howtogeek.com/tips/protect-yourself-from-spam-with-free-disposable-email-addresses/) , [WIRED](https://www.wired.com/story/avoid-spam-disposable-email-burner-phone-number/) + +## Credits +`pydispo` is a dependency-free, platform-independent replication of Siddharth's [tmpmail](https://github.com/sdushantha/tmpmail) bash-script and follows a usage pattern similar to it. + + +## License +This work is licensed under a GNU General Public License Version 3 . [![Open Source Love svg3](https://badges.frapsoft.com/os/v3/open-source.svg?v=103)](https://github.com/ellerbrock/open-source-badges/) + + + diff --git a/pydispo/__init__.py b/pydispo/__init__.py new file mode 100644 index 0000000..bc45b80 --- /dev/null +++ b/pydispo/__init__.py @@ -0,0 +1,14 @@ + +from .pydispo import * + +""" +Examples: + +from pydispo import * +print(pydispo_emailaddr_cache) + +OR + +import pydispo +print(pydispo.pydispo_emailaddr_cache) +""" diff --git a/pydispo/pydispo.py b/pydispo/pydispo.py index b916cee..dd9d10e 100644 --- a/pydispo/pydispo.py +++ b/pydispo/pydispo.py @@ -1 +1,251 @@ -STANDALONE +#!/usr/bin/env python3 +""" +pydispo - Disposable Mailbox Powered by Pure-Python +By Aakash Patil + +url="https://github.com/aakash30jan/pydispo" +version="20.9a2" +license="GNU General Public License, version 3" +""" + +from __future__ import print_function +import sys +import argparse +import os +import random +import string +import requests +import webbrowser + + +#config +cache_tag = 'TEMP' #Options: CWD, + +#os check +if os.name == 'nt': + temp_dir = r'C:\\Users\\aakash.patil\\AppData\\Local\\Temp\\' +else: + temp_dir = "/tmp/" + +#cache location +if cache_tag == 'TEMP': + pydispo_workdir = temp_dir+'pydispo' +elif cache_tag == 'CWD': + pydispo_workdir = os.getcwd() +else: + #Get from user pydispo_workdir = + pydispo_workdir = os.getcwd() + +pydispo_emailaddr_cache = pydispo_workdir+"/dispomail.addr" +pydispo_emailhtml_cache = pydispo_workdir+"/dispomail.html" + +if not pydispo_workdir == os.getcwd(): + if not os.path.exists(pydispo_workdir): + os.mkdir(pydispo_workdir) + +def generate_email_address(size=10,storeInFile='email_address',mode='w'): + tld_list=['com', 'net', 'org'] + chars=string.ascii_lowercase + string.digits + user = ''.join(random.SystemRandom().choice(chars) for _ in range(size)) + email_addr = user+'@1secmail.'+ random.choice(tld_list) + fop = open(storeInFile,mode) + if mode == 'a': + fop.write(email_addr+'\n') + else: + fop.write(email_addr) + fop.close() + print("Generated: ", email_addr) + return email_addr; + #FUTURE: HUMAN_NOM_PRENOM@platforme.CHOICE + +def get_email_address(checkFile=pydispo_emailaddr_cache, getNew=False): + if getNew: + email_addr = generate_email_address(size=10,storeInFile=checkFile) + return email_addr ; + if os.path.exists(checkFile): + fop = open(checkFile).readlines() + #print("Found email address: ", fop) + email_addr = fop[0] + else: + print("No email address found, generating new") + email_addr = generate_email_address(size=10,storeInFile=checkFile) + return email_addr ; + #FUTURE: encrypted history obj + +def check_mailbox(email_addr,showInbox=True,showRecent=True): + login_id = email_addr[:email_addr.find('@')] + login_domain = email_addr[email_addr.find('@')+1:] + http_get_url = "https://www.1secmail.com/api/v1/?action=getMessages&login="+login_id+"&domain="+login_domain + response = requests.get(http_get_url) + + if not response.status_code == 200: + print("Invalid server response code ", response.status_code) + return ; + + response = response.json() + num_mails = len(response) + if num_mails == 0: + print("Mailbox: ", email_addr, " Mails in Inbox:",num_mails ) + print("Empty Inbox") + return ; + + inboxmail_id_list = [] + print("#"*25) + print("Mailbox: ", email_addr, " Mails in Inbox:",num_mails ) + for nm in range(num_mails): + if showInbox: + if nm == 0: + print('Message ID' ,'\t', 'Sender' ,'\t \t', 'Subject', '\t' , 'Date') + print(response[nm]['id'] ,'\t', response[nm]['from'] ,'\t', response[nm]['subject'], '\t' , response[nm]['date'] ) + inboxmail_id_list.append(response[nm]['id']) + + if showRecent: + print("Showing the recent email received on: "+response[0]['date']) + check_single_email(email_addr,inboxmail_id = inboxmail_id_list[0]) + print("#"*25) + return; + #FUTURE: A proper protonmail-style layout + +def check_single_email(email_addr,inboxmail_id = 0, bodyasHTML = False, getAttached=False, saveHTMLFile="tmpmail.html",printInTerminal=True): + login_id = email_addr[:email_addr.find('@')] + login_domain = email_addr[email_addr.find('@')+1:] + http_get_url_single = "https://www.1secmail.com/api/v1/?action=readMessage&login="+login_id+"&domain="+login_domain+"&id="+str(inboxmail_id) + response = requests.get(http_get_url_single) + + if not response.status_code == 200: + print("Invalid server response code ", response.status_code) + return ; + + if response.content.decode("utf-8") == 'Message not found': + print("No message found with", inboxmail_id) + return ; + + response = response.json() + if len(response['attachments']) == 0: + str_attached = 'Not Found' + getAttached = False + else: + json_att = response['attachments'] + num_files = len(json_att) + str_attached = [] + attached_files = [] + for nf in range(num_files): + str_attached.append(json_att[nf]['filename']+' ('+json_att[nf]['contentType']+') '+str(round(json_att[nf]['size']/1E6,3))+' MB approx') + attached_files.append(json_att[nf]['filename']) + + if bodyasHTML: + email_body = response['htmlBody'] + fop = open(saveHTMLFile,'w') + fop.write(email_body) + fop.close() + email_body = "Saved as HTML in "+saveHTMLFile + else: + email_body = response['textBody'] + + if printInTerminal: + print("ID: ", response['id']) + print("To: ", email_addr) + print("From: ", response['from']) + print("Date: ", response['date']) + print("Subject: ", response['subject']) + print("Attachments: ", str_attached) + print("--------------------\n",email_body ) + print("--------------------") + + if getAttached: + print("Getting all attached files . . ") + for filename in attached_files: + getAttachedFile(http_get_url_single, filename,savedir='./') + return ; + #FUTURE: All to HTML, not just body. Link Attachments to HTML. Store attachments in workdir + +def getAttachedFile(http_get_url_single, filename,savedir='./'): + http_get_url_attached = http_get_url_single.replace("action=readMessage","action=download")+"&file="+filename + print("Getting attached file:", filename) + response = requests.get(http_get_url_attached) + + if not response.status_code == 200: + print("Invalid server response code ", response.status_code) + return ; + + open(savedir+filename, 'wb').write(response.content) + print("Downloaded to: ",savedir+filename) + return; + #FUTURE: file size verify downloaded vs server + +def use_browser(browser_name='lynx',url='https://www.google.fr/'): + try: + controller = webbrowser.get(browser_name) + except: + print("Unable to locate web browser ", browser_name) + return ; + if not os.path.exists(url): + print("Unable to open email as HTML file ", url) + return; + controller.open_new(url) #_new_tab open(url, new=0, autoraise=True) + return; + #Future: Find verify, subscribe etc to click and visit. Set cookie stuff True, clean caches before exit. + +def flush_all(pydispo_workdir,attached=False): + print("Not implemented") + return ; + +def enc_dec(pydispo_workdir): + print("Not implemented") + return ; + +def backup_previous(pydispo_workdir,attached=False): + print("Not implemented") + return ; + +def main(): + parser = argparse.ArgumentParser(description='pydispo - Disposable Mailbox Powered by Pure-Python',epilog='Cheers :)') + parser.add_argument("id", type=int, default=0, nargs='?', help="Check an email with given message ID" ) + parser.add_argument("-a", "--attached", action='store_true', default=False, required=False, help="Download all attached files in the email" ) + parser.add_argument("-r", "--recent", action='store_true', default=False, required=False, help="Check the most recent email" ) + parser.add_argument("-g", "--generate", action='store_true', default=False, required=False, help="Generate a new email address" ) + parser.add_argument("-s", "--save", action='store_true', default=False, required=False, help="Save email in an HTML file" ) + parser.add_argument("-b", "--browser", type=str, default='TextOnly', required=False, help="Browser to check the email in HTML" ) + parser.add_argument("-e", "--email", type=str, default='NONE@1secmail.com', required=False, help="Check mailbox of a particular email" ) + args = parser.parse_args() + #Take care of parsed arguments + particularID = args.id + getAttached = args.attached + showRecent = args.recent + getNew = args.generate + bodyasHTML = args.save + browser_name = args.browser + email_addr = args.email + + if email_addr == 'NONE@1secmail.com': + email_addr = get_email_address(pydispo_emailaddr_cache,getNew) + if getNew: + sys.exit() + + if particularID == 0: + #Show recent and exit + if showRecent: + check_mailbox(email_addr,showInbox=False,showRecent=True) + #Show mailbox and exit + else: + check_mailbox(email_addr,showInbox=True,showRecent=False) + sys.exit() + else: + showInbox = False + + if not browser_name == 'TextOnly': + #check particular email in browser_name + check_single_email(email_addr,inboxmail_id = particularID, bodyasHTML = True, getAttached=getAttached, saveHTMLFile = pydispo_emailhtml_cache,printInTerminal=False) + use_browser(browser_name=browser_name,url=pydispo_emailhtml_cache) + + else: + #check particular email #save as HTML #get attachments + check_single_email(email_addr, particularID, bodyasHTML, getAttached, pydispo_emailhtml_cache) + + return ; + + +if __name__ == "__main__": + main() + + diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..9c26f33 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,5 @@ +[bdist_wheel] +universal=1 +[metadata] +description-file = README.md +license_files = LICENSE diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..f1772d8 --- /dev/null +++ b/setup.py @@ -0,0 +1,29 @@ +import setuptools + +with open("README.md", "r") as fh: + long_description = fh.read() + +setuptools.setup( + name="pydispo", +<<<<<<< HEAD + version="20.9a2", + author="Aakash Patil", + description="A Disposable Mailbox Powered by Pure-Python", + license="GPL", + long_description=long_description, + long_description_content_type="text/markdown", + keywords="privacy disposable-email temporary-email", + url="https://github.com/aakash30jan/pydispo", + packages=setuptools.find_packages(), + install_requires=['requests'], #PEP-518 issue + platforms=['any'], + classifiers=[ + "Programming Language :: Python ", + "Programming Language :: Python :: 2", + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", + "Operating System :: OS Independent", + ], + entry_points={"console_scripts": ["pydispo = pydispo.pydispo:main"]}, +) +