Email Marketing as a plugin

This commit is contained in:
usmannasir
2018-10-17 23:20:02 +05:00
parent 5303800112
commit 001f762d9d
35 changed files with 4625 additions and 6 deletions

View File

@@ -61,6 +61,7 @@ INSTALLED_APPS = [
'manageServices',
'pluginHolder',
'emailPremium',
'emailMarketing',
]
MIDDLEWARE = [

View File

@@ -38,4 +38,5 @@ urlpatterns = [
url(r'^emailPremium/',include('emailPremium.urls')),
url(r'^manageservices/',include('manageServices.urls')),
url(r'^plugins/',include('pluginHolder.urls')),
url(r'^emailMarketing/', include('emailMarketing.urls')),
]

View File

@@ -624,6 +624,7 @@
<script src="{% static 'mailServer/mailServer.js' %}"></script>
<script src="{% static 'serverLogs/serverLogs.js' %}"></script>
<script src="{% static 'emailPremium/emailPremium.js' %}"></script>
<script src="{% static 'emailMarketing/emailMarketing.js' %}"></script>
<!-- PieGage charts -->

View File

@@ -0,0 +1 @@
default_app_config = 'emailMarketing.apps.EmailmarketingConfig'

6
emailMarketing/admin.py Normal file
View File

@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
# Register your models here.

10
emailMarketing/apps.py Normal file
View File

@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.apps import AppConfig
class EmailmarketingConfig(AppConfig):
name = 'emailMarketing'
def ready(self):
import signals

66
emailMarketing/emACL.py Normal file
View File

@@ -0,0 +1,66 @@
from .models import EmailMarketing, EmailTemplate, SMTPHosts, EmailLists, EmailJobs
from websiteFunctions.models import Websites
class emACL:
@staticmethod
def checkIfEMEnabled(userName):
try:
user = EmailMarketing.objects.get(userName=userName)
return 0
except:
return 1
@staticmethod
def getEmailsLists(domain):
website = Websites.objects.get(domain=domain)
emailLists = website.emaillists_set.all()
listNames = []
for items in emailLists:
listNames.append(items.listName)
return listNames
@staticmethod
def allTemplates(currentACL, admin):
if currentACL['admin'] == 1:
allTemplates = EmailTemplate.objects.all()
else:
allTemplates = admin.emailtemplate_set.all()
templateNames = []
for items in allTemplates:
templateNames.append(items.name)
return templateNames
@staticmethod
def allSMTPHosts(currentACL, admin):
if currentACL['admin'] == 1:
allHosts = SMTPHosts.objects.all()
else:
allHosts = admin.smtphosts_set.all()
hostNames = []
for items in allHosts:
hostNames.append(items.host)
return hostNames
@staticmethod
def allEmailsLists(currentACL, admin):
listNames = []
emailLists = EmailLists.objects.all()
if currentACL['admin'] == 1:
for items in emailLists:
listNames.append(items.listName)
else:
for items in emailLists:
if items.owner.admin == admin:
listNames.append(items.listName)
return listNames

View File

@@ -0,0 +1,212 @@
#!/usr/local/CyberCP/bin/python2
from __future__ import absolute_import
import os
import time
import csv
import re
import plogical.CyberCPLogFileWriter as logging
from emailMarketing.models import EmailMarketing, EmailLists, EmailsInList, EmailTemplate, EmailJobs, SMTPHosts
from websiteFunctions.models import Websites
import threading as multi
import socket, smtplib
import DNS
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()
except BaseException, msg:
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:
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
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)
except BaseException, msg:
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]')
except BaseException, msg:
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
except BaseException, msg:
items.verificationStatus = 'Verification Failed'
items.save()
counter = counter + 1
logging.CyberCPLogFileWriter.writeToFile(str(msg))
logging.CyberCPLogFileWriter.statusWriter(tempStatusPath, str(counter) + ' emails successfully verified. [200]')
except BaseException, msg:
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]')
return 0
def startEmailJob(self):
try:
try:
if self.extraArgs['host'] == 'localhost':
smtpServer = smtplib.SMTP(self.extraArgs['host'])
else:
verifyHost = SMTPHosts.objects.get(host=self.extraArgs['host'])
smtpServer = smtplib.SMTP(verifyHost.host, int(verifyHost.port))
smtpServer.login(verifyHost.userName, verifyHost.password)
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
## Compose Message
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import re
message = MIMEMultipart('alternative')
message['Subject'] = emailMessage.subject
message['From'] = emailMessage.fromEmail
if re.search('<html>', emailMessage.emailMessage, re.IGNORECASE):
html = MIMEText(emailMessage.emailMessage, 'html')
message.attach(html)
else:
html = MIMEText(emailMessage.emailMessage, 'plain')
message.attach(html)
for items in allEmails:
if items.verificationStatus == 'Verified' or self.extraArgs['verificationCheck']:
try:
smtpServer.sendmail(message['From'], items.email, message.as_string())
sent = sent + 1
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
'Successfully sent: ' + str(sent) + ' Failed: ' + str(failed))
except BaseException, msg:
failed = failed + 1
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],
'Successfully sent: ' + str(
sent) + ', Failed: ' + str(failed))
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()
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'],'Email job completed. [200]')
except BaseException, msg:
logging.CyberCPLogFileWriter.statusWriter(self.extraArgs['tempStatusPath'], str(msg) +'. [404]')
return 0

View File

@@ -0,0 +1,733 @@
from django.shortcuts import render, HttpResponse, redirect
from plogical.acl import ACLManager
from loginSystem.views import loadLoginPage
import json
from random import randint
import time
from .models import EmailMarketing, EmailLists, EmailsInList, EmailJobs
from websiteFunctions.models import Websites
from emailMarketing import emailMarketing as EM
from math import ceil
import smtplib
from .models import SMTPHosts, EmailTemplate
from loginSystem.models import Administrator
from emACL import emACL
class EmailMarketingManager:
def __init__(self, request = None, domain = None):
self.request = request
self.domain = domain
def emailMarketing(self):
try:
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
else:
return ACLManager.loadError()
return render(self.request, 'emailMarketing/emailMarketing.html')
except KeyError, msg:
return redirect(loadLoginPage)
def fetchUsers(self):
try:
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
else:
return ACLManager.loadError()
allUsers = ACLManager.findAllUsers()
disabledUsers = EmailMarketing.objects.all()
disabled = []
for items in disabledUsers:
disabled.append(items.userName)
json_data = "["
checker = 0
counter = 1
for items in allUsers:
if items in disabled:
status = 0
else:
status = 1
dic = {'id': counter, 'userName': items, 'status': status}
if checker == 0:
json_data = json_data + json.dumps(dic)
checker = 1
else:
json_data = json_data + ',' + json.dumps(dic)
counter = counter + 1
json_data = json_data + ']'
data_ret = {"status": 1, 'data': json_data}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def enableDisableMarketing(self):
try:
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
else:
return ACLManager.loadErrorJson()
data = json.loads(self.request.body)
userName = data['userName']
try:
disableMarketing = EmailMarketing.objects.get(userName=userName)
disableMarketing.delete()
except:
enableMarketing = EmailMarketing(userName=userName)
enableMarketing.save()
data_ret = {"status": 1}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def createEmailList(self):
try:
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
if ACLManager.checkOwnership(self.domain, admin, currentACL) == 1:
pass
else:
return ACLManager.loadError()
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadError()
return render(self.request, 'emailMarketing/createEmailList.html', {'domain': self.domain})
except KeyError, msg:
return redirect(loadLoginPage)
def submitEmailList(self):
try:
data = json.loads(self.request.body)
extraArgs = {}
extraArgs['domain'] = data['domain']
extraArgs['path'] = data['path']
extraArgs['listName'] = data['listName']
extraArgs['tempStatusPath'] = "/home/cyberpanel/" + str(randint(1000, 9999))
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
if ACLManager.checkOwnership(data['domain'], admin, currentACL) == 1:
pass
else:
return ACLManager.loadErrorJson()
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
em = EM('createEmailList', extraArgs)
em.start()
time.sleep(2)
data_ret = {"status": 1, 'tempStatusPath': extraArgs['tempStatusPath']}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def manageLists(self):
try:
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
if ACLManager.checkOwnership(self.domain, admin, currentACL) == 1:
pass
else:
return ACLManager.loadError()
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadError()
listNames = emACL.getEmailsLists(self.domain)
return render(self.request, 'emailMarketing/manageLists.html', {'listNames': listNames, 'domain': self.domain})
except KeyError, msg:
return redirect(loadLoginPage)
def fetchEmails(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
data = json.loads(self.request.body)
listName = data['listName']
recordstoShow = int(data['recordstoShow'])
page = int(data['page'])
finalPageNumber = ((page * recordstoShow)) - recordstoShow
endPageNumber = finalPageNumber + recordstoShow
emailList = EmailLists.objects.get(listName=listName)
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
elif emailList.owner.id != userID:
ACLManager.loadErrorJson()
emails = emailList.emailsinlist_set.all()
## Pagination value
pages = float(len(emails)) / float(recordstoShow)
pagination = []
counter = 1
if pages <= 1.0:
pages = 1
pagination.append(counter)
else:
pages = ceil(pages)
finalPages = int(pages) + 1
for i in range(1, finalPages):
pagination.append(counter)
counter = counter + 1
## Pagination value
emails = emails[finalPageNumber:endPageNumber]
json_data = "["
checker = 0
counter = 1
for items in emails:
dic = {'id': items.id, 'email': items.email, 'verificationStatus': items.verificationStatus,
'dateCreated': items.dateCreated}
if checker == 0:
json_data = json_data + json.dumps(dic)
checker = 1
else:
json_data = json_data + ',' + json.dumps(dic)
counter = counter + 1
json_data = json_data + ']'
data_ret = {"status": 1, 'data': json_data, 'pagination': pagination}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def deleteList(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
data = json.loads(self.request.body)
listName = data['listName']
delList = EmailLists.objects.get(listName=listName)
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
elif delList.owner.id != userID:
ACLManager.loadErrorJson()
delList.delete()
data_ret = {"status": 1}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def emailVerificationJob(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
data = json.loads(self.request.body)
extraArgs = {}
extraArgs['listName'] = data['listName']
delList = EmailLists.objects.get(listName=extraArgs['listName'])
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
elif delList.owner.id != userID:
ACLManager.loadErrorJson()
em = EM('verificationJob', extraArgs)
em.start()
time.sleep(2)
data_ret = {"status": 1}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def deleteEmail(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
data = json.loads(self.request.body)
id = data['id']
delEmail = EmailsInList.objects.get(id=id)
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
elif delEmail.owner.owner.id != userID:
ACLManager.loadErrorJson()
delEmail.delete()
data_ret = {"status": 1}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def manageSMTP(self):
try:
userID = self.request.session['userID']
currentACL = ACLManager.loadedACL(userID)
admin = Administrator.objects.get(pk=userID)
if ACLManager.checkOwnership(self.domain, admin, currentACL) == 1:
pass
else:
return ACLManager.loadError()
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadError()
website = Websites.objects.get(domain=self.domain)
emailLists = website.emaillists_set.all()
listNames = []
for items in emailLists:
listNames.append(items.listName)
return render(self.request, 'emailMarketing/manageSMTPHosts.html', {'listNames': listNames, 'domain': self.domain})
except KeyError, msg:
return redirect(loadLoginPage)
def saveSMTPHost(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
data = json.loads(self.request.body)
smtpHost = data['smtpHost']
smtpPort = data['smtpPort']
smtpUserName = data['smtpUserName']
smtpPassword = data['smtpPassword']
if SMTPHosts.objects.count() == 0:
admin = Administrator.objects.get(pk=1)
defaultHost = SMTPHosts(owner=admin, host='localhost', port=25, userName='None', password='None')
defaultHost.save()
try:
verifyLogin = smtplib.SMTP(smtpHost, int(smtpPort))
verifyLogin.login(smtpUserName, smtpPassword)
admin = Administrator.objects.get(pk=userID)
newHost = SMTPHosts(owner=admin, host=smtpHost, port=smtpPort, userName=smtpUserName,
password=smtpPassword)
newHost.save()
except smtplib.SMTPHeloError:
data_ret = {"status": 0, 'error_message': 'The server did not reply properly to the HELO greeting.'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except smtplib.SMTPAuthenticationError:
data_ret = {"status": 0, 'error_message': 'Username and password combination not accepted.'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except smtplib.SMTPException:
data_ret = {"status": 0, 'error_message': 'No suitable authentication method was found.'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
data_ret = {"status": 1}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def fetchSMTPHosts(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
allHosts = SMTPHosts.objects.all()
else:
admin = Administrator.objects.get(pk=userID)
allHosts = admin.smtphosts_set.all()
json_data = "["
checker = 0
counter = 1
for items in allHosts:
dic = {'id': items.id, 'owner': items.owner.userName, 'host': items.host, 'port': items.port,
'userName': items.userName}
if checker == 0:
json_data = json_data + json.dumps(dic)
checker = 1
else:
json_data = json_data + ',' + json.dumps(dic)
counter = counter + 1
json_data = json_data + ']'
data_ret = {"status": 1, 'data': json_data}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def smtpHostOperations(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
data = json.loads(self.request.body)
id = data['id']
operation = data['operation']
if operation == 'delete':
delHost = SMTPHosts.objects.get(id=id)
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
elif delHost.owner.id != userID:
ACLManager.loadErrorJson()
delHost.delete()
data_ret = {"status": 1, 'message': 'Successfully deleted.'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
else:
try:
verifyHost = SMTPHosts.objects.get(id=id)
verifyLogin = smtplib.SMTP(verifyHost.host, int(verifyHost.port))
verifyLogin.login(verifyHost.userName, verifyHost.password)
data_ret = {"status": 1, 'message': 'Login successful.'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except smtplib.SMTPHeloError:
data_ret = {"status": 0, 'error_message': 'The server did not reply properly to the HELO greeting.'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except smtplib.SMTPAuthenticationError:
data_ret = {"status": 0, 'error_message': 'Username and password combination not accepted.'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except smtplib.SMTPException:
data_ret = {"status": 0, 'error_message': 'No suitable authentication method was found.'}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def composeEmailMessage(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
return render(self.request, 'emailMarketing/composeMessages.html')
except KeyError, msg:
return redirect(loadLoginPage)
def saveEmailTemplate(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
data = json.loads(self.request.body)
name = data['name']
subject = data['subject']
fromName = data['fromName']
fromEmail = data['fromEmail']
replyTo = data['replyTo']
emailMessage = data['emailMessage']
admin = Administrator.objects.get(pk=userID)
newTemplate = EmailTemplate(owner=admin, name=name, subject=subject, fromName=fromName, fromEmail=fromEmail,
replyTo=replyTo, emailMessage=emailMessage)
newTemplate.save()
data_ret = {"status": 1}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def sendEmails(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
currentACL = ACLManager.loadedACL(userID)
templateNames = emACL.allTemplates(currentACL, admin)
hostNames = emACL.allSMTPHosts(currentACL, admin)
listNames = emACL.allEmailsLists(currentACL, admin)
Data = {}
Data['templateNames'] = templateNames
Data['hostNames'] = hostNames
Data['listNames'] = listNames
return render(self.request, 'emailMarketing/sendEmails.html', Data)
except KeyError, msg:
return redirect(loadLoginPage)
def templatePreview(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
template = EmailTemplate.objects.get(name=self.domain)
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
elif template.owner != admin:
return ACLManager.loadError()
return HttpResponse(template.emailMessage)
except KeyError, msg:
return redirect(loadLoginPage)
def fetchJobs(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
data = json.loads(self.request.body)
selectedTemplate = data['selectedTemplate']
template = EmailTemplate.objects.get(name=selectedTemplate)
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
elif template.owner != admin:
return ACLManager.loadErrorJson()
allJobs = EmailJobs.objects.filter(owner=template)
json_data = "["
checker = 0
counter = 1
for items in allJobs:
dic = {'id': items.id,
'date': items.date,
'host': items.host,
'totalEmails': items.totalEmails,
'sent': items.sent,
'failed': items.failed}
if checker == 0:
json_data = json_data + json.dumps(dic)
checker = 1
else:
json_data = json_data + ',' + json.dumps(dic)
counter = counter + 1
json_data = json_data + ']'
data_ret = {"status": 1, 'data': json_data}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def startEmailJob(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
data = json.loads(self.request.body)
extraArgs = {}
extraArgs['selectedTemplate'] = data['selectedTemplate']
extraArgs['listName'] = data['listName']
extraArgs['host'] = data['host']
extraArgs['verificationCheck'] = data['verificationCheck']
extraArgs['unsubscribeCheck'] = data['unsubscribeCheck']
extraArgs['tempStatusPath'] = "/home/cyberpanel/" + data['selectedTemplate'] + '_pendingJob'
currentACL = ACLManager.loadedACL(userID)
template = EmailTemplate.objects.get(name=extraArgs['selectedTemplate'])
if currentACL['admin'] == 1:
pass
elif template.owner != admin:
return ACLManager.loadErrorJson()
em = EM('startEmailJob', extraArgs)
em.start()
time.sleep(2)
data_ret = {"status": 1, 'tempStatusPath': extraArgs['tempStatusPath']}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def deleteTemplate(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
data = json.loads(self.request.body)
selectedTemplate = data['selectedTemplate']
delTemplate = EmailTemplate.objects.get(name=selectedTemplate)
currentACL = ACLManager.loadedACL(userID)
if currentACL['admin'] == 1:
pass
elif delTemplate.owner != admin:
return ACLManager.loadErrorJson()
delTemplate.delete()
data_ret = {"status": 1}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)
def deleteJob(self):
try:
userID = self.request.session['userID']
admin = Administrator.objects.get(pk=userID)
if emACL.checkIfEMEnabled(admin.userName) == 0:
return ACLManager.loadErrorJson()
data = json.loads(self.request.body)
id = data['id']
delJob = EmailJobs(id=id)
delJob.delete()
data_ret = {"status": 1}
json_data = json.dumps(data_ret)
return HttpResponse(json_data)
except BaseException, msg:
final_dic = {'status': 0, 'error_message': str(msg)}
final_json = json.dumps(final_dic)
return HttpResponse(final_json)

7
emailMarketing/meta.xml Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<cyberpanelPluginConfig>
<name>Email Marketing</name>
<type>plugin</type>
<description>Email Marketing plugin for CyberPanel.</description>
<version>1.0</version>
</cyberpanelPluginConfig>

View File

51
emailMarketing/models.py Normal file
View File

@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from websiteFunctions.models import Websites
from loginSystem.models import Administrator
# Create your models here.
class EmailMarketing(models.Model):
userName = models.CharField(max_length=50, unique=True)
class EmailLists(models.Model):
owner = models.ForeignKey(Websites, on_delete=models.PROTECT)
listName = models.CharField(max_length=50, unique=True)
dateCreated = models.CharField(max_length=200)
class EmailsInList(models.Model):
owner = models.ForeignKey(EmailLists, on_delete=models.CASCADE)
email = models.CharField(max_length=50)
firstName = models.CharField(max_length=20, default='')
lastName = models.CharField(max_length=20, default='')
verificationStatus = models.CharField(max_length=100)
dateCreated = models.CharField(max_length=200)
class SMTPHosts(models.Model):
owner = models.ForeignKey(Administrator, on_delete=models.CASCADE)
host = models.CharField(max_length=150, unique= True)
port = models.CharField(max_length=10)
userName = models.CharField(max_length=50)
password = models.CharField(max_length=50)
class EmailTemplate(models.Model):
owner = models.ForeignKey(Administrator, on_delete=models.CASCADE)
name = models.CharField(unique=True, max_length=100)
subject = models.CharField(max_length=1000)
fromName = models.CharField(max_length=100)
fromEmail = models.CharField(max_length=150)
replyTo = models.CharField(max_length=150)
emailMessage = models.CharField(max_length=30000)
class EmailJobs(models.Model):
owner = models.ForeignKey(EmailTemplate, on_delete=models.CASCADE)
date = models.CharField(max_length=200)
host = models.CharField(max_length=1000)
totalEmails = models.IntegerField()
sent = models.IntegerField()
failed = models.IntegerField()

79
emailMarketing/signals.py Normal file
View File

@@ -0,0 +1,79 @@
from django.dispatch import receiver
from django.shortcuts import render
from websiteFunctions.signals import preDomain
from emACL import emACL
@receiver(preDomain)
def loadDomainHome(sender, **kwargs):
from websiteFunctions.models import Websites
from loginSystem.models import Administrator
from plogical.virtualHostUtilities import virtualHostUtilities
import subprocess, shlex
import plogical.CyberCPLogFileWriter as logging
from plogical.acl import ACLManager
request = kwargs['request']
domain = request.GET['domain']
userID = request.session['userID']
if Websites.objects.filter(domain=domain).exists():
currentACL = ACLManager.loadedACL(userID)
website = Websites.objects.get(domain=domain)
admin = Administrator.objects.get(pk=userID)
if ACLManager.checkOwnership(domain, admin, currentACL) == 1:
pass
else:
return ACLManager.loadError()
marketingStatus = emACL.checkIfEMEnabled(admin.userName)
Data = {}
Data['ftpTotal'] = website.package.ftpAccounts
Data['ftpUsed'] = website.users_set.all().count()
Data['databasesUsed'] = website.databases_set.all().count()
Data['databasesTotal'] = website.package.dataBases
Data['marketingStatus'] = marketingStatus
Data['domain'] = domain
diskUsageDetails = virtualHostUtilities.getDiskUsage("/home/" + domain, website.package.diskSpace)
try:
execPath = "sudo python " + virtualHostUtilities.cyberPanel + "/plogical/virtualHostUtilities.py"
execPath = execPath + " findDomainBW --virtualHostName " + domain + " --bandwidth " + str(
website.package.bandwidth)
output = subprocess.check_output(shlex.split(execPath))
bwData = output.split(",")
except BaseException, msg:
logging.CyberCPLogFileWriter.writeToFile(str(msg))
bwData = [0, 0]
## bw usage calculations
Data['bwInMBTotal'] = website.package.bandwidth
Data['bwInMB'] = bwData[0]
Data['bwUsage'] = bwData[1]
if diskUsageDetails != None:
if diskUsageDetails[1] > 100:
diskUsageDetails[1] = 100
Data['diskUsage'] = diskUsageDetails[1]
Data['diskInMB'] = diskUsageDetails[0]
Data['diskInMBTotal'] = website.package.diskSpace
else:
Data['diskUsage'] = 0
Data['diskInMB'] = 0
Data['diskInMBTotal'] = website.package.diskSpace
return render(request, 'emailMarketing/website.html', Data)
else:
return render(request, 'emailMarketing/website.html',
{"error": 1, "domain": "This domain does not exists."})

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,90 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Compose Email Message - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "Compose Email Message" %}</h2>
<p>{% trans "On this page you can compose email message to be sent out later." %}</p>
</div>
<div ng-controller="composeMessageCTRL" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Compose Email Message" %} <img ng-hide="cyberPanelLoading" src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
<form action="/" class="form-horizontal bordered-row">
<!---- Create Email Template --->
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Template Name" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="name" required>
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Email Subject" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="subject" required>
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "From Name" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="fromName" required>
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "From Email" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="fromEmail" required>
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Reply Email" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="replyTo" required>
</div>
</div>
<div ng-hide="request" class="form-group">
<div class="col-sm-12">
<textarea placeholder="Paste your email message, any format is accepted. (HTML or Plain)" ng-model="emailMessage" rows="15" class="form-control"></textarea>
</div>
</div>
<div ng-hide="installationProgress" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="saveTemplate()" class="btn btn-primary btn-lg btn-block">{% trans "Save Template" %}</button>
</div>
</div>
<!---- Create Email Template --->
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,75 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Create Email List - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div ng-controller="createEmailList" class="container">
<div id="page-title">
<h2>{% trans "Create Email List" %} - <span id="domainNamePage">{{ domain }}</span> </h2>
<p>{% trans "Create email list, to send out news letters and marketing emails." %}</p>
</div>
<div class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Create Email List" %} <img ng-hide="cyberPanelLoading" src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
<form action="/" id="createPackages" class="form-horizontal bordered-row">
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "List Name" %}</label>
<div class="col-sm-6">
<input name="pname" type="text" class="form-control" ng-model="listName" required>
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Path" %}</label>
<div class="col-sm-6">
<input placeholder="Path to emails file (.txt and .csv accepted)" type="text" class="form-control" ng-model="path" required>
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="createEmailList()" class="btn btn-primary btn-lg btn-block">{% trans "Create List" %}</button>
</div>
</div>
<div ng-hide="installationProgress" class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-7">
<div class="alert alert-success text-center">
<h2>{$ currentStatus $}</h2>
</div>
</div>
</div>
<div ng-hide="installationProgress" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-disabled="goBackDisable" ng-click="goBack()" class="btn btn-primary btn-lg btn-block">{% trans "Go Back" %}</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,72 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Email Marketing - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2 id="domainNamePage">{% trans "Email Marketing" %}</h2>
<p>{% trans "Select users to Enable/Disable Email Marketing feature!" %}</p>
</div>
<div ng-controller="emailMarketing" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Email Marketing" %} <img ng-hide="cyberPanelLoading" src="{% static 'images/loading.gif' %}">
</h3>
{% if installCheck == 0 %}
<div class="row">
<div class="col-md-12 text-center" style="margin-bottom: 2%;">
<h3>{% trans "Email Policy Server is not enabled " %}
<a href="{% url 'emailPolicyServer' %}">
<button class="btn btn-alt btn-hover btn-blue-alt">
<span>{% trans "Enable Now." %}</span>
<i class="glyph-icon icon-arrow-right"></i>
</button></a></h3>
</div>
</div>
{% else %}
<div class="example-box-wrapper">
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" id="datatable-example">
<thead>
<tr>
<th>{% trans 'ID' %}</th>
<th>{% trans 'Username' %}</th>
<th>{% trans 'Status' %}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="user in users track by $index">
<td ><code ng-bind="user.id"></code></td>
<td><code ng-bind="user.userName"></code></td>
<td>
<img style="margin-right: 4%;" ng-show="user.status==1" title="{% trans 'Email Marketing Enabled.' %}" src="{% static 'mailServer/vpsON.png' %}">
<button ng-click="enableDisableMarketing(0, user.userName)" ng-show="user.status==1" class="btn ra-100 btn-danger">{% trans 'Disable' %}</button>
<img style="margin-right: 4%;" ng-show="user.status==0" title="{% trans 'Email Marketing Disabled.' %}" src="{% static 'mailServer/vpsOff.png' %}">
<button ng-click="enableDisableMarketing(1, user.userName)" ng-show="user.status==0" class="btn ra-100 btn-success">{% trans 'Enable' %}</button>
</td>
</tr>
</tbody>
</table>
</div>
{% endif %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,190 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Manage Email Lists - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "Manage Email Lists" %} - <span id="domainNamePage">{{ domain }}</span></h2>
<p>{% trans "On this page you can manage your email lists (Delete, Verify, Add More Emails)." %}</p>
</div>
<div ng-controller="manageEmailLists" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Manage Email Lists" %} <img ng-hide="cyberPanelLoading" src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
<form action="/" class="form-horizontal bordered-row">
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Select List" %} </label>
<div class="col-sm-6">
<select ng-change="fetchEmails(1)" ng-model="listName" class="form-control">
{% for items in listNames %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div ng-hide="currentRecords" class="form-group">
<label class="col-sm-1 control-label"></label>
<div class="col-sm-3">
<button data-toggle="modal" data-target="#deleteList" class="btn ra-100 btn-danger">{% trans 'Delete This List' %}</button>
<!--- Delete Pool --->
<div class="modal fade" id="deleteList" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{% trans "You are doing to delete this list.." %} <img ng-hide="cyberPanelLoading" src="{% static 'images/loading.gif' %}"></h4>
</div>
<div class="modal-body">
<p>{% trans 'Are you sure?' %}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans 'Close' %}</button>
<button data-dismiss="modal" ng-click="deleteList()" type="button" class="btn btn-primary">{% trans 'Confirm' %}</button>
</div>
</div>
</div>
</div>
<!--- Delete Pool --->
</div>
<div class="col-sm-3">
<button ng-disabled="verificationButton" ng-click="startVerification()" class="btn ra-100 btn-blue-alt">{% trans 'Verify This List' %}</button>
</div>
<div class="col-sm-3">
<button ng-click="showAddEmails()" class="btn ra-100 btn-blue-alt">{% trans 'Add More Emails' %}</button>
</div>
</div>
<!---- Create Email List --->
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Path" %}</label>
<div class="col-sm-6">
<input placeholder="Path to emails file (.txt and .csv accepted)" type="text" class="form-control" ng-model="path" required>
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="createEmailList()" class="btn btn-primary btn-lg btn-block">{% trans "Load Emails" %}</button>
</div>
</div>
<div ng-hide="installationProgress" class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-7">
<div class="alert alert-success text-center">
<h2>{$ currentStatus $}</h2>
</div>
</div>
</div>
<div ng-hide="installationProgress" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-disabled="goBackDisable" ng-click="goBack()" class="btn btn-primary btn-lg btn-block">{% trans "Go Back" %}</button>
</div>
</div>
<!---- Create Email List --->
<!---- Email List Verification --->
<div ng-hide="verificationStatus" class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-7">
<div class="alert alert-success text-center">
<h2>{$ currentStatusVerification $}</h2>
</div>
</div>
</div>
<!---- Create Email List --->
<!------ List of records --------------->
<div ng-hide="currentRecords" class="form-group">
<div class="col-sm-10">
<input placeholder="Search Emails..." ng-model="searchEmails" name="dom" type="text" class="form-control" ng-model="domainNameCreate" required>
</div>
<div style="margin-bottom: 1%;" class="col-sm-2">
<select ng-change="fetchRecords()" ng-model="recordstoShow" class="form-control">
<option>10</option>
<option>50</option>
<option>100</option>
</select>
</div>
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th>{% trans "ID" %}</th>
<th>{% trans "email" %}</th>
<th>{% trans "Verification Status" %}</th>
<th>{% trans "Date Created" %}</th>
<th>{% trans "Actions" %}</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="record in records | filter:searchEmails">
<td ng-bind="record.id"></td>
<td ng-bind="record.email"></td>
<td ng-bind="record.verificationStatus"></td>
<td ng-bind="record.dateCreated"></td>
<td >
<button type="button" ng-click="deleteEmail(record.id)" class="btn ra-100 btn-purple">{% trans "Delete" %}</button>
</td>
</tr>
</tbody>
</table>
<div class="row">
<div class="col-sm-4 col-sm-offset-8">
<nav aria-label="Page navigation">
<ul class="pagination">
<li ng-click="fetchEmails(page)" ng-repeat="page in pagination"><a href="">{$ page $}</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<!------ List of records --------------->
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,126 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Manage SMTP Hosts - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "Manage SMTP Hosts" %}</h2>
<p>{% trans "On this page you can manage STMP Host. (SMTP hosts are used to send emails)" %}</p>
</div>
<div ng-controller="manageSMTPHostsCTRL" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Manage SMTP Hosts" %} <img ng-hide="cyberPanelLoading" src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
<form action="/" class="form-horizontal bordered-row">
<!---- Create SMTP Host --->
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "SMTP Host" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="smtpHost" required>
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Port" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="smtpPort" required>
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Username" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" ng-model="smtpUserName" required>
</div>
</div>
<div ng-hide="installationDetailsForm" class="form-group">
<label class="col-sm-3 control-label">{% trans "Password" %}</label>
<div class="col-sm-6">
<input type="password" class="form-control" ng-model="smtpPassword" required>
</div>
</div>
<div ng-hide="installationProgress" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="saveSMTPHost()" class="btn btn-primary btn-lg btn-block">{% trans "Save Host" %}</button>
</div>
</div>
<!---- Create SMTP Host --->
<!------ List of records --------------->
<div ng-hide="currentRecords" class="form-group">
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th>{% trans "ID" %}</th>
<th>{% trans "Owner" %}</th>
<th>{% trans "Host" %}</th>
<th>{% trans "Port" %}</th>
<th>{% trans "Username" %}</th>
<th>{% trans "Actions" %}</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="record in records | filter:searchEmails">
<td ng-bind="record.id"></td>
<td ng-bind="record.owner"></td>
<td ng-bind="record.host"></td>
<td ng-bind="record.port"></td>
<td ng-bind="record.userName"></td>
<td >
<button type="button" ng-click="smtpHostOperations('verify', record.id)" class="btn ra-100 btn-purple">{% trans "Verify Host" %}</button>
<button type="button" ng-click="smtpHostOperations('delete', record.id)" class="btn ra-100 btn-purple">{% trans "Delete" %}</button>
</td>
</tr>
</tbody>
</table>
<div class="row">
<div class="col-sm-4 col-sm-offset-8">
<nav aria-label="Page navigation">
<ul class="pagination">
<li ng-click="fetchEmails(page)" ng-repeat="page in pagination"><a href="">{$ page $}</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<!------ List of records --------------->
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,204 @@
{% extends "baseTemplate/index.html" %}
{% load i18n %}
{% block title %}{% trans "Send Emails - CyberPanel" %}{% endblock %}
{% block content %}
{% load static %}
{% get_current_language as LANGUAGE_CODE %}
<!-- Current language: {{ LANGUAGE_CODE }} -->
<div class="container">
<div id="page-title">
<h2>{% trans "Send Emails" %}</h2>
<p>{% trans "On this page you can send emails to the lists you created using SMTP Hosts." %}</p>
</div>
<div ng-controller="sendEmailsCTRL" class="panel">
<div class="panel-body">
<h3 class="title-hero">
{% trans "Send Emails" %} <img ng-hide="cyberPanelLoading" src="{% static 'images/loading.gif' %}">
</h3>
<div class="example-box-wrapper">
<form action="/" class="form-horizontal bordered-row">
<div class="form-group">
<label class="col-sm-3 control-label">{% trans "Select Template" %} </label>
<div class="col-sm-6">
<select ng-change="templateSelected()" ng-model="selectedTemplate" class="form-control">
{% for items in templateNames %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div ng-hide="availableFunctions" class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-3">
<button type="button" ng-disabled="deleteTemplateBTN" data-toggle="modal" data-target="#deleteTemplate" class="btn ra-100 btn-danger">{% trans 'Delete This Template' %}</button>
<!--- Delete Template --->
<div class="modal fade" id="deleteTemplate" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{% trans "You are doing to delete this template.." %} <img ng-hide="cyberPanelLoading" src="{% static 'images/loading.gif' %}"></h4>
</div>
<div class="modal-body">
<p>{% trans 'Are you sure?' %}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{% trans 'Close' %}</button>
<button data-dismiss="modal" ng-click="deleteTemplate()" type="button" class="btn btn-primary">{% trans 'Confirm' %}</button>
</div>
</div>
</div>
</div>
<!--- Delete Template --->
</div>
<div class="col-sm-3">
<a target="_blank" href="{$ previewLink $}"><button type="button" class="btn ra-100 btn-blue-alt">{% trans 'Preview Template' %}</button></a>
</div>
<div class="col-sm-3">
<button ng-disabled="sendEmailBTN" type="button" ng-click="sendEmails()" class="btn ra-100 btn-blue-alt">{% trans 'Send Emails' %}</button>
</div>
</div>
<div ng-hide="sendEmailsView" class="form-group">
<label class="col-sm-3 control-label">{% trans "Select List" %} </label>
<div class="col-sm-6">
<select ng-model="listName" class="form-control">
{% for items in listNames %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div ng-hide="sendEmailsView" class="form-group">
<label class="col-sm-3 control-label">{% trans "Select STMP Host" %} </label>
<div class="col-sm-6">
<select ng-model="host" class="form-control">
{% for items in hostNames %}
<option>{{ items }}</option>
{% endfor %}
</select>
</div>
</div>
<div ng-hide="sendEmailsView" class="form-group">
<label class="col-sm-3 control-label">{% trans "" %}</label>
<div class="col-sm-9">
<div class="checkbox">
<label>
<input ng-model="verificationCheck" type="checkbox" value="">
{% trans 'Send to un-verified email addresses.' %}
</label>
</div>
</div>
<label class="col-sm-3 control-label"></label>
<div class="col-sm-9">
<div class="checkbox">
<label>
<input ng-model="unsubscribeCheck" type="checkbox" value="">
{% trans 'Include unsubscribe link.' %}
</label>
</div>
</div>
</div>
<div ng-hide="sendEmailsView" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-click="startEmailJob()" class="btn btn-primary btn-lg btn-block">{% trans "Start Job" %}</button>
</div>
</div>
<!---- Email Job Status --->
<div ng-hide="jobStatus" class="form-group">
<label class="col-sm-2 control-label"></label>
<div class="col-sm-7">
<div class="alert alert-success text-center">
<h2>{$ currentStatus $}</h2>
</div>
</div>
</div>
<div ng-hide="jobStatus" class="form-group">
<label class="col-sm-3 control-label"></label>
<div class="col-sm-4">
<button type="button" ng-disabled="goBackDisable" ng-click="goBack()" class="btn btn-primary btn-lg btn-block">{% trans "Go Back" %}</button>
</div>
</div>
<!---- Email Job Status --->
<!------ List of records --------------->
<div ng-hide="sendEmailsView" class="form-group">
<div class="col-sm-12">
<table class="table">
<thead>
<tr>
<th>{% trans "Job ID" %}</th>
<th>{% trans "Date" %}</th>
<th>{% trans "SMTP Host" %}</th>
<th>{% trans "Total Emails" %}</th>
<th>{% trans "Sent" %}</th>
<th>{% trans "Failed" %}</th>
<th>{% trans "Actions" %}</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="record in records | filter:searchEmails">
<td ng-bind="record.id"></td>
<td ng-bind="record.date"></td>
<td ng-bind="record.host"></td>
<td ng-bind="record.totalEmails"></td>
<td ng-bind="record.sent"></td>
<td ng-bind="record.failed"></td>
<td >
<button type="button" ng-click="deleteJob(record.id)" class="btn ra-100 btn-purple">{% trans "Delete" %}</button>
</td>
</tr>
</tbody>
</table>
<div class="row">
<div class="col-sm-4 col-sm-offset-8">
<nav aria-label="Page navigation">
<ul class="pagination">
<li ng-click="fetchEmails(page)" ng-repeat="page in pagination"><a href="">{$ page $}</a></li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<!------ List of records --------------->
</form>
</div>
</div>
</div>
</div>
{% endblock %}

File diff suppressed because it is too large Load Diff

6
emailMarketing/tests.py Normal file
View File

@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.test import TestCase
# Create your tests here.

26
emailMarketing/urls.py Normal file
View File

@@ -0,0 +1,26 @@
from django.conf.urls import url
import views
urlpatterns = [
url(r'^$', views.emailMarketing, name='emailMarketing'),
url(r'^fetchUsers$', views.fetchUsers, name='fetchUsers'),
url(r'^enableDisableMarketing$', views.enableDisableMarketing, name='enableDisableMarketing'),
url(r'^(?P<domain>([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?)/emailLists$', views.createEmailList, name='createEmailList'),
url(r'^submitEmailList$', views.submitEmailList, name='submitEmailList'),
url(r'^(?P<domain>([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?)/manageLists$', views.manageLists, name='manageLists'),
url(r'^(?P<domain>([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?)/manageSMTP$', views.manageSMTP, name='manageSMTP'),
url(r'^fetchEmails$', views.fetchEmails, name='fetchEmails'),
url(r'^deleteList$', views.deleteList, name='deleteList'),
url(r'^emailVerificationJob$', views.emailVerificationJob, name='emailVerificationJob'),
url(r'^deleteEmail$', views.deleteEmail, name='deleteEmail'),
url(r'^saveSMTPHost$', views.saveSMTPHost, name='saveSMTPHost'),
url(r'^fetchSMTPHosts$', views.fetchSMTPHosts, name='fetchSMTPHosts'),
url(r'^smtpHostOperations$', views.smtpHostOperations, name='smtpHostOperations'),
url(r'^composeEmailMessage$', views.composeEmailMessage, name='composeEmailMessage'),
url(r'^saveEmailTemplate$', views.saveEmailTemplate, name='saveEmailTemplate'),
url(r'^sendEmails$', views.sendEmails, name='sendEmails'),
url(r'^preview/(?P<templateName>[-\w]+)/$', views.templatePreview, name='templatePreview'),
url(r'^fetchJobs$', views.fetchJobs, name='fetchJobs'),
url(r'^startEmailJob$', views.startEmailJob, name='startEmailJob'),
url(r'^deleteTemplate$', views.deleteTemplate, name='deleteTemplate'),
url(r'^deleteJob$', views.deleteJob, name='deleteJob'),
]

183
emailMarketing/views.py Normal file
View File

@@ -0,0 +1,183 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import redirect
from loginSystem.views import loadLoginPage
from emailMarketingManager import EmailMarketingManager
# Create your views here.
def emailMarketing(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.emailMarketing()
except KeyError:
return redirect(loadLoginPage)
def fetchUsers(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.fetchUsers()
except KeyError:
return redirect(loadLoginPage)
def enableDisableMarketing(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.enableDisableMarketing()
except KeyError:
return redirect(loadLoginPage)
def createEmailList(request, domain):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request, domain)
return emm.createEmailList()
except KeyError:
return redirect(loadLoginPage)
def submitEmailList(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.submitEmailList()
except KeyError:
return redirect(loadLoginPage)
def manageLists(request, domain):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request, domain)
return emm.manageLists()
except KeyError:
return redirect(loadLoginPage)
def fetchEmails(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.fetchEmails()
except KeyError:
return redirect(loadLoginPage)
def deleteList(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.deleteList()
except KeyError:
return redirect(loadLoginPage)
def emailVerificationJob(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.emailVerificationJob()
except KeyError:
return redirect(loadLoginPage)
def deleteEmail(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.deleteEmail()
except KeyError:
return redirect(loadLoginPage)
def manageSMTP(request, domain):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request, domain)
return emm.manageSMTP()
except KeyError:
return redirect(loadLoginPage)
def saveSMTPHost(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.saveSMTPHost()
except KeyError:
return redirect(loadLoginPage)
def fetchSMTPHosts(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.fetchSMTPHosts()
except KeyError:
return redirect(loadLoginPage)
def smtpHostOperations(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.smtpHostOperations()
except KeyError:
return redirect(loadLoginPage)
def composeEmailMessage(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.composeEmailMessage()
except KeyError:
return redirect(loadLoginPage)
def saveEmailTemplate(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.saveEmailTemplate()
except KeyError:
return redirect(loadLoginPage)
def sendEmails(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.sendEmails()
except KeyError:
return redirect(loadLoginPage)
def templatePreview(request, templateName):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request, templateName)
return emm.templatePreview()
except KeyError:
return redirect(loadLoginPage)
def fetchJobs(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.fetchJobs()
except KeyError:
return redirect(loadLoginPage)
def startEmailJob(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.startEmailJob()
except KeyError:
return redirect(loadLoginPage)
def deleteTemplate(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.deleteTemplate()
except KeyError:
return redirect(loadLoginPage)
def deleteJob(request):
try:
userID = request.session['userID']
emm = EmailMarketingManager(request)
return emm.deleteJob()
except KeyError:
return redirect(loadLoginPage)

View File

@@ -687,8 +687,8 @@ class preFlightsChecks:
count = 0
while (1):
command = "wget http://cyberpanel.net/CyberPanel.1.7.2.tar.gz"
#command = "wget http://cyberpanel.net/CyberPanelTemp.tar.gz"
#command = "wget http://cyberpanel.net/CyberPanel.1.7.2.tar.gz"
command = "wget http://cyberpanel.net/CyberPanelTemp.tar.gz"
res = subprocess.call(shlex.split(command))
if res == 1:
@@ -707,8 +707,8 @@ class preFlightsChecks:
count = 0
while(1):
command = "tar zxf CyberPanel.1.7.2.tar.gz"
#command = "tar zxf CyberPanelTemp.tar.gz"
#command = "tar zxf CyberPanel.1.7.2.tar.gz"
command = "tar zxf CyberPanelTemp.tar.gz"
res = subprocess.call(shlex.split(command))
@@ -2582,6 +2582,29 @@ class preFlightsChecks:
logging.InstallLog.writeToFile(str(msg) + " [installTLDExtract]")
return 0
def installPYDNS(self):
try:
count = 0
while (1):
command = "pip install pydns"
res = subprocess.call(shlex.split(command))
if res == 1:
count = count + 1
preFlightsChecks.stdOut(
"Trying to install pydns, trying again, try number: " + str(count))
if count == 3:
logging.InstallLog.writeToFile(
"Failed to install pydns! [installTLDExtract]")
else:
logging.InstallLog.writeToFile("pydns successfully installed! [pip]")
preFlightsChecks.stdOut("pydns successfully installed! [pip]")
break
except OSError, msg:
logging.InstallLog.writeToFile(str(msg) + " [installTLDExtract]")
return 0
def installOpenDKIM(self):
try:
count = 0
@@ -3003,6 +3026,7 @@ def main():
checks.installCertBot()
checks.test_Requests()
checks.installPYDNS()
checks.download_install_CyberPanel(installCyberPanel.InstallCyberPanel.mysqlPassword, mysql)
checks.setupCLI()
checks.setup_cron()

View File

@@ -1495,6 +1495,8 @@ class WebsiteManager:
lastLine = statusData[-1]
if lastLine.find('[200]') > -1:
command = 'sudo rm -f ' + statusFile
subprocess.call(shlex.split(command))
data_ret = {'abort': 1, 'installStatus': 1, 'installationProgress': "100",
'currentStatus': 'Successfully Installed.'}
json_data = json.dumps(data_ret)
@@ -1507,7 +1509,10 @@ class WebsiteManager:
else:
progress = lastLine.split(',')
currentStatus = progress[0]
try:
installationProgress = progress[1]
except:
installationProgress = 0
data_ret = {'abort': 0, 'installStatus': 0, 'installationProgress': installationProgress,
'currentStatus': currentStatus}
json_data = json.dumps(data_ret)

View File

@@ -35,6 +35,7 @@ psutil==5.4.3
ptyprocess==0.6.0
pycparser==2.18
pycurl==7.19.0
pydns==2.3.6
pygpgme==0.3
pyliblzma==0.5.3
pyOpenSSL==17.5.0

View File

@@ -51,6 +51,14 @@ class pluginManager:
def postWebsiteModification(request, response):
return pluginManagerGlobal.globalPlug(request, postWebsiteModification, response)
@staticmethod
def preDomain(request):
return pluginManagerGlobal.globalPlug(request, preDomain)
@staticmethod
def postDomain(request, response):
return pluginManagerGlobal.globalPlug(request, postDomain, response)
@staticmethod
def preSaveConfigsToFile(request):
return pluginManagerGlobal.globalPlug(request, preSaveConfigsToFile)

View File

@@ -39,6 +39,13 @@ preWebsiteModification = Signal(providing_args=["request"])
## This event is fired after CyberPanel core finished suspension of website
postWebsiteModification = Signal(providing_args=["request", "response"])
## This event is fired before CyberPanel core load website launcher
preDomain = Signal(providing_args=["request"])
## This event is fired after CyberPanel core finished loading website launcher
postDomain = Signal(providing_args=["request", "response"])
## This event is fired before CyberPanel core start saving changes to vhost conf
preSaveConfigsToFile = Signal(providing_args=["request"])

View File

@@ -211,9 +211,23 @@ def saveWebsiteChanges(request):
def domain(request, domain):
try:
if not request.GET._mutable:
request.GET._mutable = True
request.GET['domain'] = domain
result = pluginManager.preDomain(request)
if result != 200:
return result
userID = request.session['userID']
wm = WebsiteManager(domain)
return wm.loadDomainHome(request, userID)
coreResult = wm.loadDomainHome(request, userID)
result = pluginManager.postDomain(request, coreResult)
if result != 200:
return result
return coreResult
except KeyError:
return redirect(loadLoginPage)