mirror of
https://github.com/ZoneMinder/zoneminder.git
synced 2026-05-17 19:15:04 -04:00
Merge branch 'master' of github.com:ZoneMinder/zoneminder
This commit is contained in:
139
src/zm_zone.cpp
139
src/zm_zone.cpp
@@ -247,7 +247,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
||||
|
||||
if ( config.record_diag_images_fifo ) {
|
||||
FifoDebug(5, "{\"zone\":%d,\"type\":\"ALRM\",\"pixels\":%d,\"avg_diff\":%d}",
|
||||
id,alarm_pixels, pixel_diff);
|
||||
id, alarm_pixels, pixel_diff);
|
||||
}
|
||||
|
||||
if ( alarm_pixels ) {
|
||||
@@ -264,11 +264,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( max_alarm_pixels != 0 )
|
||||
score = (100*alarm_pixels)/max_alarm_pixels;
|
||||
else
|
||||
score = (100*alarm_pixels)/polygon.Area();
|
||||
|
||||
score = (100*alarm_pixels)/(max_alarm_pixels?max_alarm_pixels:polygon.Area());
|
||||
if ( score < 1 )
|
||||
score = 1; /* Fix for score of 0 when frame meets thresholds but alarmed area is not big enough */
|
||||
Debug(5, "Current score is %d", score);
|
||||
@@ -358,8 +354,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
||||
|
||||
if ( check_method >= BLOBS ) {
|
||||
Debug(5, "Checking for blob pixels");
|
||||
typedef struct { unsigned char tag; int count; int lo_x; int hi_x; int lo_y; int hi_y; } BlobStats;
|
||||
BlobStats blob_stats[256];
|
||||
// ICON FIXME Would like to get rid of this memset
|
||||
memset(blob_stats, 0, sizeof(BlobStats)*256);
|
||||
uint8_t *spdiff;
|
||||
uint8_t last_x, last_y;
|
||||
@@ -369,22 +364,15 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
||||
int lo_x = ranges[y].lo_x;
|
||||
int hi_x = ranges[y].hi_x;
|
||||
|
||||
pdiff = (uint8_t*)diff_image->Buffer( lo_x, y );
|
||||
pdiff = (uint8_t*)diff_image->Buffer(lo_x, y);
|
||||
for ( int x = lo_x; x <= hi_x; x++, pdiff++ ) {
|
||||
if ( *pdiff == WHITE ) {
|
||||
Debug(9, "Got white pixel at %d,%d (%p)", x, y, pdiff);
|
||||
//last_x = (x>lo_x)?*(pdiff-1):0;
|
||||
//last_y = (y>lo_y&&x>=last_lo_x&&x<=last_hi_x)?*(pdiff-diff_width):0;
|
||||
|
||||
last_x = 0;
|
||||
if ( x > 0 ) {
|
||||
if ( (x-1) >= lo_x ) {
|
||||
last_x = *(pdiff-1);
|
||||
}
|
||||
}
|
||||
last_x = ((x > 0) && ( (x-1) >= lo_x )) ? *(pdiff-1) : 0;
|
||||
|
||||
last_y = 0;
|
||||
if (y > 0 ) {
|
||||
if ( y > 0 ) {
|
||||
if ( (y-1) >= lo_y && ranges[(y-1)].lo_x <= x && ranges[(y-1)].hi_x >= x ) {
|
||||
last_y = *(pdiff-diff_width);
|
||||
}
|
||||
@@ -631,7 +619,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
||||
}
|
||||
|
||||
if ( max_blob_pixels != 0 )
|
||||
score = (100*alarm_blob_pixels)/(max_blob_pixels);
|
||||
score = (100*alarm_blob_pixels)/max_blob_pixels;
|
||||
else
|
||||
score = (100*alarm_blob_pixels)/polygon.Area();
|
||||
|
||||
@@ -758,67 +746,42 @@ bool Zone::CheckAlarms(const Image *delta_image) {
|
||||
}
|
||||
|
||||
bool Zone::ParsePolygonString(const char *poly_string, Polygon &polygon) {
|
||||
Debug(3, "Parsing polygon string '%s'", poly_string);
|
||||
|
||||
char *str_ptr = new char[strlen(poly_string)+1];
|
||||
char *str = str_ptr;
|
||||
strcpy(str, poly_string);
|
||||
|
||||
char *str = (char *)poly_string;
|
||||
char *ws;
|
||||
char *cp;
|
||||
int n_coords = 0;
|
||||
int max_n_coords = strlen(str)/4;
|
||||
Coord *coords = new Coord[max_n_coords];
|
||||
while( true ) {
|
||||
if ( *str == '\0' ) {
|
||||
break;
|
||||
}
|
||||
ws = strchr(str, ' ');
|
||||
if ( ws ) {
|
||||
*ws = '\0';
|
||||
}
|
||||
char *cp = strchr(str, ',');
|
||||
while ( *str != '\0' ) {
|
||||
cp = strchr(str, ',');
|
||||
if ( !cp ) {
|
||||
Error("Bogus coordinate %s found in polygon string", str);
|
||||
delete[] coords;
|
||||
delete[] str_ptr;
|
||||
return false;
|
||||
} else {
|
||||
*cp = '\0';
|
||||
char *xp = str;
|
||||
char *yp = cp+1;
|
||||
break;
|
||||
}
|
||||
int x = atoi(str);
|
||||
int y = atoi(cp+1);
|
||||
Debug(3, "Got coordinate %d,%d from polygon string", x, y);
|
||||
coords[n_coords++] = Coord(x, y);
|
||||
|
||||
int x = atoi(xp);
|
||||
int y = atoi(yp);
|
||||
|
||||
Debug(3, "Got coordinate %d,%d from polygon string", x, y);
|
||||
#if 0
|
||||
if ( x < 0 )
|
||||
x = 0;
|
||||
else if ( x >= width )
|
||||
x = width-1;
|
||||
if ( y < 0 )
|
||||
y = 0;
|
||||
else if ( y >= height )
|
||||
y = height-1;
|
||||
#endif
|
||||
coords[n_coords++] = Coord( x, y );
|
||||
}
|
||||
ws = strchr(cp+2, ' ');
|
||||
if ( ws )
|
||||
str = ws+1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
polygon = Polygon(n_coords, coords);
|
||||
} // end while ! end of string
|
||||
|
||||
Debug(3, "Successfully parsed polygon string");
|
||||
//printf( "Area: %d\n", pg.Area() );
|
||||
//printf( "Centre: %d,%d\n", pg.Centre().X(), pg.Centre().Y() );
|
||||
if ( n_coords > 2 ) {
|
||||
Debug(3, "Successfully parsed polygon string %s", str);
|
||||
polygon = Polygon(n_coords, coords);
|
||||
} else {
|
||||
Error("Not enough coordinates to form a polygon!");
|
||||
n_coords = 0;
|
||||
}
|
||||
|
||||
delete[] coords;
|
||||
delete[] str_ptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
return n_coords ? true : false;
|
||||
} // end bool Zone::ParsePolygonString(const char *poly_string, Polygon &polygon)
|
||||
|
||||
bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, Polygon &polygon) {
|
||||
Debug(3, "Parsing zone string '%s'", zone_string);
|
||||
@@ -827,13 +790,12 @@ bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, P
|
||||
char *str = str_ptr;
|
||||
strcpy(str, zone_string);
|
||||
|
||||
zone_id = strtol(str, 0, 10);
|
||||
Debug(3, "Got zone %d from zone string", zone_id);
|
||||
|
||||
char *ws = strchr(str, ' ');
|
||||
if ( !ws ) {
|
||||
Debug(3, "No initial whitespace found in zone string '%s', finishing", str);
|
||||
}
|
||||
zone_id = strtol(str, 0, 10);
|
||||
Debug(3, "Got zone %d from zone string", zone_id);
|
||||
if ( !ws ) {
|
||||
delete[] str_ptr;
|
||||
return true;
|
||||
}
|
||||
@@ -841,13 +803,11 @@ bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, P
|
||||
*ws = '\0';
|
||||
str = ws+1;
|
||||
|
||||
colour = strtol(str, 0, 16);
|
||||
Debug(3, "Got colour %06x from zone string", colour);
|
||||
ws = strchr(str, ' ');
|
||||
if ( !ws ) {
|
||||
Debug(3, "No secondary whitespace found in zone string '%s', finishing", zone_string);
|
||||
}
|
||||
colour = strtol(str, 0, 16);
|
||||
Debug(3, "Got colour %06x from zone string", colour);
|
||||
if ( !ws ) {
|
||||
delete[] str_ptr;
|
||||
return true;
|
||||
}
|
||||
@@ -855,27 +815,28 @@ bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, P
|
||||
str = ws+1;
|
||||
|
||||
bool result = ParsePolygonString(str, polygon);
|
||||
|
||||
//printf( "Area: %d\n", pg.Area() );
|
||||
//printf( "Centre: %d,%d\n", pg.Centre().X(), pg.Centre().Y() );
|
||||
|
||||
delete[] str_ptr;
|
||||
|
||||
return result;
|
||||
}
|
||||
} // end bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, Polygon &polygon)
|
||||
|
||||
int Zone::Load(Monitor *monitor, Zone **&zones) {
|
||||
static char sql[ZM_SQL_MED_BUFSIZ];
|
||||
|
||||
db_mutex.lock();
|
||||
snprintf(sql, sizeof(sql), "select Id,Name,Type+0,Units,Coords,AlarmRGB,CheckMethod+0,MinPixelThreshold,MaxPixelThreshold,MinAlarmPixels,MaxAlarmPixels,FilterX,FilterY,MinFilterPixels,MaxFilterPixels,MinBlobPixels,MaxBlobPixels,MinBlobs,MaxBlobs,OverloadFrames,ExtendAlarmFrames from Zones where MonitorId = %d order by Type, Id", monitor->Id());
|
||||
snprintf(sql, sizeof(sql), "SELECT Id,Name,Type+0,Units,Coords,AlarmRGB,CheckMethod+0,"
|
||||
"MinPixelThreshold,MaxPixelThreshold,MinAlarmPixels,MaxAlarmPixels,"
|
||||
"FilterX,FilterY,MinFilterPixels,MaxFilterPixels,"
|
||||
"MinBlobPixels,MaxBlobPixels,MinBlobs,MaxBlobs,"
|
||||
"OverloadFrames,ExtendAlarmFrames"
|
||||
" FROM Zones WHERE MonitorId = %d ORDER BY Type, Id", monitor->Id());
|
||||
if ( mysql_query(&dbconn, sql) ) {
|
||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||
db_mutex.unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
MYSQL_RES *result = mysql_store_result( &dbconn );
|
||||
MYSQL_RES *result = mysql_store_result(&dbconn);
|
||||
if ( !result ) {
|
||||
Error("Can't use query result: %s", mysql_error(&dbconn));
|
||||
db_mutex.unlock();
|
||||
@@ -944,7 +905,13 @@ int Zone::Load(Monitor *monitor, Zone **&zones) {
|
||||
} else if ( atoi(dbrow[2]) == Zone::PRIVACY ) {
|
||||
zones[i] = new Zone(monitor, Id, Name, (Zone::ZoneType)Type, polygon);
|
||||
}
|
||||
zones[i] = new Zone(monitor, Id, Name, (Zone::ZoneType)Type, polygon, AlarmRGB, (Zone::CheckMethod)CheckMethod, MinPixelThreshold, MaxPixelThreshold, MinAlarmPixels, MaxAlarmPixels, Coord( FilterX, FilterY ), MinFilterPixels, MaxFilterPixels, MinBlobPixels, MaxBlobPixels, MinBlobs, MaxBlobs, OverloadFrames, ExtendAlarmFrames);
|
||||
zones[i] = new Zone(
|
||||
monitor, Id, Name, (Zone::ZoneType)Type, polygon, AlarmRGB,
|
||||
(Zone::CheckMethod)CheckMethod, MinPixelThreshold, MaxPixelThreshold,
|
||||
MinAlarmPixels, MaxAlarmPixels, Coord( FilterX, FilterY ),
|
||||
MinFilterPixels, MaxFilterPixels,
|
||||
MinBlobPixels, MaxBlobPixels, MinBlobs, MaxBlobs,
|
||||
OverloadFrames, ExtendAlarmFrames);
|
||||
} // end foreach row
|
||||
mysql_free_result(result);
|
||||
return n_zones;
|
||||
@@ -953,9 +920,9 @@ int Zone::Load(Monitor *monitor, Zone **&zones) {
|
||||
bool Zone::DumpSettings(char *output, bool /*verbose*/) {
|
||||
output[0] = 0;
|
||||
|
||||
sprintf( output+strlen(output), " Id : %d\n", id );
|
||||
sprintf( output+strlen(output), " Label : %s\n", label );
|
||||
sprintf( output+strlen(output), " Type: %d - %s\n", type,
|
||||
sprintf(output+strlen(output), " Id : %d\n", id );
|
||||
sprintf(output+strlen(output), " Label : %s\n", label );
|
||||
sprintf(output+strlen(output), " Type: %d - %s\n", type,
|
||||
type==ACTIVE?"Active":(
|
||||
type==INCLUSIVE?"Inclusive":(
|
||||
type==EXCLUSIVE?"Exclusive":(
|
||||
@@ -1020,10 +987,10 @@ void Zone::std_alarmedpixels(
|
||||
*pdiff = BLACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // end for y = lo_y to hi_y
|
||||
|
||||
/* Store the results */
|
||||
*pixel_count = pixelsalarmed;
|
||||
*pixel_sum = pixelsdifference;
|
||||
Debug(7, "STORED pixelsalarmed(%d), pixelsdifference(%d)", pixelsalarmed, pixelsdifference);
|
||||
}
|
||||
} // end void Zone::std_alarmedpixels(Image* pdiff_image, const Image* ppoly_image, unsigned int* pixel_count, unsigned int* pixel_sum)
|
||||
|
||||
@@ -32,15 +32,14 @@ class Monitor;
|
||||
// This describes a 'zone', or an area of an image that has certain
|
||||
// detection characteristics.
|
||||
//
|
||||
class Zone
|
||||
{
|
||||
class Zone {
|
||||
protected:
|
||||
struct Range
|
||||
{
|
||||
struct Range {
|
||||
int lo_x;
|
||||
int hi_x;
|
||||
int off_x;
|
||||
};
|
||||
typedef struct { unsigned char tag; int count; int lo_x; int hi_x; int lo_y; int hi_y; } BlobStats;
|
||||
|
||||
public:
|
||||
typedef enum { ACTIVE=1, INCLUSIVE, EXCLUSIVE, PRECLUSIVE, INACTIVE, PRIVACY } ZoneType;
|
||||
@@ -52,8 +51,8 @@ protected:
|
||||
|
||||
int id;
|
||||
char *label;
|
||||
ZoneType type;
|
||||
Polygon polygon;
|
||||
ZoneType type;
|
||||
Polygon polygon;
|
||||
Rgb alarm_rgb;
|
||||
CheckMethod check_method;
|
||||
|
||||
@@ -67,17 +66,18 @@ protected:
|
||||
int min_filter_pixels;
|
||||
int max_filter_pixels;
|
||||
|
||||
BlobStats blob_stats[256];
|
||||
int min_blob_pixels;
|
||||
int max_blob_pixels;
|
||||
int min_blobs;
|
||||
int max_blobs;
|
||||
|
||||
int overload_frames;
|
||||
int overload_frames;
|
||||
int extend_alarm_frames;
|
||||
|
||||
// Outputs/Statistics
|
||||
bool alarmed;
|
||||
bool was_alarmed;
|
||||
bool alarmed;
|
||||
bool was_alarmed;
|
||||
int pixel_diff;
|
||||
unsigned int alarm_pixels;
|
||||
int alarm_filter_pixels;
|
||||
@@ -139,8 +139,7 @@ public:
|
||||
inline Coord GetAlarmCentre() const { return( alarm_centre ); }
|
||||
inline unsigned int Score() const { return( score ); }
|
||||
|
||||
inline void ResetStats()
|
||||
{
|
||||
inline void ResetStats() {
|
||||
alarmed = false;
|
||||
was_alarmed = false;
|
||||
pixel_diff = 0;
|
||||
|
||||
114
web/ajax/newlog.php
Normal file
114
web/ajax/newlog.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
global $Servers;
|
||||
|
||||
if ( !canView('System') ) {
|
||||
ajaxError('Insufficient permissions to view log entries');
|
||||
return;
|
||||
}
|
||||
|
||||
// Only the query task is supported at the moment
|
||||
if ( !isset($_REQUEST['task']) or $_REQUEST['task'] != 'query' ) {
|
||||
ajaxError('Unrecognised action');
|
||||
return;
|
||||
}
|
||||
// The table we want our data from
|
||||
$table = 'Logs';
|
||||
|
||||
// The names of the dB columns in the log table we are interested in
|
||||
$columns = array('TimeKey', 'Component', 'ServerId', 'Pid', 'Code', 'Message', 'File', 'Line');
|
||||
|
||||
// The names of columns shown in the log view that are NOT dB columns in the database
|
||||
$col_alt = array('DateTime', 'Server');
|
||||
|
||||
// Search contains a user entered string to search on
|
||||
$search = '';
|
||||
if ( isset($_REQUEST['search']) ) {
|
||||
$search = $_REQUEST['search'];
|
||||
}
|
||||
|
||||
// Sort specifies the name of the column to sort on
|
||||
$sort = 'TimeKey';
|
||||
if ( isset($_REQUEST['sort']) ) {
|
||||
if ( !in_array($_REQUEST['sort'], array_merge($columns, $col_alt)) ) {
|
||||
ZM\Error('Invalid sort field: ' . $_REQUEST['sort']);
|
||||
} else {
|
||||
$sort = $_REQUEST['sort'];
|
||||
if ( $sort == 'DateTime' ) $sort = 'TimeKey';
|
||||
}
|
||||
}
|
||||
|
||||
// Offset specifies the starting row to return, used for pagination
|
||||
$offset = 0;
|
||||
if ( isset($_REQUEST['offset']) ) {
|
||||
if ( ( !is_int($_REQUEST['offset']) and !ctype_digit($_REQUEST['offset']) ) ) {
|
||||
ZM\Error('Invalid value for offset: ' . $_REQUEST['offset']);
|
||||
} else {
|
||||
$offset = $_REQUEST['offset'];
|
||||
}
|
||||
}
|
||||
|
||||
// Order specifies the sort direction, either asc or desc
|
||||
$order = (isset($_REQUEST['order']) and (strtolower($_REQUEST['order']) == 'asc')) ? 'ASC' : 'DESC';
|
||||
|
||||
// Limit specifies the number of rows to return
|
||||
$limit = 100;
|
||||
if ( isset($_REQUEST['limit']) ) {
|
||||
if ( ( !is_int($_REQUEST['limit']) and !ctype_digit($_REQUEST['limit']) ) ) {
|
||||
ZM\Error('Invalid value for limit: ' . $_REQUEST['limit']);
|
||||
} else {
|
||||
$limit = $_REQUEST['limit'];
|
||||
}
|
||||
}
|
||||
|
||||
$col_str = implode(', ', $columns);
|
||||
$data = array();
|
||||
$query = array();
|
||||
$query['values'] = array();
|
||||
$likes = array();
|
||||
if ( $search != '' ) {
|
||||
$search = '%' .$search. '%';
|
||||
foreach ( $columns as $col ) {
|
||||
array_push($likes, $col.' LIKE ?');
|
||||
array_push($query['values'], $search);
|
||||
}
|
||||
$wherevalues = $query['values'];
|
||||
$where = ' WHERE (' .implode(' OR ', $likes). ')';
|
||||
$query['sql'] = 'SELECT ' .$col_str. ' FROM `' .$table. '` ' .$where. ' ORDER BY ' .$sort. ' ' .$order. ' LIMIT ?, ?';
|
||||
array_push($query['values'], $offset, $limit);
|
||||
} else {
|
||||
$query['sql'] = 'SELECT ' .$col_str. ' FROM `' .$table. '` ORDER BY ' .$sort. ' ' .$order. ' LIMIT ?, ?';
|
||||
$query['values'] = array($offset, $limit);
|
||||
}
|
||||
|
||||
//ZM\Warning('Calling the following sql query: ' .$query['sql']);
|
||||
|
||||
$data['totalNotFiltered'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table, 'Total');
|
||||
if ( $search == '' ) {
|
||||
$data['total'] = $data['totalNotFiltered'];
|
||||
} else {
|
||||
$data['total'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table.$where , 'Total', $wherevalues);
|
||||
}
|
||||
|
||||
if ( !$Servers )
|
||||
$Servers = ZM\Server::find();
|
||||
$servers_by_Id = array();
|
||||
# There is probably a better way to do this.
|
||||
foreach ( $Servers as $server ) {
|
||||
$servers_by_Id[$server->Id()] = $server;
|
||||
}
|
||||
|
||||
$rows = array();
|
||||
foreach ( dbFetchAll($query['sql'], NULL, $query['values']) as $row ) {
|
||||
$row['DateTime'] = strftime('%Y-%m-%d %H:%M:%S', intval($row['TimeKey']));
|
||||
$row['Server'] = ( $row['ServerId'] and isset($servers_by_Id[$row['ServerId']]) ) ? $servers_by_Id[$row['ServerId']]->Name() : '';
|
||||
// First strip out any html tags
|
||||
// Second strip out all characters that are not ASCII 32-126 (yes, 126)
|
||||
$row['Message'] = preg_replace('/[^\x20-\x7E]/', '', strip_tags($row['Message']));
|
||||
$rows[] = $row;
|
||||
}
|
||||
$data['rows'] = $rows;
|
||||
$data['logstate'] = logState();
|
||||
$data['updated'] = preg_match('/%/', DATE_FMT_CONSOLE_LONG) ? strftime(DATE_FMT_CONSOLE_LONG) : date(DATE_FMT_CONSOLE_LONG);
|
||||
|
||||
ajaxResponse($data);
|
||||
|
||||
116
web/skins/classic/views/js/newlog.js
Normal file
116
web/skins/classic/views/js/newlog.js
Normal file
@@ -0,0 +1,116 @@
|
||||
var table = $j('#logTable');
|
||||
|
||||
/*
|
||||
This is the format of the json object sent by bootstrap-table
|
||||
|
||||
var params =
|
||||
{
|
||||
"type":"get",
|
||||
"data":
|
||||
{
|
||||
"search":"some search text",
|
||||
"sort":"DateTime",
|
||||
"order":"asc",
|
||||
"offset":0,
|
||||
"limit":25
|
||||
},
|
||||
"cache":true,
|
||||
"contentType":"application/json",
|
||||
"dataType":"json"
|
||||
};
|
||||
*/
|
||||
|
||||
// Called by bootstrap-table to retrieve zm log data
|
||||
function ajaxRequest(params) {
|
||||
$j.getJSON(thisUrl + '?view=request&request=newlog&task=query', params.data)
|
||||
.done(function(res) {
|
||||
//console.log('total: ' + res.total);
|
||||
//console.log('totalNotFiltered: ' + res.totalNotFiltered);
|
||||
console.log(JSON.stringify(params));
|
||||
// rearrange the result into what bootstrap-table expects
|
||||
var data = {total: res.total, totalNotFiltered: res.totalNotFiltered, rows: res.rows};
|
||||
params.success(data);
|
||||
updateHeaderStats(res);
|
||||
})
|
||||
.fail(logAjaxFail);
|
||||
}
|
||||
|
||||
function updateHeaderStats(data) {
|
||||
var pageNum = table.bootstrapTable('getOptions').pageNumber;
|
||||
var pageSize = table.bootstrapTable('getOptions').pageSize;
|
||||
var startRow = ( (pageNum - 1 ) * pageSize ) + 1;
|
||||
var stopRow = pageNum * pageSize;
|
||||
var newClass = (data.logstate == 'ok') ? 'text-success' : (data.logstate == 'alert' ? 'text-warning' : ((data.logstate == 'alarm' ? 'text-danger' : '')));
|
||||
|
||||
$j('#logState').text(data.logstate);
|
||||
$j('#logState').removeClass('text-success');
|
||||
$j('#logState').removeClass('text-warning');
|
||||
$j('#logState').removeClass('text-danger');
|
||||
$j('#logState').addClass(newClass);
|
||||
|
||||
$j('#totalLogs').text(data.total);
|
||||
$j('#availLogs').text(data.totalNotFiltered);
|
||||
$j('#lastUpdate').text(data.updated);
|
||||
$j('#displayLogs').text(startRow + ' to ' + stopRow);
|
||||
}
|
||||
|
||||
function initPage() {
|
||||
var backBtn = $j('#backBtn');
|
||||
|
||||
// Define the icons used in the bootstrap-table top-right toolbar
|
||||
var icons = {
|
||||
paginationSwitchDown: 'fa-caret-square-o-down',
|
||||
paginationSwitchUp: 'fa-caret-square-o-up',
|
||||
export: 'fa-download',
|
||||
refresh: 'fa-refresh',
|
||||
autoRefresh: 'fa-clock-o',
|
||||
advancedSearchIcon: 'fa-chevron-down',
|
||||
toggleOff: 'fa-toggle-off',
|
||||
toggleOn: 'fa-toggle-on',
|
||||
columns: 'fa-th-list',
|
||||
fullscreen: 'fa-arrows-alt',
|
||||
detailOpen: 'fa-plus',
|
||||
detailClose: 'fa-minus'
|
||||
};
|
||||
|
||||
// Init the bootstrap-table with custom icons
|
||||
table.bootstrapTable({icons: icons});
|
||||
|
||||
// Assign inf, err, fat, dbg color classes to the rows in the table
|
||||
table.on('post-body.bs.table', function(data) {
|
||||
$j('#logTable tr').each(function(ndx, row) {
|
||||
var row = $j(row)
|
||||
var level = row.find('td:eq(4)').text();
|
||||
|
||||
if (( level == 'FAT' ) || ( level == 'PNC' )) {
|
||||
row.addClass('bg-danger');
|
||||
row.addClass('font-weight-bold');
|
||||
} else if ( level == 'ERR' ) {
|
||||
row.addClass('bg-danger');
|
||||
} else if ( level == 'WAR' ) {
|
||||
row.addClass('bg-warning');
|
||||
} else if ( level == 'DBG' ) {
|
||||
row.addClass('bg-info');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Don't enable the back button if there is no previous zm page to go back to
|
||||
backBtn.prop('disabled', !document.referrer.length);
|
||||
|
||||
// Manage the BACK button
|
||||
document.getElementById("backBtn").addEventListener("click", function onBackClick(evt) {
|
||||
evt.preventDefault();
|
||||
window.history.back();
|
||||
});
|
||||
|
||||
// Manage the REFRESH Button
|
||||
document.getElementById("refreshBtn").addEventListener("click", function onRefreshClick(evt) {
|
||||
evt.preventDefault();
|
||||
window.location.reload(true);
|
||||
});
|
||||
}
|
||||
|
||||
$j(document).ready(function() {
|
||||
initPage();
|
||||
});
|
||||
95
web/skins/classic/views/newlog.php
Normal file
95
web/skins/classic/views/newlog.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
//
|
||||
// ZoneMinder web log view file, $Date: 2010-02-23 09:10:36 +0000 (Tue, 23 Feb 2010) $, $Revision: 3030 $
|
||||
// Copyright (C) 2001-2008 Philip Coombes
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canView('System') ) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('SystemLog'));
|
||||
?>
|
||||
<body>
|
||||
<?php echo getNavBarHTML() ?>
|
||||
<div id="page" class="px-3">
|
||||
|
||||
<div> <!-- DELETE ME -->
|
||||
<h3>UNDER CONSTRUTION - This view is not yet fully functional</h3>
|
||||
</div>
|
||||
|
||||
<div id="logSummary" class="text-center">
|
||||
<?php echo translate('State') ?>: <span id="logState"></span> -
|
||||
<?php echo translate('Total') ?>: <span id="totalLogs"></span> -
|
||||
<?php echo translate('Available') ?>: <span id="availLogs"></span> -
|
||||
<?php echo translate('Displaying') ?>: <span id="displayLogs"></span> -
|
||||
<?php echo translate('Updated') ?>: <span id="lastUpdate"></span>
|
||||
</div>
|
||||
|
||||
<div id="toolbar">
|
||||
<button id="backBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Back') ?>" disabled><i class="fa fa-arrow-left"></i></button>
|
||||
<button id="refreshBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Refresh') ?>" ><i class="fa fa-refresh"></i></button>
|
||||
</div>
|
||||
|
||||
<table
|
||||
id="logTable"
|
||||
class="table-sm table-borderless"
|
||||
data-side-pagination="server"
|
||||
data-ajax="ajaxRequest"
|
||||
data-pagination="true"
|
||||
data-page-list="[10, 25, 50, 100, 200, 300, 400, 500]"
|
||||
data-search="true"
|
||||
data-advanced-search="true"
|
||||
data-id-table="advancedTable"
|
||||
data-cookie="true"
|
||||
data-cookie-id-table="zmLogsTable"
|
||||
data-cookie-expire="2y"
|
||||
data-remember-order="true"
|
||||
data-show-columns="true"
|
||||
data-show-export="true"
|
||||
data-toolbar="#toolbar"
|
||||
data-show-fullscreen="true"
|
||||
data-maintain-meta-data="true"
|
||||
data-mobile-responsive="true"
|
||||
data-buttons-class="btn btn-normal"
|
||||
data-show-jump-to="true"
|
||||
data-auto-refresh="true"
|
||||
data-auto-refresh-silent="true"
|
||||
data-show-refresh="true"
|
||||
data-auto-refresh-interval="2"
|
||||
>
|
||||
<thead class="thead-highlight">
|
||||
<tr>
|
||||
<th data-sortable="true" data-field="DateTime"><?php echo translate('DateTime') ?></th>
|
||||
<th data-sortable="true" data-field="Component"><?php echo translate('Component') ?></th>
|
||||
<th data-sortable="false" data-field="Server"><?php echo translate('Server') ?></th>
|
||||
<th data-sortable="true" data-field="Pid"><?php echo translate('Pid') ?></th>
|
||||
<th data-sortable="true" data-field="Code"><?php echo translate('Level') ?></th>
|
||||
<th data-sortable="true" data-field="Message"><?php echo translate('Message') ?></th>
|
||||
<th data-sortable="true" data-field="File"><?php echo translate('File') ?></th>
|
||||
<th data-sortable="true" data-field="Line"><?php echo translate('Line') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<!-- Row data populated via Ajax -->
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div><!--page-->
|
||||
<?php xhtmlFooter() ?>
|
||||
Reference in New Issue
Block a user