mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-07 13:56:01 +01:00
Email Marketing as a plugin
This commit is contained in:
@@ -61,6 +61,7 @@ INSTALLED_APPS = [
|
|||||||
'manageServices',
|
'manageServices',
|
||||||
'pluginHolder',
|
'pluginHolder',
|
||||||
'emailPremium',
|
'emailPremium',
|
||||||
|
'emailMarketing',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
|
|||||||
@@ -38,4 +38,5 @@ urlpatterns = [
|
|||||||
url(r'^emailPremium/',include('emailPremium.urls')),
|
url(r'^emailPremium/',include('emailPremium.urls')),
|
||||||
url(r'^manageservices/',include('manageServices.urls')),
|
url(r'^manageservices/',include('manageServices.urls')),
|
||||||
url(r'^plugins/',include('pluginHolder.urls')),
|
url(r'^plugins/',include('pluginHolder.urls')),
|
||||||
|
url(r'^emailMarketing/', include('emailMarketing.urls')),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -624,6 +624,7 @@
|
|||||||
<script src="{% static 'mailServer/mailServer.js' %}"></script>
|
<script src="{% static 'mailServer/mailServer.js' %}"></script>
|
||||||
<script src="{% static 'serverLogs/serverLogs.js' %}"></script>
|
<script src="{% static 'serverLogs/serverLogs.js' %}"></script>
|
||||||
<script src="{% static 'emailPremium/emailPremium.js' %}"></script>
|
<script src="{% static 'emailPremium/emailPremium.js' %}"></script>
|
||||||
|
<script src="{% static 'emailMarketing/emailMarketing.js' %}"></script>
|
||||||
|
|
||||||
<!-- PieGage charts -->
|
<!-- PieGage charts -->
|
||||||
|
|
||||||
|
|||||||
1
emailMarketing/__init__.py
Normal file
1
emailMarketing/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
default_app_config = 'emailMarketing.apps.EmailmarketingConfig'
|
||||||
6
emailMarketing/admin.py
Normal file
6
emailMarketing/admin.py
Normal 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
10
emailMarketing/apps.py
Normal 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
66
emailMarketing/emACL.py
Normal 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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
212
emailMarketing/emailMarketing.py
Normal file
212
emailMarketing/emailMarketing.py
Normal 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
|
||||||
733
emailMarketing/emailMarketingManager.py
Normal file
733
emailMarketing/emailMarketingManager.py
Normal 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
7
emailMarketing/meta.xml
Normal 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>
|
||||||
0
emailMarketing/migrations/__init__.py
Normal file
0
emailMarketing/migrations/__init__.py
Normal file
51
emailMarketing/models.py
Normal file
51
emailMarketing/models.py
Normal 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
79
emailMarketing/signals.py
Normal 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."})
|
||||||
BIN
emailMarketing/static/emailMarketing/checklist.png
Normal file
BIN
emailMarketing/static/emailMarketing/checklist.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
BIN
emailMarketing/static/emailMarketing/compose.png
Normal file
BIN
emailMarketing/static/emailMarketing/compose.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
1323
emailMarketing/static/emailMarketing/emailMarketing.js
Normal file
1323
emailMarketing/static/emailMarketing/emailMarketing.js
Normal file
File diff suppressed because it is too large
Load Diff
BIN
emailMarketing/static/emailMarketing/mailing.png
Normal file
BIN
emailMarketing/static/emailMarketing/mailing.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
BIN
emailMarketing/static/emailMarketing/paper-plane.png
Normal file
BIN
emailMarketing/static/emailMarketing/paper-plane.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
BIN
emailMarketing/static/emailMarketing/post-office.png
Normal file
BIN
emailMarketing/static/emailMarketing/post-office.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
90
emailMarketing/templates/emailMarketing/composeMessages.html
Normal file
90
emailMarketing/templates/emailMarketing/composeMessages.html
Normal 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 %}
|
||||||
75
emailMarketing/templates/emailMarketing/createEmailList.html
Normal file
75
emailMarketing/templates/emailMarketing/createEmailList.html
Normal 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 %}
|
||||||
|
|
||||||
72
emailMarketing/templates/emailMarketing/emailMarketing.html
Normal file
72
emailMarketing/templates/emailMarketing/emailMarketing.html
Normal 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 %}
|
||||||
190
emailMarketing/templates/emailMarketing/manageLists.html
Normal file
190
emailMarketing/templates/emailMarketing/manageLists.html
Normal 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">×</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 %}
|
||||||
126
emailMarketing/templates/emailMarketing/manageSMTPHosts.html
Normal file
126
emailMarketing/templates/emailMarketing/manageSMTPHosts.html
Normal 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 %}
|
||||||
204
emailMarketing/templates/emailMarketing/sendEmails.html
Normal file
204
emailMarketing/templates/emailMarketing/sendEmails.html
Normal 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">×</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 %}
|
||||||
1097
emailMarketing/templates/emailMarketing/website.html
Normal file
1097
emailMarketing/templates/emailMarketing/website.html
Normal file
File diff suppressed because it is too large
Load Diff
6
emailMarketing/tests.py
Normal file
6
emailMarketing/tests.py
Normal 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
26
emailMarketing/urls.py
Normal 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
183
emailMarketing/views.py
Normal 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)
|
||||||
@@ -687,8 +687,8 @@ class preFlightsChecks:
|
|||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
while (1):
|
while (1):
|
||||||
command = "wget http://cyberpanel.net/CyberPanel.1.7.2.tar.gz"
|
#command = "wget http://cyberpanel.net/CyberPanel.1.7.2.tar.gz"
|
||||||
#command = "wget http://cyberpanel.net/CyberPanelTemp.tar.gz"
|
command = "wget http://cyberpanel.net/CyberPanelTemp.tar.gz"
|
||||||
res = subprocess.call(shlex.split(command))
|
res = subprocess.call(shlex.split(command))
|
||||||
|
|
||||||
if res == 1:
|
if res == 1:
|
||||||
@@ -707,8 +707,8 @@ class preFlightsChecks:
|
|||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
while(1):
|
while(1):
|
||||||
command = "tar zxf CyberPanel.1.7.2.tar.gz"
|
#command = "tar zxf CyberPanel.1.7.2.tar.gz"
|
||||||
#command = "tar zxf CyberPanelTemp.tar.gz"
|
command = "tar zxf CyberPanelTemp.tar.gz"
|
||||||
|
|
||||||
res = subprocess.call(shlex.split(command))
|
res = subprocess.call(shlex.split(command))
|
||||||
|
|
||||||
@@ -2582,6 +2582,29 @@ class preFlightsChecks:
|
|||||||
logging.InstallLog.writeToFile(str(msg) + " [installTLDExtract]")
|
logging.InstallLog.writeToFile(str(msg) + " [installTLDExtract]")
|
||||||
return 0
|
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):
|
def installOpenDKIM(self):
|
||||||
try:
|
try:
|
||||||
count = 0
|
count = 0
|
||||||
@@ -3003,6 +3026,7 @@ def main():
|
|||||||
|
|
||||||
checks.installCertBot()
|
checks.installCertBot()
|
||||||
checks.test_Requests()
|
checks.test_Requests()
|
||||||
|
checks.installPYDNS()
|
||||||
checks.download_install_CyberPanel(installCyberPanel.InstallCyberPanel.mysqlPassword, mysql)
|
checks.download_install_CyberPanel(installCyberPanel.InstallCyberPanel.mysqlPassword, mysql)
|
||||||
checks.setupCLI()
|
checks.setupCLI()
|
||||||
checks.setup_cron()
|
checks.setup_cron()
|
||||||
|
|||||||
@@ -1495,6 +1495,8 @@ class WebsiteManager:
|
|||||||
lastLine = statusData[-1]
|
lastLine = statusData[-1]
|
||||||
|
|
||||||
if lastLine.find('[200]') > -1:
|
if lastLine.find('[200]') > -1:
|
||||||
|
command = 'sudo rm -f ' + statusFile
|
||||||
|
subprocess.call(shlex.split(command))
|
||||||
data_ret = {'abort': 1, 'installStatus': 1, 'installationProgress': "100",
|
data_ret = {'abort': 1, 'installStatus': 1, 'installationProgress': "100",
|
||||||
'currentStatus': 'Successfully Installed.'}
|
'currentStatus': 'Successfully Installed.'}
|
||||||
json_data = json.dumps(data_ret)
|
json_data = json.dumps(data_ret)
|
||||||
@@ -1507,7 +1509,10 @@ class WebsiteManager:
|
|||||||
else:
|
else:
|
||||||
progress = lastLine.split(',')
|
progress = lastLine.split(',')
|
||||||
currentStatus = progress[0]
|
currentStatus = progress[0]
|
||||||
|
try:
|
||||||
installationProgress = progress[1]
|
installationProgress = progress[1]
|
||||||
|
except:
|
||||||
|
installationProgress = 0
|
||||||
data_ret = {'abort': 0, 'installStatus': 0, 'installationProgress': installationProgress,
|
data_ret = {'abort': 0, 'installStatus': 0, 'installationProgress': installationProgress,
|
||||||
'currentStatus': currentStatus}
|
'currentStatus': currentStatus}
|
||||||
json_data = json.dumps(data_ret)
|
json_data = json.dumps(data_ret)
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ psutil==5.4.3
|
|||||||
ptyprocess==0.6.0
|
ptyprocess==0.6.0
|
||||||
pycparser==2.18
|
pycparser==2.18
|
||||||
pycurl==7.19.0
|
pycurl==7.19.0
|
||||||
|
pydns==2.3.6
|
||||||
pygpgme==0.3
|
pygpgme==0.3
|
||||||
pyliblzma==0.5.3
|
pyliblzma==0.5.3
|
||||||
pyOpenSSL==17.5.0
|
pyOpenSSL==17.5.0
|
||||||
|
|||||||
@@ -51,6 +51,14 @@ class pluginManager:
|
|||||||
def postWebsiteModification(request, response):
|
def postWebsiteModification(request, response):
|
||||||
return pluginManagerGlobal.globalPlug(request, postWebsiteModification, 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
|
@staticmethod
|
||||||
def preSaveConfigsToFile(request):
|
def preSaveConfigsToFile(request):
|
||||||
return pluginManagerGlobal.globalPlug(request, preSaveConfigsToFile)
|
return pluginManagerGlobal.globalPlug(request, preSaveConfigsToFile)
|
||||||
|
|||||||
@@ -39,6 +39,13 @@ preWebsiteModification = Signal(providing_args=["request"])
|
|||||||
## This event is fired after CyberPanel core finished suspension of website
|
## This event is fired after CyberPanel core finished suspension of website
|
||||||
postWebsiteModification = Signal(providing_args=["request", "response"])
|
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
|
## This event is fired before CyberPanel core start saving changes to vhost conf
|
||||||
preSaveConfigsToFile = Signal(providing_args=["request"])
|
preSaveConfigsToFile = Signal(providing_args=["request"])
|
||||||
|
|
||||||
|
|||||||
@@ -211,9 +211,23 @@ def saveWebsiteChanges(request):
|
|||||||
def domain(request, domain):
|
def domain(request, domain):
|
||||||
try:
|
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']
|
userID = request.session['userID']
|
||||||
wm = WebsiteManager(domain)
|
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:
|
except KeyError:
|
||||||
return redirect(loadLoginPage)
|
return redirect(loadLoginPage)
|
||||||
|
|||||||
Reference in New Issue
Block a user