mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-07 22:06:05 +01:00
feature: configure server mailer for CyberPanel notifications
This commit is contained in:
@@ -797,6 +797,8 @@
|
||||
<div class="sidebar-submenu">
|
||||
|
||||
<ul>
|
||||
<li><a href="{% url 'serverMail' %}"
|
||||
title="{% trans 'Server Mail' %}"><span>{% trans "Server Mail" %}</span></a></li>
|
||||
<li><a href="{% url 'accessLogs' %}"
|
||||
title="{% trans 'Access Log' %}"><span>{% trans "Access Log" %}</span></a></li>
|
||||
<li><a href="{% url 'errorLogs' %}"
|
||||
|
||||
@@ -8,11 +8,32 @@ class CyberCPLogFileWriter:
|
||||
fileName = "/home/cyberpanel/error-logs.txt"
|
||||
|
||||
@staticmethod
|
||||
def SendEmail(sender, receivers, message):
|
||||
def SendEmail(sender, receivers, message, subject=None, type=None):
|
||||
try:
|
||||
smtpObj = smtplib.SMTP('localhost')
|
||||
smtpObj.sendmail(sender, receivers, message)
|
||||
print("Successfully sent email")
|
||||
smtpPath = '/home/cyberpanel/smtpDetails'
|
||||
|
||||
if os.path.exists(smtpPath):
|
||||
import json
|
||||
|
||||
mailSettings = json.loads(open(smtpPath, 'r').read())
|
||||
smtpHost = mailSettings['smtpHost']
|
||||
smtpPort = mailSettings['smtpPort']
|
||||
smtpUserName = mailSettings['smtpUserName']
|
||||
smtpPassword = mailSettings['smtpPassword']
|
||||
|
||||
smtpServer = smtplib.SMTP(str(smtpHost), int(smtpPort))
|
||||
smtpServer.login(smtpUserName, smtpPassword)
|
||||
|
||||
##
|
||||
|
||||
if subject != None:
|
||||
message = 'Subject: {}\n\n{}'.format(subject, message)
|
||||
|
||||
smtpServer.sendmail(smtpUserName, receivers, message)
|
||||
else:
|
||||
smtpObj = smtplib.SMTP('localhost')
|
||||
smtpObj.sendmail(sender, receivers, message)
|
||||
print("Successfully sent email")
|
||||
except BaseException as msg:
|
||||
CyberCPLogFileWriter.writeToFile(str(msg))
|
||||
|
||||
|
||||
@@ -9,6 +9,11 @@ from IncBackups.IncBackupsControl import IncJobs
|
||||
from IncBackups.models import BackupJob
|
||||
from random import randint
|
||||
import argparse
|
||||
import json
|
||||
from websiteFunctions.models import GitLogs, Websites
|
||||
from websiteFunctions.website import WebsiteManager
|
||||
import time
|
||||
|
||||
try:
|
||||
from plogical.virtualHostUtilities import virtualHostUtilities
|
||||
from plogical.mailUtilities import mailUtilities
|
||||
@@ -18,6 +23,7 @@ except:
|
||||
|
||||
class IncScheduler():
|
||||
logPath = '/home/cyberpanel/incbackuplogs'
|
||||
gitFolder = '/home/cyberpanel/git'
|
||||
|
||||
@staticmethod
|
||||
def startBackup(type):
|
||||
@@ -82,6 +88,76 @@ class IncScheduler():
|
||||
except BaseException as msg:
|
||||
logging.writeToFile(str(msg))
|
||||
|
||||
@staticmethod
|
||||
def git(type):
|
||||
try:
|
||||
for website in os.listdir(IncScheduler.gitFolder):
|
||||
finalText = ''
|
||||
web = Websites.objects.get(domain=website)
|
||||
|
||||
message = '[%s Cron] Checking if %s has any pending commits on %s.' % (type, website, time.strftime("%m.%d.%Y_%H-%M-%S"))
|
||||
finalText = '%s\n' % (message)
|
||||
GitLogs(owner=web, type='INFO', message = message).save()
|
||||
|
||||
finalPathInside = '%s/%s' % (IncScheduler.gitFolder, website)
|
||||
|
||||
for file in os.listdir(finalPathInside):
|
||||
if file.find('public_html') > -1:
|
||||
finalPath = '/home/%s/public_html' % (website)
|
||||
finalPathConf = '%s/%s' % (finalPathInside, file)
|
||||
elif file.find('vmail') > -1:
|
||||
finalPath = '/home/vmail/%s' % (website)
|
||||
finalPathConf = '%s/%s' % (finalPathInside, file)
|
||||
else:
|
||||
finalPath = '/var/lib/mysql/%s' % (file)
|
||||
finalPathConf = '%s/%s' % (finalPathInside, file)
|
||||
|
||||
gitConf = json.loads(open(finalPathConf, 'r').read())
|
||||
data = {}
|
||||
data['domain'] = website
|
||||
data['folder'] = finalPath
|
||||
data['commitMessage'] = 'Auto commit by CyberPanel %s cron on %s.' % (type, time.strftime('%m.%d.%Y_%H-%M-%S'))
|
||||
|
||||
|
||||
if gitConf['autoCommit'] == type:
|
||||
|
||||
wm = WebsiteManager()
|
||||
resp = wm.commitChanges(1, data)
|
||||
logging.writeToFile(resp.content)
|
||||
resp = json.loads(resp.content)
|
||||
|
||||
message = 'Folder: %s, Status: %s' % (finalPath, resp['commandStatus'])
|
||||
finalText = '%s\n%s' % (finalText, message)
|
||||
|
||||
if resp['status'] == 1:
|
||||
GitLogs(owner=web, type='INFO', message=message).save()
|
||||
else:
|
||||
GitLogs(owner=web, type='ERROR', message=message).save()
|
||||
|
||||
if gitConf['autoPush'] == type:
|
||||
|
||||
wm = WebsiteManager()
|
||||
resp = wm.gitPush(1, data)
|
||||
resp = json.loads(resp.content)
|
||||
|
||||
if resp['status'] == 1:
|
||||
GitLogs(owner=web, type='INFO', message=resp['commandStatus']).save()
|
||||
finalText = '%s\n%s' % (finalText, resp['commandStatus'])
|
||||
else:
|
||||
GitLogs(owner=web, type='ERROR', message=resp['commandStatus']).save()
|
||||
finalText = '%s\n%s' % (finalText, resp['commandStatus'])
|
||||
|
||||
|
||||
message = '[%s Cron] Finished checking for %s on %s.' % (type, website, time.strftime("%m.%d.%Y_%H-%M-%S"))
|
||||
finalText = '%s\n%s' % (finalText, message)
|
||||
logging.SendEmail(web.adminEmail, web.adminEmail, finalText, 'Git report for %s.' % (web.domain))
|
||||
GitLogs(owner=web, type='INFO', message=message).save()
|
||||
|
||||
except BaseException as msg:
|
||||
logging.writeToFile('%s. [IncScheduler.git:90]' % (str(msg)))
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -90,6 +166,7 @@ def main():
|
||||
args = parser.parse_args()
|
||||
|
||||
IncScheduler.startBackup(args.function)
|
||||
IncScheduler.git(args.function)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
import subprocess
|
||||
|
||||
command = 'git -C /home/usman/Backup/CyberCP commit -m "Auto commit by CyberPanel Daily cron on"'
|
||||
print(subprocess.check_output(command, shell=True).decode("utf-8"))
|
||||
File diff suppressed because it is too large
Load Diff
88
serverLogs/templates/serverLogs/serverMail.html
Executable file
88
serverLogs/templates/serverLogs/serverMail.html
Executable file
@@ -0,0 +1,88 @@
|
||||
{% extends "baseTemplate/index.html" %}
|
||||
{% load i18n %}
|
||||
{% block title %}{% trans "Server Mail - CyberPanel" %}{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{% load static %}
|
||||
{% get_current_language as LANGUAGE_CODE %}
|
||||
<!-- Current language: {{ LANGUAGE_CODE }} -->
|
||||
|
||||
|
||||
<div class="container">
|
||||
<div id="page-title">
|
||||
<h2>{% trans "Manage Server Mail" %}</h2>
|
||||
<p>{% trans "On this page you can configure how CyberPanel send mails. (Notifications or Errors from CyberPanel)" %}</p>
|
||||
</div>
|
||||
<div ng-controller="serverMail" class="panel">
|
||||
<div class="panel-body">
|
||||
<h3 class="title-hero">
|
||||
{% trans "Manage SMTP Hosts" %} <img ng-hide="cyberPanelLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
</h3>
|
||||
<div class="example-box-wrapper">
|
||||
|
||||
|
||||
<form action="/" class="form-horizontal bordered-row">
|
||||
|
||||
<!---- Create SMTP Host --->
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Mailer" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-change="mailerSettings()" ng-model="mailer" class="form-control">
|
||||
<option>Default</option>
|
||||
<option>SMTP</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "SMTP Host" %}</label>
|
||||
<div ng-init="smtpHost='{{ smtpHost }}'" class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="smtpHost" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Port" %}</label>
|
||||
<div ng-init="smtpPort='{{ smtpPort }}'" class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="smtpPort" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Username" %}</label>
|
||||
<div ng-init="smtpUserName='{{ smtpUserName }}'" class="col-sm-6">
|
||||
<input type="text" class="form-control" ng-model="smtpUserName" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Password" %}</label>
|
||||
<div ng-init="smtpPassword='{{ smtpPassword }}'" class="col-sm-6">
|
||||
<input type="password" class="form-control" ng-model="smtpPassword" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label"></label>
|
||||
<div class="col-sm-4">
|
||||
<button type="button" ng-click="saveSMTPSettings()"
|
||||
class="btn btn-primary btn-lg btn-block">{% trans "Save" %}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!---- Create SMTP Host --->
|
||||
|
||||
</form>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{% endblock %}
|
||||
@@ -10,5 +10,6 @@ urlpatterns = [
|
||||
url(r'^modSecAuditLogs', views.modSecAuditLogs, name='modSecAuditLogs'),
|
||||
url(r'^getLogsFromFile',views.getLogsFromFile, name="getLogsFromFile"),
|
||||
url(r'^clearLogFile',views.clearLogFile, name="clearLogFile"),
|
||||
|
||||
url(r'^serverMail$', views.serverMail, name="serverMail"),
|
||||
url(r'^saveSMTPSettings$', views.saveSMTPSettings, name="saveSMTPSettings"),
|
||||
]
|
||||
@@ -203,3 +203,90 @@ def clearLogFile(request):
|
||||
data_ret = {'cleanStatus': 0, 'error_message': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
def serverMail(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadError()
|
||||
|
||||
smtpPath = '/home/cyberpanel/smtpDetails'
|
||||
data = {}
|
||||
|
||||
if os.path.exists(smtpPath):
|
||||
mailSettings = json.loads(open(smtpPath, 'r').read())
|
||||
data['smtpHost'] = mailSettings['smtpHost']
|
||||
data['smtpPort'] = mailSettings['smtpPort']
|
||||
data['smtpUserName'] = mailSettings['smtpUserName']
|
||||
data['smtpPassword'] = mailSettings['smtpPassword']
|
||||
|
||||
return render(request,'serverLogs/serverMail.html', data)
|
||||
|
||||
except KeyError as msg:
|
||||
logging.CyberCPLogFileWriter.writeToFile(str(msg) + "[accessLogs]")
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def saveSMTPSettings(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
|
||||
if currentACL['admin'] == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson('logstatus', 0)
|
||||
|
||||
data = json.loads(request.body)
|
||||
mailer = data['mailer']
|
||||
|
||||
smtpPath = '/home/cyberpanel/smtpDetails'
|
||||
|
||||
if mailer != 'SMTP':
|
||||
|
||||
if os.path.exists(smtpPath):
|
||||
os.remove(smtpPath)
|
||||
else:
|
||||
import smtplib
|
||||
|
||||
smtpHost = data['smtpHost']
|
||||
smtpPort = data['smtpPort']
|
||||
smtpUserName = data['smtpUserName']
|
||||
smtpPassword = data['smtpPassword']
|
||||
|
||||
try:
|
||||
verifyLogin = smtplib.SMTP(str(smtpHost), int(smtpPort))
|
||||
verifyLogin.login(str(smtpUserName), str(smtpPassword))
|
||||
|
||||
writeToFile = open(smtpPath, 'w')
|
||||
writeToFile.write(json.dumps(data))
|
||||
writeToFile.close()
|
||||
|
||||
command = 'chmod 600 %s' % (smtpPath)
|
||||
ProcessUtilities.executioner(command)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
status = {"status": 1}
|
||||
final_json = json.dumps(status)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
except BaseException as msg:
|
||||
status = {"status": 0, 'error_message': str(msg)}
|
||||
final_json = json.dumps(status)
|
||||
return HttpResponse(final_json)
|
||||
|
||||
1497
static/serverLogs/serverLogs.js
Executable file → Normal file
1497
static/serverLogs/serverLogs.js
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
@@ -6714,5 +6714,62 @@ app.controller('manageGIT', function ($scope, $http, $timeout, $window) {
|
||||
}
|
||||
};
|
||||
|
||||
$scope.currentPage = 1;
|
||||
$scope.recordsToShow = 10;
|
||||
|
||||
$scope.fetchGitLogs = function () {
|
||||
$scope.cyberpanelLoading = false;
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
var data = {
|
||||
domain: $("#domain").text(),
|
||||
folder: $scope.folder,
|
||||
page: $scope.currentPage,
|
||||
recordsToShow: $scope.recordsToShow
|
||||
};
|
||||
|
||||
|
||||
dataurl = "/websites/fetchGitLogs";
|
||||
|
||||
$http.post(dataurl, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: 'Successfully fetched.',
|
||||
type: 'success'
|
||||
});
|
||||
$scope.logs = JSON.parse(response.data.logs);
|
||||
$scope.pagination = response.data.pagination;
|
||||
} 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'
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
});
|
||||
/* Java script code to git tracking ends here */
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
from django.db import models
|
||||
from packages.models import Package
|
||||
from loginSystem.models import Administrator
|
||||
from datetime import datetime
|
||||
|
||||
# Create your models here.
|
||||
|
||||
@@ -47,3 +48,10 @@ class aliasDomains(models.Model):
|
||||
master = models.ForeignKey(Websites, on_delete=models.CASCADE)
|
||||
aliasDomain = models.CharField(max_length=75)
|
||||
|
||||
class GitLogs(models.Model):
|
||||
owner = models.ForeignKey(Websites, on_delete=models.CASCADE)
|
||||
date = models.DateTimeField(default=datetime.now, blank=True)
|
||||
type = models.CharField(max_length=5)
|
||||
message = models.TextField(max_length=65532)
|
||||
|
||||
|
||||
|
||||
@@ -6714,5 +6714,62 @@ app.controller('manageGIT', function ($scope, $http, $timeout, $window) {
|
||||
}
|
||||
};
|
||||
|
||||
$scope.currentPage = 1;
|
||||
$scope.recordsToShow = 10;
|
||||
|
||||
$scope.fetchGitLogs = function () {
|
||||
$scope.cyberpanelLoading = false;
|
||||
var config = {
|
||||
headers: {
|
||||
'X-CSRFToken': getCookie('csrftoken')
|
||||
}
|
||||
};
|
||||
|
||||
var data = {
|
||||
domain: $("#domain").text(),
|
||||
folder: $scope.folder,
|
||||
page: $scope.currentPage,
|
||||
recordsToShow: $scope.recordsToShow
|
||||
};
|
||||
|
||||
|
||||
dataurl = "/websites/fetchGitLogs";
|
||||
|
||||
$http.post(dataurl, data, config).then(ListInitialDatas, cantLoadInitialDatas);
|
||||
|
||||
|
||||
function ListInitialDatas(response) {
|
||||
$scope.cyberpanelLoading = true;
|
||||
if (response.data.status === 1) {
|
||||
new PNotify({
|
||||
title: 'Success',
|
||||
text: 'Successfully fetched.',
|
||||
type: 'success'
|
||||
});
|
||||
$scope.logs = JSON.parse(response.data.logs);
|
||||
$scope.pagination = response.data.pagination;
|
||||
} 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'
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
});
|
||||
/* Java script code to git tracking ends here */
|
||||
|
||||
@@ -15,140 +15,144 @@
|
||||
|
||||
<div ng-controller="listWebsites" class="container">
|
||||
|
||||
<div id="page-title">
|
||||
<h2 id="domainNamePage">{% trans "List Websites" %}</h2> <img ng-hide="cyberPanelLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
<p>{% trans "On this page you can launch, list, modify and delete websites from your server." %}</p>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-10" style="padding: 0px; box-shadow: 0px 0px 1px 0px #888888; margin-bottom: 2%">
|
||||
<input ng-change="searchWebsites()" placeholder="Search..." ng-model="patternAdded" name="dom" type="text"
|
||||
class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2">
|
||||
<div class="form-group">
|
||||
<select ng-model="recordsToShow" ng-change="getFurtherWebsitesFromDB()"
|
||||
class="form-control" id="example-select">
|
||||
<option>10</option>
|
||||
<option>50</option>
|
||||
<option>100</option>
|
||||
</select>
|
||||
<div id="page-title">
|
||||
<h2 id="domainNamePage">{% trans "List Websites" %}</h2> <img ng-hide="cyberPanelLoading"
|
||||
src="{% static 'images/loading.gif' %}">
|
||||
<p>{% trans "On this page you can launch, list, modify and delete websites from your server." %}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="web in WebSitesList track by $index" class="panel col-md-12"
|
||||
style="padding: 0px; box-shadow: 0px 0px 1px 0px #888888;">
|
||||
<div class="">
|
||||
<div class="table-responsive no-gutter text-nowrap" style="overflow-x: hidden;">
|
||||
<div
|
||||
style="background-image: url({% static 'images/not-available-preview.png' %});
|
||||
height: 160px;
|
||||
width: 200px;
|
||||
background-position: top;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
position: relative;"
|
||||
class="col-lg-3 col-md-12"
|
||||
>
|
||||
</div>
|
||||
<div class="col-lg-9" style="text-transform: none">
|
||||
<div style="border-bottom: 1px solid #888888" class="col-md-12">
|
||||
<div class="col-lg-10 content-box-header" style="text-transform: none;">
|
||||
<a href="http://{$ web.domain $}" target="_blank" title="Visit Site">
|
||||
<h2 style="display: inline; color: #414C59;" ng-bind="web.domain"></h2>
|
||||
</a>
|
||||
<a target="_blank" href="/filemanager/{$ web.domain $}" title="Open File Manager"> --
|
||||
/home/{$ web.domain $}/public_html</a>
|
||||
</div>
|
||||
<div class="col-md-2 content-box-header" style="text-transform: none;">
|
||||
<a href="/websites/{$ web.domain $}" target="_blank" title="Manage Website">
|
||||
<i class="p fa fa-external-link btn-icon"> </i>
|
||||
<span>Manage</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-sm-10" style="padding: 0px; box-shadow: 0px 0px 1px 0px #888888; margin-bottom: 2%">
|
||||
<input ng-change="searchWebsites()" placeholder="Search..." ng-model="patternAdded" name="dom" type="text"
|
||||
class="form-control" required>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2">
|
||||
<div class="form-group">
|
||||
<select ng-model="recordsToShow" ng-change="getFurtherWebsitesFromDB()"
|
||||
class="form-control" id="example-select">
|
||||
<option>10</option>
|
||||
<option>50</option>
|
||||
<option>100</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-repeat="web in WebSitesList track by $index" class="panel col-md-12"
|
||||
style="padding: 0px; box-shadow: 0px 0px 1px 0px #888888;">
|
||||
<div class="">
|
||||
<div class="table-responsive no-gutter text-nowrap" style="overflow-x: hidden;">
|
||||
<div
|
||||
style="background-image: url({% static 'images/not-available-preview.png' %});
|
||||
height: 160px;
|
||||
width: 200px;
|
||||
background-position: top;
|
||||
background-repeat: no-repeat;
|
||||
background-size: cover;
|
||||
position: relative;"
|
||||
class="col-lg-3 col-md-12"
|
||||
>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="col-md-4 content-box-header">
|
||||
<i class="p fa fa-sticky-note btn-icon text-muted" data-toggle="tooltip"
|
||||
data-placement="right" title="State"> </i>
|
||||
<span ng-bind="web.state" style="text-transform: none"></span>
|
||||
<div class="col-lg-9" style="text-transform: none">
|
||||
<div style="border-bottom: 1px solid #888888" class="col-md-12">
|
||||
<div class="col-lg-10 content-box-header" style="text-transform: none;">
|
||||
<a href="http://{$ web.domain $}" target="_blank" title="Visit Site">
|
||||
<h2 style="display: inline; color: #414C59;" ng-bind="web.domain"></h2>
|
||||
</a>
|
||||
<a target="_blank" href="/filemanager/{$ web.domain $}" title="Open File Manager"> --
|
||||
/home/{$ web.domain $}/public_html</a>
|
||||
</div>
|
||||
<div class="col-md-2 content-box-header" style="text-transform: none;">
|
||||
<a href="/websites/{$ web.domain $}" target="_blank" title="Manage Website">
|
||||
<i class="p fa fa-external-link btn-icon"> </i>
|
||||
<span>Manage</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 content-box-header">
|
||||
<i class="p fa fa-map-marker btn-icon text-muted" data-toggle="tooltip"
|
||||
data-placement="right" title="IP Address"> </i>
|
||||
<span ng-bind="web.ipAddress"></span>
|
||||
<div class="col-md-12">
|
||||
<div class="col-md-4 content-box-header">
|
||||
<i class="p fa fa-sticky-note btn-icon text-muted" data-toggle="tooltip"
|
||||
data-placement="right" title="State"> </i>
|
||||
<span ng-bind="web.state" style="text-transform: none"></span>
|
||||
</div>
|
||||
<div class="col-md-4 content-box-header">
|
||||
<i class="p fa fa-map-marker btn-icon text-muted" data-toggle="tooltip"
|
||||
data-placement="right" title="IP Address"> </i>
|
||||
<span ng-bind="web.ipAddress"></span>
|
||||
</div>
|
||||
<div class="col-md-4 content-box-header">
|
||||
<i class="p fa fa-lock btn-icon text-muted" data-toggle="tooltip" data-placement="right"
|
||||
title="SSL"> </i>
|
||||
<span><a ng-click="issueSSL(web.domain)" href=""
|
||||
style="text-transform: none">Issue SSL</a></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 content-box-header">
|
||||
<i class="p fa fa-lock btn-icon text-muted" data-toggle="tooltip" data-placement="right"
|
||||
title="SSL"> </i>
|
||||
<span><a ng-click="issueSSL(web.domain)" href="" style="text-transform: none">Issue SSL</a></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<div class="col-md-12">
|
||||
|
||||
<div class="col-md-4 content-box-header">
|
||||
<i class="p fa fa-hdd-o btn-icon text-muted" data-toggle="tooltip" data-placement="right"
|
||||
title="Disk Usage"> </i>
|
||||
<span ng-bind="web.diskUsed" style="text-transform: none"></span>
|
||||
</div>
|
||||
<div class="col-md-4 content-box-header">
|
||||
<i class="p fa fa-hdd-o btn-icon text-muted" data-toggle="tooltip"
|
||||
data-placement="right"
|
||||
title="Disk Usage"> </i>
|
||||
<span ng-bind="web.diskUsed" style="text-transform: none"></span>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 content-box-header">
|
||||
<i class="p fa fa-cubes btn-icon text-muted" data-toggle="tooltip"
|
||||
data-placement="right"
|
||||
title="Packages"> </i>
|
||||
<span ng-bind="web.package" style="text-transform: none"></span>
|
||||
</div>
|
||||
<div class="col-md-4 content-box-header">
|
||||
<i class="p fa fa-user btn-icon text-muted" data-toggle="tooltip" data-placement="right"
|
||||
title="Owner"> </i>
|
||||
<span ng-bind="web.admin" style="text-transform: none"></span>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4 content-box-header">
|
||||
<i class="p fa fa-cubes btn-icon text-muted" data-toggle="tooltip" data-placement="right"
|
||||
title="Packages"> </i>
|
||||
<span ng-bind="web.package" style="text-transform: none"></span>
|
||||
</div>
|
||||
<div class="col-md-4 content-box-header">
|
||||
<i class="p fa fa-user btn-icon text-muted" data-toggle="tooltip" data-placement="right"
|
||||
title="Owner"> </i>
|
||||
<span ng-bind="web.admin" style="text-transform: none"></span>
|
||||
</div>
|
||||
<!--table cellpadding="0" cellspacing="0" border="0" class="table" style="margin:0px 0px; id="datatable-example">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>IP Address</th>
|
||||
<th>Package</th>
|
||||
<th>Owner</th>
|
||||
<th>State</th>
|
||||
<th>Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td ng-bind="web.ipAddress"></td>
|
||||
<td ng-bind="web.package"></td>
|
||||
<td ng-bind="web.admin"></td>
|
||||
<td ng-bind="web.state"></td>
|
||||
<td ng-bind="web.adminEmail"></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table-->
|
||||
|
||||
</div>
|
||||
<!--table cellpadding="0" cellspacing="0" border="0" class="table" style="margin:0px 0px; id="datatable-example">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>IP Address</th>
|
||||
<th>Package</th>
|
||||
<th>Owner</th>
|
||||
<th>State</th>
|
||||
<th>Email</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td ng-bind="web.ipAddress"></td>
|
||||
<td ng-bind="web.package"></td>
|
||||
<td ng-bind="web.admin"></td>
|
||||
<td ng-bind="web.state"></td>
|
||||
<td ng-bind="web.adminEmail"></td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table-->
|
||||
|
||||
</div>
|
||||
|
||||
<div id="listFail" class="alert alert-danger">
|
||||
<p>{% trans "Cannot list websites. Error message:" %} {$ errorMessage $}</p>
|
||||
<div id="listFail" class="alert alert-danger">
|
||||
<p>{% trans "Cannot list websites. Error message:" %} {$ errorMessage $}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: 2%" class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<select ng-model="currentPage" class="form-control"
|
||||
ng-change="getFurtherWebsitesFromDB()">
|
||||
<option ng-repeat="page in pagination">{$ $index + 1 $}</option>
|
||||
</select>
|
||||
<div style="margin-top: 2%" class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end row -->
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<select ng-model="currentPage" class="form-control"
|
||||
ng-change="getFurtherWebsitesFromDB()">
|
||||
<option ng-repeat="page in pagination">{$ $index + 1 $}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end row -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -185,19 +185,23 @@
|
||||
<option>Weekly</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Currently: {$ autoCommitCurrent $}</div>
|
||||
<div class="current-pack ng-binding">Currently: {$ autoCommitCurrent
|
||||
$}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3 control-label">{% trans "Auto Push" %}</label>
|
||||
<div class="col-sm-6">
|
||||
<select ng-disabled="remote==0" ng-model="$parent.autoPush" class="form-control">
|
||||
<select ng-disabled="remote==0" ng-model="$parent.autoPush"
|
||||
class="form-control">
|
||||
<option>Never</option>
|
||||
<option>Daily</option>
|
||||
<option>Weekly</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Currently: {$ autoPushCurrent $}</div>
|
||||
<div class="current-pack ng-binding">Currently: {$ autoPushCurrent $}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@@ -211,7 +215,8 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="current-pack ng-binding">Currently: {$ emailLogsCurrent $}</div>
|
||||
<div class="current-pack ng-binding">Currently: {$ emailLogsCurrent $}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div ng-hide="installationDetailsForm" class="form-group">
|
||||
@@ -462,6 +467,7 @@
|
||||
<input name="radio-toggle-1" type="radio">
|
||||
Push
|
||||
</a>
|
||||
|
||||
<a ng-click="fetchGitignore()" data-toggle="modal" data-target="#gitignore" href="#"
|
||||
class="btn btn-info">
|
||||
<input name="radio-toggle-1" type="radio">
|
||||
@@ -514,6 +520,81 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a ng-click="fetchGitLogs()" data-toggle="modal" data-target="#gitLogs" href="#"
|
||||
class="btn btn-info">
|
||||
<input name="radio-toggle-1" type="radio">
|
||||
Git Logs
|
||||
</a>
|
||||
|
||||
<div id="gitLogs" class="modal fade" role="dialog">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<!-- Modal content-->
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×
|
||||
</button>
|
||||
<h4 class="modal-title">{% trans "Git Logs" %} <img
|
||||
ng-hide="cyberpanelLoading" src="{% static 'images/loading.gif' %}"></h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-10">
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<div class="form-group">
|
||||
<select ng-model="recordsToShow"
|
||||
ng-change="fetchGitLogs()"
|
||||
class="form-control" id="example-select">
|
||||
<option>10</option>
|
||||
<option>50</option>
|
||||
<option>100</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table style="margin-top: 2%" class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th>Date</th>
|
||||
<th>Message</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="log in logs track by $index">
|
||||
<td ng-bind="log.type"></td>
|
||||
<td ng-bind="log.date"></td>
|
||||
<td ng-bind="log.message"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="margin-top: 2%" class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="row">
|
||||
<div class="col-md-9">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="form-group">
|
||||
<select ng-model="currentPage" class="form-control"
|
||||
ng-change="fetchGitLogs()">
|
||||
<option ng-repeat="page in pagination">{$ $index + 1
|
||||
$}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div> <!-- end row -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a data-toggle="modal" data-target="#removeGit" href="#" class="btn btn-info">
|
||||
<input name="radio-toggle-1" type="radio">
|
||||
Remove
|
||||
|
||||
@@ -136,6 +136,7 @@ urlpatterns = [
|
||||
url(r'^fetchFiles$', views.fetchFiles, name='fetchFiles'),
|
||||
url(r'^fetchChangesInFile$', views.fetchChangesInFile, name='fetchChangesInFile'),
|
||||
url(r'^saveGitConfigurations$', views.saveGitConfigurations, name='saveGitConfigurations'),
|
||||
url(r'^fetchGitLogs$', views.fetchGitLogs, name='fetchGitLogs'),
|
||||
|
||||
|
||||
## Catch all for domains
|
||||
|
||||
@@ -851,5 +851,13 @@ def saveGitConfigurations(request):
|
||||
userID = request.session['userID']
|
||||
wm = WebsiteManager()
|
||||
return wm.saveGitConfigurations(userID, json.loads(request.body))
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
|
||||
def fetchGitLogs(request):
|
||||
try:
|
||||
userID = request.session['userID']
|
||||
wm = WebsiteManager()
|
||||
return wm.fetchGitLogs(userID, json.loads(request.body))
|
||||
except KeyError:
|
||||
return redirect(loadLoginPage)
|
||||
@@ -3284,8 +3284,8 @@ StrictHostKeyChecking no
|
||||
command = 'git -C %s add -A' % (self.folder)
|
||||
ProcessUtilities.outputExecutioner(command )
|
||||
|
||||
command = 'git -C %s commit -m "%s"' % (self.folder, self.commitMessage)
|
||||
commandStatus = ProcessUtilities.outputExecutioner(command )
|
||||
command = 'git -C %s commit -m "%s"' % (self.folder, self.commitMessage.replace('"', ''))
|
||||
commandStatus = ProcessUtilities.outputExecutioner(command)
|
||||
|
||||
if commandStatus.find('nothing to commit') == -1:
|
||||
data_ret = {'status': 1, 'commandStatus': commandStatus}
|
||||
@@ -3297,7 +3297,7 @@ StrictHostKeyChecking no
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'status': 0, 'error_message': str(msg)}
|
||||
data_ret = {'status': 0, 'error_message': str(msg), 'commandStatus': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -3403,7 +3403,7 @@ StrictHostKeyChecking no
|
||||
return HttpResponse(json_data)
|
||||
|
||||
except BaseException as msg:
|
||||
data_ret = {'status': 0, 'error_message': str(msg)}
|
||||
data_ret = {'status': 0, 'error_message': str(msg), 'commandStatus': str(msg)}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
@@ -3802,7 +3802,7 @@ StrictHostKeyChecking no
|
||||
try:
|
||||
dic['autoPush'] = data['autoPush']
|
||||
except:
|
||||
dic['autoCommit'] = 'Never'
|
||||
dic['autoPush'] = 'Never'
|
||||
|
||||
try:
|
||||
dic['emailLogs'] = data['emailLogs']
|
||||
@@ -3841,6 +3841,67 @@ StrictHostKeyChecking no
|
||||
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 getLogsInJson(self, logs):
|
||||
json_data = "["
|
||||
checker = 0
|
||||
counter = 1
|
||||
|
||||
for items in logs:
|
||||
dic = {'type': items.type, 'date': items.date.strftime('%m.%d.%Y_%H-%M-%S'), 'message': items.message}
|
||||
|
||||
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 + ']'
|
||||
return json_data
|
||||
|
||||
def fetchGitLogs(self, userID=None, data=None):
|
||||
try:
|
||||
|
||||
currentACL = ACLManager.loadedACL(userID)
|
||||
admin = Administrator.objects.get(pk=userID)
|
||||
|
||||
self.domain = data['domain']
|
||||
self.folder = data['folder']
|
||||
recordsToShow = int(data['recordsToShow'])
|
||||
page = int(data['page'])
|
||||
|
||||
if ACLManager.checkOwnership(self.domain, admin, currentACL) == 1:
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson('status', 0)
|
||||
|
||||
if self.folderCheck():
|
||||
pass
|
||||
else:
|
||||
return ACLManager.loadErrorJson()
|
||||
|
||||
website = Websites.objects.get(domain=self.domain)
|
||||
logs = website.gitlogs_set.all().order_by('-id')
|
||||
|
||||
from s3Backups.s3Backups import S3Backups
|
||||
|
||||
pagination = S3Backups.getPagination(len(logs), recordsToShow)
|
||||
endPageNumber, finalPageNumber = S3Backups.recordsPointer(page, recordsToShow)
|
||||
jsonData = self.getLogsInJson(logs[finalPageNumber:endPageNumber])
|
||||
|
||||
data_ret = {'status': 1, 'logs': jsonData, 'pagination': pagination}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
except IndexError:
|
||||
data_ret = {'status': 0, 'error_message': 'Not a text file.'}
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user