diff --git a/plogical/applicationInstaller.py b/plogical/applicationInstaller.py index 83e97ad36..8d42a05a7 100755 --- a/plogical/applicationInstaller.py +++ b/plogical/applicationInstaller.py @@ -17,6 +17,7 @@ from databases.models import Databases from plogical.installUtilities import installUtilities import shutil from plogical.processUtilities import ProcessUtilities +from random import randint class ApplicationInstaller(multi.Thread): @@ -39,14 +40,6 @@ class ApplicationInstaller(multi.Thread): self.installWordPress() elif self.installApp == 'joomla': self.installJoomla() - elif self.installApp == 'git': - self.setupGit() - elif self.installApp == 'pull': - self.gitPull() - elif self.installApp == 'detach': - self.detachRepo() - elif self.installApp == 'changeBranch': - self.changeBranch() elif self.installApp == 'prestashop': self.installPrestaShop() elif self.installApp == 'magento': @@ -55,10 +48,215 @@ class ApplicationInstaller(multi.Thread): self.convertDomainToSite() elif self.installApp == 'updatePackage': self.updatePackage() + elif self.installApp == 'mautic': + self.installMautic() except BaseException as msg: logging.writeToFile(str(msg) + ' [ApplicationInstaller.run]') + def installMautic(self): + try: + + admin = self.extraArgs['admin'] + domainName = self.extraArgs['domainName'] + home = self.extraArgs['home'] + tempStatusPath = self.extraArgs['tempStatusPath'] + self.tempStatusPath = tempStatusPath + username = self.extraArgs['username'] + password = self.extraArgs['password'] + email = self.extraArgs['email'] + + FNULL = open(os.devnull, 'w') + + ## Open Status File + + statusFile = open(tempStatusPath, 'w') + statusFile.writelines('Setting up paths,0') + statusFile.close() + + finalPath = '' + self.permPath = '' + + try: + website = ChildDomains.objects.get(domain=domainName) + externalApp = website.master.externalApp + self.masterDomain = website.master.domain + + if home == '0': + path = self.extraArgs['path'] + finalPath = website.path.rstrip('/') + "/" + path + "/" + else: + finalPath = website.path + + if website.master.package.dataBases > website.master.databases_set.all().count(): + pass + else: + raise BaseException("Maximum database limit reached for this website.") + + statusFile = open(tempStatusPath, 'w') + statusFile.writelines('Setting up Database,20') + statusFile.close() + + dbName, dbUser, dbPassword = self.dbCreation(tempStatusPath, website.master) + self.permPath = website.path + + except: + website = Websites.objects.get(domain=domainName) + externalApp = website.externalApp + self.masterDomain = website.domain + + if home == '0': + path = self.extraArgs['path'] + finalPath = "/home/" + domainName + "/public_html/" + path + "/" + else: + finalPath = "/home/" + domainName + "/public_html/" + + if website.package.dataBases > website.databases_set.all().count(): + pass + else: + raise BaseException("Maximum database limit reached for this website.") + + statusFile = open(tempStatusPath, 'w') + statusFile.writelines('Setting up Database,20') + statusFile.close() + + dbName, dbUser, dbPassword = self.dbCreation(tempStatusPath, website) + self.permPath = '/home/%s/public_html' % (website.domain) + + ## Security Check + + command = 'chmod 755 %s' % (self.permPath) + ProcessUtilities.executioner(command) + + if finalPath.find("..") > -1: + raise BaseException("Specified path must be inside virtual host home.") + + if not os.path.exists(finalPath): + command = 'mkdir -p ' + finalPath + ProcessUtilities.executioner(command, externalApp) + + ## checking for directories/files + + if self.dataLossCheck(finalPath, tempStatusPath) == 0: + raise BaseException('Directory is not empty.') + + #### + + statusFile = open(tempStatusPath, 'w') + statusFile.writelines('Downloading Mautic Core,30') + statusFile.close() + + command = "wget https://github.com/mautic/mautic/releases/download/3.1.0/3.1.0.zip" + ProcessUtilities.outputExecutioner(command, externalApp, None, finalPath) + + statusFile = open(tempStatusPath, 'w') + statusFile.writelines('Extracting Mautic Core,50') + statusFile.close() + + command = "unzip 3.1.0.zip" + ProcessUtilities.outputExecutioner(command, externalApp, None, finalPath) + + ## + + statusFile = open(tempStatusPath, 'w') + statusFile.writelines('Running Mautic installer,70') + statusFile.close() + + if home == '0': + path = self.extraArgs['path'] + finalURL = domainName + '/' + path + else: + finalURL = domainName + + localDB = "/home/cyberpanel/" + str(randint(1000, 9999)) + + localDBContent = """ 'localhost', + 'db_table_prefix' => null, + 'db_port' => 3306, + 'db_name' => '%s', + 'db_user' => '%s', + 'db_password' => '%s', + 'db_backup_tables' => true, + 'db_backup_prefix' => 'bak_', + 'admin_email' => '%s', + 'admin_password' => '%s', + 'mailer_transport' => null, + 'mailer_host' => null, + 'mailer_port' => null, + 'mailer_user' => null, + 'mailer_password' => null, + 'mailer_api_key' => null, + 'mailer_encryption' => null, + 'mailer_auth_mode' => null, +);""" % (dbName, dbUser, dbPassword, email, password) + + writeToFile = open(localDB, 'w') + writeToFile.write(localDBContent) + writeToFile.close() + + command = 'rm -rf %s/app/config/local.php' % (finalPath) + ProcessUtilities.executioner(command) + + command = 'mv %s %s/app/config/local.php' % (localDB, finalPath) + ProcessUtilities.executioner(command) + + command = "/usr/local/lsws/lsphp72/bin/php bin/console mautic:install http://%s" % (finalURL) + result = ProcessUtilities.outputExecutioner(command, 'root', None, finalPath) + + if result.find('Install complete') == -1: + raise BaseException(result) + + + ## + + from filemanager.filemanager import FileManager + + fm = FileManager(None, None) + fm.fixPermissions(self.masterDomain) + + installUtilities.reStartLiteSpeedSocket() + + statusFile = open(tempStatusPath, 'w') + statusFile.writelines("Successfully Installed. [200]") + statusFile.close() + return 0 + + + except BaseException as msg: + # remove the downloaded files + FNULL = open(os.devnull, 'w') + + homeDir = "/home/" + domainName + "/public_html" + + if ProcessUtilities.decideDistro() == ProcessUtilities.centos or ProcessUtilities.decideDistro() == ProcessUtilities.cent8: + groupName = 'nobody' + else: + groupName = 'nogroup' + + if not os.path.exists(homeDir): + command = "chown " + externalApp + ":" + groupName + " " + homeDir + ProcessUtilities.executioner(command, externalApp) + + try: + mysqlUtilities.deleteDatabase(dbName, dbUser) + db = Databases.objects.get(dbName=dbName) + db.delete() + except: + pass + + command = 'chmod 750 %s' % (self.permPath) + ProcessUtilities.executioner(command) + + + statusFile = open(self.tempStatusPath, 'w') + statusFile.writelines(str(msg) + " [404]") + statusFile.close() + return 0 + def updatePackage(self): try: diff --git a/static/images/icons/mautic.png b/static/images/icons/mautic.png new file mode 100644 index 000000000..734f1913e Binary files /dev/null and b/static/images/icons/mautic.png differ diff --git a/static/websiteFunctions/websiteFunctions.js b/static/websiteFunctions/websiteFunctions.js index 2b38c563e..efd6556d3 100644 --- a/static/websiteFunctions/websiteFunctions.js +++ b/static/websiteFunctions/websiteFunctions.js @@ -961,6 +961,7 @@ app.controller('websitePages', function ($scope, $http, $timeout, $window) { $scope.setupGit = $("#domainNamePage").text() + "/setupGit"; $scope.installPrestaURL = $("#domainNamePage").text() + "/installPrestaShop"; $scope.installMagentoURL = $("#domainNamePage").text() + "/installMagento"; + $scope.installMauticURL = $("#domainNamePage").text() + "/installMautic"; $scope.domainAliasURL = "/websites/" + $("#domainNamePage").text() + "/domainAlias"; $scope.previewUrl = "/preview/" + $("#domainNamePage").text() + "/"; @@ -5218,6 +5219,191 @@ app.controller('installPrestaShopCTRL', function ($scope, $http, $timeout) { }; +}); + +app.controller('installMauticCTRL', function ($scope, $http, $timeout) { + + $scope.installationDetailsForm = false; + $scope.installationProgress = true; + $scope.installationFailed = true; + $scope.installationSuccessfull = true; + $scope.couldNotConnect = true; + $scope.wpInstallLoading = true; + $scope.goBackDisable = true; + + $scope.databasePrefix = 'ps_'; + + var statusFile; + var domain = $("#domainNamePage").text(); + var path; + + + $scope.goBack = function () { + $scope.installationDetailsForm = false; + $scope.installationProgress = true; + $scope.installationFailed = true; + $scope.installationSuccessfull = true; + $scope.couldNotConnect = true; + $scope.wpInstallLoading = true; + $scope.goBackDisable = true; + $("#installProgress").css("width", "0%"); + }; + + function getInstallStatus() { + + url = "/websites/installWordpressStatus"; + + var data = { + statusFile: statusFile, + domainName: domain + }; + + 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.installationFailed = true; + $scope.installationSuccessfull = false; + $scope.couldNotConnect = true; + $scope.wpInstallLoading = true; + $scope.goBackDisable = false; + + if (typeof path !== 'undefined') { + $scope.installationURL = "http://" + domain + "/" + path; + } else { + $scope.installationURL = domain; + } + + + $("#installProgress").css("width", "100%"); + $scope.installPercentage = "100"; + $scope.currentStatus = response.data.currentStatus; + $timeout.cancel(); + + } else { + + $scope.installationDetailsForm = true; + $scope.installationProgress = false; + $scope.installationFailed = false; + $scope.installationSuccessfull = true; + $scope.couldNotConnect = true; + $scope.wpInstallLoading = true; + $scope.goBackDisable = false; + + $scope.errorMessage = response.data.error_message; + + $("#installProgress").css("width", "0%"); + $scope.installPercentage = "0"; + + } + + } else { + $("#installProgress").css("width", response.data.installationProgress + "%"); + $scope.installPercentage = response.data.installationProgress; + $scope.currentStatus = response.data.currentStatus; + + $timeout(getInstallStatus, 1000); + + + } + + } + + function cantLoadInitialDatas(response) { + + $scope.canNotFetch = true; + $scope.couldNotConnect = false; + + + } + + + } + + $scope.installMautic = function () { + + $scope.installationDetailsForm = true; + $scope.installationProgress = false; + $scope.installationFailed = true; + $scope.installationSuccessfull = true; + $scope.couldNotConnect = true; + $scope.wpInstallLoading = false; + $scope.goBackDisable = true; + $scope.currentStatus = "Starting installation.."; + + path = $scope.installPath; + + + url = "/websites/mauticInstall"; + + var home = "1"; + + if (typeof path !== 'undefined') { + home = "0"; + } + + + var data = { + domain: domain, + home: home, + path: path, + username: $scope.adminUserName, + email: $scope.email, + passwordByPass: $scope.password + }; + + var config = { + headers: { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + if (response.data.installStatus === 1) { + statusFile = response.data.tempStatusPath; + getInstallStatus(); + } else { + + $scope.installationDetailsForm = true; + $scope.installationProgress = false; + $scope.installationFailed = false; + $scope.installationSuccessfull = true; + $scope.couldNotConnect = true; + $scope.wpInstallLoading = true; + $scope.goBackDisable = false; + + $scope.errorMessage = response.data.error_message; + + } + + + } + + function cantLoadInitialDatas(response) { + } + + }; + + }); app.controller('sshAccess', function ($scope, $http, $timeout) { diff --git a/websiteFunctions/static/websiteFunctions/websiteFunctions.js b/websiteFunctions/static/websiteFunctions/websiteFunctions.js index 2b38c563e..efd6556d3 100755 --- a/websiteFunctions/static/websiteFunctions/websiteFunctions.js +++ b/websiteFunctions/static/websiteFunctions/websiteFunctions.js @@ -961,6 +961,7 @@ app.controller('websitePages', function ($scope, $http, $timeout, $window) { $scope.setupGit = $("#domainNamePage").text() + "/setupGit"; $scope.installPrestaURL = $("#domainNamePage").text() + "/installPrestaShop"; $scope.installMagentoURL = $("#domainNamePage").text() + "/installMagento"; + $scope.installMauticURL = $("#domainNamePage").text() + "/installMautic"; $scope.domainAliasURL = "/websites/" + $("#domainNamePage").text() + "/domainAlias"; $scope.previewUrl = "/preview/" + $("#domainNamePage").text() + "/"; @@ -5218,6 +5219,191 @@ app.controller('installPrestaShopCTRL', function ($scope, $http, $timeout) { }; +}); + +app.controller('installMauticCTRL', function ($scope, $http, $timeout) { + + $scope.installationDetailsForm = false; + $scope.installationProgress = true; + $scope.installationFailed = true; + $scope.installationSuccessfull = true; + $scope.couldNotConnect = true; + $scope.wpInstallLoading = true; + $scope.goBackDisable = true; + + $scope.databasePrefix = 'ps_'; + + var statusFile; + var domain = $("#domainNamePage").text(); + var path; + + + $scope.goBack = function () { + $scope.installationDetailsForm = false; + $scope.installationProgress = true; + $scope.installationFailed = true; + $scope.installationSuccessfull = true; + $scope.couldNotConnect = true; + $scope.wpInstallLoading = true; + $scope.goBackDisable = true; + $("#installProgress").css("width", "0%"); + }; + + function getInstallStatus() { + + url = "/websites/installWordpressStatus"; + + var data = { + statusFile: statusFile, + domainName: domain + }; + + 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.installationFailed = true; + $scope.installationSuccessfull = false; + $scope.couldNotConnect = true; + $scope.wpInstallLoading = true; + $scope.goBackDisable = false; + + if (typeof path !== 'undefined') { + $scope.installationURL = "http://" + domain + "/" + path; + } else { + $scope.installationURL = domain; + } + + + $("#installProgress").css("width", "100%"); + $scope.installPercentage = "100"; + $scope.currentStatus = response.data.currentStatus; + $timeout.cancel(); + + } else { + + $scope.installationDetailsForm = true; + $scope.installationProgress = false; + $scope.installationFailed = false; + $scope.installationSuccessfull = true; + $scope.couldNotConnect = true; + $scope.wpInstallLoading = true; + $scope.goBackDisable = false; + + $scope.errorMessage = response.data.error_message; + + $("#installProgress").css("width", "0%"); + $scope.installPercentage = "0"; + + } + + } else { + $("#installProgress").css("width", response.data.installationProgress + "%"); + $scope.installPercentage = response.data.installationProgress; + $scope.currentStatus = response.data.currentStatus; + + $timeout(getInstallStatus, 1000); + + + } + + } + + function cantLoadInitialDatas(response) { + + $scope.canNotFetch = true; + $scope.couldNotConnect = false; + + + } + + + } + + $scope.installMautic = function () { + + $scope.installationDetailsForm = true; + $scope.installationProgress = false; + $scope.installationFailed = true; + $scope.installationSuccessfull = true; + $scope.couldNotConnect = true; + $scope.wpInstallLoading = false; + $scope.goBackDisable = true; + $scope.currentStatus = "Starting installation.."; + + path = $scope.installPath; + + + url = "/websites/mauticInstall"; + + var home = "1"; + + if (typeof path !== 'undefined') { + home = "0"; + } + + + var data = { + domain: domain, + home: home, + path: path, + username: $scope.adminUserName, + email: $scope.email, + passwordByPass: $scope.password + }; + + var config = { + headers: { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + + $http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + + if (response.data.installStatus === 1) { + statusFile = response.data.tempStatusPath; + getInstallStatus(); + } else { + + $scope.installationDetailsForm = true; + $scope.installationProgress = false; + $scope.installationFailed = false; + $scope.installationSuccessfull = true; + $scope.couldNotConnect = true; + $scope.wpInstallLoading = true; + $scope.goBackDisable = false; + + $scope.errorMessage = response.data.error_message; + + } + + + } + + function cantLoadInitialDatas(response) { + } + + }; + + }); app.controller('sshAccess', function ($scope, $http, $timeout) { diff --git a/websiteFunctions/templates/websiteFunctions/installMautic.html b/websiteFunctions/templates/websiteFunctions/installMautic.html new file mode 100755 index 000000000..dbda62697 --- /dev/null +++ b/websiteFunctions/templates/websiteFunctions/installMautic.html @@ -0,0 +1,112 @@ +{% extends "baseTemplate/index.html" %} +{% load i18n %} +{% block title %}{% trans "Install Mautic - CyberPanel" %}{% endblock %} +{% block content %} + +{% load static %} +{% get_current_language as LANGUAGE_CODE %} + + +
+
+

{% trans "Install Mautic" %}

+

{% trans "One-click Mautic Install!" %}

+
+ + +
+
+

+ {{ domainName }} - {% trans "Installation Details" %} +

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

{$ currentStatus $}

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

{% trans "Installation failed. Error message:" %} {$ errorMessage $}

+
+ +
+

{% trans "Installation successful. Visit:" %} {$ installationURL $}

+
+ + + +
+

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

+
+ + +
+
+ +
+ +
+ +
+
+ + +
+ +
+
+
+ + + +
+ + +{% endblock %} \ No newline at end of file diff --git a/websiteFunctions/templates/websiteFunctions/website.html b/websiteFunctions/templates/websiteFunctions/website.html index 8363ce89a..e42060fc6 100755 --- a/websiteFunctions/templates/websiteFunctions/website.html +++ b/websiteFunctions/templates/websiteFunctions/website.html @@ -1048,6 +1048,17 @@ +
+ + + + + {% trans "Mautic" %} + +
+ diff --git a/websiteFunctions/urls.py b/websiteFunctions/urls.py index ce5861be1..d1edcb6a4 100755 --- a/websiteFunctions/urls.py +++ b/websiteFunctions/urls.py @@ -96,6 +96,11 @@ urlpatterns = [ url(r'^(?P(.*))/installMagento$', views.installMagento, name='installMagento'), url(r'^magentoInstall$', views.magentoInstall, name='magentoInstall'), + ## mautic + + url(r'^(?P(.*))/installMautic$', views.installMautic, name='installMautic'), + url(r'^mauticInstall$', views.mauticInstall, name='mauticInstall'), + ## Git url(r'^(?P(.*))/setupGit$', views.setupGit, name='setupGit'), diff --git a/websiteFunctions/views.py b/websiteFunctions/views.py index ee1a1ec5f..a6d656449 100755 --- a/websiteFunctions/views.py +++ b/websiteFunctions/views.py @@ -656,6 +656,22 @@ def magentoInstall(request): except KeyError: return redirect(loadLoginPage) +def installMautic(request, domain): + try: + userID = request.session['userID'] + wm = WebsiteManager(domain) + return wm.installMautic(request, userID) + except KeyError: + return redirect(loadLoginPage) + +def mauticInstall(request): + try: + userID = request.session['userID'] + wm = WebsiteManager() + return wm.mauticInstall(userID, json.loads(request.body)) + except KeyError: + return redirect(loadLoginPage) + def prestaShopInstall(request): try: userID = request.session['userID'] diff --git a/websiteFunctions/website.py b/websiteFunctions/website.py index 3c77f9425..c8acbf778 100755 --- a/websiteFunctions/website.py +++ b/websiteFunctions/website.py @@ -2310,6 +2310,64 @@ StrictHostKeyChecking no json_data = json.dumps(data_ret) return HttpResponse(json_data) + def installMautic(self, request=None, userID=None, data=None): + try: + currentACL = ACLManager.loadedACL(userID) + admin = Administrator.objects.get(pk=userID) + + if ACLManager.checkOwnership(self.domain, admin, currentACL) == 1: + pass + else: + return ACLManager.loadError() + + return render(request, 'websiteFunctions/installMautic.html', {'domainName': self.domain}) + except BaseException as msg: + return HttpResponse(str(msg)) + + def mauticInstall(self, userID=None, data=None): + try: + + currentACL = ACLManager.loadedACL(userID) + admin = Administrator.objects.get(pk=userID) + + self.domain = data['domain'] + + if ACLManager.checkOwnership(self.domain, admin, currentACL) == 1: + pass + else: + return ACLManager.loadErrorJson('installStatus', 0) + + mailUtilities.checkHome() + + extraArgs = {} + extraArgs['admin'] = admin + extraArgs['domainName'] = data['domain'] + extraArgs['home'] = data['home'] + extraArgs['username'] = data['username'] + extraArgs['email'] = data['email'] + extraArgs['password'] = data['passwordByPass'] + extraArgs['tempStatusPath'] = "/home/cyberpanel/" + str(randint(1000, 9999)) + + if data['home'] == '0': + extraArgs['path'] = data['path'] + + background = ApplicationInstaller('mautic', extraArgs) + background.start() + + time.sleep(2) + + data_ret = {'status': 1, 'installStatus': 1, 'error_message': 'None', + 'tempStatusPath': extraArgs['tempStatusPath']} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + ## Installation ends + + except BaseException as msg: + data_ret = {'status': 0, 'installStatus': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + def prestaShopInstall(self, userID=None, data=None): try: