Merge branch 'storageareas' into work_on_zms
This commit is contained in:
commit
ed6ff23c2f
|
@ -626,6 +626,7 @@ INSERT INTO `Controls` VALUES (NULL,'Vivotek ePTZ','Remote','Vivotek_ePTZ',0,0,1
|
|||
INSERT INTO `Controls` VALUES (NULL,'Netcat ONVIF','Ffmpeg','Netcat',0,0,1,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,100,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,100,5,5,0,0,0,1,255,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
||||
INSERT INTO `Controls` VALUES (NULL,'Keekoon','Remote','Keekoon', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 6, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `Controls` VALUES (NULL,'HikVision','Local','',0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,20,1,1,1,1,0,0,0,1,1,0,0,0,0,1,1,100,0,0,1,0,0,0,0,1,1,100,1,0,0,0);
|
||||
INSERT INTO `Controls` VALUES (NULL,'Maginon Supra IPC','cURL','MaginonIPC',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,0,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0);
|
||||
|
||||
--
|
||||
-- Add some monitor preset values
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
--
|
||||
-- This adds StorageAreas
|
||||
--
|
||||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE table_name = 'Storage'
|
||||
AND table_schema = DATABASE()
|
||||
) > 0,
|
||||
"SELECT 'Storage table exists'",
|
||||
"CREATE TABLE `Storage` (
|
||||
`Id` smallint(5) unsigned NOT NULL auto_increment,
|
||||
`Path` varchar(64) NOT NULL default '',
|
||||
`Name` varchar(64) NOT NULL default '',
|
||||
PRIMARY KEY (`Id`)
|
||||
)"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
--
|
||||
-- Add StorageId column to Monitors
|
||||
--
|
||||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = 'Monitors'
|
||||
AND table_schema = DATABASE()
|
||||
AND column_name = 'StorageId'
|
||||
) > 0,
|
||||
"SELECT 'Column StorageId exists in Monitors'",
|
||||
"ALTER TABLE Monitors ADD `StorageId` smallint(5) unsigned NOT NULL default 0 AFTER `ServerId`"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
--
|
||||
-- Add StorageId column to Eventss
|
||||
--
|
||||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = 'Events'
|
||||
AND table_schema = DATABASE()
|
||||
AND column_name = 'StorageId'
|
||||
) > 0,
|
||||
"SELECT 'Column StorageId exists in Events'",
|
||||
"ALTER TABLE Events ADD `StorageId` smallint(5) unsigned NOT NULL default 0 AFTER `MonitorId`"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
UPDATE Monitors SET StorageId = 0 WHERE StorageId IS NULL;
|
||||
ALTER TABLE Monitors MODIFY `StorageId` smallint(5) unsigned NOT NULL default 0;
|
||||
UPDATE Events SET StorageId = 0 WHERE StorageId IS NULL;
|
||||
ALTER TABLE Events MODIFY `StorageId` smallint(5) unsigned NOT NULL default 0;
|
||||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = 'Events'
|
||||
AND table_schema = DATABASE()
|
||||
AND column_name = 'Orientation'
|
||||
) > 0,
|
||||
"SELECT 'Column Orientation exists in Events'",
|
||||
"ALTER TABLE `Events` ADD `Orientation` enum('0','90','180','270','hori','vert') NOT NULL default '0' AFTER `Notes`"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
--
|
||||
-- Update Monitors table to have an Index on ServerId
|
||||
--
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.STATISTICS
|
||||
WHERE table_name = 'Monitors'
|
||||
AND table_schema = DATABASE()
|
||||
AND index_name = 'Monitors_ServerId_idx'
|
||||
) > 0,
|
||||
"SELECT 'Monitors_ServerId Index already exists on Monitors table'",
|
||||
"CREATE INDEX `Monitors_ServerId_idx` ON `Monitors` (`ServerId`)"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
|
||||
--
|
||||
-- Update Server table to have an Index on Name
|
||||
--
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.STATISTICS
|
||||
WHERE table_name = 'Servers'
|
||||
AND table_schema = DATABASE()
|
||||
AND index_name = 'Servers_Name_idx'
|
||||
) > 0,
|
||||
"SELECT 'Servers_Name Index already exists on Servers table'",
|
||||
"CREATE INDEX `Servers_Name_idx` ON `Servers` (`Name`)"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
|
||||
-- ALTER TABLE Logs ALTER Message DROP DEFAULT;
|
||||
ALTER TABLE Logs MODIFY Message TEXT NOT NULL;
|
||||
|
||||
ALTER TABLE Config MODIFY DefaultValue TEXT;
|
||||
|
||||
|
||||
--
|
||||
-- Add an Id column and make it the primary key of the Filters table
|
||||
--
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*)
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE table_name = 'Filters'
|
||||
AND table_schema = DATABASE()
|
||||
AND column_name = 'Id'
|
||||
) > 0,
|
||||
"SELECT 'Column Id exists in Filters'",
|
||||
"ALTER TABLE `Filters` DROP PRIMARY KEY, ADD `Id` int(10) unsigned NOT NULL auto_increment PRIMARY KEY FIRST, ADD KEY `Name` (`Name`);"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
|
@ -16,7 +16,7 @@ Alias /zm "@ZM_WEBDIR@"
|
|||
DirectoryIndex index.php
|
||||
SSLRequireSSL
|
||||
Options -Indexes +MultiViews +FollowSymLinks
|
||||
AllowOverride All
|
||||
AllowOverride None
|
||||
<IfModule mod_authz_core.c>
|
||||
# Apache 2.4
|
||||
Require all granted
|
||||
|
@ -31,7 +31,7 @@ Alias /zm "@ZM_WEBDIR@"
|
|||
ScriptAlias /cgi-bin-zm "@ZM_CGIDIR@"
|
||||
<Directory "@ZM_CGIDIR@">
|
||||
SSLRequireSSL
|
||||
AllowOverride All
|
||||
AllowOverride None
|
||||
Options +ExecCGI +FollowSymLinks
|
||||
<IfModule mod_authz_core.c>
|
||||
# Apache 2.4
|
||||
|
@ -44,3 +44,28 @@ ScriptAlias /cgi-bin-zm "@ZM_CGIDIR@"
|
|||
</IfModule>
|
||||
</Directory>
|
||||
|
||||
# For better visibility, the following directives have been migrated from the
|
||||
# default .htaccess files included with the CakePHP project.
|
||||
# Parameters not set here are inherited from the parent directive above.
|
||||
<Directory "@ZM_WEBDIR@/api">
|
||||
RewriteEngine on
|
||||
RewriteRule ^$ app/webroot/ [L]
|
||||
RewriteRule (.*) app/webroot/$1 [L]
|
||||
RewriteBase /zm/api
|
||||
</Directory>
|
||||
|
||||
<Directory "@ZM_WEBDIR@/api/app">
|
||||
RewriteEngine on
|
||||
RewriteRule ^$ webroot/ [L]
|
||||
RewriteRule (.*) webroot/$1 [L]
|
||||
RewriteBase /zm/api
|
||||
</Directory>
|
||||
|
||||
<Directory "@ZM_WEBDIR@/api/app/webroot">
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^ index.php [L]
|
||||
RewriteBase /zm/api
|
||||
</Directory>
|
||||
|
||||
|
|
|
@ -11,18 +11,61 @@ RewriteRule ^/?(zm)(.*) https://%{SERVER_NAME}/$1$2 [R,L]
|
|||
|
||||
Alias /zm "@ZM_WEBDIR@"
|
||||
<Directory "@ZM_WEBDIR@">
|
||||
# explicitly set index.php as the only directoryindex
|
||||
DirectoryIndex disabled
|
||||
DirectoryIndex index.php
|
||||
SSLRequireSSL
|
||||
Options -Indexes MultiViews FollowSymLinks
|
||||
AllowOverride All
|
||||
Order allow,deny
|
||||
Options -Indexes +MultiViews +FollowSymLinks
|
||||
AllowOverride None
|
||||
<IfModule mod_authz_core.c>
|
||||
# Apache 2.4
|
||||
Require all granted
|
||||
</IfModule>
|
||||
<IfModule !mod_authz_core.c>
|
||||
# Apache 2.2
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
</IfModule>
|
||||
</Directory>
|
||||
|
||||
ScriptAlias /cgi-bin-zm "@ZM_CGIDIR@"
|
||||
<Directory "@ZM_CGIDIR@">
|
||||
SSLRequireSSL
|
||||
AllowOverride All
|
||||
Options ExecCGI FollowSymLinks
|
||||
Order allow,deny
|
||||
AllowOverride None
|
||||
Options +ExecCGI +FollowSymLinks
|
||||
<IfModule mod_authz_core.c>
|
||||
# Apache 2.4
|
||||
Require all granted
|
||||
</IfModule>
|
||||
<IfModule !mod_authz_core.c>
|
||||
# Apache 2.2
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
</IfModule>
|
||||
</Directory>
|
||||
|
||||
# For better visibility, the following directives have been migrated from the
|
||||
# default .htaccess files included with the CakePHP project.
|
||||
# Parameters not set here are inherited from the parent directive above.
|
||||
<Directory "@ZM_WEBDIR@/api">
|
||||
RewriteEngine on
|
||||
RewriteRule ^$ app/webroot/ [L]
|
||||
RewriteRule (.*) app/webroot/$1 [L]
|
||||
RewriteBase /zm/api
|
||||
</Directory>
|
||||
|
||||
<Directory "@ZM_WEBDIR@/api/app">
|
||||
RewriteEngine on
|
||||
RewriteRule ^$ webroot/ [L]
|
||||
RewriteRule (.*) webroot/$1 [L]
|
||||
RewriteBase /zm/api
|
||||
</Directory>
|
||||
|
||||
<Directory "@ZM_WEBDIR@/api/app/webroot">
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^ index.php [L]
|
||||
RewriteBase /zm/api
|
||||
</Directory>
|
||||
|
||||
|
|
|
@ -109,6 +109,7 @@ Requires: perl(MIME::Lite)
|
|||
Requires: perl(Net::SMTP)
|
||||
Requires: perl(Net::FTP)
|
||||
Requires: perl(LWP::Protocol::https)
|
||||
Requires: ca-certificates
|
||||
|
||||
%{?with_init_systemd:Requires(post): systemd}
|
||||
%{?with_init_systemd:Requires(post): systemd-sysv}
|
||||
|
@ -162,7 +163,14 @@ too much degradation of performance.
|
|||
%make_install
|
||||
|
||||
# Remove unwanted files and folders
|
||||
find %{buildroot} \( -name .packlist -or -name .git -or -name .gitignore -or -name .gitattributes -or -name .travis.yml \) -type f -delete > /dev/null 2>&1 || :
|
||||
find %{buildroot} \( -name .htaccess -or -name .editorconfig -or -name .packlist -or -name .git -or -name .gitignore -or -name .gitattributes -or -name .travis.yml \) -type f -delete > /dev/null 2>&1 || :
|
||||
|
||||
# Recursively change shebang in all relevant scripts and set execute permission
|
||||
find %{buildroot}%{_datadir}/zoneminder/www/api \( -name cake -or -name cake.php \) -type f -exec sed -i 's\^#!/usr/bin/env bash$\#!/usr/bin/bash\' {} \; -exec %{__chmod} 755 {} \;
|
||||
|
||||
# Use the system cacert file rather then the one bundled with CakePHP
|
||||
%{__rm} -f %{buildroot}%{_datadir}/zoneminder/www/api/lib/Cake/Config/cacert.pem
|
||||
%{__ln_s} ../../../../../../../..%{_sysconfdir}/pki/tls/certs/ca-bundle.crt %{buildroot}%{_datadir}/zoneminder/www/api/lib/Cake/Config/cacert.pem
|
||||
|
||||
%post
|
||||
%if 0%{?with_init_sysv}
|
||||
|
@ -297,6 +305,7 @@ rm -rf %{_docdir}/%{name}-%{version}
|
|||
%{_unitdir}/zoneminder.service
|
||||
%{_datadir}/polkit-1/actions/com.zoneminder.systemctl.policy
|
||||
%{_datadir}/polkit-1/rules.d/com.zoneminder.systemctl.rules
|
||||
%{_bindir}/zmsystemctl.pl
|
||||
%endif
|
||||
|
||||
%if 0%{?with_init_sysv}
|
||||
|
@ -318,7 +327,6 @@ rm -rf %{_docdir}/%{name}-%{version}
|
|||
%{_bindir}/zmvideo.pl
|
||||
%{_bindir}/zmwatch.pl
|
||||
%{_bindir}/zmcamtool.pl
|
||||
%{_bindir}/zmsystemctl.pl
|
||||
%{_bindir}/zmtelemetry.pl
|
||||
%{_bindir}/zmx10.pl
|
||||
%{_bindir}/zmonvif-probe.pl
|
||||
|
|
|
@ -101,7 +101,7 @@ How filters actually work
|
|||
--------------------------
|
||||
It is useful to know how filters actually work behind the scenes in ZoneMinder, in the event you find your filter not functioning as intended:
|
||||
|
||||
* the primary filter processing process in ZoneMinder is a perl file called ``zmfilter.pl``
|
||||
* the primary filter processing process in ZoneMinder is a perl file called ``zmfilter.pl`` which retrieves filters from the Filters database table
|
||||
* zmfilter.pl runs every FILTER_EXECUTE_INTERVAL seconds (default is 20s, can be changed in Options->System)
|
||||
* in each run, it goes through all the filters which are marked as "Run in Background" and if the conditions match performs the specified action
|
||||
* zmfilter.pl also reloads all the filters every FILTER_RELOAD_DELAY seconds (default is 300s/5mins, can be changed in Options->System)
|
||||
|
|
|
@ -253,13 +253,6 @@ sub profiles
|
|||
foreach my $profile ( @{ $profiles } ) {
|
||||
|
||||
my $token = $profile->attr()->get_token() ;
|
||||
print $token . ", " .
|
||||
$profile->get_Name() . ", " .
|
||||
$profile->get_VideoEncoderConfiguration()->get_Encoding() . ", " .
|
||||
$profile->get_VideoEncoderConfiguration()->get_Resolution()->get_Width() . ", " .
|
||||
$profile->get_VideoEncoderConfiguration()->get_Resolution()->get_Height() . ", " .
|
||||
$profile->get_VideoEncoderConfiguration()->get_RateControl()->get_FrameRateLimit() .
|
||||
", ";
|
||||
|
||||
# Specification gives conflicting values for unicast stream types, try both.
|
||||
# http://www.onvif.org/onvif/ver10/media/wsdl/media.wsdl#op.GetStreamUri
|
||||
|
@ -278,9 +271,18 @@ sub profiles
|
|||
die $result if not $result;
|
||||
# print $result . "\n";
|
||||
|
||||
print $result->get_MediaUri()->get_Uri() .
|
||||
"\n";
|
||||
}
|
||||
my $VideoEncoderConfiguration = $profile->get_VideoEncoderConfiguration();
|
||||
print join(', ', $token,
|
||||
$profile->get_Name(),
|
||||
( $VideoEncoderConfiguration ? (
|
||||
$VideoEncoderConfiguration->get_Encoding(),
|
||||
$VideoEncoderConfiguration->get_Resolution()->get_Width(),
|
||||
$VideoEncoderConfiguration->get_Resolution()->get_Height(),
|
||||
$VideoEncoderConfiguration->get_RateControl()->get_FrameRateLimit(),
|
||||
) : () ),
|
||||
$result->get_MediaUri()->get_Uri() ,
|
||||
). "\n";
|
||||
} # end foreach profile
|
||||
|
||||
#
|
||||
# use message parser without schema validation ???
|
||||
|
|
|
@ -0,0 +1,333 @@
|
|||
# ==========================================================================
|
||||
#
|
||||
# ZoneMinder Maginon Supra IPC Camera Control Protocol Module,
|
||||
# Copyright (C) 2017 Martin Gutenbrunner (martin.gutenbrunner@SPAMsonic.net)
|
||||
#
|
||||
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# ==========================================================================
|
||||
#
|
||||
# This module contains the implementation of the Maginon Supra IPC camera
|
||||
# procotol version.
|
||||
#
|
||||
package ZoneMinder::Control::MaginonIPC;
|
||||
|
||||
use 5.006;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
require ZoneMinder::Base;
|
||||
require ZoneMinder::Control;
|
||||
|
||||
our @ISA = qw(ZoneMinder::Control);
|
||||
|
||||
# ==========================================================================
|
||||
#
|
||||
# Maginon Supra IPC IP Camera Control Protocol
|
||||
#
|
||||
# ==========================================================================
|
||||
|
||||
use ZoneMinder::Logger qw(:all);
|
||||
use ZoneMinder::Config qw(:all);
|
||||
|
||||
use Time::HiRes qw( usleep );
|
||||
|
||||
sub new
|
||||
{
|
||||
my $class = shift;
|
||||
my $id = shift;
|
||||
my $self = ZoneMinder::Control->new( $id );
|
||||
bless( $self, $class );
|
||||
srand( time() );
|
||||
return $self;
|
||||
}
|
||||
|
||||
our $AUTOLOAD;
|
||||
|
||||
sub AUTOLOAD
|
||||
{
|
||||
my $self = shift;
|
||||
my $class = ref($self) || croak( "$self not object" );
|
||||
my $name = $AUTOLOAD;
|
||||
$name =~ s/.*://;
|
||||
if ( exists($self->{$name}) )
|
||||
{
|
||||
return( $self->{$name} );
|
||||
}
|
||||
Fatal( "Can't access $name member of object of class $class" );
|
||||
}
|
||||
|
||||
sub open
|
||||
{
|
||||
my $self = shift;
|
||||
|
||||
$self->loadMonitor();
|
||||
|
||||
use LWP::UserAgent;
|
||||
$self->{ua} = LWP::UserAgent->new;
|
||||
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
|
||||
|
||||
$self->{state} = 'open';
|
||||
}
|
||||
|
||||
sub close
|
||||
{
|
||||
my $self = shift;
|
||||
$self->{state} = 'closed';
|
||||
}
|
||||
|
||||
sub printMsg
|
||||
{
|
||||
my $self = shift;
|
||||
my $msg = shift;
|
||||
my $msg_len = length($msg);
|
||||
|
||||
Debug( $msg."[".$msg_len."]" );
|
||||
}
|
||||
|
||||
sub sendCmd
|
||||
{
|
||||
my $self = shift;
|
||||
my $cmd = shift;
|
||||
|
||||
#my $result = undef;
|
||||
|
||||
printMsg( $cmd, "Tx" );
|
||||
|
||||
my $url = "http://".$self->{Monitor}->{ControlAddress}."$cmd";
|
||||
# Info($url);
|
||||
my $req = HTTP::Request->new( GET=>$url );
|
||||
my $res = $self->{ua}->request($req);
|
||||
return( !undef );
|
||||
}
|
||||
|
||||
sub moveStop
|
||||
{
|
||||
Debug("moveStop");
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $cmd = "/decoder_control.cgi?command=1";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub moveConUp
|
||||
{
|
||||
Debug("moveConUp");
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $cmd = "/decoder_control.cgi?command=0";
|
||||
$self->sendCmd( $cmd );
|
||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||
{
|
||||
usleep( $self->{Monitor}->{AutoStopTimeout} );
|
||||
$self->moveStop( $params );
|
||||
}
|
||||
}
|
||||
|
||||
sub moveConDown
|
||||
{
|
||||
Debug("moveConDown");
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $cmd = "/decoder_control.cgi?command=2";
|
||||
$self->sendCmd( $cmd );
|
||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||
{
|
||||
usleep( $self->{Monitor}->{AutoStopTimeout} );
|
||||
$self->moveStop( $params );
|
||||
}
|
||||
}
|
||||
|
||||
sub moveConLeft
|
||||
{
|
||||
Debug("moveConLeft");
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $cmd = "/decoder_control.cgi?command=4";
|
||||
$self->sendCmd( $cmd );
|
||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||
{
|
||||
usleep( $self->{Monitor}->{AutoStopTimeout} );
|
||||
$self->moveStop( $params );
|
||||
}
|
||||
}
|
||||
|
||||
sub moveConRight
|
||||
{
|
||||
Debug("moveConRight");
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $cmd = "/decoder_control.cgi?command=6";
|
||||
$self->sendCmd( $cmd );
|
||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||
{
|
||||
usleep( $self->{Monitor}->{AutoStopTimeout} );
|
||||
$self->moveStop( $params );
|
||||
}
|
||||
}
|
||||
|
||||
sub moveConUpRight
|
||||
{
|
||||
Debug("moveConUpRight");
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $cmd = "/decoder_control.cgi?command=91";
|
||||
$self->sendCmd( $cmd );
|
||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||
{
|
||||
usleep( $self->{Monitor}->{AutoStopTimeout} );
|
||||
$self->moveStop( $params );
|
||||
}
|
||||
}
|
||||
|
||||
sub moveConUpLeft
|
||||
{
|
||||
Debug("moveConUpLeft");
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $cmd = "/decoder_control.cgi?command=90";
|
||||
$self->sendCmd( $cmd );
|
||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||
{
|
||||
usleep( $self->{Monitor}->{AutoStopTimeout} );
|
||||
$self->moveStop( $params );
|
||||
}
|
||||
}
|
||||
|
||||
sub moveConDownRight
|
||||
{
|
||||
Debug("moveConDownRight");
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $cmd = "/decoder_control.cgi?command=93";
|
||||
$self->sendCmd( $cmd );
|
||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||
{
|
||||
usleep( $self->{Monitor}->{AutoStopTimeout} );
|
||||
$self->moveStop( $params );
|
||||
}
|
||||
}
|
||||
|
||||
sub moveConDownLeft
|
||||
{
|
||||
Debug("moveConDownLeft");
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $cmd = "/decoder_control.cgi?command=92";
|
||||
$self->sendCmd( $cmd );
|
||||
my $autostop = $self->getParam( $params, 'autostop', 0 );
|
||||
if ( $autostop && $self->{Monitor}->{AutoStopTimeout} )
|
||||
{
|
||||
usleep( $self->{Monitor}->{AutoStopTimeout} );
|
||||
$self->moveStop( $params );
|
||||
}
|
||||
}
|
||||
|
||||
sub presetSet
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $preset = $self->getParam( $params, 'preset' );
|
||||
Info( "Set Preset $preset" );
|
||||
|
||||
my $cmdNum;
|
||||
if ($preset == 1) {
|
||||
$cmdNum = 30;
|
||||
} elsif ($preset == 2) {
|
||||
$cmdNum = 32;
|
||||
} elsif ($preset == 3) {
|
||||
$cmdNum = 34;
|
||||
} elsif ($preset == 4) {
|
||||
$cmdNum = 36;
|
||||
} else {
|
||||
$cmdNum = 36;
|
||||
}
|
||||
|
||||
my $cmd = "/decoder_control.cgi?command=$cmdNum";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
sub presetGoto
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $preset = $self->getParam( $params, 'preset' );
|
||||
Info( "Goto Preset $preset" );
|
||||
|
||||
my $cmdNum;
|
||||
if ($preset == 1) {
|
||||
$cmdNum = 31;
|
||||
} elsif ($preset == 2) {
|
||||
$cmdNum = 33;
|
||||
} elsif ($preset == 3) {
|
||||
$cmdNum = 35;
|
||||
} elsif ($preset == 4) {
|
||||
$cmdNum = 37;
|
||||
} else {
|
||||
$cmdNum = 37;
|
||||
}
|
||||
|
||||
my $cmd = "/decoder_control.cgi?command=$cmdNum";
|
||||
$self->sendCmd( $cmd );
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
# Below is stub documentation for your module. You'd better edit it!
|
||||
|
||||
=head1 NAME
|
||||
|
||||
ZoneMinder::Control::MaginonIPC - Zoneminder PTZ control module for the Maginon Supra-IPC 40 IP Camera
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use ZoneMinder::Control::MaginonIPC;
|
||||
blah blah blah
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This is for Zoneminder PTZ control module for the Maginon Supra-IPC 40 camera. It probably also works with other models.
|
||||
|
||||
=head2 EXPORT
|
||||
|
||||
None by default.
|
||||
|
||||
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
www.zoneminder.com
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Martin Gutenbrunner, E<lt>martin.gutenbrunner@gmx.atE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 2017 by Martin Gutenbrunner
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself, either Perl version 5.8.3 or,
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
|
||||
|
||||
=cut
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# ==========================================================================
|
||||
#
|
||||
# ZoneMinder External Trigger Script, $Date: 2008-07-25 10:48:16 +0100 (Fri, 25 Jul 2008) $, $Revision: 2612 $
|
||||
# ZoneMinder External Trigger Script
|
||||
# Copyright (C) 2001-2008 Philip Coombes
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
|
@ -21,92 +21,6 @@
|
|||
#
|
||||
# ==========================================================================
|
||||
|
||||
=head1 NAME
|
||||
|
||||
zmtrigger.pl - ZoneMinder External Trigger Script
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This script is used to trigger and cancel alarms from external connections
|
||||
using an arbitrary text based format.
|
||||
|
||||
This script offers generic solution to external triggering of alarms. It
|
||||
can handle external connections via either internet socket, unix socket or
|
||||
file/device interfaces. You can either use it 'as is' if you can interface
|
||||
with the existing format, or override connections and channels to customise
|
||||
it to your needs.
|
||||
|
||||
If enabled by the OPT_TRIGGERS option, Zoneminder service start
|
||||
zmtrigger.pl which listens for control messages on TCP port 6802.
|
||||
|
||||
=head1 TRIGGER MESSAGE FORMAT
|
||||
|
||||
B<id>|B<action>|B<score>|B<cause>|B<text>|B<showtext>
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<id>
|
||||
|
||||
is the id number or name of the ZM monitor.
|
||||
|
||||
=item B<action>
|
||||
|
||||
Valid actions are 'on', 'off', 'cancel' or 'show' where
|
||||
'on' forces an alarm condition on;
|
||||
'off' forces an alarm condition off;
|
||||
'cancel' negates the previous 'on' or 'off';
|
||||
'show' updates the auxiliary text represented by the %Q
|
||||
placeholder, which can optionally be added to the affected monitor's
|
||||
timestamp label format.
|
||||
|
||||
Ordinarily you would use 'on' and 'cancel', 'off' would tend to be
|
||||
used to suppress motion based events. Additionally 'on' and 'off' can
|
||||
take an additional time offset, e.g. on+20 which automatically
|
||||
cancel's the previous action after that number of seconds.
|
||||
|
||||
=item B<score>
|
||||
|
||||
is the score given to the alarm, usually to indicate it's
|
||||
importance. For 'on' triggers it should be non-zero, otherwise it should
|
||||
be zero.
|
||||
|
||||
=item B<cause>
|
||||
|
||||
is a 32 char max string indicating the reason for, or source of
|
||||
the alarm e.g. 'Relay 1 open'. This is saved in the 'Cause' field of the
|
||||
event. Ignored for 'off' or 'cancel' messages.
|
||||
|
||||
=item B<text>
|
||||
|
||||
is a 256 char max additional info field, which is saved in the
|
||||
'Description' field of an event. Ignored for 'off' or 'cancel' messages.
|
||||
|
||||
=item B<showtext>
|
||||
|
||||
is up to 32 characters of text that can be displayed in the
|
||||
timestamp that is added to images. The 'show' action is designed to
|
||||
update this text without affecting alarms but the text is updated, if
|
||||
present, for any of the actions. This is designed to allow external input
|
||||
to appear on the images captured, for instance temperature or personnel
|
||||
identity etc.
|
||||
|
||||
=back
|
||||
|
||||
Note that multiple messages can be sent at once and should be LF or CRLF
|
||||
delimited. This script is not necessarily intended to be a solution in
|
||||
itself, but is intended to be used as 'glue' to help ZoneMinder interface
|
||||
with other systems. It will almost certainly require some customisation
|
||||
before you can make any use of it. If all you want to do is generate alarms
|
||||
from external sources then using the ZoneMinder::SharedMem perl module is
|
||||
likely to be easier.
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
3|on+10|1|motion|text|showtext
|
||||
|
||||
Triggers 'alarm' on camera #3 for 10 seconds with score=1, cause='motion'.
|
||||
|
||||
=cut
|
||||
use strict;
|
||||
use bytes;
|
||||
|
||||
|
@ -198,7 +112,6 @@ my $monitor_reload_time = 0;
|
|||
my $needsReload = 0;
|
||||
loadMonitors();
|
||||
|
||||
|
||||
$! = undef;
|
||||
my $rin = '';
|
||||
my $win = $rin;
|
||||
|
@ -216,20 +129,19 @@ while( 1 ) {
|
|||
if ( $nfound > 0 ) {
|
||||
Debug( "Got input from $nfound connections\n" );
|
||||
foreach my $connection ( @in_select_connections ) {
|
||||
|
||||
if ( vec( $rout, $connection->fileno(), 1 ) ) {
|
||||
Debug( 'Got input from connection '
|
||||
.$connection->name()
|
||||
." ("
|
||||
.' ('
|
||||
.$connection->fileno()
|
||||
.")\n"
|
||||
);
|
||||
if ( $connection->spawns() ) {
|
||||
my $new_connection = $connection->accept();
|
||||
$spawned_connections{$new_connection->fileno()} = $new_connection;
|
||||
Debug( "Added new spawned connection ("
|
||||
Debug( 'Added new spawned connection ('
|
||||
.$new_connection->fileno()
|
||||
."), "
|
||||
.'), '
|
||||
.int(keys(%spawned_connections))
|
||||
." spawned connections\n"
|
||||
);
|
||||
|
@ -248,7 +160,7 @@ while( 1 ) {
|
|||
if ( vec( $rout, $connection->fileno(), 1 ) ) {
|
||||
Debug( 'Got input from spawned connection '
|
||||
.$connection->name()
|
||||
." ("
|
||||
.' ('
|
||||
.$connection->fileno()
|
||||
.")\n"
|
||||
);
|
||||
|
@ -259,16 +171,16 @@ while( 1 ) {
|
|||
}
|
||||
} else {
|
||||
delete( $spawned_connections{$connection->fileno()} );
|
||||
Debug( "Removed spawned connection ("
|
||||
Debug( 'Removed spawned connection ('
|
||||
.$connection->fileno()
|
||||
."), "
|
||||
.'), '
|
||||
.int(keys(%spawned_connections))
|
||||
." spawned connections\n"
|
||||
);
|
||||
$connection->close();
|
||||
}
|
||||
}
|
||||
} # end foreach connection
|
||||
} # end foreach spawned connection
|
||||
} elsif ( $nfound < 0 ) {
|
||||
if ( $! == EINTR ) {
|
||||
# Do nothing
|
||||
|
@ -299,33 +211,44 @@ while( 1 ) {
|
|||
}
|
||||
|
||||
my ( $state, $last_event ) = zmMemRead( $monitor,
|
||||
[ 'shared_data:state', 'shared_data:last_event' ]
|
||||
[
|
||||
'shared_data:state',
|
||||
'shared_data:last_event'
|
||||
]
|
||||
);
|
||||
|
||||
#print( "$monitor->{Id}: S:$state, LE:$last_event\n" );
|
||||
#print( "$monitor->{Id}: mS:$monitor->{LastState}, mLE:$monitor->{LastEvent}\n" );
|
||||
if ( $state == STATE_ALARM || $state == STATE_ALERT ) { # In alarm state
|
||||
if ( $state == STATE_ALARM || $state == STATE_ALERT ) {
|
||||
# In alarm state
|
||||
if ( !defined($monitor->{LastEvent})
|
||||
|| ($last_event != $monitor->{LastEvent})
|
||||
) { # A new event
|
||||
push( @out_messages, $monitor->{Id}.'|on|'.time().'|'.$last_event );
|
||||
} else { # The same one as last time, so ignore it
|
||||
) {
|
||||
# A new event
|
||||
push( @out_messages, $monitor->{Id}."|on|".time()."|".$last_event );
|
||||
} else {
|
||||
# The same one as last time, so ignore it
|
||||
# Do nothing
|
||||
}
|
||||
} elsif ( ($state == STATE_IDLE && $monitor->{LastState} != STATE_IDLE)
|
||||
|| ($state == STATE_TAPE && $monitor->{LastState} != STATE_TAPE
|
||||
)) { # Out of alarm state
|
||||
} elsif (
|
||||
($state == STATE_IDLE && $monitor->{LastState} != STATE_IDLE)
|
||||
||
|
||||
($state == STATE_TAPE && $monitor->{LastState} != STATE_TAPE)
|
||||
) {
|
||||
# Out of alarm state
|
||||
push( @out_messages, $monitor->{Id}.'|off|'.time().'|'.$last_event );
|
||||
} elsif ( defined($monitor->{LastEvent})
|
||||
&& ($last_event != $monitor->{LastEvent})
|
||||
) { # We've missed a whole event
|
||||
} elsif (
|
||||
defined($monitor->{LastEvent})
|
||||
&&
|
||||
($last_event != $monitor->{LastEvent})
|
||||
) {
|
||||
# We've missed a whole event
|
||||
push( @out_messages, $monitor->{Id}.'|on|'.time().'|'.$last_event );
|
||||
push( @out_messages, $monitor->{Id}.'|off|'.time().'|'.$last_event );
|
||||
}
|
||||
$monitor->{LastState} = $state;
|
||||
$monitor->{LastEvent} = $last_event;
|
||||
} # end foreach monitor
|
||||
|
||||
foreach my $connection ( @out_connections ) {
|
||||
if ( $connection->canWrite() ) {
|
||||
$connection->putMessages( \@out_messages );
|
||||
|
@ -379,7 +302,9 @@ while( 1 ) {
|
|||
loadMonitors();
|
||||
$needsReload = 0;
|
||||
}
|
||||
}
|
||||
# zmDbConnect will ping and reconnect if neccessary
|
||||
$dbh = zmDbConnect();
|
||||
} # end while ( 1 )
|
||||
Info( "Trigger daemon exiting\n" );
|
||||
exit;
|
||||
|
||||
|
@ -389,9 +314,9 @@ sub loadMonitors {
|
|||
|
||||
my %new_monitors = ();
|
||||
|
||||
my $sql = "SELECT * FROM Monitors WHERE find_in_set( Function, 'Modect,Mocord,Nodect' )".
|
||||
( $Config{ZM_SERVER_ID} ? 'AND ServerId=?' : '' ).
|
||||
'ORDER BY Id DESC'
|
||||
my $sql = "SELECT * FROM Monitors
|
||||
WHERE find_in_set( Function, 'Modect,Mocord,Nodect' )".
|
||||
( $Config{ZM_SERVER_ID} ? 'AND ServerId=?' : '' )
|
||||
;
|
||||
my $sth = $dbh->prepare_cached( $sql )
|
||||
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
|
||||
|
@ -450,7 +375,7 @@ sub handleMessage {
|
|||
handleDelay($delay, $connection, $action_text);
|
||||
}
|
||||
} elsif ( $action =~ /^(on|off)(?:[ \+](\d+))?$/ ) {
|
||||
next if ( !$monitor->{Enabled} );
|
||||
next if !$monitor->{Enabled};
|
||||
|
||||
my $trigger = $1;
|
||||
my $delay = $2;
|
||||
|
@ -473,7 +398,9 @@ sub handleMessage {
|
|||
zmTriggerShowtext( $monitor, $showtext ) if defined($showtext);
|
||||
Info( "Trigger '$trigger'\n" );
|
||||
# Wait til it's finished
|
||||
while( zmInAlarm( $monitor ) && ($last_event == zmGetLastEvent( $monitor ))) {
|
||||
while( zmInAlarm( $monitor )
|
||||
&& ($last_event == zmGetLastEvent( $monitor ))
|
||||
) {
|
||||
# Tenth of a second
|
||||
usleep( 100000 );
|
||||
}
|
||||
|
@ -507,3 +434,90 @@ sub handleDelay {
|
|||
}
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
zmtrigger.pl - ZoneMinder External Trigger Script
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This script is used to trigger and cancel alarms from external connections
|
||||
using an arbitrary text based format.
|
||||
|
||||
This script offers generic solution to external triggering of alarms. It
|
||||
can handle external connections via either internet socket, unix socket or
|
||||
file/device interfaces. You can either use it 'as is' if you can interface
|
||||
with the existing format, or override connections and channels to customise
|
||||
it to your needs.
|
||||
|
||||
If enabled by the OPT_TRIGGERS option, Zoneminder service start
|
||||
zmtrigger.pl which listens for control messages on TCP port 6802.
|
||||
|
||||
=head1 TRIGGER MESSAGE FORMAT
|
||||
|
||||
B<id>|B<action>|B<score>|B<cause>|B<text>|B<showtext>
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<id>
|
||||
|
||||
is the id number or name of the ZM monitor.
|
||||
|
||||
=item B<action>
|
||||
|
||||
Valid actions are 'on', 'off', 'cancel' or 'show' where
|
||||
'on' forces an alarm condition on;
|
||||
'off' forces an alarm condition off;
|
||||
'cancel' negates the previous 'on' or 'off';
|
||||
'show' updates the auxiliary text represented by the %Q
|
||||
placeholder, which can optionally be added to the affected monitor's
|
||||
timestamp label format.
|
||||
|
||||
Ordinarily you would use 'on' and 'cancel', 'off' would tend to be
|
||||
used to suppress motion based events. Additionally 'on' and 'off' can
|
||||
take an additional time offset, e.g. on+20 which automatically
|
||||
cancel's the previous action after that number of seconds.
|
||||
|
||||
=item B<score>
|
||||
|
||||
is the score given to the alarm, usually to indicate it's
|
||||
importance. For 'on' triggers it should be non-zero, otherwise it should
|
||||
be zero.
|
||||
|
||||
=item B<cause>
|
||||
|
||||
is a 32 char max string indicating the reason for, or source of
|
||||
the alarm e.g. 'Relay 1 open'. This is saved in the 'Cause' field of the
|
||||
event. Ignored for 'off' or 'cancel' messages.
|
||||
|
||||
=item B<text>
|
||||
|
||||
is a 256 char max additional info field, which is saved in the
|
||||
'Description' field of an event. Ignored for 'off' or 'cancel' messages.
|
||||
|
||||
=item B<showtext>
|
||||
|
||||
is up to 32 characters of text that can be displayed in the
|
||||
timestamp that is added to images. The 'show' action is designed to
|
||||
update this text without affecting alarms but the text is updated, if
|
||||
present, for any of the actions. This is designed to allow external input
|
||||
to appear on the images captured, for instance temperature or personnel
|
||||
identity etc.
|
||||
|
||||
=back
|
||||
|
||||
Note that multiple messages can be sent at once and should be LF or CRLF
|
||||
delimited. This script is not necessarily intended to be a solution in
|
||||
itself, but is intended to be used as 'glue' to help ZoneMinder interface
|
||||
with other systems. It will almost certainly require some customisation
|
||||
before you can make any use of it. If all you want to do is generate alarms
|
||||
from external sources then using the ZoneMinder::SharedMem perl module is
|
||||
likely to be easier.
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
3|on+10|1|motion|text|showtext
|
||||
|
||||
Triggers 'alarm' on camera #3 for 10 seconds with score=1, cause='motion'.
|
||||
|
||||
=cut
|
||||
|
|
|
@ -237,7 +237,7 @@ if ( $concat_name ) {
|
|||
}
|
||||
close $fd;
|
||||
my $command = $Config{ZM_PATH_FFMPEG}
|
||||
. " -f concat -i $concat_list_file -c copy "
|
||||
. " -f concat -safe 0 -i $concat_list_file -c copy "
|
||||
.$Config{ZM_FFMPEG_OUTPUT_OPTIONS}
|
||||
." '$video_file' > $Config{ZM_PATH_LOGS}/ffmpeg_${concat_name}.log 2>&1"
|
||||
;
|
||||
|
|
|
@ -27,10 +27,11 @@ MYSQL dbconn;
|
|||
|
||||
int zmDbConnected = false;
|
||||
|
||||
void zmDbConnect()
|
||||
{
|
||||
if ( !mysql_init( &dbconn ) )
|
||||
{
|
||||
void zmDbConnect() {
|
||||
if ( zmDbConnected )
|
||||
return;
|
||||
|
||||
if ( !mysql_init( &dbconn ) ) {
|
||||
Error( "Can't initialise database connection: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
}
|
||||
|
@ -38,48 +39,35 @@ void zmDbConnect()
|
|||
if ( mysql_options( &dbconn, MYSQL_OPT_RECONNECT, &reconnect ) )
|
||||
Fatal( "Can't set database auto reconnect option: %s", mysql_error( &dbconn ) );
|
||||
std::string::size_type colonIndex = staticConfig.DB_HOST.find( ":" );
|
||||
if ( colonIndex == std::string::npos )
|
||||
{
|
||||
if ( !mysql_real_connect( &dbconn, staticConfig.DB_HOST.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, 0, NULL, 0 ) )
|
||||
{
|
||||
if ( colonIndex == std::string::npos ) {
|
||||
if ( !mysql_real_connect( &dbconn, staticConfig.DB_HOST.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, 0, NULL, 0 ) ) {
|
||||
Error( "Can't connect to server: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
std::string dbHost = staticConfig.DB_HOST.substr( 0, colonIndex );
|
||||
std::string dbPortOrSocket = staticConfig.DB_HOST.substr( colonIndex+1 );
|
||||
if ( dbPortOrSocket[0] == '/' )
|
||||
{
|
||||
if ( !mysql_real_connect( &dbconn, NULL, staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, 0, dbPortOrSocket.c_str(), 0 ) )
|
||||
{
|
||||
if ( dbPortOrSocket[0] == '/' ) {
|
||||
if ( !mysql_real_connect( &dbconn, NULL, staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, 0, dbPortOrSocket.c_str(), 0 ) ) {
|
||||
Error( "Can't connect to server: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !mysql_real_connect( &dbconn, dbHost.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, atoi(dbPortOrSocket.c_str()), NULL, 0 ) )
|
||||
{
|
||||
} else {
|
||||
if ( !mysql_real_connect( &dbconn, dbHost.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, atoi(dbPortOrSocket.c_str()), NULL, 0 ) ) {
|
||||
Error( "Can't connect to server: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( mysql_select_db( &dbconn, staticConfig.DB_NAME.c_str() ) )
|
||||
{
|
||||
if ( mysql_select_db( &dbconn, staticConfig.DB_NAME.c_str() ) ) {
|
||||
Error( "Can't select database: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
}
|
||||
zmDbConnected = true;
|
||||
}
|
||||
|
||||
void zmDbClose()
|
||||
{
|
||||
if ( zmDbConnected )
|
||||
{
|
||||
void zmDbClose() {
|
||||
if ( zmDbConnected ) {
|
||||
mysql_close( &dbconn );
|
||||
// mysql_init() call implicitly mysql_library_init() but
|
||||
// mysql_close() does not call mysql_library_end()
|
||||
|
|
|
@ -155,6 +155,7 @@ bool EventStream::loadEventData( int event_id ) {
|
|||
else
|
||||
snprintf( event_data->path, sizeof(event_data->path), "%s/%s/%ld/%ld", staticConfig.PATH_WEB.c_str(), storage_path, event_data->monitor_id, event_data->event_id );
|
||||
}
|
||||
delete storage; storage = NULL;
|
||||
|
||||
updateFrameRate( (double)event_data->frame_count/event_data->duration );
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ FfmpegCamera::FfmpegCamera( int p_id, const std::string &p_path, const std::stri
|
|||
mRawFrame = NULL;
|
||||
mFrame = NULL;
|
||||
frameCount = 0;
|
||||
startTime=0;
|
||||
startTime = 0;
|
||||
mIsOpening = false;
|
||||
mCanCapture = false;
|
||||
mOpenStart = 0;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "zm_config.h"
|
||||
#include "zm_utils.h"
|
||||
#include "zm_db.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
@ -333,45 +334,7 @@ Logger::Level Logger::databaseLevel( Logger::Level databaseLevel ) {
|
|||
databaseLevel = limit(databaseLevel);
|
||||
if ( mDatabaseLevel != databaseLevel ) {
|
||||
if ( databaseLevel > NOLOG && mDatabaseLevel <= NOLOG ) {
|
||||
if ( !mDbConnected ) {
|
||||
if ( !mysql_init( &mDbConnection ) ) {
|
||||
Fatal( "Can't initialise database connection: %s", mysql_error( &mDbConnection ) );
|
||||
exit( mysql_errno( &mDbConnection ) );
|
||||
}
|
||||
my_bool reconnect = 1;
|
||||
if ( mysql_options( &mDbConnection, MYSQL_OPT_RECONNECT, &reconnect ) )
|
||||
Fatal( "Can't set database auto reconnect option: %s", mysql_error( &mDbConnection ) );
|
||||
std::string::size_type colonIndex = staticConfig.DB_HOST.find( ":" );
|
||||
if ( colonIndex == std::string::npos ) {
|
||||
if ( !mysql_real_connect( &mDbConnection, staticConfig.DB_HOST.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, 0, NULL, 0 ) ) {
|
||||
Fatal( "Can't connect to database: %s", mysql_error( &mDbConnection ) );
|
||||
exit( mysql_errno( &mDbConnection ) );
|
||||
}
|
||||
} else {
|
||||
std::string dbHost = staticConfig.DB_HOST.substr( 0, colonIndex );
|
||||
std::string dbPortOrSocket = staticConfig.DB_HOST.substr( colonIndex+1 );
|
||||
if ( dbPortOrSocket[0] == '/' ) {
|
||||
if ( !mysql_real_connect( &mDbConnection, NULL, staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, 0, dbPortOrSocket.c_str(), 0 ) ) {
|
||||
Fatal( "Can't connect to database: %s", mysql_error( &mDbConnection ) );
|
||||
exit( mysql_errno( &mDbConnection ) );
|
||||
}
|
||||
} else {
|
||||
if ( !mysql_real_connect( &mDbConnection, dbHost.c_str(), staticConfig.DB_USER.c_str(), staticConfig.DB_PASS.c_str(), NULL, atoi(dbPortOrSocket.c_str()), NULL, 0 ) ) {
|
||||
Fatal( "Can't connect to database: %s", mysql_error( &mDbConnection ) );
|
||||
exit( mysql_errno( &mDbConnection ) );
|
||||
}
|
||||
}
|
||||
} // end if has colon
|
||||
unsigned long mysqlVersion = mysql_get_server_version( &mDbConnection );
|
||||
if ( mysqlVersion < 50019 )
|
||||
if ( mysql_options( &mDbConnection, MYSQL_OPT_RECONNECT, &reconnect ) )
|
||||
Fatal( "Can't set database auto reconnect option: %s", mysql_error( &mDbConnection ) );
|
||||
if ( mysql_select_db( &mDbConnection, staticConfig.DB_NAME.c_str() ) ) {
|
||||
Fatal( "Can't select database: %s", mysql_error( &mDbConnection ) );
|
||||
exit( mysql_errno( &mDbConnection ) );
|
||||
}
|
||||
mDbConnected = true;
|
||||
} // end if ! mDbConnected
|
||||
zmDbConnect();
|
||||
} // end if ( databaseLevel > NOLOG && mDatabaseLevel <= NOLOG )
|
||||
mDatabaseLevel = databaseLevel;
|
||||
} // end if ( mDatabaseLevel != databaseLevel )
|
||||
|
@ -439,10 +402,7 @@ void Logger::closeFile() {
|
|||
}
|
||||
|
||||
void Logger::closeDatabase() {
|
||||
if ( mDbConnected ) {
|
||||
mysql_close( &mDbConnection );
|
||||
mDbConnected = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Logger::openSyslog() {
|
||||
|
@ -548,13 +508,13 @@ void Logger::logPrint( bool hex, const char * const filepath, const int line, co
|
|||
char sql[ZM_SQL_MED_BUFSIZ];
|
||||
char escapedString[(strlen(syslogStart)*2)+1];
|
||||
|
||||
mysql_real_escape_string( &mDbConnection, escapedString, syslogStart, strlen(syslogStart) );
|
||||
mysql_real_escape_string( &dbconn, escapedString, syslogStart, strlen(syslogStart) );
|
||||
|
||||
snprintf( sql, sizeof(sql), "insert into Logs ( TimeKey, Component, ServerId, Pid, Level, Code, Message, File, Line ) values ( %ld.%06ld, '%s', %d, %d, %d, '%s', '%s', '%s', %d )", timeVal.tv_sec, timeVal.tv_usec, mId.c_str(), staticConfig.SERVER_ID, tid, level, classString, escapedString, file, line );
|
||||
if ( mysql_query( &mDbConnection, sql ) ) {
|
||||
if ( mysql_query( &dbconn, sql ) ) {
|
||||
Level tempDatabaseLevel = mDatabaseLevel;
|
||||
databaseLevel( NOLOG );
|
||||
Error( "Can't insert log entry: sql(%s) error(%s)", sql, mysql_error( &mDbConnection ) );
|
||||
Error( "Can't insert log entry: sql(%s) error(%s)", sql, mysql_error( &dbconn ) );
|
||||
databaseLevel(tempDatabaseLevel);
|
||||
}
|
||||
}
|
||||
|
@ -566,6 +526,8 @@ void Logger::logPrint( bool hex, const char * const filepath, const int line, co
|
|||
|
||||
free(filecopy);
|
||||
if ( level <= FATAL ) {
|
||||
logTerm();
|
||||
zmDbClose();
|
||||
if ( level <= PANIC )
|
||||
abort();
|
||||
exit( -1 );
|
||||
|
|
|
@ -27,16 +27,14 @@
|
|||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
User::User()
|
||||
{
|
||||
User::User() {
|
||||
username[0] = password[0] = 0;
|
||||
enabled = false;
|
||||
stream = events = control = monitors = system = PERM_NONE;
|
||||
monitor_ids = 0;
|
||||
}
|
||||
|
||||
User::User( MYSQL_ROW &dbrow )
|
||||
{
|
||||
User::User( MYSQL_ROW &dbrow ) {
|
||||
int index = 0;
|
||||
strncpy( username, dbrow[index++], sizeof(username) );
|
||||
strncpy( password, dbrow[index++], sizeof(password) );
|
||||
|
@ -48,22 +46,18 @@ User::User( MYSQL_ROW &dbrow )
|
|||
system = (Permission)atoi( dbrow[index++] );
|
||||
monitor_ids = 0;
|
||||
char *monitor_ids_str = dbrow[index++];
|
||||
if ( monitor_ids_str && *monitor_ids_str )
|
||||
{
|
||||
if ( monitor_ids_str && *monitor_ids_str ) {
|
||||
monitor_ids = new int[strlen(monitor_ids_str)];
|
||||
int n_monitor_ids = 0;
|
||||
const char *ptr = monitor_ids_str;
|
||||
do
|
||||
{
|
||||
do {
|
||||
int id = 0;
|
||||
while( isdigit( *ptr ) )
|
||||
{
|
||||
while( isdigit( *ptr ) ) {
|
||||
id *= 10;
|
||||
id += *ptr-'0';
|
||||
ptr++;
|
||||
}
|
||||
if ( id )
|
||||
{
|
||||
if ( id ) {
|
||||
monitor_ids[n_monitor_ids++] = id;
|
||||
if ( !*ptr )
|
||||
break;
|
||||
|
@ -75,21 +69,16 @@ User::User( MYSQL_ROW &dbrow )
|
|||
}
|
||||
}
|
||||
|
||||
User::~User()
|
||||
{
|
||||
User::~User() {
|
||||
delete monitor_ids;
|
||||
}
|
||||
|
||||
bool User::canAccess( int monitor_id )
|
||||
{
|
||||
if ( !monitor_ids )
|
||||
{
|
||||
bool User::canAccess( int monitor_id ) {
|
||||
if ( !monitor_ids ) {
|
||||
return( true );
|
||||
}
|
||||
for ( int i = 0; monitor_ids[i]; i++ )
|
||||
{
|
||||
if ( monitor_ids[i] == monitor_id )
|
||||
{
|
||||
for ( int i = 0; monitor_ids[i]; i++ ) {
|
||||
if ( monitor_ids[i] == monitor_id ) {
|
||||
return( true );
|
||||
}
|
||||
}
|
||||
|
@ -98,8 +87,7 @@ bool User::canAccess( int monitor_id )
|
|||
|
||||
// Function to load a user from username and password
|
||||
// Please note that in auth relay mode = none, password is NULL
|
||||
User *zmLoadUser( const char *username, const char *password )
|
||||
{
|
||||
User *zmLoadUser( const char *username, const char *password ) {
|
||||
char sql[ZM_SQL_SML_BUFSIZ] = "";
|
||||
char safer_username[65]; // current db username size is 32
|
||||
char safer_password[129]; // current db password size is 64
|
||||
|
@ -114,22 +102,20 @@ User *zmLoadUser( const char *username, const char *password )
|
|||
snprintf( sql, sizeof(sql), "select Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds from Users where Username = '%s' and Enabled = 1", safer_username );
|
||||
}
|
||||
|
||||
if ( mysql_query( &dbconn, sql ) )
|
||||
{
|
||||
if ( mysql_query( &dbconn, sql ) ) {
|
||||
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
}
|
||||
|
||||
MYSQL_RES *result = mysql_store_result( &dbconn );
|
||||
if ( !result )
|
||||
{
|
||||
if ( !result ) {
|
||||
Error( "Can't use query result: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
}
|
||||
int n_users = mysql_num_rows( result );
|
||||
|
||||
if ( n_users != 1 )
|
||||
{
|
||||
if ( n_users != 1 ) {
|
||||
mysql_free_result( result );
|
||||
Warning( "Unable to authenticate user %s", username );
|
||||
return( 0 );
|
||||
}
|
||||
|
@ -145,13 +131,11 @@ User *zmLoadUser( const char *username, const char *password )
|
|||
}
|
||||
|
||||
// Function to validate an authentication string
|
||||
User *zmLoadAuthUser( const char *auth, bool use_remote_addr )
|
||||
{
|
||||
User *zmLoadAuthUser( const char *auth, bool use_remote_addr ) {
|
||||
#if HAVE_DECL_MD5 || HAVE_DECL_GNUTLS_FINGERPRINT
|
||||
#ifdef HAVE_GCRYPT_H
|
||||
// Special initialisation for libgcrypt
|
||||
if ( !gcry_check_version( GCRYPT_VERSION ) )
|
||||
{
|
||||
if ( !gcry_check_version( GCRYPT_VERSION ) ) {
|
||||
Fatal( "Unable to initialise libgcrypt" );
|
||||
}
|
||||
gcry_control( GCRYCTL_DISABLE_SECMEM, 0 );
|
||||
|
@ -159,11 +143,9 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr )
|
|||
#endif // HAVE_GCRYPT_H
|
||||
|
||||
const char *remote_addr = "";
|
||||
if ( use_remote_addr )
|
||||
{
|
||||
if ( use_remote_addr ) {
|
||||
remote_addr = getenv( "REMOTE_ADDR" );
|
||||
if ( !remote_addr )
|
||||
{
|
||||
if ( !remote_addr ) {
|
||||
Warning( "Can't determine remote address, using null" );
|
||||
remote_addr = "";
|
||||
}
|
||||
|
@ -173,28 +155,25 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr )
|
|||
char sql[ZM_SQL_SML_BUFSIZ] = "";
|
||||
snprintf( sql, sizeof(sql), "SELECT Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds FROM Users WHERE Enabled = 1" );
|
||||
|
||||
if ( mysql_query( &dbconn, sql ) )
|
||||
{
|
||||
if ( mysql_query( &dbconn, sql ) ) {
|
||||
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
}
|
||||
|
||||
MYSQL_RES *result = mysql_store_result( &dbconn );
|
||||
if ( !result )
|
||||
{
|
||||
if ( !result ) {
|
||||
Error( "Can't use query result: %s", mysql_error( &dbconn ) );
|
||||
exit( mysql_errno( &dbconn ) );
|
||||
}
|
||||
int n_users = mysql_num_rows( result );
|
||||
|
||||
if ( n_users < 1 )
|
||||
{
|
||||
if ( n_users < 1 ) {
|
||||
mysql_free_result( result );
|
||||
Warning( "Unable to authenticate user" );
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
while( MYSQL_ROW dbrow = mysql_fetch_row( result ) )
|
||||
{
|
||||
while( MYSQL_ROW dbrow = mysql_fetch_row( result ) ) {
|
||||
const char *user = dbrow[0];
|
||||
const char *pass = dbrow[1];
|
||||
|
||||
|
@ -204,7 +183,7 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr )
|
|||
unsigned char md5sum[md5len];
|
||||
|
||||
time_t now = time( 0 );
|
||||
unsigned int hours =config.auth_hash_ttl;
|
||||
unsigned int hours = config.auth_hash_ttl;
|
||||
|
||||
if ( ! hours ) {
|
||||
Warning("No value set for ZM_AUTH_HASH_TTL. Defaulting to 2.");
|
||||
|
@ -234,23 +213,23 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr )
|
|||
gnutls_fingerprint( GNUTLS_DIG_MD5, &md5data, md5sum, &md5len );
|
||||
#endif
|
||||
auth_md5[0] = '\0';
|
||||
for ( unsigned int j = 0; j < md5len; j++ )
|
||||
{
|
||||
for ( unsigned int j = 0; j < md5len; j++ ) {
|
||||
sprintf( &auth_md5[2*j], "%02x", md5sum[j] );
|
||||
}
|
||||
Debug( 1, "Checking auth_key '%s' -> auth_md5 '%s' == '%s'", auth_key, auth_md5, auth );
|
||||
|
||||
if ( !strcmp( auth, auth_md5 ) )
|
||||
{
|
||||
if ( !strcmp( auth, auth_md5 ) ) {
|
||||
// We have a match
|
||||
User *user = new User( dbrow );
|
||||
Debug(1, "Authenticated user '%s'", user->getUsername() );
|
||||
mysql_free_result( result );
|
||||
return( user );
|
||||
} else {
|
||||
Debug(1, "No match for %s", auth );
|
||||
}
|
||||
}
|
||||
}
|
||||
mysql_free_result( result );
|
||||
#else // HAVE_DECL_MD5
|
||||
Error( "You need to build with gnutls or openssl installed to use hash based authentication" );
|
||||
#endif // HAVE_DECL_MD5
|
||||
|
|
|
@ -259,13 +259,10 @@ fi
|
|||
|
||||
if [ $TYPE == "binary" ]; then
|
||||
if [ "$INTERACTIVE" != "no" ]; then
|
||||
read -p "Not doing dput since it's a binary release. Do you want to install it? (Y/N)"
|
||||
read -p "Not doing dput since it's a binary release. Do you want to install it? (y/N)"
|
||||
if [[ $REPLY == [yY] ]]; then
|
||||
sudo dpkg -i $DIRECTORY*.deb
|
||||
else
|
||||
echo $REPLY;
|
||||
fi;
|
||||
if [ "$DISTRO" == "jessie" ]; then
|
||||
read -p "Do you want to upload this binary to zmrepo? (y/N)"
|
||||
if [[ $REPLY == [yY] ]]; then
|
||||
if [ "$RELEASE" != "" ]; then
|
||||
|
@ -279,7 +276,6 @@ if [ $TYPE == "binary" ]; then
|
|||
fi;
|
||||
fi;
|
||||
fi;
|
||||
fi;
|
||||
else
|
||||
SC="zoneminder_${VERSION}-${DISTRO}${PACKAGE_VERSION}_source.changes";
|
||||
PPA="";
|
||||
|
|
|
@ -94,9 +94,8 @@ switch ( $_REQUEST['task'] )
|
|||
$sql .= " order by ".$sortField." ".$sortOrder." limit ".$limit;
|
||||
$logs = array();
|
||||
foreach ( dbFetchAll( $sql, NULL, $values ) as $log ) {
|
||||
$log['DateTime'] = preg_replace( '/^\d+/', strftime( "%Y-%m-%d %H:%M:%S", intval($log['TimeKey']) ), $log['TimeKey'] );
|
||||
$log['DateTime'] = preg_replace( '/^\d+/', strftime( '%Y-%m-%d %H:%M:%S', intval($log['TimeKey']) ), $log['TimeKey'] );
|
||||
$log['Server'] = ( $log['ServerId'] and isset($servers_by_Id[$log['ServerId']]) ) ? $servers_by_Id[$log['ServerId']]->Name() : '';
|
||||
#$log['Message'] = preg_replace('/[\x00-\x1F\x7F]/u', '', $log['Message'] );
|
||||
$log['Message'] = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $log['Message'] );
|
||||
$logs[] = $log;
|
||||
}
|
||||
|
|
|
@ -101,49 +101,66 @@ CakeLog::config('debug', array(
|
|||
'engine' => 'File',
|
||||
'types' => array('notice', 'info', 'debug'),
|
||||
'file' => 'cake_debug',
|
||||
'path' => '@ZM_LOGDIR@/'
|
||||
));
|
||||
CakeLog::config('error', array(
|
||||
'engine' => 'File',
|
||||
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
|
||||
'file' => 'cake_error',
|
||||
'path' => '@ZM_LOGDIR@/'
|
||||
));
|
||||
CakeLog::config('custom_path', array(
|
||||
'engine' => 'File',
|
||||
'path' => '@ZM_LOGDIR@'
|
||||
'path' => '@ZM_LOGDIR@/'
|
||||
));
|
||||
|
||||
Configure::write('ZM_CONFIG', '@ZM_CONFIG@');
|
||||
Configure::write('ZM_CONFIG_SUBDIR', '@ZM_CONFIG_SUBDIR@');
|
||||
Configure::write('ZM_VERSION', '@VERSION@');
|
||||
Configure::write('ZM_API_VERSION', '@API_VERSION@');
|
||||
|
||||
loadConfigFile();
|
||||
# Process name, value pairs from the main config file first
|
||||
$configvals = process_configfile(Configure::read('ZM_CONFIG'));
|
||||
|
||||
function loadConfigFile() {
|
||||
$configFile = Configure::read('ZM_CONFIG');
|
||||
$localConfigFile = basename($configFile);
|
||||
if ( file_exists( $localConfigFile ) && filesize( $localConfigFile ) > 0 )
|
||||
{
|
||||
if ( php_sapi_name() == 'cli' && empty($_SERVER['REMOTE_ADDR']) )
|
||||
print( "Warning, overriding installed $localConfigFile file with local copy\n" );
|
||||
else
|
||||
error_log( "Warning, overriding installed $localConfigFile file with local copy" );
|
||||
$configFile = $localConfigFile;
|
||||
# Search for user created config files. If one or more are found then
|
||||
# update our config value array with those values
|
||||
$configSubFolder = Configure::read('ZM_CONFIG_SUBDIR');
|
||||
if ( is_dir($configSubFolder) ) {
|
||||
if ( is_readable($configSubFolder) ) {
|
||||
foreach ( glob("$configSubFolder/*.conf") as $filename ) {
|
||||
$configvals = array_replace($configvals, process_configfile($filename) );
|
||||
}
|
||||
} else {
|
||||
error_log( "WARNING: ZoneMinder configuration subfolder found but is not readable. Check folder permissions on $configSubFolder." );
|
||||
}
|
||||
}
|
||||
|
||||
# Now that our array our finalized, define each key => value
|
||||
# pair in the array as a constant
|
||||
foreach( $configvals as $key => $value) {
|
||||
define( $key, $value );
|
||||
Configure::write( $matches[1], $matches[2] );
|
||||
}
|
||||
|
||||
function process_configfile($configFile) {
|
||||
if ( is_readable( $configFile ) ) {
|
||||
$configvals = array();
|
||||
|
||||
$cfg = fopen( $configFile, "r") or die("Could not open config file.");
|
||||
while ( !feof($cfg) )
|
||||
{
|
||||
while ( !feof($cfg) ) {
|
||||
$str = fgets( $cfg, 256 );
|
||||
if ( preg_match( '/^\s*$/', $str ))
|
||||
continue;
|
||||
elseif ( preg_match( '/^\s*#/', $str ))
|
||||
continue;
|
||||
elseif ( preg_match( '/^\s*([^=\s]+)\s*=\s*(.*?)\s*$/', $str, $matches )) {
|
||||
Configure::write( $matches[1], $matches[2] );
|
||||
define( $matches[1], $matches[2] );
|
||||
}
|
||||
elseif ( preg_match( '/^\s*([^=\s]+)\s*=\s*(.*?)\s*$/', $str, $matches ))
|
||||
$configvals[$matches[1]] = $matches[2];
|
||||
}
|
||||
fclose( $cfg );
|
||||
return( $configvals );
|
||||
} else {
|
||||
error_log( "WARNING: ZoneMinder configuration file found but is not readable. Check file permissions on $configFile." );
|
||||
return( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1146,7 +1146,7 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&' ) {
|
|||
|
||||
$StorageArea = NULL;
|
||||
|
||||
$terms = $filter['Query']['terms'];
|
||||
$terms = isset($filter['Query']) ? $filter['Query']['terms'] : NULL;
|
||||
|
||||
if ( isset($terms) && count($terms) ) {
|
||||
for ( $i = 0; $i < count($terms); $i++ ) {
|
||||
|
@ -2133,18 +2133,14 @@ function getStreamHTML( $monitor, $options = array() ) {
|
|||
$options['height'] = reScale( $monitor->Height(), $options['scale'] );
|
||||
} else {
|
||||
if ( ! isset( $options['width'] ) ) {
|
||||
if ( $options['width'] == 100 ) {
|
||||
$options['width'] = $monitor->Width();
|
||||
} else {
|
||||
$options['width'] = NULL;
|
||||
}
|
||||
} else if ( $options['width'] == 100 ) {
|
||||
$options['width'] = $monitor->Width();
|
||||
}
|
||||
if ( ! isset( $options['height'] ) ) {
|
||||
if ( $options['height'] == 100 ) {
|
||||
$options['height'] = $monitor->Height();
|
||||
} else {
|
||||
$options['height'] = NULL;
|
||||
}
|
||||
} else if ( $options['height'] == 100 ) {
|
||||
$options['height'] = $monitor->Height();
|
||||
}
|
||||
}
|
||||
if ( ! isset($options['mode'] ) ) {
|
||||
|
|
|
@ -194,7 +194,7 @@ isset($view) || $view = NULL;
|
|||
isset($request) || $request = NULL;
|
||||
isset($action) || $action = NULL;
|
||||
|
||||
if ( ZM_ENABLE_CSRF_MAGIC && $action != 'login' && $view != 'view_video' ) {
|
||||
if ( ZM_ENABLE_CSRF_MAGIC && $action != 'login' && $view != 'view_video' && $request != 'control' ) {
|
||||
require_once( 'includes/csrf/csrf-magic.php' );
|
||||
Logger::Debug("Calling csrf_check with the following values: \$request = \"$request\", \$view = \"$view\", \$action = \"$action\"");
|
||||
csrf_check();
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#monitors .imageFeed img ,
|
||||
#monitors .imageFeed svg {
|
||||
border: 2px solid #ffffff;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#monitors .imageFeed img.idle {
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#monitors .imageFeed img ,
|
||||
#monitors .imageFeed svg {
|
||||
border: 2px solid #999999;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#monitors .imageFeed img.idle {
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
#topPanel #textPanel {
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
height: 140px;
|
||||
margin: 0 auto;
|
||||
color: #dddddd;
|
||||
font-size: 11px;
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
margin: 0;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#monitors .imageFeed img.idle {
|
||||
|
|
|
@ -69,7 +69,6 @@
|
|||
#topPanel #textPanel {
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
height: 140px;
|
||||
margin: 0 auto;
|
||||
color: #016A9D;
|
||||
font-size: 11px;
|
||||
|
|
|
@ -211,10 +211,10 @@ function getNavBarHTML() {
|
|||
<li><?php if ( logToDatabase() > Logger::NOLOG ) { ?> <?php echo makePopupLink( '?view=log', 'zmLog', 'log', '<span class="'.logState().'">'.translate('Log').'</span>' ) ?><?php } ?></li>
|
||||
<?php } ?>
|
||||
<?php if ( ZM_OPT_X10 && canView( 'Devices' ) ) { ?>
|
||||
<li><a href="/?view=devices">Devices</a></li>
|
||||
<li><a href="?view=devices">Devices</a></li>
|
||||
<?php } ?>
|
||||
<li><?php echo makePopupLink( '?view=groups', 'zmGroups', 'groups', sprintf( $CLANG['MonitorCount'], count($displayMonitors), zmVlang( $VLANG['Monitor'], count($displayMonitors) ) ).($group?' ('.$group['Name'].')':''), canView( 'Groups' ) ); ?></li>
|
||||
<li><a href="/?view=filter">Filters</a></li>
|
||||
<li><a href="?view=filter">Filters</a></li>
|
||||
|
||||
<?php
|
||||
$cycleGroup = isset($_COOKIE['zmGroup'])?$_COOKIE['zmGroup']:0;
|
||||
|
@ -285,4 +285,19 @@ function getNavBarHTML() {
|
|||
<?php
|
||||
return( ob_get_clean() );
|
||||
} // end function getNavBarHTML()
|
||||
|
||||
function xhtmlFooter() {
|
||||
global $view;
|
||||
global $skin;
|
||||
global $running;
|
||||
if ( canEdit('System') ) {
|
||||
include("skins/$skin/views/state.php");
|
||||
?>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</body></html>
|
||||
<?php
|
||||
} // end xhtmlFooter
|
||||
|
||||
?>
|
||||
|
|
|
@ -79,8 +79,8 @@ function getPopupSize( tag, width, height ) {
|
|||
popupSize.height = height;
|
||||
Error( "Got passed height but no addHeight when getting popup size for tag '"+tag+"'" );
|
||||
}
|
||||
if ( popupSize.minHeight && popupSize.height < popupSize.minHeight ) {
|
||||
Warning( "Adjusting to minimum height when getting popup size for tag '"+tag+"'" );
|
||||
if ( popupSize.minHeight && ( popupSize.height < popupSize.minHeight ) ) {
|
||||
Warning( "Adjusting to minimum height ("+popupSize.minHeight+") when getting popup size for tag '"+tag+"' because calculated height is " + popupSize.height );
|
||||
popupSize.height = popupSize.minHeight;
|
||||
}
|
||||
Debug( popupSize );
|
||||
|
@ -293,4 +293,3 @@ function addVideoTimingTrack(video, LabelFormat, monitorName, duration, startTim
|
|||
track.src = 'data:plain/text;charset=utf-8,'+encodeURIComponent(webvttdata);
|
||||
video.appendChild(track);
|
||||
}
|
||||
|
||||
|
|
|
@ -291,10 +291,4 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
|||
</table>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
if ( canEdit('System') ) {
|
||||
include("skins/$skin/views/state.php");
|
||||
}
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
|
@ -61,6 +61,7 @@ if ( isset( $_REQUEST['streamMode'] ) )
|
|||
else
|
||||
$streamMode = 'video';
|
||||
|
||||
$replayMode = '';
|
||||
if ( isset( $_REQUEST['replayMode'] ) )
|
||||
$replayMode = validHtmlStr($_REQUEST['replayMode']);
|
||||
if ( isset( $_COOKIE['replayMode']) && preg_match('#^[a-z]+$#', $_COOKIE['replayMode']) )
|
||||
|
|
|
@ -405,5 +405,4 @@ if ( canEdit( 'Events' ) ) {
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var logParms = "view=request&request=log&task=query";
|
||||
var logReq = new Request.JSON( { url: thisUrl, method: 'get', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: logResponse } );
|
||||
var logReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: logResponse } );
|
||||
var logTimer = undefined;
|
||||
var logTable = undefined;
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ function selectLayout( element ) {
|
|||
} else if ( streamImg.nodeName == 'APPLET' || streamImg.nodeName == 'OBJECT' ) {
|
||||
// APPLET's and OBJECTS need to be re-initialized
|
||||
}
|
||||
streamImg.style.width = '';
|
||||
streamImg.style.width = '100%';
|
||||
}
|
||||
var zonesSVG = $('zones'+monitor.id);
|
||||
if ( zonesSVG ) {
|
||||
|
@ -140,37 +140,8 @@ function selectLayout( element ) {
|
|||
}
|
||||
}
|
||||
|
||||
function changeWidth() {
|
||||
function changeSize() {
|
||||
var width = $('width').get('value');
|
||||
|
||||
for ( var x = 0; x < monitors.length; x++ ) {
|
||||
var monitor = monitors[x];
|
||||
/*Stream could be an applet so can't use moo tools*/
|
||||
var streamImg = $( 'liveStream'+monitor.id );
|
||||
if ( streamImg ) {
|
||||
if ( streamImg.nodeName == 'IMG' ) {
|
||||
var src = streamImg.src;
|
||||
streamImg.src='';
|
||||
src = src.replace(/width=[\.\d]+/i,'width='+width );
|
||||
src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
|
||||
streamImg.src = src;
|
||||
|
||||
}
|
||||
streamImg.style.width = width? width + "px" : null;
|
||||
//streamImg.style.height = '';
|
||||
}
|
||||
var zonesSVG = $('zones'+monitor.id);
|
||||
if ( zonesSVG ) {
|
||||
|
||||
zonesSVG.style.width = width ? width + "px" : '100%';
|
||||
}
|
||||
}
|
||||
$('scale').set('value', '' );
|
||||
Cookie.write( 'zmMontageScale', '', { duration: 10*365 } );
|
||||
Cookie.write( 'zmMontageWidth', width, { duration: 10*365 } );
|
||||
} // end function changeWidth()
|
||||
|
||||
function changeHeight() {
|
||||
var height = $('height').get('value');
|
||||
|
||||
for ( var x = 0; x < monitors.length; x++ ) {
|
||||
|
@ -181,21 +152,27 @@ function changeHeight() {
|
|||
if ( streamImg.nodeName == 'IMG' ) {
|
||||
var src = streamImg.src;
|
||||
streamImg.src='';
|
||||
src = src.replace(/width=[\.\d]+/i,'width='+width );
|
||||
src = src.replace(/height=[\.\d]+/i,'height='+height );
|
||||
src = src.replace(/rand=\d+/i,'rand='+Math.floor((Math.random() * 1000000) ));
|
||||
streamImg.src = src;
|
||||
streamImg.style.height = height ? height + "px" : null;
|
||||
|
||||
}
|
||||
streamImg.style.width = width? width + "px" : null;
|
||||
streamImg.style.height = height ? height + "px" : null;
|
||||
//streamImg.style.height = '';
|
||||
}
|
||||
var zonesSVG = $('zones'+monitor.id);
|
||||
if ( zonesSVG ) {
|
||||
zonesSVG.style.width = width ? width + "px" : '100%';
|
||||
zonesSVG.style.height = height + "px";
|
||||
}
|
||||
}
|
||||
$('scale').set('value', '' );
|
||||
Cookie.write( 'zmMontageHeight', height, { duration: 10*365 } );
|
||||
Cookie.write( 'zmMontageScale', '', { duration: 10*365 } );
|
||||
} // end function changeHeight()
|
||||
Cookie.write( 'zmMontageWidth', width, { duration: 10*365 } );
|
||||
Cookie.write( 'zmMontageHeight', height, { duration: 10*365 } );
|
||||
} // end function changeSize()
|
||||
|
||||
function changeScale() {
|
||||
var scale = $('scale').get('value');
|
||||
|
|
|
@ -32,7 +32,14 @@ $maxTimeSecs = strtotime('1950-01-01 01:01:01');
|
|||
$index=0;
|
||||
$anyAlarms=false;
|
||||
|
||||
foreach( dbFetchAll( $eventsSql ) as $event ) {
|
||||
$result = dbQuery( $eventsSql );
|
||||
if ( ! $result ) {
|
||||
Fatal( "SQL-ERR");
|
||||
return;
|
||||
}
|
||||
|
||||
while( $event = $result->fetch( PDO::FETCH_ASSOC ) ) {
|
||||
|
||||
if ( $minTimeSecs > $event['StartTimeSecs'] ) $minTimeSecs = $event['StartTimeSecs'];
|
||||
if ( $maxTimeSecs < $event['CalcEndTimeSecs'] ) $maxTimeSecs = $event['CalcEndTimeSecs'];
|
||||
echo "
|
||||
|
@ -84,8 +91,9 @@ $fromSecs=-1;
|
|||
$toSecs=-1;
|
||||
$maxScore=-1;
|
||||
|
||||
if ( $anyAlarms ) {
|
||||
foreach( dbFetchAll ($frameSql) as $frame ) {
|
||||
if ( $anyAlarms && $result = dbQuery( $frameSql ) ) {
|
||||
|
||||
while( $frame = $result->fetch( PDO::FETCH_ASSOC ) ) {
|
||||
if ( $mId < 0 ) {
|
||||
$mId = $frame['MonitorId'];
|
||||
$fromSecs = $frame['TimeStampSecs'];
|
||||
|
|
|
@ -3,13 +3,10 @@ var filterQuery = '<?php echo validJsStr($filterQuery) ?>';
|
|||
<?php
|
||||
$jsMonitors = array();
|
||||
$fields = array('Name', 'LabelFormat', 'SaveJPEGs', 'VideoWriter');
|
||||
foreach ( $monitors as $monitor )
|
||||
{
|
||||
if ( !empty($monitorIds[$monitor['Id']]) )
|
||||
{
|
||||
foreach ( $monitors as $monitor ) {
|
||||
if ( !empty($monitorIds[$monitor['Id']]) ) {
|
||||
$jsMonitor = array();
|
||||
foreach ($fields as $field)
|
||||
{
|
||||
foreach ($fields as $field) {
|
||||
$jsMonitor[$field] = $monitor[$field];
|
||||
}
|
||||
$jsMonitors[$monitor['Id']] = $jsMonitor;
|
||||
|
|
|
@ -58,7 +58,7 @@ if ( ! empty($_REQUEST['mid']) ) {
|
|||
} else {
|
||||
|
||||
$nextId = getTableAutoInc( 'Monitors' );
|
||||
if ( ! empty( $_REQUEST['dupId'] ) ) {
|
||||
if ( isset( $_REQUEST['dupId'] ) ) {
|
||||
$monitor = new Monitor( $_REQUEST['dupId'] );
|
||||
if ( ZM_OPT_X10 )
|
||||
$x10Monitor = dbFetchOne( 'SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['dupId']) );
|
||||
|
@ -566,7 +566,7 @@ if ( $tab != 'source' || $monitor->Type()!= 'Remote' ) {
|
|||
}
|
||||
if ( $tab != 'source' || ($monitor->Type()!= 'Local' && $monitor->Type()!= 'Remote' && $monitor->Type()!= 'Ffmpeg' && $monitor->Type()!= 'Libvlc') ) {
|
||||
?>
|
||||
<input type="hidden" name="newMonitor[Method]" value="<?php echo validHtmlStr($monitor->Method()) ?>"/>
|
||||
<input type="hidden" name="newMonitor[Method]" value="<?php echo validHtmlStr(null !== $monitor->Method() ? $monitor->Method() : 'rtpRtsp' ) ?>"/>
|
||||
<?php
|
||||
}
|
||||
if ( $tab != 'source' || ($monitor->Type()!= 'Ffmpeg' && $monitor->Type()!= 'Libvlc' )) {
|
||||
|
|
|
@ -41,7 +41,6 @@ if ( isset( $_REQUEST['showZones'] ) ) {
|
|||
}
|
||||
}
|
||||
$monitors = array();
|
||||
<<<<<<< HEAD
|
||||
$widths = array(
|
||||
'' => 'auto',
|
||||
160 => 160,
|
||||
|
@ -68,7 +67,6 @@ if ( isset( $_REQUEST['scale'] ) ) {
|
|||
|
||||
if ( ! $scale )
|
||||
$scale = 100;
|
||||
}
|
||||
|
||||
foreach( dbFetchAll( $sql ) as $row ) {
|
||||
if ( !visibleMonitor( $row['Id'] ) ) {
|
||||
|
@ -142,8 +140,8 @@ if ( $showZones ) {
|
|||
</div>
|
||||
<h2><?php echo translate('Montage') ?></h2>
|
||||
<div id="headerControl">
|
||||
<span id="widthControl"><label><?php echo translate('Width') ?>:</label><?php echo htmlSelect( 'width', $widths, $options['width'], 'changeWidth(this);' ); ?></span>
|
||||
<span id="heightControl"><label><?php echo translate('Height') ?>:</label><?php echo htmlSelect( 'height', $heights, $options['height'], 'changeHeight(this);' ); ?></span>
|
||||
<span id="widthControl"><label><?php echo translate('Width') ?>:</label><?php echo htmlSelect( 'width', $widths, $options['width'], 'changeSize(this);' ); ?></span>
|
||||
<span id="heightControl"><label><?php echo translate('Height') ?>:</label><?php echo htmlSelect( 'height', $heights, $options['height'], 'changeSize(this);' ); ?></span>
|
||||
<span id="scaleControl"><label><?php echo translate('Scale') ?>:</label><?php echo htmlSelect( 'scale', $scales, $scale, 'changeScale(this);' ); ?></span>
|
||||
<span id="layoutControl"><label for="layout"><?php echo translate('Layout') ?>:</label><?php echo htmlSelect( 'layout', $layouts, $layout, 'selectLayout(this);' )?></span>
|
||||
</div>
|
||||
|
|
|
@ -116,7 +116,7 @@ if ( !empty($_REQUEST['group']) ) {
|
|||
// Note we round up just a bit on the end time as otherwise you get gaps, like 59.78 to 00 in the next second, which can give blank frames when moved through slowly.
|
||||
|
||||
$eventsSql = '
|
||||
SELECT E.Id,E.Name,E.StorageId,UNIX_TIMESTAMP(E.StartTime) AS StartTimeSecs,
|
||||
SELECT E.Id,E.Name,UNIX_TIMESTAMP(E.StartTime) AS StartTimeSecs,
|
||||
CASE WHEN E.EndTime IS NULL THEN (SELECT UNIX_TIMESTAMP(DATE_ADD(E.StartTime, Interval max(Delta)+0.5 Second)) FROM Frames F WHERE F.EventId=E.Id)
|
||||
ELSE UNIX_TIMESTAMP(E.EndTime)
|
||||
END AS CalcEndTimeSecs, E.Length,
|
||||
|
|
|
@ -34,8 +34,7 @@ require_once( $skinJsPhpFile );
|
|||
<script type="text/javascript" src="<?php echo $skinJsFile ?>"></script>
|
||||
<script type="text/javascript">
|
||||
<?php
|
||||
if ( !$debug )
|
||||
{
|
||||
if ( !$debug ) {
|
||||
?>
|
||||
closeWindow();
|
||||
<?php
|
||||
|
|
|
@ -40,6 +40,8 @@ function execONVIF( $cmd ) {
|
|||
$html_output<br/><br/>
|
||||
Please the following command from a command line for more information:<br/><br/>$shell_command"
|
||||
);
|
||||
} else {
|
||||
Logger::Debug( "Results from probe: " . implode( '<br/>', $output ) );
|
||||
}
|
||||
|
||||
return $output;
|
||||
|
@ -47,7 +49,6 @@ function execONVIF( $cmd ) {
|
|||
|
||||
function probeCameras( $localIp ) {
|
||||
$cameras = array();
|
||||
$count = 0;
|
||||
if ( $lines = @execONVIF( 'probe' ) ) {
|
||||
foreach ( $lines as $line ) {
|
||||
$line = rtrim( $line );
|
||||
|
@ -55,43 +56,43 @@ function probeCameras( $localIp ) {
|
|||
$device_ep = $matches[1];
|
||||
$soapversion = $matches[2];
|
||||
$camera = array(
|
||||
'model' => "Unknown ONVIF Camera",
|
||||
'model' => 'Unknown ONVIF Camera',
|
||||
'monitor' => array(
|
||||
'Function' => "Monitor",
|
||||
'Function' => 'Monitor',
|
||||
'Type' => 'Ffmpeg',
|
||||
'Host' => $device_ep,
|
||||
'SOAP' => $soapversion,
|
||||
),
|
||||
);
|
||||
foreach ( preg_split('|,\s*|', $matches[3]) as $attr_val ) {
|
||||
if( preg_match( '|(.+)=\'(.*)\'|', $attr_val, $tokens ) ) {
|
||||
if($tokens[1] == "hardware") {
|
||||
if ( preg_match( '|(.+)=\'(.*)\'|', $attr_val, $tokens ) ) {
|
||||
if ( $tokens[1] == 'hardware' ) {
|
||||
$camera['model'] = $tokens[2];
|
||||
} elseif($tokens[1] == "name") {
|
||||
} elseif ( $tokens[1] == 'name' ) {
|
||||
$camera['monitor']['Name'] = $tokens[2];
|
||||
} elseif($tokens[1] == "location") {
|
||||
// $camera['location'] = $tokens[2];
|
||||
}
|
||||
|
||||
} elseif ( $tokens[1] == 'location' ) {
|
||||
// $camera['location'] = $tokens[2];
|
||||
} else {
|
||||
Logger::Debug('Unknown token ' . $tokens[1] );
|
||||
}
|
||||
}
|
||||
$cameras[$count ++] = $camera;
|
||||
}
|
||||
} // end foreach token
|
||||
$cameras[] = $camera;
|
||||
}
|
||||
} // end foreach line
|
||||
}
|
||||
return( $cameras );
|
||||
}
|
||||
|
||||
function probeProfiles( $device_ep, $soapversion, $username, $password ) {
|
||||
$profiles = array();
|
||||
$count = 0;
|
||||
if ( $lines = @execONVIF( "profiles $device_ep $soapversion $username $password" ) ) {
|
||||
foreach ( $lines as $line ) {
|
||||
$line = rtrim( $line );
|
||||
if ( preg_match( '|^(.+),\s*(.+),\s*(.+),\s*(.+),\s*(.+),\s*(.+),\s*(.+)\s*$|', $line, $matches ) ) {
|
||||
$stream_uri = $matches[7];
|
||||
// add user@pass to URI
|
||||
if( preg_match( '|^(\S+://)(.+)$|', $stream_uri, $tokens ) ) {
|
||||
if ( preg_match( '|^(\S+://)(.+)$|', $stream_uri, $tokens ) ) {
|
||||
$stream_uri = $tokens[1].$username.':'.$password.'@'.$tokens[2];
|
||||
}
|
||||
|
||||
|
@ -107,7 +108,9 @@ function probeProfiles( $device_ep, $soapversion, $username, $password ) {
|
|||
'Encoding' => $matches[3],
|
||||
|
||||
);
|
||||
$profiles[$count ++] = $profile;
|
||||
$profiles[] = $profile;
|
||||
} else {
|
||||
Logger::Debug("Line did not match preg: $line");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
//
|
||||
|
||||
if ( !canEdit( 'System' ) ) {
|
||||
$view = "error";
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
?>
|
||||
|
@ -40,18 +40,24 @@ if ( !canEdit( 'System' ) ) {
|
|||
<label for="runState" class="col-sm-3 control-label">Change State</label>
|
||||
<div class="col-sm-9">
|
||||
<select id="runState" name="runState" class="form-control">
|
||||
<?php if ( daemonCheck() ) { ?>
|
||||
<?php
|
||||
if ( $running ) {
|
||||
?>
|
||||
<option value="stop" selected="selected"><?php echo translate('Stop') ?></option>
|
||||
<option value="restart"><?php echo translate('Restart') ?></option>
|
||||
<?php } else { ?>
|
||||
<option value="start" selected="selected"><?php echo translate('Start') ?></option>
|
||||
<?php }
|
||||
?>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<option value="start" selected="selected"><?php echo translate('Start') ?></option>
|
||||
<?php
|
||||
}
|
||||
$states = dbFetchAll( 'SELECT * FROM States' );
|
||||
foreach ( $states as $state ) { ?>
|
||||
foreach ( $states as $state ) {
|
||||
?>
|
||||
<option value="<?php echo $state['Name'] ?>"><?php echo $state['Name'] ?></option>
|
||||
<?php } ?>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div><!--col-sm-9-->
|
||||
</div><!--form-group-->
|
||||
|
|
|
@ -37,16 +37,16 @@ define( 'STRF_TL_AXIS_RANGE_YEAR1', '%b %Y' );
|
|||
define( 'STRF_TL_AXIS_RANGE_YEAR2', STRF_TL_AXIS_RANGE_YEAR1 );
|
||||
|
||||
// When the chart range is months
|
||||
define( "STRF_TL_AXIS_RANGE_MONTH1", "%b" );
|
||||
define( "STRF_TL_AXIS_RANGE_MONTH2", STRF_TL_AXIS_RANGE_MONTH1." %Y" );
|
||||
define( 'STRF_TL_AXIS_RANGE_MONTH1', '%b' );
|
||||
define( 'STRF_TL_AXIS_RANGE_MONTH2', STRF_TL_AXIS_RANGE_MONTH1.' %Y' );
|
||||
|
||||
// When the chart range is days
|
||||
define( "STRF_TL_AXIS_RANGE_DAY1", "%d" );
|
||||
define( "STRF_TL_AXIS_RANGE_DAY2", STRF_TL_AXIS_RANGE_DAY1." %b %Y" );
|
||||
define( 'STRF_TL_AXIS_RANGE_DAY1', '%d' );
|
||||
define( 'STRF_TL_AXIS_RANGE_DAY2', STRF_TL_AXIS_RANGE_DAY1.' %b %Y' );
|
||||
|
||||
// When the chart range is less than a day
|
||||
define( "STRF_TL_AXIS_RANGE_TIME1", "%H:%M" );
|
||||
define( "STRF_TL_AXIS_RANGE_TIME2", STRF_TL_AXIS_RANGE_TIME1.", %d %b %Y" );
|
||||
define( 'STRF_TL_AXIS_RANGE_TIME1', '%H:%M' );
|
||||
define( 'STRF_TL_AXIS_RANGE_TIME2', STRF_TL_AXIS_RANGE_TIME1.', %d %b %Y' );
|
||||
|
||||
//
|
||||
// These are the time axis tick labels
|
||||
|
@ -74,56 +74,56 @@ $minEventWidth = 3;
|
|||
$maxEventWidth = 6;
|
||||
|
||||
$chart = array(
|
||||
"width"=>700,
|
||||
"height"=>460,
|
||||
"image" => array(
|
||||
"width"=>264,
|
||||
"height"=>220,
|
||||
"topOffset"=>20,
|
||||
'width'=>700,
|
||||
'height'=>460,
|
||||
'image' => array(
|
||||
'width'=>264,
|
||||
'height'=>220,
|
||||
'topOffset'=>20,
|
||||
),
|
||||
"imageText" => array(
|
||||
"width"=>400,
|
||||
"height"=>30,
|
||||
"topOffset"=>20,
|
||||
'imageText' => array(
|
||||
'width'=>400,
|
||||
'height'=>30,
|
||||
'topOffset'=>20,
|
||||
),
|
||||
"graph" => array(
|
||||
"width"=>600,
|
||||
"height"=>160,
|
||||
"topOffset"=>30,
|
||||
'graph' => array(
|
||||
'width'=>600,
|
||||
'height'=>160,
|
||||
'topOffset'=>30,
|
||||
),
|
||||
"title" => array(
|
||||
"topOffset"=>50
|
||||
'title' => array(
|
||||
'topOffset'=>50
|
||||
),
|
||||
"key" => array(
|
||||
"topOffset"=>50
|
||||
'key' => array(
|
||||
'topOffset'=>50
|
||||
),
|
||||
"axes" => array(
|
||||
"x" => array(
|
||||
"height" => 20,
|
||||
'axes' => array(
|
||||
'x' => array(
|
||||
'height' => 20,
|
||||
),
|
||||
"y" => array(
|
||||
"width" => 30,
|
||||
'y' => array(
|
||||
'width' => 30,
|
||||
),
|
||||
),
|
||||
"grid" => array(
|
||||
"x" => array(
|
||||
"major" => array(
|
||||
"max" => 12,
|
||||
"min" => 4,
|
||||
'grid' => array(
|
||||
'x' => array(
|
||||
'major' => array(
|
||||
'max' => 12,
|
||||
'min' => 4,
|
||||
),
|
||||
"minor" => array(
|
||||
"max" => 48,
|
||||
"min" => 12,
|
||||
'minor' => array(
|
||||
'max' => 48,
|
||||
'min' => 12,
|
||||
),
|
||||
),
|
||||
"y" => array(
|
||||
"major" => array(
|
||||
"max" => 8,
|
||||
"min" => 1,
|
||||
'y' => array(
|
||||
'major' => array(
|
||||
'max' => 8,
|
||||
'min' => 1,
|
||||
),
|
||||
"minor" => array(
|
||||
"max" => 0,
|
||||
"min" => 0,
|
||||
'minor' => array(
|
||||
'max' => 0,
|
||||
'min' => 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -152,7 +152,7 @@ if ( !empty($user['MonitorIds']) ) {
|
|||
}
|
||||
|
||||
if ( isset($_REQUEST['filter']) )
|
||||
$tree = parseFilterToTree( $_REQUEST['filter'] );
|
||||
$tree = parseFilterToTree( $_REQUEST['filter']['Query'] );
|
||||
else
|
||||
$tree = false;
|
||||
|
||||
|
@ -253,16 +253,16 @@ if ( $tree ) {
|
|||
}
|
||||
|
||||
$scales = array(
|
||||
array( "name"=>"year", "factor"=>60*60*24*365, "align"=>1, "zoomout"=>2, "label"=>STRF_TL_AXIS_LABEL_YEAR ),
|
||||
array( "name"=>"month", "factor"=>60*60*24*30, "align"=>1, "zoomout"=>12, "label"=>STRF_TL_AXIS_LABEL_MONTH ),
|
||||
array( "name"=>"week", "factor"=>60*60*24*7, "align"=>1, "zoomout"=>4.25, "label"=>STRF_TL_AXIS_LABEL_WEEK, "labelCheck"=>"%W" ),
|
||||
array( "name"=>"day", "factor"=>60*60*24, "align"=>1, "zoomout"=>7, "label"=>STRF_TL_AXIS_LABEL_DAY ),
|
||||
array( "name"=>"hour4", "factor"=>60*60, "align"=>4, "zoomout"=>6, "label"=>STRF_TL_AXIS_LABEL_4HOUR, "labelCheck"=>"%H" ),
|
||||
array( "name"=>"hour", "factor"=>60*60, "align"=>1, "zoomout"=>4, "label"=>STRF_TL_AXIS_LABEL_HOUR, "labelCheck"=>"%H" ),
|
||||
array( "name"=>"minute10", "factor"=>60, "align"=>10, "zoomout"=>6, "label"=>STRF_TL_AXIS_LABEL_10MINUTE, "labelCheck"=>"%M" ),
|
||||
array( "name"=>"minute", "factor"=>60, "align"=>1, "zoomout"=>10, "label"=>STRF_TL_AXIS_LABEL_MINUTE, "labelCheck"=>"%M" ),
|
||||
array( "name"=>"second10", "factor"=>1, "align"=>10, "zoomout"=>6, "label"=>STRF_TL_AXIS_LABEL_10SECOND ),
|
||||
array( "name"=>"second", "factor"=>1, "align"=>1, "zoomout"=>10, "label"=>STRF_TL_AXIS_LABEL_SECOND ),
|
||||
array( 'name'=>"year", 'factor'=>60*60*24*365, 'align'=>1, 'zoomout'=>2, 'label'=>STRF_TL_AXIS_LABEL_YEAR ),
|
||||
array( 'name'=>"month", 'factor'=>60*60*24*30, 'align'=>1, 'zoomout'=>12, 'label'=>STRF_TL_AXIS_LABEL_MONTH ),
|
||||
array( 'name'=>"week", 'factor'=>60*60*24*7, 'align'=>1, 'zoomout'=>4.25, 'label'=>STRF_TL_AXIS_LABEL_WEEK, 'labelCheck'=>"%W" ),
|
||||
array( 'name'=>"day", 'factor'=>60*60*24, 'align'=>1, 'zoomout'=>7, 'label'=>STRF_TL_AXIS_LABEL_DAY ),
|
||||
array( 'name'=>"hour4", 'factor'=>60*60, 'align'=>4, 'zoomout'=>6, 'label'=>STRF_TL_AXIS_LABEL_4HOUR, 'labelCheck'=>"%H" ),
|
||||
array( 'name'=>"hour", 'factor'=>60*60, 'align'=>1, 'zoomout'=>4, 'label'=>STRF_TL_AXIS_LABEL_HOUR, 'labelCheck'=>"%H" ),
|
||||
array( 'name'=>"minute10", 'factor'=>60, 'align'=>10, 'zoomout'=>6, 'label'=>STRF_TL_AXIS_LABEL_10MINUTE, 'labelCheck'=>"%M" ),
|
||||
array( 'name'=>"minute", 'factor'=>60, 'align'=>1, 'zoomout'=>10, 'label'=>STRF_TL_AXIS_LABEL_MINUTE, 'labelCheck'=>"%M" ),
|
||||
array( 'name'=>"second10", 'factor'=>1, 'align'=>10, 'zoomout'=>6, 'label'=>STRF_TL_AXIS_LABEL_10SECOND ),
|
||||
array( 'name'=>"second", 'factor'=>1, 'align'=>1, 'zoomout'=>10, 'label'=>STRF_TL_AXIS_LABEL_SECOND ),
|
||||
);
|
||||
|
||||
$majXScale = getDateScale( $scales, $range, $chart['grid']['x']['major']['min'], $chart['grid']['x']['major']['max'] );
|
||||
|
@ -291,17 +291,17 @@ if ( isset($minTime) && isset($maxTime) ) {
|
|||
$eventsSql .= " and EndTime >= '$minTime' and StartTime <= '$maxTime'";
|
||||
}
|
||||
|
||||
$eventsSql .= " order by Id asc";
|
||||
$eventsSql .= ' order by Id asc';
|
||||
//echo "ESQL: $eventsSql<br>";
|
||||
|
||||
$chart['data'] = array(
|
||||
"x" => array(
|
||||
"lo" => strtotime( $minTime ),
|
||||
"hi" => strtotime( $maxTime ),
|
||||
'x' => array(
|
||||
'lo' => strtotime( $minTime ),
|
||||
'hi' => strtotime( $maxTime ),
|
||||
),
|
||||
"y" => array(
|
||||
"lo" => 0,
|
||||
"hi" => 0,
|
||||
'y' => array(
|
||||
'lo' => 0,
|
||||
'hi' => 0,
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -311,7 +311,16 @@ $chart['data']['x']['density'] = $chart['data']['x']['range']/$chart['graph']['w
|
|||
$monEventSlots = array();
|
||||
$monFrameSlots = array();
|
||||
$monitorIds = array();
|
||||
foreach( dbFetchAll( $eventsSql ) as $event ) {
|
||||
$events_result = dbQuery( $eventsSql );
|
||||
if ( ! $events_result ) {
|
||||
Fatal( "SQL-ERR");
|
||||
return;
|
||||
}
|
||||
|
||||
$first_event = $event = $events_result->fetch( PDO::FETCH_ASSOC );
|
||||
if ( $event ) {
|
||||
do {
|
||||
|
||||
if ( !isset($monitorIds[$event['MonitorId']]) )
|
||||
$monitorIds[$event['MonitorId']] = true;
|
||||
|
||||
|
@ -345,7 +354,7 @@ foreach( dbFetchAll( $eventsSql ) as $event ) {
|
|||
} else {
|
||||
$offset = 1 + ($event['Frames']?((int)(($event['Frames']-1)*(($i-$rawStartIndex)/($rawEndIndex-$rawStartIndex)))):0);
|
||||
}
|
||||
$currEventSlots[$i] = array( "count"=>0, "width"=>1, "offset"=>$offset, "event"=>$event );
|
||||
$currEventSlots[$i] = array( 'count'=>0, 'width'=>1, 'offset'=>$offset, 'event'=>$event );
|
||||
} else {
|
||||
$currEventSlots[$i]['count']++;
|
||||
}
|
||||
|
@ -399,7 +408,8 @@ foreach( dbFetchAll( $eventsSql ) as $event ) {
|
|||
} // end foreach frame
|
||||
}
|
||||
} // end if MaxScore > 0
|
||||
} // end foreach event
|
||||
} while( $event = $events_result->fetch( PDO::FETCH_ASSOC ) );
|
||||
} # end if have first event
|
||||
|
||||
ksort( $monitorIds, SORT_NUMERIC );
|
||||
ksort( $monEventSlots, SORT_NUMERIC );
|
||||
|
@ -702,15 +712,17 @@ xhtmlHeaders(__FILE__, translate('Timeline') );
|
|||
<div id="image" class="imageHeight">
|
||||
<img id="imageSrc" class="imageWidth" src="graphics/transparent.gif" alt="<?php echo translate('ViewEvent') ?>" title="<?php echo translate('ViewEvent') ?>"/>
|
||||
<?php
|
||||
if ( 0 ) {
|
||||
//due to chrome bug, has to enable https://code.google.com/p/chromium/issues/detail?id=472300
|
||||
//crossorigin has to be added below to make caption work in chrome
|
||||
?>
|
||||
<!--
|
||||
<video id="preview" width="100%" controls crossorigin="anonymous">
|
||||
<source src="<?php echo getEventDefaultVideoPath($event); ?>" type="video/mp4">
|
||||
<source src="<?php echo getEventDefaultVideoPath($first_event); ?>" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
o-->
|
||||
<?php } ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -807,16 +819,12 @@ foreach( array_keys($monEventSlots) as $monitorId ) {
|
|||
<?php
|
||||
unset( $currEventSlots );
|
||||
$currEventSlots = &$monEventSlots[$monitorId];
|
||||
$monitorMouseover = $mouseover;
|
||||
if ($monitors[$monitorId]['SaveJPEGs'] == 2) {
|
||||
$monitorMouseover = false;
|
||||
}
|
||||
for ( $i = 0; $i < $chart['graph']['width']; $i++ ) {
|
||||
if ( isset($currEventSlots[$i]) ) {
|
||||
unset( $slot );
|
||||
$slot = &$currEventSlots[$i];
|
||||
|
||||
if ( $monitorMouseover ) {
|
||||
if ( $mouseover ) {
|
||||
$behaviours = array(
|
||||
'onclick="'.getSlotShowEventBehaviour( $slot ).'"',
|
||||
'onmouseover="'.getSlotPreviewEventBehaviour( $slot ).'"'
|
||||
|
@ -854,6 +862,6 @@ foreach( array_keys($monEventSlots) as $monitorId ) {
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
|
||||
<script src="skins/<?php echo $skin ?>/js/moment.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Reference in New Issue