From 001f762d9df18c9aad4b9f11282847c4dd2ca41f Mon Sep 17 00:00:00 2001 From: usmannasir <01-134132-158@student.bahria.edu.pk> Date: Wed, 17 Oct 2018 23:20:02 +0500 Subject: [PATCH] Email Marketing as a plugin --- CyberCP/settings.py | 1 + CyberCP/urls.py | 1 + .../templates/baseTemplate/index.html | 1 + emailMarketing/__init__.py | 1 + emailMarketing/admin.py | 6 + emailMarketing/apps.py | 10 + emailMarketing/emACL.py | 66 + emailMarketing/emailMarketing.py | 212 +++ emailMarketing/emailMarketingManager.py | 733 +++++++++ emailMarketing/meta.xml | 7 + emailMarketing/migrations/__init__.py | 0 emailMarketing/models.py | 51 + emailMarketing/signals.py | 79 + .../static/emailMarketing/checklist.png | Bin 0 -> 2961 bytes .../static/emailMarketing/compose.png | Bin 0 -> 2557 bytes .../static/emailMarketing/emailMarketing.js | 1323 +++++++++++++++++ .../static/emailMarketing/mailing.png | Bin 0 -> 2124 bytes .../static/emailMarketing/paper-plane.png | Bin 0 -> 3260 bytes .../static/emailMarketing/post-office.png | Bin 0 -> 2511 bytes .../emailMarketing/composeMessages.html | 90 ++ .../emailMarketing/createEmailList.html | 75 + .../emailMarketing/emailMarketing.html | 72 + .../templates/emailMarketing/manageLists.html | 190 +++ .../emailMarketing/manageSMTPHosts.html | 126 ++ .../templates/emailMarketing/sendEmails.html | 204 +++ .../templates/emailMarketing/website.html | 1097 ++++++++++++++ emailMarketing/tests.py | 6 + emailMarketing/urls.py | 26 + emailMarketing/views.py | 183 +++ install/install.py | 32 +- plogical/website.py | 7 +- requirments.txt | 1 + websiteFunctions/pluginManager.py | 8 + websiteFunctions/signals.py | 7 + websiteFunctions/views.py | 16 +- 35 files changed, 4625 insertions(+), 6 deletions(-) create mode 100644 emailMarketing/__init__.py create mode 100644 emailMarketing/admin.py create mode 100644 emailMarketing/apps.py create mode 100644 emailMarketing/emACL.py create mode 100644 emailMarketing/emailMarketing.py create mode 100644 emailMarketing/emailMarketingManager.py create mode 100644 emailMarketing/meta.xml create mode 100644 emailMarketing/migrations/__init__.py create mode 100644 emailMarketing/models.py create mode 100644 emailMarketing/signals.py create mode 100644 emailMarketing/static/emailMarketing/checklist.png create mode 100644 emailMarketing/static/emailMarketing/compose.png create mode 100644 emailMarketing/static/emailMarketing/emailMarketing.js create mode 100644 emailMarketing/static/emailMarketing/mailing.png create mode 100644 emailMarketing/static/emailMarketing/paper-plane.png create mode 100644 emailMarketing/static/emailMarketing/post-office.png create mode 100644 emailMarketing/templates/emailMarketing/composeMessages.html create mode 100644 emailMarketing/templates/emailMarketing/createEmailList.html create mode 100644 emailMarketing/templates/emailMarketing/emailMarketing.html create mode 100644 emailMarketing/templates/emailMarketing/manageLists.html create mode 100644 emailMarketing/templates/emailMarketing/manageSMTPHosts.html create mode 100644 emailMarketing/templates/emailMarketing/sendEmails.html create mode 100644 emailMarketing/templates/emailMarketing/website.html create mode 100644 emailMarketing/tests.py create mode 100644 emailMarketing/urls.py create mode 100644 emailMarketing/views.py diff --git a/CyberCP/settings.py b/CyberCP/settings.py index 6114fe32e..ca3aabb5d 100644 --- a/CyberCP/settings.py +++ b/CyberCP/settings.py @@ -61,6 +61,7 @@ INSTALLED_APPS = [ 'manageServices', 'pluginHolder', 'emailPremium', + 'emailMarketing', ] MIDDLEWARE = [ diff --git a/CyberCP/urls.py b/CyberCP/urls.py index b6d2dc005..eb30b90d0 100644 --- a/CyberCP/urls.py +++ b/CyberCP/urls.py @@ -38,4 +38,5 @@ urlpatterns = [ url(r'^emailPremium/',include('emailPremium.urls')), url(r'^manageservices/',include('manageServices.urls')), url(r'^plugins/',include('pluginHolder.urls')), + url(r'^emailMarketing/', include('emailMarketing.urls')), ] diff --git a/baseTemplate/templates/baseTemplate/index.html b/baseTemplate/templates/baseTemplate/index.html index 0a5ebaa97..a46330835 100755 --- a/baseTemplate/templates/baseTemplate/index.html +++ b/baseTemplate/templates/baseTemplate/index.html @@ -624,6 +624,7 @@ + diff --git a/emailMarketing/__init__.py b/emailMarketing/__init__.py new file mode 100644 index 000000000..d33aad86a --- /dev/null +++ b/emailMarketing/__init__.py @@ -0,0 +1 @@ +default_app_config = 'emailMarketing.apps.EmailmarketingConfig' \ No newline at end of file diff --git a/emailMarketing/admin.py b/emailMarketing/admin.py new file mode 100644 index 000000000..13be29d96 --- /dev/null +++ b/emailMarketing/admin.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.contrib import admin + +# Register your models here. diff --git a/emailMarketing/apps.py b/emailMarketing/apps.py new file mode 100644 index 000000000..dafe02fc4 --- /dev/null +++ b/emailMarketing/apps.py @@ -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 diff --git a/emailMarketing/emACL.py b/emailMarketing/emACL.py new file mode 100644 index 000000000..e68571c8f --- /dev/null +++ b/emailMarketing/emACL.py @@ -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 + + + diff --git a/emailMarketing/emailMarketing.py b/emailMarketing/emailMarketing.py new file mode 100644 index 000000000..ff6485d06 --- /dev/null +++ b/emailMarketing/emailMarketing.py @@ -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('', 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 \ No newline at end of file diff --git a/emailMarketing/emailMarketingManager.py b/emailMarketing/emailMarketingManager.py new file mode 100644 index 000000000..9acfb2a68 --- /dev/null +++ b/emailMarketing/emailMarketingManager.py @@ -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) \ No newline at end of file diff --git a/emailMarketing/meta.xml b/emailMarketing/meta.xml new file mode 100644 index 000000000..c2abe51a7 --- /dev/null +++ b/emailMarketing/meta.xml @@ -0,0 +1,7 @@ + + + Email Marketing + plugin + Email Marketing plugin for CyberPanel. + 1.0 + \ No newline at end of file diff --git a/emailMarketing/migrations/__init__.py b/emailMarketing/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/emailMarketing/models.py b/emailMarketing/models.py new file mode 100644 index 000000000..af2db0124 --- /dev/null +++ b/emailMarketing/models.py @@ -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() + diff --git a/emailMarketing/signals.py b/emailMarketing/signals.py new file mode 100644 index 000000000..a492b6449 --- /dev/null +++ b/emailMarketing/signals.py @@ -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."}) \ No newline at end of file diff --git a/emailMarketing/static/emailMarketing/checklist.png b/emailMarketing/static/emailMarketing/checklist.png new file mode 100644 index 0000000000000000000000000000000000000000..bb709fb21690ff7679504ba461ea2c4bf7d746ac GIT binary patch literal 2961 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 T|KVWZ00000NkvXXu0mjfO;z3U literal 0 HcmV?d00001 diff --git a/emailMarketing/static/emailMarketing/emailMarketing.js b/emailMarketing/static/emailMarketing/emailMarketing.js new file mode 100644 index 000000000..2e32e0a98 --- /dev/null +++ b/emailMarketing/static/emailMarketing/emailMarketing.js @@ -0,0 +1,1323 @@ +/** + * Created by usman on 8/1/17. + */ + +var emailListURL = "/emailMarketing/"+ $("#domainNamePage").text() + "/emailLists"; +$("#emailLists").attr("href", emailListURL); +$("#emailListsChild").attr("href", emailListURL); + +var manageListsURL = "/emailMarketing/"+ $("#domainNamePage").text() + "/manageLists"; +$("#manageLists").attr("href", manageListsURL); +$("#manageListsChild").attr("href", manageListsURL); + +var sendEmailsURL = "/emailMarketing/sendEmails"; +$("#sendEmailsPage").attr("href", sendEmailsURL); +$("#sendEmailsPageChild").attr("href", sendEmailsURL); + +var composeEmailURL = "/emailMarketing/composeEmailMessage"; +$("#composeEmails").attr("href", composeEmailURL); +$("#composeEmailsChild").attr("href", composeEmailURL); + +var smtpHostsURL = "/emailMarketing/"+ $("#domainNamePage").text() + "/manageSMTP"; +$("#manageSMTPHosts").attr("href", smtpHostsURL); +$("#manageSMTPHostsChild").attr("href", smtpHostsURL); + + +app.controller('emailMarketing', function($scope,$http) { + + $scope.cyberPanelLoading = true; + $scope.fetchUsers = function(){ + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/fetchUsers"; + + var data = {}; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + + if(response.data.status === 1){ + $scope.users = JSON.parse(response.data.data); + } + else{ + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = false; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; + $scope.fetchUsers(); + $scope.enableDisableMarketing = function(status, userName){ + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/enableDisableMarketing"; + + var data = {userName: userName}; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + $scope.fetchUsers(); + + if(response.data.status === 1){ + new PNotify({ + title: 'Success!', + text: 'Changes successfully saved.', + type:'success' + }); + } + else{ + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = false; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; +}); + +app.controller('createEmailList', function($scope, $http, $timeout) { + + $scope.installationDetailsForm = false; + $scope.installationProgress = true; + $scope.cyberPanelLoading = true; + $scope.goBackDisable = true; + + var statusFile; + var path; + + + $scope.goBack = function () { + $scope.installationDetailsForm = false; + $scope.installationProgress = true; + $scope.cyberPanelLoading = true; + $scope.goBackDisable = true; + $("#installProgress").css("width", "0%"); + }; + + $scope.createEmailList = function(){ + + $scope.installationDetailsForm = true; + $scope.installationProgress = false; + $scope.cyberPanelLoading = false; + $scope.goBackDisable = true; + $scope.currentStatus = "Starting to load email addresses.."; + + + url = "/emailMarketing/submitEmailList"; + + var data = { + domain: $("#domainNamePage").text(), + path:$scope.path, + listName: $scope.listName + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + if (response.data.status === 1) + { + statusFile = response.data.tempStatusPath; + getInstallStatus(); + } + else{ + + $scope.installationDetailsForm = true; + $scope.cyberPanelLoading = true; + $scope.goBackDisable = false; + + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + + } + + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; + + function getInstallStatus(){ + + url = "/websites/installWordpressStatus"; + + var data = { + statusFile: statusFile, + domainName: $("#domainNamePage").text() + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + + if(response.data.abort === 1){ + + if(response.data.installStatus === 1){ + + $scope.installationDetailsForm = true; + $scope.installationProgress = false; + $scope.cyberPanelLoading = true; + $scope.goBackDisable = false; + $scope.currentStatus = 'Emails successfully loaded.'; + $timeout.cancel(); + + } + else{ + + $scope.installationDetailsForm = true; + $scope.installationProgress = false; + $scope.cyberPanelLoading = true; + $scope.goBackDisable = false; + $scope.currentStatus = response.data.error_message; + + + } + + } + else{ + $scope.installPercentage = response.data.installationProgress; + $scope.currentStatus = response.data.currentStatus; + + $timeout(getInstallStatus,1000); + } + + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + + } + + + } + + $scope.fetchEmails = function(){ + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/fetchEmails"; + + var data = {'listName': $scope.listName}; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + + if(response.data.status === 1){ + $scope.records = JSON.parse(response.data.data); + } + else{ + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = false; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; + + +}); + +app.controller('manageEmailLists', function($scope, $http, $timeout) { + + $scope.installationDetailsForm = true; + $scope.installationProgress = true; + $scope.cyberPanelLoading = true; + $scope.goBackDisable = true; + $scope.verificationStatus = true; + + var statusFile; + var path; + + + $scope.goBack = function () { + $scope.installationDetailsForm = false; + $scope.installationProgress = true; + $scope.cyberPanelLoading = true; + $scope.goBackDisable = true; + $("#installProgress").css("width", "0%"); + }; + + $scope.createEmailList = function(){ + + $scope.installationDetailsForm = true; + $scope.installationProgress = false; + $scope.cyberPanelLoading = false; + $scope.goBackDisable = true; + $scope.currentStatus = "Starting to load email addresses.."; + + + url = "/emailMarketing/submitEmailList"; + + var data = { + domain: $("#domainNamePage").text(), + path:$scope.path, + listName: $scope.listName + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + if (response.data.status === 1) + { + statusFile = response.data.tempStatusPath; + getInstallStatus(); + } + else{ + + $scope.installationDetailsForm = true; + $scope.cyberPanelLoading = true; + $scope.goBackDisable = false; + + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + + } + + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; + + function getInstallStatus(){ + + url = "/websites/installWordpressStatus"; + + var data = { + statusFile: statusFile, + domainName: $("#domainNamePage").text() + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + + if(response.data.abort === 1){ + + if(response.data.installStatus === 1){ + + $scope.installationDetailsForm = true; + $scope.installationProgress = false; + $scope.cyberPanelLoading = true; + $scope.goBackDisable = false; + $scope.currentStatus = 'Emails successfully loaded.'; + $timeout.cancel(); + + } + else{ + + $scope.installationDetailsForm = true; + $scope.installationProgress = false; + $scope.cyberPanelLoading = true; + $scope.goBackDisable = false; + $scope.currentStatus = response.data.error_message; + + + } + + } + else{ + $scope.installPercentage = response.data.installationProgress; + $scope.currentStatus = response.data.currentStatus; + + $timeout(getInstallStatus,1000); + } + + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + + } + + + } + + + /// + + $scope.currentRecords = true; + + $scope.recordstoShow = 50; + var globalPage; + + $scope.fetchRecords = function () { + $scope.fetchEmails(globalPage); + }; + + $scope.fetchEmails = function(page){ + globalPage = page; + listVerificationStatus(); + + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/fetchEmails"; + + var data = { + 'listName': $scope.listName, + 'recordstoShow': $scope.recordstoShow, + 'page': page + + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + + if(response.data.status === 1){ + $scope.currentRecords = false; + $scope.records = JSON.parse(response.data.data); + $scope.pagination = response.data.pagination; + } + else{ + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = false; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; + + $scope.deleteList = function () { + + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/deleteList"; + + var data = { + listName: $scope.listName + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + if (response.data.status === 1) + { + new PNotify({ + title: 'Success!', + text: 'Emails Successfully Deleted.', + type:'success' + }); + } + else{ + + $scope.cyberPanelLoading = false; + + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + + } + + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; + + $scope.showAddEmails = function () { + $scope.installationDetailsForm = false; + $scope.verificationStatus = true; + }; + + // List Verification + + $scope.startVerification = function () { + + $scope.currentStatusVerification = 'Email verification job started..'; + $scope.installationDetailsForm = true; + $scope.verificationStatus = false; + $scope.verificationButton = true; + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/emailVerificationJob"; + + var data = { + listName: $scope.listName + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + if (response.data.status === 1) + { + listVerificationStatus(); + $scope.verificationButton = true; + } + else{ + + $scope.cyberPanelLoading = true; + $scope.verificationButton = false; + + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + + } + + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + $scope.verificationButton = false; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + + }; + + var globalCounter = 0; + + function listVerificationStatus(){ + + $scope.verificationButton = true; + $scope.cyberPanelLoading = false; + + url = "/websites/installWordpressStatus"; + + var data = { + domain: $("#domainNamePage").text(), + statusFile: "/home/cyberpanel/" + $("#domainNamePage").text() + "/" + $scope.listName + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + + if(response.data.abort === 1){ + + if(response.data.installStatus === 1){ + $scope.cyberPanelLoading = true; + $scope.verificationButton = false; + $scope.currentStatusVerification = 'Emails successfully verified.'; + $timeout.cancel(); + + } + else{ + + if(response.data.error_message.search('No such file') > -1){ + $scope.verificationButton = false; + return; + } + $scope.verificationButton = true; + $scope.cyberPanelLoading = false; + $scope.verificationStatus = false; + $scope.currentStatusVerification = response.data.error_message; + + } + + } + else{ + $scope.currentStatusVerification = response.data.currentStatus; + $timeout(listVerificationStatus,1000); + $scope.verificationStatus = false; + } + + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + + } + + + } + + // Delete Email from list + + $scope.deleteEmail = function(id){ + + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/deleteEmail"; + + var data = { + id: id + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + $scope.fetchEmails(globalPage); + + if (response.data.status === 1) + { + $scope.fetchEmails(globalPage); + new PNotify({ + title: 'Success.', + text: 'Email Successfully deleted.', + type:'success' + }); + + } + else{ + + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + + } + + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; + + +}); + +app.controller('manageSMTPHostsCTRL', function($scope, $http) { + + $scope.cyberPanelLoading = true; + $scope.fetchSMTPHosts = function(){ + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/fetchSMTPHosts"; + + var data = {}; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + + if(response.data.status === 1){ + $scope.records = JSON.parse(response.data.data); + } + else{ + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = false; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; + $scope.fetchSMTPHosts(); + $scope.saveSMTPHost = function(status, userName){ + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/saveSMTPHost"; + + var data = { + smtpHost: $scope.smtpHost, + smtpPort: $scope.smtpPort, + smtpUserName: $scope.smtpUserName, + smtpPassword: $scope.smtpPassword + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + + if(response.data.status === 1){ + $scope.fetchSMTPHosts(); + new PNotify({ + title: 'Success!', + text: 'Successfully saved new SMTP host.', + type:'success' + }); + } + else{ + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = false; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; + $scope.smtpHostOperations = function(operation, id){ + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/smtpHostOperations"; + + var data = { + id: id, + operation: operation + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + $scope.fetchSMTPHosts(); + + if(response.data.status === 1){ + new PNotify({ + title: 'Success!', + text: response.data.message, + type:'success' + }); + } + else{ + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = false; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; +}); + +app.controller('composeMessageCTRL', function($scope, $http) { + + $scope.cyberPanelLoading = true; + $scope.saveTemplate = function(status, userName){ + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/saveEmailTemplate"; + + var data = { + name: $scope.name, + subject: $scope.subject, + fromName: $scope.fromName, + fromEmail: $scope.fromEmail, + replyTo: $scope.replyTo, + emailMessage: $scope.emailMessage + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + + if(response.data.status === 1){ + new PNotify({ + title: 'Success!', + text: 'Template successfully saved.', + type:'success' + }); + } + else{ + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = false; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; +}); + +app.controller('sendEmailsCTRL', function($scope, $http, $timeout) { + + $scope.cyberPanelLoading = true; + $scope.availableFunctions = true; + $scope.sendEmailsView = true; + $scope.jobStatus = true; + + // Button + + $scope.deleteTemplateBTN = false; + $scope.sendEmailBTN = false; + + $scope.templateSelected = function () { + $scope.availableFunctions = false; + $scope.sendEmailsView = true; + $scope.previewLink = '/emailMarketing/preview/' + $scope.selectedTemplate; + $scope.jobStatus = true; + emailJobStatus(); + + }; + + $scope.sendEmails = function () { + $scope.sendEmailsView = false; + $scope.fetchJobs(); + }; + + $scope.fetchJobs = function(){ + + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/fetchJobs"; + + var data = { + 'selectedTemplate': $scope.selectedTemplate + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + + if(response.data.status === 1){ + $scope.currentRecords = false; + $scope.records = JSON.parse(response.data.data); + } + else{ + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = false; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; + + $scope.startEmailJob = function () { + $scope.cyberPanelLoading = false; + $scope.deleteTemplateBTN = true; + $scope.sendEmailBTN = true; + $scope.sendEmailsView = true; + $scope.goBackDisable = true; + + url = "/emailMarketing/startEmailJob"; + + + var data = { + 'selectedTemplate': $scope.selectedTemplate, + 'listName': $scope.listName, + 'host': $scope.host, + 'verificationCheck': $scope.verificationCheck, + 'unsubscribeCheck': $scope.unsubscribeCheck + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + + if(response.data.status === 1){ + emailJobStatus(); + } + else{ + $scope.cyberPanelLoading = true; + $scope.deleteTemplateBTN = false; + $scope.sendEmailBTN = false; + $scope.sendEmailsView = false; + $scope.jobStatus = true; + $scope.goBackDisable = false; + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + } + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = false; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + + }; + + function emailJobStatus(){ + + $scope.cyberPanelLoading = false; + $scope.deleteTemplateBTN = true; + $scope.sendEmailBTN = true; + $scope.sendEmailsView = true; + $scope.jobStatus = false; + $scope.goBackDisable = true; + + url = "/websites/installWordpressStatus"; + + var data = { + domain: 'example.com', + statusFile: "/home/cyberpanel/" + $scope.selectedTemplate + "_pendingJob" + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + + if(response.data.abort === 1){ + + if(response.data.installStatus === 1){ + $scope.cyberPanelLoading = true; + $scope.deleteTemplateBTN = false; + $scope.sendEmailBTN = false; + $scope.sendEmailsView = true; + $scope.jobStatus = false; + $scope.goBackDisable = false; + $scope.currentStatus = 'Emails successfully sent.'; + $scope.fetchJobs(); + $timeout.cancel(); + + } + else{ + + if(response.data.error_message.search('No such file') > -1){ + $scope.cyberPanelLoading = true; + $scope.deleteTemplateBTN = false; + $scope.sendEmailBTN = false; + $scope.sendEmailsView = true; + $scope.jobStatus = true; + $scope.goBackDisable = false; + return; + } + $scope.cyberPanelLoading = true; + $scope.deleteTemplateBTN = false; + $scope.sendEmailBTN = false; + $scope.sendEmailsView = true; + $scope.jobStatus = false; + $scope.goBackDisable = false; + $scope.currentStatus = response.data.error_message; + + } + + } + else{ + $scope.currentStatus = response.data.currentStatus; + $timeout(emailJobStatus,1000); + $scope.cyberPanelLoading = false; + $scope.deleteTemplateBTN = true; + $scope.sendEmailBTN = true; + $scope.sendEmailsView = true; + $scope.jobStatus = false; + $scope.goBackDisable = true; + } + + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page.', + type:'error' + }); + + + } + + + } + + $scope.goBack = function () { + $scope.cyberPanelLoading = true; + $scope.deleteTemplateBTN = false; + $scope.sendEmailBTN = false; + $scope.sendEmailsView = false; + $scope.jobStatus = true; + + }; + + $scope.deleteTemplate = function(){ + + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/deleteTemplate"; + + var data = { + selectedTemplate: $scope.selectedTemplate + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + + if (response.data.status === 1) + { + new PNotify({ + title: 'Success.', + text: 'Template Successfully deleted.', + type:'success' + }); + + } + else{ + + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + + } + + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; + $scope.deleteJob = function(id){ + + $scope.cyberPanelLoading = false; + + url = "/emailMarketing/deleteJob"; + + var data = { + id: id + }; + + var config = { + headers : { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data,config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.cyberPanelLoading = true; + $scope.fetchJobs(); + + if (response.data.status === 1) + { + new PNotify({ + title: 'Success.', + text: 'Template Successfully deleted.', + type:'success' + }); + + } + else{ + + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type:'error' + }); + + } + + } + function cantLoadInitialDatas(response) { + $scope.cyberPanelLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: 'Could not connect to server, please refresh this page', + type:'error' + }); + + } + + }; +}); + + diff --git a/emailMarketing/static/emailMarketing/mailing.png b/emailMarketing/static/emailMarketing/mailing.png new file mode 100644 index 0000000000000000000000000000000000000000..b8586aea2c6ae186c8d02b71572fd44ae17f9dc6 GIT binary patch literal 2124 zcmV-S2($NzP)HbQF`&wWpDkcGLJS6~i*v}e$FcwDX>RuP2TBzX z454Onmwt)l?EG=@jC&ePi;HGc^$6JK3g$fwcN z$`=MBsYQ#)T~t0lV8{T1WPk@HnRYtNvB8uuy(2VjK(GY_8`A~^TR^ZeZ9uRE1RI*` z0JF<{q~F}1t`@WRZzmt??C$-k=Q-LM{=M4!i{4Nx^UJsDK6Xoz`YxVDF@_F4{FT)e zYVma+{I&YZ<<_S?&+$o#&y`g^_>Ni`_kh!(mJdD{P?1JInE#^|v!lJE139!+extXy zqiU8$ncICXfXj+p*Jlcb&M{kCTAF|V?V52PEKd0@Fy#$U?E;H` zc3=%|u||tT3NdT4&x!?b7k-CX5xtzhVP(Lj=yOEVxXM%zv%-{V>n1n7fw~LH3XKI8@*KCvOI?!OVl{;f zkQLKGYqyoFw=FiccroTZ!PY010Ivesqci2ZNY;_GyTyNbs|>W+o<#Bkzzjgw?$7cJ zU`l--XV?nz9R43Dek$x3*bP*Tk=umi8x+VxBQr*Kfwpx!fsYuo@&KX=ML1}CLiGaT zC|p>dK%1=&$#Zxr?}b4aIR8bIw(B$(75c^P5H%QaFm~kuvJrelqu4nz!`pz?b*qtL z`>6DhkVGQc%hk1h+(weGAX%gtH`r;x-S)oEy#Ejx2=*e0)QD7&Y{wy1dnbBubzMC0 zqR%ge2wa9e;KP-%w)NjaQ0+6b>q;!==KMxGPzV(E01-ZO3tq$_;ysT;2Dp@!AZGeZ zbQk4ZS*v|dMam6+@`Cf)W12B%$OrsAOq_|rO3%ZvrY-}!f#5Qzmup;Q0_OV7>%JLI zV}V6IhQKsSN<2S@_w}NH$dKygB5iqq$$wrqm=yJHBLdaT=l5)e8xYtv4n?D!O9aLX zAPvnL5rJ}F_52tzKyo}VE}>p7_1A3(+We+f!rWw?Jf#}r4p8&3x(*qj@b>_ydT|<# z`S3#jxs@pGg_h(P;QxJHF{Ee6fP|OdLyCQVQf(vUS6$j+t|vis`^+j#5+!DpX53ua zg=>dsaTO{}51wQNlyFp{(cL89X+pw6oFP|0ihZu2+BQRo4 z&6<7JgxDCEVS(#iaIFKH{{`(M2Ve0Eb`EYCRrzDx_u=Lc!@fGhm0rp%b)=Xsk!)(g za_c3!N#%lTE-!RGLz^>kh!uzoRo1+=)HZrm_;BJbkej{IQk*cq4-%aa?}8f!xEun_ zq44RbhI*Wv?WIC)XETUh_wdbENTe+0N78H5-df*%0;xV%pX+w1Wn)t4+xI|pxL0D0 zy%0Hgf^lz1%Pk60Xl{G^0D9zw0s!fdiK;yfW@q9~x5W@#!W z8ohiu^|Uaf48uSTamZ3bv-~tz4k!_yN=u(FO_OXehs;t-%Bh?{hP&S%=X$x9$$PmM zvRa?d`S3aWtiAU7{q8<%@3qcGlv4bYL_{2c$AAgIHu)zJAR>1IOMw7GQ_(+y01@#A z76T(oKXa^kcWO>V#1)tYJPFh)Pv>t-fQSqQQi0}`>FH|5othI7xl2T{fUQ&j-o?4( zcmLZEAR-zeL;!f#^`LzlKQleQhP9deV2JVlZ$W^Fi~)`UvjJxZ2Oa+!AIi+Q zaK1fy)>Mx*i^fsMt0Wx!r3ny`AQ9OGYykWK`gCi_=b72td=u z^;n#6AJGE?je5KHeb30ruW+NF$gF?2;HJd?JEB7Sw>1GGG8IS!JOSKXotQmk5Rb=& ztut$A0*gh%rmKaOoN%5I;76m$n=Spl)q{sFsNzaF(8#Y2X^Hn+q z01+7rqyWAEx#zA#8J2c@>UmV!_x#1H3>uxr_a}b?VETQnd16ce17_~v`i){lgjW}j zr?#h?RX)`S0V2{7SO)aD*%s2hC9$J>Th#y3AJ-ZD;8MOju4Q(Q3~kBtlLA?=;V}D; zTm;~;iD88GYHhV|)k=Vf)B)xLaexD8`FQf2d%1sD7mI9Mxt34V_~jfrdVOY9YXow8Ww%E#9CdEz>6TC;qX)c(}V*WaoNb0YhU} zu>Z>+0l2@vKg*|gCcmJV*pz(~6)T(^9ay(yg4xc{8nHV8BGLmbY3Y2kEuvpL7C&>J zF=??x@^2J!Z|q9;>^}j(J$)LndR8}dA|#}L&9T#00GK;HlHm4@tL(4c2oRC_Xi3Wi z43Vvwzc-5$MiLbsSXtLHQczgL{c)?=vF9iN5#4-Q7vCKRov<_KS5|J-HatB#HD~st z18wr#WTBe|FX1qX4LS|1H#LR~WSUok1iu61@4b=fpOgjy~d`1f|5=ItG)02mzB-mJ1~i&#Z~h&Tg}15W|&0G=MM zJUt_dDHHnP=vejXI4$9AUVG;=00LXoCL^gY9&Va@xfk=9w)7yNmAYS9IJU~;lopE# z5Rt)X`FShDJ!407Cn^3O8hCr!!N4_hkEmzIb_*#EwT6?>8noFD)2D zLm%75GnHEsAR^6yB|!AewoV=VS@PT{dUUGvtCL0Y?4oU?uKoysmUnvaeo83yyh`>7 ztGA!vLqno7c0_mXiRftan5I%G0U|OTZE14>ZTdYoYbX;R=#5S%HV^*7@()N_mIXkQ z2JU1ghti;qtMU2wKVN0eDlO4z>{pj1&smq~SRxg^w1#423I^~1y}Gubfww35HwtYY zIBm@i5*B6v;OFf|W^yQvd`iC96zdg}QuY}Wo%Gc4czU>2WUk6m;S5kp<%-BUv@NX; zAS3$_8QF($b9JJB?>0n*2NF4;gVpcksyB8sEAd?b>eq4Q{p3)Z`MR6wEPCsRG0~Ye zsXw7T?y_nOOXZdaBn&&eC}0>cfKuPtMTD*$n-Dc1km&G0+O_s8&x}#lZ`{k|S+Ap% zqOPYi*$ev-(A2zolXLtMVbga|Sfr<2Yd`jGf70xWuC0=onn~i4OwE65PKbzz8yX2i z(Sl-w(mG8W*CRSSkf`uLLb|mwTN>ZVIKcR6Ytic!p6*U$rG(P4WgWBr`31%Fn(`4x zPhG~@$&o!7vk3}lR27^RiYWnB(W;cn1GWL%L_~n@Xk-k-aPH>E(-&BlzLRC?JE`sI zMnqV9qQe6z*6W!#^ELE(g@>CXTb>Uo10EnD{cDb%(rSGPGb8N|zO>lwjF5=5poEM* z81nzp;^yMO=J_Fn1eV>#e){EaL_YZ`N(qcLT>{b(0N}W(jr7ETR z0ri1#z((MTsb13LpmM=qzE;S?hD681-G#NOG1UUTv{Xw`R4H{)DfNa@Y7|;QWEfBg zuxZ!na{J6!k;9pD*8y0RFp_5e-qqn+8L9TFuu`f(DU|`N1lax6IkNVhHPbot{qMZ> z@lVG4>`xA}VbeY?{(h~x-K){6a3T-`c+Fk&6$86A#KADdPyJ>NbaPe?o3nCoaM01a zYYU>ogNP3AK=UTHr@y7eZZkkchKR@k5t&xrbEVXIv~4v7(Q_&4TEMe^5Iulzi}_;E?l+Be_KmpQNVkYfFG%pdjA&PUI%6XK}$9s zC3Z;VDfRXIBA#2dmp`uDxY_hE@D|$2ayQ_1J+Hu+r|5J-&(6(>3J+vxc+f2?(N&%S zA`*!?_z_B}ZMW*Dl+vS}=i_Q#5zoJVxI*2ld4&w0v6WBu8<);(AWA8G49dN0{o(|{@Bm+lG`WY{udLAlfR8JKZ9$3;| z1;>W~`6l2at4LxHPzKxF()cGxdvz7Mm0{#Q+zBx|0mkr?as|w!4 z-n!BbWiA`8g6{G$ZF?7RvT+=5v=26$fU739&st+-a4GOZY;nq9voVloN`QB5H&gI$ z0*;kT`96TFm1DXZUf~ykyQ>|%!O=vt=Y9qkT;12?KRG>T6L~j*_I)w$`v#4Zcu!#Vm zE^y5Re1whQ>)t{?9_=8srQqMU6}%+`TsDwUZQw1mSsHw%J-}B=fC&i}J6}WKw`1j= zz+wUbf1s-k&c19<@CKW!O>AznCwMagN(DTtNdSE84c=fk!(cPR-r$V{loRdCtk)Jg zn~av2*af`7W-XvsMZwVy_8C|Tyu|^}U|=Fz8fc`N(g7V>|jAr_iqt;+EL0000Eh3m*+RnJn!tx5Jd=ynsAv+cZ?~@GhUOaq2F%5 zI%KsLU$WUAn2f$mTw_sD|G1_obE(sxdSha)(N6+(Cnu9GDtx-_cF(ZYx}!5I>(*%l zfI59Yb+mwLfIBUU0}yr2;rMOPW~&~ySmxfC0343nyo$1X%w#H~PW~Ru@lXIn^(Q9& z?6F#lM$G2BraXYL=;&DL^t;rtA455<1prr%!|{jPX6qiYT63osfZ4O}995L(sWUCI zPLBtGsNSTcQIE~`-B3cp!;=FbD(aTe*w{4cz*kh>@i-m{08uWx{laiU!p;FY?F{> zYm1LAna%f(8vspc@uMbFA?@U4y`45109Uuefwe{N1&ifbDFDAjNB@&1w0zpJP9vS3 zC;)zIi=?D68WpAIEf&QOz}~%ka|#O!w;#{Xf3G()v%GK7qRNSsGd0!iOi3A=|{UZGci6Y1oK9 zw6(QqivWxY7e+A{fCC2(u#v_0Cr+IBTjx)oKFuHm10X)bF^p(QNeLTKI9ps??2882 zc6N69A^`$`g9i^X8}wHkc|he+3GoP%1|TCI0sQ&YsZ%VZ;S9cm<2+o00e}r`Q3jyG zMF2h#DX_&e+C~&LG&J~}gAi5X$OEkA93UeQ4$KW0IgiKVdln-H9Sf`jwkX5@7V8u3 z#lKM}>>xmc#B!*wqoc#8-ring0NkjG2mnSM;l|1HB&KH1Gco32cXu}%4UCXDXCo1! z27N$ZP(P23Q1y=s02)Fv!u&(B!|M;iT*TbRTS5$dbO3X&y1JUp^P@+PGJ7PflP6D- zvuDrxLVr90bY4I50Phd4ANfJ8e$4#w|Q@G8oK zRQ2M)<*)Jar1rVZBu2s^{2tH(0QPzSFsEcOXYCYdJpGN~tAFV_c>tq|vOv7L7N}FR zEFmFazAaesv?c%xS3VOlfLvP|xx6@oT-~^lT+PcPzi!=1zKXZA@6aDP0E%+=n9212 zaL3qtEXk_QAOs)H*&q!7^D|@3^AQ8cx26#9iWS6LP(Zxfwh`~{-J~MU!UiNOce5M- zI`S{doa6tZD8!VU5!9iS$MZA+K=|tc0GgNd7)cdmc4UwQIwi87%9jLSGL^_)W>}h- z9yI)yuHU2y0G!tgKrmtNLJNS-pOjcq8keA|R`YBIU^5N5z{VU)*0RQA0oZ7=g1u1y z%qiIv=wfCWooliH5G|Q&HyR3nkG>`Vm+AbjnKegM z02B;Bs?eAWfO%QDK6@hoAQ|)eH35*#0V06JjMaXPg#*A7lTiS$S&LjWApjgp*7!9P z4uE~}lO*e}d1(Xyb80rLFR)L#1K4Uy@e6wy0Q0hQgWBr_z>>bwmxl}oP%wWnnVYpf zs4yi&07!Tkc{O`PQKSGct+1j@Ulm-s1E_obO}5jjrk3_DGUyo&X(I}-v;r6y^hno_ zvj-^vS7KsF(?bub$~AK)1JJf>m+$I|Uc#{&Iw%8xU!fUK{UHJTNC6z0F+){=008cy zA~s@1DBOuL0Prnzt-`*dE&zV`{BzBRnR*ETa2*HJMT@YNj0q|{VE}Yhg&p4|$ z0sx%BRKc#XjBuX;;jcRYY*UNd);PexsV#pN?+)n=08Yu?3Izm10Pt;VoC3pnE*xm^ zt?X$HfD2PWY|x0%pV9zuWGzNOB-dUh6~HKVd?*ApUHxkzG}&(f!vNs_g0L@0L41GB z;UK}}r9YXc0suIIV{;ktOBG=Oj48^~;jYPzTCI}~;PBzY>{^W$;fC6@0f75H<58%U Z;GZ;>Ulnqt#w!2-002ovPDHLkV1kgQjobhL literal 0 HcmV?d00001 diff --git a/emailMarketing/templates/emailMarketing/composeMessages.html b/emailMarketing/templates/emailMarketing/composeMessages.html new file mode 100644 index 000000000..4c4ec015d --- /dev/null +++ b/emailMarketing/templates/emailMarketing/composeMessages.html @@ -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 %} + + + +
+
+

{% trans "Compose Email Message" %}

+

{% trans "On this page you can compose email message to be sent out later." %}

+
+
+
+

+ {% trans "Compose Email Message" %} +

+
+ + +
+ + + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ + +
+
+ +
+
+ +
+ +
+ +
+
+ + + +
+ + + + +
+
+
+
+ + +{% endblock %} \ No newline at end of file diff --git a/emailMarketing/templates/emailMarketing/createEmailList.html b/emailMarketing/templates/emailMarketing/createEmailList.html new file mode 100644 index 000000000..863afa4fe --- /dev/null +++ b/emailMarketing/templates/emailMarketing/createEmailList.html @@ -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 %} + + + +
+
+

{% trans "Create Email List" %} - {{ domain }}

+

{% trans "Create email list, to send out news letters and marketing emails." %}

+
+
+
+

+ {% trans "Create Email List" %} +

+
+ + +
+
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+
+

{$ currentStatus $}

+
+
+
+ +
+ +
+ +
+
+ +
+ + + + +
+
+
+ + +
+{% endblock %} + diff --git a/emailMarketing/templates/emailMarketing/emailMarketing.html b/emailMarketing/templates/emailMarketing/emailMarketing.html new file mode 100644 index 000000000..0e5d9a677 --- /dev/null +++ b/emailMarketing/templates/emailMarketing/emailMarketing.html @@ -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 %} + + + +
+ +
+

{% trans "Email Marketing" %}

+

{% trans "Select users to Enable/Disable Email Marketing feature!" %}

+
+ +
+
+ +

+ {% trans "Email Marketing" %} +

+ + {% if installCheck == 0 %} + +
+
+

{% trans "Email Policy Server is not enabled " %} + +

+
+
+ {% else %} +
+ + + + + + + + + + + + + + + + + + +
{% trans 'ID' %}{% trans 'Username' %}{% trans 'Status' %}
+ + + + +
+ +
+ + {% endif %} +
+
+ + + +{% endblock %} \ No newline at end of file diff --git a/emailMarketing/templates/emailMarketing/manageLists.html b/emailMarketing/templates/emailMarketing/manageLists.html new file mode 100644 index 000000000..378649f87 --- /dev/null +++ b/emailMarketing/templates/emailMarketing/manageLists.html @@ -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 %} + + + +
+
+

{% trans "Manage Email Lists" %} - {{ domain }}

+

{% trans "On this page you can manage your email lists (Delete, Verify, Add More Emails)." %}

+
+
+
+

+ {% trans "Manage Email Lists" %} +

+
+ + +
+ + +
+ +
+ +
+
+ +
+ +
+ + + + +
+
+ +
+
+ +
+
+ + + + +
+ +
+ +
+
+ +
+ +
+ + +
+
+ +
+ +
+
+

{$ currentStatus $}

+
+
+
+ +
+ +
+ +
+
+ + + + + +
+ +
+
+

{$ currentStatusVerification $}

+
+
+
+ + + + + + +
+ +
+ +
+ +
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + +
{% trans "ID" %}{% trans "email" %}{% trans "Verification Status" %}{% trans "Date Created" %}{% trans "Actions" %}
+ +
+ +
+
+ + +
+
+
+
+ + + +
+ + + + +
+
+
+ + +
+ + +{% endblock %} \ No newline at end of file diff --git a/emailMarketing/templates/emailMarketing/manageSMTPHosts.html b/emailMarketing/templates/emailMarketing/manageSMTPHosts.html new file mode 100644 index 000000000..c90d4ae04 --- /dev/null +++ b/emailMarketing/templates/emailMarketing/manageSMTPHosts.html @@ -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 %} + + + +
+
+

{% trans "Manage SMTP Hosts" %}

+

{% trans "On this page you can manage STMP Host. (SMTP hosts are used to send emails)" %}

+
+
+
+

+ {% trans "Manage SMTP Hosts" %} +

+
+ + +
+ + + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
{% trans "ID" %}{% trans "Owner" %}{% trans "Host" %}{% trans "Port" %}{% trans "Username" %}{% trans "Actions" %}
+ + +
+ +
+
+ + +
+
+
+
+ + + +
+ + + + +
+
+
+ + +
+ + +{% endblock %} \ No newline at end of file diff --git a/emailMarketing/templates/emailMarketing/sendEmails.html b/emailMarketing/templates/emailMarketing/sendEmails.html new file mode 100644 index 000000000..67d19cfff --- /dev/null +++ b/emailMarketing/templates/emailMarketing/sendEmails.html @@ -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 %} + + + +
+
+

{% trans "Send Emails" %}

+

{% trans "On this page you can send emails to the lists you created using SMTP Hosts." %}

+
+
+
+

+ {% trans "Send Emails" %} +

+
+ + +
+ + +
+ +
+ +
+
+ +
+ +
+ + + + +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+ +
+ + +
+
+ + + +
+ +
+
+

{$ currentStatus $}

+
+
+
+ +
+ +
+ +
+
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
{% trans "Job ID" %}{% trans "Date" %}{% trans "SMTP Host" %}{% trans "Total Emails" %}{% trans "Sent" %}{% trans "Failed" %}{% trans "Actions" %}
+ +
+ +
+
+ + +
+
+
+
+ + + +
+ + + + +
+
+
+ + +
+ + +{% endblock %} \ No newline at end of file diff --git a/emailMarketing/templates/emailMarketing/website.html b/emailMarketing/templates/emailMarketing/website.html new file mode 100644 index 000000000..46e2938b2 --- /dev/null +++ b/emailMarketing/templates/emailMarketing/website.html @@ -0,0 +1,1097 @@ +{% extends "baseTemplate/index.html" %} +{% load i18n %} +{% block title %}{{ domain }} - CyberPanel{% endblock %} +{% block content %} + +{% load static %} +{% get_current_language as LANGUAGE_CODE %} + + +
+ +
+

{{ domain }} - {% trans "Preview" %}

+

{% trans "All functions related to a particular site." %}

+
+ + {% if not error %} + + +
+ +
+ +

+ {% trans "Resource Usage" %} +

+ + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{% trans "Resource" %}{% trans "Usage" %}{% trans "Allowed" %}
{% trans "FTP" %}{{ ftpUsed }}{{ ftpTotal }}
{% trans "Databases" %}{{ databasesUsed }}{{ databasesTotal }}
{% trans "Disk Usage" %}{{ diskInMB }} (MB){{ diskInMBTotal }} (MB)
{% trans "Bandwidth Usage" %}{{ bwInMB }} (MB){{ bwInMBTotal }} (MB)
+
+ +
+
+
+
+

+ {% trans "Disk Usage" %} +

+
+
+
+
{{ diskUsage }}%
+
+
+ + +

+ {% trans "Bandwidth Usage" %} +

+
+
+
+
{{ bwUsage }}%
+
+
+ + + +
+ +
+
+
+ +
+
+ + +
+
+ + +
+ +
+

+ {% trans "Logs" %} +

+ +
+
+ + + + + + + +
+ +
+ +
+

{% trans "Logs Fetched" %}

+
+ + +
+

{% trans "Could not fetch logs, see the logs file through command line. Error message:" %} {$ errorMessage $}

+
+ + +
+

{% trans "Could not connect to server. Please refresh this page." %}

+
+ + + +
+ +
+ +
+ +
+ +
+ +
+ + +
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + + +
DomainIP AddressTimeResourceSize
+
+
+ + +
+ +
+ +
+ +
+ + +
+ +
+ +
+ +
+ +
+
+ + + + + + + + +
+ + + + + +
+ + +
+
+
+
+ + +
+
+ +

+ {% trans "Domains" %} +

+ +
+ +
+ + + + + + + + + + + + + + + +
+
+ + +
+ +
+ +
+
+ +
+
+ +
+ +
+ +
+
{% trans "Invalid Domain (Note: You don't need to add 'http' or 'https')" %}
+
+ + +
+ +
+ +
+
+ + + +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ + +
+ +
+ + +
+
+ + + +
+ +
+ +
+

{$ currentStatus $}

+
+ +
+
+ 70% Complete +
+
+ +
+

{% trans "Error message:" %} {$ errorMessage $}

+
+ +
+

{% trans "Website succesfully created." %}

+
+ + + +
+

{% trans "Could not connect to server. Please refresh this page." %}

+
+ + +
+
+ +
+ +
+ +
+
+ + +
+
+ + + + + +
+ +
+ + + +
+

{% trans "PHP Version Changed to:" %} {$ changedPHPVersion $}

+
+ +
+

{% trans "Deleted:" %} {$ deletedDomain $}

+
+ +
+

{% trans "SSL Issued:" %} {$ sslDomainIssued $}

+
+ +
+

{% trans "Changes applied successfully." %}

+
+ + +
+

{$ errorMessage $}

+
+ + +
+

{% trans "Could not connect to server. Please refresh this page." %}

+
+ + + + +
+ +
+ +
+ +
+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + +
DomainLaunchPathopen_basedirPHPSSLDelete
+ + + +
+
+
+ + +
+ +
+ + +
+ +
+
+
+ + +
+ +
+

+ {% trans "Configurations" %} +

+ + +
+
+ + + + + + + + + + + + + + +
+ +
+ +
+

{% trans "SSL Saved" %}

+
+ + +
+

{% trans "Could not save SSL. Error message:" %} {$ errorMessage $}

+
+ + +
+

{% trans "Could not connect to server. Please refresh this page." %}

+
+ + +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+ + +
+
+ + +
+ + + + + +
+ + + + + + + +
+ +
+ +
+

{% trans "Current configuration in the file fetched." %}

+
+ + +
+

{% trans "Could not fetch current configuration. Error message:" %} {$ errorMessage $}

+
+ + +
+

{% trans "Could not connect to server. Please refresh this page." %}

+
+ +
+

{% trans "Configurations saved." %}

+
+ +
+

{% trans "Could not fetch current configuration. Error message:" %} {$ errorMessage $}

+
+ + +
+
+ +
+
+ +
+
+ +
+ +
+ + +
+
+ + +
+ +
+ + + +
+ +
+ + +
+

{% trans "Current rewrite rules in the file fetched." %} Click to read more about whats changed in rewrite rules from v1.7 onwards.

+
+ + +
+

{% trans "Could not fetch current rewrite rules. Error message:" %} {$ errorMessage $}

+
+ + +
+

{% trans "Could not connect to server. Please refresh this page." %}

+
+ +
+

{% trans "Configurations saved." %}

+
+ +
+

{% trans "Could not save rewrite rules. Error message:" %} {$ errorMessage $}

+
+ + +
+
+ +
+
+ +
+
+ +
+ +
+ + +
+
+ + +
+ +
+ + + +
+ +
+ + + +
+ +
+ +
+ +
+ +
+ +
+ + + + +
+ +
+ +
+
+ + + +
+ + +
+
+

{% trans "Failed to change PHP version. Error message:" %} {$ errorMessage $}

+
+ +
+

{% trans "PHP successfully changed for: " %} {$ websiteDomain $}

+
+ +
+

{% trans "Could not connect to server. Please refresh this page." %}

+
+
+ + + +
+ + +
+
+ +
+
+
+
+ + +
+
+

+ {% trans "Files" %} +

+ +
+
+ + + + + + + + + + + + + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + +
+ +
+ +
+
+
+ + +
+
+

{% trans "Error message:" %} {$ errorMessage $}

+
+ +
+

{% trans "Changes successfully saved." %}

+
+ +
+

{% trans "Could not connect to server. Please refresh this page." %}

+
+
+ +
+ + +
+
+ + + + + +
+
+
+
+ + {% if marketingStatus %} + + + + {% endif %} + +
+ +
+

+ {% trans "Application Installer" %} +

+ + + +
+
+ + {% else %} + +
+

{{ domain }}

+
+ + + {% endif %} + + + + +
+ + + +{% endblock %} \ No newline at end of file diff --git a/emailMarketing/tests.py b/emailMarketing/tests.py new file mode 100644 index 000000000..5982e6bcd --- /dev/null +++ b/emailMarketing/tests.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.test import TestCase + +# Create your tests here. diff --git a/emailMarketing/urls.py b/emailMarketing/urls.py new file mode 100644 index 000000000..b8bf67151 --- /dev/null +++ b/emailMarketing/urls.py @@ -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([\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([\da-z\.-]+\.[a-z\.]{2,12}|[\d\.]+)([\/:?=&#]{1}[\da-z\.-]+)*[\/\?]?)/manageLists$', views.manageLists, name='manageLists'), + url(r'^(?P([\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[-\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'), +] \ No newline at end of file diff --git a/emailMarketing/views.py b/emailMarketing/views.py new file mode 100644 index 000000000..a5ba2efc4 --- /dev/null +++ b/emailMarketing/views.py @@ -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) \ No newline at end of file diff --git a/install/install.py b/install/install.py index 19f13377c..46fa22abb 100644 --- a/install/install.py +++ b/install/install.py @@ -687,8 +687,8 @@ class preFlightsChecks: count = 0 while (1): - command = "wget http://cyberpanel.net/CyberPanel.1.7.2.tar.gz" - #command = "wget http://cyberpanel.net/CyberPanelTemp.tar.gz" + #command = "wget http://cyberpanel.net/CyberPanel.1.7.2.tar.gz" + command = "wget http://cyberpanel.net/CyberPanelTemp.tar.gz" res = subprocess.call(shlex.split(command)) if res == 1: @@ -707,8 +707,8 @@ class preFlightsChecks: count = 0 while(1): - command = "tar zxf CyberPanel.1.7.2.tar.gz" - #command = "tar zxf CyberPanelTemp.tar.gz" + #command = "tar zxf CyberPanel.1.7.2.tar.gz" + command = "tar zxf CyberPanelTemp.tar.gz" res = subprocess.call(shlex.split(command)) @@ -2582,6 +2582,29 @@ class preFlightsChecks: logging.InstallLog.writeToFile(str(msg) + " [installTLDExtract]") return 0 + def installPYDNS(self): + try: + count = 0 + while (1): + command = "pip install pydns" + + res = subprocess.call(shlex.split(command)) + + if res == 1: + count = count + 1 + preFlightsChecks.stdOut( + "Trying to install pydns, trying again, try number: " + str(count)) + if count == 3: + logging.InstallLog.writeToFile( + "Failed to install pydns! [installTLDExtract]") + else: + logging.InstallLog.writeToFile("pydns successfully installed! [pip]") + preFlightsChecks.stdOut("pydns successfully installed! [pip]") + break + except OSError, msg: + logging.InstallLog.writeToFile(str(msg) + " [installTLDExtract]") + return 0 + def installOpenDKIM(self): try: count = 0 @@ -3003,6 +3026,7 @@ def main(): checks.installCertBot() checks.test_Requests() + checks.installPYDNS() checks.download_install_CyberPanel(installCyberPanel.InstallCyberPanel.mysqlPassword, mysql) checks.setupCLI() checks.setup_cron() diff --git a/plogical/website.py b/plogical/website.py index 198ce662e..1eabfef17 100644 --- a/plogical/website.py +++ b/plogical/website.py @@ -1495,6 +1495,8 @@ class WebsiteManager: lastLine = statusData[-1] if lastLine.find('[200]') > -1: + command = 'sudo rm -f ' + statusFile + subprocess.call(shlex.split(command)) data_ret = {'abort': 1, 'installStatus': 1, 'installationProgress': "100", 'currentStatus': 'Successfully Installed.'} json_data = json.dumps(data_ret) @@ -1507,7 +1509,10 @@ class WebsiteManager: else: progress = lastLine.split(',') currentStatus = progress[0] - installationProgress = progress[1] + try: + installationProgress = progress[1] + except: + installationProgress = 0 data_ret = {'abort': 0, 'installStatus': 0, 'installationProgress': installationProgress, 'currentStatus': currentStatus} json_data = json.dumps(data_ret) diff --git a/requirments.txt b/requirments.txt index cacd75630..cb196634f 100644 --- a/requirments.txt +++ b/requirments.txt @@ -35,6 +35,7 @@ psutil==5.4.3 ptyprocess==0.6.0 pycparser==2.18 pycurl==7.19.0 +pydns==2.3.6 pygpgme==0.3 pyliblzma==0.5.3 pyOpenSSL==17.5.0 diff --git a/websiteFunctions/pluginManager.py b/websiteFunctions/pluginManager.py index 757114926..1659ac516 100644 --- a/websiteFunctions/pluginManager.py +++ b/websiteFunctions/pluginManager.py @@ -51,6 +51,14 @@ class pluginManager: def postWebsiteModification(request, response): return pluginManagerGlobal.globalPlug(request, postWebsiteModification, response) + @staticmethod + def preDomain(request): + return pluginManagerGlobal.globalPlug(request, preDomain) + + @staticmethod + def postDomain(request, response): + return pluginManagerGlobal.globalPlug(request, postDomain, response) + @staticmethod def preSaveConfigsToFile(request): return pluginManagerGlobal.globalPlug(request, preSaveConfigsToFile) diff --git a/websiteFunctions/signals.py b/websiteFunctions/signals.py index edae8427b..3876b7461 100644 --- a/websiteFunctions/signals.py +++ b/websiteFunctions/signals.py @@ -39,6 +39,13 @@ preWebsiteModification = Signal(providing_args=["request"]) ## This event is fired after CyberPanel core finished suspension of website postWebsiteModification = Signal(providing_args=["request", "response"]) + +## This event is fired before CyberPanel core load website launcher +preDomain = Signal(providing_args=["request"]) + +## This event is fired after CyberPanel core finished loading website launcher +postDomain = Signal(providing_args=["request", "response"]) + ## This event is fired before CyberPanel core start saving changes to vhost conf preSaveConfigsToFile = Signal(providing_args=["request"]) diff --git a/websiteFunctions/views.py b/websiteFunctions/views.py index 7d91ac470..265e0d7cd 100644 --- a/websiteFunctions/views.py +++ b/websiteFunctions/views.py @@ -211,9 +211,23 @@ def saveWebsiteChanges(request): def domain(request, domain): try: + if not request.GET._mutable: + request.GET._mutable = True + request.GET['domain'] = domain + + result = pluginManager.preDomain(request) + if result != 200: + return result + userID = request.session['userID'] wm = WebsiteManager(domain) - return wm.loadDomainHome(request, userID) + coreResult = wm.loadDomainHome(request, userID) + + result = pluginManager.postDomain(request, coreResult) + if result != 200: + return result + + return coreResult except KeyError: return redirect(loadLoginPage)