Files
CyberPanel/emailMarketing/emailMarketing.py

278 lines
14 KiB
Python
Raw Normal View History

2019-12-10 23:04:24 +05:00
#!/usr/local/CyberCP/bin/python
2019-12-10 15:09:10 +05:00
2018-10-17 23:20:02 +05:00
import os
import time
import csv
import re
import plogical.CyberCPLogFileWriter as logging
2019-12-11 20:53:39 +05:00
from .models import EmailMarketing, EmailLists, EmailsInList, EmailTemplate, EmailJobs, SMTPHosts
2018-10-17 23:20:02 +05:00
from websiteFunctions.models import Websites
import threading as multi
import socket, smtplib
import DNS
2018-10-29 21:36:03 +05:00
from random import randint
2019-03-21 23:26:42 +05:00
from plogical.processUtilities import ProcessUtilities
2018-10-29 21:36:03 +05:00
2018-10-17 23:20:02 +05:00
class emailMarketing(multi.Thread):
def __init__(self, function, extraArgs):
multi.Thread.__init__(self)
self.function = function
self.extraArgs = extraArgs
def run(self):
try:
if self.function == 'createEmailList':
self.createEmailList()
elif self.function == 'verificationJob':
self.verificationJob()
elif self.function == 'startEmailJob':
self.startEmailJob()
2019-12-10 15:09:10 +05:00
except BaseException as msg:
2018-10-17 23:20:02 +05:00
logging.CyberCPLogFileWriter.writeToFile(str(msg) + ' [emailMarketing.run]')
def createEmailList(self):
try:
website = Websites.objects.get(domain=self.extraArgs['domain'])
try:
newList = EmailLists(owner=website, listName=self.extraArgs['listName'], dateCreated=time.strftime("%I-%M-%S-%a-%b-%Y"))
newList.save()
except:
newList = EmailLists.objects.get(listName=self.extraArgs['listName'])
counter = 0
if self.extraArgs['path'].endswith('.csv'):
with open(self.extraArgs['path'], 'r') as emailsList:
data = csv.reader(emailsList, delimiter=',')
for items in data:
2018-10-19 22:47:15 +05:00
try:
for value in items:
if re.match('^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', value) != None:
try:
getEmail = EmailsInList.objects.get(owner=newList, email=value)
except:
newEmail = EmailsInList(owner=newList, email=value,
verificationStatus='NOT CHECKED',
dateCreated=time.strftime("%I-%M-%S-%a-%b-%Y"))
newEmail.save()
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], str(counter) + ' emails read.')
counter = counter + 1
2019-12-10 15:09:10 +05:00
except BaseException as msg:
2018-10-19 22:47:15 +05:00
logging.CyberCPLogFileWriter.writeToFile(str(msg))
continue
2018-10-17 23:20:02 +05:00
elif self.extraArgs['path'].endswith('.txt'):
with open(self.extraArgs['path'], 'r') as emailsList:
emails = emailsList.readline()
while emails:
email = emails.strip('\n')
if re.match('^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', email) != None:
try:
getEmail = EmailsInList.objects.get(owner=newList, email=email)
2019-12-10 15:09:10 +05:00
except BaseException as msg:
2018-10-17 23:20:02 +05:00
newEmail = EmailsInList(owner=newList, email=email, verificationStatus='NOT CHECKED',
dateCreated=time.strftime("%I-%M-%S-%a-%b-%Y"))
newEmail.save()
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],str(counter) + ' emails read.')
counter = counter + 1
emails = emailsList.readline()
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], str(counter) + 'Successfully read all emails. [200]')
2019-12-10 15:09:10 +05:00
except BaseException as msg:
2018-10-17 23:20:02 +05:00
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], str(msg) +'. [404]')
return 0
def verificationJob(self):
try:
verificationList = EmailLists.objects.get(listName=self.extraArgs['listName'])
domain = verificationList.owner.domain
if not os.path.exists('/home/cyberpanel/' + domain):
os.mkdir('/home/cyberpanel/' + domain)
tempStatusPath = '/home/cyberpanel/' + domain + "/" + self.extraArgs['listName']
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, 'Starting verification job..')
counter = 1
allEmailsInList = verificationList.emailsinlist_set.all()
for items in allEmailsInList:
if items.verificationStatus != 'Verified':
try:
email = items.email
domainName = email.split('@')[1]
records = DNS.dnslookup(domainName, 'MX')
for mxRecord in records:
# Get local server hostname
host = socket.gethostname()
server = smtplib.SMTP()
server.set_debuglevel(0)
# SMTP Conversation
server.connect(mxRecord[1])
server.helo(host)
server.mail('host' + "@" + host)
code, message = server.rcpt(str(email))
server.quit()
# Assume 250 as Success
if code == 250:
items.verificationStatus = 'Verified'
items.save()
break
else:
items.verificationStatus = 'Verification Failed'
logging.CyberCPLogFileWriter.writeToFile(email + " verification failed with error: " + message)
items.save()
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, str(counter) + ' emails verified so far..')
counter = counter + 1
2019-12-10 15:09:10 +05:00
except BaseException as msg:
2018-10-17 23:20:02 +05:00
items.verificationStatus = 'Verification Failed'
items.save()
counter = counter + 1
logging.CyberCPLogFileWriter.writeToFile(str(msg))
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, str(counter) + ' emails successfully verified. [200]')
2019-12-10 15:09:10 +05:00
except BaseException as msg:
2018-10-17 23:20:02 +05:00
verificationList = EmailLists.objects.get(listName=self.extraArgs['listName'])
domain = verificationList.owner.domain
tempStatusPath = '/home/cyberpanel/' + domain + "/" + self.extraArgs['listName']
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, str(msg) +'. [404]')
2018-10-19 22:47:15 +05:00
logging.CyberCPLogFileWriter.writeToFile('your error')
2018-10-17 23:20:02 +05:00
return 0
def startEmailJob(self):
try:
try:
if self.extraArgs['host'] == 'localhost':
2018-10-19 22:47:15 +05:00
smtpServer = smtplib.SMTP('127.0.0.1')
2018-10-17 23:20:02 +05:00
else:
verifyHost = SMTPHosts.objects.get(host=self.extraArgs['host'])
2019-03-19 01:04:22 +05:00
smtpServer = smtplib.SMTP(str(verifyHost.host), int(verifyHost.port))
smtpServer.login(str(verifyHost.userName), str(verifyHost.password))
2018-10-17 23:20:02 +05:00
except smtplib.SMTPHeloError:
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
'The server didnt reply properly to the HELO greeting.')
return
except smtplib.SMTPAuthenticationError:
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
'Username and password combination not accepted.')
return
except smtplib.SMTPException:
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
'No suitable authentication method was found.')
return
emailList = EmailLists.objects.get(listName=self.extraArgs['listName'])
allEmails = emailList.emailsinlist_set.all()
emailMessage = EmailTemplate.objects.get(name=self.extraArgs['selectedTemplate'])
totalEmails = allEmails.count()
sent = 0
failed = 0
2018-10-19 22:47:15 +05:00
ipFile = "/etc/cyberpanel/machineIP"
f = open(ipFile)
ipData = f.read()
ipAddress = ipData.split('\n', 1)[0]
2018-10-17 23:20:02 +05:00
## Compose Message
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import re
2018-10-29 21:36:03 +05:00
tempPath = "/home/cyberpanel/" + str(randint(1000, 9999))
2018-10-17 23:20:02 +05:00
2020-06-04 22:24:51 +05:00
emailJob = EmailJobs(owner=emailMessage, date=time.strftime("%I-%M-%S-%a-%b-%Y"),
host=self.extraArgs['host'], totalEmails=totalEmails,
sent=sent, failed=failed
)
emailJob.save()
2018-10-22 10:55:52 +05:00
2020-06-04 22:24:51 +05:00
for items in allEmails:
try:
message = MIMEMultipart('alternative')
message['Subject'] = emailMessage.subject
message['From'] = emailMessage.fromEmail
message['reply-to'] = emailMessage.replyTo
if (items.verificationStatus == 'Verified' or self.extraArgs[
'verificationCheck']) and not items.verificationStatus == 'REMOVED':
try:
2018-10-19 22:47:15 +05:00
2020-06-04 22:24:51 +05:00
removalLink = "https:\/\/" + ipAddress + ":8090\/emailMarketing\/remove\/" + self.extraArgs[
'listName'] + "\/" + items.email
messageText = emailMessage.emailMessage.encode('utf-8', 'replace')
message['To'] = items.email
2018-10-29 21:36:03 +05:00
2020-06-04 22:24:51 +05:00
if re.search(b'<html', messageText, re.IGNORECASE) and re.search(b'<body', messageText,
re.IGNORECASE):
finalMessage = messageText.decode()
2018-10-29 21:36:03 +05:00
2020-06-04 22:24:51 +05:00
self.extraArgs['unsubscribeCheck'] = 0
if self.extraArgs['unsubscribeCheck']:
messageFile = open(tempPath, 'w')
messageFile.write(finalMessage)
messageFile.close()
2018-10-22 10:55:52 +05:00
2020-06-04 22:24:51 +05:00
command = "sudo sed -i 's/{{ unsubscribeCheck }}/" + removalLink + "/g' " + tempPath
ProcessUtilities.executioner(command, 'cyberpanel')
2018-10-22 10:55:52 +05:00
2020-06-04 22:24:51 +05:00
messageFile = open(tempPath, 'r')
finalMessage = messageFile.read()
messageFile.close()
2018-10-22 10:55:52 +05:00
2020-06-04 22:24:51 +05:00
html = MIMEText(finalMessage, 'html')
message.attach(html)
2018-10-19 22:47:15 +05:00
2020-06-04 22:24:51 +05:00
else:
finalMessage = messageText
if self.extraArgs['unsubscribeCheck']:
finalMessage = finalMessage.replace('{{ unsubscribeCheck }}', removalLink)
html = MIMEText(finalMessage, 'plain')
message.attach(html)
smtpServer.sendmail(message['From'], items.email, message.as_string())
sent = sent + 1
emailJob.sent = sent
emailJob.save()
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
'Successfully sent: ' + str(
sent) + ' Failed: ' + str(
failed))
except BaseException as msg:
failed = failed + 1
emailJob.failed = failed
emailJob.save()
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
'Successfully sent: ' + str(
sent) + ', Failed: ' + str(failed))
logging.CyberCPLogFileWriter.writeToFile(str(msg))
except BaseException as msg:
failed = failed + 1
emailJob.failed = failed
emailJob.save()
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
'Successfully sent: ' + str(
sent) + ', Failed: ' + str(failed))
logging.CyberCPLogFileWriter.writeToFile(str(msg))
2018-10-19 22:47:15 +05:00
2018-10-17 23:20:02 +05:00
2020-06-04 22:24:51 +05:00
emailJob = EmailJobs(owner=emailMessage, date=time.strftime("%I-%M-%S-%a-%b-%Y"),
host=self.extraArgs['host'], totalEmails=totalEmails,
sent=sent, failed=failed
)
emailJob.save()
2018-10-17 23:20:02 +05:00
2020-06-04 22:24:51 +05:00
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
'Email job completed. [200]')
2019-12-10 15:09:10 +05:00
except BaseException as msg:
2018-10-29 21:36:03 +05:00
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], str(msg) + '. [404]')
2018-10-17 23:20:02 +05:00
return 0