Skip to content

Commit

Permalink
fix: optimize code
Browse files Browse the repository at this point in the history
feat: add no-reply
  • Loading branch information
Al-Taie committed Jan 20, 2022
1 parent 9bfff05 commit 027f01c
Show file tree
Hide file tree
Showing 13 changed files with 547 additions and 300 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ else:
receiver: Email Address as String or List. [Recuired]
cc: Email Address as String or List. (Carbon Copy) [Optional]
bcc: Email Address as String or List. (Blind Carbon Copy) [Optional]
no_reply: Set Another Email To Reoly [Optional]
subject: Message Title. [Optional]
message: Your Message. [Optional]
image: Image File Name. (Image Path) [Optional]
Expand Down
Binary file added dist/quick-mailer-2022.1.19.tar.gz
Binary file not shown.
Binary file added dist/quick_mailer-2022.1.19-py3-none-any.whl
Binary file not shown.
303 changes: 3 additions & 300 deletions mailer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,305 +22,8 @@
SOFTWARE.
"""

import ssl as _ssl
from email.mime.application import MIMEApplication as _MIMEApp
from email.mime.audio import MIMEAudio as _MIMEAudio
from email.mime.image import MIMEImage as _MIMEImage
from email.mime.multipart import MIMEMultipart as _MIMEMultipart
from email.mime.text import MIMEText as _MIMEText
from smtplib import SMTP as _SMTP
from time import sleep as _sleep
from mailer.mailer import Mailer
from mailer.utils import example

__all__ = ['Mailer', '__VERSION__', 'example']
__VERSION__ = '0.1.0'


# Main Class
class Mailer:
def __init__(self, email: str, password: str):
"""
:param email: Your Email Address
:param password: Yor Email Password
"""
# Variables
self.email = email
self.__password = password
self.__server = None
self.status = bool()
self.login = bool()
self.multi = bool()
self.__sleep = int()
self.__repeat = 1
self.count_rec = 1
self.count_cc = int()
self.count_bcc = int()
self.count_msg = self.__repeat*self.count_rec
self.__port = 587
self.GMAIL = 'smtp.gmail.com'
# self.YAHOO = 'smtp.mail.yahoo.com' # Unsupported Now
self.MICROSOFT = 'smtp.office365.com'
self.provider = self.GMAIL

# Apply Settings
self.settings()

# About Method
@staticmethod
def about():
info = """
About Module:
This Module help you to send fast Email.
And you can attach [image, audio, and other files] easily.
About Developer:
Name: Ahmed Al-Taie
Github: https://github.com/Al-Taie
Pypi: https://pypi.org/user/Altaie
Instagram: https://www.instagram.com/9_Tay
Finally Thanks For Use My Module.
You Can Join Our Discord For Any Question:
Discord: https://discord.gg/gWdCNv7
"""
print(info)
return

# File Reader Method
@staticmethod
def _file_reader(filename: str):
with open(filename, 'rb') as f:
return f.read()

# Settings Method
def settings(self,
repeat: int = 1,
sleep=None,
provider: str = None,
multi=False):
"""
:param multi:
:type multi:
:param repeat: Repeat Number
:param sleep: Set Sleep Time (In Seconds)
:param provider: See example Function
:return: None
"""
self.__repeat = repeat
self.multi = multi

if sleep:
self.__sleep = sleep

if provider:
self.provider = provider

# Login Method
def __login(self):
context = _ssl.create_default_context()

self.__server = _SMTP(host=self.provider,
port=self.__port)
self.__server.ehlo()
self.__server.starttls(context=context)
self.__server.ehlo()

try:
self.__server.login(user=self.email,
password=self.__password)
self.login = True
return True
except Exception as e:
if self.provider == self.GMAIL:
problem = """
Error: Email And Password Not Accepted.
Note:
Make sure you Allowed less secure apps,
if you didn't, visit this link:
==> https://myaccount.google.com/lesssecureapps
For More information visit this link:
==> https://support.google.com/mail/?p=BadCredentials
"""
else:
problem = e
print(problem)
self.login = False
return False

# Send Method
def send(self,
receiver,
cc=None,
bcc=None,
subject: str = None,
message: str = None,
image: str = None,
audio: str = None,
file: str = None):
"""
:param cc: Email Address as String or List. (Carbon Copy)
:param bcc: Email Address as String or List. (Blind Carbon Copy)
:param receiver: Email Address as String or List
:param subject: Message Title
:param message: Your Message
:param image: Image File Name
:param audio: Audio File Name
:param file: File Name
:return: Boolean
"""

msg = _MIMEMultipart()
msg['Subject'] = subject
msg['From'] = self.email

try:
if message is not None:
text = _MIMEText(message)
msg.attach(text)

if image is not None:
image_data = self._file_reader(image)
image = _MIMEImage(_imagedata=image_data, name=image)
msg.attach(image)

if audio is not None:
audio_data = self._file_reader(audio)
audio = _MIMEAudio(_audiodata=audio_data, name=audio, _subtype='')
msg.attach(audio)

if file is not None:
file_data = self._file_reader(file)
file = _MIMEApp(_data=file_data, name=file)
msg.attach(file)
except Exception:
print('Error: File Not Found!')
self.status = False
return False

send_info = []
multi_info = {}

if 'list' in str(type(receiver)):
self.count_rec = len(receiver)
receiver = ','.join(i for i in receiver)

if 'list' in str(type(cc)):
self.count_cc = len(cc)
cc = ','.join(i for i in cc)

if 'list' in str(type(bcc)):
self.count_bcc = len(bcc)
bcc = ','.join(i for i in bcc)

if self.__login():
msg['To'] = receiver
msg['CC'] = cc
msg['BCC'] = bcc

if self.multi:
for _ in range(self.__repeat):
try:
self.__server.sendmail(from_addr=self.email,
to_addrs=receiver,
msg=msg.as_string())
except Exception:
if self.__repeat == 1 & self.count_rec == 1:
self.status = False
else:
send_info.append(False)

else:
if self.__repeat == 1 & self.count_rec == 1:
self.status = True
else:
send_info.append(True)
self.status = send_info

finally:
_sleep(self.__sleep)
else:
for rec in receiver.split(','):
send_info = []
for _ in range(self.__repeat):
try:
self.__server.sendmail(from_addr=self.email,
to_addrs=rec,
msg=msg.as_string())
except Exception as e:
if self.__repeat == 1 & self.count_rec == 1:
self.status = False
else:
send_info.append(False)

if 'OutboundSpamException' in str(e):
print('Error: Please Login To Your Account And Verify it.')
break

else:
if self.__repeat == 1 & self.count_rec == 1:
self.status = True
else:
send_info.append(True)
self.status = send_info
multi_info[rec] = send_info

finally:
_sleep(self.__sleep)

if self.count_rec != 1:
self.status = multi_info

self.__server.close()


# Example Function
def example():
ex = """
####################
# [Copy This Code] #
####################
mail = Mailer(email='someone@gmail.com',
password='***')
# IF You Want Repeat Sending, Change repeat Value
# And IF You Want Change Mail Service
# Chose One: mail.[GMAIL, MICROSOFT]
mail.settings(repeat=1,
sleep=0,
provider=mail.GMAIL,
multi=False)
# Send Message
mail.send(receiver='someone@example.com', # Email From Any service Provider
cc='someone1@example.com'
bcc='someone2@example.com'
subject='TEST',
message='HI, This Message From Python :)',
image=None, # Image File Path
audio=None, # Audio File Path
file=None) # Any File Path
# Login Status Info
print('login:', mail.login)
# Sending Status Info
print('status:', mail.status)
# CC Receivers Count
print('CC count:', mail.count_cc)
# BCC Receivers Count
print('BCC count:', mail.count_bcc)
# Receivers Count
print('Receivers count:', mail.count_rec)
# Messages Count IF You Allowed Repeat
print('Messages count:', mail.count_msg)
# For More Information
mail.about()
"""
print(ex)
__VERSION__ = '2022.1.19'
34 changes: 34 additions & 0 deletions mailer/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
class ImageNotFoundError(FileNotFoundError):
"""Exception raised when image not exists.
Attributes:
message -- explanation of the error
"""

def __init__(self, message="Image not exists in a path!"):
self.message = message
super().__init__(self.message)


class AudioNotFoundError(FileNotFoundError):
"""Exception raised when audio not exists.
Attributes:
message -- explanation of the error
"""

def __init__(self, message="Audio not exists in a path!"):
self.message = message
super().__init__(self.message)


class OutboundSpamException(Exception):
"""Exception raised when Account need to verify.
Attributes:
message -- explanation of the error
"""

def __init__(self, message="Please Login To Your Account And Verify it."):
self.message = message
super().__init__(self.message)
Loading

0 comments on commit 027f01c

Please sign in to comment.