Merge branch 'master' of github.com:ZoneMinder/zoneminder

This commit is contained in:
Isaac Connor 2019-12-19 09:24:44 -05:00
commit 3c59be9616
11 changed files with 189 additions and 143 deletions

View File

@ -434,6 +434,7 @@ DROP TABLE IF EXISTS `Monitors`;
CREATE TABLE `Monitors` (
`Id` int(10) unsigned NOT NULL auto_increment,
`Name` varchar(64) NOT NULL default '',
`Notes` TEXT NOT NULL default '',
`ServerId` int(10) unsigned,
`StorageId` smallint(5) unsigned default 0,
`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 NOT NULL default '' AFTER `Name`"
));
PREPARE stmt FROM @s;
EXECUTE stmt;

View File

@ -23,7 +23,7 @@
%global _hardened_build 1
Name: zoneminder
Version: 1.33.15
Version: 1.33.16
Release: 1%{?dist}
Summary: A camera monitoring and analysis tool
Group: System Environment/Daemons

View File

@ -1 +1 @@
1.33.15
1.33.16

View File

@ -77,16 +77,24 @@ class GroupsController extends AppController {
}
$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(
__('The group has been saved.'),
array('action' => 'index')
);
}
}
$monitors = $this->Group->Monitor->find('list');
} else {
ZM\Error("Failed to save Group");
debug($this->Group->invalidFields());
}
} # end if post
$monitors = $this->Group->Monitor->find('list');
$this->set(compact('monitors'));
}
} # end add
/**
* edit method

View File

@ -59,7 +59,7 @@ class Group extends AppModel {
*
* @var array
*/
public $hasMany = array(
public $hasAndBelongsToMany = array(
'Monitor' => array(
'className' => 'Monitor',
'joinTable' => 'Groups_Monitors',

View File

@ -9,111 +9,112 @@ require_once('Storage.php');
class Monitor extends ZM_Object {
protected static $table = 'Monitors';
protected $defaults = array(
'Id' => null,
'Name' => '',
'ServerId' => 0,
'StorageId' => 0,
'Type' => 'Ffmpeg',
'Function' => 'Mocord',
'Enabled' => array('type'=>'boolean','default'=>1),
'LinkedMonitors' => array('type'=>'set', 'default'=>null),
'Triggers' => array('type'=>'set','default'=>''),
'Device' => '',
'Channel' => 0,
'Format' => '0',
'V4LMultiBuffer' => null,
'V4LCapturesPerFrame' => 1,
'Protocol' => null,
'Method' => '',
'Host' => null,
'Port' => '',
'SubPath' => '',
'Path' => null,
'Options' => null,
'User' => null,
'Pass' => null,
// These are NOT NULL default 0 in the db, but 0 is not a valid value. FIXME
'Width' => null,
'Height' => null,
'Colours' => 4,
'Palette' => '0',
'Orientation' => null,
'Deinterlacing' => 0,
'DecoderHWAccelName' => null,
'DecoderHWAccelDevice' => null,
'SaveJPEGs' => 3,
'VideoWriter' => '0',
'OutputCodec' => null,
'OutputContainer' => null,
'EncoderParameters' => "# Lines beginning with # are a comment \n# For changing quality, use the crf option\n# 1 is best, 51 is worst quality\n#crf=23\n",
'RecordAudio' => array('type'=>'boolean', 'default'=>0),
'RTSPDescribe' => array('type'=>'boolean','default'=>0),
'Brightness' => -1,
'Contrast' => -1,
'Hue' => -1,
'Colour' => -1,
'EventPrefix' => 'Event-',
'LabelFormat' => '%N - %d/%m/%y %H:%M:%S',
'LabelX' => 0,
'LabelY' => 0,
'LabelSize' => 1,
'ImageBufferCount' => 100,
'WarmupCount' => 0,
'PreEventCount' => 0,
'PostEventCount' => 0,
'StreamReplayBuffer' => 0,
'AlarmFrameCount' => 1,
'SectionLength' => 600,
'MinSectionLength' => 10,
'FrameSkip' => 0,
'MotionFrameSkip' => 0,
'AnalysisFPSLimit' => null,
'AnalysisUpdateDelay' => 0,
'MaxFPS' => null,
'AlarmMaxFPS' => null,
'FPSReportInterval' => 100,
'RefBlendPerc' => 6,
'AlarmRefBlendPerc' => 6,
'Controllable' => array('type'=>'boolean','default'=>0),
'ControlId' => null,
'ControlDevice' => null,
'ControlAddress' => null,
'AutoStopTimeout' => null,
'TrackMotion' => array('type'=>'boolean','default'=>0),
'TrackDelay' => null,
'ReturnLocation' => -1,
'ReturnDelay' => null,
'DefaultRate' => 100,
'DefaultScale' => 100,
'SignalCheckPoints' => 0,
'SignalCheckColour' => '#0000BE',
'WebColour' => 'red',
'Exif' => array('type'=>'boolean','default'=>0),
'Sequence' => null,
'TotalEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'TotalEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'HourEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'HourEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'DayEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'DayEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'WeekEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'WeekEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'MonthEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'MonthEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ArchivedEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ArchivedEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ZoneCount' => 0,
'Refresh' => null,
'DefaultCodec' => 'auto',
'GroupIds' => array('default'=>array(), 'do_not_update'=>1),
);
private $status_fields = array(
'Status' => null,
'AnalysisFPS' => null,
'CaptureFPS' => null,
'CaptureBandwidth' => null,
);
protected $defaults = array(
'Id' => null,
'Name' => '',
'Notes' => '',
'ServerId' => 0,
'StorageId' => 0,
'Type' => 'Ffmpeg',
'Function' => 'Mocord',
'Enabled' => array('type'=>'boolean','default'=>1),
'LinkedMonitors' => array('type'=>'set', 'default'=>null),
'Triggers' => array('type'=>'set','default'=>''),
'Device' => '',
'Channel' => 0,
'Format' => '0',
'V4LMultiBuffer' => null,
'V4LCapturesPerFrame' => 1,
'Protocol' => null,
'Method' => '',
'Host' => null,
'Port' => '',
'SubPath' => '',
'Path' => null,
'Options' => null,
'User' => null,
'Pass' => null,
// These are NOT NULL default 0 in the db, but 0 is not a valid value. FIXME
'Width' => null,
'Height' => null,
'Colours' => 4,
'Palette' => '0',
'Orientation' => null,
'Deinterlacing' => 0,
'DecoderHWAccelName' => null,
'DecoderHWAccelDevice' => null,
'SaveJPEGs' => 3,
'VideoWriter' => '0',
'OutputCodec' => null,
'OutputContainer' => null,
'EncoderParameters' => "# Lines beginning with # are a comment \n# For changing quality, use the crf option\n# 1 is best, 51 is worst quality\n#crf=23\n",
'RecordAudio' => array('type'=>'boolean', 'default'=>0),
'RTSPDescribe' => array('type'=>'boolean','default'=>0),
'Brightness' => -1,
'Contrast' => -1,
'Hue' => -1,
'Colour' => -1,
'EventPrefix' => 'Event-',
'LabelFormat' => '%N - %d/%m/%y %H:%M:%S',
'LabelX' => 0,
'LabelY' => 0,
'LabelSize' => 1,
'ImageBufferCount' => 100,
'WarmupCount' => 0,
'PreEventCount' => 0,
'PostEventCount' => 0,
'StreamReplayBuffer' => 0,
'AlarmFrameCount' => 1,
'SectionLength' => 600,
'MinSectionLength' => 10,
'FrameSkip' => 0,
'MotionFrameSkip' => 0,
'AnalysisFPSLimit' => null,
'AnalysisUpdateDelay' => 0,
'MaxFPS' => null,
'AlarmMaxFPS' => null,
'FPSReportInterval' => 100,
'RefBlendPerc' => 6,
'AlarmRefBlendPerc' => 6,
'Controllable' => array('type'=>'boolean','default'=>0),
'ControlId' => null,
'ControlDevice' => null,
'ControlAddress' => null,
'AutoStopTimeout' => null,
'TrackMotion' => array('type'=>'boolean','default'=>0),
'TrackDelay' => null,
'ReturnLocation' => -1,
'ReturnDelay' => null,
'DefaultRate' => 100,
'DefaultScale' => 100,
'SignalCheckPoints' => 0,
'SignalCheckColour' => '#0000BE',
'WebColour' => 'red',
'Exif' => array('type'=>'boolean','default'=>0),
'Sequence' => null,
'TotalEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'TotalEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'HourEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'HourEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'DayEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'DayEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'WeekEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'WeekEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'MonthEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'MonthEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ArchivedEvents' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ArchivedEventDiskSpace' => array('type'=>'integer', 'default'=>null, 'do_not_update'=>1),
'ZoneCount' => 0,
'Refresh' => null,
'DefaultCodec' => 'auto',
'GroupIds' => array('default'=>array(), 'do_not_update'=>1),
);
private $status_fields = array(
'Status' => null,
'AnalysisFPS' => null,
'CaptureFPS' => null,
'CaptureBandwidth' => null,
);
public function Control() {
if ( !property_exists($this, 'Control') ) {

View File

@ -158,14 +158,24 @@ class ZM_Object {
# perhaps should turn into a comma-separated string
$this->{$k} = implode(',', $v);
} else if ( is_string($v) ) {
if ( $v == '' and array_key_exists($k, $this->defaults) ) {
if ( is_array($this->defaults[$k]) )
if ( 0 ) {
# 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'];
else
$this->{$k} = $this->defaults[$k];
} else {
$this->{$k} = trim($v);
} else {
$this->{$k} = $this->defaults[$k];
Logger::Debug("$k => Have default for $v: " . $this->{$k});
}
} else {
$this->{$k} = trim($v);
}
} else {
$this->{$k} = trim($v);
}
} else if ( is_integer($v) ) {
$this->{$k} = $v;
} else if ( is_bool($v) ) {

View File

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

View File

@ -40,8 +40,8 @@ if ( !empty($_REQUEST['mid']) ) {
if ( $monitor and ZM_OPT_X10 )
$x10Monitor = dbFetchOne('SELECT * FROM TriggersX10 WHERE MonitorId = ?', NULL, array($_REQUEST['mid']));
}
if ( !$monitor ) {
if ( !$monitor ) {
$nextId = getTableAutoInc('Monitors');
if ( isset($_REQUEST['dupId']) ) {
$monitor = new ZM\Monitor($_REQUEST['dupId']);
@ -67,7 +67,6 @@ if ( ZM_OPT_X10 && empty($x10Monitor) ) {
function fourcc($a, $b, $c, $d) {
return ord($a) | (ord($b) << 8) | (ord($c) << 16) | (ord($d) << 24);
}
if ( isset($_REQUEST['newMonitor']) ) {
# Update the monitor object with whatever has been set so far.
$monitor->set($_REQUEST['newMonitor']);
@ -371,13 +370,6 @@ $label_size = array(
'Large' => 2
);
$savejpegopts = array(
'Disabled' => 0,
'Frames only' => 1,
'Analysis images only (if available)' => 2,
'Frames + Analysis images (if available)' => 3,
);
$codecs = array(
'auto' => translate('Auto'),
'MP4' => translate('MP4'),
@ -459,8 +451,8 @@ foreach ( $tabs as $name=>$value ) {
if ( $tab != 'general' ) {
?>
<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[StorageId]" value="<?= validHtmlStr($monitor->StorageId() ) ?>"/>
<input type="hidden" name="newMonitor[LinkedMonitors]" value="<?php echo (null !== $monitor->LinkedMonitors())?validHtmlStr($monitor->LinkedMonitors()):'' ?>"/>
<?php
foreach ( $monitor->GroupIds() as $group_id ) {
@ -529,6 +521,7 @@ if ( $tab != 'source' ) {
}
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[VideoWriter]" value="<?php echo validHtmlStr($monitor->VideoWriter()) ?>"/>
<input type="hidden" name="newMonitor[EncoderParameters]" value="<?php echo validHtmlStr($monitor->EncoderParameters()) ?>"/>
@ -612,6 +605,10 @@ switch ( $tab ) {
<td><?php echo translate('Name') ?></td>
<td><input type="text" name="newMonitor[Name]" value="<?php echo validHtmlStr($monitor->Name()) ?>"/></td>
</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>
<td><?php echo translate('Server') ?></td><td>
<?php
@ -620,18 +617,6 @@ switch ( $tab ) {
$servers[$Server->Id()] = $Server->Name();
}
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>
</tr>
@ -921,7 +906,32 @@ if ( $monitor->Type() == 'Local' ) {
}
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>
<?php
$videowriteropts = array(

View File

@ -24,7 +24,7 @@ if ( !canEdit('System') ) {
}
?>
<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">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">