diff --git a/baseTemplate/templates/baseTemplate/index.html b/baseTemplate/templates/baseTemplate/index.html index 3516383a2..c23d0282c 100755 --- a/baseTemplate/templates/baseTemplate/index.html +++ b/baseTemplate/templates/baseTemplate/index.html @@ -418,6 +418,9 @@
  • {% trans "Restore Backups" %}
  • +
  • {% trans "Remote Backup" %} +
  • diff --git a/websiteFunctions/models.py b/websiteFunctions/models.py index 34647f3e1..c9b1a8640 100755 --- a/websiteFunctions/models.py +++ b/websiteFunctions/models.py @@ -128,3 +128,22 @@ class WPSitesBackup(models.Model): WPSiteID = models.IntegerField(default=-1) WebsiteID = models.IntegerField(default=-1) config = models.TextField() + + +class RemoteBackupConfig(models.Model): + owner = models.ForeignKey(Administrator, on_delete=models.CASCADE) + configtype = models.CharField(max_length=255, default='') + config = models.TextField() + +class RemoteBackupSchedule(models.Model): + RemoteBackupConfig = models.ForeignKey(RemoteBackupConfig, on_delete=models.CASCADE) + Name = models.CharField(max_length=255, default='') + timeintervel = models.CharField(max_length=200) + fileretention = models.CharField(max_length=200) + lastrun = models.CharField(max_length=200) + config = models.TextField() + +class RemoteBackupsites(models.Model): + owner = models.ForeignKey(RemoteBackupSchedule, on_delete=models.CASCADE) + WPsites = models.IntegerField(null=True) + database = models.IntegerField(null=True) diff --git a/websiteFunctions/static/websiteFunctions/websiteFunctions.js b/websiteFunctions/static/websiteFunctions/websiteFunctions.js index 61b512882..c743a525d 100755 --- a/websiteFunctions/static/websiteFunctions/websiteFunctions.js +++ b/websiteFunctions/static/websiteFunctions/websiteFunctions.js @@ -521,7 +521,7 @@ app.controller('WPsiteHome', function ($scope, $http, $timeout, $compile, $windo if (response.data.ret_data.maintenanceMode === 1) { $('#maintenanceMode').prop('checked', true); } - if(response.data.ret_data.wpcron === 1) { + if (response.data.ret_data.wpcron === 1) { $('#wpcron').prop('checked', true); } if (response.data.ret_data.passwordprotection == 1) { @@ -589,8 +589,7 @@ app.controller('WPsiteHome', function ($scope, $http, $timeout, $compile, $windo PPPassword: $scope.PPPassword, } - } - else { + } else { var data = { WPid: $('#WPid').html(), setting: setting, @@ -633,7 +632,7 @@ app.controller('WPsiteHome', function ($scope, $http, $timeout, $compile, $windo text: 'Successfully Updated!.', type: 'success' }); - if (setting === "PasswordProtection"){ + if (setting === "PasswordProtection") { location.reload(); } } else { @@ -642,7 +641,7 @@ app.controller('WPsiteHome', function ($scope, $http, $timeout, $compile, $windo text: response.data.error_message, type: 'error' }); - if (setting === "PasswordProtection"){ + if (setting === "PasswordProtection") { location.reload(); } @@ -1955,6 +1954,217 @@ app.controller('RestoreWPBackup', function ($scope, $http, $timeout, $window) { }); +//.......................................Remote Backup + +//........... delete DeleteBackupConfigNow + +function DeleteBackupConfigNow(url) { + window.location.href = url; +} +function DeleteRemoteBackupsiteNow(url) { + window.location.href = url; +} +function DeleteBackupfileConfigNow(url) { + window.location.href = url; +} + + +app.controller('RemoteBackupConfig', function ($scope, $http, $timeout, $window) { + $scope.RemoteBackupLoading = true; + $scope.SFTPBackUpdiv = true; + $scope.S3backupdiv = true; + $scope.SelectRemoteBackuptype = function () { + var val = $scope.RemoteBackuptype; + if (val == "SFTP") { + $scope.SFTPBackUpdiv = false; + $scope.S3backupdiv = true; + } else { + $scope.S3backupdiv = false; + $scope.SFTPBackUpdiv = true; + } + } + + $scope.SaveBackupConfig = function () { + $scope.RemoteBackupLoading = false; + var Hname = $scope.Hostname; + var Uname = $scope.Username; + var Passwd = $scope.Password; + var path = $scope.path; + var type = $scope.RemoteBackuptype; + + if (type == "SFTP") { + + var data = { + Hname: Hname, + Uname: Uname, + Passwd: Passwd, + path: path, + type: type + } + var url = "/websites/SaveBackupConfig"; + + + var config = { + headers: { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + $http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.RemoteBackupLoading = true; + if (response.data.status === 1) { + new PNotify({ + title: 'Success!', + text: 'Successfully Saved!.', + type: 'success' + }); + location.reload(); + + + } else { + new PNotify({ + title: 'Error!', + text: response.data.error_message, + type: 'error' + }); + } + } + + function cantLoadInitialDatas(response) { + $scope.RemoteBackupLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type: 'error' + }); + + + } + } + + + } + +}); + + +app.controller('BackupSchedule', function ($scope, $http, $timeout, $window) { + $scope.BackupScheduleLoading = true; + $scope.SaveBackupSchedule = function () { + $scope.RemoteBackupLoading = false; + var FileRetention = $scope.Fretention; + var Backfrequency = $scope.Bfrequency; + + + var data = { + FileRetention: FileRetention, + Backfrequency: Backfrequency, + ScheduleName: $scope.ScheduleName, + RemoteConfigID : $('#RemoteConfigID').html(), + BackupType: $scope.BackupType + } + var url = "/websites/SaveBackupSchedule"; + + + var config = { + headers: { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + $http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.RemoteBackupLoading = true; + if (response.data.status === 1) { + new PNotify({ + title: 'Success!', + text: 'Successfully Saved!.', + type: 'success' + }); + location.reload(); + + + } else { + new PNotify({ + title: 'Error!', + text: response.data.error_message, + type: 'error' + }); + } + } + + function cantLoadInitialDatas(response) { + $scope.RemoteBackupLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type: 'error' + }); + + + } + + + } + + + $scope.AddWPsiteforRemoteBackup = function () { + $scope.RemoteBackupLoading = false; + + + + var data = { + WpsiteID: $('#Wpsite').val(), + RemoteScheduleID : $('#RemoteScheduleID').html() + } + var url = "/websites/AddWPsiteforRemoteBackup"; + + + var config = { + headers: { + 'X-CSRFToken': getCookie('csrftoken') + } + }; + $http.post(url, data, config).then(ListInitialDatas, cantLoadInitialDatas); + + + function ListInitialDatas(response) { + $scope.RemoteBackupLoading = true; + if (response.data.status === 1) { + new PNotify({ + title: 'Success!', + text: 'Successfully Saved!.', + type: 'success' + }); + location.reload(); + + + } else { + new PNotify({ + title: 'Error!', + text: response.data.error_message, + type: 'error' + }); + } + } + + function cantLoadInitialDatas(response) { + $scope.RemoteBackupLoading = true; + new PNotify({ + title: 'Operation Failed!', + text: response.data.error_message, + type: 'error' + }); + + + } + + + } +}); /* Java script code to create account */ app.controller('createWebsite', function ($scope, $http, $timeout, $window) { diff --git a/websiteFunctions/templates/websiteFunctions/AddRemoteBackupSite.html b/websiteFunctions/templates/websiteFunctions/AddRemoteBackupSite.html new file mode 100644 index 000000000..583492b0a --- /dev/null +++ b/websiteFunctions/templates/websiteFunctions/AddRemoteBackupSite.html @@ -0,0 +1,87 @@ +{% extends "baseTemplate/index.html" %} +{% load i18n %} +{% block title %}{% trans "Backup Sites Configurations - CyberPanel" %}{% endblock %} +{% block content %} + + {% load static %} + {% get_current_language as LANGUAGE_CODE %} + + +
    +
    +

    {% trans "Backup Sites Configurations" %}

    +
    + + +
    +
    +

    + {% trans " Add WordPress Sites for Remote Backup" %} +

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

    + {% trans "Saved Sites For Remote Backup" %}

    + + + + + + + + + + + {% for sub in RemoteBackupsites %} + + + + + + {% endfor %} + +
    IDWordPress TitleAction
    {{ sub.id }}{{ sub.Title }} + + +
    + +
    +
    + + +
    + + +{% endblock %} diff --git a/websiteFunctions/templates/websiteFunctions/BackupfileConfig.html b/websiteFunctions/templates/websiteFunctions/BackupfileConfig.html new file mode 100644 index 000000000..ce8819d25 --- /dev/null +++ b/websiteFunctions/templates/websiteFunctions/BackupfileConfig.html @@ -0,0 +1,127 @@ +{% extends "baseTemplate/index.html" %} +{% load i18n %} +{% block title %}{% trans "File Config - CyberPanel" %}{% endblock %} +{% block content %} + + {% load static %} + {% get_current_language as LANGUAGE_CODE %} + + +
    +
    +

    {% trans "Backup File Configurations" %}

    +
    + + +
    +
    +

    + {% trans " Schedule Backups" %} +

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

    + {% trans "Configure Backup Schedules" %}

    + + + + + + + + + + + + {% for sub in Backupschedule %} + + + + + + + {% endfor %} + +
    IDSchedule NameRemote Configuration + Action
    {{ sub.id }}{{ sub.Name }}{{ sub.RemoteConfiguration }} + + + Add WordPress Sites + +
    + +
    +
    + + +
    + + +{% endblock %} diff --git a/websiteFunctions/templates/websiteFunctions/RemoteBackupConfig.html b/websiteFunctions/templates/websiteFunctions/RemoteBackupConfig.html new file mode 100644 index 000000000..5b18dc1f3 --- /dev/null +++ b/websiteFunctions/templates/websiteFunctions/RemoteBackupConfig.html @@ -0,0 +1,131 @@ +{% extends "baseTemplate/index.html" %} +{% load i18n %} +{% block title %}{% trans "Remote Backup Configurations - CyberPanel" %}{% endblock %} +{% block content %} + + {% load static %} + {% get_current_language as LANGUAGE_CODE %} + + +
    +
    +

    {% trans "Remote Backup Configurations" %}

    +
    + + +
    +
    +

    + {% trans "Configure Remote Backups" %} +

    +
    + +
    + +
    + +
    + +
    +
    + + +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    + +
    + S3 BAckups +
    + + +
    + +
    + + +
    +
    + + +
    + +
    +

    + {% trans "Saved Remote Configuration" %}

    + + + + + + + + + + + + {% for sub in backupconfigs %} + + + + + + + {% endfor %} + +
    Backup TypeHostNamePathAction
    {{ sub.Type }}{{ sub.HostName }}{{ sub.Path }} + + Schedule Backups +
    +
    +
    + + + +
    + + +{% endblock %} diff --git a/websiteFunctions/urls.py b/websiteFunctions/urls.py index 82253f0e5..9d812686a 100755 --- a/websiteFunctions/urls.py +++ b/websiteFunctions/urls.py @@ -23,6 +23,9 @@ urlpatterns = [ url(r'^RestoreBackups$', views.RestoreBackups, name='RestoreBackups'), url(r'^RestoreHome$', views.RestoreHome, name='RestoreHome'), url(r'^AutoLogin$', views.AutoLogin, name='AutoLogin'), + url(r'^RemoteBackupConfig$', views.RemoteBackupConfig, name='RemoteBackupConfig'), + url(r'^BackupfileConfig$', views.BackupfileConfig, name='BackupfileConfig'), + url(r'^AddRemoteBackupsite$', views.AddRemoteBackupsite, name='AddRemoteBackupsite'), ###WordPress Ajax @@ -44,9 +47,11 @@ urlpatterns = [ url(r'^DeploytoProduction', views.DeploytoProduction, name='DeploytoProduction'), url(r'^WPCreateBackup', views.WPCreateBackup, name='WPCreateBackup'), url(r'^RestoreWPbackupNow', views.RestoreWPbackupNow, name='RestoreWPbackupNow'), - url(r'^RestoreWPbackupNow', views.RestoreWPbackupNow, name='RestoreWPbackupNow'), url(r'^dataintegrity', views.dataintegrity, name='dataintegrity'), url(r'^installwpcore', views.installwpcore, name='installwpcore'), + url(r'^SaveBackupConfig', views.SaveBackupConfig, name='SaveBackupConfig'), + url(r'^SaveBackupSchedule', views.SaveBackupSchedule, name='SaveBackupSchedule'), + url(r'^AddWPsiteforRemoteBackup', views.AddWPsiteforRemoteBackup, name='AddWPsiteforRemoteBackup'), diff --git a/websiteFunctions/views.py b/websiteFunctions/views.py index 726dac42c..96bc48d33 100755 --- a/websiteFunctions/views.py +++ b/websiteFunctions/views.py @@ -65,6 +65,40 @@ def RestoreHome(request): return wm.RestoreHome(request, userID, BackupID) except KeyError: return redirect(loadLoginPage) + + +def RemoteBackupConfig(request): + try: + userID = request.session['userID'] + + DeleteID = request.GET.get('DeleteID') + wm = WebsiteManager() + return wm.RemoteBackupConfig(request, userID, DeleteID) + except KeyError: + return redirect(loadLoginPage) + +def BackupfileConfig(request): + try: + userID = request.session['userID'] + + ID = request.GET.get('ID') + DeleteID = request.GET.get('DeleteID') + wm = WebsiteManager() + return wm.BackupfileConfig(request, userID, ID, DeleteID) + except KeyError: + return redirect(loadLoginPage) + +def AddRemoteBackupsite(request): + try: + userID = request.session['userID'] + + ID = request.GET.get('ID') + DeleteSiteID = request.GET.get('DeleteID') + wm = WebsiteManager() + return wm.AddRemoteBackupsite(request, userID, ID,DeleteSiteID ) + except KeyError: + return redirect(loadLoginPage) + def RestoreBackups(request): try: userID = request.session['userID'] @@ -407,6 +441,67 @@ def RestoreWPbackupNow(request): return redirect(loadLoginPage) +def SaveBackupConfig(request): + try: + userID = request.session['userID'] + + result = pluginManager.preWebsiteCreation(request) + if result != 200: + return result + + wm = WebsiteManager() + coreResult = wm.SaveBackupConfig(userID, json.loads(request.body)) + + result = pluginManager.postWebsiteCreation(request, coreResult) + if result != 200: + return result + + return coreResult + + except KeyError: + return redirect(loadLoginPage) + +def SaveBackupSchedule(request): + try: + userID = request.session['userID'] + + result = pluginManager.preWebsiteCreation(request) + if result != 200: + return result + + wm = WebsiteManager() + coreResult = wm.SaveBackupSchedule(userID, json.loads(request.body)) + + result = pluginManager.postWebsiteCreation(request, coreResult) + if result != 200: + return result + + return coreResult + + except KeyError: + return redirect(loadLoginPage) + +def AddWPsiteforRemoteBackup(request): + try: + userID = request.session['userID'] + + result = pluginManager.preWebsiteCreation(request) + if result != 200: + return result + + wm = WebsiteManager() + coreResult = wm.AddWPsiteforRemoteBackup(userID, json.loads(request.body)) + + result = pluginManager.postWebsiteCreation(request, coreResult) + if result != 200: + return result + + return coreResult + + except KeyError: + return redirect(loadLoginPage) + + def installwpcore(request): try: userID = request.session['userID'] diff --git a/websiteFunctions/website.py b/websiteFunctions/website.py index 5aac1f113..7fb91ae6e 100755 --- a/websiteFunctions/website.py +++ b/websiteFunctions/website.py @@ -4,6 +4,7 @@ import os.path import sys import django +from databases.models import Databases from plogical.httpProc import httpProc sys.path.append('/usr/local/CyberCP') @@ -12,7 +13,7 @@ django.setup() import json from plogical.acl import ACLManager import plogical.CyberCPLogFileWriter as logging -from websiteFunctions.models import Websites, ChildDomains, GitLogs, wpplugins, WPSites, WPStaging, WPSitesBackup +from websiteFunctions.models import Websites, ChildDomains, GitLogs, wpplugins, WPSites, WPStaging, WPSitesBackup, RemoteBackupConfig,RemoteBackupSchedule, RemoteBackupsites from plogical.virtualHostUtilities import virtualHostUtilities import subprocess import shlex @@ -202,6 +203,100 @@ class WebsiteManager: else: return redirect("https://cyberpanel.net/cyberpanel-addons") + + def RemoteBackupConfig(self, request=None, userID=None, DeleteID=None ): + Data = {} + currentACL = ACLManager.loadedACL(userID) + admin = Administrator.objects.get(pk=userID) + try: + if DeleteID != None: + BackupconfigDelete = RemoteBackupConfig.objects.get(pk=DeleteID) + BackupconfigDelete.delete() + except: + pass + + if ACLManager.CheckForPremFeature('wp-manager'): + + Data['WPsites'] = ACLManager.GetALLWPObjects(currentACL, userID) + allcon = RemoteBackupConfig.objects.all() + Data['backupconfigs'] =[] + for i in allcon: + configr = json.loads(i.config) + Data['backupconfigs'].append({ + 'id':i.pk, + 'Type': i.configtype, + 'HostName': configr['Hostname'], + 'Path': configr['Path'] + }) + proc = httpProc(request, 'websiteFunctions/RemoteBackupConfig.html', + Data, 'createWebsite') + return proc.render() + else: + return redirect("https://cyberpanel.net/cyberpanel-addons") + + + def BackupfileConfig(self, request=None, userID=None, RemoteConfigID=None, DeleteID=None ): + Data = {} + currentACL = ACLManager.loadedACL(userID) + admin = Administrator.objects.get(pk=userID) + + Data['RemoteConfigID'] = RemoteConfigID + RemoteConfigobj = RemoteBackupConfig.objects.get(pk=RemoteConfigID) + try: + if DeleteID != None: + RemoteBackupConfigDelete = RemoteBackupSchedule.objects.get(pk=DeleteID) + RemoteBackupConfigDelete.delete() + except: + pass + + if ACLManager.CheckForPremFeature('wp-manager'): + Data['WPsites'] = ACLManager.GetALLWPObjects(currentACL, userID) + allsechedule = RemoteBackupSchedule.objects.filter(RemoteBackupConfig=RemoteConfigobj) + Data['Backupschedule'] = [] + for i in allsechedule: + Data['Backupschedule'].append({ + 'id': i.pk, + 'Name': i.Name, + 'RemoteConfiguration': i.RemoteBackupConfig.configtype + }) + proc = httpProc(request, 'websiteFunctions/BackupfileConfig.html', + Data, 'createWebsite') + return proc.render() + else: + return redirect("https://cyberpanel.net/cyberpanel-addons") + + + def AddRemoteBackupsite(self, request=None, userID=None, RemoteScheduleID=None , DeleteSiteID=None): + Data = {} + currentACL = ACLManager.loadedACL(userID) + admin = Administrator.objects.get(pk=userID) + + Data['RemoteScheduleID'] = RemoteScheduleID + RemoteBackupScheduleobj= RemoteBackupSchedule.objects.get(pk=RemoteScheduleID) + + try: + if DeleteSiteID != None: + RemoteBackupsitesDelete = RemoteBackupsites.objects.get(pk=DeleteSiteID) + RemoteBackupsitesDelete.delete() + except: + pass + + if ACLManager.CheckForPremFeature('wp-manager'): + Data['WPsites'] = ACLManager.GetALLWPObjects(currentACL, userID) + allRemoteBackupsites = RemoteBackupsites.objects.filter(owner=RemoteBackupScheduleobj) + Data['RemoteBackupsites'] = [] + for i in allRemoteBackupsites: + wpsite = WPSites.objects.get(pk=i.WPsites) + Data['RemoteBackupsites'].append({ + 'id': i.pk, + 'Title': wpsite.title, + }) + proc = httpProc(request, 'websiteFunctions/AddRemoteBackupSite.html', + Data, 'createWebsite') + return proc.render() + else: + return redirect("https://cyberpanel.net/cyberpanel-addons") + def RestoreBackups(self, request=None, userID=None, DeleteID=None): Data = {} currentACL = ACLManager.loadedACL(userID) @@ -1033,6 +1128,118 @@ class WebsiteManager: return HttpResponse(json_data) + + def SaveBackupConfig(self, userID=None, data=None): + try: + + currentACL = ACLManager.loadedACL(userID) + admin = Administrator.objects.get(pk=userID) + ConfigType = data['type'] + if ConfigType == 'SFTP': + Hname = data['Hname'] + Uname = data['Uname'] + Passwd = data['Passwd'] + path = data['path'] + config = { + "Hostname": Hname, + "Username": Uname, + "Password": Passwd, + "Path": path + } + mkobj = RemoteBackupConfig(owner=admin, configtype=ConfigType, config=json.dumps(config)) + mkobj.save() + + + time.sleep(1) + + data_ret = {'status': 1, 'error_message': 'None',} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException as msg: + data_ret = {'status': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + + def SaveBackupSchedule(self, userID=None, data=None): + try: + + currentACL = ACLManager.loadedACL(userID) + admin = Administrator.objects.get(pk=userID) + FileRetention = data['FileRetention'] + Backfrequency = data['Backfrequency'] + ScheduleName = data['ScheduleName'] + RemoteConfigID = data['RemoteConfigID'] + BackupType = data['BackupType'] + config = { + 'BackupType': BackupType + } + + RemoteBackupConfigobj = RemoteBackupConfig.objects.get(pk=RemoteConfigID) + + svobj = RemoteBackupSchedule( RemoteBackupConfig=RemoteBackupConfigobj, Name=ScheduleName, + timeintervel=Backfrequency, fileretention=FileRetention, config=json.dumps(config), + lastrun=str(time.time())) + svobj.save() + + data_ret = {'status': 1, 'error_message': 'None',} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException as msg: + data_ret = {'status': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + + def AddWPsiteforRemoteBackup(self, userID=None, data=None): + try: + + currentACL = ACLManager.loadedACL(userID) + admin = Administrator.objects.get(pk=userID) + WPid = data['WpsiteID'] + RemoteScheduleID = data['RemoteScheduleID'] + + wpsiteobj = WPSites.objects.get(pk=WPid) + WPpath = wpsiteobj.path + VHuser = wpsiteobj.owner.externalApp + PhpVersion = wpsiteobj.owner.phpSelection + php = PHPManager.getPHPString(PhpVersion) + FinalPHPPath = '/usr/local/lsws/lsphp%s/bin/php' % (php) + + ####Get DB Name + + command = 'sudo -u %s %s -d error_reporting=0 /usr/bin/wp config get DB_NAME --skip-plugins --skip-themes --path=%s' % ( + VHuser, FinalPHPPath, WPpath) + result, stdout = ProcessUtilities.outputExecutioner(command, None, None, None, 1) + + if stdout.find('Error:') > -1: + raise BaseException(stdout) + else: + Finaldbname = stdout.rstrip("\n") + + ## Get DB obj + try: + DBobj = Databases.objects.get(dbName=Finaldbname) + except: + raise BaseException(str("DataBase Not Found")) + RemoteScheduleIDobj = RemoteBackupSchedule.objects.get(pk=RemoteScheduleID) + + svobj = RemoteBackupsites( owner=RemoteScheduleIDobj, WPsites = WPid, database = DBobj.pk) + svobj.save() + + data_ret = {'status': 1, 'error_message': 'None',} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + except BaseException as msg: + data_ret = {'status': 0, 'error_message': str(msg)} + json_data = json.dumps(data_ret) + return HttpResponse(json_data) + + + def installwpcore(self, userID=None, data=None): try: