Merge branch 'master' into wip_axisv2

This commit is contained in:
Isaac Connor 2020-01-10 17:20:32 -05:00
commit 80c95d5afe
78 changed files with 1809 additions and 1636 deletions

12
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: [connortechnology,pliablepixels] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: zoneminder # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@ -33,24 +33,23 @@ install:
env: env:
- SMPFLAGS=-j4 OS=el DIST=7 - SMPFLAGS=-j4 OS=el DIST=7
- SMPFLAGS=-j4 OS=el DIST=8 - SMPFLAGS=-j4 OS=el DIST=8 DOCKER_REPO=knnniggett/packpack
- SMPFLAGS=-j4 OS=fedora DIST=29 DOCKER_REPO=knnniggett/packpack
- SMPFLAGS=-j4 OS=fedora DIST=30 - SMPFLAGS=-j4 OS=fedora DIST=30
- SMPFLAGS=-j4 OS=ubuntu DIST=trusty DOCKER_REPO=iconzm/packpack USE_SFTP=yes - SMPFLAGS=-j4 OS=fedora DIST=31
- SMPFLAGS=-j4 OS=ubuntu DIST=xenial DOCKER_REPO=iconzm/packpack USE_SFTP=yes - SMPFLAGS=-j4 OS=ubuntu DIST=trusty DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=ubuntu DIST=bionic DOCKER_REPO=iconzm/packpack USE_SFTP=yes - SMPFLAGS=-j4 OS=ubuntu DIST=xenial DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=ubuntu DIST=disco DOCKER_REPO=iconzm/packpack USE_SFTP=yes - SMPFLAGS=-j4 OS=ubuntu DIST=bionic DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=ubuntu DIST=eoan DOCKER_REPO=iconzm/packpack USE_SFTP=yes - SMPFLAGS=-j4 OS=ubuntu DIST=disco DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=debian DIST=jessie DOCKER_REPO=iconzm/packpack USE_SFTP=yes - SMPFLAGS=-j4 OS=ubuntu DIST=eoan DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=debian DIST=stretch DOCKER_REPO=iconzm/packpack USE_SFTP=yes - SMPFLAGS=-j4 OS=debian DIST=jessie DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=debian DIST=buster DOCKER_REPO=iconzm/packpack USE_SFTP=yes - SMPFLAGS=-j4 OS=debian DIST=stretch DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=debian DIST=buster DOCKER_REPO=iconzm/packpack
- SMPFLAGS=-j4 OS=ubuntu DIST=trusty ARCH=i386 - SMPFLAGS=-j4 OS=ubuntu DIST=trusty ARCH=i386
- SMPFLAGS=-j4 OS=ubuntu DIST=xenial ARCH=i386 - SMPFLAGS=-j4 OS=ubuntu DIST=xenial ARCH=i386
- SMPFLAGS=-j4 OS=ubuntu DIST=bionic ARCH=i386
- SMPFLAGS=-j4 OS=ubuntu DIST=disco ARCH=i386 - SMPFLAGS=-j4 OS=ubuntu DIST=disco ARCH=i386
- SMPFLAGS=-j4 OS=debian DIST=buster ARCH=i386 - SMPFLAGS=-j4 OS=debian DIST=buster ARCH=i386
- SMPFLAGS=-j4 OS=debian DIST=stretch ARCH=i386 - SMPFLAGS=-j4 OS=debian DIST=stretch ARCH=i386
- SMPFLAGS=-j4 OS=raspbian DIST=stretch ARCH=armhf DOCKER_REPO=knnniggett/packpack - SMPFLAGS=-j4 OS=eslint DIST=eslint
compiler: compiler:
- gcc - gcc
@ -58,12 +57,6 @@ services:
- mysql - mysql
- docker - docker
jobs:
include:
- name: eslint
install: npm install -g eslint@5.12.0 eslint-config-google@0.11.0 eslint-plugin-html@5.0.0 eslint-plugin-php-markup@0.2.5
script: eslint --ext .php,.js .
script: script:
- utils/packpack/startpackpack.sh - utils/packpack/startpackpack.sh

View File

@ -1,9 +1,10 @@
ZoneMinder ZoneMinder
========== ==========
[![Build Status](https://travis-ci.org/ZoneMinder/zoneminder.png)](https://travis-ci.org/ZoneMinder/zoneminder) [![Bountysource](https://api.bountysource.com/badge/team?team_id=204&style=bounties_received)](https://www.bountysource.com/teams/zoneminder/issues?utm_source=ZoneMinder&utm_medium=shield&utm_campaign=bounties_received) [![Build Status](https://travis-ci.org/ZoneMinder/zoneminder.png)](https://travis-ci.org/ZoneMinder/zoneminder)
[![Bounty Source](https://api.bountysource.com/badge/team?team_id=204&style=bounties_received)](https://www.bountysource.com/teams/zoneminder/issues?utm_source=ZoneMinder&utm_medium=shield&utm_campaign=bounties_received)
[![Join Slack](https://github.com/ozonesecurity/ozonebase/blob/master/img/slacksm.png?raw=true)](https://join.slack.com/t/zoneminder-chat/shared_invite/enQtNTU0NDkxMDM5NDQwLTdhZmQ5Y2M2NWQyN2JkYTBiN2ZkMzIzZGQ0MDliMTRmM2FjZWRlYzUwYTQ2MjMwMTVjMzQ1NjYxOTdmMjE2MTE) [![Join Slack](https://github.com/ozonesecurity/ozonebase/blob/master/img/slacksm.png?raw=true)](https://join.slack.com/t/zoneminder-chat/shared_invite/enQtNTU0NDkxMDM5NDQwLTdhZmQ5Y2M2NWQyN2JkYTBiN2ZkMzIzZGQ0MDliMTRmM2FjZWRlYzUwYTQ2MjMwMTVjMzQ1NjYxOTdmMjE2MTE)
[![IRC Network](https://img.shields.io/badge/irc-%23zoneminder-blue.svg "IRC Freenode")](https://webchat.freenode.net/?channels=zoneminder)
All documentation for ZoneMinder is now online at https://zoneminder.readthedocs.org All documentation for ZoneMinder is now online at https://zoneminder.readthedocs.org

View File

@ -434,6 +434,7 @@ DROP TABLE IF EXISTS `Monitors`;
CREATE TABLE `Monitors` ( CREATE TABLE `Monitors` (
`Id` int(10) unsigned NOT NULL auto_increment, `Id` int(10) unsigned NOT NULL auto_increment,
`Name` varchar(64) NOT NULL default '', `Name` varchar(64) NOT NULL default '',
`Notes` TEXT,
`ServerId` int(10) unsigned, `ServerId` int(10) unsigned,
`StorageId` smallint(5) unsigned default 0, `StorageId` smallint(5) unsigned default 0,
`Type` enum('Local','Remote','File','Ffmpeg','Libvlc','cURL','WebSite','NVSocket') NOT NULL default 'Local', `Type` enum('Local','Remote','File','Ffmpeg','Libvlc','cURL','WebSite','NVSocket') NOT NULL default 'Local',

12
db/zm_update-1.33.16.sql Normal file
View File

@ -0,0 +1,12 @@
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Monitors'
AND column_name = 'Notes'
) > 0,
"SELECT 'Column Notes already exists in Monitors'",
"ALTER TABLE `Monitors` ADD `Notes` TEXT AFTER `Name`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -22,14 +22,10 @@ What's New
switching between httpd <-> nginx requires manaully changing ownership of switching between httpd <-> nginx requires manaully changing ownership of
all event folders and the php session folder after the change. all event folders and the php session folder after the change.
4. If you have installed ZoneMinder from the FedBerry repositories, this build 4. The timezone must now be set from the ZoneMinder web console. See the
of ZoneMinder has support for Raspberry Pi hardware acceleration when using appropriate README, mentioned in the next step, for details.
ffmpeg. Unforunately, there is a problem with the same hardware acceleration
when using libvlc. Consequently, libvlc support in this build of ZoneMinder
has been disabled until the problem is resolved. See the following bug
report for details: https://trac.videolan.org/vlc/ticket/18594
5. Continue on to the next README that corresponds to the chosen webserver: 6. Continue on to the next README that corresponds to your chosen webserver:
README.httpd - Follow these steps when using Apache README.httpd - Follow these steps when using Apache
README.nginx - Follow these steps when using Nginx README.nginx - Follow these steps when using Nginx

View File

@ -36,20 +36,17 @@ NOTE: EL7 users should replace "dnf" with "yum" in the instructions below.
sudo chown root:apache *.conf sudo chown root:apache *.conf
sudo chmod 640 *.conf sudo chmod 640 *.conf
4. Edit /etc/php.ini, uncomment the date.timezone line, and add your local 4. Manually setting the timezone in /etc/php.ini is deprecated.
timezone. PHP will complain loudly if this is not set, or if it is set
incorrectly, and these complaints will show up in the zoneminder logging
system as errors.
If you are not sure of the proper timezone specification to use, look at Instead, navigate to Options -> System from the ZoneMinder web console.
http://php.net/date.timezone Do this after completing step 10, below.
Note that timezone errors will appear in the ZoneMinder log until this
has been completed.
5. Disable SELinux 5. Disable SELinux
We currently do not have the resources to create and maintain an accurate SELinux must be disabled or put into permissive mode. This is not optional!
SELinux policy for ZoneMinder on Fedora. We will gladly accept pull
reqeusts from anyone who wishes to do the work. In the meantime, SELinux
will need to be disabled or put into permissive mode.
To immediately disbale SELinux for the current seesion, issue the following To immediately disbale SELinux for the current seesion, issue the following
from the command line: from the command line:
@ -166,3 +163,11 @@ Upgrades
sudo systemctl restart httpd sudo systemctl restart httpd
sudo systemctl start zoneminder sudo systemctl start zoneminder
6. Manually setting the timezone in /etc/php.ini is deprecated.
Instead, navigate to Options -> System from the ZoneMinder web console.
Do this now.
Note that timezone errors will appear in the ZoneMinder log until this
has been completed.

View File

@ -34,13 +34,13 @@ New installs
sudo chown root:nginx *.conf sudo chown root:nginx *.conf
sudo chmod 640 *.conf sudo chmod 640 *.conf
4. Edit /etc/php.ini, uncomment the date.timezone line, and add your local 4. Manually setting the timezone in /etc/php.ini is deprecated.
timezone. PHP will complain loudly if this is not set, or if it is set
incorrectly, and these complaints will show up in the zoneminder logging
system as errors.
If you are not sure of the proper timezone specification to use, look at Instead, navigate to Options -> System from the ZoneMinder web console.
http://php.net/date.timezone Do this after completing step 10, below.
Note that timezone errors will appear in the ZoneMinder log until this
has been completed.
5. Disable SELinux 5. Disable SELinux
@ -169,3 +169,11 @@ Upgrades
sudo systemctl restart php-fpm sudo systemctl restart php-fpm
sudo systemctl start zoneminder sudo systemctl start zoneminder
6. Manually setting the timezone in /etc/php.ini is deprecated.
Instead, navigate to Options -> System from the ZoneMinder web console.
Do this now.
Note that timezone errors will appear in the ZoneMinder log until this
has been completed.

View File

@ -14,16 +14,21 @@
# This will tell zoneminder's cmake process we are building against a known distro # This will tell zoneminder's cmake process we are building against a known distro
%global zmtargetdistro %{?rhel:el%{rhel}}%{!?rhel:fc%{fedora}} %global zmtargetdistro %{?rhel:el%{rhel}}%{!?rhel:fc%{fedora}}
# Fedora >= 25 needs apcu backwards compatibility module # Fedora needs apcu backwards compatibility module
%if 0%{?fedora} >= 25 %if 0%{?fedora}
%global with_apcu_bc 1 %global with_apcu_bc 1
%endif %endif
# Newer php's keep json functions in a subpackage
%if 0%{?fedora} || 0%{?rhel} >= 8
%global with_php_json 1
%endif
# The default for everything but el7 these days # The default for everything but el7 these days
%global _hardened_build 1 %global _hardened_build 1
Name: zoneminder Name: zoneminder
Version: 1.33.14 Version: 1.33.16
Release: 1%{?dist} Release: 1%{?dist}
Summary: A camera monitoring and analysis tool Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons Group: System Environment/Daemons
@ -105,7 +110,7 @@ Summary: Common files for ZoneMinder, not tied to a specific web server
Requires: php-mysqli Requires: php-mysqli
Requires: php-common Requires: php-common
Requires: php-gd Requires: php-gd
%{?fedora:Requires: php-json} %{?with_php_json:Requires: php-json}
Requires: php-pecl-apcu Requires: php-pecl-apcu
%{?with_apcu_bc:Requires: php-pecl-apcu-bc} %{?with_apcu_bc:Requires: php-pecl-apcu-bc}
Requires: cambozola Requires: cambozola
@ -411,6 +416,9 @@ EOF
%dir %attr(755,nginx,nginx) %{_localstatedir}/spool/zoneminder-upload %dir %attr(755,nginx,nginx) %{_localstatedir}/spool/zoneminder-upload
%changelog %changelog
* Sun Dec 08 2019 Isaac Connor <isaac@zoneminder.com> - 1.33.15-1
- Bump to 1.33.15 Development
* Sun Aug 11 2019 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.14-1 * Sun Aug 11 2019 Andrew Bauer <zonexpertconsulting@outlook.com> - 1.33.14-1
- Bump to 1.33.13 Development - Bump to 1.33.13 Development

View File

@ -1,10 +1,3 @@
# Remember to enable cgi mod (i.e. "a2enmod cgi").
ScriptAlias /zm/cgi-bin "/usr/lib/zoneminder/cgi-bin"
<Directory "/usr/lib/zoneminder/cgi-bin">
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
AllowOverride All
Require all granted
</Directory>
# Order matters. This alias must come first. # Order matters. This alias must come first.
Alias /zm/cache /var/cache/zoneminder/cache Alias /zm/cache /var/cache/zoneminder/cache
@ -30,6 +23,14 @@ Alias /zm /usr/share/zoneminder/www
</IfModule> </IfModule>
</Directory> </Directory>
# Remember to enable cgi mod (i.e. "a2enmod cgi").
ScriptAlias /zm/cgi-bin "/usr/lib/zoneminder/cgi-bin"
<Directory "/usr/lib/zoneminder/cgi-bin">
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
AllowOverride All
Require all granted
</Directory>
# For better visibility, the following directives have been migrated from the # For better visibility, the following directives have been migrated from the
# default .htaccess files included with the CakePHP project. # default .htaccess files included with the CakePHP project.
# Parameters not set here are inherited from the parent directive above. # Parameters not set here are inherited from the parent directive above.

View File

@ -61,7 +61,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
,libjson-maybexs-perl ,libjson-maybexs-perl
,libsys-mmap-perl [!hurd-any] ,libsys-mmap-perl [!hurd-any]
,liburi-encode-perl ,liburi-encode-perl
,libwww-perl ,libwww-perl, liburi-perl
,libdata-dump-perl ,libdata-dump-perl
,libdatetime-perl ,libdatetime-perl
,libclass-std-fast-perl ,libclass-std-fast-perl
@ -74,7 +74,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
,libfile-slurp-perl ,libfile-slurp-perl
,mysql-client | mariadb-client | virtual-mysql-client ,mysql-client | mariadb-client | virtual-mysql-client
,perl-modules ,perl-modules
,php5-mysql | php-mysql, php5-gd | php-gd , php5-apcu | php-apcu , php-apc | php-apcu-bc ,php5-mysql | php-mysql, php5-gd | php-gd , php5-apcu | php-apcu , php-apc | php-apcu-bc, php-json | php5-json
,policykit-1 ,policykit-1
,rsyslog | system-log-daemon ,rsyslog | system-log-daemon
,zip ,zip

View File

@ -28,3 +28,4 @@ zmtelemetry\[[[:digit:]]+\]: INF \[Telemetry data uploaded successfully.\]$
zmtelemetry\[[[:digit:]]+\]: INF \[Sending data to ZoneMinder Telemetry server.\]$ zmtelemetry\[[[:digit:]]+\]: INF \[Sending data to ZoneMinder Telemetry server.\]$
zmtelemetry\[[[:digit:]]+\]: INF \[Collec?ting data to send to ZoneMinder Telemetry server.\]$ zmtelemetry\[[[:digit:]]+\]: INF \[Collec?ting data to send to ZoneMinder Telemetry server.\]$
web_php\[[[:digit:]]+\]: INF \[Login successful for user "[[:alnum:]]+"\]$ web_php\[[[:digit:]]+\]: INF \[Login successful for user "[[:alnum:]]+"\]$
zmeventnotification\[[[:digit:]]+\]: INF

View File

@ -1127,7 +1127,7 @@ our @options = (
}, },
{ {
name => 'ZM_LOG_LEVEL_FILE', name => 'ZM_LOG_LEVEL_FILE',
default => '-5', default => '1',
description => 'Save logging output to component files', description => 'Save logging output to component files',
help => q` help => q`
ZoneMinder logging is now more integrated between ZoneMinder logging is now more integrated between
@ -1312,7 +1312,7 @@ our @options = (
}, },
{ {
name => 'ZM_LOG_DEBUG_FILE', name => 'ZM_LOG_DEBUG_FILE',
default => '@ZM_LOGDIR@/zm_debug.log+', default => '',
description => 'Where extra debug is output to', description => 'Where extra debug is output to',
help => q` help => q`
This option allows you to specify a different target for debug This option allows you to specify a different target for debug
@ -2468,7 +2468,7 @@ our @options = (
}, },
{ {
name => 'ZM_WATCH_MAX_DELAY', name => 'ZM_WATCH_MAX_DELAY',
default => '5', default => '45',
description => 'The maximum delay allowed since the last captured image', description => 'The maximum delay allowed since the last captured image',
help => q` help => q`
The zmwatch daemon checks the image capture performance of the The zmwatch daemon checks the image capture performance of the

View File

@ -1,6 +1,6 @@
# ========================================================================== # ==========================================================================
# #
# ZoneMinder Acrest HTTP API Control Protocol Module, 20180214, Rev 3.0 # ZoneMinder Amcrest HTTP API Control Protocol Module, 20180214, Rev 3.0
# #
# Change Log # Change Log
# #
@ -38,6 +38,7 @@ use Time::HiRes qw( usleep );
require ZoneMinder::Base; require ZoneMinder::Base;
require ZoneMinder::Control; require ZoneMinder::Control;
require LWP::UserAgent;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
@ -50,130 +51,109 @@ our @ISA = qw(ZoneMinder::Control);
use ZoneMinder::Logger qw(:all); use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
sub new sub new {
{
my $class = shift; my $class = shift;
my $id = shift; my $id = shift;
my $self = ZoneMinder::Control->new($id); my $self = ZoneMinder::Control->new($id);
bless($self, $class); bless($self, $class);
srand( time() );
return $self; return $self;
} }
our $AUTOLOAD; sub open {
sub AUTOLOAD
{
my $self = shift;
my $class = ref($self) || croak( "$self not object" );
my $name = $AUTOLOAD;
$name =~ s/.*://;
Debug( "Received command: $name" );
if ( exists($self->{$name}) )
{
return( $self->{$name} );
}
Fatal( "Can't access $name member of object of class $class" );
}
sub open
{
my $self = shift; my $self = shift;
$self->loadMonitor(); $self->loadMonitor();
my $username;
my $password;
my $realm = 'Login to ' . $self->{Monitor}->{ControlDevice};
if ( $self->{Monitor}->{ControlAddress} =~ /(.*):(.*)@(.*)/ ) {
$username = $1;
$password = $2;
$$self{address} = $3;
}
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->credentials($$self{address}, $realm, $username, $password);
$self->{ua}->agent('ZoneMinder Control Agent/'.ZoneMinder::Base::ZM_VERSION);
# Detect REALM
my $res = $self->{ua}->get($$self{address}.'/cgi-bin/ptz.cgi');
if ( $res->is_success ) {
$self->{state} = 'open';
return;
}
if ( $res->status_line() eq '401 Unauthorized' ) {
my $headers = $res->headers();
foreach my $k ( keys %$headers ) {
Debug("Initial Header $k => $$headers{$k}");
}
if ( $$headers{'www-authenticate'} ) {
my ( $auth, $tokens ) = $$headers{'www-authenticate'} =~ /^(\w+)\s+(.*)$/;
if ( $tokens =~ /\w+="([^"]+)"/i ) {
if ( $realm ne $1 ) {
$realm = $1;
Debug("Changing REALM to $realm");
$self->{ua}->credentials($$self{address}, $realm, $username, $password);
$res = $self->{ua}->get($$self{address}.'/cgi-bin/ptz.cgi');
if ( $res->is_success() ) {
$self->{state} = 'open';
return;
}
Error('Authentication still failed after updating REALM' . $res->status_line);
$headers = $res->headers();
foreach my $k ( keys %$headers ) {
Debug("Initial Header $k => $$headers{$k}");
} # end foreach
} else {
Error('Authentication failed, not a REALM problem');
}
} else {
Error('Failed to match realm in tokens');
} # end if
} else {
Debug('No headers line');
} # end if headers
} # end if $res->status_line() eq '401 Unauthorized'
$self->{state} = 'open'; $self->{state} = 'open';
} }
sub initUA sub close {
{
my $self = shift;
my $user = undef;
my $password = undef;
my $address = undef;
if ( $self->{Monitor}->{ControlAddress} =~ /(.*):(.*)@(.*)/ )
{
$user = $1;
$password = $2;
$address = $3;
}
use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->credentials("$address", "Login to " . $self->{Monitor}->{ControlDevice}, "$user", "$password");
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION );
}
sub destroyUA
{
my $self = shift;
$self->{ua} = undef;
}
sub close
{
my $self = shift; my $self = shift;
$self->{state} = 'closed'; $self->{state} = 'closed';
} }
sub printMsg sub sendCmd {
{
my $self = shift;
my $msg = shift;
my $msg_len = length($msg);
Debug( $msg."[".$msg_len."]" );
}
sub sendCmd
{
my $self = shift; my $self = shift;
my $cmd = shift; my $cmd = shift;
my $result = undef; my $result = undef;
destroyUA($self); $self->printMsg($cmd, 'Tx');
initUA($self);
my $user = undef; my $req = HTTP::Request->new( GET=>"http://$$self{address}/$cmd" );
my $password = undef;
my $address = undef;
if ( $self->{Monitor}->{ControlAddress} =~ /(.*):(.*)@(.*)/ )
{
$user = $1;
$password = $2;
$address = $3;
}
printMsg( $cmd, "Tx" );
my $req = HTTP::Request->new( GET=>"http://$address/$cmd" );
my $res = $self->{ua}->request($req); my $res = $self->{ua}->request($req);
if ( $res->is_success ) if ( $res->is_success ) {
{
$result = !undef; $result = !undef;
# Command to camera appears successful, write Info item to log # Command to camera appears successful, write Info item to log
Info( "Camera control: '".$res->status_line()."' for URL ".$self->{Monitor}->{ControlAddress}."/$cmd" ); Info('Camera control: \''.$res->status_line().'\' for URL '.$self->{Monitor}->{ControlAddress}.'/'.$cmd);
# TODO: Add code to retrieve $res->message_decode or some such. Then we could do things like check the camera status. # TODO: Add code to retrieve $res->message_decode or some such. Then we could do things like check the camera status.
} } else {
else Error('Camera control command FAILED: \''.$res->status_line().'\' for URL '.$self->{Monitor}->{ControlAddress}.'/'.$cmd);
{
Error( "Camera control command FAILED: '".$res->status_line()."' for URL ".$self->{Monitor}->{ControlAddress}."/$cmd" );
} }
return( $result ); return $result;
} }
sub reset sub reset {
{
my $self = shift; my $self = shift;
# This reboots the camera effectively resetting it # This reboots the camera effectively resetting it
Debug( "Camera Reset" );
$self->sendCmd('cgi-bin/magicBox.cgi?action=reboot'); $self->sendCmd('cgi-bin/magicBox.cgi?action=reboot');
##FIXME: Exit is a bad idea as it appears to cause zmc to run away.
#Exit (0);
} }
# NOTE: I'm putting this in, but absolute camera movement does not seem to be well supported in the classic skin ATM. # NOTE: I'm putting this in, but absolute camera movement does not seem to be well supported in the classic skin ATM.
@ -188,79 +168,71 @@ sub moveAbs ## Up, Down, Left, Right, etc. ??? Doesn't make sense here...
my $pan_degrees = shift || 0; my $pan_degrees = shift || 0;
my $tilt_degrees = shift || 0; my $tilt_degrees = shift || 0;
my $speed = shift || 1; my $speed = shift || 1;
Debug( "Move ABS" ); Debug('Move ABS');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1='.$pan_degrees.'&arg2='.$tilt_degrees.'&arg3=0&arg4='.$speed); $self->sendCmd('cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1='.$pan_degrees.'&arg2='.$tilt_degrees.'&arg3=0&arg4='.$speed);
} }
sub moveConUp sub moveConUp {
{
my $self = shift; my $self = shift;
Debug( "Move Up" ); Debug('Move Up');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=Up&channel=0&arg1=0&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&code=Up&channel=0&arg1=0&arg2=1&arg3=0');
usleep(500); ##XXX Should this be passed in as a "speed" parameter? usleep(500); ##XXX Should this be passed in as a "speed" parameter?
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=Up&channel=0&arg1=0&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=Up&channel=0&arg1=0&arg2=1&arg3=0');
} }
sub moveConDown sub moveConDown {
{
my $self = shift; my $self = shift;
Debug( "Move Down" ); Debug('Move Down');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=Down&channel=0&arg1=0&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&code=Down&channel=0&arg1=0&arg2=1&arg3=0');
usleep(500); usleep(500);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=Down&channel=0&arg1=0&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=Down&channel=0&arg1=0&arg2=1&arg3=0');
} }
sub moveConLeft sub moveConLeft {
{
my $self = shift; my $self = shift;
Debug( "Move Left" ); Debug('Move Left');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=Left&channel=0&arg1=0&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&code=Left&channel=0&arg1=0&arg2=1&arg3=0');
usleep(500); usleep(500);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=Left&channel=0&arg1=0&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=Left&channel=0&arg1=0&arg2=1&arg3=0');
} }
sub moveConRight sub moveConRight {
{
my $self = shift; my $self = shift;
Debug( "Move Right" ); Debug('Move Right');
# $self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1=270&arg2=5&arg3=0' ); # $self->sendCmd( 'cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1=270&arg2=5&arg3=0' );
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=Right&channel=0&arg1=0&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&code=Right&channel=0&arg1=0&arg2=1&arg3=0');
usleep(500); usleep(500);
Debug( "Move Right Stop" ); Debug('Move Right Stop');
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=Right&channel=0&arg1=0&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=Right&channel=0&arg1=0&arg2=1&arg3=0');
} }
sub moveConUpRight sub moveConUpRight {
{
my $self = shift; my $self = shift;
Debug( "Move Diagonally Up Right" ); Debug('Move Diagonally Up Right');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=RightUp&channel=0&arg1=1&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&code=RightUp&channel=0&arg1=1&arg2=1&arg3=0');
usleep(500); usleep(500);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=RightUp&channel=0&arg1=0&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=RightUp&channel=0&arg1=0&arg2=1&arg3=0');
} }
sub moveConDownRight sub moveConDownRight {
{
my $self = shift; my $self = shift;
Debug( "Move Diagonally Down Right" ); Debug('Move Diagonally Down Right');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=RightDown&channel=0&arg1=1&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&code=RightDown&channel=0&arg1=1&arg2=1&arg3=0');
usleep(500); usleep(500);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=RightDown&channel=0&arg1=0&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=RightDown&channel=0&arg1=0&arg2=1&arg3=0');
} }
sub moveConUpLeft sub moveConUpLeft {
{
my $self = shift; my $self = shift;
Debug( "Move Diagonally Up Left" ); Debug('Move Diagonally Up Left');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=LeftUp&channel=0&arg1=1&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&code=LeftUp&channel=0&arg1=1&arg2=1&arg3=0');
usleep(500); usleep(500);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=LeftUp&channel=0&arg1=0&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=LeftUp&channel=0&arg1=0&arg2=1&arg3=0');
} }
sub moveConDownLeft sub moveConDownLeft {
{
my $self = shift; my $self = shift;
Debug( "Move Diagonally Down Left" ); Debug('Move Diagonally Down Left');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=LeftDown&channel=0&arg1=1&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&code=LeftDown&channel=0&arg1=1&arg2=1&arg3=0');
usleep (500); usleep (500);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=LeftDown&channel=0&arg1=0&arg2=1&arg3=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=stop&code=LeftDown&channel=0&arg1=0&arg2=1&arg3=0');
@ -270,10 +242,9 @@ sub moveConDownLeft
# So we'll just send the camera to 0* Horz, 0* Vert, zoom out; Also, Amcrest does not seem to # So we'll just send the camera to 0* Horz, 0* Vert, zoom out; Also, Amcrest does not seem to
# support a generic stop-all-current-action command. # support a generic stop-all-current-action command.
sub moveStop sub moveStop {
{
my $self = shift; my $self = shift;
Debug( "Move Stop/Center" ); Debug('Move Stop/Center');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1=0&arg2=0&arg3=0&arg4=1'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1=0&arg2=0&arg3=0&arg4=1');
} }
@ -281,15 +252,13 @@ sub moveStop
# The current API does not support a Home per se, so we'll just send the camera to preset #1 # The current API does not support a Home per se, so we'll just send the camera to preset #1
# NOTE: It goes without saying that the user must have set up preset #1 for this to work. # NOTE: It goes without saying that the user must have set up preset #1 for this to work.
sub presetHome sub presetHome {
{
my $self = shift; my $self = shift;
Debug( "Home Preset" ); Debug('Home Preset');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=GotoPreset&&arg1=0&arg2=1&arg3=0&arg4=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=GotoPreset&&arg1=0&arg2=1&arg3=0&arg4=0');
} }
sub presetGoto sub presetGoto {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $preset = $self->getParam($params, 'preset'); my $preset = $self->getParam($params, 'preset');
@ -297,19 +266,17 @@ sub presetGoto
$self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=GotoPreset&&arg1=0&arg2='.$preset.'&arg3=0&arg4=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=GotoPreset&&arg1=0&arg2='.$preset.'&arg3=0&arg4=0');
} }
sub presetSet sub presetSet {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $preset = $self->getParam($params, 'preset'); my $preset = $self->getParam($params, 'preset');
Debug( "Set Preset" ); Debug('Set Preset');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=SetPreset&arg1=0&arg2='.$preset.'&arg3=0&arg4=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=SetPreset&arg1=0&arg2='.$preset.'&arg3=0&arg4=0');
} }
# NOTE: This does not appear to be implemented in the classic skin. But we'll leave it here for later. # NOTE: This does not appear to be implemented in the classic skin. But we'll leave it here for later.
sub moveMap sub moveMap {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
@ -325,19 +292,17 @@ sub moveMap
$self->sendCmd('cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1='.$pan.'&arg2='.$tilt.'&arg3=1&arg4=1'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&code=PositionABS&channel=0&arg1='.$pan.'&arg2='.$tilt.'&arg3=1&arg4=1');
} }
sub zoomConTele sub zoomConTele {
{
my $self = shift; my $self = shift;
Debug( "Zoom continuous tele" ); Debug('Zoom continuous tele');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=ZoomTele&arg1=0&arg2=0&arg3=0&arg4=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=ZoomTele&arg1=0&arg2=0&arg3=0&arg4=0');
usleep(100000); usleep(100000);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&channel=0&code=ZoomTele&arg1=0&arg2=0&arg3=0&arg4=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=stop&channel=0&code=ZoomTele&arg1=0&arg2=0&arg3=0&arg4=0');
} }
sub zoomConWide sub zoomConWide {
{
my $self = shift; my $self = shift;
Debug( "Zoom continuous wide" ); Debug('Zoom continuous wide');
$self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=ZoomWide&arg1=0&arg2=0&arg3=0&arg4=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=start&channel=0&code=ZoomWide&arg1=0&arg2=0&arg3=0&arg4=0');
usleep (100000); usleep (100000);
$self->sendCmd('cgi-bin/ptz.cgi?action=stop&channel=0&code=ZoomWide&arg1=0&arg2=0&arg3=0&arg4=0'); $self->sendCmd('cgi-bin/ptz.cgi?action=stop&channel=0&code=ZoomWide&arg1=0&arg2=0&arg3=0&arg4=0');

View File

@ -1,6 +1,6 @@
# ========================================================================== # ==========================================================================
# #
# ZoneMinder Axis version 2 API Control Protocol Module, $Date$, $Revision$ # ZoneMinder Axis version 2 API Control Protocol Module
# Copyright (C) 2001-2008 Philip Coombes # Copyright (C) 2001-2008 Philip Coombes
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
@ -33,12 +33,6 @@ require ZoneMinder::Control;
our @ISA = qw(ZoneMinder::Control); our @ISA = qw(ZoneMinder::Control);
our $REALM = '';
our $PROTOCOL = 'http://';
our $USERNAME = 'admin';
our $PASSWORD = '';
our $ADDRESS = '';
our $PORT = '';
# ========================================================================== # ==========================================================================
# #
# Axis V2 Control Protocol # Axis V2 Control Protocol
@ -51,39 +45,27 @@ use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep ); use Time::HiRes qw( usleep );
use URI; use URI;
our $ADDRESS;
sub open { sub open {
my $self = shift; my $self = shift;
$self->loadMonitor(); $self->loadMonitor();
my $uri = URI->new($self->{Monitor}->{ControlAddress}); my $uri = URI->new($self->{Monitor}->{ControlAddress});
Debug("Have " . $uri);
#my($scheme, $authority, $path, $query, $fragment) =
# $self->{Monitor}->{ControlAddress} =~ m|(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?|;
#Debug("Have $scheme, $authority, $path, $query, $fragment)");
# $PROTOCOL = $scheme;
#($USERNAME, $PASSWORD) = split(':', $authority);
# $ADDRESS = $path;
$ADDRESS = $uri->scheme.'://'.$uri->host().$uri->path().($uri->port()?':'.$uri->port():''); $ADDRESS = $uri->scheme.'://'.$uri->host().$uri->path().($uri->port()?':'.$uri->port():'');
Debug($uri->authority());
use LWP::UserAgent; use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new; $self->{ua} = LWP::UserAgent->new;
$self->{ua}->cookie_jar( {} ); $self->{ua}->cookie_jar( {} );
$self->{ua}->agent('ZoneMinder Control Agent/'.ZoneMinder::Base::ZM_VERSION); $self->{ua}->agent('ZoneMinder Control Agent/'.ZoneMinder::Base::ZM_VERSION);
$self->{state} = 'closed'; $self->{state} = 'closed';
# credentials: ("ip:port" (no prefix!), realm (string), username (string), password (string)
Debug("sendCmd credentials control address:'".$ADDRESS
."' realm:'".$REALM
."' username:'".$USERNAME
."' password:'".$PASSWORD
."'"
);
$self->{ua}->credentials($ADDRESS, $REALM, $USERNAME, $PASSWORD);
# Detect REALM my ( $username, $password, $host ) = ( $uri->authority() =~ /^([^:]+):([^@]*)@(.+)$/ );
my $realm = $self->{Monitor}->{ControlDevice};
$self->{ua}->credentials($ADDRESS, $realm, $username, $password);
# test auth
my $res = $self->{ua}->get($ADDRESS.'/cgi/ptdc.cgi'); my $res = $self->{ua}->get($ADDRESS.'/cgi/ptdc.cgi');
if ( $res->is_success ) { if ( $res->is_success ) {
@ -99,13 +81,13 @@ Debug($uri->authority());
} }
if ( $$headers{'www-authenticate'} ) { if ( $$headers{'www-authenticate'} ) {
Debug("Authenticating"); Debug('Authenticating');
my ( $auth, $tokens ) = $$headers{'www-authenticate'} =~ /^(\w+)\s+(.*)$/; my ( $auth, $tokens ) = $$headers{'www-authenticate'} =~ /^(\w+)\s+(.*)$/;
if ( $tokens =~ /\w+="([^"]+)"/i ) { if ( $tokens =~ /\w+="([^"]+)"/i ) {
if ( $REALM ne $1 ) { if ( $realm ne $1 ) {
$REALM = $1; $realm = $1;
Debug("Changing REALM to $REALM"); Debug("Changing REALM to $realm");
$self->{ua}->credentials($ADDRESS,$REALM,$USERNAME,$PASSWORD); $self->{ua}->credentials($host, $realm, $username, $password);
$res = $self->{ua}->get($ADDRESS); $res = $self->{ua}->get($ADDRESS);
if ( $res->is_success() ) { if ( $res->is_success() ) {
$self->{state} = 'open'; $self->{state} = 'open';
@ -154,52 +136,53 @@ sub cameraReset {
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub moveConUp sub moveConUp {
{
my $self = shift; my $self = shift;
Debug( "Move Up" ); Debug('Move Up');
my $cmd = "/axis-cgi/com/ptz.cgi?move=up"; my $cmd = '/axis-cgi/com/ptz.cgi?move=up';
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub moveConDown sub moveConDown {
{
my $self = shift; my $self = shift;
Debug( "Move Down" ); Debug('Move Down');
my $cmd = "/axis-cgi/com/ptz.cgi?move=down"; my $cmd = '/axis-cgi/com/ptz.cgi?move=down';
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub moveConLeft sub moveConLeft {
{
my $self = shift; my $self = shift;
Debug( "Move Left" ); Debug('Move Left');
my $cmd = "/axis-cgi/com/ptz.cgi?move=left"; my $cmd = '/axis-cgi/com/ptz.cgi?move=left';
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub moveConRight { sub moveConRight {
my $self = shift; my $self = shift;
Debug('Move Right'); Debug('Move Right');
$self->sendCmd('/axis-cgi/com/ptz.cgi?move=right'); my $cmd = '/axis-cgi/com/ptz.cgi?move=right';
$self->sendCmd($cmd);
} }
sub moveConUpRight { sub moveConUpRight {
my $self = shift; my $self = shift;
Debug('Move Up/Right'); Debug('Move Up/Right');
$self->sendCmd('/axis-cgi/com/ptz.cgi?move=upright'); my $cmd = '/axis-cgi/com/ptz.cgi?move=upright';
$self->sendCmd($cmd);
} }
sub moveConUpLeft { sub moveConUpLeft {
my $self = shift; my $self = shift;
Debug( "Move Up/Left" ); Debug('Move Up/Left');
$self->sendCmd('/axis-cgi/com/ptz.cgi?move=upleft'); my $cmd = '/axis-cgi/com/ptz.cgi?move=upleft';
$self->sendCmd($cmd);
} }
sub moveConDownRight { sub moveConDownRight {
my $self = shift; my $self = shift;
Debug('Move Down/Right'); Debug('Move Down/Right');
$self->sendCmd('/axis-cgi/com/ptz.cgi?move=downright'); my $cmd = '/axis-cgi/com/ptz.cgi?move=downright';
$self->sendCmd( $cmd );
} }
sub moveConDownLeft { sub moveConDownLeft {
@ -215,51 +198,47 @@ sub moveMap {
my $xcoord = $self->getParam($params, 'xcoord'); my $xcoord = $self->getParam($params, 'xcoord');
my $ycoord = $self->getParam($params, 'ycoord'); my $ycoord = $self->getParam($params, 'ycoord');
Debug("Move Map to $xcoord,$ycoord"); Debug("Move Map to $xcoord,$ycoord");
my $cmd = "/axis-cgi/com/ptz.cgi?center=$xcoord,$ycoord&imagewidth=".$self->{Monitor}->{Width}."&imageheight=".$self->{Monitor}->{Height}; my $cmd = "/axis-cgi/com/ptz.cgi?center=$xcoord,$ycoord&imagewidth=".$self->{Monitor}->{Width}.'&imageheight='.$self->{Monitor}->{Height};
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub moveRelUp sub moveRelUp {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'tiltstep'); my $step = $self->getParam($params, 'tiltstep');
Debug("Step Up $step"); Debug("Step Up $step");
my $cmd = "/axis-cgi/com/ptz.cgi?rtilt=$step"; my $cmd = '/axis-cgi/com/ptz.cgi?rtilt='.$step;
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub moveRelDown sub moveRelDown {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'tiltstep'); my $step = $self->getParam($params, 'tiltstep');
Debug("Step Down $step"); Debug("Step Down $step");
my $cmd = "/axis-cgi/com/ptz.cgi?rtilt=-$step"; my $cmd = '/axis-cgi/com/ptz.cgi?rtilt=-'.$step;
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub moveRelLeft sub moveRelLeft {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'panstep'); my $step = $self->getParam($params, 'panstep');
Debug("Step Left $step"); Debug("Step Left $step");
my $cmd = "/axis-cgi/com/ptz.cgi?rpan=-$step"; my $cmd = '/axis-cgi/com/ptz.cgi?rpan=-'.$step;
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub moveRelRight sub moveRelRight {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'panstep'); my $step = $self->getParam($params, 'panstep');
Debug("Step Right $step"); Debug("Step Right $step");
$self->sendCmd("/axis-cgi/com/ptz.cgi?rpan=$step&camera=1&whoami=1"); my $cmd = '/axis-cgi/com/ptz.cgi?rpan='.$step;
$self->sendCmd($cmd);
} }
sub moveRelUpRight sub moveRelUpRight {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $panstep = $self->getParam($params, 'panstep'); my $panstep = $self->getParam($params, 'panstep');
@ -269,8 +248,7 @@ sub moveRelUpRight
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub moveRelUpLeft sub moveRelUpLeft {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $panstep = $self->getParam($params, 'panstep'); my $panstep = $self->getParam($params, 'panstep');
@ -280,8 +258,7 @@ sub moveRelUpLeft
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub moveRelDownRight sub moveRelDownRight {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $panstep = $self->getParam($params, 'panstep'); my $panstep = $self->getParam($params, 'panstep');
@ -291,8 +268,7 @@ sub moveRelDownRight
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub moveRelDownLeft sub moveRelDownLeft {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $panstep = $self->getParam($params, 'panstep'); my $panstep = $self->getParam($params, 'panstep');
@ -302,100 +278,89 @@ sub moveRelDownLeft
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub zoomRelTele sub zoomRelTele {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'step'); my $step = $self->getParam($params, 'step');
Debug( "Zoom Tele" ); Debug('Zoom Tele');
my $cmd = "/axis-cgi/com/ptz.cgi?rzoom=$step"; my $cmd = "/axis-cgi/com/ptz.cgi?rzoom=$step";
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub zoomRelWide sub zoomRelWide {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'step'); my $step = $self->getParam($params, 'step');
Debug( "Zoom Wide" ); Debug('Zoom Wide');
my $cmd = "/axis-cgi/com/ptz.cgi?rzoom=-$step"; my $cmd = "/axis-cgi/com/ptz.cgi?rzoom=-$step";
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub focusRelNear sub focusRelNear {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'step'); my $step = $self->getParam($params, 'step');
Debug( "Focus Near" ); Debug('Focus Near');
my $cmd = "/axis-cgi/com/ptz.cgi?rfocus=-$step"; my $cmd = "/axis-cgi/com/ptz.cgi?rfocus=-$step";
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub focusRelFar sub focusRelFar {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'step'); my $step = $self->getParam($params, 'step');
Debug( "Focus Far" ); Debug('Focus Far');
my $cmd = "/axis-cgi/com/ptz.cgi?rfocus=$step"; my $cmd = "/axis-cgi/com/ptz.cgi?rfocus=$step";
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub focusAuto sub focusAuto {
{
my $self = shift; my $self = shift;
Debug( "Focus Auto" ); Debug('Focus Auto');
my $cmd = "/axis-cgi/com/ptz.cgi?autofocus=on"; my $cmd = '/axis-cgi/com/ptz.cgi?autofocus=on';
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub focusMan sub focusMan {
{
my $self = shift; my $self = shift;
Debug( "Focus Manual" ); Debug('Focus Manual');
my $cmd = "/axis-cgi/com/ptz.cgi?autofocus=off"; my $cmd = '/axis-cgi/com/ptz.cgi?autofocus=off';
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub irisRelOpen sub irisRelOpen {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'step'); my $step = $self->getParam($params, 'step');
Debug( "Iris Open" ); Debug('Iris Open');
my $cmd = "/axis-cgi/com/ptz.cgi?riris=$step"; my $cmd = "/axis-cgi/com/ptz.cgi?riris=$step";
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub irisRelClose sub irisRelClose {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'step'); my $step = $self->getParam($params, 'step');
Debug( "Iris Close" ); Debug('Iris Close');
my $cmd = "/axis-cgi/com/ptz.cgi?riris=-$step"; my $cmd = "/axis-cgi/com/ptz.cgi?riris=-$step";
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub irisAuto sub irisAuto {
{
my $self = shift; my $self = shift;
Debug( "Iris Auto" ); Debug('Iris Auto');
my $cmd = "/axis-cgi/com/ptz.cgi?autoiris=on"; my $cmd = '/axis-cgi/com/ptz.cgi?autoiris=on';
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub irisMan sub irisMan {
{
my $self = shift; my $self = shift;
Debug( "Iris Manual" ); Debug('Iris Manual');
my $cmd = "/axis-cgi/com/ptz.cgi?autoiris=off"; my $cmd = '/axis-cgi/com/ptz.cgi?autoiris=off';
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub presetClear sub presetClear {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $preset = $self->getParam($params, 'preset'); my $preset = $self->getParam($params, 'preset');
@ -404,8 +369,7 @@ sub presetClear
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub presetSet sub presetSet {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $preset = $self->getParam($params, 'preset'); my $preset = $self->getParam($params, 'preset');
@ -414,8 +378,7 @@ sub presetSet
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub presetGoto sub presetGoto {
{
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $preset = $self->getParam($params, 'preset'); my $preset = $self->getParam($params, 'preset');
@ -424,11 +387,10 @@ sub presetGoto
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub presetHome sub presetHome {
{
my $self = shift; my $self = shift;
Debug( "Home Preset" ); Debug('Home Preset');
my $cmd = "/axis-cgi/com/ptz.cgi?move=home"; my $cmd = '/axis-cgi/com/ptz.cgi?move=home';
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }

View File

@ -1,6 +1,6 @@
# ========================================================================== # ==========================================================================
# #
# ZoneMinder Airlink SkyIPCam AICN747/AICN747W Control Protocol Module, $Date: 2008-09-13 17:30:29 +0000 (Sat, 13 Sept 2008) $, $Revision: 2229 $ # ZoneMinder Airlink SkyIPCam AICN747/AICN747W Control Protocol Module
# Copyright (C) 2008 Brian Rudy (brudyNO@SPAMpraecogito.com) # Copyright (C) 2008 Brian Rudy (brudyNO@SPAMpraecogito.com)
# #
# This program is free software; you can redistribute it and/or # This program is free software; you can redistribute it and/or
@ -43,8 +43,6 @@ our @ISA = qw(ZoneMinder::Control);
use ZoneMinder::Logger qw(:all); use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all); use ZoneMinder::Config qw(:all);
use Time::HiRes qw( usleep );
sub open { sub open {
my $self = shift; my $self = shift;
@ -52,29 +50,21 @@ sub open {
use LWP::UserAgent; use LWP::UserAgent;
$self->{ua} = LWP::UserAgent->new; $self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent( "ZoneMinder Control Agent/".ZoneMinder::Base::ZM_VERSION ); $self->{ua}->agent('ZoneMinder Control Agent/'.ZoneMinder::Base::ZM_VERSION);
$self->{state} = 'open'; $self->{state} = 'open';
} }
sub printMsg {
my $self = shift;
my $msg = shift;
my $msg_len = length($msg);
Debug( $msg."[".$msg_len."]" );
}
sub sendCmd { sub sendCmd {
my $self = shift; my $self = shift;
my $cmd = shift; my $cmd = shift;
my $result = undef; my $result = undef;
printMsg( $cmd, "Tx" ); $self->printMsg($cmd, 'Tx');
my $url; my $url;
if ( $self->{Monitor}->{ControlAddress} =~ /^http/ ) { if ( $self->{Monitor}->{ControlAddress} =~ /^http/i ) {
$url = $self->{Monitor}->{ControlAddress}.$cmd; $url = $self->{Monitor}->{ControlAddress}.$cmd;
} else { } else {
$url = 'http://'.$self->{Monitor}->{ControlAddress}.$cmd; $url = 'http://'.$self->{Monitor}->{ControlAddress}.$cmd;
@ -86,16 +76,16 @@ sub sendCmd {
if ( $res->is_success ) { if ( $res->is_success ) {
$result = !undef; $result = !undef;
} else { } else {
Error( "Error check failed: '".$res->status_line()."'" ); Error('Error check failed: \''.$res->status_line().'\'');
} }
return( $result ); return $result;
} }
sub reset { sub reset {
my $self = shift; my $self = shift;
Debug( "Camera Reset" ); Debug('Camera Reset');
my $cmd = "/admin/ptctl.cgi?move=reset"; my $cmd = '/admin/ptctl.cgi?move=reset';
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
@ -125,19 +115,19 @@ sub moveMap {
elsif ( $hor > 50 ) { elsif ( $hor > 50 ) {
# right # right
$horSteps = (($hor - 50) / 50) * $maxhor; $horSteps = (($hor - 50) / 50) * $maxhor;
$horDir = "right"; $horDir = 'right';
} }
# Vertical movement # Vertical movement
if ( $ver < 50 ) { if ( $ver < 50 ) {
# up # up
$verSteps = ((50 - $ver) / 50) * $maxver; $verSteps = ((50 - $ver) / 50) * $maxver;
$verDir = "up"; $verDir = 'up';
} }
elsif ( $ver > 50 ) { elsif ( $ver > 50 ) {
# down # down
$verSteps = (($ver - 50) / 50) * $maxver; $verSteps = (($ver - 50) / 50) * $maxver;
$verDir = "down"; $verDir = 'down';
} }
my $v = int($verSteps); my $v = int($verSteps);
@ -155,7 +145,7 @@ sub moveRelUp {
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'tiltstep'); my $step = $self->getParam($params, 'tiltstep');
Debug("Step Up $step"); Debug("Step Up $step");
my $cmd = "/admin/ptctl.cgi?move=up"; my $cmd = '/admin/ptctl.cgi?move=up';
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
@ -164,7 +154,7 @@ sub moveRelDown {
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'tiltstep'); my $step = $self->getParam($params, 'tiltstep');
Debug("Step Down $step"); Debug("Step Down $step");
my $cmd = "/admin/ptctl.cgi?move=down"; my $cmd = '/admin/ptctl.cgi?move=down';
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
@ -173,12 +163,12 @@ sub moveRelLeft {
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'panstep'); my $step = $self->getParam($params, 'panstep');
if ( $self->{Monitor}->{Orientation} eq "hori" ) { if ( $self->{Monitor}->{Orientation} eq 'FLIP_HORI' ) {
Debug( "Stepping Right because flipped horizontally " ); Debug('Stepping Right because flipped horizontally');
$self->sendCmd( "/admin/ptctl.cgi?move=right" ); $self->sendCmd('/admin/ptctl.cgi?move=right');
} else { } else {
Debug( "Step Left" ); Debug('Step Left');
$self->sendCmd( "/admin/ptctl.cgi?move=left" ); $self->sendCmd('/admin/ptctl.cgi?move=left');
} }
} }
@ -186,12 +176,12 @@ sub moveRelRight {
my $self = shift; my $self = shift;
my $params = shift; my $params = shift;
my $step = $self->getParam($params, 'panstep'); my $step = $self->getParam($params, 'panstep');
if ( $self->{Monitor}->{Orientation} eq "hori" ) { if ( $self->{Monitor}->{Orientation} eq 'FLIP_HORI' ) {
Debug( "Stepping Left because flipped horizontally " ); Debug('Stepping Left because flipped horizontally');
$self->sendCmd( "/admin/ptctl.cgi?move=left" ); $self->sendCmd('/admin/ptctl.cgi?move=left');
} else { } else {
Debug( "Step Right" ); Debug('Step Right');
$self->sendCmd( "/admin/ptctl.cgi?move=right" ); $self->sendCmd('/admin/ptctl.cgi?move=right');
} }
} }
@ -209,7 +199,7 @@ sub presetSet {
my $params = shift; my $params = shift;
my $preset = $self->getParam($params, 'preset'); my $preset = $self->getParam($params, 'preset');
Debug("Set Preset $preset"); Debug("Set Preset $preset");
my $cmd = "/admin/ptctl.cgi?position=" . ($preset - 1) . "&positionname=zm$preset"; my $cmd = '/admin/ptctl.cgi?position=' . ($preset - 1) . "&positionname=zm$preset";
$self->sendCmd( $cmd ); $self->sendCmd( $cmd );
} }
@ -218,14 +208,14 @@ sub presetGoto {
my $params = shift; my $params = shift;
my $preset = $self->getParam($params, 'preset'); my $preset = $self->getParam($params, 'preset');
Debug("Goto Preset $preset"); Debug("Goto Preset $preset");
my $cmd = "/admin/ptctl.cgi?move=p" . ($preset - 1); my $cmd = '/admin/ptctl.cgi?move=p'.($preset - 1);
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }
sub presetHome { sub presetHome {
my $self = shift; my $self = shift;
Debug( "Home Preset" ); Debug('Home Preset');
my $cmd = "/admin/ptctl.cgi?move=h"; my $cmd = '/admin/ptctl.cgi?move=h';
$self->sendCmd($cmd); $self->sendCmd($cmd);
} }

View File

@ -108,6 +108,9 @@ if ( $options{command} ) {
Fatal("Unable to load control data for monitor $id"); Fatal("Unable to load control data for monitor $id");
} }
my $protocol = $monitor->{Protocol}; my $protocol = $monitor->{Protocol};
if ( !$protocol ) {
Fatal('No protocol is set in monitor. Please edit the monitor, edit control type, select the control capability and fill in the Protocol field');
}
if ( -x $protocol ) { if ( -x $protocol ) {
# Protocol is actually a script! # Protocol is actually a script!

View File

@ -23,6 +23,7 @@
use strict; use strict;
use bytes; use bytes;
use utf8;
@EXTRA_PERL_LIB@ @EXTRA_PERL_LIB@
use ZoneMinder; use ZoneMinder;
@ -34,6 +35,7 @@ use Sys::MemInfo qw(totalmem);
use Sys::CPU qw(cpu_count); use Sys::CPU qw(cpu_count);
use POSIX qw(strftime uname); use POSIX qw(strftime uname);
use JSON::MaybeXS; use JSON::MaybeXS;
use Encode;
$ENV{PATH} = '/bin:/usr/bin:/usr/local/bin'; $ENV{PATH} = '/bin:/usr/bin:/usr/local/bin';
$ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL}; $ENV{SHELL} = '/bin/sh' if exists $ENV{SHELL};
@ -166,7 +168,7 @@ sub sendData {
$req->header('content-length' => length($msg)); $req->header('content-length' => length($msg));
$req->header('connection' => 'Close'); $req->header('connection' => 'Close');
$req->content($msg); $req->content(encode('UTF-8',$msg));
my $resp = $ua->request($req); my $resp = $ua->request($req);
my $resp_msg = $resp->decoded_content; my $resp_msg = $resp->decoded_content;

View File

@ -81,7 +81,7 @@ void FFMPEGInit() {
av_log_set_callback(log_libav_callback); av_log_set_callback(log_libav_callback);
Info("Enabling ffmpeg logs, as LOG_DEBUG+LOG_FFMPEG are enabled in options"); Info("Enabling ffmpeg logs, as LOG_DEBUG+LOG_FFMPEG are enabled in options");
} else { } else {
Info("Not enabling ffmpeg logs, as LOG_FFMPEG and/or LOG_DEBUG is disabled in options, or this monitor not part of your debug targets"); Info("Not enabling ffmpeg logs, as LOG_FFMPEG and/or LOG_DEBUG is disabled in options, or this monitor is not part of your debug targets");
av_log_set_level(AV_LOG_QUIET); av_log_set_level(AV_LOG_QUIET);
} }
#if !LIBAVFORMAT_VERSION_CHECK(58, 9, 0, 64, 0) #if !LIBAVFORMAT_VERSION_CHECK(58, 9, 0, 64, 0)
@ -291,8 +291,9 @@ static void zm_log_fps(double d, const char *postfix) {
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0) #if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
void zm_dump_codecpar ( const AVCodecParameters *par ) { void zm_dump_codecpar ( const AVCodecParameters *par ) {
Debug(1, "Dumping codecpar codec_type(%d) codec_id(%d %s) codec_tag(%d) width(%d) height(%d) bit_rate(%d) format(%d = %s)", Debug(1, "Dumping codecpar codec_type(%d %s) codec_id(%d %s) codec_tag(%" PRIu32 ") width(%d) height(%d) bit_rate(%" PRIu64 ") format(%d %s)",
par->codec_type, par->codec_type,
av_get_media_type_string(par->codec_type),
par->codec_id, par->codec_id,
avcodec_get_name(par->codec_id), avcodec_get_name(par->codec_id),
par->codec_tag, par->codec_tag,
@ -300,7 +301,7 @@ void zm_dump_codecpar ( const AVCodecParameters *par ) {
par->height, par->height,
par->bit_rate, par->bit_rate,
par->format, par->format,
((AVPixelFormat)par->format == AV_PIX_FMT_NONE ? "none" : av_get_pix_fmt_name((AVPixelFormat)par->format)) (((AVPixelFormat)par->format == AV_PIX_FMT_NONE) ? "none" : av_get_pix_fmt_name((AVPixelFormat)par->format))
); );
} }
#endif #endif

View File

@ -517,19 +517,19 @@ int FfmpegCamera::OpenFfmpeg() {
Debug(1, "Selected hw_pix_fmt %d %s", Debug(1, "Selected hw_pix_fmt %d %s",
hw_pix_fmt, av_get_pix_fmt_name(hw_pix_fmt)); hw_pix_fmt, av_get_pix_fmt_name(hw_pix_fmt));
mVideoCodecContext->get_format = get_hw_format;
ret = av_hwdevice_ctx_create(&hw_device_ctx, type, ret = av_hwdevice_ctx_create(&hw_device_ctx, type,
(hwaccel_device != "" ? hwaccel_device.c_str(): NULL), NULL, 0); (hwaccel_device != "" ? hwaccel_device.c_str(): NULL), NULL, 0);
if ( ret < 0 ) { if ( ret < 0 ) {
Error("Failed to create hwaccel device."); Error("Failed to create hwaccel device. %s",av_make_error_string(ret).c_str());
return -1; hw_pix_fmt = AV_PIX_FMT_NONE;
} } else {
Debug(1, "Created hwdevice for %s", hwaccel_device.c_str()); Debug(1, "Created hwdevice for %s", hwaccel_device.c_str());
mVideoCodecContext->get_format = get_hw_format;
mVideoCodecContext->hw_device_ctx = av_buffer_ref(hw_device_ctx); mVideoCodecContext->hw_device_ctx = av_buffer_ref(hw_device_ctx);
hwFrame = zm_av_frame_alloc(); hwFrame = zm_av_frame_alloc();
}
} else { } else {
Debug(1, "Failed to setup hwaccel."); Debug(1, "Failed to find suitable hw_pix_fmt.");
} }
#else #else
Debug(1, "AVCodec not new enough for hwaccel"); Debug(1, "AVCodec not new enough for hwaccel");
@ -537,7 +537,7 @@ int FfmpegCamera::OpenFfmpeg() {
#else #else
Warning("HWAccel support not compiled in."); Warning("HWAccel support not compiled in.");
#endif #endif
} // end if hwacel_name } // end if hwaccel_name
// Open the codec // Open the codec
#if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0) #if !LIBAVFORMAT_VERSION_CHECK(53, 8, 0, 8, 0)
@ -1087,6 +1087,7 @@ int FfmpegCamera::transfer_to_image(
return -1; return -1;
} }
#if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0) #if LIBAVUTIL_VERSION_CHECK(54, 6, 0, 6, 0)
// From what I've read, we should align the linesizes to 32bit so that ffmpeg can use SIMD instructions too.
int size = av_image_fill_arrays( int size = av_image_fill_arrays(
output_frame->data, output_frame->linesize, output_frame->data, output_frame->linesize,
directbuffer, imagePixFormat, width, height, 32); directbuffer, imagePixFormat, width, height, 32);
@ -1128,8 +1129,8 @@ int FfmpegCamera::transfer_to_image(
mConvertContext, input_frame->data, input_frame->linesize, mConvertContext, input_frame->data, input_frame->linesize,
0, mVideoCodecContext->height, 0, mVideoCodecContext->height,
output_frame->data, output_frame->linesize); output_frame->data, output_frame->linesize);
if ( ret <= 0 ) { if ( ret < 0 ) {
Error("Unable to convert format %u %s linesize %d height %d to format %u %s linesize %d at frame %d codec %u %s : code: %d", Error("Unable to convert format %u %s linesize %d height %d to format %u %s linesize %d at frame %d codec %u %s lines %d: code: %d",
input_frame->format, av_get_pix_fmt_name((AVPixelFormat)input_frame->format), input_frame->format, av_get_pix_fmt_name((AVPixelFormat)input_frame->format),
input_frame->linesize, mVideoCodecContext->height, input_frame->linesize, mVideoCodecContext->height,
imagePixFormat, imagePixFormat,
@ -1137,6 +1138,7 @@ int FfmpegCamera::transfer_to_image(
output_frame->linesize, output_frame->linesize,
frameCount, frameCount,
mVideoCodecContext->pix_fmt, av_get_pix_fmt_name(mVideoCodecContext->pix_fmt), mVideoCodecContext->pix_fmt, av_get_pix_fmt_name(mVideoCodecContext->pix_fmt),
mVideoCodecContext->height,
ret ret
); );
return -1; return -1;

View File

@ -10,6 +10,7 @@ FFmpeg_Input::FFmpeg_Input() {
FFMPEGInit(); FFMPEGInit();
streams = NULL; streams = NULL;
frame = NULL; frame = NULL;
last_seek_request = -1;
} }
FFmpeg_Input::~FFmpeg_Input() { FFmpeg_Input::~FFmpeg_Input() {
@ -102,7 +103,6 @@ int FFmpeg_Input::Open(const char *filepath) {
} // end int FFmpeg_Input::Open( const char * filepath ) } // end int FFmpeg_Input::Open( const char * filepath )
AVFrame *FFmpeg_Input::get_frame(int stream_id) { AVFrame *FFmpeg_Input::get_frame(int stream_id) {
Debug(1, "Getting frame from stream %d", stream_id);
int frameComplete = false; int frameComplete = false;
AVPacket packet; AVPacket packet;
@ -138,12 +138,14 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id) {
frame = zm_av_frame_alloc(); frame = zm_av_frame_alloc();
} }
ret = zm_send_packet_receive_frame(context, frame, packet); ret = zm_send_packet_receive_frame(context, frame, packet);
if ( ret <= 0 ) { if ( ret < 0 ) {
Error("Unable to decode frame at frame %d: %s, continuing", Error("Unable to decode frame at frame %d: %s, continuing",
streams[packet.stream_index].frame_count, av_make_error_string(ret).c_str()); streams[packet.stream_index].frame_count, av_make_error_string(ret).c_str());
zm_av_packet_unref(&packet); zm_av_packet_unref(&packet);
av_frame_free(&frame); av_frame_free(&frame);
continue; continue;
} else {
zm_dump_frame(frame, "resulting frame");
} }
frameComplete = 1; frameComplete = 1;
@ -177,7 +179,18 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) {
get_frame(stream_id); get_frame(stream_id);
} // end if ! frame } // end if ! frame
if ( frame->pts > seek_target ) { if ( !frame ) {
Warning("Unable to get frame.");
return NULL;
}
if (
(last_seek_request >= 0)
&&
(last_seek_request > seek_target )
&&
(frame->pts > seek_target)
) {
zm_dump_frame(frame, "frame->pts > seek_target, seek backwards"); zm_dump_frame(frame, "frame->pts > seek_target, seek backwards");
// our frame must be beyond our seek target. so go backwards to before it // our frame must be beyond our seek target. so go backwards to before it
if ( ( ret = av_seek_frame(input_format_context, stream_id, seek_target, if ( ( ret = av_seek_frame(input_format_context, stream_id, seek_target,
@ -191,6 +204,8 @@ AVFrame *FFmpeg_Input::get_frame(int stream_id, double at) {
zm_dump_frame(frame, "frame->pts > seek_target, got"); zm_dump_frame(frame, "frame->pts > seek_target, got");
} // end if frame->pts > seek_target } // end if frame->pts > seek_target
last_seek_request = seek_target;
// Seeking seems to typically seek to a keyframe, so then we have to decode until we get the frame we want. // Seeking seems to typically seek to a keyframe, so then we have to decode until we get the frame we want.
if ( frame->pts <= seek_target ) { if ( frame->pts <= seek_target ) {
zm_dump_frame(frame, "pts <= seek_target"); zm_dump_frame(frame, "pts <= seek_target");

View File

@ -42,6 +42,7 @@ class FFmpeg_Input {
int audio_stream_id; int audio_stream_id;
AVFormatContext *input_format_context; AVFormatContext *input_format_context;
AVFrame *frame; AVFrame *frame;
int64_t last_seek_request;
}; };
#endif #endif

View File

@ -156,6 +156,7 @@ void Logger::initialise(const std::string &id, const Options &options) {
if ( options.mTerminalLevel != NOOPT ) if ( options.mTerminalLevel != NOOPT )
tempTerminalLevel = options.mTerminalLevel; tempTerminalLevel = options.mTerminalLevel;
// DEBUG1 == 1. So >= DEBUG1, we set to DEBUG9?! Why?
if ( options.mDatabaseLevel != NOOPT ) if ( options.mDatabaseLevel != NOOPT )
tempDatabaseLevel = options.mDatabaseLevel; tempDatabaseLevel = options.mDatabaseLevel;
else else
@ -359,7 +360,7 @@ Logger::Level Logger::databaseLevel(Logger::Level databaseLevel) {
if ( databaseLevel > NOOPT ) { if ( databaseLevel > NOOPT ) {
databaseLevel = limit(databaseLevel); databaseLevel = limit(databaseLevel);
if ( mDatabaseLevel != databaseLevel ) { if ( mDatabaseLevel != databaseLevel ) {
if ( databaseLevel > NOLOG && mDatabaseLevel <= NOLOG ) { if ( (databaseLevel > NOLOG) && (mDatabaseLevel <= NOLOG) ) { // <= NOLOG would be NOOPT
if ( !zmDbConnect() ) { if ( !zmDbConnect() ) {
databaseLevel = NOLOG; databaseLevel = NOLOG;
} }

View File

@ -430,7 +430,7 @@ bool MonitorStream::sendFrame(Image *image, struct timeval *timestamp) {
Warning("Frame send time %d msec too slow, throttling maxfps to %.2f", Warning("Frame send time %d msec too slow, throttling maxfps to %.2f",
frameSendTime, maxfps); frameSendTime, maxfps);
} }
} } // Not mpeg
last_frame_sent = TV_2_FLOAT(now); last_frame_sent = TV_2_FLOAT(now);
return true; return true;
} // end bool MonitorStream::sendFrame( Image *image, struct timeval *timestamp ) } // end bool MonitorStream::sendFrame( Image *image, struct timeval *timestamp )
@ -474,6 +474,7 @@ void MonitorStream::runStream() {
Image *paused_image = NULL; Image *paused_image = NULL;
struct timeval paused_timestamp; struct timeval paused_timestamp;
if ( connkey && ( playback_buffer > 0 ) ) {
// 15 is the max length for the swap path suffix, /zmswap-whatever, assuming max 6 digits for monitor id // 15 is the max length for the swap path suffix, /zmswap-whatever, assuming max 6 digits for monitor id
const int max_swap_len_suffix = 15; const int max_swap_len_suffix = 15;
@ -482,8 +483,6 @@ void MonitorStream::runStream() {
int subfolder2_length = snprintf(NULL, 0, "/zmswap-q%06d", connkey) + 1; int subfolder2_length = snprintf(NULL, 0, "/zmswap-q%06d", connkey) + 1;
int total_swap_path_length = swap_path_length + subfolder1_length + subfolder2_length; int total_swap_path_length = swap_path_length + subfolder1_length + subfolder2_length;
if ( connkey && ( playback_buffer > 0 ) ) {
if ( total_swap_path_length + max_swap_len_suffix > PATH_MAX ) { if ( total_swap_path_length + max_swap_len_suffix > PATH_MAX ) {
Error("Swap Path is too long. %d > %d ", total_swap_path_length+max_swap_len_suffix, PATH_MAX); Error("Swap Path is too long. %d > %d ", total_swap_path_length+max_swap_len_suffix, PATH_MAX);
} else { } else {
@ -608,8 +607,9 @@ void MonitorStream::runStream() {
if ( temp_index%frame_mod == 0 ) { if ( temp_index%frame_mod == 0 ) {
Debug(2, "Sending delayed frame %d", temp_index); Debug(2, "Sending delayed frame %d", temp_index);
// Send the next frame // Send the next frame
if ( ! sendFrame(temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp) ) if ( ! sendFrame(temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp) ) {
zm_terminate = true; zm_terminate = true;
}
memcpy(&last_frame_timestamp, &(swap_image->timestamp), sizeof(last_frame_timestamp)); memcpy(&last_frame_timestamp, &(swap_image->timestamp), sizeof(last_frame_timestamp));
// frame_sent = true; // frame_sent = true;
} }
@ -622,9 +622,17 @@ void MonitorStream::runStream() {
SwapImage *swap_image = &temp_image_buffer[temp_read_index]; SwapImage *swap_image = &temp_image_buffer[temp_read_index];
// Send the next frame // Send the next frame
if ( !sendFrame( temp_image_buffer[temp_read_index].file_name, &temp_image_buffer[temp_read_index].timestamp ) ) if ( !sendFrame(
temp_image_buffer[temp_read_index].file_name,
&temp_image_buffer[temp_read_index].timestamp
) ) {
zm_terminate = true; zm_terminate = true;
memcpy( &last_frame_timestamp, &(swap_image->timestamp), sizeof(last_frame_timestamp) ); }
memcpy(
&last_frame_timestamp,
&(swap_image->timestamp),
sizeof(last_frame_timestamp)
);
// frame_sent = true; // frame_sent = true;
step = 0; step = 0;
} else { } else {
@ -632,12 +640,13 @@ void MonitorStream::runStream() {
int temp_index = MOD_ADD(temp_read_index, 0, temp_image_buffer_count); int temp_index = MOD_ADD(temp_read_index, 0, temp_image_buffer_count);
double actual_delta_time = TV_2_FLOAT(now) - last_frame_sent; double actual_delta_time = TV_2_FLOAT(now) - last_frame_sent;
if ( got_command || actual_delta_time > 5 ) { if ( got_command || (actual_delta_time > 5) ) {
// Send keepalive // Send keepalive
Debug(2, "Sending keepalive frame %d", temp_index); Debug(2, "Sending keepalive frame %d", temp_index);
// Send the next frame // Send the next frame
if ( !sendFrame( temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp ) ) if ( !sendFrame(temp_image_buffer[temp_index].file_name, &temp_image_buffer[temp_index].timestamp) ) {
zm_terminate = true; zm_terminate = true;
}
// frame_sent = true; // frame_sent = true;
} }
} // end if (!paused) or step or paused } // end if (!paused) or step or paused
@ -671,7 +680,11 @@ void MonitorStream::runStream() {
zm_terminate = true; zm_terminate = true;
} }
// Perhaps we should use NOW instead. // Perhaps we should use NOW instead.
memcpy(&last_frame_timestamp, snap->timestamp, sizeof(last_frame_timestamp)); memcpy(
&last_frame_timestamp,
snap->timestamp,
sizeof(last_frame_timestamp)
);
// frame_sent = true; // frame_sent = true;
temp_read_index = temp_write_index; temp_read_index = temp_write_index;
@ -826,8 +839,10 @@ void MonitorStream::SingleImage( int scale ) {
} }
snap_image->EncodeJpeg(img_buffer, &img_buffer_size); snap_image->EncodeJpeg(img_buffer, &img_buffer_size);
fprintf( stdout, "Content-Length: %d\r\n", img_buffer_size ); fprintf(stdout,
fprintf( stdout, "Content-Type: image/jpeg\r\n\r\n" ); "Content-Length: %d\r\n"
"Content-Type: image/jpeg\r\n\r\n",
img_buffer_size);
fwrite(img_buffer, img_buffer_size, 1, stdout); fwrite(img_buffer, img_buffer_size, 1, stdout);
} }
@ -845,12 +860,13 @@ void MonitorStream::SingleImageRaw( int scale ) {
monitor->TimestampImage(snap_image, snap->timestamp); monitor->TimestampImage(snap_image, snap->timestamp);
} }
fprintf( stdout, "Content-Length: %d\r\n", snap_image->Size() ); fprintf(stdout,
fprintf( stdout, "Content-Type: image/x-rgb\r\n\r\n" ); "Content-Length: %d\r\n"
"Content-Type: image/x-rgb\r\n\r\n",
snap_image->Size());
fwrite(snap_image->Buffer(), snap_image->Size(), 1, stdout); fwrite(snap_image->Buffer(), snap_image->Size(), 1, stdout);
} }
#ifdef HAVE_ZLIB_H #ifdef HAVE_ZLIB_H
void MonitorStream::SingleImageZip(int scale) { void MonitorStream::SingleImageZip(int scale) {
unsigned long img_buffer_size = 0; unsigned long img_buffer_size = 0;
@ -870,8 +886,10 @@ void MonitorStream::SingleImageZip( int scale ) {
} }
snap_image->Zip(img_buffer, &img_buffer_size); snap_image->Zip(img_buffer, &img_buffer_size);
fprintf( stdout, "Content-Length: %ld\r\n", img_buffer_size ); fprintf(stdout,
fprintf( stdout, "Content-Type: image/x-rgbz\r\n\r\n" ); "Content-Length: %ld\r\n"
"Content-Type: image/x-rgbz\r\n\r\n",
img_buffer_size);
fwrite(img_buffer, img_buffer_size, 1, stdout); fwrite(img_buffer, img_buffer_size, 1, stdout);
} }
#endif // HAVE_ZLIB_H #endif // HAVE_ZLIB_H

View File

@ -175,7 +175,7 @@ cd ../
VERSION=`cat ${GITHUB_FORK}_zoneminder_release/version` VERSION=`cat ${GITHUB_FORK}_zoneminder_release/version`
if [ $VERSION == "" ]; then if [ -z "$VERSION" ]; then
exit 1; exit 1;
fi; fi;
if [ "$SNAPSHOT" != "stable" ] && [ "$SNAPSHOT" != "" ]; then if [ "$SNAPSHOT" != "stable" ] && [ "$SNAPSHOT" != "" ]; then

View File

@ -1,5 +1,10 @@
#!/bin/bash #!/bin/bash
# We don't deploy during eslint checks, so exit immediately
if [ "${DIST}" == "eslint" ]; then
exit 0
fi
# Check to see if this script has access to all the commands it needs # Check to see if this script has access to all the commands it needs
for CMD in sshfs rsync find fusermount mkdir; do for CMD in sshfs rsync find fusermount mkdir; do
type $CMD 2>&1 > /dev/null type $CMD 2>&1 > /dev/null
@ -12,11 +17,7 @@ for CMD in sshfs rsync find fusermount mkdir; do
fi fi
done done
# We only want to deploy packages during cron events if [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ] || [ "${OS}" == "raspbian" ]; then
# See https://docs.travis-ci.com/user/cron-jobs/
if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ]; then
if [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ]; then
targetfolder="debian/master/mini-dinstall/incoming" targetfolder="debian/master/mini-dinstall/incoming"
else else
targetfolder="travis" targetfolder="travis"
@ -25,40 +26,17 @@ if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${OS}" == "debian" ] || [ "${OS}"
echo echo
echo "Target subfolder set to $targetfolder" echo "Target subfolder set to $targetfolder"
echo echo
if [ "${USE_SFTP}" == "yes" ]; then
echo "Running \$(rsync -v -e 'ssh -vvv' build/* zmrepo@zmrepo.zoneminder.com:${targetfolder}/ 2>&1)" echo "Running \$(rsync -v -e 'ssh -vvv' build/*.{rpm,deb,dsc,tar.xz,buildinfo,changes} zmrepo@zmrepo.zoneminder.com:${targetfolder}/ 2>&1)"
rsync -v -e 'ssh -vvv' build/* zmrepo@zmrepo.zoneminder.com:${targetfolder}/ 2>&1 rsync -v --ignore-missing-args --exclude 'external-repo.noarch.rpm' -e 'ssh -vvv' build/*.{rpm,deb,dsc,tar.xz,changes} zmrepo@zmrepo.zoneminder.com:${targetfolder}/ 2>&1
if [ $? -eq 0 ]; then if [ "$?" -eq 0 ]; then
echo echo
echo "Files copied successfully." echo "Files copied successfully."
echo echo
else else
echo echo
echo "ERROR: Attempt to rsync to zmrepo.zoneminder.com failed!" echo "ERROR: Attempt to rsync to zmrepo.zoneminder.com failed!"
echo "See log output for details."
echo echo
exit 99 exit 99
fi fi
else
mkdir -p ./zmrepo
ssh_mntchk="$(sshfs zmrepo@zmrepo.zoneminder.com:./ ./zmrepo -o workaround=rename,reconnect 2>&1)"
if [ -z "$ssh_mntchk" ]; then
echo
echo "Remote filesystem mounted successfully."
echo "Begin transfering files..."
echo
# Don't keep packages older than 5 days
find ./zmrepo/$targetfolder/ -maxdepth 1 -type f,l -mtime +5 -delete
rsync -vzlh --ignore-errors build/* zmrepo/$targetfolder/
fusermount -zu zmrepo
else
echo
echo "ERROR: Attempt to mount zmrepo.zoneminder.com failed!"
echo "sshfs gave the following error message:"
echo \"$ssh_mntchk\"
echo
exit 99
fi
fi
fi

View File

@ -9,7 +9,7 @@
# General sanity checks # General sanity checks
checksanity () { checksanity () {
# Check to see if this script has access to all the commands it needs # Check to see if this script has access to all the commands it needs
for CMD in set echo curl git ln mkdir rmdir cat patch; do for CMD in set echo curl git ln mkdir rmdir cat patch sed; do
type $CMD 2>&1 > /dev/null type $CMD 2>&1 > /dev/null
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
@ -30,7 +30,7 @@ checksanity () {
ARCH="x86_64" ARCH="x86_64"
fi fi
if [[ "${ARCH}" != "x86_64" && "${ARCH}" != "i386" && "${ARCH}" != "armhf" ]]; then if [[ "${ARCH}" != "x86_64" && "${ARCH}" != "i386" && "${ARCH}" != "armhf" && "${ARCH}" != "aarch64" ]]; then
echo echo
echo "ERROR: Unsupported architecture specified \"${ARCH}\"." echo "ERROR: Unsupported architecture specified \"${ARCH}\"."
echo echo
@ -150,7 +150,7 @@ install_deb () {
exit 1 exit 1
fi fi
# Install and test the zoneminder package (only) for Ubuntu Trusty # Install and test the zoneminder package (only) for Ubuntu Xenial
pkgname="build/zoneminder_${VERSION}-${RELEASE}_amd64.deb" pkgname="build/zoneminder_${VERSION}-${RELEASE}_amd64.deb"
if [ -e $pkgname ]; then if [ -e $pkgname ]; then
@ -275,6 +275,8 @@ checkdeploytarget () {
echo "*** TRACEROUTE ***" echo "*** TRACEROUTE ***"
echo echo
traceroute -w 2 -m 15 ${DEPLOYTARGET} traceroute -w 2 -m 15 ${DEPLOYTARGET}
exit 97
fi fi
} }
@ -291,16 +293,16 @@ if [ "${TRAVIS}" == "true" ]; then
fi fi
checksanity checksanity
# We don't want to build packages for all supported distros after every commit
# Only build all packages when executed via cron
# See https://docs.travis-ci.com/user/cron-jobs/
# Steps common to Redhat distros # Steps common to Redhat distros
if [ "${OS}" == "el" ] || [ "${OS}" == "fedora" ]; then if [ "${OS}" == "el" ] || [ "${OS}" == "fedora" ]; then
if [ "${TRAVIS_EVENT_TYPE}" == "cron" ] || [ "${TRAVIS}" != "true" ]; then
commonprep commonprep
echo "Begin Redhat build..." echo "Begin Redhat build..."
# Newer Redhat distros use dnf package manager rather than yum
if [ "${DIST}" -gt "7" ]; then
sed -i 's\yum\dnf\' utils/packpack/redhat_package.mk
fi
setrpmpkgname setrpmpkgname
ln -sfT distros/redhat rpm ln -sfT distros/redhat rpm
@ -326,7 +328,7 @@ if [ "${OS}" == "el" ] || [ "${OS}" == "fedora" ]; then
echo "Starting packpack..." echo "Starting packpack..."
execpackpack execpackpack
fi;
# Steps common to Debian based distros # Steps common to Debian based distros
elif [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ] || [ "${OS}" == "raspbian" ]; then elif [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ] || [ "${OS}" == "raspbian" ]; then
commonprep commonprep
@ -348,14 +350,27 @@ elif [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ] || [ "${OS}" == "raspbia
echo "Starting packpack..." echo "Starting packpack..."
execpackpack execpackpack
# We were not triggered via cron so just build and test trusty # Try to install and run the newly built zoneminder package
if [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "xenial" ] && [ "${ARCH}" == "x86_64" ]; then if [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "xenial" ] && [ "${ARCH}" == "x86_64" ] && [ "${TRAVIS}" == "true" ]; then
# If we are running inside Travis then attempt to install the deb we just built echo "Begin Deb package installation..."
if [ "${TRAVIS}" == "true" ]; then
install_deb install_deb
fi fi
fi
# Steps common to eslint checks
elif [ "${OS}" == "eslint" ] || [ "${DIST}" == "eslint" ]; then
# Check we've got npm installed
type npm 2>&1 > /dev/null
if [ $? -ne 0 ]; then
echo
echo "ERROR: The script cannot find the required command \"npm\"."
echo
exit 1
fi fi
exit 0 npm install -g eslint@5.12.0 eslint-config-google@0.11.0 eslint-plugin-html@5.0.0 eslint-plugin-php-markup@0.2.5
echo "Begin eslint checks..."
eslint --ext .php,.js .
fi

View File

@ -1 +1 @@
1.33.15 1.33.16

View File

@ -58,7 +58,7 @@ function buildLogQuery($action) {
$sql .= ' ORDER BY '.$sortField.' '.$sortOrder.' LIMIT '.$limit; $sql .= ' ORDER BY '.$sortField.' '.$sortOrder.' LIMIT '.$limit;
return array('sql'=>$sql, 'values'=>$values); return array('sql'=>$sql, 'values'=>$values);
} } # function buildLogQuery($action)
switch ( $_REQUEST['task'] ) { switch ( $_REQUEST['task'] ) {
case 'create' : case 'create' :
@ -70,14 +70,16 @@ switch ( $_REQUEST['task'] ) {
$string = $_POST['message']; $string = $_POST['message'];
$file = !empty($_POST['file']) ? preg_replace( '/\w+:\/\/[\w.:]+\//', '', $_POST['file'] ) : ''; $file = !empty($_POST['file']) ? preg_replace( '/\w+:\/\/[\w.:]+\//', '', $_POST['file'] ) : '';
if ( !empty( $_POST['line'] ) ) if ( !empty( $_POST['line'] ) ) {
$line = validInt($_POST['line']); $line = validInt($_POST['line']);
else } else {
$line = NULL; $line = NULL;
}
$levels = array_flip(ZM\Logger::$codes); $levels = array_flip(ZM\Logger::$codes);
if ( !isset($levels[$_POST['level']]) ) if ( !isset($levels[$_POST['level']]) ) {
ZM\Panic('Unexpected logger level '.$_POST['level']); ZM\Panic('Unexpected logger level '.$_POST['level']);
}
$level = $levels[$_POST['level']]; $level = $levels[$_POST['level']];
ZM\Logger::fetch()->logPrint($level, $string, $file, $line); ZM\Logger::fetch()->logPrint($level, $string, $file, $line);
} }
@ -141,6 +143,10 @@ switch ( $_REQUEST['task'] ) {
$logs[] = $log; $logs[] = $log;
} }
foreach ( $options as $field => $values ) {
asort($options[$field]);
}
$available = count($logs); $available = count($logs);
ajaxResponse( array( ajaxResponse( array(
'updated' => preg_match('/%/', DATE_FMT_CONSOLE_LONG)?strftime(DATE_FMT_CONSOLE_LONG):date(DATE_FMT_CONSOLE_LONG), 'updated' => preg_match('/%/', DATE_FMT_CONSOLE_LONG)?strftime(DATE_FMT_CONSOLE_LONG):date(DATE_FMT_CONSOLE_LONG),

View File

@ -83,8 +83,8 @@ $statusData = array(
'MinEventId' => array( 'sql' => '(SELECT min(Events.Id) FROM Events WHERE Events.MonitorId = Monitors.Id' ), 'MinEventId' => array( 'sql' => '(SELECT min(Events.Id) FROM Events WHERE Events.MonitorId = Monitors.Id' ),
'MaxEventId' => array( 'sql' => '(SELECT max(Events.Id) FROM Events WHERE Events.MonitorId = Monitors.Id' ), 'MaxEventId' => array( 'sql' => '(SELECT max(Events.Id) FROM Events WHERE Events.MonitorId = Monitors.Id' ),
'TotalEvents' => array( 'sql' => '(SELECT count(Events.Id) FROM Events WHERE Events.MonitorId = Monitors.Id' ), 'TotalEvents' => array( 'sql' => '(SELECT count(Events.Id) FROM Events WHERE Events.MonitorId = Monitors.Id' ),
'Status' => array( 'zmu' => '-m '.escapeshellarg($_REQUEST['id'][0]).' -s' ), 'Status' => (isset($_REQUEST['id'])?array( 'zmu' => '-m '.escapeshellarg($_REQUEST['id'][0]).' -s' ):null),
'FrameRate' => array( 'zmu' => '-m '.escapeshellarg($_REQUEST['id'][0]).' -f' ), 'FrameRate' => (isset($_REQUEST['id'])?array( 'zmu' => '-m '.escapeshellarg($_REQUEST['id'][0]).' -f' ):null),
), ),
), ),
'events' => array( 'events' => array(
@ -204,6 +204,7 @@ function collectData() {
$fieldSql = array(); $fieldSql = array();
$joinSql = array(); $joinSql = array();
$groupSql = array(); $groupSql = array();
$values = array();
$elements = &$entitySpec['elements']; $elements = &$entitySpec['elements'];
$lc_elements = array_change_key_case( $elements ); $lc_elements = array_change_key_case( $elements );
@ -258,7 +259,6 @@ function collectData() {
if ( $id && !empty($entitySpec['selector']) ) { if ( $id && !empty($entitySpec['selector']) ) {
$index = 0; $index = 0;
$where = array(); $where = array();
$values = array();
foreach( $entitySpec['selector'] as $selIndex => $selector ) { foreach( $entitySpec['selector'] as $selIndex => $selector ) {
$selectorParamName = ':selector' . $selIndex; $selectorParamName = ':selector' . $selIndex;
if ( is_array( $selector ) ) { if ( is_array( $selector ) ) {

View File

@ -119,13 +119,11 @@ if ( sem_acquire($semaphore,1) !== false ) {
switch ( $data['type'] ) { switch ( $data['type'] ) {
case MSG_DATA_WATCH : case MSG_DATA_WATCH :
$data = unpack('ltype/imonitor/istate/dfps/ilevel/irate/ddelay/izoom/Cdelayed/Cpaused/Cenabled/Cforced', $msg); $data = unpack('ltype/imonitor/istate/dfps/ilevel/irate/ddelay/izoom/Cdelayed/Cpaused/Cenabled/Cforced', $msg);
ZM\Logger::Debug('FPS: ' . $data['fps']);
$data['fps'] = round( $data['fps'], 2 ); $data['fps'] = round( $data['fps'], 2 );
ZM\Logger::Debug('FPS: ' . $data['fps'] );
$data['rate'] /= RATE_BASE; $data['rate'] /= RATE_BASE;
$data['delay'] = round( $data['delay'], 2 ); $data['delay'] = round( $data['delay'], 2 );
$data['zoom'] = round( $data['zoom']/SCALE_BASE, 1 ); $data['zoom'] = round( $data['zoom']/SCALE_BASE, 1 );
if ( ZM_OPT_USE_AUTH && ZM_AUTH_RELAY == 'hashed' ) { if ( ZM_OPT_USE_AUTH && (ZM_AUTH_RELAY == 'hashed') ) {
$time = time(); $time = time();
// Regenerate auth hash after half the lifetime of the hash // Regenerate auth hash after half the lifetime of the hash
if ( (!isset($_SESSION['AuthHashGeneratedAt'])) or ( $_SESSION['AuthHashGeneratedAt'] < $time - (ZM_AUTH_HASH_TTL * 1800) ) ) { if ( (!isset($_SESSION['AuthHashGeneratedAt'])) or ( $_SESSION['AuthHashGeneratedAt'] < $time - (ZM_AUTH_HASH_TTL * 1800) ) ) {
@ -144,7 +142,7 @@ if ( sem_acquire($semaphore,1) !== false ) {
} }
$data['rate'] /= RATE_BASE; $data['rate'] /= RATE_BASE;
$data['zoom'] = round( $data['zoom']/SCALE_BASE, 1 ); $data['zoom'] = round( $data['zoom']/SCALE_BASE, 1 );
if ( ZM_OPT_USE_AUTH && ZM_AUTH_RELAY == 'hashed' ) { if ( ZM_OPT_USE_AUTH && (ZM_AUTH_RELAY == 'hashed') ) {
$time = time(); $time = time();
// Regenerate auth hash after half the lifetime of the hash // Regenerate auth hash after half the lifetime of the hash
if ( (!isset($_SESSION['AuthHashGeneratedAt'])) or ( $_SESSION['AuthHashGeneratedAt'] < $time - (ZM_AUTH_HASH_TTL * 1800) ) ) { if ( (!isset($_SESSION['AuthHashGeneratedAt'])) or ( $_SESSION['AuthHashGeneratedAt'] < $time - (ZM_AUTH_HASH_TTL * 1800) ) ) {

View File

@ -77,16 +77,24 @@ class GroupsController extends AppController {
} }
$this->Group->create(); $this->Group->create();
if ( $this->Group->save($this->request->data) ) {
if ( $this->request->data['Group']['MonitorIds'] and ! isset($this->request->data['Monitor']) ) {
$this->request->data['Monitor'] = explode(',', $this->request->data['Group']['MonitorIds']);
unset($this->request->data['Group']['MonitorIds']);
}
if ( $this->Group->saveAssociated($this->request->data, array('atomic'=>true)) ) {
return $this->flash( return $this->flash(
__('The group has been saved.'), __('The group has been saved.'),
array('action' => 'index') array('action' => 'index')
); );
} else {
ZM\Error("Failed to save Group");
debug($this->Group->invalidFields());
} }
} } # end if post
$monitors = $this->Group->Monitor->find('list'); $monitors = $this->Group->Monitor->find('list');
$this->set(compact('monitors')); $this->set(compact('monitors'));
} } # end add
/** /**
* edit method * edit method

View File

@ -136,7 +136,7 @@ class HostController extends AppController {
}*/ }*/
$access_issued_at = time(); $access_issued_at = time();
$access_ttl = (ZM_AUTH_HASH_TTL || 2) * 3600; $access_ttl = max(ZM_AUTH_HASH_TTL,1) * 3600;
// by default access token will expire in 2 hrs // by default access token will expire in 2 hrs
// you can change it by changing the value of ZM_AUTH_HASH_TLL // you can change it by changing the value of ZM_AUTH_HASH_TLL

View File

@ -44,33 +44,25 @@ class MonitorsController extends AppController {
} else { } else {
$conditions = array(); $conditions = array();
} }
global $user; global $user;
$allowedMonitors = $user ? preg_split('@,@', $user['MonitorIds'], NULL, PREG_SPLIT_NO_EMPTY) : null; $allowedMonitors = $user ? preg_split('@,@', $user['MonitorIds'], NULL, PREG_SPLIT_NO_EMPTY) : null;
if ( $allowedMonitors ) { if ( $allowedMonitors ) {
$conditions['Monitor.Id' ] = $allowedMonitors; $conditions['Monitor.Id' ] = $allowedMonitors;
} }
$find_array = array('conditions'=>$conditions,'contain'=>array('Group'));
if ( isset($conditions['GroupId']) ) { $find_array = array(
$find_array['joins'] = array( 'conditions' => &$conditions,
'contain' => array('Group'),
'joins' => array(
array( array(
'table' => 'Groups_Monitors', 'table' => 'Groups_Monitors',
'type' => 'inner', 'type' => 'left',
'conditions' => array( 'conditions' => array(
'Groups_Monitors.MonitorId = Monitor.Id' 'Groups_Monitors.MonitorId = Monitor.Id',
), ),
), ),
//array( )
//'table' => 'Groups',
//'type' => 'inner',
//'conditions' => array(
//'Groups.Id = Groups_Monitors.GroupId',
//'Groups.Id' => $this->request->params['GroupId'],
//),
//)
); );
}
$monitors = $this->Monitor->find('all',$find_array); $monitors = $this->Monitor->find('all',$find_array);
$this->set(array( $this->set(array(
'monitors' => $monitors, 'monitors' => $monitors,

View File

@ -59,7 +59,7 @@ class Group extends AppModel {
* *
* @var array * @var array
*/ */
public $hasMany = array( public $hasAndBelongsToMany = array(
'Monitor' => array( 'Monitor' => array(
'className' => 'Monitor', 'className' => 'Monitor',
'joinTable' => 'Groups_Monitors', 'joinTable' => 'Groups_Monitors',
@ -77,4 +77,5 @@ class Group extends AppModel {
'counterQuery' => '' 'counterQuery' => ''
), ),
); );
var $actsAs = array( 'Containable' );
} }

View File

@ -128,12 +128,16 @@ class Control extends ZM_Object {
$cmds['PresetHome'] = 'presetHome'; $cmds['PresetHome'] = 'presetHome';
if ( $this->CanZoom() ) { if ( $this->CanZoom() ) {
if ( $this->CanZoomCon() ) if ( $this->CanZoomCon() ) {
$cmds['ZoomRoot'] = 'zoomCon'; $cmds['ZoomRoot'] = 'zoomCon';
elseif ( $this->CanZoomRel() ) } else if ( $this->CanZoomRel() ) {
$cmds['ZoomRoot'] = 'zoomRel'; $cmds['ZoomRoot'] = 'zoomRel';
elseif ( $this->CanZoomAbs() ) } else if ( $this->CanZoomAbs() ) {
$cmds['ZoomRoot'] = 'zoomAbs'; $cmds['ZoomRoot'] = 'zoomAbs';
} else {
$cmds['ZoomRoot'] = '';
Error('No zoom type selected. Please select Continuous, Relative, Absolute');
}
$cmds['ZoomTele'] = $cmds['ZoomRoot'].'Tele'; $cmds['ZoomTele'] = $cmds['ZoomRoot'].'Tele';
$cmds['ZoomWide'] = $cmds['ZoomRoot'].'Wide'; $cmds['ZoomWide'] = $cmds['ZoomRoot'].'Wide';
$cmds['ZoomStop'] = 'zoomStop'; $cmds['ZoomStop'] = 'zoomStop';
@ -142,12 +146,16 @@ class Control extends ZM_Object {
} }
if ( $this->CanFocus() ) { if ( $this->CanFocus() ) {
if ( $this->CanFocusCon() ) if ( $this->CanFocusCon() ) {
$cmds['FocusRoot'] = 'focusCon'; $cmds['FocusRoot'] = 'focusCon';
elseif ( $this->CanFocusRel() ) } else if ( $this->CanFocusRel() ) {
$cmds['FocusRoot'] = 'focusRel'; $cmds['FocusRoot'] = 'focusRel';
elseif ( $this->CanFocusAbs() ) } else if ( $this->CanFocusAbs() ) {
$cmds['FocusRoot'] = 'focusAbs'; $cmds['FocusRoot'] = 'focusAbs';
} else {
$cmds['FocusRoot'] = '';
Error('No focus type selected. Please select Continuous, Relative, Absolute');
}
$cmds['FocusFar'] = $cmds['FocusRoot'].'Far'; $cmds['FocusFar'] = $cmds['FocusRoot'].'Far';
$cmds['FocusNear'] = $cmds['FocusRoot'].'Near'; $cmds['FocusNear'] = $cmds['FocusRoot'].'Near';
$cmds['FocusStop'] = 'focusStop'; $cmds['FocusStop'] = 'focusStop';
@ -156,12 +164,16 @@ class Control extends ZM_Object {
} }
if ( $this->CanIris() ) { if ( $this->CanIris() ) {
if ( $this->CanIrisCon() ) if ( $this->CanIrisCon() ) {
$cmds['IrisRoot'] = 'irisCon'; $cmds['IrisRoot'] = 'irisCon';
elseif ( $this->CanIrisRel() ) } else if ( $this->CanIrisRel() ) {
$cmds['IrisRoot'] = 'irisRel'; $cmds['IrisRoot'] = 'irisRel';
elseif ( $this->CanIrisAbs() ) } else if ( $this->CanIrisAbs() ) {
$cmds['IrisRoot'] = 'irisAbs'; $cmds['IrisRoot'] = 'irisAbs';
} else {
$cmds['IrisRoot'] = '';
Error('No iris type selected. Please select Continuous, Relative, Absolute');
}
$cmds['IrisOpen'] = $cmds['IrisRoot'].'Open'; $cmds['IrisOpen'] = $cmds['IrisRoot'].'Open';
$cmds['IrisClose'] = $cmds['IrisRoot'].'Close'; $cmds['IrisClose'] = $cmds['IrisRoot'].'Close';
$cmds['IrisStop'] = 'irisStop'; $cmds['IrisStop'] = 'irisStop';
@ -170,12 +182,16 @@ class Control extends ZM_Object {
} }
if ( $this->CanWhite() ) { if ( $this->CanWhite() ) {
if ( $this->CanWhiteCon() ) if ( $this->CanWhiteCon() ) {
$cmds['WhiteRoot'] = 'whiteCon'; $cmds['WhiteRoot'] = 'whiteCon';
elseif ( $this->CanWhiteRel() ) } else if ( $this->CanWhiteRel() ) {
$cmds['WhiteRoot'] = 'whiteRel'; $cmds['WhiteRoot'] = 'whiteRel';
elseif ( $this->CanWhiteAbs() ) } else if ( $this->CanWhiteAbs() ) {
$cmds['WhiteRoot'] = 'whiteAbs'; $cmds['WhiteRoot'] = 'whiteAbs';
} else {
Error('No White type selected. Please select Continuous, Relative, Absolute');
$cmds['WhiteRoot'] = '';
}
$cmds['WhiteIn'] = $cmds['WhiteRoot'].'In'; $cmds['WhiteIn'] = $cmds['WhiteRoot'].'In';
$cmds['WhiteOut'] = $cmds['WhiteRoot'].'Out'; $cmds['WhiteOut'] = $cmds['WhiteRoot'].'Out';
$cmds['WhiteAuto'] = 'whiteAuto'; $cmds['WhiteAuto'] = 'whiteAuto';
@ -183,12 +199,16 @@ class Control extends ZM_Object {
} }
if ( $this->CanGain() ) { if ( $this->CanGain() ) {
if ( $this->CanGainCon() ) if ( $this->CanGainCon() ) {
$cmds['GainRoot'] = 'gainCon'; $cmds['GainRoot'] = 'gainCon';
elseif ( $this->CanGainRel() ) } else if ( $this->CanGainRel() ) {
$cmds['GainRoot'] = 'gainRel'; $cmds['GainRoot'] = 'gainRel';
elseif ( $this->CanGainAbs() ) } else if ( $this->CanGainAbs() ) {
$cmds['GainRoot'] = 'gainAbs'; $cmds['GainRoot'] = 'gainAbs';
} else {
Error('No Gain type selected');
$cmds['GainRoot'] = '';
}
$cmds['GainUp'] = $cmds['GainRoot'].'Up'; $cmds['GainUp'] = $cmds['GainRoot'].'Up';
$cmds['GainDown'] = $cmds['GainRoot'].'Down'; $cmds['GainDown'] = $cmds['GainRoot'].'Down';
$cmds['GainAuto'] = 'gainAuto'; $cmds['GainAuto'] = 'gainAuto';
@ -207,6 +227,7 @@ class Control extends ZM_Object {
$cmds['Center'] = $cmds['PresetHome']; $cmds['Center'] = $cmds['PresetHome'];
} else { } else {
$cmds['MoveRoot'] = ''; $cmds['MoveRoot'] = '';
Error('No move type selected. Please select Continuous, Relative, Absolute');
} }
$cmds['MoveUp'] = $cmds['MoveRoot'].'Up'; $cmds['MoveUp'] = $cmds['MoveRoot'].'Up';

View File

@ -51,10 +51,10 @@ class Event extends ZM_Object {
if ( $new ) { if ( $new ) {
$this->{'Storage'} = $new; $this->{'Storage'} = $new;
} }
if ( ! ( array_key_exists('Storage', $this) and $this->{'Storage'} ) ) { if ( ! ( property_exists($this, 'Storage') and $this->{'Storage'} ) ) {
if ( isset($this->{'StorageId'}) and $this->{'StorageId'} ) if ( isset($this->{'StorageId'}) and $this->{'StorageId'} )
$this->{'Storage'} = Storage::find_one(array('Id'=>$this->{'StorageId'})); $this->{'Storage'} = Storage::find_one(array('Id'=>$this->{'StorageId'}));
if ( ! ( array_key_exists('Storage', $this) and $this->{'Storage'} ) ) if ( ! ( property_exists($this, 'Storage') and $this->{'Storage'} ) )
$this->{'Storage'} = new Storage(NULL); $this->{'Storage'} = new Storage(NULL);
} }
return $this->{'Storage'}; return $this->{'Storage'};
@ -64,10 +64,10 @@ class Event extends ZM_Object {
if ( $new ) { if ( $new ) {
$this->{'SecondaryStorage'} = $new; $this->{'SecondaryStorage'} = $new;
} }
if ( ! ( array_key_exists('SecondaryStorage', $this) and $this->{'SecondaryStorage'} ) ) { if ( ! ( property_exists($this, 'SecondaryStorage') and $this->{'SecondaryStorage'} ) ) {
if ( isset($this->{'SecondaryStorageId'}) and $this->{'SecondaryStorageId'} ) if ( isset($this->{'SecondaryStorageId'}) and $this->{'SecondaryStorageId'} )
$this->{'SecondaryStorage'} = Storage::find_one(array('Id'=>$this->{'SecondaryStorageId'})); $this->{'SecondaryStorage'} = Storage::find_one(array('Id'=>$this->{'SecondaryStorageId'}));
if ( ! ( array_key_exists('SecondaryStorage', $this) and $this->{'SecondaryStorage'} ) ) if ( ! ( property_exists($this, 'SecondaryStorage') and $this->{'SecondaryStorage'} ) )
$this->{'SecondaryStorage'} = new Storage(NULL); $this->{'SecondaryStorage'} = new Storage(NULL);
} }
return $this->{'SecondaryStorage'}; return $this->{'SecondaryStorage'};
@ -262,7 +262,7 @@ class Event extends ZM_Object {
if ( is_null($new) or ( $new != '' ) ) { if ( is_null($new) or ( $new != '' ) ) {
$this->{'DiskSpace'} = $new; $this->{'DiskSpace'} = $new;
} }
if ( (!array_key_exists('DiskSpace',$this)) or (null === $this->{'DiskSpace'}) ) { if ( (!property_exists($this, 'DiskSpace')) or (null === $this->{'DiskSpace'}) ) {
$this->{'DiskSpace'} = folder_size($this->Path()); $this->{'DiskSpace'} = folder_size($this->Path());
dbQuery('UPDATE Events SET DiskSpace=? WHERE Id=?', array($this->{'DiskSpace'}, $this->{'Id'})); dbQuery('UPDATE Events SET DiskSpace=? WHERE Id=?', array($this->{'DiskSpace'}, $this->{'Id'}));
} }
@ -298,7 +298,7 @@ class Event extends ZM_Object {
} // end function createListThumbnail } // end function createListThumbnail
function ThumbnailWidth( ) { function ThumbnailWidth( ) {
if ( ! ( array_key_exists('ThumbnailWidth', $this) ) ) { if ( ! ( property_exists($this, 'ThumbnailWidth') ) ) {
if ( ZM_WEB_LIST_THUMB_WIDTH ) { if ( ZM_WEB_LIST_THUMB_WIDTH ) {
$this->{'ThumbnailWidth'} = ZM_WEB_LIST_THUMB_WIDTH; $this->{'ThumbnailWidth'} = ZM_WEB_LIST_THUMB_WIDTH;
$scale = (SCALE_BASE*ZM_WEB_LIST_THUMB_WIDTH)/$this->{'Width'}; $scale = (SCALE_BASE*ZM_WEB_LIST_THUMB_WIDTH)/$this->{'Width'};
@ -315,7 +315,7 @@ class Event extends ZM_Object {
} // end function ThumbnailWidth } // end function ThumbnailWidth
function ThumbnailHeight( ) { function ThumbnailHeight( ) {
if ( ! ( array_key_exists('ThumbnailHeight', $this) ) ) { if ( ! ( property_exists($this, 'ThumbnailHeight') ) ) {
if ( ZM_WEB_LIST_THUMB_WIDTH ) { if ( ZM_WEB_LIST_THUMB_WIDTH ) {
$this->{'ThumbnailWidth'} = ZM_WEB_LIST_THUMB_WIDTH; $this->{'ThumbnailWidth'} = ZM_WEB_LIST_THUMB_WIDTH;
$scale = (SCALE_BASE*ZM_WEB_LIST_THUMB_WIDTH)/$this->{'Width'}; $scale = (SCALE_BASE*ZM_WEB_LIST_THUMB_WIDTH)/$this->{'Width'};

View File

@ -39,8 +39,8 @@ class Filter extends ZM_Object {
$this->{'Query'} = func_get_arg(0);; $this->{'Query'} = func_get_arg(0);;
$this->{'Query_json'} = jsonEncode($this->{'Query'}); $this->{'Query_json'} = jsonEncode($this->{'Query'});
} }
if ( !array_key_exists('Query', $this) ) { if ( !property_exists($this, 'Query') ) {
if ( array_key_exists('Query_json', $this) and $this->{'Query_json'} ) { if ( property_exists($this, 'Query_json') and $this->{'Query_json'} ) {
$this->{'Query'} = jsonDecode($this->{'Query_json'}); $this->{'Query'} = jsonDecode($this->{'Query_json'});
} else { } else {
$this->{'Query'} = array(); $this->{'Query'} = array();

View File

@ -18,7 +18,7 @@ class Group extends ZM_Object {
} }
public function delete() { public function delete() {
if ( array_key_exists('Id', $this) ) { if ( property_exists($this, 'Id') ) {
dbQuery('DELETE FROM Groups_Monitors WHERE GroupId=?', array($this->{'Id'})); dbQuery('DELETE FROM Groups_Monitors WHERE GroupId=?', array($this->{'Id'}));
dbQuery('UPDATE Groups SET ParentId=NULL WHERE ParentId=?', array($this->{'Id'})); dbQuery('UPDATE Groups SET ParentId=NULL WHERE ParentId=?', array($this->{'Id'}));
dbQuery('DELETE FROM Groups WHERE Id=?', array($this->{'Id'})); dbQuery('DELETE FROM Groups WHERE Id=?', array($this->{'Id'}));
@ -35,7 +35,7 @@ class Group extends ZM_Object {
if ( isset($new) ) { if ( isset($new) ) {
$this->{'depth'} = $new; $this->{'depth'} = $new;
} }
if ( !array_key_exists('depth', $this) or ($this->{'depth'} === null) ) { if ( !property_exists($this, 'depth') or ($this->{'depth'} === null) ) {
$this->{'depth'} = 0; $this->{'depth'} = 0;
if ( $this->{'ParentId'} != null ) { if ( $this->{'ParentId'} != null ) {
$Parent = Group::find_one(array('Id'=>$this->{'ParentId'})); $Parent = Group::find_one(array('Id'=>$this->{'ParentId'}));
@ -46,7 +46,7 @@ class Group extends ZM_Object {
} // end public function depth } // end public function depth
public function MonitorIds( ) { public function MonitorIds( ) {
if ( ! array_key_exists('MonitorIds', $this) ) { if ( ! property_exists($this, 'MonitorIds') ) {
$this->{'MonitorIds'} = dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId=?', 'MonitorId', array($this->{'Id'})); $this->{'MonitorIds'} = dbFetchAll('SELECT MonitorId FROM Groups_Monitors WHERE GroupId=?', 'MonitorId', array($this->{'Id'}));
} }
return $this->{'MonitorIds'}; return $this->{'MonitorIds'};

View File

@ -12,6 +12,7 @@ class Monitor extends ZM_Object {
protected $defaults = array( protected $defaults = array(
'Id' => null, 'Id' => null,
'Name' => '', 'Name' => '',
'Notes' => '',
'ServerId' => 0, 'ServerId' => 0,
'StorageId' => 0, 'StorageId' => 0,
'Type' => 'Ffmpeg', 'Type' => 'Ffmpeg',
@ -58,10 +59,10 @@ protected $defaults = array(
'LabelX' => 0, 'LabelX' => 0,
'LabelY' => 0, 'LabelY' => 0,
'LabelSize' => 1, 'LabelSize' => 1,
'ImageBufferCount' => 100, 'ImageBufferCount' => 20,
'WarmupCount' => 0, 'WarmupCount' => 0,
'PreEventCount' => 0, 'PreEventCount' => 5,
'PostEventCount' => 0, 'PostEventCount' => 5,
'StreamReplayBuffer' => 0, 'StreamReplayBuffer' => 0,
'AlarmFrameCount' => 1, 'AlarmFrameCount' => 1,
'SectionLength' => 600, 'SectionLength' => 600,
@ -88,7 +89,7 @@ protected $defaults = array(
'DefaultScale' => 100, 'DefaultScale' => 100,
'SignalCheckPoints' => 0, 'SignalCheckPoints' => 0,
'SignalCheckColour' => '#0000BE', 'SignalCheckColour' => '#0000BE',
'WebColour' => 'red', 'WebColour' => '#ff0000',
'Exif' => array('type'=>'boolean','default'=>0), 'Exif' => array('type'=>'boolean','default'=>0),
'Sequence' => null, 'Sequence' => null,
'TotalEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1), 'TotalEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
@ -116,18 +117,18 @@ private $status_fields = array(
); );
public function Control() { public function Control() {
if ( !array_key_exists('Control', $this) ) { if ( !property_exists($this, 'Control') ) {
if ( $this->ControlId() ) if ( $this->ControlId() )
$this->{'Control'} = Control::find_one(array('Id'=>$this->{'ControlId'})); $this->{'Control'} = Control::find_one(array('Id'=>$this->{'ControlId'}));
if ( !(array_key_exists('Control', $this) and $this->{'Control'}) ) if ( !(property_exists($this, 'Control') and $this->{'Control'}) )
$this->{'Control'} = new Control(); $this->{'Control'} = new Control();
} }
return $this->{'Control'}; return $this->{'Control'};
} }
public function Server() { public function Server() {
return new Server($this->{'ServerId'}); return Server::find_one(array('Id'=>$this->{'ServerId'}));
} }
public function __call($fn, array $args){ public function __call($fn, array $args){
@ -138,7 +139,7 @@ private $status_fields = array(
$this->{$fn} = $args[0]; $this->{$fn} = $args[0];
} }
} }
if ( array_key_exists($fn, $this) ) { if ( property_exists($this, $fn) ) {
return $this->{$fn}; return $this->{$fn};
} else if ( array_key_exists($fn, $this->defaults) ) { } else if ( array_key_exists($fn, $this->defaults) ) {
if ( is_array($this->defaults[$fn]) ) { if ( is_array($this->defaults[$fn]) ) {
@ -211,9 +212,9 @@ private $status_fields = array(
$this->{'Width'} = $new; $this->{'Width'} = $new;
$field = ( $this->Orientation() == 'ROTATE_90' or $this->Orientation() == 'ROTATE_270' ) ? 'Height' : 'Width'; $field = ( $this->Orientation() == 'ROTATE_90' or $this->Orientation() == 'ROTATE_270' ) ? 'Height' : 'Width';
if ( array_key_exists($field, $this) ) if ( property_exists($this, $field) )
return $this->{$field}; return $this->{$field};
return $this->defaults{$field}; return $this->defaults[$field];
} // end function Width } // end function Width
public function ViewHeight($new=null) { public function ViewHeight($new=null) {
@ -221,9 +222,9 @@ private $status_fields = array(
$this->{'Height'} = $new; $this->{'Height'} = $new;
$field = ( $this->Orientation() == 'ROTATE_90' or $this->Orientation() == 'ROTATE_270' ) ? 'Width' : 'Height'; $field = ( $this->Orientation() == 'ROTATE_90' or $this->Orientation() == 'ROTATE_270' ) ? 'Width' : 'Height';
if ( array_key_exists($field, $this) ) if ( property_exists($this, $field) )
return $this->{$field}; return $this->{$field};
return $this->defaults{$field}; return $this->defaults[$field];
} // end function Height } // end function Height
public function SignalCheckColour($new=null) { public function SignalCheckColour($new=null) {
@ -234,10 +235,10 @@ private $status_fields = array(
// Validate that it's a valid colour (we seem to allow color names, not just hex). // Validate that it's a valid colour (we seem to allow color names, not just hex).
// This also helps prevent XSS. // This also helps prevent XSS.
if (array_key_exists($field, $this) && preg_match('/^[#0-9a-zA-Z]+$/', $this->{$field})) { if ( property_exists($this, $field) && preg_match('/^[#0-9a-zA-Z]+$/', $this->{$field})) {
return $this->{$field}; return $this->{$field};
} }
return $this->defaults{$field}; return $this->defaults[$field];
} // end function SignalCheckColour } // end function SignalCheckColour
public static function find( $parameters = array(), $options = array() ) { public static function find( $parameters = array(), $options = array() ) {
@ -253,7 +254,7 @@ private $status_fields = array(
Warning('Attempt to control a monitor with no Id'); Warning('Attempt to control a monitor with no Id');
return; return;
} }
if ( (!defined('ZM_SERVER_ID')) or ( array_key_exists('ServerId', $this) and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) { if ( (!defined('ZM_SERVER_ID')) or ( property_exists($this, 'ServerId') and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
if ( $this->Type() == 'Local' ) { if ( $this->Type() == 'Local' ) {
$zmcArgs = '-d '.$this->{'Device'}; $zmcArgs = '-d '.$this->{'Device'};
} else { } else {
@ -306,7 +307,7 @@ private $status_fields = array(
return; return;
} }
if ( (!defined('ZM_SERVER_ID')) or ( array_key_exists('ServerId', $this) and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) { if ( (!defined('ZM_SERVER_ID')) or ( property_exists($this, 'ServerId') and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
if ( $this->{'Function'} == 'None' || $this->{'Function'} == 'Monitor' || $mode == 'stop' ) { if ( $this->{'Function'} == 'None' || $this->{'Function'} == 'Monitor' || $mode == 'stop' ) {
if ( ZM_OPT_CONTROL ) { if ( ZM_OPT_CONTROL ) {
daemonControl('stop', 'zmtrack.pl', '-m '.$this->{'Id'}); daemonControl('stop', 'zmtrack.pl', '-m '.$this->{'Id'});
@ -367,8 +368,8 @@ private $status_fields = array(
} }
} }
if ( !array_key_exists('GroupIds', $this) ) { if ( !property_exists($this, 'GroupIds') ) {
if ( array_key_exists('Id', $this) and $this->{'Id'} ) { if ( property_exists($this, 'Id') and $this->{'Id'} ) {
$this->{'GroupIds'} = dbFetchAll('SELECT `GroupId` FROM `Groups_Monitors` WHERE `MonitorId`=?', 'GroupId', array($this->{'Id'}) ); $this->{'GroupIds'} = dbFetchAll('SELECT `GroupId` FROM `Groups_Monitors` WHERE `MonitorId`=?', 'GroupId', array($this->{'Id'}) );
if ( ! $this->{'GroupIds'} ) if ( ! $this->{'GroupIds'} )
$this->{'GroupIds'} = array(); $this->{'GroupIds'} = array();
@ -417,7 +418,7 @@ private $status_fields = array(
if ( $new ) { if ( $new ) {
$this->{'Storage'} = $new; $this->{'Storage'} = $new;
} }
if ( ! ( array_key_exists('Storage', $this) and $this->{'Storage'} ) ) { if ( ! ( property_exists($this, 'Storage') and $this->{'Storage'} ) ) {
$this->{'Storage'} = isset($this->{'StorageId'}) ? $this->{'Storage'} = isset($this->{'StorageId'}) ?
Storage::find_one(array('Id'=>$this->{'StorageId'})) : Storage::find_one(array('Id'=>$this->{'StorageId'})) :
new Storage(NULL); new Storage(NULL);
@ -467,8 +468,8 @@ private $status_fields = array(
return $source; return $source;
} // end function Source } // end function Source
public function UrlToIndex() { public function UrlToIndex($port=null) {
return $this->Server()->UrlToIndex(); return $this->Server()->UrlToIndex($port);
//ZM_MIN_STREAMING_PORT ? (ZM_MIN_STREAMING_PORT+$this->Id()) : null); //ZM_MIN_STREAMING_PORT ? (ZM_MIN_STREAMING_PORT+$this->Id()) : null);
} }
@ -493,7 +494,7 @@ public function sendControlCommand($command) {
} }
} }
if ( (!defined('ZM_SERVER_ID')) or ( array_key_exists('ServerId', $this) and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) { if ( (!defined('ZM_SERVER_ID')) or ( property_exists($this, 'ServerId') and (ZM_SERVER_ID==$this->{'ServerId'}) ) ) {
# Local # Local
Logger::Debug('Trying to send options ' . print_r($options, true)); Logger::Debug('Trying to send options ' . print_r($options, true));

View File

@ -1,133 +1,22 @@
<?php <?php
namespace ZM; namespace ZM;
require_once('Object.php');
require_once('database.php'); class MontageLayout extends ZM_Object {
protected static $table = 'MontageLayouts';
class MontageLayout { protected $defaults = array(
private $defaults = array(
'Id' => null, 'Id' => null,
'Name' => '', 'Name' => '',
'Positions' => 0, 'Positions' => 0,
); );
public function __construct( $IdOrRow = NULL ) { public static function find( $parameters = array(), $options = array() ) {
if ( $IdOrRow ) { return ZM_Object::_find(get_class(), $parameters, $options);
$row = NULL;
if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) {
$row = dbFetchOne( 'SELECT * FROM MontageLayouts WHERE Id=?', NULL, array( $IdOrRow ) );
if ( ! $row ) {
Error("Unable to load MontageLayout record for Id=" . $IdOrRow );
}
} else if ( is_array( $IdOrRow ) ) {
$row = $IdOrRow;
} else {
Error("Unknown argument passed to MontageLayout Constructor ($IdOrRow)");
return;
} }
if ( $row ) { public static function find_one( $parameters = array(), $options = array() ) {
foreach ($row as $k => $v) { return ZM_Object::_find_one(get_class(), $parameters, $options);
$this->{$k} = $v;
} }
} else {
Error('No row for MontageLayout ' . $IdOrRow );
}
} # end if isset($IdOrRow)
} // end function __construct
public function __call($fn, array $args){
if ( count($args) ) {
$this->{$fn} = $args[0];
}
if ( array_key_exists($fn, $this) ) {
return $this->{$fn};
} else {
if ( array_key_exists( $fn, $this->defaults ) ) {
return $this->defaults{$fn};
} else {
$backTrace = debug_backtrace();
$file = $backTrace[1]['file'];
$line = $backTrace[1]['line'];
Warning( "Unknown function call MontageLayout->$fn from $file:$line" );
}
}
}
public function set( $data ) {
foreach ($data as $k => $v) {
if ( is_array( $v ) ) {
# perhaps should turn into a comma-separated string
$this->{$k} = implode(',',$v);
} else if ( is_string( $v ) ) {
$this->{$k} = trim( $v );
} else if ( is_integer( $v ) ) {
$this->{$k} = $v;
} else if ( is_bool( $v ) ) {
$this->{$k} = $v;
} else {
Error( "Unknown type $k => $v of var " . gettype( $v ) );
$this->{$k} = $v;
}
}
}
public static function find( $parameters = null, $options = null ) {
$filters = array();
$sql = 'SELECT * FROM MontageLayouts ';
$values = array();
if ( $parameters ) {
$fields = array();
$sql .= 'WHERE ';
foreach ( $parameters as $field => $value ) {
if ( $value == null ) {
$fields[] = $field.' IS NULL';
} else if ( is_array( $value ) ) {
$func = function(){return '?';};
$fields[] = $field.' IN ('.implode(',', array_map( $func, $value ) ). ')';
$values += $value;
} else {
$fields[] = $field.'=?';
$values[] = $value;
}
}
$sql .= implode(' AND ', $fields );
}
if ( $options and isset($options['order']) ) {
$sql .= ' ORDER BY ' . $options['order'];
}
$result = dbQuery($sql, $values);
if ( $result ) {
$results = $result->fetchALL();
foreach ( $results as $row ) {
$filters[] = new MontageLayout($row);
}
}
return $filters;
}
public function save( $new_values = null ) {
if ( $new_values ) {
foreach ( $new_values as $k=>$v ) {
$this->{$k} = $v;
}
}
$fields = array_values( array_filter( array_keys($this->defaults), function($field){return $field != 'Id';} ) );
$values = null;
if ( isset($this->{'Id'}) ) {
$sql = 'UPDATE MontageLayouts SET '.implode(', ', array_map( function($field) {return $field.'=?';}, $fields ) ) . ' WHERE Id=?';
$values = array_map( function($field){return $this->{$field};}, $fields );
$values[] = $this->{'Id'};
dbQuery($sql, $values);
} else {
$sql = 'INSERT INTO MontageLayouts ('.implode( ',', $fields ).') VALUES ('.implode(',',array_map( function(){return '?';}, $fields ) ).')';
$values = array_map( function($field){return $this->{$field};}, $fields );
dbQuery($sql, $values);
global $dbConn;
$this->{'Id'} = $dbConn->lastInsertId();
}
} // end function save
} // end class MontageLayout } // end class MontageLayout
?> ?>

View File

@ -45,7 +45,7 @@ class ZM_Object {
$this->{$fn} = $args[0]; $this->{$fn} = $args[0];
} }
if ( array_key_exists($fn, $this) ) { if ( property_exists($this, $fn) ) {
return $this->{$fn}; return $this->{$fn};
} else { } else {
if ( array_key_exists($fn, $this->defaults) ) { if ( array_key_exists($fn, $this->defaults) ) {
@ -110,8 +110,9 @@ class ZM_Object {
public static function _find_one($class, $parameters = array(), $options = array() ) { public static function _find_one($class, $parameters = array(), $options = array() ) {
global $object_cache; global $object_cache;
if ( ! isset($object_cache[$class]) ) if ( ! isset($object_cache[$class]) ) {
$object_cache[$class] = array(); $object_cache[$class] = array();
}
$cache = &$object_cache[$class]; $cache = &$object_cache[$class];
if ( if (
( count($parameters) == 1 ) and ( count($parameters) == 1 ) and
@ -140,10 +141,10 @@ class ZM_Object {
foreach ($this->defaults as $key => $value) { foreach ($this->defaults as $key => $value) {
if ( is_callable(array($this, $key)) ) { if ( is_callable(array($this, $key)) ) {
$json[$key] = $this->$key(); $json[$key] = $this->$key();
} else if ( array_key_exists($key, $this) ) { } else if ( property_exists($this, $key) ) {
$json[$key] = $this->{$key}; $json[$key] = $this->{$key};
} else { } else {
$json[$key] = $this->defaults{$key}; $json[$key] = $this->defaults[$key];
} }
} }
return json_encode($json); return json_encode($json);
@ -158,14 +159,24 @@ class ZM_Object {
# perhaps should turn into a comma-separated string # perhaps should turn into a comma-separated string
$this->{$k} = implode(',', $v); $this->{$k} = implode(',', $v);
} else if ( is_string($v) ) { } else if ( is_string($v) ) {
if ( $v == '' and array_key_exists($k, $this->defaults) ) { if ( 0 ) {
if ( is_array($this->defaults[$k]) ) # Remarking this out. We are setting a value, not asking for a default to be set.
# So don't do defaults here, do them somewhere else
if ( ($v == null) and array_key_exists($k, $this->defaults) ) {
Logger::Debug("$k => Have default for $v: ");
if ( is_array($this->defaults[$k]) ) {
$this->{$k} = $this->defaults[$k]['default']; $this->{$k} = $this->defaults[$k]['default'];
else } else {
$this->{$k} = $this->defaults[$k]; $this->{$k} = $this->defaults[$k];
Logger::Debug("$k => Have default for $v: " . $this->{$k});
}
} else { } else {
$this->{$k} = trim($v); $this->{$k} = trim($v);
} }
} else {
$this->{$k} = trim($v);
}
} else if ( is_integer($v) ) { } else if ( is_integer($v) ) {
$this->{$k} = $v; $this->{$k} = $v;
} else if ( is_bool($v) ) { } else if ( is_bool($v) ) {
@ -215,7 +226,7 @@ class ZM_Object {
} else if ( $this->$field() != $value ) { } else if ( $this->$field() != $value ) {
$changes[$field] = $value; $changes[$field] = $value;
} }
} else if ( array_key_exists($field, $this) ) { } else if ( property_exists($this, $field) ) {
$type = (array_key_exists($field, $this->defaults) && is_array($this->defaults[$field])) ? $this->defaults[$field]['type'] : 'scalar'; $type = (array_key_exists($field, $this->defaults) && is_array($this->defaults[$field])) ? $this->defaults[$field]['type'] : 'scalar';
Logger::Debug("Checking field $field => current ". Logger::Debug("Checking field $field => current ".
(is_array($this->{$field}) ? implode(',',$this->{$field}) : $this->{$field}) . ' ?= ' . (is_array($this->{$field}) ? implode(',',$this->{$field}) : $this->{$field}) . ' ?= ' .
@ -280,6 +291,18 @@ class ZM_Object {
$this->set($new_values); $this->set($new_values);
} }
# Set defaults. Note that we only replace "" with null, not other values
# because for example if we want to clear TimestampFormat, we clear it, but the default is a string value
foreach ( $this->defaults as $field => $default ) {
if ( (!array_key_exists($field, $this)) or ($this->{$field} == '') ) {
if ( is_array($default) ) {
$this->{$field} = $default['default'];
} else if ( $default == null ) {
$this->{$field} = $default;
}
}
}
$fields = array_filter( $fields = array_filter(
$this->defaults, $this->defaults,
function($v) { function($v) {

View File

@ -80,7 +80,7 @@ class Server extends ZM_Object {
public function PathToZMS( $new = null ) { public function PathToZMS( $new = null ) {
if ( $new != null ) if ( $new != null )
$this{'PathToZMS'} = $new; $this->{'PathToZMS'} = $new;
if ( $this->Id() and $this->{'PathToZMS'} ) { if ( $this->Id() and $this->{'PathToZMS'} ) {
return $this->{'PathToZMS'}; return $this->{'PathToZMS'};
} else { } else {

View File

@ -80,7 +80,7 @@ class Storage extends ZM_Object {
} }
public function disk_total_space() { public function disk_total_space() {
if ( !array_key_exists('disk_total_space', $this) ) { if ( !property_exists($this, 'disk_total_space') ) {
$path = $this->Path(); $path = $this->Path();
if ( file_exists($path) ) { if ( file_exists($path) ) {
$this->{'disk_total_space'} = disk_total_space($path); $this->{'disk_total_space'} = disk_total_space($path);
@ -94,7 +94,7 @@ class Storage extends ZM_Object {
public function disk_used_space() { public function disk_used_space() {
# This isn't a function like this in php, so we have to add up the space used in each event. # This isn't a function like this in php, so we have to add up the space used in each event.
if ( ( !array_key_exists('disk_used_space', $this)) or !$this->{'disk_used_space'} ) { if ( ( !property_exists($this, 'disk_used_space')) or !$this->{'disk_used_space'} ) {
if ( $this->{'Type'} == 's3fs' ) { if ( $this->{'Type'} == 's3fs' ) {
$this->{'disk_used_space'} = $this->event_disk_space(); $this->{'disk_used_space'} = $this->event_disk_space();
} else { } else {
@ -112,7 +112,7 @@ class Storage extends ZM_Object {
public function event_disk_space() { public function event_disk_space() {
# This isn't a function like this in php, so we have to add up the space used in each event. # This isn't a function like this in php, so we have to add up the space used in each event.
if ( (! array_key_exists('DiskSpace', $this)) or (!$this->{'DiskSpace'}) ) { if ( (! property_exists($this, 'DiskSpace')) or (!$this->{'DiskSpace'}) ) {
$used = dbFetchOne('SELECT SUM(DiskSpace) AS DiskSpace FROM Events WHERE StorageId=? AND DiskSpace IS NOT NULL', 'DiskSpace', array($this->Id())); $used = dbFetchOne('SELECT SUM(DiskSpace) AS DiskSpace FROM Events WHERE StorageId=? AND DiskSpace IS NOT NULL', 'DiskSpace', array($this->Id()));
do { do {
@ -130,8 +130,8 @@ class Storage extends ZM_Object {
} // end function event_disk_space } // end function event_disk_space
public function Server() { public function Server() {
if ( ! array_key_exists('Server',$this) ) { if ( ! property_exists($this, 'Server') ) {
if ( array_key_exists('ServerId', $this) ) { if ( property_exists($this, 'ServerId') ) {
$this->{'Server'} = Server::find_one(array('Id'=>$this->{'ServerId'})); $this->{'Server'} = Server::find_one(array('Id'=>$this->{'ServerId'}));
if ( !$this->{'Server'} ) { if ( !$this->{'Server'} ) {

View File

@ -28,6 +28,65 @@ if ( $action == 'controlcap' ) {
require_once('includes/Control.php'); require_once('includes/Control.php');
$Control = new ZM\Control( !empty($_REQUEST['cid']) ? $_REQUEST['cid'] : null ); $Control = new ZM\Control( !empty($_REQUEST['cid']) ? $_REQUEST['cid'] : null );
$field_defaults = array(
'CanWake' => 0,
'CanSleep' => 0,
'CanReset' => 0,
'CanReboot' => 0,
'CanMove' => 0,
'CanMoveDiag' => 0,
'CanMoveMap' => 0,
'CanMoveRel' => 0,
'CanMoveAbs' => 0,
'CanMoveCon' => 0,
'CanPan' => 0,
'HasPanSpeed' => 0,
'HasTurboPan' => 0,
'CanTilt' => 0,
'HasTiltSpeed' => 0,
'HasTurboTilt' => 0,
'CanZoom' => 0,
'CanZoomRel' => 0,
'CanZoomAbs' => 0,
'CanZoomCon' => 0,
'HasZoomSpeed' => 0,
'CanFocus' => 0,
'CanAutoFocus' => 0,
'CanFocusRel' => 0,
'CanFocusAbs' => 0,
'CanFocusCon' => 0,
'HasFocusSpeed' => 0,
'CanGain' => 0,
'CanAutoGain' => 0,
'CanGainRel' => 0,
'CanGainAbs' => 0,
'CanGainCon' => 0,
'HasGainSpeed' => 0,
'CanWhite' => 0,
'CanAutoWhite' => 0,
'CanWhiteRel' => 0,
'CanWhiteAbs' => 0,
'CanWhiteCon' => 0,
'HasWhiteSpeed' => 0,
'CanIris' => 0,
'CanAutoIris' => 0,
'CanIrisRel' => 0,
'CanIrisAbs' => 0,
'CanIrisCon' => 0,
'HasIrisSpeed' => 0,
'HasPresets' => 0,
'HasHomePreset' => 0,
'CanSetPresets' => 0,
);
# Checkboxes don't return an element in the POST data, so won't be present in newControl.
# So force a value for these fields
foreach ( $field_defaults as $field => $value ) {
if ( ! (isset($_REQUEST['newControl'][$field]) and $_REQUEST['newControl'][$field]) ) {
$_REQUEST['newControl'][$field] = $value;
}
} # end foreach type
//$changes = getFormChanges( $control, $_REQUEST['newControl'], $types, $columns ); //$changes = getFormChanges( $control, $_REQUEST['newControl'], $types, $columns );
$Control->save($_REQUEST['newControl']); $Control->save($_REQUEST['newControl']);
$refreshParent = true; $refreshParent = true;

View File

@ -39,7 +39,7 @@ if ( $action == 'function' ) {
$oldFunction = $monitor['Function']; $oldFunction = $monitor['Function'];
$oldEnabled = $monitor['Enabled']; $oldEnabled = $monitor['Enabled'];
if ( $newFunction != $oldFunction || $newEnabled != $oldEnabled ) { if ( $newFunction != $oldFunction || $newEnabled != $oldEnabled ) {
dbQuery('UPDATE Monitors SET Function=?, Enabled=? WHERE Id=?', dbQuery('UPDATE Monitors SET `Function`=?, `Enabled`=? WHERE `Id`=?',
array($newFunction, $newEnabled, $mid)); array($newFunction, $newEnabled, $mid));
$monitor['Function'] = $newFunction; $monitor['Function'] = $newFunction;

View File

@ -219,7 +219,6 @@ if ( $action == 'monitor' ) {
} else { } else {
ZM\Error('Error saving new Monitor.'); ZM\Error('Error saving new Monitor.');
$error_message = dbError($sql);
return; return;
} }
} }

View File

@ -31,7 +31,7 @@ if ( $action == 'state' ) {
} }
} else if ( $action == 'save' ) { } else if ( $action == 'save' ) {
if ( !empty($_REQUEST['runState']) || !empty($_REQUEST['newState']) ) { if ( !empty($_REQUEST['runState']) || !empty($_REQUEST['newState']) ) {
$sql = 'SELECT Id,Function,Enabled FROM Monitors ORDER BY Id'; $sql = 'SELECT `Id`,`Function`,`Enabled` FROM Monitors ORDER BY Id';
$definitions = array(); $definitions = array();
foreach ( dbFetchAll($sql) as $monitor ) { foreach ( dbFetchAll($sql) as $monitor ) {
$definitions[] = $monitor['Id'].':'.$monitor['Function'].':'.$monitor['Enabled']; $definitions[] = $monitor['Id'].':'.$monitor['Function'].':'.$monitor['Enabled'];
@ -39,11 +39,11 @@ if ( $action == 'state' ) {
$definition = join(',', $definitions); $definition = join(',', $definitions);
if ( $_REQUEST['newState'] ) if ( $_REQUEST['newState'] )
$_REQUEST['runState'] = $_REQUEST['newState']; $_REQUEST['runState'] = $_REQUEST['newState'];
dbQuery('REPLACE INTO States SET Name=?, Definition=?', array($_REQUEST['runState'],$definition)); dbQuery('REPLACE INTO `States` SET `Name`=?, `Definition`=?', array($_REQUEST['runState'],$definition));
} }
} else if ( $action == 'delete' ) { } else if ( $action == 'delete' ) {
if ( isset($_REQUEST['runState']) ) if ( isset($_REQUEST['runState']) )
dbQuery('DELETE FROM States WHERE Name=?', array($_REQUEST['runState'])); dbQuery('DELETE FROM `States` WHERE `Name`=?', array($_REQUEST['runState']));
} }
$view = 'console'; $view = 'console';
?> ?>

View File

@ -220,19 +220,19 @@ function generateAuthHash($useRemoteAddr, $force=false) {
function visibleMonitor($mid) { function visibleMonitor($mid) {
global $user; global $user;
return ( empty($user['MonitorIds']) || in_array($mid, explode(',', $user['MonitorIds'])) ); return ( $user && empty($user['MonitorIds']) || in_array($mid, explode(',', $user['MonitorIds'])) );
} }
function canView($area, $mid=false) { function canView($area, $mid=false) {
global $user; global $user;
return ( ($user[$area] == 'View' || $user[$area] == 'Edit') && ( !$mid || visibleMonitor($mid) ) ); return ( $user && ($user[$area] == 'View' || $user[$area] == 'Edit') && ( !$mid || visibleMonitor($mid) ) );
} }
function canEdit($area, $mid=false) { function canEdit($area, $mid=false) {
global $user; global $user;
return ( $user[$area] == 'Edit' && ( !$mid || visibleMonitor($mid) )); return ( $user && ($user[$area] == 'Edit') && ( !$mid || visibleMonitor($mid) ));
} }
function userFromSession() { function userFromSession() {

View File

@ -174,19 +174,21 @@ function loadConfig( $defineConsts=true ) {
// For Human-readability, use ZM_SERVER_HOST or ZM_SERVER_NAME in zm.conf, and convert it here to a ZM_SERVER_ID // For Human-readability, use ZM_SERVER_HOST or ZM_SERVER_NAME in zm.conf, and convert it here to a ZM_SERVER_ID
if ( ! defined('ZM_SERVER_ID') ) { if ( ! defined('ZM_SERVER_ID') ) {
require_once('Server.php');
if ( defined('ZM_SERVER_NAME') and ZM_SERVER_NAME ) { if ( defined('ZM_SERVER_NAME') and ZM_SERVER_NAME ) {
$server_id = dbFetchOne('SELECT Id FROM Servers WHERE Name=?', 'Id', array(ZM_SERVER_NAME)); # Use Server lookup so that it caches
if ( ! $server_id ) { $Server = ZM\Server::find_one(array('Name'=>ZM_SERVER_NAME));
Error('Invalid Multi-Server configration detected. ZM_SERVER_NAME set to ' . ZM_SERVER_NAME . ' in zm.conf, but no corresponding entry found in Servers table.'); if ( !$Server ) {
ZM\Error('Invalid Multi-Server configration detected. ZM_SERVER_NAME set to ' . ZM_SERVER_NAME . ' in zm.conf, but no corresponding entry found in Servers table.');
} else { } else {
define( 'ZM_SERVER_ID', $server_id ); define('ZM_SERVER_ID', $Server->Id());
} }
} else if ( defined('ZM_SERVER_HOST') and ZM_SERVER_HOST ) { } else if ( defined('ZM_SERVER_HOST') and ZM_SERVER_HOST ) {
$server_id = dbFetchOne('SELECT Id FROM Servers WHERE Name=?', 'Id', array(ZM_SERVER_HOST)); $Server = ZM\Server::find_one(array('Name'=>ZM_SERVER_HOST));
if ( ! $server_id ) { if ( ! $Server ) {
Error('Invalid Multi-Server configration detected. ZM_SERVER_HOST set to ' . ZM_SERVER_HOST . ' in zm.conf, but no corresponding entry found in Servers table.'); ZM\Error('Invalid Multi-Server configration detected. ZM_SERVER_HOST set to ' . ZM_SERVER_HOST . ' in zm.conf, but no corresponding entry found in Servers table.');
} else { } else {
define( 'ZM_SERVER_ID', $server_id ); define('ZM_SERVER_ID', $Server->Id());
} }
} }
} }
@ -197,21 +199,22 @@ function process_configfile($configFile) {
if ( is_readable( $configFile ) ) { if ( is_readable( $configFile ) ) {
$configvals = array(); $configvals = array();
$cfg = fopen( $configFile, 'r') or Error("Could not open config file: $configFile."); $cfg = fopen($configFile, 'r') or ZM\Error("Could not open config file: $configFile.");
while ( !feof($cfg) ) { while ( !feof($cfg) ) {
$str = fgets($cfg, 256); $str = fgets($cfg, 256);
if ( preg_match( '/^\s*$/', $str )) if ( preg_match('/^\s*(#.*)?$/', $str) ) {
continue; continue;
elseif ( preg_match( '/^\s*#/', $str )) } else if ( preg_match( '/^\s*([^=\s]+)\s*=\s*[\'"]*(.*?)[\'"]*\s*$/', $str, $matches )) {
continue;
elseif ( preg_match( '/^\s*([^=\s]+)\s*=\s*[\'"]*(.*?)[\'"]*\s*$/', $str, $matches ))
$configvals[$matches[1]] = $matches[2]; $configvals[$matches[1]] = $matches[2];
} else {
ZM\Error("Malformed line in config $configFile\n$str");
}
} }
fclose($cfg); fclose($cfg);
return( $configvals ); return $configvals;
} else { } else {
error_log("WARNING: ZoneMinder configuration file found but is not readable. Check file permissions on $configFile."); error_log("WARNING: ZoneMinder configuration file found but is not readable. Check file permissions on $configFile.");
return( false ); return false;
} }
} }

View File

@ -110,13 +110,7 @@ function dbError($sql) {
function dbEscape( $string ) { function dbEscape( $string ) {
global $dbConn; global $dbConn;
if ( version_compare(phpversion(), '4.3.0', '<')) if ( version_compare(phpversion(), '5.4', '<=') and get_magic_quotes_gpc() )
if ( get_magic_quotes_gpc() )
return $dbConn->quote(stripslashes($string));
else
return $dbConn->quote($string);
else
if ( get_magic_quotes_gpc() )
return $dbConn->quote(stripslashes($string)); return $dbConn->quote(stripslashes($string));
else else
return $dbConn->quote($string); return $dbConn->quote($string);
@ -212,6 +206,10 @@ function dbFetch($sql, $col=false) {
} }
function dbFetchNext($result, $col=false) { function dbFetchNext($result, $col=false) {
if ( !$result ) {
ZM\Error("dbFetchNext called on null result.");
return false;
}
if ( $dbRow = $result->fetch(PDO::FETCH_ASSOC) ) if ( $dbRow = $result->fetch(PDO::FETCH_ASSOC) )
return $col ? $dbRow[$col] : $dbRow; return $col ? $dbRow[$col] : $dbRow;
return false; return false;

View File

@ -409,6 +409,11 @@ ZM\Logger::Debug("Event type: " . gettype($event));
global $user; global $user;
if ( $event->Archived() ) {
ZM\Info('Cannot delete Archived event.');
return;
} # end if Archived
if ( $user['Events'] == 'Edit' ) { if ( $user['Events'] == 'Edit' ) {
$event->delete(); $event->delete();
} # CAN EDIT } # CAN EDIT
@ -1085,9 +1090,8 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&amp;') {
$terms = isset($filter['Query']) ? $filter['Query']['terms'] : NULL; $terms = isset($filter['Query']) ? $filter['Query']['terms'] : NULL;
if ( !isset($terms) ) { if ( !isset($terms) ) {
$backTrace = debug_backtrace(); $backTrace = debug_backtrace();
$file = $backTrace[1]['file']; ZM\Warning('No terms in filter');
$line = $backTrace[1]['line']; ZM\Warning(print_r($backTrace, true));
ZM\Warning("No terms in filter from $file:$line");
ZM\Warning(print_r($filter, true)); ZM\Warning(print_r($filter, true));
} }
if ( isset($terms) && count($terms) ) { if ( isset($terms) && count($terms) ) {
@ -1324,7 +1328,7 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&amp;') {
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][val]").'='.urlencode($term['val']); $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][val]").'='.urlencode($term['val']);
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][val]\" value=\"".htmlspecialchars($term['val'])."\"/>\n"; $filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][val]\" value=\"".htmlspecialchars($term['val'])."\"/>\n";
} }
} // end if ( isset($term['attr']) ) } // end if isset($term['attr'])
if ( isset($term['cbr']) && (string)(int)$term['cbr'] == $term['cbr'] ) { if ( isset($term['cbr']) && (string)(int)$term['cbr'] == $term['cbr'] ) {
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cbr]").'='.urlencode($term['cbr']); $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cbr]").'='.urlencode($term['cbr']);
$filter['sql'] .= ' '.str_repeat(')', $term['cbr']).' '; $filter['sql'] .= ' '.str_repeat(')', $term['cbr']).' ';
@ -1336,6 +1340,8 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&amp;') {
if ( $saveToSession ) { if ( $saveToSession ) {
$_SESSION['filter'] = $filter; $_SESSION['filter'] = $filter;
} }
} else {
$filter['query'] = $querySep.urlencode('filter[Query][terms]=[]');
} // end if terms } // end if terms
#if ( 0 ) { #if ( 0 ) {
@ -2580,20 +2586,22 @@ function html_radio($name, $values, $selected=null, $options=array(), $attrs=arr
if ( isset($options['container']) ) { if ( isset($options['container']) ) {
$html .= $options['container'][0]; $html .= $options['container'][0];
} }
$attributes = array_map(
function($attr, $value){return $attr.'="'.$value.'"';},
array_keys($attrs),
array_values($attrs)
);
$attributes_string = implode(' ', $attributes);
$html .= sprintf(' $html .= sprintf('
<div class="form-check%7$s"> <div class="form-check%7$s">
<label class="form-check-label radio%7$s" for="%1$s%6$s%2$s"> <label class="form-check-label radio%7$s" for="%1$s%6$s%2$s">
<input class="form-check-input" type="radio" name="%1$s" value="%2$s" id="%1$s%6$s%2$s" %4$s%5$s /> <input class="form-check-input" type="radio" name="%1$s" value="%2$s" id="%1$s%6$s%2$s" %4$s%5$s />
%3$s</label></div> %3$s</label></div>
', $name, $value, $label, ($value==$selected?' checked="checked"':''), ', $name, $value, $label, ($value==$selected?' checked="checked"':''),
implode(' ', array_map( $attributes_string,
function($attr, $value){return $attr.'="'.$value.'"';},
array_keys($attrs),
array_values($attrs)
),
),
(isset($options['id']) ? $options['id'] : ''), (isset($options['id']) ? $options['id'] : ''),
( ( (!isset($options['inline'])) or $options['inline'] ) ? '-inline' : ''), ( ( (!isset($options['inline'])) or $options['inline'] ) ? '-inline' : '')
); );
if ( isset($options['container']) ) { if ( isset($options['container']) ) {
$html .= $options['container'][1]; $html .= $options['container'][1];
@ -2602,4 +2610,12 @@ function html_radio($name, $values, $selected=null, $options=array(), $attrs=arr
return $html; return $html;
} # end sub html_radio } # end sub html_radio
function random_colour() {
return '#'.
str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT).
str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT).
str_pad( dechex( mt_rand( 0, 255 ) ), 2, '0', STR_PAD_LEFT);
}
?> ?>

View File

@ -274,7 +274,7 @@ class Logger {
} }
} }
} }
return( $this->databaseLevel ); return $this->databaseLevel;
} }
public function fileLevel( $fileLevel ) { public function fileLevel( $fileLevel ) {
@ -288,7 +288,7 @@ class Logger {
$this->openFile(); $this->openFile();
} }
} }
return( $this->fileLevel ); return $this->fileLevel;
} }
public function weblogLevel( $weblogLevel ) { public function weblogLevel( $weblogLevel ) {
@ -303,7 +303,7 @@ class Logger {
$this->weblogLevel = $weblogLevel; $this->weblogLevel = $weblogLevel;
} }
} }
return( $this->weblogLevel ); return $this->weblogLevel;
} }
public function syslogLevel( $syslogLevel ) { public function syslogLevel( $syslogLevel ) {
@ -317,7 +317,7 @@ class Logger {
$this->openSyslog(); $this->openSyslog();
} }
} }
return( $this->syslogLevel ); return $this->syslogLevel;
} }
private function openSyslog() { private function openSyslog() {
@ -329,11 +329,12 @@ class Logger {
} }
private function logFile($logFile) { private function logFile($logFile) {
if ( preg_match( '/^(.+)\+$/', $logFile, $matches ) ) if ( preg_match('/^(.+)\+$/', $logFile, $matches) ) {
$this->logFile = $matches[1].'.'.getmypid(); $this->logFile = $matches[1].'.'.getmypid();
else } else {
$this->logFile = $logFile; $this->logFile = $logFile;
} }
}
private function openFile() { private function openFile() {
if ( !$this->useErrorLog ) { if ( !$this->useErrorLog ) {
@ -353,12 +354,15 @@ class Logger {
} }
public function logPrint( $level, $string, $file=NULL, $line=NULL ) { public function logPrint( $level, $string, $file=NULL, $line=NULL ) {
if ( $level <= $this->effectiveLevel ) { if ( $level > $this->effectiveLevel ) {
return;
}
$string = preg_replace('/[\r\n]+$/', '', $string); $string = preg_replace('/[\r\n]+$/', '', $string);
$code = self::$codes[$level]; $code = self::$codes[$level];
$time = gettimeofday(); $time = gettimeofday();
$message = sprintf( '%s.%06d %s[%d].%s [%s]', strftime( '%x %H:%M:%S', $time['sec'] ), $time['usec'], $this->id, getmypid(), $code, $string ); $message = sprintf('%s.%06d %s[%d].%s [%s] [%s]', strftime('%x %H:%M:%S', $time['sec']), $time['usec'], $this->id, getmypid(), $code, $_SERVER['REMOTE_ADDR'], $string);
if ( is_null($file) ) { if ( is_null($file) ) {
if ( $this->useErrorLog || $this->databaseLevel > self::NOLOG ) { if ( $this->useErrorLog || $this->databaseLevel > self::NOLOG ) {
@ -373,18 +377,20 @@ class Logger {
} }
} }
if ( $this->useErrorLog ) if ( $this->useErrorLog ) {
$message .= ' at '.$file.' line '.$line; $message .= ' at '.$file.' line '.$line;
else } else {
$message = $message; $message = $message;
}
if ( $level <= $this->termLevel ) if ( $level <= $this->termLevel ) {
if ( $this->hasTerm ) if ( $this->hasTerm )
print($message."\n"); print($message."\n");
else else
print(preg_replace("/\n/", '<br/>', htmlspecialchars($message) ).'<br/>'); print(preg_replace("/\n/", '<br/>', htmlspecialchars($message) ).'<br/>');
}
if ( $level <= $this->fileLevel ) if ( $level <= $this->fileLevel ) {
if ( $this->useErrorLog ) { if ( $this->useErrorLog ) {
if ( !error_log($message."\n", 3, $this->logFile) ) { if ( !error_log($message."\n", 3, $this->logFile) ) {
if ( strnatcmp(phpversion(), '5.2.0') >= 0 ) { if ( strnatcmp(phpversion(), '5.2.0') >= 0 ) {
@ -395,14 +401,16 @@ class Logger {
} else if ( $this->logFd ) { } else if ( $this->logFd ) {
fprintf($this->logFd, $message."\n"); fprintf($this->logFd, $message."\n");
} }
}
$message = $code.' ['.$string.']'; $message = $code.' ['.$string.']';
if ( $level <= $this->syslogLevel ) if ( $level <= $this->syslogLevel )
syslog( self::$syslogPriorities[$level], $message ); syslog( self::$syslogPriorities[$level], $message );
if ( $level <= $this->databaseLevel ) { if ( $level <= $this->databaseLevel ) {
try { try {
global $dbConn; global $dbConn;
$sql = 'INSERT INTO Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) values ( ?, ?, ?, ?, ?, ?, ?, ? )'; $sql = 'INSERT INTO Logs ( TimeKey, Component, Pid, Level, Code, Message, File, Line ) VALUES ( ?, ?, ?, ?, ?, ?, ?, ? )';
$stmt = $dbConn->prepare($sql); $stmt = $dbConn->prepare($sql);
$result = $stmt->execute(array(sprintf('%d.%06d', $time['sec'], $time['usec']), $this->id, getmypid(), $level, $code, $string, $file, $line)); $result = $stmt->execute(array(sprintf('%d.%06d', $time['sec'], $time['usec']), $this->id, getmypid(), $level, $code, $string, $file, $line));
} catch(PDOException $ex) { } catch(PDOException $ex) {
@ -412,9 +420,9 @@ class Logger {
} }
// This has to be last as trigger_error can be fatal // This has to be last as trigger_error can be fatal
if ( $level <= $this->weblogLevel ) { if ( $level <= $this->weblogLevel ) {
if ( $this->useErrorLog ) if ( $this->useErrorLog ) {
error_log($message, 0); error_log($message, 0);
else } else {
trigger_error($message, self::$phpErrorLevels[$level]); trigger_error($message, self::$phpErrorLevels[$level]);
} }
} }

View File

@ -0,0 +1,4 @@
input[type="number"] {
width: 70px;
}

View File

@ -1,3 +1,9 @@
#content table.major .colCanMove, #content table.major .colCanZoom, #content table.major .colCanFocus, #content table.major .colCanIris, #content table.major .colCanWhiteBal, #content table.major .colHasPresets { #content table.major .colCanMove,
#content table.major .colCanZoom,
#content table.major .colCanFocus,
#content table.major .colCanIris,
#content table.major .colCanWhiteBal,
#content table.major .colHasPresets {
text-align: center; text-align: center;
} }

View File

@ -9,6 +9,10 @@
width: 100%; width: 100%;
} }
textarea,
input[name="newMonitor[Name]"] {
width: 100%;
}
input[name="newMonitor[Width]"], input[name="newMonitor[Width]"],
input[name="newMonitor[Height]"] { input[name="newMonitor[Height]"] {
width: 80px; width: 80px;

View File

@ -113,7 +113,7 @@ function exportEventDetail($event, $exportFrames, $exportImages) {
<table id="eventDetail"> <table id="eventDetail">
<tr><th scope="row"><?php echo translate('Id') ?></th><td><?php echo $event->Id() ?></td></tr> <tr><th scope="row"><?php echo translate('Id') ?></th><td><?php echo $event->Id() ?></td></tr>
<tr><th scope="row"><?php echo translate('Name') ?></th><td><?php echo validHtmlStr($event->Name()) ?></td></tr> <tr><th scope="row"><?php echo translate('Name') ?></th><td><?php echo validHtmlStr($event->Name()) ?></td></tr>
<tr><th scope="row"><?php echo translate('Monitor') ?></th><td><?php echo validHtmlStr($event->MonitorName()) ?> (<?php echo $event->MonitorId() ?>)</td></tr> <tr><th scope="row"><?php echo translate('Monitor') ?></th><td><?php echo validHtmlStr($event->Monitor()->Name()) ?> (<?php echo $event->MonitorId() ?>)</td></tr>
<tr><th scope="row"><?php echo translate('Cause') ?></th><td><?php echo validHtmlStr($event->Cause()) ?></td></tr> <tr><th scope="row"><?php echo translate('Cause') ?></th><td><?php echo validHtmlStr($event->Cause()) ?></td></tr>
<tr><th scope="row"><?php echo translate('Notes') ?></th><td><?php echo validHtmlStr($event->Notes()) ?></td></tr> <tr><th scope="row"><?php echo translate('Notes') ?></th><td><?php echo validHtmlStr($event->Notes()) ?></td></tr>
<tr><th scope="row"><?php echo translate('Time') ?></th><td><?php echo strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->StartTime())) ?></td></tr> <tr><th scope="row"><?php echo translate('Time') ?></th><td><?php echo strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->StartTime())) ?></td></tr>
@ -123,7 +123,7 @@ function exportEventDetail($event, $exportFrames, $exportImages) {
<tr><th scope="row"><?php echo translate('AttrTotalScore') ?></th><td><?php echo $event->TotScore() ?></td></tr> <tr><th scope="row"><?php echo translate('AttrTotalScore') ?></th><td><?php echo $event->TotScore() ?></td></tr>
<tr><th scope="row"><?php echo translate('AttrAvgScore') ?></th><td><?php echo $event->AvgScore() ?></td></tr> <tr><th scope="row"><?php echo translate('AttrAvgScore') ?></th><td><?php echo $event->AvgScore() ?></td></tr>
<tr><th scope="row"><?php echo translate('AttrMaxScore') ?></th><td><?php echo $event->MaxScore() ?></td></tr> <tr><th scope="row"><?php echo translate('AttrMaxScore') ?></th><td><?php echo $event->MaxScore() ?></td></tr>
<tr><th scope="row"><?php echo translate('Archived') ?></th><td><?php echo $event->Archived()?translate('Yes'):translate('No') ?></td></tr> <tr><th scope="row"><?php echo translate('Archived') ?></th><td><?php echo translate($event->Archived()?'Yes':'No') ?></td></tr>
</table> </table>
</div> </div>
</div> </div>
@ -226,13 +226,13 @@ function exportEventImages($event, $exportDetail, $exportFrames, $myfilelist) {
?> ?>
<body> <body>
<style> <style>
*.horizontal_track {background-color: #bbb;width: <?php echo$event->Width()?>px;line-height: 0px;font-size: 0px;text-align: left;padding: 4px;border: 1px solid;border-color: #ddd #999 #999 #ddd;} .horizontal_track {background-color: #bbb;width: <?php echo $event->Width()?>px;line-height: 0px;font-size: 0px;text-align: left;padding: 4px;border: 1px solid;border-color: #ddd #999 #999 #ddd;}
*.horizontal_slider {background-color: #666;width: 16px;height: 8px;position: relative;z-index: 2;line-height: 0;margin: 0;border: 2px solid;border-color: #999 #333 #333 #999;} .horizontal_slider {background-color: #666;width: 16px;height: 8px;position: relative;z-index: 2;line-height: 0;margin: 0;border: 2px solid;border-color: #999 #333 #333 #999;}
*.horizontal_slit {background-color: #333;width: <?php echo($event->Width()-10)?>px;height: 2px;margin: 4px 4px 2px 4px;line-height: 0;position: absolute;z-index: 1;border: 1px solid;border-color: #999 #ddd #ddd #999;} .horizontal_slit {background-color: #333;width: <?php echo($event->Width()-10)?>px;height: 2px;margin: 4px 4px 2px 4px;line-height: 0;position: absolute;z-index: 1;border: 1px solid;border-color: #999 #ddd #ddd #999;}
*.vertical_track {background-color: #bbb;padding: 3px 5px 15px 5px;border: 1px solid;border-color: #ddd #999 #999 #ddd;} .vertical_track {background-color: #bbb;padding: 3px 5px 15px 5px;border: 1px solid;border-color: #ddd #999 #999 #ddd;}
*.vertical_slider {background-color: #666;width: 18px;height: 8px;font: 0px;text-align: left;line-height: 0px;position: relative;z-index: 1;border: 2px solid;border-color: #999 #333 #333 #999;} .vertical_slider {background-color: #666;width: 18px;height: 8px;font: 0px;text-align: left;line-height: 0px;position: relative;z-index: 1;border: 2px solid;border-color: #999 #333 #333 #999;}
*.vertical_slit {background-color: #000;width: 2px;height: 100px;position: absolute;margin: 4px 10px 4px 10px;padding: 4px 0 1px 0;line-height: 0;font-size: 0;border: 1px solid;border-color: #666 #ccc #ccc #666;} .vertical_slit {background-color: #000;width: 2px;height: 100px;position: absolute;margin: 4px 10px 4px 10px;padding: 4px 0 1px 0;line-height: 0;font-size: 0;border: 1px solid;border-color: #666 #ccc #ccc #666;}
*.display_holder {background-color: #bbb;color: #fff;width: 34px;height: 20px;text-align: right;padding: 0;border: 1px solid;border-color: #ddd #999 #999 #ddd;} .display_holder {background-color: #bbb;color: #fff;width: 34px;height: 20px;text-align: right;padding: 0;border: 1px solid;border-color: #ddd #999 #999 #ddd;}
.value_display {background-color: #bbb;color: #333;width: 30px;margin: 0 2px;text-align: right;font-size: 8pt;font-face: verdana, arial, helvetica, sans-serif;font-weight: bold;line-height: 12px;border: 0;cursor: default;} .value_display {background-color: #bbb;color: #333;width: 30px;margin: 0 2px;text-align: right;font-size: 8pt;font-face: verdana, arial, helvetica, sans-serif;font-weight: bold;line-height: 12px;border: 0;cursor: default;}
</style> </style>
@ -247,7 +247,7 @@ function exportEventImages($event, $exportDetail, $exportFrames, $myfilelist) {
if ( $Monitor->VideoWriter() == '2' ) { if ( $Monitor->VideoWriter() == '2' ) {
# Passthrough # Passthrough
$Rotation = $event->Orientation(); $Rotation = $event->Orientation();
if ( in_array($event->Orientation(),array('90','270')) ) if ( in_array($event->Orientation(),array('ROTATE_90','ROTATE_270')) )
$Zoom = $event->Height()/$event->Width(); $Zoom = $event->Height()/$event->Width();
} }
?> ?>
@ -618,10 +618,10 @@ function exportEventImagesMaster($eids) {
<body> <body>
<h2><?php echo translate('Images') ?> Master</h2> <h2><?php echo translate('Images') ?> Master</h2>
<?php <?php
// TODO: Should use find to make this 1 db query $events = ZM\Event::find(array('Id'=>$eids));
foreach ($eids as $eid) {
foreach ($events as $event) {
//get monitor id and event id //get monitor id and event id
$event = new ZM\Event($eid);
$eventMonitorId[$eid] = $event->MonitorId(); $eventMonitorId[$eid] = $event->MonitorId();
$eventPath[$eid] = $event->Relative_Path(); $eventPath[$eid] = $event->Relative_Path();
} }
@ -653,20 +653,18 @@ function exportEventImagesMaster($eids) {
<div class="tab_content" id="all"> <div class="tab_content" id="all">
<h2> All </h2> <h2> All </h2>
<?php <?php
foreach($eids as $eid) { foreach($events as $event) {
$Event = new ZM\Event($eid); eventlist_html($event);
eventlist_html($Event); } # end foreach event
} # end foreach event id
?> ?>
</div> </div>
<?php <?php
foreach ($monitors as $monitor_id) { foreach ($monitors as $monitor_id) {
echo "<div class=\"tab_content\" id=\"tab$monitor_id\">"; echo "<div class=\"tab_content\" id=\"tab$monitor_id\">";
echo '<h2>Monitor: ' . $monitorNames[$monitor_id] . ' </h2>'; echo '<h2>Monitor: ' . $monitorNames[$monitor_id] . ' </h2>';
foreach ( $eids as $eid ) { foreach ( $events as $event ) {
$Event = new ZM\Event($eid); if ( $event->MonitorId() == $monitor_id ) {
if ( $Event->MonitorId() == $monitor_id ) { eventlist_html($event);
eventlist_html($Event);
} # end if its the right monitor } # end if its the right monitor
} # end foreach event } # end foreach event
echo '</div>'; echo '</div>';
@ -780,7 +778,7 @@ function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $ex
} }
fwrite($fp, exportEventDetail($event, $exportFrames, $exportImages)); fwrite($fp, exportEventDetail($event, $exportFrames, $exportImages));
fclose($fp); fclose($fp);
$exportFileList[$file] = $event->Id().'/'.$file; $exportFileList[$file] = $file;
} }
if ( $exportFrames ) { if ( $exportFrames ) {
$file = 'zmEventFrames.html'; $file = 'zmEventFrames.html';
@ -789,7 +787,7 @@ function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $ex
} }
fwrite($fp, exportEventFrames($event, $exportDetail, $exportImages)); fwrite($fp, exportEventFrames($event, $exportDetail, $exportImages));
fclose($fp); fclose($fp);
$exportFileList[$file] = $event->Id().'/'.$file; $exportFileList[$file] = $file;
} }
if ( $exportImages ) { if ( $exportImages ) {
@ -797,7 +795,7 @@ function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $ex
$myfilelist = array(); $myfilelist = array();
foreach ( $files as $file ) { foreach ( $files as $file ) {
if ( preg_match('/-(?:capture|analyse).jpg$/', $file ) ) { if ( preg_match('/-(?:capture|analyse).jpg$/', $file ) ) {
$myfilelist[$file] = $exportFileList[$file] = $event->Id().'/'.$file; $myfilelist[$file] = $exportFileList[$file] = $file;
} else { } else {
$filesLeft[$file] = $file; $filesLeft[$file] = $file;
} }
@ -806,12 +804,12 @@ function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $ex
// create an image slider // create an image slider
if ( !empty($myfilelist) ) { if ( !empty($myfilelist) ) {
$file = $event->Id().'/zmEventImages.html'; $file = 'zmEventImages.html';
if ( !($fp = fopen($file, 'w')) ) if ( !($fp = fopen($file, 'w')) )
ZM\Fatal("Can't open event images export file '$file'"); ZM\Fatal("Can't open event images export file '$file'");
fwrite($fp, exportEventImages($event, $exportDetail, $exportFrames, $myfilelist)); fwrite($fp, exportEventImages($event, $exportDetail, $exportFrames, $myfilelist));
fclose($fp); fclose($fp);
$exportFileList[$file] = $event->Id().'/'.$file; $exportFileList[$file] = $file;
} }
} # end if exportImages } # end if exportImages
@ -819,7 +817,7 @@ function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $ex
$filesLeft = array(); $filesLeft = array();
foreach ( $files as $file ) { foreach ( $files as $file ) {
if ( preg_match('/\.(?:mpg|mpeg|mov|swf|mp4|mkv|avi|asf|3gp)$/', $file) ) { if ( preg_match('/\.(?:mpg|mpeg|mov|swf|mp4|mkv|avi|asf|3gp)$/', $file) ) {
$exportFileList[$file] = $event->Id().'/'.$file; $exportFileList[$file] = $file;
} else { } else {
$filesLeft[$file] = $file; $filesLeft[$file] = $file;
} }
@ -829,7 +827,7 @@ function exportFileList($event, $exportDetail, $exportFrames, $exportImages, $ex
if ( $exportMisc ) { if ( $exportMisc ) {
foreach ( $files as $file ) { foreach ( $files as $file ) {
$exportFileList[$file] = $event->Id().'/'.$file; $exportFileList[$file] = $file;
} }
$files = array(); $files = array();
} }
@ -850,10 +848,10 @@ function exportEvents(
) { ) {
if ( !canView('Events') ) { if ( !canView('Events') ) {
ZM\Error("You do not have permission to view events."); ZM\Error('You do not have permission to view events.');
return false; return false;
} else if ( empty($eids) ) { } else if ( empty($eids) ) {
ZM\Error("Attempt to export an empty list of events."); ZM\Error('Attempt to export an empty list of events.');
return false; return false;
} }
@ -863,23 +861,22 @@ function exportEvents(
} }
# Ensure that we are going to be able to do this. # Ensure that we are going to be able to do this.
if ( ! file_exists(ZM_DIR_EXPORTS) ) { if ( ! ( mkdir(ZM_DIR_EXPORTS) or file_exists(ZM_DIR_EXPORTS) ) ) {
if ( ! mkdir(ZM_DIR_EXPORTS) ) { ZM\Fatal('Can\'t create exports dir at \''.ZM_DIR_EXPORTS.'\'');
ZM\Fatal("Can't create exports dir at '".ZM_DIR_EXPORTS."'");
}
} }
chmod(ZM_DIR_EXPORTS, 0700);
$export_dir = ZM_DIR_EXPORTS.'/zmExport_'.$connkey; $export_dir = ZM_DIR_EXPORTS.'/zmExport_'.$connkey;
# Ensure that we are going to be able to do this. # Ensure that we are going to be able to do this.
if ( ! file_exists($export_dir) ) { if ( ! ( mkdir($export_dir) or file_exists($export_dir) ) ) {
if ( ! mkdir($export_dir) ) {
ZM\Fatal("Can't create exports dir at '$export_dir'"); ZM\Fatal("Can't create exports dir at '$export_dir'");
} else { } else {
ZM\Logger::Debug("Successfully created dir '$export_dir'"); ZM\Logger::Debug("Successfully created dir '$export_dir'");
} }
} chmod($export_dir, 0700);
if ( !chdir($export_dir) ) if ( !chdir($export_dir) ) {
ZM\Fatal("Can't chdir to $export_dir"); ZM\Fatal("Can't chdir to $export_dir");
}
$export_root = 'zmExport'; $export_root = 'zmExport';
$export_listFile = 'zmFileList.txt'; $export_listFile = 'zmFileList.txt';
@ -889,27 +886,30 @@ function exportEvents(
if ( !is_array($eids) ) { if ( !is_array($eids) ) {
$eids = array($eids); $eids = array($eids);
} }
ZM\Logger::Debug("Eids: " . print_r($eids,true)); ZM\Logger::Debug('Eids: ' . print_r($eids,true));
foreach ( $eids as $eid ) { foreach ( $eids as $eid ) {
$event = new ZM\Event($eid); $event = new ZM\Event($eid);
$event_dir = $export_dir.'/'.$event->Id(); $event_dir = $export_dir.'/'.$event->Id();
if ( !mkdir($event_dir) ) if ( !(mkdir($event_dir) or file_exists($event_dir) ) ) {
ZM\Error("Can't mkdir $event_dir"); ZM\Error("Can't mkdir $event_dir");
}
$event_exportFileList = exportFileList($event, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc); $event_exportFileList = exportFileList($event, $exportDetail, $exportFrames, $exportImages, $exportVideo, $exportMisc);
ZM\Logger::Debug("File list for event $eid " . print_r($event_exportFileList, true)); ZM\Logger::Debug("File list for event $eid " . print_r($event_exportFileList, true));
$exportFileList = array_merge($exportFileList,$event_exportFileList); $exportFileList = array_merge($exportFileList,$event_exportFileList);
foreach ( $event_exportFileList as $file ) { foreach ( $event_exportFileList as $file ) {
if ( preg_match('/\.html$/', $file) ) if ( preg_match('/\.html$/', $file) )
continue; continue;
ZM\Logger::Debug('cp -as '.$event->Path().'/../'.$file.' '.$export_dir.'/'.$file); #exec('cp -as '.$event->Path().'/../'.$file.' '.$export_dir.'/'.$file, $output, $return);
exec('cp -as '.$event->Path().'/../'.$file.' '.$export_dir.'/'.$file); $cmd = 'cp -as '.$event->Path().'/'.$file.' '.$export_dir.'/'.$event->Id().'/'.$file. ' 2>&1';
} exec($cmd, $output, $return);
ZM\Logger::Debug($cmd.' return code: '.$return.' output: '.print_r($output,true));
} }
} # end foreach event
// create an master image // create an master image
if ( $exportImages ) { if ( $exportImages ) {
if ( !symlink(ZM_PATH_WEB.'/'.ZM_SKIN_PATH.'/js/jquery.js', $export_dir.'/jquery.js') ) if ( !symlink(ZM_PATH_WEB.'/'.ZM_SKIN_PATH.'/js/jquery.js', $export_dir.'/jquery.js') )
ZM\Error("Failed linking jquery.js"); ZM\Error('Failed linking jquery.js');
//if ( !symlink(ZM_PATH_WEB.'/'.ZM_SKIN_PATH.'/js/video.js', $export_dir.'/video.js') ) //if ( !symlink(ZM_PATH_WEB.'/'.ZM_SKIN_PATH.'/js/video.js', $export_dir.'/video.js') )
//Error("Failed linking video.js"); //Error("Failed linking video.js");
@ -960,12 +960,12 @@ function exportEvents(
@unlink($archive); @unlink($archive);
$command .= ' zmExport_' . $connkey.'/'; $command .= ' zmExport_' . $connkey.'/';
ZM\Logger::Debug("Command is $command");
exec($command, $output, $status); exec($command, $output, $status);
if ( $status ) { if ( $status ) {
ZM\Error("Command '$command' returned with status $status"); ZM\Error("Command '$command' returned with status $status");
if ( isset($output[0]) ) if ( isset($output[0]) ) {
ZM\Error("First line of output is '".$output[0]."'"); ZM\Error('First line of output is \''.$output[0].'\'');
}
return false; return false;
} }

View File

@ -290,12 +290,12 @@ if ( $user and $user['Username'] ) {
# zmaudit can clean the logs, but if we aren't running it, then we should clean them regularly # zmaudit can clean the logs, but if we aren't running it, then we should clean them regularly
if ( preg_match('/^\d+$/', ZM_LOG_DATABASE_LIMIT) ) { if ( preg_match('/^\d+$/', ZM_LOG_DATABASE_LIMIT) ) {
# Number of lines, instead of an interval # Number of lines, instead of an interval
$rows = dbFetchOne('SELECT Count(*) AS Rows FROM Logs', 'Rows'); $rows = dbFetchOne('SELECT Count(*) AS `Rows` FROM `Logs`', 'Rows');
if ( $rows > ZM_LOG_DATABASE_LIMIT ) { if ( $rows > ZM_LOG_DATABASE_LIMIT ) {
dbQuery('DELETE low_priority FROM Logs ORDER BY TimeKey ASC LIMIT ?', array($rows - ZM_LOG_DATABASE_LIMIT)); dbQuery('DELETE low_priority FROM `Logs` ORDER BY `TimeKey` ASC LIMIT ?', array($rows - ZM_LOG_DATABASE_LIMIT));
} }
} else if ( preg_match('/^\d\s*(hour|minute|day|week|month|year)$/', ZM_LOG_DATABASE_LIMIT, $matches) ) { } else if ( preg_match('/^\d\s*(hour|minute|day|week|month|year)$/', ZM_LOG_DATABASE_LIMIT, $matches) ) {
dbQuery('DELETE FROM Logs WHERE TimeKey < unix_timestamp( NOW() - interval '.ZM_LOG_DATABASE_LIMIT.') LIMIT 100'); dbQuery('DELETE FROM `Logs` WHERE `TimeKey` < unix_timestamp( NOW() - interval '.ZM_LOG_DATABASE_LIMIT.') LIMIT 100');
} else { } else {
ZM\Error('Potentially invalid value for ZM_LOG_DATABASE_LIMIT: ' . ZM_LOG_DATABASE_LIMIT); ZM\Error('Potentially invalid value for ZM_LOG_DATABASE_LIMIT: ' . ZM_LOG_DATABASE_LIMIT);
} }
@ -389,8 +389,8 @@ if ( (!ZM_OPT_USE_AUTH) or $user ) {
<li class="Load"><i class="material-icons md-18">trending_up</i>&nbsp;<?php echo translate('Load') ?>: <?php echo getLoad() ?></li> <li class="Load"><i class="material-icons md-18">trending_up</i>&nbsp;<?php echo translate('Load') ?>: <?php echo getLoad() ?></li>
<i class="material-icons md-18">storage</i> <i class="material-icons md-18">storage</i>
<?php <?php
$connections = dbFetchOne( "SHOW status WHERE variable_name='threads_connected'", 'Value' ); $connections = dbFetchOne('SHOW status WHERE variable_name=\'threads_connected\'', 'Value');
$max_connections = dbFetchOne( "SHOW variables WHERE variable_name='max_connections'", 'Value' ); $max_connections = dbFetchOne('SHOW variables WHERE variable_name=\'max_connections\'', 'Value');
$percent_used = $max_connections ? 100 * $connections / $max_connections : 100; $percent_used = $max_connections ? 100 * $connections / $max_connections : 100;
echo '<li'. ( $percent_used > 90 ? ' class="warning"' : '' ).'>'.translate('DB').':'.$connections.'/'.$max_connections.'</li>'; echo '<li'. ( $percent_used > 90 ? ' class="warning"' : '' ).'>'.translate('DB').':'.$connections.'/'.$max_connections.'</li>';
?> ?>
@ -398,8 +398,12 @@ if ( (!ZM_OPT_USE_AUTH) or $user ) {
<?php <?php
$storage_areas = ZM\Storage::find(); $storage_areas = ZM\Storage::find();
$storage_paths = null; $storage_paths = null;
$storage_areas_with_no_server_id = array();
foreach ( $storage_areas as $area ) { foreach ( $storage_areas as $area ) {
$storage_paths[$area->Path()] = $area; $storage_paths[$area->Path()] = $area;
if ( ! $area->ServerId() ) {
$storage_areas_with_no_server_id[] = $area;
}
} }
$func = function($S){ $func = function($S){
$class = ''; $class = '';
@ -415,7 +419,7 @@ if ( (!ZM_OPT_USE_AUTH) or $user ) {
'; }; '; };
#$func = function($S){ return '<span title="">'.$S->Name() . ': ' . $S->disk_usage_percent().'%' . '</span>'; }; #$func = function($S){ return '<span title="">'.$S->Name() . ': ' . $S->disk_usage_percent().'%' . '</span>'; };
if ( count($storage_areas) > 4 ) if ( count($storage_areas) > 4 )
$storage_areas = ZM\Storage::find( array('ServerId'=>null) ); $storage_areas = $storage_areas_with_no_server_id;
if ( count($storage_areas) <= 4 ) if ( count($storage_areas) <= 4 )
echo implode(', ', array_map($func, $storage_areas)); echo implode(', ', array_map($func, $storage_areas));
echo ' ' . ZM_PATH_MAP .': '. getDiskPercent(ZM_PATH_MAP).'%'; echo ' ' . ZM_PATH_MAP .': '. getDiskPercent(ZM_PATH_MAP).'%';

View File

@ -29,7 +29,7 @@ var popupSizes = {
'console': {'width': 750, 'height': 312}, 'console': {'width': 750, 'height': 312},
'control': {'width': 480, 'height': 480}, 'control': {'width': 480, 'height': 480},
'controlcaps': {'width': 780, 'height': 320}, 'controlcaps': {'width': 780, 'height': 320},
'controlcap': {'width': 400, 'height': 400}, 'controlcap': {'width': 600, 'height': 500},
'cycle': {'addWidth': 32, 'minWidth': 384, 'addHeight': 62}, 'cycle': {'addWidth': 32, 'minWidth': 384, 'addHeight': 62},
'device': {'width': 260, 'height': 150}, 'device': {'width': 260, 'height': 150},
'devices': {'width': 400, 'height': 240}, 'devices': {'width': 400, 'height': 240},
@ -46,7 +46,7 @@ var popupSizes = {
'group': {'width': 760, 'height': 600}, 'group': {'width': 760, 'height': 600},
'groups': {'width': 540, 'height': 420}, 'groups': {'width': 540, 'height': 420},
'image': {'addWidth': 48, 'addHeight': 80}, 'image': {'addWidth': 48, 'addHeight': 80},
'log': {'width': 1080, 'height': 720}, 'log': {'width': 1180, 'height': 720},
'login': {'width': 720, 'height': 480}, 'login': {'width': 720, 'height': 480},
'logout': {'width': 260, 'height': 150}, 'logout': {'width': 260, 'height': 150},
'monitor': {'width': 800, 'height': 780}, 'monitor': {'width': 800, 'height': 780},

View File

@ -175,12 +175,13 @@ window.addEventListener("DOMContentLoaded", function onSkinDCL() {
}); });
// 'data-on-click' calls the global function in the attribute value with no arguments when a click happens. // 'data-on-click' calls the global function in the attribute value with no arguments when a click happens.
document.querySelectorAll("a[data-on-click], button[data-on-click], input[data-on-click]").forEach(function attachOnClick(el) { document.querySelectorAll("i[data-on-click], a[data-on-click], button[data-on-click], input[data-on-click]").forEach(function attachOnClick(el) {
var fnName = el.getAttribute("data-on-click"); var fnName = el.getAttribute("data-on-click");
if ( !window[fnName] ) { if ( !window[fnName] ) {
console.error("Nothing found to bind to " + fnName + " on element " + el.name); console.error("Nothing found to bind to " + fnName + " on element " + el.name);
return; return;
} }
el.onclick = function() { el.onclick = function() {
window[fnName](); window[fnName]();
}; };

View File

@ -187,7 +187,8 @@ getBodyTopHTML();
<button type="button" name="cloneBtn" data-on-click-this="cloneMonitor" <button type="button" name="cloneBtn" data-on-click-this="cloneMonitor"
<?php echo (canEdit('Monitors') && !$user['MonitorIds']) ? '' : ' disabled="disabled"' ?> <?php echo (canEdit('Monitors') && !$user['MonitorIds']) ? '' : ' disabled="disabled"' ?>
style="display:none;"> style="display:none;">
<i class="material-icons md-18">copy</i> <i class="material-icons md-18">content_copy</i>
<!--content_copy used instead of file_copy as there is a bug in material-icons -->
&nbsp;<?php echo translate('CloneMonitor') ?> &nbsp;<?php echo translate('CloneMonitor') ?>
</button> </button>
<button type="button" name="editBtn" data-on-click-this="editMonitor" disabled="disabled"> <button type="button" name="editBtn" data-on-click-this="editMonitor" disabled="disabled">

View File

@ -18,40 +18,31 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
// //
if ( !canEdit( 'Control' ) ) if ( !canEdit('Control') ) {
{ $view = 'error';
$view = "error";
return; return;
} }
$tabs = array(); $tabs = array();
$tabs["main"] = translate('Main'); $tabs['main'] = translate('Main');
$tabs["move"] = translate('Move'); $tabs['move'] = translate('Move');
$tabs["pan"] = translate('Pan'); $tabs['pan'] = translate('Pan');
$tabs["tilt"] = translate('Tilt'); $tabs['tilt'] = translate('Tilt');
$tabs["zoom"] = translate('Zoom'); $tabs['zoom'] = translate('Zoom');
$tabs["focus"] = translate('Focus'); $tabs['focus'] = translate('Focus');
$tabs["white"] = translate('White'); $tabs['gain'] = translate('Gain');
$tabs["iris"] = translate('Iris'); $tabs['white'] = translate('White');
$tabs["presets"] = translate('Presets'); $tabs['iris'] = translate('Iris');
$tabs['presets'] = translate('Presets');
if ( isset($_REQUEST['tab']) ) $tab = isset($_REQUEST['tab']) ? validHtmlStr($_REQUEST['tab']) :'main';
$tab = validHtmlStr($_REQUEST['tab']);
else
$tab = "main";
if ( isset( $_REQUEST['newControl'] ) ) if ( isset($_REQUEST['newControl']) ) {
{
$newControl = $_REQUEST['newControl']; $newControl = $_REQUEST['newControl'];
} } else {
else if ( !empty($_REQUEST['cid']) ) {
{
if ( !empty($_REQUEST['cid']) )
{
$control = dbFetchOne('SELECT * FROM Controls WHERE Id = ?', NULL, array($_REQUEST['cid'])); $control = dbFetchOne('SELECT * FROM Controls WHERE Id = ?', NULL, array($_REQUEST['cid']));
} } else {
else
{
$control = array( $control = array(
'Name' => translate('New'), 'Name' => translate('New'),
'Type' => "Local", 'Type' => "Local",
@ -166,16 +157,12 @@ xhtmlHeaders(__FILE__, translate('ControlCap')." - ".$newControl['Name'] );
<div id="content"> <div id="content">
<ul class="tabList"> <ul class="tabList">
<?php <?php
foreach ( $tabs as $name=>$value ) foreach ( $tabs as $name=>$value ) {
{ if ( $tab == $name ) {
if ( $tab == $name )
{
?> ?>
<li class="active"><?php echo $value ?></li> <li class="active"><?php echo $value ?></li>
<?php <?php
} } else {
else
{
?> ?>
<li><a href="#" data-tab-name="<?php echo $name ?>"><?php echo $value ?></a></li> <li><a href="#" data-tab-name="<?php echo $name ?>"><?php echo $value ?></a></li>
<?php <?php
@ -190,8 +177,7 @@ foreach ( $tabs as $name=>$value )
<input type="hidden" name="action" value="controlcap"/> <input type="hidden" name="action" value="controlcap"/>
<input type="hidden" name="cid" value="<?php echo requestVar('cid') ?>"/> <input type="hidden" name="cid" value="<?php echo requestVar('cid') ?>"/>
<?php <?php
if ( $tab != 'main' ) if ( $tab != 'main' ) {
{
?> ?>
<input type="hidden" name="newControl[Name]" value="<?php echo validHtmlStr($newControl['Name']) ?>"/> <input type="hidden" name="newControl[Name]" value="<?php echo validHtmlStr($newControl['Name']) ?>"/>
<input type="hidden" name="newControl[Type]" value="<?php echo validHtmlStr($newControl['Type']) ?>"/> <input type="hidden" name="newControl[Type]" value="<?php echo validHtmlStr($newControl['Type']) ?>"/>
@ -201,8 +187,7 @@ if ( $tab != 'main' )
<input type="hidden" name="newControl[CanReset]" value="<?php echo !empty($newControl['CanReset']) ?>"/> <input type="hidden" name="newControl[CanReset]" value="<?php echo !empty($newControl['CanReset']) ?>"/>
<?php <?php
} }
if ( $tab != 'move' ) if ( $tab != 'move' ) {
{
?> ?>
<input type="hidden" name="newControl[CanMove]" value="<?php echo !empty($newControl['CanMove']) ?>"/> <input type="hidden" name="newControl[CanMove]" value="<?php echo !empty($newControl['CanMove']) ?>"/>
<input type="hidden" name="newControl[CanMoveDiag]" value="<?php echo !empty($newControl['CanMoveDiag']) ?>"/> <input type="hidden" name="newControl[CanMoveDiag]" value="<?php echo !empty($newControl['CanMoveDiag']) ?>"/>
@ -212,8 +197,7 @@ if ( $tab != 'move' )
<input type="hidden" name="newControl[CanMoveCon]" value="<?php echo !empty($newControl['CanMoveCon']) ?>"/> <input type="hidden" name="newControl[CanMoveCon]" value="<?php echo !empty($newControl['CanMoveCon']) ?>"/>
<?php <?php
} }
if ( $tab != 'pan' ) if ( $tab != 'pan' ) {
{
?> ?>
<input type="hidden" name="newControl[CanPan]" value="<?php echo !empty($newControl['CanPan']) ?>"/> <input type="hidden" name="newControl[CanPan]" value="<?php echo !empty($newControl['CanPan']) ?>"/>
<input type="hidden" name="newControl[MinPanRange]" value="<?php echo validHtmlStr($newControl['MinPanRange']) ?>"/> <input type="hidden" name="newControl[MinPanRange]" value="<?php echo validHtmlStr($newControl['MinPanRange']) ?>"/>
@ -227,8 +211,7 @@ if ( $tab != 'pan' )
<input type="hidden" name="newControl[TurboPanSpeed]" value="<?php echo validHtmlStr($newControl['TurboPanSpeed']) ?>"/> <input type="hidden" name="newControl[TurboPanSpeed]" value="<?php echo validHtmlStr($newControl['TurboPanSpeed']) ?>"/>
<?php <?php
} }
if ( $tab != 'tilt' ) if ( $tab != 'tilt' ) {
{
?> ?>
<input type="hidden" name="newControl[CanTilt]" value="<?php echo !empty($newControl['CanTilt']) ?>"/> <input type="hidden" name="newControl[CanTilt]" value="<?php echo !empty($newControl['CanTilt']) ?>"/>
<input type="hidden" name="newControl[MinTiltRange]" value="<?php echo validHtmlStr($newControl['MinTiltRange']) ?>"/> <input type="hidden" name="newControl[MinTiltRange]" value="<?php echo validHtmlStr($newControl['MinTiltRange']) ?>"/>
@ -242,8 +225,7 @@ if ( $tab != 'tilt' )
<input type="hidden" name="newControl[TurboTiltSpeed]" value="<?php echo validHtmlStr($newControl['TurboTiltSpeed']) ?>"/> <input type="hidden" name="newControl[TurboTiltSpeed]" value="<?php echo validHtmlStr($newControl['TurboTiltSpeed']) ?>"/>
<?php <?php
} }
if ( $tab != 'zoom' ) if ( $tab != 'zoom' ) {
{
?> ?>
<input type="hidden" name="newControl[CanZoom]" value="<?php echo !empty($newControl['CanZoom']) ?>"/> <input type="hidden" name="newControl[CanZoom]" value="<?php echo !empty($newControl['CanZoom']) ?>"/>
<input type="hidden" name="newControl[CanZoomAbs]" value="<?php echo !empty($newControl['CanZoomAbs']) ?>"/> <input type="hidden" name="newControl[CanZoomAbs]" value="<?php echo !empty($newControl['CanZoomAbs']) ?>"/>
@ -258,8 +240,7 @@ if ( $tab != 'zoom' )
<input type="hidden" name="newControl[MaxZoomSpeed]" value="<?php echo validHtmlStr($newControl['MaxZoomSpeed']) ?>"/> <input type="hidden" name="newControl[MaxZoomSpeed]" value="<?php echo validHtmlStr($newControl['MaxZoomSpeed']) ?>"/>
<?php <?php
} }
if ( $tab != 'focus' ) if ( $tab != 'focus' ) {
{
?> ?>
<input type="hidden" name="newControl[CanFocus]" value="<?php echo !empty($newControl['CanFocus']) ?>"/> <input type="hidden" name="newControl[CanFocus]" value="<?php echo !empty($newControl['CanFocus']) ?>"/>
<input type="hidden" name="newControl[CanAutoFocus]" value="<?php echo !empty($newControl['CanAutoFocus']) ?>"/> <input type="hidden" name="newControl[CanAutoFocus]" value="<?php echo !empty($newControl['CanAutoFocus']) ?>"/>
@ -275,8 +256,7 @@ if ( $tab != 'focus' )
<input type="hidden" name="newControl[MaxFocusSpeed]" value="<?php echo validHtmlStr($newControl['MaxFocusSpeed']) ?>"/> <input type="hidden" name="newControl[MaxFocusSpeed]" value="<?php echo validHtmlStr($newControl['MaxFocusSpeed']) ?>"/>
<?php <?php
} }
if ( $tab != 'iris' ) if ( $tab != 'iris' ) {
{
?> ?>
<input type="hidden" name="newControl[CanIris]" value="<?php echo !empty($newControl['CanIris']) ?>"/> <input type="hidden" name="newControl[CanIris]" value="<?php echo !empty($newControl['CanIris']) ?>"/>
<input type="hidden" name="newControl[CanAutoIris]" value="<?php echo !empty($newControl['CanAutoIris']) ?>"/> <input type="hidden" name="newControl[CanAutoIris]" value="<?php echo !empty($newControl['CanAutoIris']) ?>"/>
@ -292,8 +272,7 @@ if ( $tab != 'iris' )
<input type="hidden" name="newControl[MaxIrisSpeed]" value="<?php echo validHtmlStr($newControl['MaxIrisSpeed']) ?>"/> <input type="hidden" name="newControl[MaxIrisSpeed]" value="<?php echo validHtmlStr($newControl['MaxIrisSpeed']) ?>"/>
<?php <?php
} }
if ( $tab != 'gain' ) if ( $tab != 'gain' ) {
{
?> ?>
<input type="hidden" name="newControl[CanGain]" value="<?php echo !empty($newControl['CanGain']) ?>"/> <input type="hidden" name="newControl[CanGain]" value="<?php echo !empty($newControl['CanGain']) ?>"/>
<input type="hidden" name="newControl[CanAutoGain]" value="<?php echo !empty($newControl['CanAutoGain']) ?>"/> <input type="hidden" name="newControl[CanAutoGain]" value="<?php echo !empty($newControl['CanAutoGain']) ?>"/>
@ -309,8 +288,7 @@ if ( $tab != 'gain' )
<input type="hidden" name="newControl[MaxGainSpeed]" value="<?php echo validHtmlStr($newControl['MaxGainSpeed']) ?>"/> <input type="hidden" name="newControl[MaxGainSpeed]" value="<?php echo validHtmlStr($newControl['MaxGainSpeed']) ?>"/>
<?php <?php
} }
if ( $tab != 'white' ) if ( $tab != 'white' ) {
{
?> ?>
<input type="hidden" name="newControl[CanWhite]" value="<?php echo !empty($newControl['CanWhite']) ?>"/> <input type="hidden" name="newControl[CanWhite]" value="<?php echo !empty($newControl['CanWhite']) ?>"/>
<input type="hidden" name="newControl[CanAutoWhite]" value="<?php echo !empty($newControl['CanAutoWhite']) ?>"/> <input type="hidden" name="newControl[CanAutoWhite]" value="<?php echo !empty($newControl['CanAutoWhite']) ?>"/>
@ -326,8 +304,7 @@ if ( $tab != 'white' )
<input type="hidden" name="newControl[MaxWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MaxWhiteSpeed']) ?>"/> <input type="hidden" name="newControl[MaxWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MaxWhiteSpeed']) ?>"/>
<?php <?php
} }
if ( $tab != 'presets' ) if ( $tab != 'presets' ) {
{
?> ?>
<input type="hidden" name="newControl[HasPresets]" value="<?php echo !empty($newControl['HasPresets']) ?>"/> <input type="hidden" name="newControl[HasPresets]" value="<?php echo !empty($newControl['HasPresets']) ?>"/>
<input type="hidden" name="newControl[NumPresets]" value="<?php echo validHtmlStr($newControl['NumPresets']) ?>"/> <input type="hidden" name="newControl[NumPresets]" value="<?php echo validHtmlStr($newControl['NumPresets']) ?>"/>
@ -336,19 +313,17 @@ if ( $tab != 'presets' )
<?php <?php
} }
?> ?>
<table id="contentTable" class="major" cellspacing="0"> <table id="contentTable" class="major">
<tbody> <tbody>
<?php <?php
switch ( $tab ) switch ( $tab ) {
{
case 'main' : case 'main' :
{ {
?> ?>
<tr><th scope="row"><?php echo translate('Name') ?></th><td><input type="text" name="newControl[Name]" value="<?php echo validHtmlStr($newControl['Name']) ?>" size="24"/></td></tr> <tr><th scope="row"><?php echo translate('Name') ?></th><td><input type="text" name="newControl[Name]" value="<?php echo validHtmlStr($newControl['Name']) ?>"/></td></tr>
<?php <tr><th scope="row"><?php echo translate('Type') ?></th><td><?php
$types = array( 'Local'=>translate('Local'), 'Remote'=>translate('Remote'), 'Ffmpeg'=>translate('Ffmpeg'), 'Libvlc'=>translate('Libvlc'), 'cURL'=>"cURL"); $types = array( 'Local'=>translate('Local'), 'Remote'=>translate('Remote'), 'Ffmpeg'=>translate('Ffmpeg'), 'Libvlc'=>translate('Libvlc'), 'cURL'=>'cURL');
?> echo buildSelect('newControl[Type]', $types); ?></td></tr>
<tr><th scope="row"><?php echo translate('Type') ?></th><td><?php echo buildSelect( "newControl[Type]", $types ); ?></td></tr>
<tr><th scope="row"><?php echo translate('Protocol') ?></th><td><input type="text" name="newControl[Protocol]" value="<?php echo validHtmlStr($newControl['Protocol']) ?>" size="24"/></td></tr> <tr><th scope="row"><?php echo translate('Protocol') ?></th><td><input type="text" name="newControl[Protocol]" value="<?php echo validHtmlStr($newControl['Protocol']) ?>" size="24"/></td></tr>
<tr><th scope="row"><?php echo translate('CanWake') ?></th><td><input type="checkbox" name="newControl[CanWake]" value="1"<?php if ( !empty($newControl['CanWake']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanWake') ?></th><td><input type="checkbox" name="newControl[CanWake]" value="1"<?php if ( !empty($newControl['CanWake']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanSleep') ?></th><td><input type="checkbox" name="newControl[CanSleep]" value="1"<?php if ( !empty($newControl['CanSleep']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanSleep') ?></th><td><input type="checkbox" name="newControl[CanSleep]" value="1"<?php if ( !empty($newControl['CanSleep']) ) { ?> checked="checked"<?php } ?>/></td></tr>
@ -373,15 +348,15 @@ switch ( $tab )
{ {
?> ?>
<tr><th scope="row"><?php echo translate('CanPan') ?></th><td><input type="checkbox" name="newControl[CanPan]" value="1"<?php if ( !empty($newControl['CanPan']) ) { ?> checked="checked"<?php } ?>></td></tr> <tr><th scope="row"><?php echo translate('CanPan') ?></th><td><input type="checkbox" name="newControl[CanPan]" value="1"<?php if ( !empty($newControl['CanPan']) ) { ?> checked="checked"<?php } ?>></td></tr>
<tr><th scope="row"><?php echo translate('MinPanRange') ?></th><td><input type="text" name="newControl[MinPanRange]" value="<?php echo validHtmlStr($newControl['MinPanRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinPanRange') ?></th><td><input type="number" name="newControl[MinPanRange]" value="<?php echo validHtmlStr($newControl['MinPanRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxPanRange') ?></th><td><input type="text" name="newControl[MaxPanRange]" value="<?php echo validHtmlStr($newControl['MaxPanRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxPanRange') ?></th><td><input type="number" name="newControl[MaxPanRange]" value="<?php echo validHtmlStr($newControl['MaxPanRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinPanStep') ?></th><td><input type="text" name="newControl[MinPanStep]" value="<?php echo validHtmlStr($newControl['MinPanStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinPanStep') ?></th><td><input type="number" name="newControl[MinPanStep]" value="<?php echo validHtmlStr($newControl['MinPanStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxPanStep') ?></th><td><input type="text" name="newControl[MaxPanStep]" value="<?php echo validHtmlStr($newControl['MaxPanStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxPanStep') ?></th><td><input type="number" name="newControl[MaxPanStep]" value="<?php echo validHtmlStr($newControl['MaxPanStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasPanSpeed') ?></th><td><input type="checkbox" name="newControl[HasPanSpeed]" value="1"<?php if ( !empty($newControl['HasPanSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('HasPanSpeed') ?></th><td><input type="checkbox" name="newControl[HasPanSpeed]" value="1"<?php if ( !empty($newControl['HasPanSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinPanSpeed') ?></th><td><input type="text" name="newControl[MinPanSpeed]" value="<?php echo validHtmlStr($newControl['MinPanSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinPanSpeed') ?></th><td><input type="number" name="newControl[MinPanSpeed]" value="<?php echo validHtmlStr($newControl['MinPanSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxPanSpeed') ?></th><td><input type="text" name="newControl[MaxPanSpeed]" value="<?php echo validHtmlStr($newControl['MaxPanSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxPanSpeed') ?></th><td><input type="number" name="newControl[MaxPanSpeed]" value="<?php echo validHtmlStr($newControl['MaxPanSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasTurboPan') ?></th><td><input type="checkbox" name="newControl[HasTurboPan]" value="1"<?php if ( !empty($newControl['HasTurboPan']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('HasTurboPan') ?></th><td><input type="checkbox" name="newControl[HasTurboPan]" value="1"<?php if ( !empty($newControl['HasTurboPan']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('TurboPanSpeed') ?></th><td><input type="text" name="newControl[TurboPanSpeed]" value="<?php echo validHtmlStr($newControl['TurboPanSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('TurboPanSpeed') ?></th><td><input type="number" name="newControl[TurboPanSpeed]" value="<?php echo validHtmlStr($newControl['TurboPanSpeed']) ?>"/></td></tr>
<?php <?php
break; break;
} }
@ -389,15 +364,15 @@ switch ( $tab )
{ {
?> ?>
<tr><th scope="row"><?php echo translate('CanTilt') ?></th><td><input type="checkbox" name="newControl[CanTilt]" value="1"<?php if ( !empty($newControl['CanTilt']) ) { ?> checked="checked"<?php } ?>></td></tr> <tr><th scope="row"><?php echo translate('CanTilt') ?></th><td><input type="checkbox" name="newControl[CanTilt]" value="1"<?php if ( !empty($newControl['CanTilt']) ) { ?> checked="checked"<?php } ?>></td></tr>
<tr><th scope="row"><?php echo translate('MinTiltRange') ?></th><td><input type="text" name="newControl[MinTiltRange]" value="<?php echo validHtmlStr($newControl['MinTiltRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinTiltRange') ?></th><td><input type="number" name="newControl[MinTiltRange]" value="<?php echo validHtmlStr($newControl['MinTiltRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxTiltRange') ?></th><td><input type="text" name="newControl[MaxTiltRange]" value="<?php echo validHtmlStr($newControl['MaxTiltRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxTiltRange') ?></th><td><input type="number" name="newControl[MaxTiltRange]" value="<?php echo validHtmlStr($newControl['MaxTiltRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinTiltStep') ?></th><td><input type="text" name="newControl[MinTiltStep]" value="<?php echo validHtmlStr($newControl['MinTiltStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinTiltStep') ?></th><td><input type="number" name="newControl[MinTiltStep]" value="<?php echo validHtmlStr($newControl['MinTiltStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxTiltStep') ?></th><td><input type="text" name="newControl[MaxTiltStep]" value="<?php echo validHtmlStr($newControl['MaxTiltStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxTiltStep') ?></th><td><input type="number" name="newControl[MaxTiltStep]" value="<?php echo validHtmlStr($newControl['MaxTiltStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasTiltSpeed') ?></th><td><input type="checkbox" name="newControl[HasTiltSpeed]" value="1"<?php if ( !empty($newControl['HasTiltSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('HasTiltSpeed') ?></th><td><input type="checkbox" name="newControl[HasTiltSpeed]" value="1"<?php if ( !empty($newControl['HasTiltSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinTiltSpeed') ?></th><td><input type="text" name="newControl[MinTiltSpeed]" value="<?php echo validHtmlStr($newControl['MinTiltSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinTiltSpeed') ?></th><td><input type="number" name="newControl[MinTiltSpeed]" value="<?php echo validHtmlStr($newControl['MinTiltSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxTiltSpeed') ?></th><td><input type="text" name="newControl[MaxTiltSpeed]" value="<?php echo validHtmlStr($newControl['MaxTiltSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxTiltSpeed') ?></th><td><input type="number" name="newControl[MaxTiltSpeed]" value="<?php echo validHtmlStr($newControl['MaxTiltSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasTurboTilt') ?></th><td><input type="checkbox" name="newControl[HasTurboTilt]" value="1"<?php if ( !empty($newControl['HasTurboTilt']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('HasTurboTilt') ?></th><td><input type="checkbox" name="newControl[HasTurboTilt]" value="1"<?php if ( !empty($newControl['HasTurboTilt']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('TurboTiltSpeed') ?></th><td><input type="text" name="newControl[TurboTiltSpeed]" value="<?php echo validHtmlStr($newControl['TurboTiltSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('TurboTiltSpeed') ?></th><td><input type="number" name="newControl[TurboTiltSpeed]" value="<?php echo validHtmlStr($newControl['TurboTiltSpeed']) ?>"/></td></tr>
<?php <?php
break; break;
} }
@ -408,13 +383,13 @@ switch ( $tab )
<tr><th scope="row"><?php echo translate('CanZoomAbs') ?></th><td><input type="checkbox" name="newControl[CanZoomAbs]" value="1"<?php if ( !empty($newControl['CanZoomAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanZoomAbs') ?></th><td><input type="checkbox" name="newControl[CanZoomAbs]" value="1"<?php if ( !empty($newControl['CanZoomAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanZoomRel') ?></th><td><input type="checkbox" name="newControl[CanZoomRel]" value="1"<?php if ( !empty($newControl['CanZoomRel']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanZoomRel') ?></th><td><input type="checkbox" name="newControl[CanZoomRel]" value="1"<?php if ( !empty($newControl['CanZoomRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanZoomCon') ?></th><td><input type="checkbox" name="newControl[CanZoomCon]" value="1"<?php if ( !empty($newControl['CanZoomCon']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanZoomCon') ?></th><td><input type="checkbox" name="newControl[CanZoomCon]" value="1"<?php if ( !empty($newControl['CanZoomCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinZoomRange') ?></th><td><input type="text" name="newControl[MinZoomRange]" value="<?php echo validHtmlStr($newControl['MinZoomRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinZoomRange') ?></th><td><input type="number" name="newControl[MinZoomRange]" value="<?php echo validHtmlStr($newControl['MinZoomRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxZoomRange') ?></th><td><input type="text" name="newControl[MaxZoomRange]" value="<?php echo validHtmlStr($newControl['MaxZoomRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxZoomRange') ?></th><td><input type="number" name="newControl[MaxZoomRange]" value="<?php echo validHtmlStr($newControl['MaxZoomRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinZoomStep') ?></th><td><input type="text" name="newControl[MinZoomStep]" value="<?php echo validHtmlStr($newControl['MinZoomStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinZoomStep') ?></th><td><input type="number" name="newControl[MinZoomStep]" value="<?php echo validHtmlStr($newControl['MinZoomStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxZoomStep') ?></th><td><input type="text" name="newControl[MaxZoomStep]" value="<?php echo validHtmlStr($newControl['MaxZoomStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxZoomStep') ?></th><td><input type="number" name="newControl[MaxZoomStep]" value="<?php echo validHtmlStr($newControl['MaxZoomStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasZoomSpeed') ?></th><td><input type="checkbox" name="newControl[HasZoomSpeed]" value="1"<?php if ( !empty($newControl['HasZoomSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('HasZoomSpeed') ?></th><td><input type="checkbox" name="newControl[HasZoomSpeed]" value="1"<?php if ( !empty($newControl['HasZoomSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinZoomSpeed') ?></th><td><input type="text" name="newControl[MinZoomSpeed]" value="<?php echo validHtmlStr($newControl['MinZoomSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinZoomSpeed') ?></th><td><input type="number" name="newControl[MinZoomSpeed]" value="<?php echo validHtmlStr($newControl['MinZoomSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxZoomSpeed') ?></th><td><input type="text" name="newControl[MaxZoomSpeed]" value="<?php echo validHtmlStr($newControl['MaxZoomSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxZoomSpeed') ?></th><td><input type="number" name="newControl[MaxZoomSpeed]" value="<?php echo validHtmlStr($newControl['MaxZoomSpeed']) ?>"/></td></tr>
<?php <?php
break; break;
} }
@ -426,13 +401,13 @@ switch ( $tab )
<tr><th scope="row"><?php echo translate('CanFocusAbs') ?></th><td><input type="checkbox" name="newControl[CanFocusAbs]" value="1"<?php if ( !empty($newControl['CanFocusAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanFocusAbs') ?></th><td><input type="checkbox" name="newControl[CanFocusAbs]" value="1"<?php if ( !empty($newControl['CanFocusAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanFocusRel') ?></th><td><input type="checkbox" name="newControl[CanFocusRel]" value="1"<?php if ( !empty($newControl['CanFocusRel']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanFocusRel') ?></th><td><input type="checkbox" name="newControl[CanFocusRel]" value="1"<?php if ( !empty($newControl['CanFocusRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanFocusCon') ?></th><td><input type="checkbox" name="newControl[CanFocusCon]" value="1"<?php if ( !empty($newControl['CanFocusCon']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanFocusCon') ?></th><td><input type="checkbox" name="newControl[CanFocusCon]" value="1"<?php if ( !empty($newControl['CanFocusCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinFocusRange') ?></th><td><input type="text" name="newControl[MinFocusRange]" value="<?php echo validHtmlStr($newControl['MinFocusRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinFocusRange') ?></th><td><input type="number" name="newControl[MinFocusRange]" value="<?php echo validHtmlStr($newControl['MinFocusRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxFocusRange') ?></th><td><input type="text" name="newControl[MaxFocusRange]" value="<?php echo validHtmlStr($newControl['MaxFocusRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxFocusRange') ?></th><td><input type="number" name="newControl[MaxFocusRange]" value="<?php echo validHtmlStr($newControl['MaxFocusRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinFocusStep') ?></th><td><input type="text" name="newControl[MinFocusStep]" value="<?php echo validHtmlStr($newControl['MinFocusStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinFocusStep') ?></th><td><input type="number" name="newControl[MinFocusStep]" value="<?php echo validHtmlStr($newControl['MinFocusStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxFocusStep') ?></th><td><input type="text" name="newControl[MaxFocusStep]" value="<?php echo validHtmlStr($newControl['MaxFocusStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxFocusStep') ?></th><td><input type="number" name="newControl[MaxFocusStep]" value="<?php echo validHtmlStr($newControl['MaxFocusStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasFocusSpeed') ?></th><td><input type="checkbox" name="newControl[HasFocusSpeed]" value="1"<?php if ( !empty($newControl['HasFocusSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('HasFocusSpeed') ?></th><td><input type="checkbox" name="newControl[HasFocusSpeed]" value="1"<?php if ( !empty($newControl['HasFocusSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinFocusSpeed') ?></th><td><input type="text" name="newControl[MinFocusSpeed]" value="<?php echo validHtmlStr($newControl['MinFocusSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinFocusSpeed') ?></th><td><input type="number" name="newControl[MinFocusSpeed]" value="<?php echo validHtmlStr($newControl['MinFocusSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxFocusSpeed') ?></th><td><input type="text" name="newControl[MaxFocusSpeed]" value="<?php echo validHtmlStr($newControl['MaxFocusSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxFocusSpeed') ?></th><td><input type="number" name="newControl[MaxFocusSpeed]" value="<?php echo validHtmlStr($newControl['MaxFocusSpeed']) ?>"/></td></tr>
<?php <?php
break; break;
} }
@ -444,13 +419,13 @@ switch ( $tab )
<tr><th scope="row"><?php echo translate('CanIrisAbs') ?></th><td><input type="checkbox" name="newControl[CanIrisAbs]" value="1"<?php if ( !empty($newControl['CanIrisAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanIrisAbs') ?></th><td><input type="checkbox" name="newControl[CanIrisAbs]" value="1"<?php if ( !empty($newControl['CanIrisAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanIrisRel') ?></th><td><input type="checkbox" name="newControl[CanIrisRel]" value="1"<?php if ( !empty($newControl['CanIrisRel']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanIrisRel') ?></th><td><input type="checkbox" name="newControl[CanIrisRel]" value="1"<?php if ( !empty($newControl['CanIrisRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanIrisCon') ?></th><td><input type="checkbox" name="newControl[CanIrisCon]" value="1"<?php if ( !empty($newControl['CanIrisCon']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanIrisCon') ?></th><td><input type="checkbox" name="newControl[CanIrisCon]" value="1"<?php if ( !empty($newControl['CanIrisCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinIrisRange') ?></th><td><input type="text" name="newControl[MinIrisRange]" value="<?php echo validHtmlStr($newControl['MinIrisRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinIrisRange') ?></th><td><input type="number" name="newControl[MinIrisRange]" value="<?php echo validHtmlStr($newControl['MinIrisRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxIrisRange') ?></th><td><input type="text" name="newControl[MaxIrisRange]" value="<?php echo validHtmlStr($newControl['MaxIrisRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxIrisRange') ?></th><td><input type="number" name="newControl[MaxIrisRange]" value="<?php echo validHtmlStr($newControl['MaxIrisRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinIrisStep') ?></th><td><input type="text" name="newControl[MinIrisStep]" value="<?php echo validHtmlStr($newControl['MinIrisStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinIrisStep') ?></th><td><input type="number" name="newControl[MinIrisStep]" value="<?php echo validHtmlStr($newControl['MinIrisStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxIrisStep') ?></th><td><input type="text" name="newControl[MaxIrisStep]" value="<?php echo validHtmlStr($newControl['MaxIrisStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxIrisStep') ?></th><td><input type="number" name="newControl[MaxIrisStep]" value="<?php echo validHtmlStr($newControl['MaxIrisStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasIrisSpeed') ?></th><td><input type="checkbox" name="newControl[HasIrisSpeed]" value="1"<?php if ( !empty($newControl['HasIrisSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('HasIrisSpeed') ?></th><td><input type="checkbox" name="newControl[HasIrisSpeed]" value="1"<?php if ( !empty($newControl['HasIrisSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinIrisSpeed') ?></th><td><input type="text" name="newControl[MinIrisSpeed]" value="<?php echo validHtmlStr($newControl['MinIrisSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinIrisSpeed') ?></th><td><input type="number" name="newControl[MinIrisSpeed]" value="<?php echo validHtmlStr($newControl['MinIrisSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxIrisSpeed') ?></th><td><input type="text" name="newControl[MaxIrisSpeed]" value="<?php echo validHtmlStr($newControl['MaxIrisSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxIrisSpeed') ?></th><td><input type="number" name="newControl[MaxIrisSpeed]" value="<?php echo validHtmlStr($newControl['MaxIrisSpeed']) ?>"/></td></tr>
<?php <?php
break; break;
} }
@ -462,13 +437,13 @@ switch ( $tab )
<tr><th scope="row"><?php echo translate('CanGainAbs') ?></th><td><input type="checkbox" name="newControl[CanGainAbs]" value="1"<?php if ( !empty($newControl['CanGainAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanGainAbs') ?></th><td><input type="checkbox" name="newControl[CanGainAbs]" value="1"<?php if ( !empty($newControl['CanGainAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanGainRel') ?></th><td><input type="checkbox" name="newControl[CanGainRel]" value="1"<?php if ( !empty($newControl['CanGainRel']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanGainRel') ?></th><td><input type="checkbox" name="newControl[CanGainRel]" value="1"<?php if ( !empty($newControl['CanGainRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanGainCon') ?></th><td><input type="checkbox" name="newControl[CanGainCon]" value="1"<?php if ( !empty($newControl['CanGainCon']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanGainCon') ?></th><td><input type="checkbox" name="newControl[CanGainCon]" value="1"<?php if ( !empty($newControl['CanGainCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinGainRange') ?></th><td><input type="text" name="newControl[MinGainRange]" value="<?php echo validHtmlStr($newControl['MinGainRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinGainRange') ?></th><td><input type="number" name="newControl[MinGainRange]" value="<?php echo validHtmlStr($newControl['MinGainRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxGainRange') ?></th><td><input type="text" name="newControl[MaxGainRange]" value="<?php echo validHtmlStr($newControl['MaxGainRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxGainRange') ?></th><td><input type="number" name="newControl[MaxGainRange]" value="<?php echo validHtmlStr($newControl['MaxGainRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinGainStep') ?></th><td><input type="text" name="newControl[MinGainStep]" value="<?php echo validHtmlStr($newControl['MinGainStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinGainStep') ?></th><td><input type="number" name="newControl[MinGainStep]" value="<?php echo validHtmlStr($newControl['MinGainStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxGainStep') ?></th><td><input type="text" name="newControl[MaxGainStep]" value="<?php echo validHtmlStr($newControl['MaxGainStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxGainStep') ?></th><td><input type="number" name="newControl[MaxGainStep]" value="<?php echo validHtmlStr($newControl['MaxGainStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasGainSpeed') ?></th><td><input type="checkbox" name="newControl[HasGainSpeed]" value="1"<?php if ( !empty($newControl['HasGainSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('HasGainSpeed') ?></th><td><input type="checkbox" name="newControl[HasGainSpeed]" value="1"<?php if ( !empty($newControl['HasGainSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinGainSpeed') ?></th><td><input type="text" name="newControl[MinGainSpeed]" value="<?php echo validHtmlStr($newControl['MinGainSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinGainSpeed') ?></th><td><input type="number" name="newControl[MinGainSpeed]" value="<?php echo validHtmlStr($newControl['MinGainSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxGainSpeed') ?></th><td><input type="text" name="newControl[MaxGainSpeed]" value="<?php echo validHtmlStr($newControl['MaxGainSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxGainSpeed') ?></th><td><input type="number" name="newControl[MaxGainSpeed]" value="<?php echo validHtmlStr($newControl['MaxGainSpeed']) ?>"/></td></tr>
<?php <?php
break; break;
} }
@ -480,13 +455,13 @@ switch ( $tab )
<tr><th scope="row"><?php echo translate('CanWhiteAbs') ?></th><td><input type="checkbox" name="newControl[CanWhiteAbs]" value="1"<?php if ( !empty($newControl['CanWhiteAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanWhiteAbs') ?></th><td><input type="checkbox" name="newControl[CanWhiteAbs]" value="1"<?php if ( !empty($newControl['CanWhiteAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanWhiteRel') ?></th><td><input type="checkbox" name="newControl[CanWhiteRel]" value="1"<?php if ( !empty($newControl['CanWhiteRel']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanWhiteRel') ?></th><td><input type="checkbox" name="newControl[CanWhiteRel]" value="1"<?php if ( !empty($newControl['CanWhiteRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanWhiteCon') ?></th><td><input type="checkbox" name="newControl[CanWhiteCon]" value="1"<?php if ( !empty($newControl['CanWhiteCon']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanWhiteCon') ?></th><td><input type="checkbox" name="newControl[CanWhiteCon]" value="1"<?php if ( !empty($newControl['CanWhiteCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinWhiteRange') ?></th><td><input type="text" name="newControl[MinWhiteRange]" value="<?php echo validHtmlStr($newControl['MinWhiteRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinWhiteRange') ?></th><td><input type="number" name="newControl[MinWhiteRange]" value="<?php echo validHtmlStr($newControl['MinWhiteRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxWhiteRange') ?></th><td><input type="text" name="newControl[MaxWhiteRange]" value="<?php echo validHtmlStr($newControl['MaxWhiteRange']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxWhiteRange') ?></th><td><input type="number" name="newControl[MaxWhiteRange]" value="<?php echo validHtmlStr($newControl['MaxWhiteRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinWhiteStep') ?></th><td><input type="text" name="newControl[MinWhiteStep]" value="<?php echo validHtmlStr($newControl['MinWhiteStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinWhiteStep') ?></th><td><input type="number" name="newControl[MinWhiteStep]" value="<?php echo validHtmlStr($newControl['MinWhiteStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxWhiteStep') ?></th><td><input type="text" name="newControl[MaxWhiteStep]" value="<?php echo validHtmlStr($newControl['MaxWhiteStep']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxWhiteStep') ?></th><td><input type="number" name="newControl[MaxWhiteStep]" value="<?php echo validHtmlStr($newControl['MaxWhiteStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasWhiteSpeed') ?></th><td><input type="checkbox" name="newControl[HasWhiteSpeed]" value="1"<?php if ( !empty($newControl['HasWhiteSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('HasWhiteSpeed') ?></th><td><input type="checkbox" name="newControl[HasWhiteSpeed]" value="1"<?php if ( !empty($newControl['HasWhiteSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinWhiteSpeed') ?></th><td><input type="text" name="newControl[MinWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MinWhiteSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MinWhiteSpeed') ?></th><td><input type="number" name="newControl[MinWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MinWhiteSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxWhiteSpeed') ?></th><td><input type="text" name="newControl[MaxWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MaxWhiteSpeed']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('MaxWhiteSpeed') ?></th><td><input type="number" name="newControl[MaxWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MaxWhiteSpeed']) ?>"/></td></tr>
<?php <?php
break; break;
} }
@ -494,7 +469,7 @@ switch ( $tab )
{ {
?> ?>
<tr><th scope="row"><?php echo translate('HasPresets') ?></th><td><input type="checkbox" name="newControl[HasPresets]" value="1"<?php if ( !empty($newControl['HasPresets']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('HasPresets') ?></th><td><input type="checkbox" name="newControl[HasPresets]" value="1"<?php if ( !empty($newControl['HasPresets']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('NumPresets') ?></th><td><input type="text" name="newControl[NumPresets]" value="<?php echo validHtmlStr($newControl['NumPresets']) ?>" size="8"/></td></tr> <tr><th scope="row"><?php echo translate('NumPresets') ?></th><td><input type="number" name="newControl[NumPresets]" value="<?php echo validHtmlStr($newControl['NumPresets']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasHomePreset') ?></th><td><input type="checkbox" name="newControl[HasHomePreset]" value="1"<?php if ( !empty($newControl['HasHomePreset']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('HasHomePreset') ?></th><td><input type="checkbox" name="newControl[HasHomePreset]" value="1"<?php if ( !empty($newControl['HasHomePreset']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanSetPresets') ?></th><td><input type="checkbox" name="newControl[CanSetPresets]" value="1"<?php if ( !empty($newControl['CanSetPresets']) ) { ?> checked="checked"<?php } ?>/></td></tr> <tr><th scope="row"><?php echo translate('CanSetPresets') ?></th><td><input type="checkbox" name="newControl[CanSetPresets]" value="1"<?php if ( !empty($newControl['CanSetPresets']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<?php <?php
@ -505,7 +480,8 @@ switch ( $tab )
</tbody> </tbody>
</table> </table>
<div id="contentButtons"> <div id="contentButtons">
<input type="submit" value="<?php echo translate('Save') ?>"<?php if ( !canEdit( 'Control' ) ) { ?> disabled="disabled"<?php } ?>/><input type="button" value="<?php echo translate('Cancel') ?>" data-on-click="closeWindow"/> <button type="submit" value="Save"<?php if ( !canEdit( 'Control' ) ) { ?> disabled="disabled"<?php } ?>><?php echo translate('Save') ?></button>
<button type="button" data-on-click="closeWindow"><?php echo translate('Cancel') ?></button>
</div> </div>
</form> </form>
</div> </div>

View File

@ -138,7 +138,7 @@ $disk_space_total = 0;
$event_count = 0; $event_count = 0;
while ( $event_row = dbFetchNext($results) ) { while ( $event_row = dbFetchNext($results) ) {
$event = new ZM\Event($event_row); $event = new ZM\Event($event_row);
$scale = max(reScale(SCALE_BASE, $event->DefaultScale(), ZM_WEB_DEFAULT_SCALE), SCALE_BASE); $scale = max(reScale(SCALE_BASE, $event->Monitor()->DefaultScale(), ZM_WEB_DEFAULT_SCALE), SCALE_BASE);
?> ?>
<tr<?php echo $event->Archived() ? ' class="archived"' : '' ?>> <tr<?php echo $event->Archived() ? ' class="archived"' : '' ?>>
<td class="colId"> <td class="colId">

View File

@ -3,21 +3,131 @@ function validateForm( form ) {
// If "Can Move" is enabled, then the end user must also select at least one of the other check boxes (excluding Can Move Diagonally) // If "Can Move" is enabled, then the end user must also select at least one of the other check boxes (excluding Can Move Diagonally)
if ( form.elements['newControl[CanMove]'].checked ) { if ( form.elements['newControl[CanMove]'].checked ) {
if ( !(form.elements['newControl[CanMoveCon]'].checked || form.elements['newControl[CanMoveRel]'].checked || form.elements['newControl[CanMoveAbs]'].checked || form.elements['newControl[CanMoveMap]'].checked) ) { if ( !(
errors[errors.length] = "In addition to \"Can Move\", you also must select at least one of: \"Can Move Mapped\", \"Can Move Absolute\", \"Can Move Relative\", or \"Can Move Continuous\""; form.elements['newControl[CanMoveCon]'].checked
||
form.elements['newControl[CanMoveRel]'].checked
||
form.elements['newControl[CanMoveAbs]'].checked
||
form.elements['newControl[CanMoveMap]'].checked
) ) {
errors[errors.length] = 'In addition to "Can Move", you also must select at least one of: "Can Move Mapped", "Can Move Absolute", "Can Move Relative", or "Can Move Continuous"';
} }
} else { } else {
// Now lets check for the opposite condition. If any of the boxes below Can Move are checked, but Can Move is not checked then signal an error // Now lets check for the opposite condition. If any of the boxes below Can Move are checked, but Can Move is not checked then signal an error
if ( form.elements['newControl[CanMoveCon]'].checked || form.elements['newControl[CanMoveRel]'].checked || form.elements['newControl[CanMoveAbs]'].checked || form.elements['newControl[CanMoveMap]'].checked || form.elements['newControl[CanMoveDiag]'].checked ) { if ( form.elements['newControl[CanMoveCon]'].checked
errors[errors.length] = "\"Can Move\" must also be selected if any one of the movement types are sleceted"; ||
form.elements['newControl[CanMoveRel]'].checked
||
form.elements['newControl[CanMoveAbs]'].checked
||
form.elements['newControl[CanMoveMap]'].checked
||
form.elements['newControl[CanMoveDiag]'].checked
) {
errors[errors.length] = '"Can Move" must also be selected if any one of the movement types are selected.';
}
}
// If "Can Zoom" is enabled, then the end user must also select at least one of the other check boxes
if ( form.elements['newControl[CanZoom]'].checked ) {
if ( !(
form.elements['newControl[CanZoomCon]'].checked
||
form.elements['newControl[CanZoomRel]'].checked
||
form.elements['newControl[CanZoomAbs]'].checked
) ) {
errors[errors.length] = 'In addition to "Can Zoom", you also must select at least one of: "Can Zoom Absolute", "Can Zoom Relative", or "Can Zoom Continuous"';
}
} else {
// Now lets check for the opposite condition. If any of the boxes below Can Zoom are checked, but Can Zoom is not checked then signal an error
if ( form.elements['newControl[CanZoomCon]'].checked
||
form.elements['newControl[CanZoomRel]'].checked
||
form.elements['newControl[CanZoomAbs]'].checked
) {
errors[errors.length] = '"Can Move" must also be selected if any one of the zoom types are selected.';
}
}
// If "Can Zoom" is enabled, then the end user must also select at least one of the other check boxes
if ( form.elements['newControl[CanFocus]'].checked ) {
if ( !(
form.elements['newControl[CanFocusCon]'].checked
||
form.elements['newControl[CanFocusRel]'].checked
||
form.elements['newControl[CanFocusAbs]'].checked
) ) {
errors[errors.length] = 'In addition to "Can Focus", you also must select at least one of: "Can Focus Absolute", "Can Focus Relative", or "Can Focus Continuous"';
}
} else {
// Now lets check for the opposite condition. If any of the boxes below Can Zoom are checked, but Can Zoom is not checked then signal an error
if ( form.elements['newControl[CanFocusCon]'].checked
||
form.elements['newControl[CanFocusRel]'].checked
||
form.elements['newControl[CanFocusAbs]'].checked
) {
errors[errors.length] = '"Can Focus" must also be selected if any one of the focus types are selected.';
}
}
// If "Can White" is enabled, then the end user must also select at least one of the other check boxes
if ( form.elements['newControl[CanWhite]'].checked ) {
if ( !(
form.elements['newControl[CanWhiteCon]'].checked
||
form.elements['newControl[CanWhiteRel]'].checked
||
form.elements['newControl[CanWhiteAbs]'].checked
) ) {
errors[errors.length] = 'In addition to "Can White Balance", you also must select at least one of: "Can White Bal Absolute", "Can White Bal Relative", or "Can White Bal Continuous"';
}
} else {
// Now lets check for the opposite condition. If any of the boxes below Can Zoom are checked, but Can Zoom is not checked then signal an error
if ( form.elements['newControl[CanWhiteCon]'].checked
||
form.elements['newControl[CanWhiteRel]'].checked
||
form.elements['newControl[CanWhiteAbs]'].checked
) {
errors[errors.length] = '"Can White Balance" must also be selected if any one of the white balance types are selected.';
}
}
// If "Can Iris" is enabled, then the end user must also select at least one of the other check boxes
if ( form.elements['newControl[CanIris]'].checked ) {
if ( !(
form.elements['newControl[CanIrisCon]'].checked
||
form.elements['newControl[CanIrisRel]'].checked
||
form.elements['newControl[CanIrisAbs]'].checked
) ) {
errors[errors.length] = 'In addition to "Can Iris", you also must select at least one of: "Can Iris Absolute", "Can Iris Relative", or "Can Iris Continuous"';
}
} else {
// Now lets check for the opposite condition. If any of the boxes below Can Zoom are checked, but Can Zoom is not checked then signal an error
if ( form.elements['newControl[CanIrisCon]'].checked
||
form.elements['newControl[CanIrisRel]'].checked
||
form.elements['newControl[CanIrisAbs]'].checked
) {
errors[errors.length] = '"Can Iris" must also be selected if any one of the iris types are selected.';
} }
} }
if ( errors.length ) { if ( errors.length ) {
alert(errors.join("\n")); alert(errors.join("\n"));
return ( false ); return false;
} }
return ( true ); return true;
} }

View File

@ -57,7 +57,7 @@ function setAlarmCues(data) {
function renderAlarmCues(containerEl) { function renderAlarmCues(containerEl) {
if ( !( cueFrames && cueFrames.length ) ) { if ( !( cueFrames && cueFrames.length ) ) {
console.log("No cue frames for event"); console.log('No cue frames for event');
return; return;
} }
// This uses the Delta of the last frame to get the length of the event. I can't help but wonder though // This uses the Delta of the last frame to get the length of the event. I can't help but wonder though
@ -139,7 +139,7 @@ function setButtonState( element, butClass ) {
element.disabled = false; element.disabled = false;
} }
} else { } else {
console.log("Element was null in setButtonState"); console.log('Element was null in setButtonState');
} }
} }
@ -211,7 +211,7 @@ var lastEventId = 0;
var zmsBroke = false; //Use alternate navigation if zms has crashed var zmsBroke = false; //Use alternate navigation if zms has crashed
function getCmdResponse( respObj, respText ) { function getCmdResponse( respObj, respText ) {
if ( checkStreamForErrors("getCmdResponse", respObj) ) { if ( checkStreamForErrors('getCmdResponse', respObj) ) {
console.log('Got an error from getCmdResponse'); console.log('Got an error from getCmdResponse');
console.log(respObj); console.log(respObj);
console.log(respText); console.log(respText);
@ -542,8 +542,8 @@ var currEventId = null;
var CurEventDefVideoPath = null; var CurEventDefVideoPath = null;
function getEventResponse(respObj, respText) { function getEventResponse(respObj, respText) {
if ( checkStreamForErrors( "getEventResponse", respObj ) ) { if ( checkStreamForErrors('getEventResponse', respObj) ) {
console.log("getEventResponse: errors" ); console.log('getEventResponse: errors');
return; return;
} }
@ -582,7 +582,7 @@ function getEventResponse( respObj, respText ) {
//eventImg.setStyles( { 'width': eventData.width, 'height': eventData.height } ); //eventImg.setStyles( { 'width': eventData.width, 'height': eventData.height } );
if ( vid && CurEventDefVideoPath ) { if ( vid && CurEventDefVideoPath ) {
vid.src({type: 'video/mp4', src: CurEventDefVideoPath}); //Currently mp4 is all we use vid.src({type: 'video/mp4', src: CurEventDefVideoPath}); //Currently mp4 is all we use
console.log("getEventResponse"); console.log('getEventResponse');
initialAlarmCues(eventData.Id);//ajax and render, new event initialAlarmCues(eventData.Id);//ajax and render, new event
addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartTime); addVideoTimingTrack(vid, LabelFormat, eventData.MonitorName, eventData.Length, eventData.StartTime);
CurEventDefVideoPath = null; CurEventDefVideoPath = null;
@ -644,7 +644,7 @@ var frameBatch = 40;
function loadEventThumb( event, frame, loadImage ) { function loadEventThumb( event, frame, loadImage ) {
var thumbImg = $('eventThumb'+frame.FrameId); var thumbImg = $('eventThumb'+frame.FrameId);
if ( !thumbImg ) { if ( !thumbImg ) {
console.error( "No holder found for frame "+frame.FrameId ); console.error('No holder found for frame '+frame.FrameId);
return; return;
} }
var img = new Asset.image( imagePrefix+frame.EventId+"&fid="+frame.FrameId, var img = new Asset.image( imagePrefix+frame.EventId+"&fid="+frame.FrameId,
@ -667,7 +667,7 @@ function loadEventThumb( event, frame, loadImage ) {
} }
function loadEventImage(event, frame) { function loadEventImage(event, frame) {
console.debug( "Loading "+event.Id+"/"+frame.FrameId ); console.debug('Loading '+event.Id+'/'+frame.FrameId);
var eventImg = $('eventImage'); var eventImg = $('eventImage');
var thumbImg = $('eventThumb'+frame.FrameId); var thumbImg = $('eventThumb'+frame.FrameId);
if ( eventImg.getProperty('src') != thumbImg.getProperty('src') ) { if ( eventImg.getProperty('src') != thumbImg.getProperty('src') ) {
@ -714,7 +714,7 @@ function hideEventImageComplete() {
thumbImg.removeClass('selected'); thumbImg.removeClass('selected');
thumbImg.setOpacity(1.0); thumbImg.setOpacity(1.0);
} else { } else {
console.log("Unable to find eventThumb at " + 'eventThumb'+$('eventImage').getProperty( 'alt' ) ); console.log('Unable to find eventThumb at eventThumb'+$('eventImage').getProperty('alt'));
} }
$('prevImageBtn').disabled = true; $('prevImageBtn').disabled = true;
$('nextImageBtn').disabled = true; $('nextImageBtn').disabled = true;
@ -752,14 +752,14 @@ function resetEventStills() {
} }
function getFrameResponse(respObj, respText) { function getFrameResponse(respObj, respText) {
if ( checkStreamForErrors( "getFrameResponse", respObj ) ) { if ( checkStreamForErrors('getFrameResponse', respObj) ) {
return; return;
} }
var frame = respObj.frameimage; var frame = respObj.frameimage;
if ( !eventData ) { if ( !eventData ) {
console.error( "No event "+frame.EventId+" found" ); console.error('No event '+frame.EventId+' found');
return; return;
} }
@ -806,7 +806,8 @@ function checkFrames( eventId, frameId, loadImage ) {
if ( !$('eventThumb'+fid) ) { if ( !$('eventThumb'+fid) ) {
var img = new Element('img', {'id': 'eventThumb'+fid, 'src': 'graphics/transparent.png', 'alt': fid, 'class': 'placeholder'}); var img = new Element('img', {'id': 'eventThumb'+fid, 'src': 'graphics/transparent.png', 'alt': fid, 'class': 'placeholder'});
img.addEvent('click', function() { img.addEvent('click', function() {
eventData['frames'][fid] = null; checkFrames( eventId, fid ); eventData['frames'][fid] = null;
checkFrames(eventId, fid);
}); });
frameQuery(eventId, fid, loadImage && (fid == frameId)); frameQuery(eventId, fid, loadImage && (fid == frameId));
var imgs = $('eventThumbs').getElements('img'); var imgs = $('eventThumbs').getElements('img');
@ -819,9 +820,9 @@ function checkFrames( eventId, frameId, loadImage ) {
function( thumbImg, index ) { function( thumbImg, index ) {
if ( parseInt(img.getProperty('alt')) < parseInt(thumbImg.getProperty('alt')) ) { if ( parseInt(img.getProperty('alt')) < parseInt(thumbImg.getProperty('alt')) ) {
img.inject(thumbImg, 'before'); img.inject(thumbImg, 'before');
return ( true ); return true;
} }
return ( false ); return false;
} }
); );
} }
@ -1090,7 +1091,7 @@ function initPage() {
} }
nearEventsQuery(eventData.Id); nearEventsQuery(eventData.Id);
initialAlarmCues(eventData.Id); //call ajax+renderAlarmCues initialAlarmCues(eventData.Id); //call ajax+renderAlarmCues
if (scale == "auto") changeScale(); if ( scale == 'auto' ) changeScale();
} }
// Kick everything off // Kick everything off

View File

@ -146,10 +146,12 @@ if ( openFilterWindow ) {
function thumbnail_onmouseover(event) { function thumbnail_onmouseover(event) {
var img = event.target; var img = event.target;
img.src = '';
img.src = img.getAttribute('stream_src'); img.src = img.getAttribute('stream_src');
} }
function thumbnail_onmouseout(event) { function thumbnail_onmouseout(event) {
var img = event.target; var img = event.target;
img.src = '';
img.src = img.getAttribute('still_src'); img.src = img.getAttribute('still_src');
} }

View File

@ -43,7 +43,6 @@ function exportProgress() {
} }
function exportResponse(respObj, respText) { function exportResponse(respObj, respText) {
clearInterval(exportTimer); clearInterval(exportTimer);
if ( respObj.result != 'Ok' ) { if ( respObj.result != 'Ok' ) {
$('exportProgressTicker').set('text', respObj.message); $('exportProgressTicker').set('text', respObj.message);

View File

@ -131,9 +131,36 @@ function initPage() {
document.querySelectorAll('select[name="newMonitor[ControlId]"]').forEach(function(el) { document.querySelectorAll('select[name="newMonitor[ControlId]"]').forEach(function(el) {
el.onchange = window['loadLocations'].bind(el, el); el.onchange = window['loadLocations'].bind(el, el);
}); });
document.querySelectorAll('input[name="newMonitor[WebColour]"]').forEach(function(el) {
el.onchange = window['change_WebColour'].bind(el);
});
$j('.chosen').chosen(); $j('.chosen').chosen();
} // end function initPage() } // end function initPage()
function change_WebColour() {
$j('#WebSwatch').css(
'backgroundColor',
$j('input[name="newMonitor[WebColour]"]').val()
);
}
function getRandomColour() {
var letters = '0123456789ABCDEF';
var colour = '#';
for (var i = 0; i < 6; i++) {
colour += letters[Math.floor(Math.random() * 16)];
}
return colour;
}
function random_WebColour() {
var new_colour = getRandomColour();
$j('input[name="newMonitor[WebColour]"]').val(new_colour);
$j('#WebSwatch').css(
'backgroundColor', new_colour
);
}
window.addEventListener('DOMContentLoaded', initPage); window.addEventListener('DOMContentLoaded', initPage);

View File

@ -35,7 +35,7 @@ monitorData[monitorData.length] = {
'connKey': <?php echo $monitor->connKey() ?>, 'connKey': <?php echo $monitor->connKey() ?>,
'width': <?php echo $monitor->ViewWidth() ?>, 'width': <?php echo $monitor->ViewWidth() ?>,
'height':<?php echo $monitor->ViewHeight() ?>, 'height':<?php echo $monitor->ViewHeight() ?>,
'url': '<?php echo $monitor->UrlToIndex() ?>', 'url': '<?php echo $monitor->UrlToIndex( $monitor->Id() + ZM_MIN_STREAMING_PORT) ?>',
'onclick': function(){createPopup( '?view=watch&mid=<?php echo $monitor->Id() ?>', 'zmWatch<?php echo $monitor->Id() ?>', 'watch', <?php echo reScale( $monitor->ViewWidth(), $monitor->PopupScale() ); ?>, <?php echo reScale( $monitor->ViewHeight(), $monitor->PopupScale() ); ?> );}, 'onclick': function(){createPopup( '?view=watch&mid=<?php echo $monitor->Id() ?>', 'zmWatch<?php echo $monitor->Id() ?>', 'watch', <?php echo reScale( $monitor->ViewWidth(), $monitor->PopupScale() ); ?>, <?php echo reScale( $monitor->ViewHeight(), $monitor->PopupScale() ); ?> );},
'type': '<?php echo $monitor->Type() ?>', 'type': '<?php echo $monitor->Type() ?>',
'refresh': '<?php echo $monitor->Refresh() ?>' 'refresh': '<?php echo $monitor->Refresh() ?>'

View File

@ -18,7 +18,7 @@ var speedIndex=<?php echo $speedIndex?>;
// for history, and fps for live, and dynamically determined (in ms) // for history, and fps for live, and dynamically determined (in ms)
var currentDisplayInterval=<?php echo $initialDisplayInterval?>; var currentDisplayInterval=<?php echo $initialDisplayInterval?>;
var playSecsperInterval=1; // How many seconds of recorded image we play per refresh determined by speed (replay rate) and display interval; (default=1 if coming from live) var playSecsPerInterval=1; // How many seconds of recorded image we play per refresh determined by speed (replay rate) and display interval; (default=1 if coming from live)
var timerInterval; // milliseconds between interrupts var timerInterval; // milliseconds between interrupts
var timerObj; // object to hold timer interval; var timerObj; // object to hold timer interval;
var freeTimeLastIntervals=[]; // Percentage of current interval used in loading most recent image var freeTimeLastIntervals=[]; // Percentage of current interval used in loading most recent image

View File

@ -54,7 +54,7 @@ $j(document).ready(function() {
url: thisUrl, url: thisUrl,
data: formData, data: formData,
dataType: 'html', dataType: 'html',
enocde: true timeout: 0
}).done(function(data) { }).done(function(data) {
location.reload(); location.reload();
}); });

View File

@ -49,12 +49,12 @@ function changeScale() {
/*Stream could be an applet so can't use moo tools*/ /*Stream could be an applet so can't use moo tools*/
var streamImg = $('liveStream'+monitorId); var streamImg = $('liveStream'+monitorId);
if ( streamImg ) { if ( streamImg ) {
streamImg.style.width = newWidth + "px"; streamImg.style.width = newWidth + 'px';
streamImg.style.height = newHeight + "px"; streamImg.style.height = newHeight + 'px';
streamImg.src = streamImg.src.replace(/scale=\d+/i, 'scale='+(scale== 'auto' ? autoScale : scale)); streamImg.src = streamImg.src.replace(/scale=\d+/i, 'scale='+(scale== 'auto' ? autoScale : scale));
} else { } else {
console.error("No element found for liveStream."); console.error('No element found for liveStream.');
} }
} }
@ -64,11 +64,11 @@ var lastAlarmState = STATE_IDLE;
function setAlarmState( currentAlarmState ) { function setAlarmState( currentAlarmState ) {
alarmState = currentAlarmState; alarmState = currentAlarmState;
var stateClass = ""; var stateClass = '';
if ( alarmState == STATE_ALARM ) { if ( alarmState == STATE_ALARM ) {
stateClass = "alarm"; stateClass = 'alarm';
} else if ( alarmState == STATE_ALERT ) { } else if ( alarmState == STATE_ALERT ) {
stateClass = "alert"; stateClass = 'alert';
} }
$('stateValue').set('text', stateStrings[alarmState]); $('stateValue').set('text', stateStrings[alarmState]);
if ( stateClass ) { if ( stateClass ) {
@ -114,7 +114,7 @@ function setAlarmState( currentAlarmState ) {
} }
if ( monitorType != 'WebSite' ) { if ( monitorType != 'WebSite' ) {
var streamCmdParms = "view=request&request=stream&connkey="+connKey; var streamCmdParms = 'view=request&request=stream&connkey='+connKey;
if ( auth_hash ) { if ( auth_hash ) {
streamCmdParms += '&auth='+auth_hash; streamCmdParms += '&auth='+auth_hash;
} }
@ -141,7 +141,7 @@ function getStreamCmdFailure(xhr) {
console.log(xhr); console.log(xhr);
} }
function getStreamCmdResponse(respObj, respText) { function getStreamCmdResponse(respObj, respText) {
watchdogOk("stream"); watchdogOk('stream');
if ( streamCmdTimer ) { if ( streamCmdTimer ) {
streamCmdTimer = clearTimeout(streamCmdTimer); streamCmdTimer = clearTimeout(streamCmdTimer);
} }
@ -229,12 +229,18 @@ function getStreamCmdResponse(respObj, respText) {
} // end if canEditMonitors } // end if canEditMonitors
if ( streamStatus.auth ) { if ( streamStatus.auth ) {
auth_hash = streamStatus.auth;
console.log("Have a new auth hash" + streamStatus.auth); console.log("Have a new auth hash" + streamStatus.auth);
// Try to reload the image stream. // Try to reload the image stream.
var streamImg = $('liveStream'); var streamImg = $('liveStream');
if ( streamImg ) { if ( streamImg ) {
streamImg.src = streamImg.src.replace(/auth=\w+/i, 'auth='+streamStatus.auth); streamImg.src = streamImg.src.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
} }
streamCmdParms = streamCmdParms.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
statusCmdParms = statusCmdParms.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
eventCmdParms = eventCmdParms.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
actParms = actParms.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
controlParms = controlParms.replace(/auth=\w+/i, 'auth='+streamStatus.auth);
} // end if have a new auth hash } // end if have a new auth hash
} // end if respObj.status } // end if respObj.status
} else { } else {
@ -473,6 +479,9 @@ function getActResponse( respObj, respText ) {
function deleteEvent( event, eventId ) { function deleteEvent( event, eventId ) {
var actParms = "view=request&request=event&action=delete&id="+eventId; var actParms = "view=request&request=event&action=delete&id="+eventId;
if ( auth_hash ) {
actParms += '&auth='+auth_hash;
}
var actReq = new Request.JSON( { var actReq = new Request.JSON( {
url: thisUrl, url: thisUrl,
method: 'post', method: 'post',

View File

@ -122,9 +122,12 @@ xhtmlHeaders(__FILE__, translate('SystemLog') );
<form id="exportForm" action="" method="post"> <form id="exportForm" action="" method="post">
<fieldset> <fieldset>
<legend><?php echo translate('SelectLog') ?></legend> <legend><?php echo translate('SelectLog') ?></legend>
<label for="selectorAll"><?php echo translate('All') ?></label><input type="radio" id="selectorAll" name="selector" value="all"/> <label for="selectorAll"><?php echo translate('All') ?></label>
<label for="selectorFilter"><?php echo translate('Filter') ?></label><input type="radio" id="selectorFilter" name="selector" value="filter"/> <input type="radio" id="selectorAll" name="selector" value="all"/>
<label for="selectorCurrent"><?php echo translate('Current') ?></label><input type="radio" id="selectorCurrent" name="selector" value="current" title="<?php echo translate('ChooseLogSelection') ?>" data-validators="validate-one-required"/> <label for="selectorFilter"><?php echo translate('Filter') ?></label>
<input type="radio" id="selectorFilter" name="selector" value="filter"/>
<label for="selectorCurrent"><?php echo translate('Current') ?></label>
<input type="radio" id="selectorCurrent" name="selector" value="current" title="<?php echo translate('ChooseLogSelection') ?>" data-validators="validate-one-required"/>
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend><?php echo translate('SelectFormat') ?></legend> <legend><?php echo translate('SelectFormat') ?></legend>

View File

@ -40,8 +40,8 @@ if ( !empty($_REQUEST['mid']) ) {
if ( $monitor and ZM_OPT_X10 ) if ( $monitor and ZM_OPT_X10 )
$x10Monitor = dbFetchOne('SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['mid'])); $x10Monitor = dbFetchOne('SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['mid']));
} }
if ( !$monitor ) {
if ( !$monitor ) {
$nextId = getTableAutoInc('Monitors'); $nextId = getTableAutoInc('Monitors');
if ( isset($_REQUEST['dupId']) ) { if ( isset($_REQUEST['dupId']) ) {
$monitor = new ZM\Monitor($_REQUEST['dupId']); $monitor = new ZM\Monitor($_REQUEST['dupId']);
@ -54,6 +54,7 @@ if ( !$monitor ) {
$monitor = new ZM\Monitor(); $monitor = new ZM\Monitor();
} # end if $_REQUEST['dupID'] } # end if $_REQUEST['dupID']
$monitor->Name(translate('Monitor').'-'.$nextId); $monitor->Name(translate('Monitor').'-'.$nextId);
$monitor->WebColour(random_colour());
} # end if $_REQUEST['mid'] } # end if $_REQUEST['mid']
if ( ZM_OPT_X10 && empty($x10Monitor) ) { if ( ZM_OPT_X10 && empty($x10Monitor) ) {
@ -67,7 +68,6 @@ if ( ZM_OPT_X10 && empty($x10Monitor) ) {
function fourcc($a, $b, $c, $d) { function fourcc($a, $b, $c, $d) {
return ord($a) | (ord($b) << 8) | (ord($c) << 16) | (ord($d) << 24); return ord($a) | (ord($b) << 8) | (ord($c) << 16) | (ord($d) << 24);
} }
if ( isset($_REQUEST['newMonitor']) ) { if ( isset($_REQUEST['newMonitor']) ) {
# Update the monitor object with whatever has been set so far. # Update the monitor object with whatever has been set so far.
$monitor->set($_REQUEST['newMonitor']); $monitor->set($_REQUEST['newMonitor']);
@ -371,13 +371,6 @@ $label_size = array(
'Large' => 2 'Large' => 2
); );
$savejpegopts = array(
'Disabled' => 0,
'Frames only' => 1,
'Analysis images only (if available)' => 2,
'Frames + Analysis images (if available)' => 3,
);
$codecs = array( $codecs = array(
'auto' => translate('Auto'), 'auto' => translate('Auto'),
'MP4' => translate('MP4'), 'MP4' => translate('MP4'),
@ -459,8 +452,8 @@ foreach ( $tabs as $name=>$value ) {
if ( $tab != 'general' ) { if ( $tab != 'general' ) {
?> ?>
<input type="hidden" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>"/> <input type="hidden" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>"/>
<input type="hidden" name="newMonitor[Notes]" value="<?php echo validHtmlStr($monitor->Notes()) ?>"/>
<input type="hidden" name="newMonitor[ServerId]" value="<?php echo validHtmlStr($monitor->ServerId() ) ?>"/> <input type="hidden" name="newMonitor[ServerId]" value="<?php echo validHtmlStr($monitor->ServerId() ) ?>"/>
<input type="hidden" name="newMonitor[StorageId]" value="<?= validHtmlStr($monitor->StorageId() ) ?>"/>
<input type="hidden" name="newMonitor[LinkedMonitors]" value="<?php echo (null !== $monitor->LinkedMonitors())?validHtmlStr($monitor->LinkedMonitors()):'' ?>"/> <input type="hidden" name="newMonitor[LinkedMonitors]" value="<?php echo (null !== $monitor->LinkedMonitors())?validHtmlStr($monitor->LinkedMonitors()):'' ?>"/>
<?php <?php
foreach ( $monitor->GroupIds() as $group_id ) { foreach ( $monitor->GroupIds() as $group_id ) {
@ -529,6 +522,7 @@ if ( $tab != 'source' ) {
} }
if ( $tab != 'storage' ) { if ( $tab != 'storage' ) {
?> ?>
<input type="hidden" name="newMonitor[StorageId]" value="<?php echo validHtmlStr($monitor->StorageId()) ?>"/>
<input type="hidden" name="newMonitor[SaveJPEGs]" value="<?php echo validHtmlStr($monitor->SaveJPEGs()) ?>"/> <input type="hidden" name="newMonitor[SaveJPEGs]" value="<?php echo validHtmlStr($monitor->SaveJPEGs()) ?>"/>
<input type="hidden" name="newMonitor[VideoWriter]" value="<?php echo validHtmlStr($monitor->VideoWriter()) ?>"/> <input type="hidden" name="newMonitor[VideoWriter]" value="<?php echo validHtmlStr($monitor->VideoWriter()) ?>"/>
<input type="hidden" name="newMonitor[EncoderParameters]" value="<?php echo validHtmlStr($monitor->EncoderParameters()) ?>"/> <input type="hidden" name="newMonitor[EncoderParameters]" value="<?php echo validHtmlStr($monitor->EncoderParameters()) ?>"/>
@ -612,6 +606,10 @@ switch ( $tab ) {
<td><?php echo translate('Name') ?></td> <td><?php echo translate('Name') ?></td>
<td><input type="text" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>"/></td> <td><input type="text" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>"/></td>
</tr> </tr>
<tr class="Notes">
<td><?php echo translate('Notes') ?></td>
<td><textarea name="newMonitor[Notes]" rows="4"><?php echo validHtmlStr($monitor->Notes()) ?></textarea></td>
</tr>
<tr> <tr>
<td><?php echo translate('Server') ?></td><td> <td><?php echo translate('Server') ?></td><td>
<?php <?php
@ -620,18 +618,6 @@ switch ( $tab ) {
$servers[$Server->Id()] = $Server->Name(); $servers[$Server->Id()] = $Server->Name();
} }
echo htmlSelect( 'newMonitor[ServerId]', $servers, $monitor->ServerId() ); echo htmlSelect( 'newMonitor[ServerId]', $servers, $monitor->ServerId() );
?>
</td>
</tr>
<tr>
<td><?php echo translate('StorageArea') ?></td>
<td>
<?php
$storage_areas = array(0=>'Default');
foreach ( ZM\Storage::find(NULL, array('order'=>'lower(Name)')) as $Storage ) {
$storage_areas[$Storage->Id()] = $Storage->Name();
}
echo htmlSelect('newMonitor[StorageId]', $storage_areas, $monitor->StorageId());
?> ?>
</td> </td>
</tr> </tr>
@ -921,7 +907,32 @@ if ( $monitor->Type() == 'Local' ) {
} }
case 'storage' : case 'storage' :
?> ?>
<tr><td><?php echo translate('SaveJPEGs') ?></td><td><select name="newMonitor[SaveJPEGs]"><?php foreach ( $savejpegopts as $name => $value ) { ?><option value="<?php echo validHtmlStr($value); ?>"<?php if ( $value == $monitor->SaveJPEGs() ) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($name); ?></option><?php } ?></select></td></tr> <tr>
<td><?php echo translate('StorageArea') ?></td>
<td>
<?php
$storage_areas = array(0=>'Default');
foreach ( ZM\Storage::find(NULL, array('order'=>'lower(Name)')) as $Storage ) {
$storage_areas[$Storage->Id()] = $Storage->Name();
}
echo htmlSelect('newMonitor[StorageId]', $storage_areas, $monitor->StorageId());
?>
</td>
</tr>
<tr>
<td><?php echo translate('SaveJPEGs') ?></td>
<td>
<?php
$savejpegopts = array(
0 => 'Disabled',
1 => 'Frames only',
2 => 'Analysis images only (if available)',
3 => 'Frames + Analysis images (if available)',
);
echo htmlSelect('newMonitor[SaveJPEGs]', $savejpegopts, $monitor->SaveJPEGs());
?>
</td>
</tr>
<tr><td><?php echo translate('VideoWriter') ?></td><td> <tr><td><?php echo translate('VideoWriter') ?></td><td>
<?php <?php
$videowriteropts = array( $videowriteropts = array(
@ -1102,15 +1113,17 @@ if ( canEdit('Control') ) {
<tr> <tr>
<td><?php echo translate('SignalCheckColour') ?></td> <td><?php echo translate('SignalCheckColour') ?></td>
<td> <td>
<input type="text" name="newMonitor[SignalCheckColour]" value="<?php echo validHtmlStr($monitor->SignalCheckColour()) ?>"/> <input type="color" name="newMonitor[SignalCheckColour]" value="<?php echo validHtmlStr($monitor->SignalCheckColour()) ?>"/>
<span id="SignalCheckSwatch" class="swatch" style="background-color: <?php echo validHtmlStr($monitor->SignalCheckColour()); ?>;">&nbsp;&nbsp;&nbsp;&nbsp;</span> <span id="SignalCheckSwatch" class="swatch" style="background-color: <?php echo validHtmlStr($monitor->SignalCheckColour()); ?>;">&nbsp;&nbsp;&nbsp;&nbsp;</span>
</td> </td>
</tr> </tr>
<tr> <tr>
<td><?php echo translate('WebColour') ?></td> <td><?php echo translate('WebColour') ?></td>
<td> <td>
<input type="text" name="newMonitor[WebColour]" value="<?php echo validHtmlStr($monitor->WebColour()) ?>" onchange="$('WebSwatch').setStyle( 'backgroundColor', this.value )"/> <input type="color" name="newMonitor[WebColour]" value="<?php echo validHtmlStr($monitor->WebColour()) ?>"/>
<span id="WebSwatch" class="swatch" style="background-color: <?php echo validHtmlStr($monitor->WebColour()) ?>;">&nbsp;&nbsp;&nbsp;&nbsp;</span> <span id="WebSwatch" class="swatch" style="background-color: <?php echo validHtmlStr($monitor->WebColour()) ?>;">&nbsp;&nbsp;&nbsp;&nbsp;</span>
<i class="material-icons" data-on-click="random_WebColour">sync</i>
</td> </td>
</tr> </tr>
<tr> <tr>

View File

@ -110,8 +110,6 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*',GLOB_ONLYDIR)) as $
<button value="Save" type="submit"><?php echo translate('Save') ?></button> <button value="Save" type="submit"><?php echo translate('Save') ?></button>
</div> </div>
</form> </form>
<?php <?php
} else if ( $tab == 'users' ) { } else if ( $tab == 'users' ) {
?> ?>
@ -278,15 +276,10 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*',GLOB_ONLYDIR)) as $
<td class="colPath"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Path()), $canEdit ) ?></td> <td class="colPath"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Path()), $canEdit ) ?></td>
<td class="colType"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Type()), $canEdit ) ?></td> <td class="colType"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Type()), $canEdit ) ?></td>
<td class="colScheme"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Scheme()), $canEdit ) ?></td> <td class="colScheme"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Scheme()), $canEdit ) ?></td>
<td class="colServer"><?php <td class="colServer"><?php echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Server()->Name()), $canEdit ) ?></td>
echo makePopupLink('?view=storage&amp;id='.$Storage->Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Server()->Name()), $canEdit ) ?></td> <td class="colDiskSpace"><?php echo human_filesize($Storage->disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space()) ?></td>
<td class="colDiskSpace">
<?php echo
human_filesize($Storage->disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space())
?>
</td>
<td class="ColEvents"><?php echo count($Storage->Events()).' using '.human_filesize($Storage->event_disk_space()) ?></td> <td class="ColEvents"><?php echo count($Storage->Events()).' using '.human_filesize($Storage->event_disk_space()) ?></td>
<td class="colMark"><input type="checkbox" name="markIds[]" value="<?php echo $Storage->Id() ?>" data-on-click-this="configureDeleteButton"<?php if ( count($Storage->Events()) or !$canEdit ) { ?> disabled="disabled"<?php } ?><?php echo count($Storage->Events()) ? ' title="Can\' delete as long as there are events stored here."' : ''?>/></td> <td class="colMark"><input type="checkbox" name="markIds[]" value="<?php echo $Storage->Id() ?>" data-on-click-this="configureDeleteButton"<?php if ( count($Storage->Events()) or !$canEdit ) { ?> disabled="disabled"<?php } ?><?php echo count($Storage->Events()) ? ' title="Can\'t delete as long as there are events stored here."' : ''?>/></td>
</tr> </tr>
<?php } #end foreach Server ?> <?php } #end foreach Server ?>
</tbody> </tbody>
@ -319,14 +312,19 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*',GLOB_ONLYDIR)) as $
} }
function updateSelected() { function updateSelected() {
# Turn them all off, then selectively turn the checked ones back on
dbQuery('UPDATE `Users` SET `APIEnabled`=0'); dbQuery('UPDATE `Users` SET `APIEnabled`=0');
foreach ( $_REQUEST["tokenUids"] as $markUid ) {
if ( isset($_REQUEST['tokenUids']) ) {
foreach ( $_REQUEST['tokenUids'] as $markUid ) {
$minTime = time(); $minTime = time();
dbQuery('UPDATE `Users` SET `TokenMinExpiry`=? WHERE `Id`=?', array($minTime, $markUid)); dbQuery('UPDATE `Users` SET `TokenMinExpiry`=? WHERE `Id`=?', array($minTime, $markUid));
} }
foreach ( $_REQUEST["apiUids"] as $markUid ) { }
if ( isset($_REQUEST['apiUids']) ) {
foreach ( $_REQUEST['apiUids'] as $markUid ) {
dbQuery('UPDATE `Users` SET `APIEnabled`=1 WHERE `Id`=?', array($markUid)); dbQuery('UPDATE `Users` SET `APIEnabled`=1 WHERE `Id`=?', array($markUid));
}
} }
echo '<span class="timedSuccessBox">'.translate('Updated').'</span>'; echo '<span class="timedSuccessBox">'.translate('Updated').'</span>';
} }

View File

@ -24,7 +24,11 @@ if ( !canEdit('System') ) {
} }
?> ?>
<div id="modalState" class="modal fade"> <div id="modalState" class="modal fade">
<form class="form-horizontal" name="contentForm" id="contentForm" method="get" action="?view=state"> <form class="form-horizontal" name="contentForm" method="get" action="?view=state">
<input type="hidden" name="view" value="state"/>
<input type="hidden" name="action" value="state"/>
<input type="hidden" name="apply" value="1"/>
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
@ -32,9 +36,6 @@ if ( !canEdit('System') ) {
<h2 class="modal-title"><?php echo translate('RunState') ?></h2> <h2 class="modal-title"><?php echo translate('RunState') ?></h2>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<input type="hidden" name="view" value="state"/>
<input type="hidden" name="action" value="state"/>
<input type="hidden" name="apply" value="1"/>
<div class="form-group"> <div class="form-group">
<label for="runState" class="col-sm-3 control-label">Change State</label> <label for="runState" class="col-sm-3 control-label">Change State</label>

View File

@ -69,6 +69,7 @@ if ( !isset($newZone) ) {
'Id' => 0, 'Id' => 0,
'Name' => translate('New'), 'Name' => translate('New'),
'Type' => 'Active', 'Type' => 'Active',
'Units' => 'Pixels',
'MonitorId' => $monitor->Id(), 'MonitorId' => $monitor->Id(),
'NumCoords' => 4, 'NumCoords' => 4,
'Coords' => sprintf('%d,%d %d,%d, %d,%d %d,%d', $minX, $minY, $maxX, $minY, $maxX, $maxY, $minX, $maxY), 'Coords' => sprintf('%d,%d %d,%d, %d,%d %d,%d', $minX, $minY, $maxX, $minY, $maxX, $maxY, $minX, $maxY),