mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2025-11-13 16:56:09 +01:00
ssh logs
This commit is contained in:
@@ -868,18 +868,37 @@ app.controller('OnboardingCP', function ($scope, $http, $timeout, $window) {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.controller('dashboardStatsController', function ($scope, $http, $timeout) {
|
app.controller('dashboardStatsController', function ($scope, $http) {
|
||||||
// Card values
|
// Card values
|
||||||
$scope.totalSites = 0;
|
$scope.totalSites = 0;
|
||||||
$scope.totalWPSites = 0;
|
$scope.totalWPSites = 0;
|
||||||
$scope.totalDBs = 0;
|
$scope.totalDBs = 0;
|
||||||
$scope.totalEmails = 0;
|
$scope.totalEmails = 0;
|
||||||
|
|
||||||
|
// SSH Logins
|
||||||
|
$scope.sshLogins = [];
|
||||||
|
$scope.loadingSSHLogins = true;
|
||||||
|
$scope.errorSSHLogins = '';
|
||||||
|
$scope.refreshSSHLogins = function() {
|
||||||
|
$scope.loadingSSHLogins = true;
|
||||||
|
$http.get('/base/getRecentSSHLogins').then(function (response) {
|
||||||
|
$scope.loadingSSHLogins = false;
|
||||||
|
if (response.data && response.data.logins) {
|
||||||
|
$scope.sshLogins = response.data.logins;
|
||||||
|
} else {
|
||||||
|
$scope.sshLogins = [];
|
||||||
|
}
|
||||||
|
}, function (err) {
|
||||||
|
$scope.loadingSSHLogins = false;
|
||||||
|
$scope.errorSSHLogins = 'Failed to load SSH logins.';
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// SSH Logs
|
// SSH Logs
|
||||||
$scope.sshLogs = [];
|
$scope.sshLogs = [];
|
||||||
$scope.loadingSSHLogs = true;
|
$scope.loadingSSHLogs = true;
|
||||||
$scope.errorSSHLogs = '';
|
$scope.errorSSHLogs = '';
|
||||||
function fetchSSHLogs() {
|
$scope.refreshSSHLogs = function() {
|
||||||
$scope.loadingSSHLogs = true;
|
$scope.loadingSSHLogs = true;
|
||||||
$http.get('/base/getRecentSSHLogs').then(function (response) {
|
$http.get('/base/getRecentSSHLogs').then(function (response) {
|
||||||
$scope.loadingSSHLogs = false;
|
$scope.loadingSSHLogs = false;
|
||||||
@@ -892,35 +911,11 @@ app.controller('dashboardStatsController', function ($scope, $http, $timeout) {
|
|||||||
$scope.loadingSSHLogs = false;
|
$scope.loadingSSHLogs = false;
|
||||||
$scope.errorSSHLogs = 'Failed to load SSH logs.';
|
$scope.errorSSHLogs = 'Failed to load SSH logs.';
|
||||||
});
|
});
|
||||||
}
|
|
||||||
fetchSSHLogs();
|
|
||||||
setInterval(fetchSSHLogs, 10000);
|
|
||||||
|
|
||||||
// SSH Logins
|
|
||||||
$scope.sshLogins = [];
|
|
||||||
$scope.loadingSSHLogins = true;
|
|
||||||
$scope.errorSSHLogins = '';
|
|
||||||
function fetchSSHLogins() {
|
|
||||||
$scope.loadingSSHLogins = true;
|
|
||||||
$http.get('/base/getRecentSSHLogins').then(function (response) {
|
|
||||||
$scope.loadingSSHLogins = false;
|
|
||||||
if (response.data && response.data.logins) {
|
|
||||||
$scope.sshLogins = response.data.logins;
|
|
||||||
} else {
|
|
||||||
$scope.sshLogins = [];
|
|
||||||
}
|
|
||||||
}, function (error) {
|
|
||||||
$scope.loadingSSHLogins = false;
|
|
||||||
$scope.sshLogins = [];
|
|
||||||
$scope.errorSSHLogins = 'Failed to load SSH logins.';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
fetchSSHLogins();
|
|
||||||
var sshPoller = function() {
|
|
||||||
fetchSSHLogins();
|
|
||||||
$timeout(sshPoller, 10000);
|
|
||||||
};
|
};
|
||||||
$timeout(sshPoller, 10000);
|
|
||||||
|
// Initial fetch
|
||||||
|
$scope.refreshSSHLogins();
|
||||||
|
$scope.refreshSSHLogs();
|
||||||
|
|
||||||
// Chart.js chart objects
|
// Chart.js chart objects
|
||||||
var trafficChart, diskIOChart, cpuChart;
|
var trafficChart, diskIOChart, cpuChart;
|
||||||
|
|||||||
@@ -108,7 +108,7 @@
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
{$ totalSites $}
|
{$ totalSites $}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style="
|
style="
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
@@ -118,12 +118,12 @@
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
Total Sites
|
Total Sites
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
<!-- WordPress Sites Card -->
|
<!-- WordPress Sites Card -->
|
||||||
<a
|
<a
|
||||||
@@ -167,7 +167,7 @@
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
{$ totalWPSites $}
|
{$ totalWPSites $}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
style="
|
style="
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
@@ -177,12 +177,12 @@
|
|||||||
"
|
"
|
||||||
>
|
>
|
||||||
WordPress Sites
|
WordPress Sites
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
|
||||||
<!-- Total Databases Card -->
|
<!-- Total Databases Card -->
|
||||||
<a
|
<a
|
||||||
@@ -239,9 +239,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<!-- Total Emails Card -->
|
<!-- Total Emails Card -->
|
||||||
<a
|
<a
|
||||||
@@ -298,12 +298,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if admin %}
|
{% if admin %}
|
||||||
<div ng-controller="homePageStatus" style="margin-bottom: 40px;">
|
<div ng-controller="homePageStatus" style="margin-bottom: 40px;">
|
||||||
<div style="display: flex; justify-content: center; gap: 30px; align-items: stretch; flex-wrap: wrap;" class="system-stats-row">
|
<div style="display: flex; justify-content: center; gap: 30px; align-items: stretch; flex-wrap: wrap;" class="system-stats-row">
|
||||||
<!-- CPU Usage -->
|
<!-- CPU Usage -->
|
||||||
@@ -312,41 +312,41 @@
|
|||||||
<div style="display: flex; justify-content: center;">
|
<div style="display: flex; justify-content: center;">
|
||||||
<div id="redcircle" class="c100 red p{$ cpuUsage $}">
|
<div id="redcircle" class="c100 red p{$ cpuUsage $}">
|
||||||
<span style="font-weight: 700; font-size: 1.2rem; color: #333;">{$ cpuUsage $}%</span>
|
<span style="font-weight: 700; font-size: 1.2rem; color: #333;">{$ cpuUsage $}%</span>
|
||||||
<div class="slice">
|
<div class="slice">
|
||||||
<div class="bar"></div>
|
<div class="bar"></div>
|
||||||
<div class="fill"></div>
|
<div class="fill"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- RAM Usage -->
|
<!-- RAM Usage -->
|
||||||
<div style="background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 30px 40px; flex: 1 1 0; min-width: 0; text-align: center; border: 1px solid #e9ecef;">
|
<div style="background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 30px 40px; flex: 1 1 0; min-width: 0; text-align: center; border: 1px solid #e9ecef;">
|
||||||
<div style="font-size: 1rem; color: #43a047; font-weight: 600; margin-bottom: 15px; text-transform: uppercase; letter-spacing: 1px;">{% trans "Ram Usage" %}</div>
|
<div style="font-size: 1rem; color: #43a047; font-weight: 600; margin-bottom: 15px; text-transform: uppercase; letter-spacing: 1px;">{% trans "Ram Usage" %}</div>
|
||||||
<div style="display: flex; justify-content: center;">
|
<div style="display: flex; justify-content: center;">
|
||||||
<div id="greencircle" class="c100 p{$ ramUsage $} green">
|
<div id="greencircle" class="c100 p{$ ramUsage $} green">
|
||||||
<span style="font-weight: 700; font-size: 1.2rem; color: #333;">{$ ramUsage $}%</span>
|
<span style="font-weight: 700; font-size: 1.2rem; color: #333;">{$ ramUsage $}%</span>
|
||||||
<div class="slice">
|
<div class="slice">
|
||||||
<div class="bar"></div>
|
<div class="bar"></div>
|
||||||
<div class="fill"></div>
|
<div class="fill"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Disk Usage -->
|
<!-- Disk Usage -->
|
||||||
<div style="background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 30px 40px; flex: 1 1 0; min-width: 0; text-align: center; border: 1px solid #e9ecef;">
|
<div style="background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 30px 40px; flex: 1 1 0; min-width: 0; text-align: center; border: 1px solid #e9ecef;">
|
||||||
<div style="font-size: 1rem; color: #d81b60; font-weight: 600; margin-bottom: 15px; text-transform: uppercase; letter-spacing: 1px;">{% trans "Disk Usage '/'" %}</div>
|
<div style="font-size: 1rem; color: #d81b60; font-weight: 600; margin-bottom: 15px; text-transform: uppercase; letter-spacing: 1px;">{% trans "Disk Usage '/'" %}</div>
|
||||||
<div style="display: flex; justify-content: center;">
|
<div style="display: flex; justify-content: center;">
|
||||||
<div id="pinkcircle" class="c100 pink p{$ diskUsage $}">
|
<div id="pinkcircle" class="c100 pink p{$ diskUsage $}">
|
||||||
<span style="font-weight: 700; font-size: 1.2rem; color: #333;">{$ diskUsage $}%</span>
|
<span style="font-weight: 700; font-size: 1.2rem; color: #333;">{$ diskUsage $}%</span>
|
||||||
<div class="slice">
|
<div class="slice">
|
||||||
<div class="bar"></div>
|
<div class="bar"></div>
|
||||||
<div class="fill"></div>
|
<div class="fill"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
@@ -449,7 +449,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tab Content -->
|
<!-- Tab Content -->
|
||||||
<div
|
<div
|
||||||
@@ -484,68 +484,74 @@
|
|||||||
<canvas id="cpuChart" height="80"></canvas>
|
<canvas id="cpuChart" height="80"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- SSH Logins and Logs Row (side by side) -->
|
<!-- SSH Logins and Logs Row (side by side) -->
|
||||||
{% if admin %}
|
{% if admin %}
|
||||||
<div style="display: flex; gap: 30px; justify-content: center; align-items: flex-start; flex-wrap: wrap; margin-bottom: 40px;">
|
<div style="display: flex; gap: 30px; justify-content: center; align-items: flex-start; flex-wrap: wrap; margin-bottom: 40px;">
|
||||||
<!-- Recent SSH Logins Widget -->
|
<!-- Recent SSH Logins Widget -->
|
||||||
<div style="flex: 1 1 420px; min-width: 320px; max-width: 600px; background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 25px 30px; border: 1px solid #e9ecef;">
|
<div style="flex: 1 1 420px; min-width: 320px; max-width: 600px; background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 25px 30px; border: 1px solid #e9ecef;">
|
||||||
<div style="font-size: 1.25rem; font-weight: 700; color: #333; letter-spacing: 0.5px; margin-bottom: 18px;">Recent SSH Logins</div>
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||||
<div ng-if="loadingSSHLogins" style="text-align: center; padding: 20px; color: #888;">Loading recent SSH logins...</div>
|
<div style="font-size: 1.25rem; font-weight: 700; color: #333;">Recent SSH Logins</div>
|
||||||
<div ng-if="!loadingSSHLogins && sshLogins.length === 0" style="text-align: center; color: #888; padding: 20px;">No recent SSH logins found.</div>
|
<button class="btn btn-sm btn-outline-primary" ng-click="refreshSSHLogins()" title="Refresh"><span style="font-size:1.2em;">↻</span> Refresh</button>
|
||||||
<div ng-if="!loadingSSHLogins && sshLogins.length > 0" style="overflow-x: auto;">
|
</div>
|
||||||
<table style="width: 100%; border-collapse: collapse; min-width: 320px;">
|
<div ng-if="loadingSSHLogins" style="text-align:center; color:#888; padding:20px;">Loading...</div>
|
||||||
|
<div ng-if="errorSSHLogins" style="color:#e53935;">{$ errorSSHLogins $}</div>
|
||||||
|
<div ng-if="!loadingSSHLogins && !errorSSHLogins && sshLogins.length === 0" style="text-align:center; color:#888; padding:20px;">No recent SSH logins found.</div>
|
||||||
|
<div style="overflow-x:auto;">
|
||||||
|
<table class="table table-striped table-hover" style="margin-bottom:0;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr style="background: #4c5fad; color: #fff;">
|
<tr style="background:#f1f3f6;">
|
||||||
<th style="padding: 12px 15px; border-radius: 8px 0 0 8px; text-align: left; font-weight: 600;">User</th>
|
<th>User</th>
|
||||||
<th style="padding: 12px 15px; text-align: left; font-weight: 600;">IP</th>
|
<th>IP</th>
|
||||||
<th style="padding: 12px 15px; text-align: left; font-weight: 600;">Country</th>
|
<th>Country</th>
|
||||||
<th style="padding: 12px 15px; text-align: left; font-weight: 600;">Date/Time</th>
|
<th>Date</th>
|
||||||
<th style="padding: 12px 15px; border-radius: 0 8px 8px 0; text-align: left; font-weight: 600;">Session</th>
|
<th>Session</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="login in sshLogins" class="ssh-login-row" style="background: #f8f9fa; border-bottom: 1px solid #e9ecef; transition: background 0.2s;">
|
<tr ng-repeat="login in sshLogins" style="background: #f8f9fa; border-bottom: 1px solid #e9ecef;">
|
||||||
<td style="padding: 10px 15px; font-weight: 600; color: #333;">{$ login.user $}</td>
|
<td style="padding: 8px 8px; font-weight: 600; color: #333;">{$ login.user $}</td>
|
||||||
<td style="padding: 10px 15px; color: #555;">{$ login.ip $}</td>
|
<td style="padding: 8px 8px; color: #555;">{$ login.ip $}</td>
|
||||||
<td style="padding: 10px 15px;">
|
<td style="padding: 8px 8px;">
|
||||||
<span ng-if="login.flag"><img ng-src="{$ login.flag $}" alt="{$ login.country $}" style="height: 18px; margin-right: 6px; vertical-align: middle; border-radius: 2px;" /></span>
|
<span ng-if="login.flag"><img ng-src="{$ login.flag $}" alt="{$ login.country $}" style="height: 18px; margin-right: 6px; vertical-align: middle;" /></span>
|
||||||
<span ng-if="!login.flag && login.country">{$ login.country $}</span>
|
<span ng-if="!login.flag && login.country">{$ login.country $}</span>
|
||||||
<span ng-if="!login.flag && !login.country">-</span>
|
|
||||||
</td>
|
</td>
|
||||||
<td style="padding: 10px 15px; color: #555;">{$ login.date $}</td>
|
<td style="padding: 8px 8px;">{$ login.date $}</td>
|
||||||
<td style="padding: 10px 15px; color: #888;">{$ login.session $}</td>
|
<td style="padding: 8px 8px;">{$ login.session $}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Recent SSH Logs Widget -->
|
<!-- Recent SSH Logs Widget -->
|
||||||
<div style="flex: 1 1 420px; min-width: 320px; max-width: 600px; background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 25px 30px; border: 1px solid #e9ecef;">
|
<div style="flex: 1 1 520px; min-width: 380px; max-width: 900px; background: #fff; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); padding: 25px 30px; border: 1px solid #e9ecef; min-height: 480px; max-height: 600px; display: flex; flex-direction: column;">
|
||||||
<div style="font-size: 1.25rem; font-weight: 700; color: #333; letter-spacing: 0.5px; margin-bottom: 18px;">Recent SSH Logs</div>
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||||
<div ng-if="loadingSSHLogs" style="text-align: center; padding: 20px; color: #888;">Loading recent SSH logs...</div>
|
<div style="font-size: 1.25rem; font-weight: 700; color: #333;">Recent SSH Logs</div>
|
||||||
<div ng-if="errorSSHLogs" style="text-align: center; color: #d81b60; padding: 20px;">{$ errorSSHLogs $}</div>
|
<button class="btn btn-sm btn-outline-primary" ng-click="refreshSSHLogs()" title="Refresh"><span style="font-size:1.2em;">↻</span> Refresh</button>
|
||||||
<div ng-if="!loadingSSHLogs && sshLogs.length === 0 && !errorSSHLogs" style="text-align: center; color: #888; padding: 20px;">No recent SSH logs found.</div>
|
</div>
|
||||||
<div ng-if="!loadingSSHLogs && sshLogs.length > 0" style="overflow-x: auto; max-height: 350px;">
|
<div ng-if="loadingSSHLogs" style="text-align:center; color:#888; padding:20px;">Loading...</div>
|
||||||
<table style="width: 100%; border-collapse: collapse; min-width: 320px;">
|
<div ng-if="errorSSHLogs" style="color:#e53935;">{$ errorSSHLogs $}</div>
|
||||||
|
<div ng-if="!loadingSSHLogs && !errorSSHLogs && sshLogs.length === 0" style="text-align:center; color:#888; padding:20px;">No recent SSH logs found.</div>
|
||||||
|
<div style="overflow-y:auto; flex:1; max-height: 480px;">
|
||||||
|
<table class="table table-striped table-hover" style="margin-bottom:0;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr style="background: #4c5fad; color: #fff;">
|
<tr style="background:#f1f3f6;">
|
||||||
<th style="padding: 12px 15px; border-radius: 8px 0 0 8px; text-align: left; font-weight: 600;">Timestamp</th>
|
<th style="width: 160px;">Timestamp</th>
|
||||||
<th style="padding: 12px 15px; border-radius: 0 8px 8px 0; text-align: left; font-weight: 600;">Message</th>
|
<th>Message</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="log in sshLogs" style="background: #f8f9fa; border-bottom: 1px solid #e9ecef; transition: background 0.2s;">
|
<tr ng-repeat="log in sshLogs">
|
||||||
<td style="padding: 10px 15px; color: #555; white-space: nowrap;">{$ log.timestamp $}</td>
|
<td style="padding: 8px 8px; color: #555;">{$ log.timestamp $}</td>
|
||||||
<td style="padding: 10px 15px; color: #333;">{$ log.message $}</td>
|
<td style="padding: 8px 8px; font-family: monospace;">{$ log.message $}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<!-- End Dashboard Stats Section -->
|
<!-- End Dashboard Stats Section -->
|
||||||
|
|
||||||
|
|||||||
@@ -612,16 +612,16 @@ def getRecentSSHLogs(request):
|
|||||||
lines = output.split('\n')
|
lines = output.split('\n')
|
||||||
logs = []
|
logs = []
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if 'sshd' in line:
|
if not line.strip():
|
||||||
# Try to split into timestamp and message
|
continue
|
||||||
parts = line.split()
|
parts = line.split()
|
||||||
if len(parts) > 4:
|
if len(parts) > 4:
|
||||||
timestamp = ' '.join(parts[:3])
|
timestamp = ' '.join(parts[:3])
|
||||||
message = ' '.join(parts[4:])
|
message = ' '.join(parts[4:])
|
||||||
else:
|
else:
|
||||||
timestamp = ''
|
timestamp = ''
|
||||||
message = line
|
message = line
|
||||||
logs.append({'timestamp': timestamp, 'message': message, 'raw': line})
|
logs.append({'timestamp': timestamp, 'message': message, 'raw': line})
|
||||||
return HttpResponse(json.dumps({'logs': logs}), content_type='application/json')
|
return HttpResponse(json.dumps({'logs': logs}), content_type='application/json')
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return HttpResponse(json.dumps({'error': str(e)}), content_type='application/json', status=500)
|
return HttpResponse(json.dumps({'error': str(e)}), content_type='application/json', status=500)
|
||||||
|
|||||||
Reference in New Issue
Block a user