Merge branch 'master' of github.com:/ZoneMinder/ZoneMinder
This commit is contained in:
commit
9938346752
|
@ -42,7 +42,7 @@ This is the recommended method to install ZoneMinder onto your system. ZoneMinde
|
|||
|
||||
If a repository that hosts ZoneMinder packages is not available for your distro, then you are encouraged to build your own package, rather than build from source. While each distro is different in ways that set it apart from all the others, they are often similar enough to allow you to adapt another distro's package building instructions to your own.
|
||||
|
||||
### Building a ZoneMinder Package
|
||||
### Building a ZoneMinder Package ###
|
||||
|
||||
Building ZoneMinder into a package is not any harder than building from source. As a matter of fact, if you have successfully built ZoneMinder from source in the past, then you may find these steps to be easier.
|
||||
|
||||
|
@ -55,7 +55,7 @@ Please visit our [ReadtheDocs site](https://zoneminder.readthedocs.org/en/stable
|
|||
### Package Maintainers
|
||||
Many of the ZoneMinder configration variable default values are not configurable at build time through autotools or cmake. A new tool called *zmeditconfigdata.sh* has been added to allow package maintainers to manipulate any variable stored in ConfigData.pm without patching the source.
|
||||
|
||||
For example, let's say I have created a new ZoneMinder package that contains the cambolzola javascript file. However, by default cambozola support is turned off. To fix that, add this to the pacakging script:
|
||||
For example, let's say I have created a new ZoneMinder package that contains the cambozola javascript file. However, by default cambozola support is turned off. To fix that, add this to the pacakging script:
|
||||
```bash
|
||||
./utils/zmeditconfigdata.sh ZM_OPT_CAMBOZOLA yes
|
||||
```
|
||||
|
|
|
@ -781,6 +781,7 @@ INSERT INTO `Controls` VALUES (NULL,'D-LINK DCS-3415','Remote','DCS3415',0,0,0,1
|
|||
INSERT INTO `Controls` VALUES (NULL,'IOS Camera','Ffmpeg','IPCAMIOS',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,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,'Dericam P2','Ffmpeg','DericamP2',0,1,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,10,0,1,1,1,0,0,0,1,1,0,0,0,0,1,1,45,0,0,1,0,0,0,0,1,1,45,0,0,0,0);
|
||||
INSERT INTO `Controls` VALUES (NULL,'Trendnet','Remote','Trendnet',1,1,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,0,0,0,0,1,1,1,0,1,0,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,'PSIA','Remote','PSIA',0,0,0,1,0,0,1,0,0,0,0,0,0,0,100,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,0,1,1,1,0,0,1,0,1,0,0,0,0,1,-100,100,0,0,1,0,0,0,0,1,-100,100,0,0,0,0);
|
||||
INSERT INTO `Controls` VALUES (NULL,'Dahua','Remote','Dahua',0,0,0,1,0,0,1,0,0,0,0,0,0,0,8,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,0,1,1,1,0,0,1,0,1,0,0,0,0,1,1,8,0,0,1,0,0,0,0,1,1,8,0,0,0,0);
|
||||
|
||||
--
|
||||
|
@ -808,6 +809,7 @@ INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, unicast','Remote','rtsp
|
|||
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, multicast','Remote','rtsp',0,255,'rtsp','rtpMulti','<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP','Remote','rtsp',0,255,'rtsp','rtpRtsp','<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||
INSERT into MonitorPresets VALUES (NULL,'Axis IP, mpeg4, RTP/RTSP/HTTP','Remote',NULL,NULL,NULL,'rtsp','rtpRtspHttp','<ip-address>',554,'/mpeg4/media.amp','/trackID=',NULL,NULL,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||
INSERT INTO MonitorPresets VALUES (NULL,'D-link DCS-930L, 640x480, mjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/mjpeg.cgi',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, mpjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/nphMotionJpeg?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,NULL,0,NULL,NULL,NULL,100,100);
|
||||
INSERT INTO MonitorPresets VALUES (NULL,'Panasonic IP, 320x240, jpeg, max 5 FPS','Remote','http',0,0,'http','simple','<ip-address>',80,'/SnapshotJPEG?Resolution=320x240&Quality=Standard',NULL,320,240,3,5.0,0,NULL,NULL,NULL,100,100);
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
--
|
||||
-- This updates a 1.32.1 database to 1.32.2
|
||||
--
|
||||
-- No changes required
|
||||
--
|
|
@ -0,0 +1,9 @@
|
|||
--
|
||||
-- This updates a 1.32.2 database to 1.32.3
|
||||
--
|
||||
|
||||
--
|
||||
-- Add some additional monitor preset values
|
||||
--
|
||||
|
||||
INSERT INTO MonitorPresets VALUES (NULL,'D-link DCS-930L, 640x480, mjpeg','Remote','http',0,0,'http','simple','<ip-address>',80,'/mjpeg.cgi',NULL,640,480,3,NULL,0,NULL,NULL,NULL,100,100);
|
|
@ -25,7 +25,7 @@
|
|||
%global _hardened_build 1
|
||||
|
||||
Name: zoneminder
|
||||
Version: 1.32.1
|
||||
Version: 1.32.2
|
||||
Release: 1%{?dist}
|
||||
Summary: A camera monitoring and analysis tool
|
||||
Group: System Environment/Daemons
|
||||
|
@ -320,6 +320,13 @@ EOF
|
|||
%dir %attr(755,%{zmuid_final},%{zmgid_final}) %{_localstatedir}/run/zoneminder
|
||||
|
||||
%changelog
|
||||
* Sat Oct 13 2018 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.32.2-1
|
||||
- 1.32.2 release
|
||||
- Bug fix release
|
||||
|
||||
* Thu Oct 04 2018 Sérgio Basto <sergio@serjux.com> - 1.32.1-2
|
||||
- Mass rebuild for x264 and/or x265
|
||||
|
||||
* Tue Oct 2 2018 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.32.1-1
|
||||
- 1.32.1 release
|
||||
- Bug fix release
|
||||
|
|
|
@ -13,6 +13,13 @@ The API is built in CakePHP and lives under the ``/api`` directory. It
|
|||
provides a RESTful service and supports CRUD (create, retrieve, update, delete)
|
||||
functions for Monitors, Events, Frames, Zones and Config.
|
||||
|
||||
Enabling API
|
||||
^^^^^^^^^^^^
|
||||
A default ZoneMinder installs with APIs enabled. You can explictly enable/disable the APIs
|
||||
via the Options->System menu by enabling/disabling ``OPT_USE_API``. Note that if you intend
|
||||
to use APIs with 3rd party apps, such as zmNinja or others that use APIs, you should also
|
||||
enable ``AUTH_HASH_LOGINS``.
|
||||
|
||||
Login, Logout & API Security
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The APIs tie into ZoneMinder's existing security model. This means if you have
|
||||
|
|
|
@ -0,0 +1,365 @@
|
|||
package ZoneMinder::Control::PSIA;
|
||||
|
||||
use 5.006;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
require ZoneMinder::Base;
|
||||
require ZoneMinder::Control;
|
||||
|
||||
our @ISA = qw(ZoneMinder::Control);
|
||||
|
||||
our $REALM = 'TV-IP450PI';
|
||||
our $USERNAME = 'admin';
|
||||
our $PASSWORD = '';
|
||||
our $ADDRESS = '';
|
||||
our $PROTOCOL = 'http://';
|
||||
|
||||
use ZoneMinder::Logger qw(:all);
|
||||
use ZoneMinder::Config qw(:all);
|
||||
use ZoneMinder::Database qw(zmDbConnect);
|
||||
|
||||
sub open
|
||||
{
|
||||
my $self = shift;
|
||||
$self->loadMonitor();
|
||||
|
||||
if ( ( $self->{Monitor}->{ControlAddress} =~ /^(?<PROTOCOL>https?:\/\/)?(?<USERNAME>[^:@]+)?:?(?<PASSWORD>[^\/@]+)?@?(?<ADDRESS>.*)$/ ) ) {
|
||||
$PROTOCOL = $+{PROTOCOL} if $+{PROTOCOL};
|
||||
$USERNAME = $+{USERNAME} if $+{USERNAME};
|
||||
$PASSWORD = $+{PASSWORD} if $+{PASSWORD};
|
||||
$ADDRESS = $+{ADDRESS} if $+{ADDRESS};
|
||||
} else {
|
||||
Error('Failed to parse auth from address ' . $self->{Monitor}->{ControlAddress});
|
||||
$ADDRESS = $self->{Monitor}->{ControlAddress};
|
||||
}
|
||||
if ( !($ADDRESS =~ /:/) ) {
|
||||
Error('You generally need to also specify the port. I will append :80');
|
||||
$ADDRESS .= ':80';
|
||||
}
|
||||
|
||||
use LWP::UserAgent;
|
||||
$self->{ua} = LWP::UserAgent->new;
|
||||
$self->{ua}->agent( "ZoneMinder Control Agent/".$ZoneMinder::Base::ZM_VERSION );
|
||||
$self->{state} = 'closed';
|
||||
Debug( "sendCmd credentials control address:'".$ADDRESS
|
||||
."' realm:'" . $REALM
|
||||
. "' username:'" . $USERNAME
|
||||
. "' password:'".$PASSWORD
|
||||
."'"
|
||||
);
|
||||
$self->{ua}->credentials($ADDRESS, $REALM, $USERNAME, $PASSWORD);
|
||||
|
||||
# Detect REALM
|
||||
my $req = HTTP::Request->new(GET=>$PROTOCOL . $ADDRESS . "/PSIA/PTZ/channels");
|
||||
my $res = $self->{ua}->request($req);
|
||||
|
||||
if ($res->is_success) {
|
||||
$self->{state} = 'open';
|
||||
return;
|
||||
} elsif (! $res->is_success) {
|
||||
Debug("Need newer REALM");
|
||||
if ( $res->status_line() eq '401 Unauthorized' ) {
|
||||
my $headers = $res->headers();
|
||||
foreach my $k ( keys %$headers ) {
|
||||
Debug("Initial Header $k => $$headers{$k}");
|
||||
} # end foreach
|
||||
if ( $$headers{'www-authenticate'} ) {
|
||||
my ($auth, $tokens) = $$headers{'www-authenticate'} =~ /^(\w+)\s+(.*)$/;
|
||||
if ($tokens =~ /\w+="([^"]+)"/i) {
|
||||
$REALM = $1;
|
||||
Debug("Changing REALM to $REALM");
|
||||
$self->{ua}->credentials($ADDRESS, $REALM, $USERNAME, $PASSWORD);
|
||||
} # end if
|
||||
} else {
|
||||
Debug("No WWW-Authenticate header");
|
||||
} # end if www-authenticate header
|
||||
} # end if $res->status_line() eq '401 Unauthorized'
|
||||
} # end elsif ! $res->is_success
|
||||
}
|
||||
|
||||
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 sendGetRequest {
|
||||
my $self = shift;
|
||||
my $url_path = shift;
|
||||
|
||||
my $result = undef;
|
||||
|
||||
my $url = $PROTOCOL . $ADDRESS . $url_path;
|
||||
my $req = HTTP::Request->new(GET=>$url);
|
||||
|
||||
my $res = $self->{ua}->request($req);
|
||||
|
||||
if ($res->is_success) {
|
||||
$result = !undef;
|
||||
} else {
|
||||
if ( $res->status_line() eq '401 Unauthorized' ) {
|
||||
Error( "Error check failed, trying again: USERNAME: $USERNAME realm: $REALM password: " . $PASSWORD );
|
||||
Error("Content was " . $res->content() );
|
||||
my $res = $self->{ua}->request($req);
|
||||
if ( $res->is_success ) {
|
||||
$result = !undef;
|
||||
} else {
|
||||
Error("Content was " . $res->content() );
|
||||
}
|
||||
}
|
||||
if ( ! $result ) {
|
||||
Error("Error check failed: '".$res->status_line());
|
||||
}
|
||||
}
|
||||
return($result);
|
||||
}
|
||||
sub sendPutRequest {
|
||||
my $self = shift;
|
||||
my $url_path = shift;
|
||||
my $content = shift;
|
||||
|
||||
my $result = undef;
|
||||
|
||||
my $url = $PROTOCOL . $ADDRESS . $url_path;
|
||||
my $req = HTTP::Request->new(PUT=>$url);
|
||||
if(defined($content)) {
|
||||
$req->content_type("application/x-www-form-urlencoded; charset=UTF-8");
|
||||
$req->content('<?xml version="1.0" encoding="UTF-8"?>' . "\n" . $content);
|
||||
}
|
||||
|
||||
my $res = $self->{ua}->request($req);
|
||||
|
||||
if ($res->is_success) {
|
||||
$result = !undef;
|
||||
} else {
|
||||
if ( $res->status_line() eq '401 Unauthorized' ) {
|
||||
Error( "Error check failed, trying again: USERNAME: $USERNAME realm: $REALM password: " . $PASSWORD );
|
||||
Error("Content was " . $res->content() );
|
||||
my $res = $self->{ua}->request($req);
|
||||
if ( $res->is_success ) {
|
||||
$result = !undef;
|
||||
} else {
|
||||
Error("Content was " . $res->content() );
|
||||
}
|
||||
}
|
||||
if ( ! $result ) {
|
||||
Error( "Error check failed: '".$res->status_line()."' cmd:'".$cmd."'" );
|
||||
}
|
||||
}
|
||||
return($result);
|
||||
}
|
||||
sub sendDeleteRequest {
|
||||
my $self = shift;
|
||||
my $url_path = shift;
|
||||
|
||||
my $result = undef;
|
||||
|
||||
my $url = $PROTOCOL . $ADDRESS . $url_path;
|
||||
my $req = HTTP::Request->new(DELETE=>$url);
|
||||
my $res = $self->{ua}->request($req);
|
||||
if ($res->is_success) {
|
||||
$result = !undef;
|
||||
} else {
|
||||
if ( $res->status_line() eq '401 Unauthorized' ) {
|
||||
Error( "Error check failed, trying again: USERNAME: $USERNAME realm: $REALM password: " . $PASSWORD );
|
||||
Error("Content was " . $res->content() );
|
||||
my $res = $self->{ua}->request($req);
|
||||
if ( $res->is_success ) {
|
||||
$result = !undef;
|
||||
} else {
|
||||
Error("Content was " . $res->content() );
|
||||
}
|
||||
}
|
||||
if ( ! $result ) {
|
||||
Error( "Error check failed: '".$res->status_line()."' cmd:'".$cmd."'" );
|
||||
}
|
||||
}
|
||||
return($result);
|
||||
}
|
||||
|
||||
sub move
|
||||
{
|
||||
my $self = shift;
|
||||
my $panPercentage = shift;
|
||||
my $tiltPercentage = shift;
|
||||
my $zoomPercentage = shift;
|
||||
|
||||
my $cmd = "set_relative_pos&posX=$panSteps&posY=$tiltSteps";
|
||||
my $ptzdata = '<PTZData version="1.0" xmlns="urn:psialliance-org">';
|
||||
$ptzdata .= '<pan>' . $panPercentage . '</pan>';
|
||||
$ptzdata .= '<tilt>' . $tiltPercentage . '</tilt>';
|
||||
$ptzdata .= '<zoom>' . $zoomPercentage . '</zoom>';
|
||||
$ptzdata .= '<Momentary><duration>500</duration></Momentary>';
|
||||
$ptzdata .= '</PTZData>';
|
||||
$self->sendPutRequest("/PSIA/PTZ/channels/1/momentary", $ptzdata);
|
||||
}
|
||||
|
||||
sub moveRelUpLeft
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Up Left" );
|
||||
$self->move(-50, 50, 0);
|
||||
}
|
||||
|
||||
sub moveRelUp
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Up" );
|
||||
$self->move(0, 50, 0);
|
||||
}
|
||||
|
||||
sub moveRelUpRight
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Up Right" );
|
||||
$self->move(50, 50, 0);
|
||||
}
|
||||
|
||||
sub moveRelLeft
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Left" );
|
||||
$self->move(-50, 0, 0);
|
||||
}
|
||||
|
||||
sub moveRelRight
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Right" );
|
||||
$self->move(50, 0, 0);
|
||||
}
|
||||
|
||||
sub moveRelDownLeft
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Down Left" );
|
||||
$self->move(-50, -50, 0);
|
||||
}
|
||||
|
||||
sub moveRelDown
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Down" );
|
||||
$self->move(0, -50, 0);
|
||||
}
|
||||
|
||||
sub moveRelDownRight
|
||||
{
|
||||
my $self = shift;
|
||||
Debug( "Move Down Right" );
|
||||
$self->move(50, -50, 0);
|
||||
}
|
||||
|
||||
sub zoomRelTele
|
||||
{
|
||||
my $self = shift;
|
||||
Debug("Zoom Relative Tele");
|
||||
$self->move(0, 0, 50);
|
||||
}
|
||||
|
||||
sub zoomRelWide
|
||||
{
|
||||
my $self = shift;
|
||||
Debug("Zoom Relative Wide");
|
||||
$self->move(0, 0, -50);
|
||||
}
|
||||
|
||||
|
||||
sub presetClear
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $preset_id = $self->getParam($params, 'preset');
|
||||
my $url_path = "/PSIA/PTZ/channels/1/presets/" . $preset_id;
|
||||
$self->sendDeleteRequest($url_path);
|
||||
}
|
||||
|
||||
|
||||
sub presetSet
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
|
||||
my $preset_id = $self->getParam($params, 'preset');
|
||||
|
||||
my $dbh = zmDbConnect(1);
|
||||
my $sql = 'SELECT * FROM ControlPresets WHERE MonitorId = ? AND Preset = ?';
|
||||
my $sth = $dbh->prepare($sql)
|
||||
or Fatal("Can't prepare sql '$sql': " . $dbh->errstr());
|
||||
my $res = $sth->execute($self->{Monitor}->{Id}, $preset_id)
|
||||
or Fatal("Can't execute sql '$sql': " . $sth->errstr());
|
||||
my $control_preset_row = $sth->fetchrow_hashref();
|
||||
my $new_label_name = $control_preset_row->{'Label'};
|
||||
|
||||
my $url_path = "/PSIA/PTZ/channels/1/presets/" . $preset_id;
|
||||
my $ptz_preset_data = '<PTZPreset>';
|
||||
$ptz_preset_data .= '<id>' . $preset_id . '</id>';
|
||||
$ptz_preset_data .= '<presetName>' . $new_label_name . '</presetName>';
|
||||
$ptz_preset_data .= '</PTZPreset>';
|
||||
$self->sendPutRequest($url_path, $ptz_preset_data);
|
||||
}
|
||||
|
||||
sub presetGoto
|
||||
{
|
||||
my $self = shift;
|
||||
my $params = shift;
|
||||
my $preset_id = $self->getParam($params, 'preset');
|
||||
|
||||
my $url_path = '/PSIA/PTZ/channels/1/presets/' . $preset_id . '/goto';
|
||||
|
||||
$self->sendPutRequest($url_path);
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
ZoneMinder::Control::PSIA - Perl module for cameras implementing the PSIA
|
||||
(Physical Security Interoperability Alliance), IP Media Devices API
|
||||
specification
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use ZoneMinder::Control::PSIA;
|
||||
place this in /usr/share/perl5/ZoneMinder/Control
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This has so far been tested with:
|
||||
- Trendnet TV-IP450PI
|
||||
|
||||
=head2 EXPORT
|
||||
|
||||
None by default.
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 2018 ZoneMinder LLC
|
||||
|
||||
This library 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 library 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.
|
||||
|
||||
=cut
|
|
@ -704,6 +704,8 @@ sub Fatal( @ ) {
|
|||
if ( $SIG{TERM} and ( $SIG{TERM} ne 'DEFAULT' ) ) {
|
||||
$SIG{TERM}();
|
||||
}
|
||||
# I think if we don't disconnect we will leave sockets around in TIME_WAIT
|
||||
zmDbDisconnect();
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ use Time::HiRes qw/gettimeofday/;
|
|||
use Getopt::Long;
|
||||
use autouse 'Pod::Usage'=>qw(pod2usage);
|
||||
use autouse 'Data::Dumper'=>qw(Dumper);
|
||||
use File::Path qw(make_path);
|
||||
|
||||
my $daemon = 0;
|
||||
my $filter_name = '';
|
||||
|
@ -162,7 +163,7 @@ my $delay = $Config{ZM_FILTER_EXECUTE_INTERVAL};
|
|||
my $event_id = 0;
|
||||
|
||||
if ( ! EVENT_PATH ) {
|
||||
Error("No event path defined. Config was $Config{ZM_DIR_EVENTS}\n");
|
||||
Error("No event path defined. Config was $Config{ZM_DIR_EVENTS}");
|
||||
die;
|
||||
}
|
||||
|
||||
|
@ -173,11 +174,11 @@ chdir( EVENT_PATH );
|
|||
my $dbh = zmDbConnect();
|
||||
|
||||
if ( $filter_name ) {
|
||||
Info("Scanning for events using filter '$filter_name'\n");
|
||||
Info("Scanning for events using filter '$filter_name'");
|
||||
} elsif ( $filter_id ) {
|
||||
Info("Scanning for events using filter id '$filter_id'\n");
|
||||
Info("Scanning for events using filter id '$filter_id'");
|
||||
} else {
|
||||
Info("Scanning for events using all filters\n");
|
||||
Info("Scanning for events using all filters");
|
||||
}
|
||||
|
||||
if ( ! ( $filter_name or $filter_id ) ) {
|
||||
|
@ -191,7 +192,7 @@ my $last_action = 0;
|
|||
while( !$zm_terminate ) {
|
||||
my $now = time;
|
||||
if ( ($now - $last_action) > $Config{ZM_FILTER_RELOAD_DELAY} ) {
|
||||
Debug("Reloading filters\n");
|
||||
Debug("Reloading filters");
|
||||
$last_action = $now;
|
||||
@filters = getFilters({ Name=>$filter_name, Id=>$filter_id });
|
||||
}
|
||||
|
@ -211,7 +212,7 @@ while( !$zm_terminate ) {
|
|||
|
||||
last if (!$daemon and ($filter_name or $filter_id)) or $zm_terminate;
|
||||
|
||||
Debug("Sleeping for $delay seconds\n");
|
||||
Debug("Sleeping for $delay seconds");
|
||||
sleep($delay);
|
||||
}
|
||||
|
||||
|
@ -292,48 +293,48 @@ sub checkFilter {
|
|||
last if $zm_terminate;
|
||||
my $Event = new ZoneMinder::Event($$event{Id}, $event);
|
||||
|
||||
Debug("Checking event $event->{Id}");
|
||||
Debug("Checking event $Event->{Id}");
|
||||
my $delete_ok = !undef;
|
||||
$dbh->ping();
|
||||
if ( $filter->{AutoArchive} ) {
|
||||
Info("Archiving event $event->{Id}");
|
||||
Info("Archiving event $Event->{Id}");
|
||||
# Do it individually to avoid locking up the table for new events
|
||||
my $sql = 'UPDATE Events SET Archived = 1 WHERE Id = ?';
|
||||
my $sth = $dbh->prepare_cached( $sql )
|
||||
or Fatal("Unable to prepare '$sql': ".$dbh->errstr());
|
||||
my $res = $sth->execute( $event->{Id} )
|
||||
my $res = $sth->execute( $Event->{Id} )
|
||||
or Error("Unable to execute '$sql': ".$dbh->errstr());
|
||||
}
|
||||
if ( $Config{ZM_OPT_FFMPEG} && $filter->{AutoVideo} ) {
|
||||
if ( !$event->{Videoed} ) {
|
||||
$delete_ok = undef if !generateVideo($filter, $event);
|
||||
if ( !$Event->{Videoed} ) {
|
||||
$delete_ok = undef if !generateVideo($filter, $Event);
|
||||
}
|
||||
}
|
||||
if ( $Config{ZM_OPT_EMAIL} && $filter->{AutoEmail} ) {
|
||||
if ( !$event->{Emailed} ) {
|
||||
if ( !$Event->{Emailed} ) {
|
||||
$delete_ok = undef if !sendEmail($filter, $Event);
|
||||
}
|
||||
}
|
||||
if ( $Config{ZM_OPT_MESSAGE} && $filter->{AutoMessage} ) {
|
||||
if ( !$event->{Messaged} ) {
|
||||
if ( !$Event->{Messaged} ) {
|
||||
$delete_ok = undef if !sendMessage($filter, $Event);
|
||||
}
|
||||
}
|
||||
if ( $Config{ZM_OPT_UPLOAD} && $filter->{AutoUpload} ) {
|
||||
if ( !$event->{Uploaded} ) {
|
||||
if ( !$Event->{Uploaded} ) {
|
||||
$delete_ok = undef if !uploadArchFile($filter, $Event);
|
||||
}
|
||||
}
|
||||
if ( $filter->{AutoExecute} ) {
|
||||
if ( !$event->{Executed} ) {
|
||||
$delete_ok = undef if !executeCommand($filter, $event);
|
||||
if ( !$Event->{Executed} ) {
|
||||
$delete_ok = undef if !executeCommand($filter, $Event);
|
||||
}
|
||||
}
|
||||
if ( $filter->{AutoDelete} ) {
|
||||
if ( $delete_ok ) {
|
||||
$Event->delete();
|
||||
} else {
|
||||
Error("Unable toto delete event $event->{Id} as previous operations failed");
|
||||
Error("Unable to delete event $Event->{Id} as previous operations failed");
|
||||
}
|
||||
} # end if AutoDelete
|
||||
|
||||
|
@ -364,11 +365,11 @@ sub checkFilter {
|
|||
|
||||
sub generateVideo {
|
||||
my $filter = shift;
|
||||
my $event = shift;
|
||||
my $Event = shift;
|
||||
my $phone = shift;
|
||||
|
||||
my $rate = $event->{DefaultRate}/100;
|
||||
my $scale = $event->{DefaultScale}/100;
|
||||
my $rate = $Event->{DefaultRate}/100;
|
||||
my $scale = $Event->{DefaultScale}/100;
|
||||
my $format;
|
||||
|
||||
my @ffmpeg_formats = split(/\s+/, $Config{ZM_FFMPEG_FORMATS});
|
||||
|
@ -393,7 +394,7 @@ sub generateVideo {
|
|||
my $command = join('',
|
||||
$Config{ZM_PATH_BIN},
|
||||
'/zmvideo.pl -e ',
|
||||
$event->{Id},
|
||||
$Event->{Id},
|
||||
' -r ',
|
||||
$rate,
|
||||
' -s ',
|
||||
|
@ -405,10 +406,10 @@ sub generateVideo {
|
|||
chomp($output);
|
||||
my $status = $? >> 8;
|
||||
if ( $status || logDebugging() ) {
|
||||
Debug("Output: $output\n");
|
||||
Debug("Output: $output");
|
||||
}
|
||||
if ( $status ) {
|
||||
Error("Video generation '$command' failed with status: $status\n");
|
||||
Error("Video generation '$command' failed with status: $status");
|
||||
if ( wantarray() ) {
|
||||
return( undef, undef );
|
||||
}
|
||||
|
@ -417,8 +418,8 @@ sub generateVideo {
|
|||
my $sql = 'UPDATE Events SET Videoed = 1 WHERE Id = ?';
|
||||
my $sth = $dbh->prepare_cached($sql)
|
||||
or Fatal("Unable to prepare '$sql': ".$dbh->errstr());
|
||||
my $res = $sth->execute($event->{Id})
|
||||
or Fatal("Unable toexecute '$sql': ".$dbh->errstr());
|
||||
my $res = $sth->execute($Event->{Id})
|
||||
or Fatal("Unable to execute '$sql': ".$dbh->errstr());
|
||||
if ( wantarray() ) {
|
||||
return( $format, $output );
|
||||
}
|
||||
|
@ -453,7 +454,7 @@ sub generateImage {
|
|||
chomp( $output );
|
||||
my $status = $? >> 8;
|
||||
if ( $status || logDebugging() ) {
|
||||
Debug("Output: $output\n");
|
||||
Debug("Output: $output");
|
||||
}
|
||||
if ( $status ) {
|
||||
Error("Failed $command status $status");
|
||||
|
@ -467,22 +468,30 @@ sub generateImage {
|
|||
|
||||
sub uploadArchFile {
|
||||
my $filter = shift;
|
||||
my $event = shift;
|
||||
my $Event = shift;
|
||||
|
||||
if ( ! $Config{ZM_UPLOAD_HOST} ) {
|
||||
Error('Cannot upload archive as no upload host defined');
|
||||
return( 0 );
|
||||
}
|
||||
|
||||
my $archFile = $event->{MonitorName}.'-'.$event->{Id};
|
||||
my $archImagePath = $event->Path()
|
||||
# Try to make the path to the upload folder if it doesn't already exist
|
||||
make_path( $Config{ZM_UPLOAD_LOC_DIR} );
|
||||
|
||||
# Complain if the upload folder is still not writable
|
||||
if ( ! -w $Config{ZM_UPLOAD_LOC_DIR} ) {
|
||||
Error("Upload folder either does not exist or is not writable: $Config{ZM_UPLOAD_LOC_DIR}");
|
||||
return(0);
|
||||
}
|
||||
|
||||
my $archFile = $Event->{MonitorName}.'-'.$Event->{Id};
|
||||
my $archImagePath = $Event->Path()
|
||||
.'/'
|
||||
.(
|
||||
( $Config{ZM_UPLOAD_ARCH_ANALYSE} )
|
||||
? '{*analyse,*capture}'
|
||||
: '*capture'
|
||||
? '{*analyse.jpg,*capture.jpg,snapshot.jpg,*.mp4}'
|
||||
: '{*capture.jpg,snapshot.jpg,*.mp4}'
|
||||
)
|
||||
.'.jpg'
|
||||
;
|
||||
my @archImageFiles = glob($archImagePath);
|
||||
my $archLocPath;
|
||||
|
@ -492,11 +501,11 @@ sub uploadArchFile {
|
|||
$archFile .= '.zip';
|
||||
$archLocPath = $Config{ZM_UPLOAD_LOC_DIR}.'/'.$archFile;
|
||||
my $zip = Archive::Zip->new();
|
||||
Info("Creating upload file '$archLocPath', ".int(@archImageFiles)." files\n");
|
||||
Info("Creating upload file '$archLocPath', ".int(@archImageFiles).' files');
|
||||
|
||||
my $status = &AZ_OK;
|
||||
foreach my $imageFile ( @archImageFiles ) {
|
||||
Debug("Adding $imageFile\n");
|
||||
Debug("Adding $imageFile");
|
||||
my $member = $zip->addFile($imageFile);
|
||||
if ( !$member ) {
|
||||
Error("Unable toto add image file $imageFile to zip archive $archLocPath");
|
||||
|
@ -524,7 +533,7 @@ sub uploadArchFile {
|
|||
$archFile .= '.tar';
|
||||
}
|
||||
$archLocPath = $Config{ZM_UPLOAD_LOC_DIR}.'/'.$archFile;
|
||||
Info("Creating upload file '$archLocPath', ".int(@archImageFiles)." files\n");
|
||||
Info("Creating upload file '$archLocPath', ".int(@archImageFiles).' files');
|
||||
|
||||
if ( $archError = !Archive::Tar->create_archive(
|
||||
$archLocPath,
|
||||
|
@ -540,7 +549,7 @@ sub uploadArchFile {
|
|||
return( 0 );
|
||||
} else {
|
||||
if ( $Config{ZM_UPLOAD_PROTOCOL} eq 'ftp' ) {
|
||||
Info('Uploading to '.$Config{ZM_UPLOAD_HOST}." using FTP");
|
||||
Info('Uploading to '.$Config{ZM_UPLOAD_HOST}.' using FTP');
|
||||
my $ftp = Net::FTP->new(
|
||||
$Config{ZM_UPLOAD_HOST},
|
||||
Timeout=>$Config{ZM_UPLOAD_TIMEOUT},
|
||||
|
@ -548,24 +557,24 @@ sub uploadArchFile {
|
|||
Debug=>$Config{ZM_UPLOAD_DEBUG}
|
||||
);
|
||||
if ( !$ftp ) {
|
||||
Error("Unable tocreate FTP connection: $@");
|
||||
Error("Unable to create FTP connection: $@");
|
||||
return 0;
|
||||
}
|
||||
$ftp->login($Config{ZM_UPLOAD_USER}, $Config{ZM_UPLOAD_PASS})
|
||||
or Error("FTP - Unable tologin");
|
||||
or Error("FTP - Unable to login");
|
||||
$ftp->binary()
|
||||
or Error("FTP - Unable togo binary");
|
||||
or Error("FTP - Unable to go binary");
|
||||
$ftp->cwd($Config{ZM_UPLOAD_REM_DIR})
|
||||
or Error("FTP - Unable tocwd")
|
||||
or Error("FTP - Unable to cwd")
|
||||
if ( $Config{ZM_UPLOAD_REM_DIR} );
|
||||
$ftp->put( $archLocPath )
|
||||
or Error("FTP - Unable toupload '$archLocPath'");
|
||||
or Error("FTP - Unable to upload '$archLocPath'");
|
||||
$ftp->quit()
|
||||
or Error("FTP - Unable toquit");
|
||||
or Error("FTP - Unable to quit");
|
||||
} else {
|
||||
my $host = $Config{ZM_UPLOAD_HOST};
|
||||
$host .= ':'.$Config{ZM_UPLOAD_PORT} if $Config{ZM_UPLOAD_PORT};
|
||||
Info('Uploading to '.$host." using SFTP\n");
|
||||
Info('Uploading to '.$host.' using SFTP');
|
||||
my %sftpOptions = (
|
||||
host=>$Config{ZM_UPLOAD_HOST}, user=>$Config{ZM_UPLOAD_USER}
|
||||
($Config{ZM_UPLOAD_PASS} ? (password=>$Config{ZM_UPLOAD_PASS}) : ()),
|
||||
|
@ -580,7 +589,7 @@ sub uploadArchFile {
|
|||
$sftpOptions{more} = [@more_ssh_args];
|
||||
my $sftp = Net::SFTP::Foreign->new($Config{ZM_UPLOAD_HOST}, %sftpOptions);
|
||||
if ( $sftp->error ) {
|
||||
Error("Unable tocreate SFTP connection: ".$sftp->error);
|
||||
Error("Unable to create SFTP connection: ".$sftp->error);
|
||||
return 0;
|
||||
}
|
||||
$sftp->setcwd($Config{ZM_UPLOAD_REM_DIR})
|
||||
|
@ -592,9 +601,9 @@ sub uploadArchFile {
|
|||
unlink($archLocPath);
|
||||
my $sql = 'UPDATE Events SET Uploaded = 1 WHERE Id = ?';
|
||||
my $sth = $dbh->prepare_cached($sql)
|
||||
or Fatal("Unable toprepare '$sql': ".$dbh->errstr());
|
||||
my $res = $sth->execute($event->{Id})
|
||||
or Fatal("Unable toexecute '$sql': ".$dbh->errstr());
|
||||
or Fatal("Unable to prepare '$sql': ".$dbh->errstr());
|
||||
my $res = $sth->execute($Event->{Id})
|
||||
or Fatal("Unable to execute '$sql': ".$dbh->errstr());
|
||||
}
|
||||
return 1;
|
||||
} # end sub uploadArchFile
|
||||
|
@ -622,9 +631,9 @@ sub substituteTags {
|
|||
WHERE EventId = ? AND Type = 'Alarm'
|
||||
ORDER BY FrameId`;
|
||||
my $sth = $dbh->prepare_cached($sql)
|
||||
or Fatal("Unable toprepare '$sql': ".$dbh->errstr());
|
||||
or Fatal("Unable to prepare '$sql': ".$dbh->errstr());
|
||||
my $res = $sth->execute($Event->{Id})
|
||||
or Fatal( "Unable toexecute '$sql': ".$dbh->errstr());
|
||||
or Fatal("Unable to execute '$sql': ".$dbh->errstr());
|
||||
my $rows = 0;
|
||||
while( my $frame = $sth->fetchrow_hashref() ) {
|
||||
if ( !$first_alarm_frame ) {
|
||||
|
@ -796,7 +805,7 @@ sub sendEmail {
|
|||
$ssmtp_location = qx('which ssmtp');
|
||||
}
|
||||
if ( !$ssmtp_location ) {
|
||||
Debug('Unable tofind ssmtp, trying MIME::Lite->send');
|
||||
Debug('Unable to find ssmtp, trying MIME::Lite->send');
|
||||
MIME::Lite->send('smtp', $Config{ZM_EMAIL_HOST}, Timeout=>60);
|
||||
$mail->send();
|
||||
} else {
|
||||
|
@ -828,16 +837,16 @@ sub sendEmail {
|
|||
}
|
||||
};
|
||||
if ( $@ ) {
|
||||
Error("Unable tosend email: $@");
|
||||
Error("Unable to send email: $@");
|
||||
return 0;
|
||||
} else {
|
||||
Info('Notification email sent');
|
||||
}
|
||||
my $sql = 'UPDATE Events SET Emailed = 1 WHERE Id = ?';
|
||||
my $sth = $dbh->prepare_cached($sql)
|
||||
or Fatal("Unable toprepare '$sql': ".$dbh->errstr());
|
||||
or Fatal("Unable to prepare '$sql': ".$dbh->errstr());
|
||||
my $res = $sth->execute($Event->{Id})
|
||||
or Fatal("Unable toexecute '$sql': ".$dbh->errstr());
|
||||
or Fatal("Unable to execute '$sql': ".$dbh->errstr());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -898,7 +907,7 @@ sub sendMessage {
|
|||
$ssmtp_location = qx('which ssmtp');
|
||||
}
|
||||
if ( !$ssmtp_location ) {
|
||||
Debug('Unable tofind ssmtp, trying MIME::Lite->send');
|
||||
Debug('Unable to find ssmtp, trying MIME::Lite->send');
|
||||
MIME::Lite->send(smtp=>$Config{ZM_EMAIL_HOST}, Timeout=>60);
|
||||
$mail->send();
|
||||
} else {
|
||||
|
@ -933,29 +942,29 @@ sub sendMessage {
|
|||
}
|
||||
};
|
||||
if ( $@ ) {
|
||||
Error("Unable tosend email: $@");
|
||||
Error("Unable to send email: $@");
|
||||
return 0;
|
||||
} else {
|
||||
Info('Notification message sent');
|
||||
}
|
||||
my $sql = 'UPDATE Events SET Messaged = 1 WHERE Id = ?';
|
||||
my $sth = $dbh->prepare_cached($sql)
|
||||
or Fatal("Unable toprepare '$sql': ".$dbh->errstr());
|
||||
or Fatal("Unable to prepare '$sql': ".$dbh->errstr());
|
||||
my $res = $sth->execute($Event->{Id})
|
||||
or Fatal("Unable toexecute '$sql': ".$dbh->errstr());
|
||||
or Fatal("Unable to execute '$sql': ".$dbh->errstr());
|
||||
|
||||
return 1;
|
||||
} # end sub sendMessage
|
||||
|
||||
sub executeCommand {
|
||||
my $filter = shift;
|
||||
my $event = shift;
|
||||
my $Event = shift;
|
||||
|
||||
my $event_path = $event->Path();
|
||||
my $event_path = $Event->Path();
|
||||
|
||||
my $command = $filter->{AutoExecuteCmd};
|
||||
$command .= " $event_path";
|
||||
$command = substituteTags($command, $filter, $event);
|
||||
$command = substituteTags($command, $filter, $Event);
|
||||
|
||||
Info("Executing '$command'");
|
||||
my $output = qx($command);
|
||||
|
@ -971,7 +980,7 @@ sub executeCommand {
|
|||
my $sql = 'UPDATE Events SET Executed = 1 WHERE Id = ?';
|
||||
my $sth = $dbh->prepare_cached($sql)
|
||||
or Fatal("Unable to prepare '$sql': ".$dbh->errstr());
|
||||
my $res = $sth->execute( $event->{Id} )
|
||||
my $res = $sth->execute( $Event->{Id} )
|
||||
or Fatal("Unable to execute '$sql': ".$dbh->errstr());
|
||||
}
|
||||
return( 1 );
|
||||
|
|
|
@ -44,7 +44,6 @@ delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
|
|||
my $store_state=''; # PP - will remember state name passed
|
||||
|
||||
logInit();
|
||||
Info("Aftere LogInit");
|
||||
|
||||
my $command = $ARGV[0]||'';
|
||||
if ( $command eq 'version' ) {
|
||||
|
|
|
@ -88,13 +88,13 @@ delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
|
|||
logInit();
|
||||
logSetSignal();
|
||||
|
||||
Info( "Trigger daemon starting\n" );
|
||||
Info( "Trigger daemon starting" );
|
||||
|
||||
my $dbh = zmDbConnect();
|
||||
|
||||
my $base_rin = '';
|
||||
foreach my $connection ( @connections ) {
|
||||
Info( "Opening connection '$connection->{name}'\n" );
|
||||
Info( "Opening connection '$connection->{name}'" );
|
||||
$connection->open();
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ foreach my $connection ( @in_select_connections ) {
|
|||
my %spawned_connections;
|
||||
my %monitors;
|
||||
my $monitor_reload_time = 0;
|
||||
my $needsReload = 0;
|
||||
my @needsReload;
|
||||
loadMonitors();
|
||||
|
||||
$! = undef;
|
||||
|
@ -127,14 +127,14 @@ while( 1 ) {
|
|||
|
||||
my $nfound = select( my $rout = $rin, undef, my $eout = $ein, $timeout );
|
||||
if ( $nfound > 0 ) {
|
||||
Debug( "Got input from $nfound connections\n" );
|
||||
Debug( "Got input from $nfound connections" );
|
||||
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();
|
||||
|
@ -143,7 +143,7 @@ while( 1 ) {
|
|||
.$new_connection->fileno()
|
||||
.'), '
|
||||
.int(keys(%spawned_connections))
|
||||
." spawned connections\n"
|
||||
." spawned connections"
|
||||
);
|
||||
} else {
|
||||
my $messages = $connection->getMessages();
|
||||
|
@ -162,7 +162,7 @@ while( 1 ) {
|
|||
.$connection->name()
|
||||
.' ('
|
||||
.$connection->fileno()
|
||||
.")\n"
|
||||
.")"
|
||||
);
|
||||
my $messages = $connection->getMessages();
|
||||
if ( defined($messages) ) {
|
||||
|
@ -175,7 +175,7 @@ while( 1 ) {
|
|||
.$connection->fileno()
|
||||
.'), '
|
||||
.int(keys(%spawned_connections))
|
||||
." spawned connections\n"
|
||||
." spawned connections"
|
||||
);
|
||||
$connection->close();
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ while( 1 ) {
|
|||
if ( ! zmMemVerify($monitor) ) {
|
||||
# Our attempt to verify the memory handle failed. We should reload the monitors.
|
||||
# Don't need to zmMemInvalidate because the monitor reload will do it.
|
||||
$needsReload = 1;
|
||||
push @needsReload, $monitor;
|
||||
next;
|
||||
}
|
||||
|
||||
|
@ -217,8 +217,8 @@ while( 1 ) {
|
|||
]
|
||||
);
|
||||
|
||||
#print( "$monitor->{Id}: S:$state, LE:$last_event\n" );
|
||||
#print( "$monitor->{Id}: mS:$monitor->{LastState}, mLE:$monitor->{LastEvent}\n" );
|
||||
#print( "$monitor->{Id}: S:$state, LE:$last_event" );
|
||||
#print( "$monitor->{Id}: mS:$monitor->{LastState}, mLE:$monitor->{LastEvent}" );
|
||||
if ( $state == STATE_ALARM || $state == STATE_ALERT ) {
|
||||
# In alarm state
|
||||
if ( !defined($monitor->{LastEvent})
|
||||
|
@ -261,14 +261,14 @@ while( 1 ) {
|
|||
}
|
||||
|
||||
if ( my @action_times = keys(%actions) ) {
|
||||
Debug( "Checking for timed actions\n" );
|
||||
Debug( "Checking for timed actions" );
|
||||
my $now = time();
|
||||
foreach my $action_time ( sort( grep { $_ < $now } @action_times ) ) {
|
||||
Info( "Found actions expiring at $action_time\n" );
|
||||
Info( "Found actions expiring at $action_time" );
|
||||
foreach my $action ( @{$actions{$action_time}} ) {
|
||||
my $connection = $action->{connection};
|
||||
my $message = $action->{message};
|
||||
Info( "Found action '$message'\n" );
|
||||
Info( "Found action '$message'" );
|
||||
handleMessage( $connection, $message );
|
||||
}
|
||||
delete( $actions{$action_time} );
|
||||
|
@ -293,23 +293,41 @@ while( 1 ) {
|
|||
}
|
||||
}
|
||||
|
||||
# If necessary reload monitors
|
||||
if ( $needsReload || ((time() - $monitor_reload_time) > MONITOR_RELOAD_INTERVAL )) {
|
||||
# Reload all monitors from the dB every MONITOR_RELOAD_INTERVAL
|
||||
if ( (time() - $monitor_reload_time) > MONITOR_RELOAD_INTERVAL ) {
|
||||
foreach my $monitor ( values(%monitors) ) {
|
||||
# Free up any used memory handle
|
||||
zmMemInvalidate( $monitor );
|
||||
zmMemInvalidate( $monitor ); # Free up any used memory handle
|
||||
}
|
||||
loadMonitors();
|
||||
$needsReload = 0;
|
||||
@needsReload = (); # We just reloaded all monitors so no need reload a specific monitor
|
||||
# If we have NOT just reloaded all monitors, reload a specific monitor if its shared mem changed
|
||||
} elsif ( @needsReload ) {
|
||||
foreach my $monitor ( @needsReload ) {
|
||||
loadMonitor($monitor);
|
||||
}
|
||||
@needsReload = ();
|
||||
}
|
||||
|
||||
# zmDbConnect will ping and reconnect if neccessary
|
||||
$dbh = zmDbConnect();
|
||||
} # end while ( 1 )
|
||||
Info( "Trigger daemon exiting\n" );
|
||||
Info( "Trigger daemon exiting" );
|
||||
exit;
|
||||
|
||||
sub loadMonitor {
|
||||
my $monitor = shift;
|
||||
|
||||
Debug( "Loading monitor $monitor" );
|
||||
zmMemInvalidate( $monitor );
|
||||
|
||||
if ( zmMemVerify( $monitor ) ) { # This will re-init shared memory
|
||||
$monitor->{LastState} = zmGetMonitorState( $monitor );
|
||||
$monitor->{LastEvent} = zmGetLastEvent( $monitor );
|
||||
}
|
||||
}
|
||||
|
||||
sub loadMonitors {
|
||||
Debug( "Loading monitors\n" );
|
||||
Debug( "Loading monitors" );
|
||||
$monitor_reload_time = time();
|
||||
|
||||
my %new_monitors = ();
|
||||
|
@ -323,7 +341,7 @@ sub loadMonitors {
|
|||
my $res = $sth->execute( $Config{ZM_SERVER_ID} ? $Config{ZM_SERVER_ID} : () )
|
||||
or Fatal( "Can't execute: ".$sth->errstr() );
|
||||
while( my $monitor = $sth->fetchrow_hashref() ) {
|
||||
if ( zmMemVerify( $monitor ) ) {
|
||||
if ( zmMemVerify( $monitor ) ) { # This will re-init shared memory
|
||||
$monitor->{LastState} = zmGetMonitorState( $monitor );
|
||||
$monitor->{LastEvent} = zmGetLastEvent( $monitor );
|
||||
}
|
||||
|
@ -344,14 +362,14 @@ sub handleMessage {
|
|||
|
||||
my $monitor = $monitors{$id};
|
||||
if ( !$monitor ) {
|
||||
Warning( "Can't find monitor '$id' for message '$message'\n" );
|
||||
Warning( "Can't find monitor '$id' for message '$message'" );
|
||||
return;
|
||||
}
|
||||
Debug( "Found monitor for id '$id'\n" );
|
||||
Debug( "Found monitor for id '$id'" );
|
||||
|
||||
next if ( !zmMemVerify( $monitor ) );
|
||||
|
||||
Debug( "Handling action '$action'\n" );
|
||||
Debug( "Handling action '$action'" );
|
||||
if ( $action =~ /^(enable|disable)(?:\+(\d+))?$/ ) {
|
||||
my $state = $1;
|
||||
my $delay = $2;
|
||||
|
@ -362,7 +380,7 @@ sub handleMessage {
|
|||
}
|
||||
# Force a reload
|
||||
$monitor_reload_time = 0;
|
||||
Info( "Set monitor to $state\n" );
|
||||
Info( "Set monitor to $state" );
|
||||
if ( $delay ) {
|
||||
my $action_text = $id.'|'.( ($state eq 'enable')
|
||||
? 'disable'
|
||||
|
@ -379,7 +397,7 @@ sub handleMessage {
|
|||
if ( $trigger eq 'on' ) {
|
||||
zmTriggerEventOn( $monitor, $score, $cause, $text );
|
||||
zmTriggerShowtext( $monitor, $showtext ) if defined($showtext);
|
||||
Info( "Trigger '$trigger' '$cause'\n" );
|
||||
Info( "Trigger '$trigger' '$cause'" );
|
||||
if ( $delay ) {
|
||||
my $action_text = $id.'|cancel';
|
||||
handleDelay($delay, $connection, $action_text);
|
||||
|
@ -392,7 +410,7 @@ sub handleMessage {
|
|||
my $last_event = zmGetLastEvent( $monitor );
|
||||
zmTriggerEventOff( $monitor );
|
||||
zmTriggerShowtext( $monitor, $showtext ) if defined($showtext);
|
||||
Info( "Trigger '$trigger'\n" );
|
||||
Info( "Trigger '$trigger'" );
|
||||
# Wait til it's finished
|
||||
while( zmInAlarm( $monitor )
|
||||
&& ($last_event == zmGetLastEvent( $monitor ))
|
||||
|
@ -406,12 +424,12 @@ sub handleMessage {
|
|||
} elsif( $action eq 'cancel' ) {
|
||||
zmTriggerEventCancel( $monitor );
|
||||
zmTriggerShowtext( $monitor, $showtext ) if defined($showtext);
|
||||
Info( "Cancelled event\n" );
|
||||
Info( "Cancelled event" );
|
||||
} elsif( $action eq 'show' ) {
|
||||
zmTriggerShowtext( $monitor, $showtext );
|
||||
Info( "Updated show text to '$showtext'\n" );
|
||||
Info( "Updated show text to '$showtext'" );
|
||||
} else {
|
||||
Error( "Unrecognised action '$action' in message '$message'\n" );
|
||||
Error( "Unrecognised action '$action' in message '$message'" );
|
||||
}
|
||||
} # end sub handleMessage
|
||||
|
||||
|
@ -426,7 +444,7 @@ sub handleDelay {
|
|||
$action_array = $actions{$action_time} = [];
|
||||
}
|
||||
push( @$action_array, { connection=>$connection, message=>$action_text } );
|
||||
Debug( "Added timed event '$action_text', expires at $action_time (+$delay secs)\n" );
|
||||
Debug( "Added timed event '$action_text', expires at $action_time (+$delay secs)" );
|
||||
}
|
||||
1;
|
||||
__END__
|
||||
|
|
|
@ -755,6 +755,12 @@ void EventStream::runStream() {
|
|||
// commands may set send_frame to true
|
||||
while(checkCommandQueue());
|
||||
|
||||
// Update modified time of the socket .lock file so that we can tell which ones are stale.
|
||||
if ( now.tv_sec - last_comm_update.tv_sec > 3600 ) {
|
||||
touch(sock_path_lock);
|
||||
last_comm_update = now;
|
||||
}
|
||||
|
||||
if ( step != 0 )
|
||||
curr_frame_id += step;
|
||||
|
||||
|
|
849
src/zm_image.cpp
849
src/zm_image.cpp
File diff suppressed because it is too large
Load Diff
|
@ -274,6 +274,7 @@ void std_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result,
|
|||
void std_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
||||
void std_delta8_argb(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
||||
void std_delta8_abgr(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
||||
|
||||
void neon32_armv7_delta8_gray8(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
||||
void neon32_armv7_delta8_rgba(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
||||
void neon32_armv7_delta8_bgra(const uint8_t* col1, const uint8_t* col2, uint8_t* result, unsigned long count);
|
||||
|
|
|
@ -531,6 +531,12 @@ void MonitorStream::runStream() {
|
|||
Debug(2, "Have checking command Queue for connkey: %d", connkey );
|
||||
got_command = true;
|
||||
}
|
||||
// Update modified time of the socket .lock file so that we can tell which ones are stale.
|
||||
if ( now.tv_sec - last_comm_update.tv_sec > 3600 ) {
|
||||
touch(sock_path_lock);
|
||||
last_comm_update = now;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( paused ) {
|
||||
|
|
|
@ -332,6 +332,8 @@ void StreamBase::openComms() {
|
|||
snprintf(rem_sock_path, sizeof(rem_sock_path), "%s/zms-%06dw.sock", staticConfig.PATH_SOCKS.c_str(), connkey);
|
||||
strncpy(rem_addr.sun_path, rem_sock_path, sizeof(rem_addr.sun_path)-1);
|
||||
rem_addr.sun_family = AF_UNIX;
|
||||
|
||||
gettimeofday(&last_comm_update, NULL);
|
||||
} // end if connKey > 0
|
||||
Debug(2, "comms open");
|
||||
} // end void StreamBase::openComms()
|
||||
|
|
|
@ -85,6 +85,7 @@ protected:
|
|||
int step;
|
||||
|
||||
struct timeval now;
|
||||
struct timeval last_comm_update;
|
||||
|
||||
double base_fps;
|
||||
double effective_fps;
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <fcntl.h> /* Definition of AT_* constants */
|
||||
#include <sys/stat.h>
|
||||
#if defined(__arm__)
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
|
@ -414,3 +416,22 @@ Warning("ZM Compiled without LIBCURL. UriDecoding not implemented.");
|
|||
#endif
|
||||
}
|
||||
|
||||
void touch(const char *pathname) {
|
||||
int fd = open(pathname,
|
||||
O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK,
|
||||
0666);
|
||||
if ( fd < 0 ) {
|
||||
// Couldn't open that path.
|
||||
Error("Couldn't open() path \"%s in touch", pathname);
|
||||
return;
|
||||
}
|
||||
int rc = utimensat(AT_FDCWD,
|
||||
pathname,
|
||||
nullptr,
|
||||
0);
|
||||
if ( rc ) {
|
||||
Error("Couldn't utimensat() path %s in touch", pathname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,5 +63,5 @@ extern unsigned int neonversion;
|
|||
|
||||
char *timeval_to_string( struct timeval tv );
|
||||
std::string UriDecode( const std::string &encoded );
|
||||
|
||||
void touch( const char *pathname );
|
||||
#endif // ZM_UTILS_H
|
||||
|
|
|
@ -23,7 +23,7 @@ case $i in
|
|||
shift # past argument=value
|
||||
;;
|
||||
-d=*|--distro=*)
|
||||
DISTRO="${i#*=}"
|
||||
DISTROS="${i#*=}"
|
||||
shift # past argument=value
|
||||
;;
|
||||
-i=*|--interactive=*)
|
||||
|
@ -74,11 +74,15 @@ else
|
|||
echo "Doing $TYPE build"
|
||||
fi;
|
||||
|
||||
if [ "$DISTRO" == "" ]; then
|
||||
DISTRO=`lsb_release -a 2>/dev/null | grep Codename | awk '{print $2}'`;
|
||||
echo "Defaulting to $DISTRO for distribution";
|
||||
if [ "$DISTROS" == "" ]; then
|
||||
if [ "$RELEASE" != "" ]; then
|
||||
DISTROS="xenial,bionic,trusty"
|
||||
else
|
||||
DISTROS=`lsb_release -a 2>/dev/null | grep Codename | awk '{print $2}'`;
|
||||
fi;
|
||||
echo "Defaulting to $DISTROS for distribution";
|
||||
else
|
||||
echo "Building for $DISTRO";
|
||||
echo "Building for $DISTROS";
|
||||
fi;
|
||||
|
||||
# Release is a special mode... it uploads to the release ppa and cannot have a snapshot
|
||||
|
@ -116,6 +120,18 @@ else
|
|||
fi;
|
||||
fi
|
||||
|
||||
PPA="";
|
||||
if [ "$RELEASE" != "" ]; then
|
||||
# We need to use our official tarball for the original source, so grab it and overwrite our generated one.
|
||||
IFS='.' read -r -a VERSION <<< "$RELEASE"
|
||||
PPA="ppa:iconnor/zoneminder-${VERSION[0]}.${VERSION[1]}"
|
||||
else
|
||||
if [ "$BRANCH" == "" ]; then
|
||||
PPA="ppa:iconnor/zoneminder-master";
|
||||
else
|
||||
PPA="ppa:iconnor/zoneminder-$BRANCH";
|
||||
fi;
|
||||
fi;
|
||||
|
||||
# Instead of cloning from github each time, if we have a fork lying around, update it and pull from there instead.
|
||||
if [ ! -d "${GITHUB_FORK}_zoneminder_release" ]; then
|
||||
|
@ -154,6 +170,11 @@ if [ "$SNAPSHOT" != "stable" ] && [ "$SNAPSHOT" != "" ]; then
|
|||
fi;
|
||||
|
||||
DIRECTORY="zoneminder_$VERSION";
|
||||
if [ -d "$DIRECTORY.orig" ]; then
|
||||
echo "$DIRECTORY.orig already exists. Please delete it."
|
||||
exit 0;
|
||||
fi;
|
||||
|
||||
echo "Doing $TYPE release $DIRECTORY";
|
||||
mv "${GITHUB_FORK}_zoneminder_release" "$DIRECTORY.orig";
|
||||
if [ $? -ne 0 ]; then
|
||||
|
@ -161,6 +182,7 @@ if [ $? -ne 0 ]; then
|
|||
echo "Setting up build dir failed.";
|
||||
exit $?;
|
||||
fi;
|
||||
|
||||
cd "$DIRECTORY.orig";
|
||||
|
||||
# Init submodules
|
||||
|
@ -172,36 +194,45 @@ rm -rf .git
|
|||
rm .gitignore
|
||||
cd ../
|
||||
|
||||
tar zcf $DIRECTORY.orig.tar.gz $DIRECTORY.orig
|
||||
cd $DIRECTORY.orig
|
||||
|
||||
# Generate Changlog
|
||||
if [ "$DISTRO" == "trusty" ] || [ "$DISTRO" == "precise" ]; then
|
||||
mv distros/ubuntu1204 debian
|
||||
else
|
||||
if [ "$DISTRO" == "wheezy" ]; then
|
||||
mv distros/debian debian
|
||||
else
|
||||
mv distros/ubuntu1604 debian
|
||||
fi;
|
||||
if [ ! -e "$DIRECTORY.orig.tar.gz" ]; then
|
||||
tar zcf $DIRECTORY.orig.tar.gz $DIRECTORY.orig
|
||||
fi;
|
||||
|
||||
if [ "$DEBEMAIL" != "" ] && [ "$DEBFULLNAME" != "" ]; then
|
||||
IFS=',' ;for DISTRO in `echo "$DISTROS"`; do
|
||||
echo "Generating package for $DISTRO";
|
||||
cd $DIRECTORY.orig
|
||||
|
||||
if [ -e "debian" ]; then
|
||||
rm -rf debian
|
||||
fi;
|
||||
|
||||
# Generate Changlog
|
||||
if [ "$DISTRO" == "trusty" ] || [ "$DISTRO" == "precise" ]; then
|
||||
cp -Rpd distros/ubuntu1204 debian
|
||||
else
|
||||
if [ "$DISTRO" == "wheezy" ]; then
|
||||
cp -Rpd distros/debian debian
|
||||
else
|
||||
cp -Rpd distros/ubuntu1604 debian
|
||||
fi;
|
||||
fi;
|
||||
|
||||
if [ "$DEBEMAIL" != "" ] && [ "$DEBFULLNAME" != "" ]; then
|
||||
AUTHOR="$DEBFULLNAME <$DEBEMAIL>"
|
||||
else
|
||||
else
|
||||
if [ -z `hostname -d` ] ; then
|
||||
AUTHOR="`getent passwd $USER | cut -d ':' -f 5 | cut -d ',' -f 1` <`whoami`@`hostname`.local>"
|
||||
else
|
||||
AUTHOR="`getent passwd $USER | cut -d ':' -f 5 | cut -d ',' -f 1` <`whoami`@`hostname`>"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$URGENCY" = "" ]; then
|
||||
if [ "$URGENCY" = "" ]; then
|
||||
URGENCY="medium"
|
||||
fi;
|
||||
fi;
|
||||
|
||||
if [ "$SNAPSHOT" == "stable" ]; then
|
||||
cat <<EOF > debian/changelog
|
||||
if [ "$SNAPSHOT" == "stable" ]; then
|
||||
cat <<EOF > debian/changelog
|
||||
zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
|
||||
|
||||
* Release $VERSION
|
||||
|
@ -209,37 +240,37 @@ zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
|
|||
-- $AUTHOR $DATE
|
||||
|
||||
EOF
|
||||
cat <<EOF > debian/NEWS
|
||||
cat <<EOF > debian/NEWS
|
||||
zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
|
||||
|
||||
* Release $VERSION
|
||||
|
||||
-- $AUTHOR $DATE
|
||||
EOF
|
||||
else
|
||||
cat <<EOF > debian/changelog
|
||||
else
|
||||
cat <<EOF > debian/changelog
|
||||
zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
|
||||
|
||||
*
|
||||
|
||||
-- $AUTHOR $DATE
|
||||
EOF
|
||||
cat <<EOF > debian/changelog
|
||||
cat <<EOF > debian/changelog
|
||||
zoneminder ($VERSION-$DISTRO${PACKAGE_VERSION}) $DISTRO; urgency=$URGENCY
|
||||
|
||||
*
|
||||
|
||||
-- $AUTHOR $DATE
|
||||
EOF
|
||||
fi;
|
||||
fi;
|
||||
|
||||
if [ $TYPE == "binary" ]; then
|
||||
if [ $TYPE == "binary" ]; then
|
||||
# Auto-install all ZoneMinder's depedencies using the Debian control file
|
||||
sudo apt-get install devscripts equivs
|
||||
sudo mk-build-deps -ir ./debian/control
|
||||
echo "Status: $?"
|
||||
DEBUILD=debuild
|
||||
else
|
||||
else
|
||||
if [ $TYPE == "local" ]; then
|
||||
# Auto-install all ZoneMinder's depedencies using the Debian control file
|
||||
sudo apt-get install devscripts equivs
|
||||
|
@ -250,27 +281,20 @@ else
|
|||
# Source build, don't need build depends.
|
||||
DEBUILD="debuild -S -sa"
|
||||
fi;
|
||||
fi;
|
||||
if [ "$DEBSIGN_KEYID" != "" ]; then
|
||||
fi;
|
||||
if [ "$DEBSIGN_KEYID" != "" ]; then
|
||||
DEBUILD="$DEBUILD -k$DEBSIGN_KEYID"
|
||||
fi
|
||||
$DEBUILD
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error status code is: $?"
|
||||
fi
|
||||
eval $DEBUILD
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error status code is: $?"
|
||||
echo "Build failed.";
|
||||
exit $?;
|
||||
fi;
|
||||
fi;
|
||||
|
||||
cd ../
|
||||
if [ "$INTERACTIVE" != "no" ]; then
|
||||
read -p "Do you want to keep the checked out version of Zoneminder (incase you want to modify it later) [y/N]"
|
||||
[[ $REPLY == [yY] ]] && { mv "$DIRECTORY.orig" zoneminder_release; echo "The checked out copy is preserved in zoneminder_release"; } || { rm -fr "$DIRECTORY.orig"; echo "The checked out copy has been deleted"; }
|
||||
echo "Done!"
|
||||
else
|
||||
rm -fr "$DIRECTORY.orig"; echo "The checked out copy has been deleted";
|
||||
fi
|
||||
cd ../
|
||||
|
||||
if [ $TYPE == "binary" ]; then
|
||||
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)"
|
||||
if [[ $REPLY == [yY] ]]; then
|
||||
|
@ -289,26 +313,8 @@ if [ $TYPE == "binary" ]; then
|
|||
fi;
|
||||
fi;
|
||||
fi;
|
||||
else
|
||||
else
|
||||
SC="zoneminder_${VERSION}-${DISTRO}${PACKAGE_VERSION}_source.changes";
|
||||
PPA="";
|
||||
if [ "$RELEASE" != "" ]; then
|
||||
# We need to use our official tarball for the original source, so grab it and overwrite our generated one.
|
||||
if [ ! -e "$RELEASE.tar.gz" ]; then
|
||||
echo "Grabbing official source tarball from github."
|
||||
wget "https://github.com/ZoneMinder/zoneminder/archive/$RELEASE.tar.gz"
|
||||
fi;
|
||||
echo "Overwriting generated zoneminder_${VERSION}.orig.tar.gz with source tarball from github";
|
||||
cp "$RELEASE.tar.gz" "zoneminder_${VERSION}.orig.tar.gz"
|
||||
IFS='.' read -r -a VERSION <<< "$RELEASE"
|
||||
PPA="ppa:iconnor/zoneminder-${VERSION[0]}.${VERSION[1]}"
|
||||
else
|
||||
if [ "$BRANCH" == "" ]; then
|
||||
PPA="ppa:iconnor/zoneminder-master";
|
||||
else
|
||||
PPA="ppa:iconnor/zoneminder-$BRANCH";
|
||||
fi;
|
||||
fi;
|
||||
|
||||
dput="Y";
|
||||
if [ "$INTERACTIVE" != "no" ]; then
|
||||
|
@ -317,6 +323,15 @@ else
|
|||
dput $PPA $SC
|
||||
fi;
|
||||
fi;
|
||||
fi;
|
||||
fi;
|
||||
done; # foreach distro
|
||||
|
||||
if [ "$INTERACTIVE" != "no" ]; then
|
||||
read -p "Do you want to keep the checked out version of Zoneminder (incase you want to modify it later) [y/N]"
|
||||
[[ $REPLY == [yY] ]] && { mv "$DIRECTORY.orig" zoneminder_release; echo "The checked out copy is preserved in zoneminder_release"; } || { rm -fr "$DIRECTORY.orig"; echo "The checked out copy has been deleted"; }
|
||||
echo "Done!"
|
||||
else
|
||||
rm -fr "$DIRECTORY.orig"; echo "The checked out copy has been deleted";
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ class HostController extends AppController {
|
|||
$this->Session->read('user'); # this is needed for command line/curl to recognize a session
|
||||
$zmAuthRelay = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_RELAY')))['Config']['Value'];
|
||||
if ( $zmAuthRelay == 'hashed' ) {
|
||||
$zmAuthHashIps= $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_IPS')))['Config']['Value'];
|
||||
$zmAuthHashIps = $this->Config->find('first',array('conditions' => array('Config.' . $this->Config->primaryKey => 'ZM_AUTH_HASH_IPS')))['Config']['Value'];
|
||||
$credentials = 'auth='.generateAuthHash($zmAuthHashIps);
|
||||
} else if ( $zmAuthRelay == 'plain' ) {
|
||||
// user will need to append the store password here
|
||||
|
@ -101,27 +101,25 @@ class HostController extends AppController {
|
|||
$this->loadModel('Monitor');
|
||||
|
||||
// If $mid is passed, see if it is valid
|
||||
if ($mid) {
|
||||
if (!$this->Monitor->exists($mid)) {
|
||||
if ( $mid ) {
|
||||
if ( !$this->Monitor->exists($mid) ) {
|
||||
throw new NotFoundException(__('Invalid monitor'));
|
||||
}
|
||||
}
|
||||
|
||||
$zm_dir_events = $this->Config->find('list', array(
|
||||
'conditions' => array('Name' => 'ZM_DIR_EVENTS'),
|
||||
'fields' => array('Name', 'Value')
|
||||
));
|
||||
$zm_dir_events = $zm_dir_events['ZM_DIR_EVENTS' ];
|
||||
$zm_dir_events = ZM_DIR_EVENTS;
|
||||
|
||||
// Test to see if $zm_dir_events is relative or absolute
|
||||
if ('/' === "" || strrpos($zm_dir_events, '/', -strlen($zm_dir_events)) !== TRUE) {
|
||||
#if ('/' === "" || strrpos($zm_dir_events, '/', -strlen($zm_dir_events)) !== TRUE) {
|
||||
if ( substr($zm_dir_events, 0, 1) != '/' ) {
|
||||
// relative - so add the full path
|
||||
$zm_dir_events = Configure::read('ZM_PATH_WEB') . '/' . $zm_dir_events;
|
||||
$zm_dir_events = ZM_PATH_WEB . '/' . $zm_dir_events;
|
||||
}
|
||||
|
||||
if ($mid) {
|
||||
if ( $mid ) {
|
||||
// Get disk usage for $mid
|
||||
$usage = shell_exec ("du -sh0 $zm_dir_events/$mid | awk '{print $1}'");
|
||||
Logger::Debug("Executing du -s0 $zm_dir_events/$mid | awk '{print $1}'");
|
||||
$usage = shell_exec("du -s0 $zm_dir_events/$mid | awk '{print $1}'");
|
||||
} else {
|
||||
$monitors = $this->Monitor->find('all', array(
|
||||
'fields' => array('Id', 'Name', 'WebColour')
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
<?php
|
||||
App::uses('AppController', 'Controller');
|
||||
/**
|
||||
* Storage Controller
|
||||
*
|
||||
* @property Storage $Storage
|
||||
* @property PaginatorComponent $Paginator
|
||||
*/
|
||||
class StorageController extends AppController {
|
||||
|
||||
/**
|
||||
* Components
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $components = array('Paginator', 'RequestHandler');
|
||||
|
||||
public function beforeFilter() {
|
||||
parent::beforeFilter();
|
||||
global $user;
|
||||
$canView = (!$user) || ($user['System'] != 'None');
|
||||
if ( !$canView ) {
|
||||
throw new UnauthorizedException(__('Insufficient Privileges'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* index method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function index() {
|
||||
$this->Storage->recursive = 0;
|
||||
|
||||
$options = '';
|
||||
$storage_areas = $this->Storage->find('all',$options);
|
||||
$this->set(array(
|
||||
'storage' => $storage_areas,
|
||||
'_serialize' => array('storage')
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* view method
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @param string $id
|
||||
* @return void
|
||||
*/
|
||||
public function view($id = null) {
|
||||
$this->Storage->recursive = 0;
|
||||
if (!$this->Storage->exists($id)) {
|
||||
throw new NotFoundException(__('Invalid storage area'));
|
||||
}
|
||||
$restricted = '';
|
||||
|
||||
$options = array('conditions' => array(
|
||||
array('Storage.' . $this->Storage->primaryKey => $id),
|
||||
$restricted
|
||||
)
|
||||
);
|
||||
$storage = $this->Storage->find('first', $options);
|
||||
$this->set(array(
|
||||
'storage' => $storage,
|
||||
'_serialize' => array('storage')
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* add method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add() {
|
||||
if ( $this->request->is('post') ) {
|
||||
|
||||
global $user;
|
||||
$canEdit = (!$user) || ($user['System'] == 'Edit');
|
||||
if ( !$canEdit ) {
|
||||
throw new UnauthorizedException(__('Insufficient privileges'));
|
||||
return;
|
||||
}
|
||||
|
||||
$this->Storage->create();
|
||||
if ( $this->Storage->save($this->request->data) ) {
|
||||
# Might be nice to send it a start request
|
||||
#$this->daemonControl($this->Storage->id, 'start', $this->request->data);
|
||||
return $this->flash(__('The storage area has been saved.'), array('action' => 'index'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* edit method
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @param string $id
|
||||
* @return void
|
||||
*/
|
||||
public function edit($id = null) {
|
||||
$this->Storage->id = $id;
|
||||
|
||||
global $user;
|
||||
$canEdit = (!$user) || ($user['System'] == 'Edit');
|
||||
if ( !$canEdit ) {
|
||||
throw new UnauthorizedException(__('Insufficient privileges'));
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !$this->Storage->exists($id) ) {
|
||||
throw new NotFoundException(__('Invalid storage area'));
|
||||
}
|
||||
if ( $this->Storage->save($this->request->data) ) {
|
||||
$message = 'Saved';
|
||||
} else {
|
||||
$message = 'Error';
|
||||
}
|
||||
|
||||
$this->set(array(
|
||||
'message' => $message,
|
||||
'_serialize' => array('message')
|
||||
));
|
||||
// - restart this storage area after change
|
||||
#$this->daemonControl($this->Storage->id, 'restart', $this->request->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* delete method
|
||||
*
|
||||
* @throws NotFoundException
|
||||
* @param string $id
|
||||
* @return void
|
||||
*/
|
||||
public function delete($id = null) {
|
||||
global $user;
|
||||
$canEdit = (!$user) || ($user['System'] == 'Edit');
|
||||
if ( !$canEdit ) {
|
||||
throw new UnauthorizedException(__('Insufficient privileges'));
|
||||
return;
|
||||
}
|
||||
|
||||
$this->Storage->id = $id;
|
||||
if ( !$this->Storage->exists() ) {
|
||||
throw new NotFoundException(__('Invalid storage area'));
|
||||
}
|
||||
$this->request->allowMethod('post', 'delete');
|
||||
|
||||
#$this->daemonControl($this->Storage->id, 'stop');
|
||||
|
||||
if ( $this->Storage->delete() ) {
|
||||
return $this->flash(__('The storage area has been deleted.'), array('action' => 'index'));
|
||||
} else {
|
||||
return $this->flash(__('The storage area could not be deleted. Please, try again.'), array('action' => 'index'));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
.overlayHeader {
|
||||
float: left;
|
||||
background-color: #dddddd;
|
||||
background-color: #853131;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #666666;
|
||||
color: black;
|
||||
|
|
|
@ -55,7 +55,7 @@ class Frame {
|
|||
#return $_SERVER['PHP_SELF'].'?view=image&fid='.$this->{'Id'}.'&show='.$show.'&filename='.$this->Event()->MonitorId().'_'.$this->{'EventId'}.'_'.$this->{'FrameId'}.'.jpg';
|
||||
} // end function getImageSrc
|
||||
|
||||
public static function find( $parameters = array(), $limit = NULL ) {
|
||||
public static function find( $parameters = array(), $options = NULL ) {
|
||||
$sql = 'SELECT * FROM Frames';
|
||||
$values = array();
|
||||
if ( sizeof($parameters) ) {
|
||||
|
@ -65,17 +65,23 @@ class Frame {
|
|||
) );
|
||||
$values = array_values( $parameters );
|
||||
}
|
||||
if ( $limit ) {
|
||||
if ( is_integer( $limit ) or ctype_digit( $limit ) ) {
|
||||
$sql .= ' LIMIT ' . $limit;
|
||||
if ( $options ) {
|
||||
if ( isset($options['order']) ) {
|
||||
$sql .= ' ORDER BY ' . $options['order'];
|
||||
}
|
||||
if ( isset($options['limit']) ) {
|
||||
if ( is_integer($options['limit']) or ctype_digit($options['limit']) ) {
|
||||
$sql .= ' LIMIT ' . $options['limit'];
|
||||
} else {
|
||||
$backTrace = debug_backtrace();
|
||||
$file = $backTrace[1]['file'];
|
||||
$line = $backTrace[1]['line'];
|
||||
Error("Invalid value for limit($limit) passed to Frame::find from $file:$line");
|
||||
Error("Invalid value for limit(".$options['limit'].") passed to Frame::find from $file:$line");
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$results = dbFetchAll($sql, NULL, $values);
|
||||
if ( $results ) {
|
||||
return array_map( function($id){ return new Frame($id); }, $results );
|
||||
|
@ -83,8 +89,9 @@ class Frame {
|
|||
return array();
|
||||
}
|
||||
|
||||
public static function find_one( $parameters = array() ) {
|
||||
$results = Frame::find( $parameters, 1 );
|
||||
public static function find_one( $parameters = array(), $options = null ) {
|
||||
$options['limit'] = 1;
|
||||
$results = Frame::find($parameters, $options);
|
||||
if ( ! sizeof($results) ) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -152,10 +152,11 @@ private $control_fields = array(
|
|||
}
|
||||
if ( $this->{'Controllable'} ) {
|
||||
$s = dbFetchOne('SELECT * FROM Controls WHERE Id=?', NULL, array($this->{'ControlId'}) );
|
||||
if ( $s ) {
|
||||
foreach ($s as $k => $v) {
|
||||
if ( $k == 'Id' ) {
|
||||
continue;
|
||||
# The reason for these is that the name overlaps Monitor fields.
|
||||
# The reason for these is that the name overlaps Monitor fields.
|
||||
} else if ( $k == 'Protocol' ) {
|
||||
$this->{'ControlProtocol'} = $v;
|
||||
} else if ( $k == 'Name' ) {
|
||||
|
@ -166,6 +167,9 @@ private $control_fields = array(
|
|||
$this->{$k} = $v;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Warning('No Controls found for monitor '.$this->{'Id'} . ' ' . $this->{'Name'}.' althrough it is marked as controllable');
|
||||
}
|
||||
}
|
||||
global $monitor_cache;
|
||||
$monitor_cache[$row['Id']] = $this;
|
||||
|
@ -381,7 +385,7 @@ private $control_fields = array(
|
|||
} else if ( $this->ServerId() ) {
|
||||
$Server = $this->Server();
|
||||
|
||||
$url = $Server->Url() . '/zm/api/monitors/'.$this->{'Id'}.'.json';
|
||||
$url = ZM_BASE_PROTOCOL . '://'.$Server->Hostname().'/zm/api/monitors/'.$this->{'Id'}.'.json';
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_RELAY == 'hashed' ) {
|
||||
$url .= '?auth='.generateAuthHash( ZM_AUTH_HASH_IPS );
|
||||
|
@ -547,7 +551,7 @@ private $control_fields = array(
|
|||
} // end function Source
|
||||
|
||||
public function Url() {
|
||||
return $this->Server()->Url() .':'. ( ZM_MIN_STREAMING_PORT ? (ZM_MIN_STREAMING_PORT+$this->Id()) : $_SERVER['SERVER_PORT'] );
|
||||
return $this->Server()->Url( ZM_MIN_STREAMING_PORT ? (ZM_MIN_STREAMING_PORT+$this->Id()) : null );
|
||||
}
|
||||
|
||||
} // end class Monitor
|
||||
|
|
|
@ -38,13 +38,20 @@ class Server {
|
|||
}
|
||||
}
|
||||
|
||||
public function Url() {
|
||||
public function Url( $port = null ) {
|
||||
$url = ZM_BASE_PROTOCOL . '://';
|
||||
if ( $this->Id() ) {
|
||||
return ZM_BASE_PROTOCOL . '://'. $this->Hostname();
|
||||
$url .= $this->Hostname();
|
||||
} else {
|
||||
return ZM_BASE_PROTOCOL . '://'. $_SERVER['SERVER_NAME'];
|
||||
return '';
|
||||
$url .= $_SERVER['SERVER_NAME'];
|
||||
}
|
||||
if ( $port ) {
|
||||
$url .= ':'.$port;
|
||||
} else {
|
||||
$url .= ':'.$_SERVER['SERVER_PORT'];
|
||||
}
|
||||
$url .= $_SERVER['PHP_SELF'];
|
||||
return $url;
|
||||
}
|
||||
public function Hostname() {
|
||||
if ( isset( $this->{'Hostname'} ) and ( $this->{'Hostname'} != '' ) ) {
|
||||
|
|
|
@ -116,7 +116,7 @@ function generateAuthHash($useRemoteAddr, $force=false) {
|
|||
$time = time();
|
||||
$mintime = $time - ( ZM_AUTH_HASH_TTL * 1800 );
|
||||
|
||||
if ( $force or ( !isset($_SESSION['AuthHash']) ) or ( $_SESSION['AuthHashGeneratedAt'] < $mintime ) ) {
|
||||
if ( $force or ( !isset($_SESSION['AuthHash'.$_SESSION['remoteAddr']]) ) or ( $_SESSION['AuthHashGeneratedAt'] < $mintime ) ) {
|
||||
# Don't both regenerating Auth Hash if an hour hasn't gone by yet
|
||||
$local_time = localtime();
|
||||
$authKey = '';
|
||||
|
@ -133,7 +133,7 @@ function generateAuthHash($useRemoteAddr, $force=false) {
|
|||
session_start();
|
||||
$close_session = 1;
|
||||
}
|
||||
$_SESSION['AuthHash'] = $auth;
|
||||
$_SESSION['AuthHash'.$_SESSION['remoteAddr']] = $auth;
|
||||
$_SESSION['AuthHashGeneratedAt'] = $time;
|
||||
session_write_close();
|
||||
} else {
|
||||
|
@ -143,7 +143,7 @@ function generateAuthHash($useRemoteAddr, $force=false) {
|
|||
#} else {
|
||||
#Logger::Debug("Using cached auth " . $_SESSION['AuthHash'] ." beacuse generatedat:" . $_SESSION['AuthHashGeneratedAt'] . ' < now:'. $time . ' - ' . ZM_AUTH_HASH_TTL . ' * 1800 = '. $mintime);
|
||||
} # end if AuthHash is not cached
|
||||
return $_SESSION['AuthHash'];
|
||||
return $_SESSION['AuthHash'.$_SESSION['remoteAddr']];
|
||||
} # end if using AUTH and AUTH_RELAY
|
||||
return '';
|
||||
}
|
||||
|
|
|
@ -40,15 +40,16 @@ function CORSHeaders() {
|
|||
|
||||
# The following is left for future reference/use.
|
||||
$valid = false;
|
||||
$servers = dbFetchAll('SELECT * FROM Servers');
|
||||
if ( sizeof($servers) <= 1 ) {
|
||||
$Servers = Server::find();
|
||||
if ( sizeof($Servers) <= 1 ) {
|
||||
# Only need CORSHeaders in the event that there are multiple servers in use.
|
||||
# ICON: Might not be true. multi-port?
|
||||
return;
|
||||
}
|
||||
foreach( $servers as $row ) {
|
||||
$Server = new Server($row);
|
||||
if ( preg_match('/^'.preg_quote($Server->Url(),'/').'/', $_SERVER['HTTP_ORIGIN']) ) {
|
||||
foreach( $Servers as $Server ) {
|
||||
if ( preg_match('/^(https?:\/\/)?'.preg_quote($Server->Hostname(),'/').'/', $_SERVER['HTTP_ORIGIN']) ) {
|
||||
$valid = true;
|
||||
Logger::Debug("Setting Access-Controll-Allow-Origin from " . $_SERVER['HTTP_ORIGIN']);
|
||||
header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
|
||||
header('Access-Control-Allow-Headers: x-requested-with,x-request');
|
||||
break;
|
||||
|
|
|
@ -183,13 +183,12 @@ foreach ( getSkinIncludes('skin.php') as $includeFile )
|
|||
require_once $includeFile;
|
||||
|
||||
if ( ZM_OPT_USE_AUTH ) {
|
||||
if ( ZM_AUTH_HASH_LOGINS ) {
|
||||
if ( empty($user) && ! empty($_REQUEST['auth']) ) {
|
||||
if ( ZM_AUTH_HASH_LOGINS && empty($user) && ! empty($_REQUEST['auth']) ) {
|
||||
if ( $authUser = getAuthUser($_REQUEST['auth']) ) {
|
||||
userLogin($authUser['Username'], $authUser['Password'], true);
|
||||
}
|
||||
}
|
||||
} else if ( isset($_REQUEST['username']) and isset($_REQUEST['password']) ) {
|
||||
else if ( isset($_REQUEST['username']) and isset($_REQUEST['password']) ) {
|
||||
userLogin($_REQUEST['username'], $_REQUEST['password'], false);
|
||||
}
|
||||
if ( !empty($user) ) {
|
||||
|
|
|
@ -41,4 +41,3 @@ $DLANG = array(
|
|||
);
|
||||
|
||||
?>
|
||||
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
User-agent: *
|
||||
Disallow: /
|
||||
###
|
|
@ -21,7 +21,7 @@
|
|||
}
|
||||
|
||||
.ptzControls input[type=image] {
|
||||
border: 0px;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.ptzControls .controlsPanel .arrowControl {
|
||||
|
@ -115,7 +115,7 @@
|
|||
}
|
||||
|
||||
.ptzControls .controlsPanel .pantiltPanel .pantiltControls .centerBtn {
|
||||
background: url("../skins/classic/graphics/graphics/center.png") no-repeat 0 0;
|
||||
background: url("../skins/classic/graphics/center.png") no-repeat 0 0;
|
||||
}
|
||||
|
||||
.ptzControls .controlsPanel .pantiltPanel .pantiltControls .rightBtn {
|
||||
|
|
|
@ -124,6 +124,7 @@ echo output_link_if_exists( array(
|
|||
jQuery("#flip").click(function(){
|
||||
jQuery("#panel").slideToggle("slow");
|
||||
jQuery("#flip").toggleClass('glyphicon-menu-down').toggleClass('glyphicon-menu-up');
|
||||
Cookie.write( 'zmHeaderFlip', jQuery('#flip').hasClass('glyphicon-menu-up') ? 'up' : 'down', { duration: 10*365 } );
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@ -208,6 +209,9 @@ echo output_link_if_exists( array(
|
|||
} // end function xhtmlHeaders( $file, $title )
|
||||
|
||||
function getNavBarHTML($reload = null) {
|
||||
# Provide a facility to turn off the headers if you put headers=0 into the url
|
||||
if ( isset($_REQUEST['navbar']) and $_REQUEST['navbar']=='0' )
|
||||
return '';
|
||||
|
||||
$versionClass = (ZM_DYN_DB_VERSION&&(ZM_DYN_DB_VERSION!=ZM_VERSION))?'errorText':'';
|
||||
global $running;
|
||||
|
@ -303,7 +307,7 @@ if (isset($_REQUEST['filter']['Query']['terms']['attr'])) {
|
|||
}
|
||||
?>
|
||||
<li><a href="?view=report_event_audit"<?php echo $view=='report_event_audit'?' class="selected"':''?>><?php echo translate('ReportEventAudit') ?></a></li>
|
||||
<li><a href="#"><span id="flip" class="glyphicon glyphicon-menu-up pull-right"></span></a></li>
|
||||
<li><a href="#"><span id="flip" class="glyphicon glyphicon-menu-<?php echo ( isset($_COOKIE['zmHeaderFlip']) and $_COOKIE['zmHeaderFlip'] == 'down') ? 'down' : 'up' ?> pull-right"></span></a></li>
|
||||
</ul>
|
||||
<?php } // end if canView('Monitors') ?>
|
||||
|
||||
|
@ -321,7 +325,7 @@ if (isset($_REQUEST['filter']['Query']['terms']['attr'])) {
|
|||
</div>
|
||||
</div><!-- End .navbar-collapse -->
|
||||
</div> <!-- End .container-fluid -->
|
||||
<div id="panel">
|
||||
<div id="panel"<?php echo ( isset($_COOKIE['zmHeaderFlip']) and $_COOKIE['zmHeaderFlip'] == 'down' ) ? 'style="display:none;"' : '' ?>>
|
||||
<?php
|
||||
}//end reload null. Runs on full page load
|
||||
|
||||
|
@ -378,13 +382,13 @@ if ($reload == 'reload') ob_start();
|
|||
<?php } ?>
|
||||
<!-- End .footer/reload --></div>
|
||||
<?php
|
||||
if ($reload == 'reload') return( ob_get_clean() );
|
||||
if ($reload == 'reload') return ob_get_clean();
|
||||
} // end if (!ZM_OPT_USE_AUTH) or $user )
|
||||
?>
|
||||
</div>
|
||||
</div><!-- End .navbar .navbar-default -->
|
||||
<?php
|
||||
return( ob_get_clean() );
|
||||
return ob_get_clean();
|
||||
} // end function getNavBarHTML()
|
||||
|
||||
function xhtmlFooter() {
|
||||
|
|
|
@ -195,11 +195,12 @@ if ( currentView != 'none' && currentView != 'login' ) {
|
|||
$j.getJSON(thisUrl + '?view=request&request=status&entity=navBar')
|
||||
.done(setNavBar)
|
||||
.fail(function( jqxhr, textStatus, error ) {
|
||||
var err = textStatus + ", " + error;
|
||||
console.log( "Request Failed: " + err );
|
||||
console.log( "Request Failed: " + textStatus + ", " + error);
|
||||
if ( textStatus != "timeout" ) {
|
||||
// The idea is that this should only fail due to auth, so reload the page
|
||||
// which should go to login if it can't stay logged in.
|
||||
window.location.reload( true );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ foreach ( Group::find() as $G ) {
|
|||
|
||||
$groupSql = '';
|
||||
if ( count($GroupsById) ) {
|
||||
$html .= '<span id="groupControl"><label>'. translate('Group') .':</label>';
|
||||
$html .= '<span id="groupControl"><label>'. translate('Group') .'</label>';
|
||||
# This will end up with the group_id of the deepest selection
|
||||
$group_id = isset($_SESSION['Group']) ? $_SESSION['Group'] : null;
|
||||
$html .= Group::get_group_dropdown();
|
||||
|
@ -114,7 +114,7 @@ $html .= htmlSelect('Function[]', $Functions,
|
|||
$html .= '</span>';
|
||||
|
||||
if ( count($ServersById) > 1 ) {
|
||||
$html .= '<span class="ServerFilter"><label>'. translate('Server').':</label>';
|
||||
$html .= '<span class="ServerFilter"><label>'. translate('Server').'</label>';
|
||||
$html .= htmlSelect('ServerId[]', $ServersById,
|
||||
(isset($_SESSION['ServerId'])?$_SESSION['ServerId']:''),
|
||||
array(
|
||||
|
@ -128,7 +128,7 @@ if ( count($ServersById) > 1 ) {
|
|||
} # end if have Servers
|
||||
|
||||
if ( count($StorageById) > 1 ) {
|
||||
$html .= '<span class="StorageFilter"><label>'.translate('Storage').':</label>';
|
||||
$html .= '<span class="StorageFilter"><label>'.translate('Storage').'</label>';
|
||||
$html .= htmlSelect('StorageId[]', $StorageById,
|
||||
(isset($_SESSION['StorageId'])?$_SESSION['StorageId']:''),
|
||||
array(
|
||||
|
@ -140,7 +140,7 @@ if ( count($StorageById) > 1 ) {
|
|||
$html .= '</span>';
|
||||
} # end if have Storage Areas
|
||||
|
||||
$html .= '<span class="StatusFilter"><label>'. translate('Status') . ':</label>';
|
||||
$html .= '<span class="StatusFilter"><label>'. translate('Status') . '</label>';
|
||||
$status_options = array(
|
||||
'Unknown' => translate('StatusUnknown'),
|
||||
'NotRunning' => translate('StatusNotRunning'),
|
||||
|
@ -157,7 +157,7 @@ $html .= htmlSelect( 'Status[]', $status_options,
|
|||
) );
|
||||
$html .= '</span>';
|
||||
|
||||
$html .= '<span class="SourceFilter"><label>'.translate('Source').':</label>';
|
||||
$html .= '<span class="SourceFilter"><label>'.translate('Source').'</label>';
|
||||
$html .= '<input type="text" name="Source" value="'.(isset($_SESSION['Source'])?$_SESSION['Source']:'').'" onkeydown="if(event&&event.keyCode==13){this.form.submit();}" placeholder="text or regular expression"/>';
|
||||
$html .= '</span>';
|
||||
|
||||
|
@ -232,7 +232,7 @@ $html .= htmlSelect( 'Status[]', $status_options,
|
|||
$displayMonitors[] = $monitors[$i];
|
||||
} # end foreach monitor
|
||||
|
||||
$html .= '<span class="MonitorFilter"><label>'.translate('Monitor').':</label>';
|
||||
$html .= '<span class="MonitorFilter"><label>'.translate('Monitor').'</label>';
|
||||
$html .= htmlSelect('MonitorId[]', $monitors_dropdown, $selected_monitor_ids,
|
||||
array(
|
||||
'onchange'=>'this.form.submit();',
|
||||
|
|
|
@ -217,7 +217,7 @@ ob_start();
|
|||
echo '<th class="colEvents">'. $j .'</th>';
|
||||
}
|
||||
?>
|
||||
<th class="colZones"><a href="<?php echo $_SERVER['PHP_SELF'] ?>?view=zones_overview"><?php echo translate('Zones') ?></a></th>
|
||||
<th class="colZones"><?php echo translate('Zones') ?></th>
|
||||
<?php if ( canEdit('Monitors') ) { ?>
|
||||
<th class="colMark"><input type="checkbox" name="toggleCheck" value="1" onclick="toggleCheckbox(this, 'markMids[]');setButtonStates(this);"/> <?php echo translate('All') ?></th>
|
||||
<?php } ?>
|
||||
|
|
|
@ -191,7 +191,8 @@ while ( $event_row = dbFetchNext($results) ) {
|
|||
<td class="colId"><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1"> '.$event->Id().($event->Archived()?'*':'') ?></a></td>
|
||||
<td class="colName"><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1"> '.validHtmlStr($event->Name()).($event->Archived()?'*':'') ?></a></td>
|
||||
<td class="colMonitorName"><?php echo makePopupLink( '?view=monitor&mid='.$event->MonitorId(), 'zmMonitor'.$event->Monitorid(), 'monitor', $event->MonitorName(), canEdit( 'Monitors' ) ) ?></td>
|
||||
<td class="colCause"><?php echo makePopupLink( '?view=eventdetail&eid='.$event->Id(), 'zmEventDetail', 'eventdetail', validHtmlStr($event->Cause()), canEdit( 'Events' ), 'title="'.htmlspecialchars($event->Notes()).'"' ) ?></td>
|
||||
<td class="colCause"><?php echo makePopupLink( '?view=eventdetail&eid='.$event->Id(), 'zmEventDetail', 'eventdetail', validHtmlStr($event->Cause()), canEdit( 'Events' ), 'title="'.htmlspecialchars($event->Notes()).'"' ) ?>
|
||||
<?php if ($event->Notes() && ($event->Notes() != 'Forced Web: ')) echo "<br/><div class=\"small text-nowrap text-muted\">".$event->Notes()."</div>" ?></td>
|
||||
<td class="colTime"><?php echo strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->StartTime())) .
|
||||
( $event->EndTime() ? ' until ' . strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->EndTime()) ) : '' ) ?>
|
||||
</td>
|
||||
|
|
|
@ -253,7 +253,7 @@ for ( $i=0; $i < count($terms); $i++ ) {
|
|||
<td><?php echo htmlSelect( "filter[Query][terms][$i][op]", $opTypes, $term['op'] ); ?></td>
|
||||
<td>
|
||||
<input type="text" name="filter[Query][terms][<?php echo $i ?>][val]" id="filter[Query][terms][<?php echo $i ?>][val]" value="<?php echo isset($term['val'])?validHtmlStr(str_replace('T', ' ', $term['val'])):'' ?>"/>
|
||||
<script type="text/javascript">$j("[name$='\\[<?php echo $i ?>\\]\\[val\\]']").timepicker({timeFormat: "HH:mm:ss", constrainInput: falsepi}); </script>
|
||||
<script type="text/javascript">$j("[name$='\\[<?php echo $i ?>\\]\\[val\\]']").timepicker({timeFormat: "HH:mm:ss", constrainInput: false}); </script>
|
||||
</td>
|
||||
<?php
|
||||
} elseif ( $term['attr'] == 'StateId' ) {
|
||||
|
|
|
@ -3,11 +3,11 @@ var requestQueue = new Request.Queue( { concurrent: monitorData.length, stopOnFa
|
|||
function Monitor( monitorData ) {
|
||||
this.id = monitorData.id;
|
||||
this.connKey = monitorData.connKey;
|
||||
this.server_url = monitorData.server_url;
|
||||
this.url = monitorData.url;
|
||||
this.status = null;
|
||||
this.alarmState = STATE_IDLE;
|
||||
this.lastAlarmState = STATE_IDLE;
|
||||
this.streamCmdParms = this.server_url+'?view=request&request=stream&connkey='+this.connKey;
|
||||
this.streamCmdParms = 'view=request&request=stream&connkey='+this.connKey;
|
||||
this.onclick = monitorData.onclick;
|
||||
if ( auth_hash )
|
||||
this.streamCmdParms += '&auth='+auth_hash;
|
||||
|
@ -38,14 +38,14 @@ function Monitor( monitorData ) {
|
|||
console.log('onerror: ' + text + ' error:'+error);
|
||||
// Requeue, but want to wait a while.
|
||||
var streamCmdTimeout = 1000*statusRefreshTimeout;
|
||||
this.streamCmdTimer = this.streamCmdQuery.delay( streamCmdTimeout, this );
|
||||
this.streamCmdTimer = this.streamCmdQuery.delay(streamCmdTimeout, this);
|
||||
};
|
||||
this.onFailure = function( xhr ) {
|
||||
console.log('onFailure: ' + this.connKey);
|
||||
console.log(xhr );
|
||||
console.log(xhr);
|
||||
if ( ! requestQueue.hasNext("cmdReq"+this.id) ) {
|
||||
console.log("Not requeuing because there is one already");
|
||||
requestQueue.addRequest( "cmdReq"+this.id, this.streamCmdReq );
|
||||
requestQueue.addRequest("cmdReq"+this.id, this.streamCmdReq);
|
||||
}
|
||||
if ( 0 ) {
|
||||
// Requeue, but want to wait a while.
|
||||
|
@ -153,7 +153,7 @@ function Monitor( monitorData ) {
|
|||
|
||||
if ( this.type != 'WebSite' ) {
|
||||
this.streamCmdReq = new Request.JSON( {
|
||||
url: this.server_url,
|
||||
url: this.url,
|
||||
method: 'get',
|
||||
timeout: 1000+AJAX_TIMEOUT,
|
||||
onSuccess: this.getStreamCmdResponse.bind( this ),
|
||||
|
@ -402,8 +402,14 @@ function initPage() {
|
|||
jQuery("#hdrbutton").click(function(){
|
||||
jQuery("#flipMontageHeader").slideToggle("slow");
|
||||
jQuery("#hdrbutton").toggleClass('glyphicon-menu-down').toggleClass('glyphicon-menu-up');
|
||||
Cookie.write( 'zmMontageHeaderFlip', jQuery('#hdrbutton').hasClass('glyphicon-menu-up') ? 'up' : 'down', { duration: 10*365 } );
|
||||
});
|
||||
});
|
||||
if ( Cookie.read('zmMontageHeaderFlip') == 'down' ) {
|
||||
// The chosen dropdowns require the selects to be visible, so once chosen has initialized, we can hide the header
|
||||
jQuery("#flipMontageHeader").slideToggle("fast");
|
||||
jQuery("#hdrbutton").toggleClass('glyphicon-menu-down').toggleClass('glyphicon-menu-up');
|
||||
}
|
||||
|
||||
for ( var i = 0; i < monitorData.length; i++ ) {
|
||||
monitors[i] = new Monitor(monitorData[i]);
|
||||
|
@ -416,6 +422,9 @@ function initPage() {
|
|||
}
|
||||
selectLayout('#zmMontageLayout');
|
||||
|
||||
if ( 0 ) {
|
||||
// What is the purpose of this code? I think it just starts up a second ajax thread,
|
||||
//increasing the load on the server.
|
||||
for ( var i = 0; i < monitorData.length; i++ ) {
|
||||
if ( monitors[i].type == 'WebSite' )
|
||||
continue;
|
||||
|
@ -424,6 +433,7 @@ function initPage() {
|
|||
monitors[i].streamCmdQuery.delay( delay, monitors[i] );
|
||||
//monitors[i].zm_startup(delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Kick everything off
|
||||
window.addEvent( 'domready', initPage );
|
||||
|
|
|
@ -35,7 +35,7 @@ monitorData[monitorData.length] = {
|
|||
'connKey': <?php echo $monitor->connKey() ?>,
|
||||
'width': <?php echo $monitor->Width() ?>,
|
||||
'height':<?php echo $monitor->Height() ?>,
|
||||
'server_url': '<?php echo $monitor->Url() ?>',
|
||||
'url': '<?php echo $monitor->Url() ?>',
|
||||
'onclick': function(){createPopup( '?view=watch&mid=<?php echo $monitor->Id() ?>', 'zmWatch<?php echo $monitor->Id() ?>', 'watch', <?php echo reScale( $monitor->Width(), $monitor->PopupScale() ); ?>, <?php echo reScale( $monitor->Height(), $monitor->PopupScale() ); ?> );},
|
||||
'type': '<?php echo $monitor->Type() ?>',
|
||||
'refresh': '<?php echo $monitor->Refresh() ?>'
|
||||
|
|
|
@ -110,7 +110,7 @@ if ( monitorType != 'WebSite' ) {
|
|||
if ( auth_hash )
|
||||
streamCmdParms += '&auth='+auth_hash;
|
||||
var streamCmdReq = new Request.JSON( {
|
||||
url: monitorUrl+thisUrl,
|
||||
url: monitorUrl,
|
||||
method: 'get',
|
||||
timeout: AJAX_TIMEOUT,
|
||||
link: 'chain',
|
||||
|
@ -367,7 +367,7 @@ if ( monitorType != 'WebSite' ) {
|
|||
var statusCmdParms = "view=request&request=status&entity=monitor&id="+monitorId+"&element[]=Status&element[]=FrameRate";
|
||||
if ( auth_hash )
|
||||
statusCmdParms += '&auth='+auth_hash;
|
||||
var statusCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'get', data: statusCmdParms, timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getStatusCmdResponse } );
|
||||
var statusCmdReq = new Request.JSON( { url: monitorUrl, method: 'get', data: statusCmdParms, timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getStatusCmdResponse } );
|
||||
var statusCmdTimer = null;
|
||||
}
|
||||
|
||||
|
@ -397,8 +397,8 @@ if ( monitorType != 'WebSite' ) {
|
|||
if ( auth_hash )
|
||||
alarmCmdParms += '&auth='+auth_hash;
|
||||
var alarmCmdReq = new Request.JSON( {
|
||||
url: monitorUrl+thisUrl,
|
||||
method: 'post',
|
||||
url: monitorUrl,
|
||||
method: 'get',
|
||||
timeout: AJAX_TIMEOUT,
|
||||
link: 'cancel',
|
||||
onSuccess: getAlarmCmdResponse,
|
||||
|
@ -455,7 +455,15 @@ if ( monitorType != 'WebSite' ) {
|
|||
var eventCmdParms = "view=request&request=status&entity=events&id="+monitorId+"&count="+maxDisplayEvents+"&sort=Id%20desc";
|
||||
if ( auth_hash )
|
||||
eventCmdParms += '&auth='+auth_hash;
|
||||
var eventCmdReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, data: eventCmdParms, link: 'cancel', onSuccess: getEventCmdResponse, onTimeout: eventCmdQuery } );
|
||||
var eventCmdReq = new Request.JSON( {
|
||||
url: monitorUrl,
|
||||
method: 'get',
|
||||
timeout: AJAX_TIMEOUT,
|
||||
data: eventCmdParms,
|
||||
link: 'cancel',
|
||||
onSuccess: getEventCmdResponse,
|
||||
onTimeout: eventCmdQuery
|
||||
} );
|
||||
var eventCmdTimer = null;
|
||||
var eventCmdFirst = true;
|
||||
}
|
||||
|
@ -565,7 +573,7 @@ if ( monitorType != 'WebSite' ) {
|
|||
var controlParms = "view=request&request=control&id="+monitorId;
|
||||
if ( auth_hash )
|
||||
controlParms += '&auth='+auth_hash;
|
||||
var controlReq = new Request.JSON( { url: thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getControlResponse } );
|
||||
var controlReq = new Request.JSON( { url: monitorUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getControlResponse } );
|
||||
}
|
||||
|
||||
function getControlResponse( respObj, respText ) {
|
||||
|
|
|
@ -471,7 +471,13 @@ function setAlarmState( currentAlarmState ) {
|
|||
}
|
||||
|
||||
var streamCmdParms = "view=request&request=stream&connkey="+connKey;
|
||||
var streamCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getStreamCmdResponse } );
|
||||
var streamCmdReq = new Request.JSON( {
|
||||
url: monitorUrl,
|
||||
method: 'get',
|
||||
timeout: AJAX_TIMEOUT,
|
||||
link: 'cancel',
|
||||
onSuccess: getStreamCmdResponse
|
||||
} );
|
||||
var streamCmdTimer = null;
|
||||
|
||||
var streamStatus;
|
||||
|
@ -546,7 +552,14 @@ function streamCmdQuery() {
|
|||
}
|
||||
|
||||
var statusCmdParms = "view=request&request=status&entity=monitor&id="+monitorId+"&element[]=Status&element[]=FrameRate";
|
||||
var statusCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'post', data: statusCmdParms, timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getStatusCmdResponse } );
|
||||
var statusCmdReq = new Request.JSON( {
|
||||
url: monitorUrl,
|
||||
method: 'get',
|
||||
data: statusCmdParms,
|
||||
timeout: AJAX_TIMEOUT,
|
||||
link: 'cancel',
|
||||
onSuccess: getStatusCmdResponse
|
||||
} );
|
||||
var statusCmdTimer = null;
|
||||
|
||||
function getStatusCmdResponse( respObj, respText ) {
|
||||
|
@ -652,11 +665,13 @@ function initPage() {
|
|||
// Imported from watch.js and modified for new zone edit view
|
||||
//
|
||||
|
||||
var delay = (Math.random()+0.1)*statusRefreshTimeout;
|
||||
//console.log("Delay for status updates is: " + delay );
|
||||
if ( streamMode == "single" ) {
|
||||
statusCmdTimer = statusCmdQuery.delay( (Math.random()+0.1)*statusRefreshTimeout );
|
||||
statusCmdTimer = statusCmdQuery.delay( delay );
|
||||
watchdogCheck.pass('status').periodical(statusRefreshTimeout*2);
|
||||
} else {
|
||||
streamCmdTimer = streamCmdQuery.delay( (Math.random()+0.1)*statusRefreshTimeout );
|
||||
streamCmdTimer = streamCmdQuery.delay( delay );
|
||||
watchdogCheck.pass('stream').periodical(statusRefreshTimeout*2);
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ var streamMode = "<?php echo $streamMode ?>";
|
|||
var connKey = '<?php echo $connkey ?>';
|
||||
|
||||
var monitorId = <?php echo $monitor->Id() ?>;
|
||||
var monitorUrl = '<?php echo ( $monitor->Server()->Url() ) ?>';
|
||||
var monitorUrl = '<?php echo ( $monitor->Url() ) ?>';
|
||||
|
||||
var streamSrc = "<?php echo preg_replace( '/&/', '&', $streamSrc ) ?>";
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var streamCmdParms = "view=request&request=stream&connkey="+connKey;
|
||||
var streamCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel' } );
|
||||
var streamCmdReq = new Request.JSON( { url: monitorUrl, method: 'post', timeout: AJAX_TIMEOUT, link: 'cancel' } );
|
||||
|
||||
function streamCmdQuit( action ) {
|
||||
if ( action )
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var connKey = '<?php echo $connkey ?>';
|
||||
var monitorUrl = '<?php echo ( $monitor->Server()->Url() ) ?>';
|
||||
var monitorUrl = '<?php echo ( $monitor->Url() ) ?>';
|
||||
var CMD_QUIT = <?php echo CMD_QUIT ?>;
|
||||
|
||||
|
|
|
@ -45,16 +45,15 @@ xhtmlHeaders(__FILE__, translate('SystemLog') );
|
|||
<tr class="row">
|
||||
<td class="col text-center">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-sm" onclick="expandLog()"> <?php echo translate('More') ?></button>
|
||||
<button type="button" class="btn btn-sm" onclick="clearLog()"> <?php echo translate('Clear') ?></button>
|
||||
<button type="button" class="btn btn-sm" onclick="refreshLog()"> <?php echo translate('Refresh') ?></button>
|
||||
<button type="button" class="btn btn-sm" onclick="exportLog()"> <?php echo translate('Export') ?></button>
|
||||
<button type="button" class="btn btn-sm" onclick="closeWindow()"> <?php echo translate('Close') ?></button>
|
||||
<button type="button" onclick="expandLog()"><?php echo translate('More') ?></button>
|
||||
<button type="button" onclick="clearLog()"><?php echo translate('Clear') ?></button>
|
||||
<button type="button" onclick="refreshLog()"><?php echo translate('Refresh') ?></button>
|
||||
<button type="button" onclick="exportLog()"><?php echo translate('Export') ?></button>
|
||||
<button type="button" onclick="closeWindow()"><?php echo translate('Close') ?></button>
|
||||
</div> <!--btn-->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div> <!--header-->
|
||||
<div id="content">
|
||||
<div id="filters">
|
||||
|
@ -89,7 +88,7 @@ xhtmlHeaders(__FILE__, translate('SystemLog') );
|
|||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<input type="reset" value="<?php echo translate('Reset') ?>" onclick="resetLog()"/>
|
||||
<button type="reset" onclick="resetLog()"><?php echo translate('Reset') ?></button>
|
||||
</div>
|
||||
<form name="logForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
|
@ -137,8 +136,8 @@ xhtmlHeaders(__FILE__, translate('SystemLog') );
|
|||
<div id="exportError">
|
||||
<?php echo translate('ExportFailed') ?>: <span id="exportErrorText"></span>
|
||||
</div>
|
||||
<input type="button" id="exportButton" value="<?php echo translate('Export') ?>" onclick="exportRequest()"/>
|
||||
<input type="button" value="<?php echo translate('Cancel') ?>" class="overlayCloser"/>
|
||||
<button type="button" id="exportButton" value="Export" onclick="exportRequest()"><?php echo translate('Export') ?></button>
|
||||
<button type="button" value="Cancel" class="overlayCloser"><?php echo translate('Cancel') ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -135,7 +135,7 @@ xhtmlHeaders(__FILE__, translate('Montage'));
|
|||
<div id="page">
|
||||
<?php echo getNavBarHTML() ?>
|
||||
<div id="header">
|
||||
<a href="#"><span id="hdrbutton" class="glyphicon glyphicon-menu-up pull-right"></span></a>
|
||||
<a href="#"><span id="hdrbutton" class="glyphicon glyphicon-menu-up pull-right" title="Toggle Filters"></span></a>
|
||||
<div id="flipMontageHeader">
|
||||
<div id="headerButtons">
|
||||
<?php
|
||||
|
|
|
@ -225,7 +225,7 @@ xhtmlHeaders(__FILE__, translate('MontageReview') );
|
|||
<?php echo getNavBarHTML() ?>
|
||||
<form id="montagereview_form" action="<?php echo $_SERVER['PHP_SELF'] ?>" method="get">
|
||||
<input type="hidden" name="view" value="montagereview"/>
|
||||
<div id="header">  
|
||||
<div id="header">
|
||||
<a href="#"><span id="hdrbutton" class="glyphicon glyphicon-menu-up pull-right"></span></a>
|
||||
<div id="flipMontageHeader">
|
||||
<?php echo $filter_bar ?>
|
||||
|
|
|
@ -77,6 +77,23 @@ Logger::Debug("Loading by eid");
|
|||
return;
|
||||
}
|
||||
|
||||
# if alarm, get the fid of the first alarmed frame if available and let the
|
||||
# fid= code continue processing it. Sort it to get the first alarmed frame
|
||||
if ( $_REQUEST['fid'] == 'alarm' ) {
|
||||
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'], 'Type'=>'Alarm'),
|
||||
array('order'=>'FrameId ASC'));
|
||||
if ( !$Frame ) # no alarms
|
||||
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'])); # first frame
|
||||
if ( !$Frame ) {
|
||||
Warning("No frame found for event " + $_REQUEST['eid']);
|
||||
$Frame = new Frame();
|
||||
$Frame->Delta(1);
|
||||
$Frame->FrameId('snapshot');
|
||||
}
|
||||
$_REQUEST['fid']=$Frame->FrameId();
|
||||
}
|
||||
|
||||
|
||||
if ( $_REQUEST['fid'] == 'snapshot' ) {
|
||||
$Frame = Frame::find_one(array('EventId'=>$_REQUEST['eid'], 'Score'=>$Event->MaxScore()));
|
||||
if ( !$Frame )
|
||||
|
|
Loading…
Reference in New Issue